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

    public static 
$options_cache = array();

    public 
$name;
    public 
$title;
    public 
$model null;
    public 
$request;
    public 
$current_action;
    public 
$current_params;

    protected 
$useOptions false;

    function 
__construct($request){

        
$config cmsConfig::getInstance();

        
$this->name mb_strtolower(get_called_class());

        
$this->root_url $this->name;

        
$this->root_path $config->root_path 'system/controllers/' $this->name '/';

        
$this->request $request;

        
cmsCore::loadControllerLanguage($this->name);

        
$title_constant 'LANG_'.strtoupper($this->name).'_CONTROLLER';

        
$this->title defined($title_constant) ? constant($title_constant) : $this->name;

        if (
cmsCore::isModelExists($this->name)){
            
$this->model cmsCore::getModel($this->name);
        }

        if (
$this->useOptions){
            
$this->options $this->getOptions();
        }

    }

    public function 
setRootURL($root_url){
        
$this->root_url $root_url;
    }

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

    /**
     * Загружает и возвращает опции контроллера,
     * заполняя отсутсвующие из них значениями по-умолчанию
     * @return array
     */
    
public function getOptions(){

        
$options self::loadOptions($this->name);

        
$form $this->getForm('options'false'backend/');

        
$options $form->parse(new cmsRequest($options));

        return 
$options;

    }

    
/**
     * Загружает опции контроллера
     * @param string $controller_name
     * @return array
     */
    
static function loadOptions($controller_name){

        if (isset(
self::$options_cache[$controller_name])){
            return 
self::$options_cache[$controller_name];
        }

        
$model = new cmsModel();

        
$model->filterEqual('name'$controller_name);

        
$options $model->getFieldFiltered('controllers''options');

        if (
$options){
            
$options cmsModel::yamlToArray($options);
            
self::$options_cache[$controller_name] = $options;
        }

        return 
$options;

    }

    
/**
     * Сохраняет опции контроллера
     * @param string $controller_name
     * @param array $options
     * @return boolean
     */
    
static function saveOptions($controller_name$options){

        
$model = new cmsModel();

        
$model->filterEqual('name'$controller_name);

        return 
$model->updateFiltered('controllers', array('options' => $options));

    }

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

    //
    // ХУКИ
    //

    /**
     * Вызывается до начала работы экшена
     */
    
public function before($action_name){

        
cmsTemplate::getInstance()->setContext($this);

        return 
true;

    }

    
/**
     * Вызывается после работы экшена
     */
    
public function after($action_name){

        
cmsTemplate::getInstance()->restoreContext();

        return 
true;

    }

    
/**
     * Вызывается до начала работы хука
     */
    
public function beforeHook($event_name){

        if (
$this->useOptions){
            
$this->options $this->getOptions();
        }

        return 
true;

    }

    
/**
     * Вызывается после работы хука
     */
    
public function afterHook($event_name){

        return 
true;

    }

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

    /**
     * Проверяет существование экшена
     * @param string $action_name
     * @return boolean
     */
    
public function isActionExists($action_name){

        
$method_name 'action' string_to_camel('_'$action_name);

        if(
method_exists($this$method_name)){
            return 
true;
        }

        
$action_file $this->root_path 'actions/' $action_name.'.php';

        if (
file_exists($action_file)){
            return 
true;
        }

        return 
false;

    }

    
/**
     * Находит и запускает требуемый экшен
     * @param string $action_name
     * @param array $params
     */
    
public function runAction($action_name$params = array()){

        if (
$this->before($action_name) === false) { return false; }

        
$this->current_params $params;

        
$action_name $this->routeAction($action_name);

        
$method_name 'action' string_to_camel('_'$action_name);

        
// епроверяем наличие экшена его в отдельном файле
        
$action_file $this->root_path 'actions/' $action_name.'.php';

        if(
file_exists($action_file)){

            
// вызываем экшен из отдельного файла
            
$result $this->runExternalAction($action_name$this->current_params);

        } else {

            
// Если файла нет, ищем метод класса
            
if (method_exists($this$method_name)){

                
// проверяем максимальное число аргументов экшена
                
if ($this->name != 'admin'){
                    
$rf = new ReflectionMethod($this$method_name);
                    
$max_params $rf->getNumberOfParameters();
                    if (
$max_params count($this->current_params)) { cmsCore::error404(); }
                }
                
                
// если есть нужный экшен, то вызываем его
                
$result call_user_func_array(array($this$method_name), $this->current_params);

            } else {

                
// если нет экшена в отдельном файле,
                // проверяем метод route()
                
if(method_exists($this'route')){

                    
$route_uri $action_name;
                    if (
$this->current_params) { $route_uri .= '/' implode('/'$this->current_params); }
                    
$result call_user_func(array($this'route'), $route_uri);

                } else {

                    
// если метода route() тоже нет,
                    // то 404
                    
cmsCore::error404();

                }

            }

        }

        
$this->after($action_name);
                
        return 
$result;

    }

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

    /**
     * Выполняет экшен, находящийся в отдельном файле ./actions/$action_name.php
     * @param str $action_name
     */
    
public function runExternalAction($action_name$params = array()){

        
$action_file $this->root_path 'actions/'.$action_name.'.php';

        
$class_name 'action' string_to_camel('_'$this->name) . string_to_camel('_'$action_name);

        include(
$action_file);

        
// проверяем максимальное число аргументов экшена
        
if ($this->name != 'admin'){
            
$rf = new ReflectionMethod($class_name'run');
            
$max_params $rf->getNumberOfParameters();
            if (
$max_params count($params)) { cmsCore::error404(); }
        }
        
        
$action_object = new $class_name($this$params);
        
        
$result call_user_func_array(array($action_object'run'), $params);

        return 
$result;

    }

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

    /**
     * Находит и запускает хук для указанного события
     * @param string $event_name
     */
    
public function runHook($event_name$params = array()){

        if (
$this->beforeHook($event_name) === false) { return false; }

        
$method_name 'on' string_to_camel('_'$event_name);

        if(
method_exists($this$method_name)){

            
// если есть нужный хук, то вызываем его
            
$result call_user_func_array(array($this$method_name), $params);

        } else {

            
// если метода хука нет, проверяем наличие его в отдельном файле
            
$hook_file $this->root_path 'hooks/' $event_name '.php';

            if (
file_exists($hook_file)){

                
// вызываем хук из отдельного файла
                
$result $this->runExternalHook($event_name$params);

            } else {

                
// хука нет вообще, возвращаем данные запроса без изменений
                
return $this->request->getData();

            }

        }

        
$this->afterHook($event_name);

        return 
$result;

    }

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

    /**
     * Выполняет хук, находящийся в отдельном файле ./hooks/$event_name.php
     * @param str $event_name
     */
    
public function runExternalHook($event_name$params = array()){

        
$class_name 'on' string_to_camel('_'$this->name) . string_to_camel('_'$event_name);

        if (!
class_exists($class_name)){

            
$hook_file $this->root_path 'hooks/' $event_name '.php';

            include_once 
$hook_file;

        }

        
$hook_object = new $class_name($this);

        
$result call_user_func_array(array($hook_object'run'), $params);

        return 
$result;

    }

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

    /**
     * Загружает и возвращает описание структуры формы
     * @param type $form_name
     * @param type $params
     * @return cmsForm
     */
    
public function getForm($form_name$params=false$path_prefix=''){

        
$form_file $this->root_path $path_prefix 'forms/form_' $form_name '.php';
        
$form_name $this->name $form_name;

        return 
cmsForm::getForm($form_file$form_name$params);

    }

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

    /**
     * Загружает и возвращает описание структуры таблицы
     * @param string $grid_name
     */
    
public function loadDataGrid($grid_name$params false){

        
$default_options = array(
            
'order_by' => 'id',
            
'order_to' => 'asc',
            
'show_id' => true,
            
'is_auto_init' => true,
            
'is_sortable' => true,
            
'is_filter' => true,
            
'is_actions' => true,
            
'is_pagination' => true,
            
'is_toolbar' => true,
            
'is_draggable' => false,
            
'is_selectable' => false
        
);

        
$grid_file $this->root_path 'grids/grid_' $grid_name '.php';

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

        include(
$grid_file);

        
$args = array($this);
        if (
$params) {
            if (
is_array($params)){ $args = array($this) + $params; }
            else { 
$args[] = $params; }
        }

        
$grid call_user_func_array('grid_'.$grid_name$args);

        if (!isset(
$grid['options'])) {
            
$grid['options'] = $default_options;
        } else {
            
$grid['options'] = array_merge($default_options$grid['options']);
        }

        
$grid cmsEventsManager::hook('grid_'.$this->name.'_'.$grid_name$grid);
        
        return 
$grid;

    }

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

    
public function loadRoutes(){

        
$file $this->root_path 'routes.php';

        if (!
file_exists($file)){ return array(); }

        include(
$file);

        
$routes_func 'routes_' $this->name;

        
$routes call_user_func($routes_func);

        if (!
is_array($routes)) { return array(); }

        return 
$routes;

    }

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

    
public function halt() {
        die();
    }

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

    /**
     * Позволяет переопределить экшен перед вызовом
     * @param string $action_name
     * @return string
     */
    
public function routeAction($action_name){

        return 
$action_name;

    }

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

    /**
     * Определяет экшен, по списку маршрутов из файла routes.php контроллера
     * @param string $uri
     * @return boolean
     */
    
public function parseRoute($uri){

        
$routes $this->loadRoutes();

        
// Флаг удачного перебора
        
$is_found false;

        
// Название найденного экшена
        
$action_name false;

        
//перебираем все маршруты
        
if($routes){
            foreach(
$routes as $route){

                
//сравниваем шаблон маршрута с текущим URI
                
preg_match($route['pattern'], $uri$matches);

                
//Если найдено совпадение
                
if ($matches){

                    
$action_name $route['action'];

                    
// удаляем шаблон и экшен из параметров маршрута,
                    // чтобы не мешали при переборе параметров запроса
                    
unset($route['pattern']);
                    unset(
$route['action']);

                    
//перебираем параметры маршрута в виде ключ=>значение
                    
foreach($route as $key=>$value){
                        if (
is_integer($key)){

                            
//Если ключ - целое число, то значением является сегмент URI
                            
$this->request->set($value$matches[$key]);

                        } else {

                            
//иначе, значение берется из маршрута
                            
$this->request->set($key$value);

                        }
                    }

                    
// совпадение есть
                    
$is_found true;

                    
//раз найдено совпадение, прерываем цикл
                    
break;

                }

            }
        }

        
// Если в маршруте нет совпадений
        
if(!$is_found) { return false; }

        return 
$action_name;

    }

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

    /**
     * Редирект на указанный адрес
     * @param str $url
     */
    
public function redirect($url$code=303){
        if (
$code == 301){
            
header('HTTP/1.1 301 Moved Permanently');
        } else {
            
header('HTTP/1.1 303 See Other');
        }
        
header('Location: '.$url);
        
$this->halt();
    }

    
/**
     * Редирект на главную страницу
     */
    
public function redirectToHome(){
        
$this->redirect(href_to_home());
    }


    
/**
     * Редирект на другой контроллер
     * @param str $controller
     * @param str $action
     * @param array $params
     * @param array $query
     */
    
public function redirectTo($controller$action=''$params=array(), $query=array()){

        
$config cmsConfig::getInstance();
        
$location $config->root $controller '/' $action;

        if (
$params){ $location .= '/' implode('/'$params); }
        if (
$query){ $location .= '?' http_build_query($query); }

        
$this->redirect($location);

    }

    
/**
     * Редирект на собственный экшен
     * @param str $controller
     * @param str $action
     * @param array $params
     * @param array $query
     */
    
public function redirectToAction($action$params=array(), $query=array()){

        if (
$action=='index') {
            
$location $this->root_url;
        } else {
            
$location $this->root_url '/' $action;
        }

        if (
$params){
            if (
is_array($params)) { $location .= '/' implode('/'$params); }
            else { 
$location .= '/' $params; }
        }
        
        if (
$query){ $location .= '?' http_build_query($query); }

        
$this->redirect(href_to($location));

    }

    
/**
     * Возвращает предыдущий URL
     * @return str
     */
    
public function getBackURL() {
        
$config cmsConfig::getInstance();
        if (!isset(
$_SERVER['HTTP_REFERER'])) { return $config->root; }
        return 
strlen($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/';
    }

    
/**
     * Редирект на предыдущий URL
     */
    
public function redirectBack(){
        
$url $this->getBackURL();
        
header('Location: '.$url);
        
$this->halt();
    }

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

    /**
     * Возвращает список субъектов к которым применяются права пользователей
     * @return array
     */
    
public function getPermissionsSubjects(){
        return array(
            array(
                
'name' => $this->name,
                
'title' => $this->title
            
)
        );
    }

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

    
public function validate_required($value){
        if (empty(
$value)) { return ERR_VALIDATE_REQUIRED; }
        return 
true;
    }

    public function 
validate_min($min$value){
        if ((int)
$value $min) { return sprintf(ERR_VALIDATE_MIN$min); }
        return 
true;
    }

    public function 
validate_max($max$value){
        if ((int)
$value $max) { return sprintf(ERR_VALIDATE_MAX$max); }
        return 
true;
    }

    public function 
validate_min_length($length$value){
        if (empty(
$value)) { return true; }
        if (
mb_strlen($value)<$length) { return sprintf(ERR_VALIDATE_MIN_LENGTH$length); }
        return 
true;
    }

    public function 
validate_max_length($length$value){
        if (empty(
$value)) { return true; }
        if (
mb_strlen($value)>$length) { return sprintf(ERR_VALIDATE_MAX_LENGTH$length); }
        return 
true;
    }

    public function 
validate_array_key($array$value){
        if (!isset(
$array[$value])) { return ERR_VALIDATE_INVALID; }
        return 
true;
    }

    public function 
validate_array_keys($array$values){
        if (empty(
$values)) { return true; }
        foreach(
$values as $value){
            if (!isset(
$array[$value])) { return ERR_VALIDATE_INVALID; }
        }
        return 
true;
    }

    public function 
validate_in_array($array$value){
        if (empty(
$value)) { return true; }
        if (!
in_array($value$array)) { return ERR_VALIDATE_INVALID; }
        return 
true;
    }

    public function 
validate_email($value){
        if (empty(
$value)) { return true; }
        if (!
preg_match("/^([a-zA-Z0-9._-]+)@([a-zA-Z0-9._-]+).([a-zA-Z]{2,6})$/i"$value)){ return ERR_VALIDATE_EMAIL; }
        return 
true;
    }

    public function 
validate_alphanumeric($value){
        if (empty(
$value)) { return true; }
        if (!
preg_match("/^([a-zA-Z0-9]*)$/i"$value)){ return ERR_VALIDATE_ALPHANUMERIC; }
        return 
true;
    }

    public function 
validate_sysname($value){
        if (empty(
$value)) { return true; }
        if (!
preg_match("/^([a-zA-Z0-9_]*)$/i"$value)){ return ERR_VALIDATE_SYSNAME; }
        return 
true;
    }

    public function 
validate_digits($value){
        if (empty(
$value)) { return true; }
        if (!
preg_match("/^([0-9]+)$/i"$value)){ return ERR_VALIDATE_DIGITS; }
        return 
true;
    }

    public function 
validate_number($value){
        if (empty(
$value)) { return true; }
        if (!
preg_match("/^([-]?)([0-9.,]+)$/i"$value)){ return ERR_VALIDATE_NUMBER; }
        return 
true;
    }

    public function 
validate_regexp($regexp$value){
        if (empty(
$value)) { return true; }
        if (!
preg_match($regexp$value)){ return ERR_VALIDATE_REGEXP; }
        return 
true;
    }

    public function 
validate_unique($table_name$field_name$value){
        if (empty(
$value)) { return true; }
        
$core cmsCore::getInstance();
        
$result $core->db->isFieldUnique($table_name$field_name$value);
        if (!
$result) { return ERR_VALIDATE_UNIQUE; }
        return 
true;
    }

    public function 
validate_unique_exclude($table_name$field_name$exclude_row_id$value){
        if (empty(
$value)) { return true; }
        
$core cmsCore::getInstance();
        
$result $core->db->isFieldUnique($table_name$field_name$value$exclude_row_id);
        if (!
$result) { return ERR_VALIDATE_UNIQUE; }
        return 
true;
    }

    public function 
validate_unique_ctype_field($ctype_name$value){
        if (empty(
$value)) { return true; }
        
$core cmsCore::getInstance();
        
$content_model cmsCore::getModel('content');
        
$table_name $content_model->table_prefix $ctype_name;
        
$result = !$core->db->isFieldExists($table_name$value);
        if (!
$result) { return ERR_VALIDATE_UNIQUE; }
        return 
true;        
    }

    public function 
validate_unique_ctype_dataset($ctype_id$value){
        if (empty(
$value)) { return true; }
        
$core cmsCore::getInstance();
        
$ctype_id = (int)$ctype_id;
        
$value $core->db->escape($value);
        
$result = !$core->db->getRow('content_datasets'"ctype_id='{$ctype_id}' AND name='{$value}'");
        if (!
$result) { return ERR_VALIDATE_UNIQUE; }
        return 
true;
    }

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

}
Онлайн: 1
Реклама