<?php
 namespace TCMS;
 class Extension {
 private $extPath = null;
 private $extName = null;
 private $__view = null;
 public function __construct() {
 }
 public function getExtPath() {
 if(!$this->extPath) {
 $rc = new \ReflectionClass(get_class($this));
 $this->extPath = dirname($rc->getFileName()) . DIRECTORY_SEPARATOR;
 $this->extName = basename($this->extPath);
 }
 return $this->extPath;
 }
 public function makeModelPath(string $modelName) {
 return $this->getExtPath() . 'models' . DIRECTORY_SEPARATOR . $modelName . '.php';
 }
 public function getExtName() {
 if(!$this->extName) {
 $rc = new \ReflectionClass(get_class($this));
 $this->extPath = dirname($rc->getFileName()) . DIRECTORY_SEPARATOR;
 $this->extName = basename($this->extPath);
 }
 return $this->extName;
 }
 public function __get($name) {
 if($name == 'view') {
 if($this->__view == null) {
 $this->__view = new TCmsParentView();
 $this->__view->__parentExtension = $this;
 }
 return $this->__view;
 }
 }
 protected function lang($langKey, array $args = null) {
 $langKeyArray = explode(".", $langKey);
 if(count($langKeyArray) == 2) {
 $langPath = $this->getExtPath() . 'langs' . DIRECTORY_SEPARATOR . $langKeyArray[0] . '.' . \GlobalVars::$requestInfo['cur_lang'] . '.php';
 if(file_exists($langPath)) {
 $langData = include($langPath);
 if(isset($langData[$langKeyArray[1]])) {
 if($args == null || count($args) === 0) {
 return $langData[$langKeyArray[1]];
 }
 $text = $langData[$langKeyArray[1]];
 foreach($args as $k => $v) {
 $text = str_replace('{' . $k . '}', $v , $text);
 }
 return $text;
 }
 }
 }
 return $langKey;
 }
 public function addStyle(string $url, bool $isAddVersion = true) {
 $this->addOrRemoveStyleScript($url, true, $isAddVersion);
 }
 public function addScript(string $url, bool $isAddVersion = true) {
 $this->addOrRemoveStyleScript($url, false, $isAddVersion);
 }
 private function addOrRemoveStyleScript($url, $isStyle, $isAddVersion = true) {
 $arr = explode('/', $url);
 $fileName = $arr[count($arr) - 1];
 $isExistFile = array_key_exists($fileName, \GlobalVars::$styleScriptAdded);
 if($isExistFile === false) {
 if($isAddVersion) {
 if(strpos($fileName, "?") === false) {
 $url .= '?v=' . APP_VERSION;
 }
 else {
 $url .= '&v=' . APP_VERSION;
 }
 }
 \GlobalVars::$styleScriptAdded[$fileName] = [ 'url' => $url, 'isStyle' => $isStyle, 'extension' => $this->getExtName() ];
 if($isStyle) {
 \GlobalVars::$styleScriptAdded[$fileName]['r'] = true;
 echo "<link rel=\"stylesheet\" type=\"text/css\" href=\"".$url."\">\n";
 }
 }
 }
 protected function view($arg = null, $arg2 = null) {
 if($this->__view == null) {
 $this->__view = new TCmsParentView();
 $this->__view->__parentExtension = $this;
 }
 $viewFile = $this->getViewFile($arg, $arg2);
 if($viewFile == null) throw new TException("Không tìm thấy view file", 501);
 $viewFile = $this->getExtPath() . 'views' . DIRECTORY_SEPARATOR . $viewFile;
 $this->readerView($viewFile);
 }
 private function readerView($viewFile) {
 if(file_exists($viewFile . TCMS_VIEW_ENGINE . '.php')) {
 $this->view->renderTCmsViewEngine($viewFile . TCMS_VIEW_ENGINE . '.php', true);
 }
 else {
 if(file_exists($viewFile . '.php')) $this->view->renderTCmsViewEngine($viewFile . '.php', false);
 else throw new TException("Không tìm thấy view file " . str_replace(MODULE_PATH, "", $viewFile), 501);
 }
 }
 private function getViewFile($arg, $arg2) {
 $viewFile = null;
 if(isset($arg)) {
 if(is_string($arg)) {
 $viewFile = $arg;
 if(isset($arg2)) {
 $this->view->setViewData($arg2);
 }
 }
 else if(is_array($arg)) {
 $this->view->setViewData($arg);
 }
 else if($arg instanceof \stdClass) {
 $this->view->setViewData($arg);
 }
 else if($arg instanceof \TCMS\Model) {
 $this->view->setViewData($arg);
 }
 }
 if($viewFile == null && $this->view->__parentExtension == null) {
 $viewFile = \GlobalVars::$requestInfo['action'];
 if(strpos($viewFile, "post") === 0) {
 $viewFile = substr($viewFile, 4);
 }
 else if(strpos($viewFile, "get") === 0) {
 $viewFile = substr($viewFile, 3);
 }
 }
 return $viewFile;
 }
 }
 abstract class ControlExtension extends Extension {
 abstract public function render($value, $option = null);
 }
 abstract class FormControlExtension extends Extension {
 final public function __construct() {
 if(\GlobalVars::$isHasCallRenderViewFromCtr) {
 $obj = new \ReflectionClass($this);
 $fileName = basename($obj->getFileName());
 $fileName = substr($fileName, 0, strlen($fileName) - 4);
 echo '<input type="hidden" name="__tcms_call_ext_model[]" value="' . $fileName . '" />';
 }
 }
 abstract public function render($value, $option = null);
 abstract public function onSubmit($model);
 }
 abstract class ModelExtension extends Extension {
 abstract public function render($value, $option = null);
 public function onModelChanged(Model $model, $isInsert) {
 }
 public function onModelDeleted(Model $model, $id) {
 }
 }
 abstract class AuthExtension extends Extension {
 public $__isNeedKeyInMemory = true;
 public $loginUrl = '/login';
 abstract public function login(string $username, string $password, array $option = null);
 abstract public function logout();
 abstract public function auth();
 abstract public function hasRole($role);
 abstract public function getName();
 abstract public function encodePass($password);
 public function getUserId() {
 return false;
 }
 public function getUser() {
 return false;
 }
 public function createUser($user) {
 return false;
 }
 public function updateUser($user) {
 return false;
 }
 }
 class HookExtension extends Extension {
 public $__isNeedKeyInMemory = true;
 public function startup() {
 }
 public function beforeModuleLoad($module) {
 }
 public function beforeControllerLoad($controller) {
 }
 public function beforeViewLoad($view) {
 }
 }
 ?>