_name = $name; } function __set($key, $value) { $this->_data[$key] = $value; } function execute() { return json_encode($this->_data); } } /** * Класс компонента */ class Component { public $viewPath = array(); public $webPath = array(); public $template = null; public $templatePath; public $component_id; public $component_title; public $COMPONENTS_WEB; public Registry $config; public Database $db; public Collection $parameter; public $output = 'html'; public $module; public $item_module; public $site; function before() { } static function replaceContent($match) { return \ctiso\Tales::phptal_component(htmlspecialchars_decode($match[3])); } static function applyComponents($text) { return preg_replace_callback('/<(\w+)(\s+[a-zA-Z\-]+=\"[^\"]*\")*\s+tal:replace="structure\s+component:([^\"]*)"[^>]*>/u', 'ctiso\\Controller\\Component::replaceContent', $text); } function execute(HttpRequest $request, $has_id = true) { $crequest = new ComponentRequest($this->component_id, $request); $_action = $request->get('action', 'index'); if (is_array($_action)) { $action = 'action' . ucfirst(Arr::get($_action, $this->component_id, 'index')); } else { $action = 'action' . ucfirst($_action); } $this->before(); if (method_exists($this, $action)) { return call_user_func(array($this, $action), $crequest); } else { return $this->actionIndex($crequest); } } public function getTemplateName($_registry/*: \ctiso\Settings*/) { return (isset($_COOKIE['with_template']) && preg_match('/^[\w\d-]{3,20}$/', $_COOKIE['with_template'])) ? $_COOKIE['with_template'] : ($_registry ? $_registry->get('site', 'template') : 'modern'); } public function getView($name) { if ($this->output == 'json') { return new FakeTemplate($name); } $config/*: Registry*/ = $this->config; $default = $config->get('site', 'template'); $template = ($this->template) ? $this->template : $this->getTemplateName($config); $selected = null; $tpl = null; foreach ($this->viewPath as $index => $viewPath) { // Загружать шаблон по умолчанию если не найден текущий $dir = Path::join($this->viewPath[$index], 'templates', $template); if(is_dir($dir)) { $tpl = new PHPTAL(Path::join($this->viewPath[$index], 'templates', $template, $name)); $tpl->setPhpCodeDestination(PHPTAL_PHP_CODE_DESTINATION); $selected = $index; break; } } if ($selected === null) { // Последний вариант viewPath, путь к папке компонента $selected = count($this->viewPath) - 1; $tpl = new PHPTAL(Path::join($this->viewPath[$selected], 'templates', 'modern', $name)); $tpl->setPhpCodeDestination(PHPTAL_PHP_CODE_DESTINATION); $template = 'modern'; } $tpl->stripComments(true); $tpl->addPreFilter(new PHPTAL_PreFilter_Normalize()); $tpl->set('common', Path::join($this->config->get('system', 'web'), '../', 'common')); $tpl->set('script', Path::join($this->config->get('system', 'web'), 'js')); $tpl->set('media', Path::join($this->config->get('system', 'templates.web'), $template)); if ($default) { $tpl->set('site_template', Path::join($this->config->get('site', 'templates.web'), $default)); } $tpl->set('base', $this->config->get('site', 'web')); $tpl->set('component_base', $this->webPath[$selected]); $tpl->set('component', Path::join($this->webPath[$selected], 'templates', $template)); $tpl->set('component_id', $this->component_id); return $tpl; } function _getDefaultPath() { return $this->viewPath[count($this->viewPath) - 1]; } public function getTemplatePath($name) { $registry = $this->config; // Брать настройки из куков если есть $template = ($this->template) ? $this->template : $this->getTemplateName($registry); foreach ($this->viewPath as $index => $viewPath) { if(is_dir(Path::join($this->viewPath[$index], 'templates', $template))) { return Path::join($this->viewPath[$index], 'templates', $template, $name); } } return Path::join($this->viewPath[count($this->viewPath) - 1], 'templates', 'modern', $name); } public function getTemplateWebPath() { return Path::join($this->webPath[count($this->webPath) - 1], 'templates', 'modern'); } /** * Создает модель * @param string $name * @return mixed */ public function getModel($name) { $modelName = "App\\Mapper\\" . $name; $model = new $modelName(); $model->config = $this->config; $model->db = $this->db; return $model; } public function options($key, $val, $res/*: PDOStatement*/) { $result = array(); while($res->next()) { $result[] = array('value' => $res->getString($key), 'name' => $res->getString($val)); } return $result; } public function optionsPair($list, $selected = false) { $result = array(); foreach ($list as $key => $value) { $result [] = array('value' => $key, 'name' => $value, 'selected' => $key == $selected); } return $result; } function findFile($pathList, $name) { foreach($pathList as $item) { $filename = Path::join($item, $name); if (file_exists($filename)) { return $filename; } } return null; } function getInfo() { $filename = Path::join($this->viewPath[count($this->viewPath) - 1], 'install.json'); if (file_exists($filename)) { $settings = json_decode(File::getContents($filename), true); if ($settings) { return $settings; } } return array('parameter' => []); } /** * Генерация интерфейса для выбора галлереи фотографии */ public function setParameters($view/*: Composite*/, $options = null) { $form = new Form(); $settings = $this->getInfo(); $form->addFieldList($settings['parameter'], $options); $view->form = $form; $view->component = $settings['component']; $view->component_title = $settings['title']; } static function loadComponent($expression, $site/*: SiteInterface*/) { $expression = htmlspecialchars_decode($expression); $offset = strpos($expression, '?'); $url = parse_url($expression); $arguments = array(); if ($offset === false) { $path = $expression; } else if (is_int($offset)) { $path = substr($expression, 0, $offset); $query = substr($expression, $offset + 1); parse_str($query, $arguments); } $name = $path; $config = $site->config; $filename = ucfirst($name); $path = Path::join ($config->get('site', 'components'), $name, $filename . '.php'); $className = implode("\\", ['Components', ucfirst($name), $filename]); $component/*: Component*/ = null; if (file_exists($path)) { // require_once ($path); $component = new $className(); $component->viewPath = array($config->get('site', 'components') . '/' . $name . '/'); $component->webPath = array($config->get('site', 'components.web') . '/' . $name); $component->COMPONENTS_WEB = $config->get('site', 'web') . '/components/'; } else { $component = new $className(); $template = $component->getTemplateName($site->config); $component->viewPath = array( // Сначало ищем локально $config->get('site', 'templates') . '/'. $template . '/_components/' . $name . '/', $config->get('site', 'components') . '/' . $name . '/', // Потом в общем хранилище $config->get('system', 'templates'). '/' . $template . '/_components/' . $name . '/', $config->get('system', 'components') . '/' . $name . '/', ); if (defined('COMPONENTS_WEB')) { $component->webPath = array( // Сначало локально $config->get('site', 'templates.web') . '/' . $template . '/_components/' . $name, $config->get('site', 'components.web') . '/' . $name, // Потом в общем хранилище $config->get('system', 'templates.web') . '/' . $template . '/_components/' . $name, $config->get('system', 'components.web') . '/' . $name, ); $component->COMPONENTS_WEB = $config->get('system', 'components.web'); } else { $component->webPath = array('', $config->get('site', 'components.web') . '/' . $name, ''); } } $db = $site->getDatabase(); $component->db = $db; $component->config = $site->config; $component->site = $site; $stmt = $db->prepareStatement("SELECT * FROM component WHERE code = ?"); $stmt->setString(1, $expression); $cid = $stmt->executeQuery(); if ($cid->next()) { $component->component_id = $cid->getInt('id_component'); } else { $last = $db->getIdGenerator(); $result = null; if ($last->isBeforeInsert()) { $result = $last->getId('component_id_component_seq'); $stmt = $db->prepareStatement("INSERT INTO component (id_component, code) VALUES ($result, ?)"); $stmt->setString(1, $expression); $stmt->executeQuery(); } if ($last->isAfterInsert()) { $stmt = $db->prepareStatement("INSERT INTO component (code) VALUES (?)"); $stmt->setString(1, $expression); $stmt->executeQuery(); $result = $last->getId('component_id_component_seq'); } $component->component_id = $result; } $params = new Collection(); $params->import(array_merge($_GET, $arguments)); $component->parameter = $params; $component->template = $params->get('template', false); $editor = $component->getEditUrl(); if ($editor) { $site->componentsConfig[] = $editor; } return $component; } function getEditUrl() { return null; } function raw_query($request/*: ComponentRequest*/) { $arr = $request->r->export('get'); $param = array(); $parameter/*: Collection*/ = $this->parameter; foreach($parameter->export() as $key => $value) { $param[$key] = $value; } $data = array(); foreach($arr as $key => $value) { if (is_array($value)) { $data[$key] = Arr::get($value, $this->component_id); } else { $data[$key] = $value; } } $data['param'] = $param; return $data; } function query($request/*: ComponentRequest*/, $list) { $arr = $request->r->export('get'); foreach($list as $key => $val) { $arr[$key] [$this->component_id] = $val; } unset($arr['active_page']); return '?' . http_build_query($arr); } function addRequireJsPath($name, $path, $shim = null) { $this->site->addRequireJsPath($name, $path, $shim); } function actionIndex($request/*: ComponentRequest*/) { } }