Вход Регистрация
Файл: system/core/core.php
Строк: 1038
<?php

class cmsCore {

    private static 
$instance;

    public 
$uri            '';
    public 
$uri_before_remap '';
    public 
$uri_absolute   '';
    public 
$uri_controller '';
    public 
$uri_controller_before_remap '';
    public 
$uri_action     '';
    public 
$uri_params     = [];
    public 
$uri_query      = [];
    private 
$matched_pages null;
    private 
$widgets_pages null;

    private static 
$language 'ru';
    private static 
$language_href_prefix '';
    private static 
$core_version null;
    private static 
$controllers_instance = [];
    private static 
$templates null;

    public 
$controller '';
    private 
$defined_controllers = [];

    public 
$link;
    public 
$request;

    public 
$db;

    private static 
$includedFiles = [];

    public static function 
getInstance() {
        if (
self::$instance === null) {
            
self::$instance = new self;
        }
        return 
self::$instance;
    }

    public function 
__construct(){

        
$this->request = new cmsRequest($_REQUEST);

        
self::detectLanguage();

    }

    
/*
     * deprecated, use cmsDebugging
     */
    
private static $start_time;
    public static function 
startTimer() {
        
self::$start_time microtime(true);
    }
    public static function 
getTime() {
        return 
microtime(true) - self::$start_time;
    }

//============================================================================//
//============================================================================//

    
private static function detectLanguage() {

        
$config cmsConfig::getInstance();

        
self::$language $config->language;

        if(!empty(
$_SERVER['REQUEST_URI']) && !empty($config->is_user_change_lang)){

            
$segments explode('/'mb_substr($_SERVER['REQUEST_URI'], mb_strlen($config->root)));

            
// язык может быть только двухбуквенный, определяем его по первому сегменту
            
if (!empty($segments[0]) && preg_match('/^[a-z]{2}$/i'$segments[0])) {
                if(
is_dir($config->root_path.'system/languages/'.$segments[0].'/')){
                    
// язык по умолчанию без префиксов, дубли нам не нужны
                    
if($segments[0] != $config->language){

                        
// включаем для моделей поддержку
                        
cmsModel::globalLocalizedOn();

                        
self::$language self::$language_href_prefix $segments[0]; unset($segments[0]);

                        
$_SERVER['REQUEST_URI'] = $config->root.implode('/'$segments);

                    }
                }
            }

        }

    }

    public static function 
getLanguageHrefPrefix() {
        return 
self::$language_href_prefix;
    }

    public static function 
getLanguageName() {
        return 
self::$language;
    }

    public static function 
changeLanguage($new_lang){
        
self::$language $new_lang;
    }

//============================================================================//
//============================================================================//

    /**
     * Возвращает информацию о версии CMS
     * в виде строки
     * @param boolean $show_date Показывать дату версии
     * @return string
     */
    
public static function getVersion($show_date false){

        
$version self::getVersionArray();

        if (!
$show_date && isset($version['date'])) { unset($version['date']); }

        return 
$version['version'].($show_date ' '.LANG_FROM.' '.$version['date'] : '');

    }

    
/**
     * Возвращает информацию о версии CMS
     * в виде массива с ключами:
     *  - date Дата релиза
     *  - version Полная версия CMS
     *  - raw
     *  -- major
     *  -- minor
     *  -- build
     *  -- date
     * @return array
     */
    
public static function getVersionArray(){

        if(
self::$core_version === null){

            
$file cmsConfig::get('root_path') . 'system/config/version.ini';
            if (!
is_readable($file)){ die('system/config/version.ini not found'); }

            
$version parse_ini_file($file);

            
self::$core_version = array(
                
'date'    => $version['date'],
                
'version' => $version['major'] .'.'$version['minor'] .'.'$version['build'],
                
'raw'     => $version
            
);

        }

        return 
self::$core_version;

    }

//============================================================================//
//============================================================================//

    
public static function isWritable($path$is_force_mkdir=true) {

        if (
$is_force_mkdir && (!file_exists($path))) { @mkdir($path); }

        return (
is_writable($path));

    }

//============================================================================//
//============================================================================//

    /**
     * Подключает файл
     * @param string $file Путь относительно корня сайта без начального слеша
     * @return mixed
     */
    
public static function includeFile($file) {

        
$file cmsConfig::get('root_path') . $file;

        if (isset(
self::$includedFiles[$file])) {
            return 
self::$includedFiles[$file];
        }

        if (!
is_readable($file)) {
            
self::$includedFiles[$file] = false;
            return 
false;
        }

        
$result = include_once $file;

        if (
is_null($result)) {
            
$result true;
        }

        
self::$includedFiles[$file] = $result;

        return 
$result;
    }

    public static function 
requireFile($file) {

        
$file cmsConfig::get('root_path') . $file;

        if (!
is_readable($file)) {
            return 
false;
        }

        
$result = require $file;

        if (
is_null($result)) {
            
$result true;
        }

        return 
$result;
    }

    public static function 
includeAndCall($file$function_name$params = []) {

        if (!
self::includeFile($file)) {
            return 
false;
        }

        if (!
function_exists($function_name)) {
            return 
false;
        }

        return 
call_user_func_array($function_name$params);
    }

//============================================================================//
//============================================================================//

    /**
     * Загружает внешнюю библиотеку из папки /system/libs
     *
     * @param string $library Название библиотеки в /system/libs (без расширения)
     * @param string $class Название загружаемого класса (для предотвращения повторной загрузки)
     */
     
public static function loadLib($library$class=false){

        if (
$class && class_exists($classfalse)){ return true; }

        
$lib_file cmsConfig::get('root_path').'system/libs/'.$library.'.php';

        if (!
is_readable($lib_file)){ self::error(ERR_LIBRARY_NOT_FOUND ': '$library); }

        include_once 
$lib_file;

        return 
true;

    }

//============================================================================//
//============================================================================//

    /**
     * Загружает класс ядра из папки /system/core
     * @param string $class
     */
    
public static function loadCoreClass($class){

        
$class_file cmsConfig::get('root_path') . 'system/core/'.$class.'.class.php';

        if (!
is_readable($class_file)){
            
self::error(ERR_CLASS_NOT_FOUND ': '$class);
        }

        include_once 
$class_file;

        return 
true;

    }

//============================================================================//
//============================================================================//

    /**
     * Проверяет существование модели
     * @param str $controller Название контроллера
     * @return bool
     */
    
public static function isModelExists($controller){

        
$model_file cmsConfig::get('root_path').'system/controllers/'.$controller.'/model.php';

        return 
file_exists($model_file);

    }

    
/**
     * Возвращает объект модели из указанного файла (без расширения)
     * @param string $controller Контроллер модели
     * @param string $delimitter Разделитель слов в названии класса
     */
    
public static function getModel($controller$delimitter='_'){

        if(
is_array($controller)){
            
$controller end($controller);
        }

        
$model_class 'model' string_to_camel($delimitter$controller);

        try {
            
$model = new $model_class();
        } catch (
Exception $e) {
            
self::error(ERR_MODEL_NOT_FOUND ': '.$e->getMessage());
        } finally {
            return isset(
$model) ? $model null;
        }
    }

    
/**
     * @deprecated
     *
     * С версии 2.14.0 работает в autoLoad
     * Инклюдит файл модели контроллера (контроллеров)
     * @param string $controllers Контроллер модели или массив контроллеров
     * @param boolean $quiet
     * @return boolean
     */
    
public static function includeModel($controllers$quiet false) {
        return 
true;
    }


//============================================================================//
//============================================================================//

    /**
     * Проверяет существования контроллера
     * @param string $controller_name
     * @return bool
     */
    
public static function isControllerExists($controller_name){
        return 
is_dir(cmsConfig::get('root_path').'system/controllers/'.$controller_name);
    }

    
/**
     * Создает и возвращает объект контроллера
     * @param string $controller_name
     * @param cmsRequest $request
     * @return controller_class
     */
    
public static function getController($controller_name$request null){

        if (!
$request) { $request = new cmsRequest([], cmsRequest::CTX_INTERNAL); }

        
$config cmsConfig::getInstance();

        
$ctrl_file $config->root_path 'system/controllers/'.$controller_name.'/frontend.php';

        if (!
class_exists($controller_namefalse)) {
            if(!
is_readable($ctrl_file)){
                if(
$request->isStandard()){
                    return 
self::error404();
                }
                return 
self::error(ERR_COMPONENT_NOT_FOUND ': 'str_replace($config->root_path''$ctrl_file));
            }
            include_once(
$ctrl_file);
        }

        
$custom_file $config->root_path 'system/controllers/'.$controller_name.'/custom.php';

        if(!
is_readable($custom_file)){
            
$controller_class $controller_name;
        } else {
            
$controller_class $controller_name '_custom';
            if (!
class_exists($controller_classfalse)){
                include_once(
$custom_file);
            }
        }

        if (!
class_exists($controller_classfalse)) {
            return 
self::error(ERR_COMPONENT_NOT_FOUND ': 'str_replace($config->root_path''$ctrl_file));
        }

        return new 
$controller_class($request);
    }

    public static function 
getControllerInstance($controller_name$request=null){

        if(!isset(
self::$controllers_instance[$controller_name])){

            
self::$controllers_instance[$controller_name] = self::getController($controller_name$request);

        }

        return 
self::$controllers_instance[$controller_name];

    }

    public static function 
getControllerNameByAlias($controller_alias){

        
$config_mapping      cmsConfig::getControllersMapping();
        
$controllers_mapping cmsController::getControllersMapping();

        
$mapping array_merge($controllers_mapping$config_mapping);
        if (!
$mapping) { return false; }

        foreach(
$mapping as $name=>$alias){
            if (
$alias == $controller_alias) { return $name; }
        }

        return 
false;

    }

    public static function 
getControllerAliasByName($controller_name){

        if(!
$controller_name){ return false; }

        
$mapping cmsConfig::getControllersMapping();

        if (!empty(
$mapping[$controller_name])){ return $mapping[$controller_name]; }

        
$cmapping cmsController::getControllersMapping();

        if (!empty(
$cmapping[$controller_name])){ return $cmapping[$controller_name]; }

        return 
false;

    }

    
/**
     * Возвращает массив хуков контроллеров
     * @param boolean $is_debug Если передано true, то массив формируется из файлов манифестов, иначе - из БД
     * @param boolean $is_enabled
     * @return array
     */
    
public static function getControllersManifests($is_debug false$is_enabled true){

        if (
$is_debug){
            return 
self::getManifestsEvents();
        }

        
$events = [];

        
$db cmsDatabase::getInstance();

        if(!
$db->ready()){
            return 
$events;
        }

        if(
$is_enabled){
            
$controllers_events $db->getRows('events FORCE INDEX (is_enabled)''`is_enabled` = 1''*''ordering ASC'true);
        } else {
            
$controllers_events $db->getRows('events''1''*''ordering ASC'true);
        }

        if(
$controllers_events){
            foreach(
$controllers_events as $event){
                
// для сохранения сортировки + совместимость
                
if(!isset($events$event['listener'] ][$event['ordering']])){
                    
$events$event['listener'] ][$event['ordering']] = $event['event'];
                } else {
                    
// если вдруг по какой-то причине порядок одинаковый
                    
$events$event['listener'] ][intval($event['ordering'].'00'.$event['id'])] = $event['event'];
                }
            }
        }

        return 
$events;

    }

    
/**
     * Возвращает массив хуков контроллеров
     * из файлов манифестов
     * @return array
     */
    
public static function getManifestsEvents(){

        
$manifests_events = [];

        
$controllers cmsCore::getDirsList('system/controllers'true);

        
$index 0;

        foreach(
$controllers as $controller_name){

            
$manifest_file cmsConfig::get('root_path') . 'system/controllers/' $controller_name '/manifest.php';

            if (!
is_readable($manifest_file)){ continue; }

            
$manifest = include $manifest_file;

            if (empty(
$manifest['hooks']) || !is_array($manifest['hooks'])) { continue; }

            foreach (
$manifest['hooks'] as $hook) {

                
$manifests_events$controller_name ][$index] = $hook;

                
$index++;

            }

        }

        return 
$manifests_events;

    }

//============================================================================//
//============================================================================//

    
public static function getWidgetPath($widget_name$controller_name=false){

        if (
$controller_name){
            
$path "controllers/{$controller_name}/widgets/{$widget_name}";
        } else {
            
$path "widgets/{$widget_name}";
        }

        return 
$path;

    }

//============================================================================//
//============================================================================//

    /**
     * Подключает указанный языковой файл.
     * Если файл не указан, то подключаются все PHP-файлы из папки текущего языка
     *
     * @param string $file Относительный путь к файлу
     * @param string $default Язык по умолчанию, если в текущем не найдено
     * @return boolean
     */
    
public static function loadLanguage($file false$default 'ru') {

        
$lang_dir 'system/languages/'self::$language;

        if (!
$file){

            
// Если файл не указан, то подключаем все php-файлы
            // из папки с текущим языком
            
return self::getFilesList($lang_dir'*.php'truetrue);

        } else {

            
// Если файл указан, то подключаем только его
            
$lang_file $lang_dir .'/'.$file.'.php';

            
$result self::includeFile($lang_file);

            if(!
$result && $default !== self::$language){
                
$result self::includeFile('system/languages/'$default .'/'.$file.'.php');
            }

            return 
$result;

        }

    }

    
/**
     * Возвращает содержимое текстового файла из папки с текущим языком
     * @param string $file
     * @return string
     */
    
public static function getLanguageTextFile($file){

        
$lang_dir cmsConfig::get('root_path').'system/languages/'.self::$language;

        
$lang_file $lang_dir .'/' $file '.txt';

        if (!
file_exists($lang_file)) { return false; }

        return 
file_get_contents($lang_file);

    }

    
/**
     * Подключает языковой файл контроллера
     * @param string $controller_name
     * @return bool
     */
    
public static function loadControllerLanguage($controller_name){
        return 
self::loadLanguage("controllers/{$controller_name}/{$controller_name}");
    }

    
/**
     * Подключает языковой файл виджета
     * @param string $widget_name
     * @param string $controller_name
     * @return bool
     */
    
public static function loadWidgetLanguage($widget_name$controller_name=false){

        
$path self::getWidgetPath($widget_name$controller_name);

        return 
self::loadLanguage($path);

    }

    
/**
     * Подключает языковой файл шаблона
     * @param string|array $template_name
     * @return bool
     */
    
public static function loadTemplateLanguage($template_names){
        if(!
is_array($template_names)){
            
$template_names = [$template_names];
        }
        
$result false;
        foreach (
$template_names as $template_name) {
            
$result self::loadLanguage("templates/{$template_name}");
            if(
$result){
                break;
            }
        }
        return 
$result;
    }

    
/**
     * Подключает языковые файлы всех контроллеров
     *
     * @param string $file
     * @return bool
     */
    
public static function loadAllControllersLanguages(){

        
$controllers self::getDirsList('system/controllers');

        foreach(
$controllers as $controller_name){
            
self::loadControllerLanguage($controller_name);
        }

    }

//============================================================================//
//============================================================================//

    /**
     * Определяет контроллер, действие и параметры для запуска по полученному URI
     * @param string $uri
     */
    
public function route($uri){

        
$config cmsConfig::getInstance();

        
$uri trim(urldecode($uri));
        
$uri mb_substr($urimb_strlen$config->root ));

        if (!
$uri) { return; }

        
// если в URL присутствует знак вопроса, значит есть
        // в нем есть GET-параметры которые нужно распарсить
        // и добавить в массив $_REQUEST
        
$pos_que  mb_strpos($uri'?');
        if (
$pos_que !== false){

            
// получаем строку запроса
            
$query_data = [];
            
$query_str  mb_substr($uri$pos_que+1);

            
// удаляем строку запроса из URL
            
$uri mb_substr($uri0$pos_que);

            
// парсим строку запроса
            
parse_str($query_str$query_data);

            
$this->uri_query $query_data;

            
// добавляем к полученным данным $_REQUEST
            // именно в таком порядке, чтобы POST имел преимущество над GET
            
$_REQUEST array_merge($query_data$_REQUEST);

        }

        
$this->uri $this->uri_before_remap $uri;
        
$this->uri_absolute $config->root $uri;

        
// разбиваем URL на сегменты
        
$segments explode('/'$uri);

        
// Определяем контроллер из первого сегмента
        
if (isset($segments[0])) { $this->uri_controller $segments[0]; }

        
// Определяем действие из второго сегмента
        
if (isset($segments[1])) { $this->uri_action $segments[1]; }

        
// Определяем параметры действия из всех остальных сегментов
        
if (sizeof($segments)>2){
            
$this->uri_params array_slice($segments2);
        }

        return 
true;

    }

    public function 
getUriData() {
        return array(
            
'controller' => $this->uri_controller,
            
'action'     => $this->uri_action,
            
'params'     => $this->uri_params
        
);
    }

//============================================================================//
//============================================================================//

    
public function defineController() {

        
$hash md5($this->uri_controller.$this->uri_action);

        if(isset(
$this->defined_controllers[$hash])){
            return 
$this;
        }

        
$this->defined_controllers[$hash] = true;

        
$config cmsConfig::getInstance();

        
// контроллер и экшен по умолчанию
        
if (!$this->uri_controller){ $this->uri_controller $config->ct_autoload;    }
        if (!
$this->uri_action) { $this->uri_action 'index'; }

        
// проверяем ремаппинг контроллера
        
$remap_to self::getControllerNameByAlias($this->uri_controller);
        if (
$remap_to) {
            
// в uri также меняем
            
if($this->uri){
                
$seg explode('/'$this->uri);
                
$seg[0] = $remap_to;
                
$this->uri implode('/'$seg);
                
$this->uri_absolute str_replace($this->uri_before_remap$this->uri$this->uri_absolute);
            }
            
$this->uri_controller_before_remap $this->uri_controller;
            
$this->uri_controller $remap_to;
        }

        if (!
self::isControllerExists($this->uri_controller)) {
            if(
$this->uri_action !== 'index'){
                
array_unshift($this->uri_params$this->uri_action);
            }
            
$this->uri_action     $this->uri_controller;
            
$this->uri_controller $config->ct_default;
        }

        
$this->controller $this->uri_controller;

        return 
$this;

    }

    
/**
     * Запускает выбранное действие контроллера
     */
    
public function runController(){

        
$this->defineController();

        if (!
preg_match('/^[a-z]{1}[a-z0-9_]*$/'$this->controller)){
            
self::error404();
        }

        
// загружаем контроллер
        
$controller self::getController($this->controller$this->request);

        
// контроллер включен?
        
if(!$controller->isEnabled()){
            return 
self::error404();
        }

        
// редирект 301, если настроен ремап
        
if(!$this->uri_controller_before_remap && $slug $controller->hasSlug()){

            
// если контроллер запрещает редирект, то 404
            
if($controller->disallow_mapping_redirect){
                return 
self::error404();
            }

            
$controller->redirectTo($slug, ($this->uri_action === 'index' '' $this->uri_action), $this->uri_params$this->uri_query301);
        }

        
// запускаем действие
        
$controller->runAction($this->uri_action$this->uri_params);

    }

    
/**
     * Определяет и загружает id страниц, которые определены для текущего uri
     * @return cmsCore
     */
    
public function loadMatchedPages() {

        if (
$this->matched_pages !== null) {
            return 
$this;
        }

        if (
$this->widgets_pages === null) {
            
$this->widgets_pages cmsCore::getModel('widgets')->getPages();
        }

        
$this->matched_pages $this->detectMatchedWidgetPages($this->widgets_pages);

        return 
$this;
    }

    public function 
getWidgetsPages() {
        return 
$this->widgets_pages;
    }

    public function 
getMatchedPagesIds() {
        return 
$this->matched_pages array_keys($this->matched_pages) : [];
    }

    public function 
getMatchedPages() {
        return 
$this->matched_pages;
    }

    public function 
setMatchedPages($matched_pages) {
        
$this->matched_pages $matched_pages;
        return 
$this;
    }

//============================================================================//
//============================================================================//

    /**
     * Запускает все виджеты, привязанные к текущей странице
     */
    
public function runWidgets() {

        
$template cmsTemplate::getInstance();

        if (
$template->widgets_rendered) {
            return 
$this;
        }

        
$template->widgets_rendered true;

        
$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; }

        
$widgets_list cmsCore::getModel('widgets')->getWidgetsForPages(array_keys($matched_pages), $template->getName());

        if (
is_array($widgets_list)) {

            
$device_type cmsRequest::getDeviceType();
            
$layout $template->getLayout();
            
$user cmsUser::getInstance();

            if (
$user->is_admin) {
                
cmsCore::loadControllerLanguage('admin');
            }

            foreach (
$widgets_list as $widget) {

                
// не выводим виджеты контроллеров, которые отключены
                
if (!empty($widget['controller']) && !cmsController::enabled($widget['controller'])) {
                    continue;
                }

                
// проверяем доступ для виджетов
                
if (!$user->isInGroups($widget['groups_view'])) {
                    continue;
                }
                if (!empty(
$widget['groups_hide']) && $user->isInGroups($widget['groups_hide']) && !$user->is_admin) {
                    continue;
                }

                
// проверяем для каких устройств показывать
                
if ($widget['device_types'] && !in_array($device_type$widget['device_types'])) {
                    continue;
                }

                
// проверяем для каких макетов показывать
                
if ($widget['template_layouts'] && !in_array($layout$widget['template_layouts'])) {
                    continue;
                }

                
// проверяем для каких языков показывать
                
if ($widget['languages'] && !in_array(cmsCore::getLanguageName(), $widget['languages'])) {
                    continue;
                }

                
cmsDebugging::pointStart('widgets');

                
$this->runWidget($widget);

                
cmsDebugging::pointProcess('widgets', function () use($widget) {
                    return [
                        
'data' => $widget['title'] . ' => /system/' cmsCore::getWidgetPath($widget['name'], $widget['controller']) . '/widget.php',
                        
'context' => [
                            
'target' => $widget['controller'],
                            
'subject' => $widget['name']
                        ]
                    ];
                }, 
0);
            }
        }

        return 
$this;
    }

    public static function 
getWidgetObject($widget) {

        
$file 'system/'.cmsCore::getWidgetPath($widget['name'], $widget['controller']).'/widget.php';

        
$class 'widget' .
                    (
$widget['controller'] ? string_to_camel('_'$widget['controller']) : '') .
                    
string_to_camel('_'$widget['name']);

        if (!
class_exists($classfalse)) {
            
cmsCore::includeFile($file);
            
cmsCore::loadWidgetLanguage($widget['name'], $widget['controller']);
        }

        return new 
$class($widget);

    }

    public function 
runWidget($widget){

        
$result false;

        
$widget_object cmsCore::getWidgetObject($widget);

        
$cache_key 'widgets'.$widget['id'];
        
$cache cmsCache::getInstance();

        if(
$widget_object->isCacheable()){
            
$result $cache->get($cache_key);
        }

        if (
$result === false){
            
$result call_user_func_array(array($widget_object'run'), []);
            if (
$result !== false){
                
// Отдельно кешируем имя шаблона виджета, заголовок и враппер, поскольку они могли быть
                // изменены внутри виджета, а в кеш у нас попадает только тот массив
                // который возвращается кодом виджета (без самих свойств $widget_object)
                
$result['_wd_template'] = $widget_object->getTemplate();
                
$result['_wd_title']    = $widget_object->title;
                
$result['_wd_wrapper']  = $widget_object->getWrapper();
            }
            if(
$widget_object->isCacheable()){
                
$cache->set($cache_key$result);
            }
        }

        if (
$result === false) { return false; }

        if (isset(
$result['_wd_template'])) { $widget_object->setTemplate($result['_wd_template']); }
        if (isset(
$result['_wd_title'])) { $widget_object->title $result['_wd_title']; }
        if (isset(
$result['_wd_wrapper'])) { $widget_object->setWrapper($result['_wd_wrapper']); }

        return 
cmsTemplate::getInstance()->renderWidget($widget_object$result);

    }

    
/**
     * Определяет какие из списка страниц виджетов
     * совпадают по маске с текущей страницей
     *
     * @param array $pages
     * @param string $uri
     * @return array
     */
    
public function detectMatchedWidgetPages($pages$uri null) {

        if(
$uri === null){
            
$uri $this->uri;
            
$uri_query $this->uri_query;
        }

        if (
$uri === '') {
            return [
01];
        }

        
$matched_pages = [];

        
$_full_uri $uri . (!empty($uri_query) ? '?' http_build_query($uri_query) : '');

        
//
        // Перебираем все точки привязок и проверяем совпадение
        // маски URL с текущим URL
        //
        
foreach ($pages as $page) {

            if (empty(
$page['url_mask']) && !empty($page['id'])) {
                continue;
            }

            
$is_mask_match = empty($page['id']);
            
$is_stop_match false;

            if (!empty(
$page['url_mask'])) {
                foreach (
$page['url_mask'] as $mask) {
                    
$regular       string_mask_to_regular($mask);
                    
$regular       "/^{$regular}$/iu";
                    
$is_mask_match $is_mask_match || preg_match($regular$uri);
                }
            }

            if (!empty(
$page['url_mask_not'])) {
                foreach (
$page['url_mask_not'] as $mask) {
                    
$regular       string_mask_to_regular($mask);
                    
$regular       "/^{$regular}$/iu";
                    
$is_stop_match $is_stop_match || preg_match($regular$_full_uri);
                }
            }

            if (
$is_mask_match && !$is_stop_match) {
                
$matched_pages[$page['id']] = $page;
            }
        }

        return 
$matched_pages;
    }

//============================================================================//
//============================================================================//

    /**
     * Показывает сообщение об ошибке и завершает работу
     * @param string $message
     * @param string $details
     */
    
public static function error($message$details '') {

        if(
ob_get_length()) { ob_end_clean(); }

        
http_response_code(503);

        
$is_debug cmsConfig::get('debug');

        if(!
$is_debug){
            
$message LANG_ERROR_503;
            
$details LANG_ERROR_503_HINT;
        }

        
ob_start();

        
cmsTemplate::getInstance()->renderAsset('errors/error', [
            
'is_debug' => $is_debug,
            
'message'  => $message,
            
'details'  => $details
        
], self::getInstance()->request);

        
$html ob_get_clean();

        die(
cmsConfig::get('min_html') ? html_minify($html) : $html);
    }

    
/**
     * Показывает сообщение об ошибке 403 и завершает работу
     * @param string $message Текстовое сообщение к ошибке
     * @param boolean $show_login_link Показывать ссылку на авторизацию
     * @return die
     */
    
public static function errorForbidden($message ''$show_login_link false){

        
$result cmsEventsManager::hook('error_403'self::getInstance()->uri);

        if(
$result === true){ return false; }

        if(
ob_get_length()) { ob_end_clean(); }

        
http_response_code(403);

        
ob_start();

        
cmsTemplate::getInstance()->renderAsset('errors/forbidden', [
            
'message'         => $message,
            
'show_login_link' => $show_login_link
        
]);

        
$html ob_get_clean();

        die(
cmsConfig::get('min_html') ? html_minify($html) : $html);
    }

    
/**
     * Показывает сообщение об ошибке 404 и завершает работу
     */
    
public static function error404(){

        
$result cmsEventsManager::hook('error_404'self::getInstance()->uri);

        if(
$result === true){ return false; }

        if(
ob_get_length()) { ob_end_clean(); }

        
http_response_code(404);

        
ob_start();

        
cmsTemplate::getInstance()->renderAsset('errors/notfound');

        
$html ob_get_clean();

        die(
cmsConfig::get('min_html') ? html_minify($html) : $html);
    }

    
/**
     * Показывает сообщение о том что сайт отключен и завершает работу
     */
    
public static function errorMaintenance(){

        if(
ob_get_length()) { ob_end_clean(); }

        
http_response_code(503);

        
ob_start();

        
cmsTemplate::getInstance()->renderAsset('errors/offline', [
            
'reason' => cmsConfig::get('off_reason')
        ]);

        
$html ob_get_clean();

        die(
cmsConfig::get('min_html') ? html_minify($html) : $html);
    }

    public static function 
respondIfModifiedSince($lastmod) {

        
$last_modified_unix strtotime($lastmod);

        
$last_modified gmdate("D, d M Y H:i:s GMT"$last_modified_unix);

        
$if_modified_since false;

        if (isset(
$_ENV['HTTP_IF_MODIFIED_SINCE'])) {
            
$if_modified_since strtotime(substr($_ENV['HTTP_IF_MODIFIED_SINCE'], 5));
        }

        if (isset(
$_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
            
$if_modified_since strtotime(substr($_SERVER['HTTP_IF_MODIFIED_SINCE'], 5));
        }

        if (
$if_modified_since && $if_modified_since >= $last_modified_unix) {

            if (
ob_get_length()) {
                
ob_end_clean();
            }

            
http_response_code(304);

            die();

        }

        
header('Last-Modified: ' $last_modified);

    }

//============================================================================//
//============================================================================//

    /**
     * Возвращает массив со списком всех шаблонов
     * @return array
     */
    
public static function getTemplates(){

        if(
self::$templates !== null){
            return 
self::$templates;
        }

        if(
cmsTemplate::TEMPLATE_BASE_PATH){
            return 
self::$templates self::getDirsList(cmsTemplate::TEMPLATE_BASE_PATH);
        }

        
$root_path cmsConfig::get('root_path');
        
$all_dirs self::getDirsList('');
        
$result = [];

        foreach(
$all_dirs as $dir){
            
// В папке шаблона в обязательном порядке должны быть как минимум эти файлы
            
if(file_exists($root_path.$dir.'/main.tpl.php') && (file_exists($root_path.$dir.'/scheme.html') || file_exists($root_path.$dir.'/scheme.php'))){
                
$result[] = $dir;
            }
        }

        return 
self::$templates $result;

    }

    
/**
     * Возвращает массив со списком всех языков
     * @return array
     */
    
public static function getLanguages(){

        
$default_lang cmsConfig::get('language');

        
$langs self::getDirsList('system/languages'true);

        
$current_lang_key array_search(self::$language$langs);

        if(
$current_lang_key !== 0){

            list(
$langs[0], $langs[$current_lang_key]) = [$langs[$current_lang_key], $langs[0]];

        }

        if(
$default_lang !== self::$language){

            
$default_lang_key array_search($default_lang$langs);

            if(
$default_lang_key !== 1){

                list(
$langs[1], $langs[$default_lang_key]) = [$langs[$default_lang_key], $langs[1]];

            }

        }

        return 
$langs;

    }

    
/**
     * Возвращает массив со списком всех визуальных редакторов
     * @return array
     */
    
public static function getWysiwygs(){

        return 
self::getDirsList('wysiwyg');

    }

//============================================================================//
//============================================================================//

    /**
     * Возвращает список директорий внутри указанной
     * @param string $root_dir
     * @param bool $asc_sort Сортировать по алфавиту, по умолчанию false
     * @return array
     */
    
public static function getDirsList($root_dir$asc_sort=false){

        
$dir cmsConfig::get('root_path') . $root_dir;
        
$dir_context opendir($dir);

        
$list = [];

        while (
$next readdir($dir_context)){

            if (
in_array($next, array('.''..'))){ continue; }
            if (
strpos($next'.') === 0){ continue; }
            if (!
is_dir($dir.'/'.$next)) { continue; }

            
$list[] = $next;

        }

        if(
$asc_sort){
            
sort($list);
        }

        return 
$list;

    }

    
/**
     * Возвращает список файлов из указанной директории по нужной маске
     * @param string $root_dir Директория
     * @param string $pattern Маска файлов
     * @param bool $is_strip_ext Отрезать расширения?
     * @param bool $is_include Подключать каждый файл?
     * @return array
     */
    
public static function getFilesList($root_dir$pattern='*.*'$is_strip_ext=false$is_include=false){

        
$config cmsConfig::getInstance();

        
$directory $config->root_path $root_dir;
        
$pattern $directory '/' $pattern;

        
$list = [];

        
$files = @glob($pattern);

        if (!
$files) { return $list; }

        foreach (
$files as $file) {

            if (
$is_include && !isset(self::$includedFiles[$file])) {
                include_once 
$file;
                
self::$includedFiles[$file] = true;
            }

            
$file basename($file);

            if (
$is_strip_ext){ $file pathinfo($filePATHINFO_FILENAME); }

            
$list[] = $file;

        }

        return 
$list;

    }

//============================================================================//
//============================================================================//

    /**
     * Устанавливает соединение с БД
     *
     */
    
public function connectDB(){
        
$this->db cmsDatabase::getInstance();
    }

//============================================================================//
//============================================================================//

    
public static function getTimeZones(){
        
self::loadLib('timezones');
        
$_zones getTimeZones();
        
$zones = [];
        foreach(
$_zones as $zone){
            
$zones$zone ] = $zone;
        }
        return 
$zones;
    }

}

/**
 * В случае, если отладка отключена, не загружаем файл класса
 */
if(!class_exists('cmsDebugging'false)){
    class 
cmsDebugging {
        public static function 
__callStatic($name$arguments) {}
    }
}
Онлайн: 0
Реклама