db; } public function installPath($name) { return Path::join(CMS_PATH, "modules", $name); } public function addSuggest(View_View $view, $name) { $suggest = array(); $file = Path::join($this->viewPath, 'help', $name . '.suggest'); if (file_exists($file)) { include($file); $view->suggestions = $suggest; } } function findIcon($icon, $size) { return Path::join($this->iconPath, $size . 'x' . $size, $icon . '.png'); } /** * Создает представление * @param $name String * @param $viewClass String * @return View_Composite */ public function getView($name, $viewClass = 'View_Composite') { $file = $name . self::TEMPLATE_EXTENSION; $list = array( Path::join($this->viewPath, TEMPLATES, $this->viewPathPrefix) => Path::join(WWW_PATH, "modules", $this->name, TEMPLATES, $this->viewPathPrefix), Path::join(CMS_PATH, "templates") => Path::join(WWW_PATH, "templates") ); // Поиск файла для шаблона foreach($list as $ospath => $path) { $template = Path::join($ospath, $file); if(file_exists($template)) { break; } } /*.View_Composite.*/$tpl = new $viewClass($template); $assets = Path::join(WWW_PATH, "assets", "css"); $tpl->set('icons', $this->iconPath); // Путь к файлам текущей темы $tpl->set('media', $this->themePath); // Путь к файлам текущей темы $tpl->set('assets', $assets); $tpl->set('script', $this->jsPath); // Путь к файлам скриптов $tpl->set('template', $path); // Путь к файлам текущего шаблона $tpl->setAlias(array( 'assets' => $assets, 'icons' => $this->iconPath, 'script' => $this->jsPath, // Для 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 Model_Factory($this->db, $this->_registry); } return $this->factory->getModel($name); } /** * Выбор действия * Т.к действия являются методами класса то * 1. Можно переопределить действия * 2. Использовать наследование чтобы добавить к старому обработчику новое поведение * @param $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) { $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 postUrl($name, $param) { $uri = array_merge(array('module' => strtr($this->modulePrefix . strtolower(get_class($this)), array('module_' => '')), "action" => $name), $this->param, $param); return "?" . http_build_query($uri); } /** * Генерация ссылки c учетом прав пользователя на ссылки * @param string $name Действие * @param array $param Дополнительные параметры * 'mode' означает что элемент до отправки обрабатывается javascript * @return array|null */ public function nUrl($name, array $param = array()) { /*.Filter_ActionAccess.*/$access = $this->access; if ($access != null || $access->checkAction($name)) { return lcurry(array($this, 'postUrl'), $name, $param); } return null; } public function fUrl($name, array $param = array()) { return forceUrl($this->nUrl($name, $param)); } /** * Добавляет параметр для всех ссылок создаваемых функцией nUrl, aUrl */ public function addParameter($name, $value) { if ($value) { $this->param [$name] = $value; } } /** * Генерация ссылки на действие контроллера * Ajax определяется автоматически mode = ajax используется для смены layout * @param $name * @param array $param * @return array|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)); // FIXME } /** * Добавление помошника контроллера */ 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(/*Widget*/ $section, $node) { $this->childNodes[$section] = $node; } public function setValue(/*Widget*/ $name, $value) { $this->ctrlValues[$name] = $value; } /** * Добавление дочернего отображения к текущему отображению */ public function addView(/*CompositeView*/ $section, $node) { $this->childViews[$section] = $node; } /** * Генерация содержания * Путаница c execute и render */ public function render() { if ($this->view instanceof View_View) { $this->view->assignValues($this->ctrlValues); 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 Controller_State('index'); } // Тоже убрать в метод Controller_Model function getActionPath(HttpRequest $request, $action = null) { $this->_getActionPath()->getPath($this, ($action) ? $action : $request->getAction()); } function redirect($action) { header('location: ' . $this->fUrl($action)); exit(); } }