diff --git a/install/languages/en/base.sql b/install/languages/en/base.sql index c172dfa90..bd9d7faef 100755 --- a/install/languages/en/base.sql +++ b/install/languages/en/base.sql @@ -229,6 +229,7 @@ CREATE TABLE `{#}controllers` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `title` varchar(64) NOT NULL, `name` varchar(32) NOT NULL COMMENT 'System name', + `slug` varchar(64) DEFAULT NULL, `is_enabled` tinyint(1) unsigned DEFAULT '1' COMMENT 'Enabled?', `options` text COMMENT 'Settings array', `author` varchar(128) NOT NULL COMMENT 'Author name', @@ -239,9 +240,7 @@ CREATE TABLE `{#}controllers` ( `files` varchar(10000) DEFAULT NULL, `addon_id` int(11) UNSIGNED DEFAULT NULL, PRIMARY KEY (`id`), - KEY `name` (`name`), - KEY `enabled` (`is_enabled`), - KEY `is_backend` (`is_backend`) + KEY `name` (`name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Components'; INSERT INTO `{#}controllers` (`id`, `title`, `name`, `is_enabled`, `options`, `author`, `url`, `version`, `is_backend`) VALUES diff --git a/install/languages/ru/base.sql b/install/languages/ru/base.sql index eacc093f3..aefe4ecc4 100755 --- a/install/languages/ru/base.sql +++ b/install/languages/ru/base.sql @@ -229,6 +229,7 @@ CREATE TABLE `{#}controllers` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `title` varchar(64) NOT NULL, `name` varchar(32) NOT NULL COMMENT 'Системное имя', + `slug` varchar(64) DEFAULT NULL, `is_enabled` tinyint(1) unsigned DEFAULT '1' COMMENT 'Включен?', `options` text COMMENT 'Массив настроек', `author` varchar(128) NOT NULL COMMENT 'Имя автора', @@ -239,9 +240,7 @@ CREATE TABLE `{#}controllers` ( `files` varchar(10000) DEFAULT NULL COMMENT 'Список файлов контроллера (для стороних компонентов)', `addon_id` int(11) UNSIGNED DEFAULT NULL COMMENT 'ID дополнения в официальном каталоге', PRIMARY KEY (`id`), - KEY `name` (`name`), - KEY `enabled` (`is_enabled`), - KEY `is_backend` (`is_backend`) + KEY `name` (`name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Компоненты'; INSERT INTO `{#}controllers` (`id`, `title`, `name`, `is_enabled`, `options`, `author`, `url`, `version`, `is_backend`) VALUES diff --git a/install/steps/config.php b/install/steps/config.php index d743537aa..b472911d3 100755 --- a/install/steps/config.php +++ b/install/steps/config.php @@ -89,7 +89,8 @@ function create_config($path, $file){ 'allow_ips' => '', 'default_editor' => 'redactor', 'show_breadcrumbs' => 1, - 'check_spoofing_type' => 0 + 'check_spoofing_type' => 0, + 'controllers_without_widgets' => array('admin') ); write_config($file, $config); diff --git a/system/controllers/admin/frontend.php b/system/controllers/admin/frontend.php index c8899b435..2c39938bd 100755 --- a/system/controllers/admin/frontend.php +++ b/system/controllers/admin/frontend.php @@ -4,6 +4,8 @@ class admin extends cmsFrontend { const addons_api_key = '8e13cb202f8bdc27dc765e0448e50d11'; const addons_api_point = 'http://addons.instantcms.ru/api/method/'; + public $disallow_mapping_redirect = true; + protected $useOptions = true; const perpage = 30; @@ -275,7 +277,10 @@ public function loadControllerBackend($controller_name, $request){ $backend = new $controller_class($request); // Устанавливаем корень для URL внутри бакенда - $backend->setRootURL($this->name.'/controllers/edit/'.$controller_name); + $admin_controller_url = $this->name; + $controller_alias = cmsCore::getControllerAliasByName($admin_controller_url); + if ($controller_alias) { $admin_controller_url = $controller_alias; } + $backend->setRootURL($admin_controller_url.'/controllers/edit/'.$controller_name); return $backend; diff --git a/system/controllers/admin/grids/grid_controllers.php b/system/controllers/admin/grids/grid_controllers.php index b61405d04..100d721f5 100755 --- a/system/controllers/admin/grids/grid_controllers.php +++ b/system/controllers/admin/grids/grid_controllers.php @@ -20,6 +20,20 @@ function grid_controllers($controller){ return $item['is_backend']; } ), + 'slug' => array( + 'title' => LANG_ADMIN_CONTROLLER_SLUG, + 'width' => 300, + 'editable' => array( + 'table' => 'controllers', + 'attributes' => array('placeholder' => '{name}') + ), + 'handler' => function ($v, $row){ + if(!$v){ + return $row['name']; + } + return $v; + } + ), 'is_enabled' => array( 'title' => LANG_IS_ENABLED, 'flag' => true, diff --git a/system/controllers/content/actions/item_add.php b/system/controllers/content/actions/item_add.php index 0235426ff..65842b4c1 100755 --- a/system/controllers/content/actions/item_add.php +++ b/system/controllers/content/actions/item_add.php @@ -169,7 +169,8 @@ public function run(){ } $item['ctype_name'] = $ctype['name']; - $item['ctype_id'] = $ctype['id']; + $item['ctype_id'] = $ctype['id']; + $item['ctype_data'] = $ctype; if ($is_submitted){ diff --git a/system/controllers/content/actions/item_edit.php b/system/controllers/content/actions/item_edit.php index 6d201957d..16e1876c0 100755 --- a/system/controllers/content/actions/item_edit.php +++ b/system/controllers/content/actions/item_edit.php @@ -18,6 +18,7 @@ public function run(){ if (!$item) { cmsCore::error404(); } $item['ctype_id'] = $ctype['id']; + $item['ctype_name'] = $ctype['name']; // проверяем наличие доступа if (!cmsUser::isAllowed($ctype['name'], 'edit')) { cmsCore::error404(); } @@ -94,9 +95,6 @@ public function run(){ // Форма отправлена? $is_submitted = $this->request->has('submit'); - $item['ctype_name'] = $ctype['name']; - $item['ctype_id'] = $ctype['id']; - if ($ctype['props']){ $category_id = !$is_submitted ? $item['category_id'] : @@ -144,9 +142,6 @@ public function run(){ if (!$errors){ - unset($item['ctype_name']); - unset($item['ctype_id']); - $item['is_approved'] = $item['is_approved'] && (!$ctype['is_premod_edit'] || $is_moderator); $item['approved_by'] = null; diff --git a/system/controllers/content/widgets/slider/options.form.php b/system/controllers/content/widgets/slider/options.form.php index fa6c01a7f..cd2cad36a 100755 --- a/system/controllers/content/widgets/slider/options.form.php +++ b/system/controllers/content/widgets/slider/options.form.php @@ -140,4 +140,4 @@ public function init($options=false) { } -} \ No newline at end of file +} diff --git a/system/controllers/images/model.php b/system/controllers/images/model.php index c2e27a401..4032a9296 100755 --- a/system/controllers/images/model.php +++ b/system/controllers/images/model.php @@ -18,7 +18,7 @@ public function getPresetsList($with_params = false){ orderBy('width')-> get('images_presets', function($item, $model) use($with_params){ if($with_params){ - return $item['title'].', '.$item['name'].', '.($item['width'] ? $item['width'] : LANG_AUTO).'X'.($item['height'] ? $item['height'] : LANG_AUTO).'px'; + return $item['title'].' ('.$item['name'].', '.($item['width'] ? $item['width'] : LANG_AUTO).' x '.($item['height'] ? $item['height'] : LANG_AUTO).')'; } return $item['title']; }, 'name'); diff --git a/system/core/config.php b/system/core/config.php index c732220c8..2fc52c3db 100755 --- a/system/core/config.php +++ b/system/core/config.php @@ -29,13 +29,13 @@ public static function getControllersMapping(){ $map_file = 'system/config/remap.php'; $map_function = 'remap_controllers'; - if (!cmsCore::includeFile($map_file)) { return false; } + if (!cmsCore::includeFile($map_file)) { return self::$mapping; } - if (!function_exists($map_function)){ return false; } + if (!function_exists($map_function)){ return self::$mapping; } self::$mapping = call_user_func($map_function); - if (!is_array(self::$mapping)){ return false; } + if (!is_array(self::$mapping)){ return array(); } return self::$mapping; @@ -95,6 +95,10 @@ public function setData($cfg_file = 'config.php') { $this->data['detect_ip_key'] = 'REMOTE_ADDR'; } + if(!isset($this->data['controllers_without_widgets'])){ + $this->data['controllers_without_widgets'] = array('admin'); + } + $this->upload_host_abs = $this->upload_host; if (mb_strpos($this->upload_host, $this->host) === 0){ diff --git a/system/core/controller.php b/system/core/controller.php index b2196799a..166307a28 100755 --- a/system/core/controller.php +++ b/system/core/controller.php @@ -2,6 +2,7 @@ class cmsController { private static $controllers; + private static $mapping; public $name; public $title; @@ -13,6 +14,14 @@ class cmsController { public $root_url; public $root_path; + /** + * Если для контроллера задан ремап + * и это свойство установлено в true + * редиректа со старого адреса не будет + * + * @var boolean + */ + public $disallow_mapping_redirect = false; /** * Флаг, что контроллер должен работать только после * регистрации в БД @@ -164,6 +173,10 @@ public function isControllerInstalled($name) { return isset(self::$controllers[$name]); } + public function hasSlug() { + return !empty(self::$controllers[$this->name]['slug']) ? self::$controllers[$this->name]['slug'] : false; + } + public function isControllerEnabled($name) { // проверяем только те, которые зарегистрированы в базе @@ -183,6 +196,24 @@ public static function enabled($name) { return true; } + public static function getControllersMapping() { + + if (self::$mapping !== null) { return self::$mapping; } + + self::$mapping = array(); + + self::loadControllers(); + + foreach (self::$controllers as $controller) { + if($controller['slug']){ + self::$mapping[$controller['name']] = $controller['slug']; + } + } + + return self::$mapping; + + } + private static function loadControllers() { if(!isset(self::$controllers)){ @@ -193,7 +224,8 @@ private static function loadControllers() { 'i.id' => 'id', 'i.is_enabled' => 'is_enabled', 'i.options' => 'options', - 'i.name' => 'name' + 'i.name' => 'name', + 'i.slug' => 'slug' ), true); self::$controllers = $model->useCache('controllers')->get('controllers', function ($item, $model) { @@ -767,16 +799,16 @@ public function redirectToHome(){ * @param array $params * @param array $query */ - public function redirectTo($controller, $action='', $params=array(), $query=array()){ + public function redirectTo($controller, $action='', $params=array(), $query=array(), $code=303){ $href_lang = cmsCore::getLanguageHrefPrefix(); - $location = $this->cms_config->root .($href_lang ? $href_lang.'/' : ''). $controller . '/' . $action; + $location = $this->cms_config->root .($href_lang ? $href_lang.'/' : ''). $controller . ($action ? '/'.$action : ''); if ($params){ $location .= '/' . implode('/', $params); } - if ($query){ $location .= '?' . http_build_query($query); } + if ($query){ $location .= '?' . http_build_query($query, '', '&'); } - $this->redirect($location); + $this->redirect($location, $code); } diff --git a/system/core/core.php b/system/core/core.php index 2beccdcc0..3292b6e16 100755 --- a/system/core/core.php +++ b/system/core/core.php @@ -348,8 +348,10 @@ public static function getController($controller_name, $request=null){ public static function getControllerNameByAlias($controller_alias){ - $mapping = cmsConfig::getControllersMapping(); + $config_mapping = cmsConfig::getControllersMapping(); + $controllers_mapping = cmsController::getControllersMapping(); + $mapping = array_merge($controllers_mapping, $config_mapping); if (!$mapping) { return false; } foreach($mapping as $name=>$alias){ @@ -364,9 +366,13 @@ public static function getControllerAliasByName($controller_name){ $mapping = cmsConfig::getControllersMapping(); - if (!$mapping || !isset($mapping[$controller_name])){ return false; } + if (!empty($mapping[$controller_name])){ return $mapping[$controller_name]; } + + $cmapping = cmsController::getControllersMapping(); + + if (!empty($cmapping[$controller_name])){ return $cmapping[$controller_name]; } - return $mapping[$controller_name]; + return false; } @@ -654,7 +660,18 @@ public function runController(){ // контроллер включен? if(!$controller->isEnabled()){ - self::error404(); + return self::error404(); + } + + // редирект 301, если настроен ремап + if(!$remap_to && $slug = $controller->hasSlug()){ + + // если контроллер запрещает редирект, то 404 + if($controller->disallow_mapping_redirect){ + return self::error404(); + } + + $controller->redirectTo($slug, $this->uri_action, $this->uri_params, $this->uri_query, 301); } // сохраняем в контроллере название текущего экшена @@ -701,8 +718,9 @@ public function setMatchedPages($matched_pages) { */ public function runWidgets(){ - // в админке нам виджеты не нужны - if ($this->controller == 'admin') { return; } + $controllers_without_widgets = cmsConfig::get('controllers_without_widgets'); + + if ($controllers_without_widgets && in_array($this->controller, $controllers_without_widgets)) { return; } $matched_pages = $this->loadMatchedPages()->getMatchedPages(); if (!$matched_pages) { return; } diff --git a/system/core/template.php b/system/core/template.php index 44ce0c8c1..e96609b55 100755 --- a/system/core/template.php +++ b/system/core/template.php @@ -17,6 +17,8 @@ class cmsTemplate { protected $head_css = array(); protected $head_main_js = array(); protected $head_js = array(); + protected $insert_js = array(); + protected $insert_css = array(); protected $head_js_no_merge = array(); protected $head_css_no_merge = array(); protected $title; @@ -831,18 +833,30 @@ public function addControllerCSS($path, $cname = '', $allow_merge = true){ public function insertJS($file, $comment=''){ + $hash = md5($file); + if (isset($this->insert_js[$hash])) { return false; } + $this->insert_js[$hash] = $file; + $file = (strpos($file, '://') !== false) ? $file : $this->site_config->root . $file; $comment = $comment ? "" : ''; // атрибут rel="forceLoad" добавлен для nyroModal echo ''; + return true; + } public function insertCSS($file){ + $hash = md5($file); + if (isset($this->insert_css[$hash])) { return false; } + $this->insert_css[$hash] = $file; + $file = (strpos($file, '://') !== false) ? $file : $this->site_config->root . $file; echo ''; + return true; + } /** @@ -1499,9 +1513,19 @@ public function renderGridRowsJSON($grid, $dataset, $total=1, $pages_count=1){ if(!empty($column['editable']['save_action'])){ $save_action = string_replace_keys_values($column['editable']['save_action'], $row); } + $attributes = array(); + if(!empty($column['editable']['attributes'])){ + foreach ($column['editable']['attributes'] as $akey => $avalue) { + if(is_string($avalue)){ + $attributes[$akey] = string_replace_keys_values($avalue, $row); + } else { + $attributes[$akey] = $avalue; + } + } + } if(!empty($save_action)){ $value = '