part = new Url(); } public function setUp() { } public function loadConfig($name) { $basePath = $this->config->get('site', 'path'); $filename = Path::join($basePath, 'modules', $name); $settings = []; if (file_exists($filename)) { $settings = include($filename); } else { throw new Exception('Невозможно загрузить файл настроек ' . $name); } return $settings; } public function getConnection() { return $this->db; } public function installPath($name) { $basePath = $this->config->get('system', 'path'); return Path::join($basePath, "modules", $name); } public function addSuggest(View $view, $name) { $suggest = array(); $file = Path::join($this->modulePath, 'help', $name . '.suggest'); if (file_exists($file)) { $view->suggestions = include($file); } } function findIcon($icon, $size) { $webPath = $this->config->get('site', 'web'); return Path::join($webPath, 'icons', $size . 'x' . $size, $icon . '.png'); } /** * Создает представление * @param string $name * @param string $viewClass * @return Composite */ public function getView($name, $viewClass = Composite::class) { $file = $name . self::TEMPLATE_EXTENSION; $basePath = $this->config->get('system', 'path'); $webPath = $this->config->get('system', 'web'); $list = array( Path::join($this->modulePath, 'templates', $this->viewPathPrefix) => Path::join($webPath, "modules", $this->name, 'templates', $this->viewPathPrefix), Path::join($basePath, "templates") => Path::join($webPath, "templates") ); // Поиск файла для шаблона foreach($list as $ospath => $path) { $template = Path::join($ospath, $file); if(file_exists($template)) { break; } } $tpl/*: Composite*/ = new $viewClass($template); $tpl->config = $this->config; $stylePath = Path::join($webPath, "assets", "css"); $iconsPath = Path::join($webPath, 'icons'); $scriptPath = Path::join($webPath, 'assets'); $tpl->set('icons', $iconsPath); // Путь к файлам текущей темы $tpl->set('assets', $stylePath); $tpl->set('script', $scriptPath); // Путь к файлам скриптов $tpl->set('template', $path); // Путь к файлам текущего шаблона $tpl->setAlias(array( 'assets' => $stylePath, 'icons' => $iconsPath, 'script' => $scriptPath, // Для media и template поиск происходит как для файлов шаблонов 'media' => $list, 'template' => $list )); $tpl->loadImports(Path::skipExtension($template) . ".import"); $this->addSuggest($tpl, $name); return $tpl; } public function getModel($name) { if (!$this->factory) { $this->factory = new Factory($this->db, $this->config, $this->user); } return $this->factory->getModel($name); } /** * Выбор действия * Т.к действия являются методами класса то * 1. Можно переопределить действия * 2. Использовать наследование чтобы добавить к старому обработчику новое поведение * @param HttpRequest $request запроса */ public function preProcess(HttpRequest $request) { $action = self::ACTION_PREFIX . ucfirst($request->getAction()); if (!method_exists($this, $action)) { $action = "actionIndex"; } $view = $this->forward($action, $request); if ($view instanceof View) { $view->active_module = get_class($this); $view->module_action = $action; } return $view; } public function execute(HttpRequest $request) { $result = $this->preProcess($request); if (!empty($result)) { $this->view = $result; } $text = $this->render(); return $text; } public function forward($action, HttpRequest $args) { $value = call_user_func(array($this, $action), $args); return $value; } /** * Страница по умолчанию */ public function actionIndex(HttpRequest $request) { return ""; } public function addUrlPart($key, $value) { $this->part->addQueryParam($key, $value); } /** * Генерация ссылки c учетом прав пользователя на ссылки * @param string $name Действие * @param array $param Дополнительные параметры * 'mode' означает что элемент до отправки обрабатывается javascript * @return Url|null */ public function nUrl($name, array $param = array()) { $access/*: ActionAccess*/ = $this->access; $url = new Url(); if ($access == null || $access->checkAction($name)) { $moduleName = explode("\\", strtolower(get_class($this))); if (count($moduleName) > 2) { array_shift($moduleName); if ($moduleName[0] == $moduleName[1]) { array_shift($moduleName); } } $param = array_merge(array('module' => implode("\\", $moduleName), "action" => $name), $param); $url->setParent($this->part); $url->setQuery($param); } return $url; } /** * Генерация ссылки на действие контроллера * Ajax определяется автоматически mode = ajax используется для смены layout * @param $name * @param array $param * @return Url|null * * @example ?action=$name&mode=ajax * {$param[i].key = $param[i].value} */ public function aUrl($name, array $param = array()) { return $this->nUrl($name, array_merge(array('mode' => 'ajax'), $param)); } /** * Добавление помошника контроллера */ public function addHelper($class) { $this->helpers [] = $class; } /** * Вызов помошников контроллера */ public function callHelpers(HttpRequest $request) { $action = self::ACTION_PREFIX . $request->getAction(); foreach ($this->helpers as $helper) { if (method_exists($helper, $action)) { return call_user_func(array($helper, $action), $request, $this); } else { return $helper->actionIndex($request, $this); // Вместо return response ??? } } } /** * Загрузка файла класса */ public function loadClass($path, $setup = null, $prefix = '') { if (file_exists($path)) { require_once ($path); $class = $prefix . pathinfo($path, PATHINFO_FILENAME); return new $class($setup); } throw new Exception("NO CLASS $path"); } public function loadSettings($path) { $result = new Settings($path); $result->read(); return $result->export(); } public function setView($name) { $this->view = $this->getView($name); } /** * Установка заголовка для отображения */ public function setTitle($title) { $this->view->setTitle($title); } /** * Добавление widget к отображению */ public function addChild($section, $node) { $this->childNodes[$section] = $node; } public function setValue($name, $value) { $this->ctrlValues[$name] = $value; } /** * Добавление дочернего отображения к текущему отображению */ public function addView($section, $node) { $this->childViews[$section] = $node; } /** * Генерация содержания * Путаница c execute и render */ public function render() { $view = $this->view; if ($view instanceof View) { $this->view->assignValues($this->ctrlValues); $node/*: Composite*/ = null; foreach ($this->childNodes as $name => $node) { $node->make($this); $this->view->setView($name, $node->view); } foreach ($this->childViews as $name => $node) { $this->view->setView($name, $node); } } return $this->view; } function getPageId(HttpRequest $request) { $pageId = time(); $request->session()->set('page', $pageId); return $pageId; } function checkPageId(HttpRequest $request, $page) { if ($request->get('__forced__')) { return true; } $_page = $request->session()->get('page'); $result = ($_page && $_page == $page); $request->session()->clean('page'); return $result; } function _getActionPath() { return new State('index'); } // Тоже убрать в метод Controller_Model function getActionPath(HttpRequest $request, $action = null) { $this->_getActionPath()->getPath($this, ($action) ? $action : $request->getAction()); } function redirect($action/*: string*/) { header('location: ' . $action); exit(); } }