Файл: system/core/controller.php
Строк: 1167
<?php
class cmsController {
private static $controllers;
private static $mapping;
public $name;
public $title;
public $model = null;
public $request;
public $current_action;
public $current_template_name;
public $current_params;
public $options;
public $root_url;
public $root_path;
/**
* Контекст списка записей
* @var string
*/
protected $list_type = 'category_view';
/**
* Если для контроллера задан ремап
* и это свойство установлено в true
* редиректа со старого адреса не будет
*
* @var boolean
*/
public $disallow_mapping_redirect = false;
/**
* Флаг, что контроллер должен работать только после
* регистрации в БД
* @var boolean
*/
public $mb_installed = false;
/**
* Флаг наличия SEO параметров для index экшена
* @var boolean
*/
public $useSeoOptions = false;
/**
* Флаг наличия SEO паттернов для страниц записей
* @var boolean
*/
public $useItemSeoOptions = false;
/**
* Флаг блокировки прямого вызова экшена
* полезно если название экшена переопределяется
* а вызов экшена напрямую нужно запретить
* @var boolean || null
*/
public $lock_explicit_call = null;
/**
* Если необходимо использовать у контроллера
* не свою модель и/или своя модель
* будет наследоваться от модели какого-то контроллера
* укажите его в этом параметре в классе своего контроллера
*
* @var string|array
*/
protected $outer_controller_model = '';
protected $callbacks = array();
protected $useOptions = false;
protected $active_filters = array();
/**
* Неизвестные экшены определять
* как первый параметр экшена index
* @var boolean
*/
protected $unknown_action_as_index_param = false;
public function __construct( cmsRequest $request){
self::loadControllers();
$this->name = $this->name ? $this->name : mb_strtolower(get_called_class());
$this->root_url = $this->name;
$this->root_path = $this->cms_config->root_path . 'system/controllers/' . $this->name . '/';
$this->setRequest($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);
} elseif($this->outer_controller_model) {
$this->model = cmsCore::getModel($this->outer_controller_model);
}
if ($this->useOptions){
$this->options = $this->getOptions();
}
$this->loadCallback();
}
public function setRequest( cmsRequest $request) {
$this->request = $request; return $this;
}
///////////////// Набор методов для коллбэков ////////////////////////
/**
* Этот метод переопределяется в дочерних классах
* где задается начальный набор функций, которые будут применены в коллбэках
*/
public function loadCallback() {}
/**
* Устанавливает один или множество коллбэков
* @param string $name Назначение - обычно название метода, где будет применяться
* @param array $callbacks Массив коллбэков
* @return cmsController
*/
public function setCallback($name, $callbacks) { $this->callbacks[$name] = $callbacks; return $this; }
/**
* Применяет коллбэки
* @param string $name Назначение - обычно __FUNCTION__
* @param array $params Массив параметров
* @return cmsController
*/
public function processCallback($name, $params) {
$name = strtolower($name);
if(!empty($this->callbacks[$name])){
array_unshift($params, $this);
foreach ($this->callbacks[$name] as $callback) {
call_user_func_array($callback, $params);
}
}
return $this;
}
protected function loadCmsObj($name) {
if(strpos($name, 'cms_') === 0){
$class_name = string_to_camel('_', $name);
if(method_exists($class_name, 'getInstance')){
$this->{$name} = call_user_func(array($class_name, 'getInstance'));
} else {
$this->{$name} = new $class_name();
}
return true;
}
return false;
}
public function __get($name) {
if($this->loadCmsObj($name)){
return $this->{$name};
}
if(strpos($name, 'controller_') === 0){
$this->{$name} = cmsCore::getController(str_replace('controller_', '', $name), $this->request);
return $this->{$name};
}
if(strpos($name, 'model_') === 0){
$this->{$name} = cmsCore::getModel(str_replace('model_', '', $name));
return $this->{$name};
}
return null;
}
public function setRootURL($root_url){
$this->root_url = $root_url;
}
//============================================================================//
//============================================================================//
public function setListContext($list_type) {
$this->list_type = $list_type; return $this;
}
public function getListContext() {
return $this->list_type;
}
//============================================================================//
//============================================================================//
/**
* Загружает и возвращает опции текущего контроллера,
* @return array
*/
public function getOptions(){
return (array)self::loadOptions($this->name);
}
public function setOption($key, $val){
$this->options[$key] = $val; return $this;
}
public function getOption($key){
if(!$this->useOptions){ return null; }
return isset($this->options[$key]) ? $this->options[$key] : null;
}
/**
* Проверяет включен ли текущий контроллер
* @return boolean
*/
public function isEnabled() {
return $this->isControllerEnabled($this->name);
}
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) {
// проверяем только те, которые зарегистрированы в базе
if (isset(self::$controllers[$name]['is_enabled'])){
return self::$controllers[$name]['is_enabled'];
}
return true;
}
public static function enabled($name) {
self::loadControllers();
if (isset(self::$controllers[$name]['is_enabled'])){
return self::$controllers[$name]['is_enabled'];
}
return true;
}
public static function getControllersMapping() {
if (self::$mapping !== null) { return self::$mapping; }
self::$mapping = array();
self::loadControllers();
if(self::$controllers){
foreach (self::$controllers as $controller) {
if(!empty($controller['slug'])){
self::$mapping[$controller['name']] = $controller['slug'];
}
}
}
return self::$mapping;
}
private static function loadControllers() {
if(!isset(self::$controllers)){
$model = new cmsModel();
$model->selectList(array(
'i.id' => 'id',
'i.is_enabled' => 'is_enabled',
'i.options' => 'options',
'i.name' => 'name',
'i.slug' => 'slug'
), true);
self::$controllers = $model->useCache('controllers')->get('controllers', function ($item, $model) {
$item['options'] = cmsModel::yamlToArray($item['options']);
return $item;
}, 'name');
}
}
/**
* Загружает опции контроллера
* @param string $controller_name
* @return array
*/
public static function loadOptions($controller_name){
self::loadControllers();
if (isset(self::$controllers[$controller_name]['options'])){
return self::$controllers[$controller_name]['options'];
}
return array();
}
/**
* Сохраняет опции контроллера
* @param string $controller_name
* @param array $options
* @return boolean
*/
static function saveOptions($controller_name, $options){
$model = new cmsModel();
$model->filterEqual('name', $controller_name);
$model->updateFiltered('controllers', array('options' => $options));
cmsCache::getInstance()->clean('controllers');
return true;
}
//============================================================================//
//============================================================================//
//
// ХУКИ
//
/**
* Вызывается до начала работы экшена
*/
public function before($action_name){
$this->cms_template->setContext($this);
if($this->useSeoOptions && $action_name == 'index'){
if (!empty($this->options['seo_keys'])){ $this->cms_template->setPageKeywords($this->options['seo_keys']); }
if (!empty($this->options['seo_desc'])){ $this->cms_template->setPageDescription($this->options['seo_desc']); }
}
return true;
}
/**
* Вызывается после работы экшена
*/
public function after($action_name){
$this->cms_template->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->getExternalActionPath($action_name);
if (is_readable($action_file)){
return true;
}
return false;
}
/**
* Запускает требуемый экшен
* @param string $action_name
* @param array $params
* @return mixed
*/
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);
$result = $this->executeAction($action_name, $this->current_params);
$this->after($action_name);
return $result;
}
/**
* Находит и выполняет требуемый экшен
* @param string $action_name
* @param array $params
* @return mixed
*/
public function executeAction($action_name, $params = array()) {
$method_name = 'action' . string_to_camel('_', $action_name);
// проверяем наличие экшена его в отдельном файле
$action_file = $this->getExternalActionPath($action_name);
if(is_readable($action_file)){
// вызываем экшен из отдельного файла
$result = $this->runExternalAction($action_name, $params);
} else {
// Если файла нет, ищем метод класса
if (method_exists($this, $method_name)){
if (!$this->validateParamsCount($this, $method_name, $params)) { cmsCore::error404(); }
// сохраняем название текущего экшена
$this->setCurrentAction($action_name);
// если есть нужный экшен, то вызываем его
$result = call_user_func_array(array($this, $method_name), $params);
} else {
// если нет экшена в отдельном файле,
// проверяем метод route()
if(method_exists($this, 'route')){
$route_uri = $action_name;
if ($params) { $route_uri .= '/' . implode('/', $params); }
$result = call_user_func(array($this, 'route'), $route_uri);
} else {
// если метода route() тоже нет,
// то 404
cmsCore::error404();
}
}
}
return $result;
}
/**
* Проверяем максимальное число аргументов экшена
* Возвращает false если переданных количество параметров не соответствует кол-ву аргументов экшена
* Для отключения проверки, можно переопределить этот метод (например см. в контроллере admin)
* @param string|object $class Имя класса или текущий объект контроллера $this
* @param string $method_name Имя метода
* @param array $params Массив параметров
* @return bool Результат проверки
*/
protected function validateParamsCount($class, $method_name, $params) {
$rf = new ReflectionMethod($class, $method_name);
// кол-во переданных параметров
$current_params = count($params);
// передано больше чем нужно параметров
if ($rf->getNumberOfParameters() < $current_params) { return false; }
// передано меньше чем нужно параметров
if ($rf->getNumberOfRequiredParameters() > $current_params) { return false; }
return true;
}
/**
* Возвращает путь к файлу экшена (./actions/$action_name.php по умолчанию)
* @param string $action_name
* @return string
*/
public function getExternalActionPath($action_name) {
return $this->root_path . 'actions/'.$action_name.'.php';
}
/**
* Устанавливает имя текущего экшена
* и шаблона экшена (если он не будет передан в cmsTemplate->render)
*
* @param string $action_name
* @return $this
*/
public function setCurrentAction($action_name) {
$this->current_action = $action_name;
$this->current_template_name = $action_name;
return $this;
}
/**
* Выполняет экшен, находящийся в отдельном файле
* @param string $action_name Название экшена
* @param array $params Параметры
* @return mixed
*/
public function runExternalAction($action_name, $params = array()){
$action_file = $this->getExternalActionPath($action_name);
$class_name = 'action' . string_to_camel('_', $this->name) . string_to_camel('_', $action_name);
if (!is_readable($action_file)){
cmsCore::error(ERR_FILE_NOT_FOUND . ': '. str_replace(PATH, '', $action_file));
}
include_once $action_file;
if(!class_exists($class_name, false)){
cmsCore::error(sprintf(ERR_CLASS_NOT_DEFINED, str_replace(PATH, '', $action_file), $class_name));
}
if (!$this->validateParamsCount($class_name, 'run', $params)) { cmsCore::error404(); }
// сохраняем название текущего экшена
$this->setCurrentAction($action_name);
$action_object = new $class_name($this, $params);
// проверяем разрешен ли прямой вызов экшена
if($action_object->lock_explicit_call === true && $this->lock_explicit_call !== false && !$this->request->isInternal()){
cmsCore::error404();
}
// проверяем параметры если нужно
$params_error = $this->validateRequestParams($action_object);
if($params_error !== false){
if ($this->request->isAjax()){
return $this->cms_template->renderJSON(array('error' => true, 'errors' => $params_error, 'message' => sprintf(LANG_REQUEST_PARAMS_ERROR, implode(', ', array_keys($params_error)))));
} else {
cmsCore::error(LANG_ERROR, sprintf(LANG_REQUEST_PARAMS_ERROR, implode(', ', array_keys($params_error))));
}
}
return call_user_func_array(array($action_object, 'run'), $params);
}
/**
* Проверяет параметры запроса, если они заданы
* @param object $action_object
* @return boolean
*/
public function validateRequestParams($action_object) {
if(empty($action_object->request_params)){
return false;
}
$errors = array();
// валидация аналогична валидации форм
foreach ($action_object->request_params as $param_name => $rules) {
$value = $this->request->get($param_name, null);
if (is_null($value) && isset($rules['default'])) {
$value = $rules['default'];
$this->request->set($param_name, $value);
} elseif(!is_null($value) && isset($rules['default'])){
$value = $this->request->get($param_name, $rules['default']);
// для применения типизации переменной
$this->request->set($param_name, $value);
}
foreach ($rules['rules'] as $rule) {
if (!$rule) { continue; }
$validate_function = "validate_{$rule[0]}";
$rule[] = $value;
unset($rule[0]);
$result = call_user_func_array(array($this, $validate_function), $rule);
// если получилось false, то дальше не проверяем, т.к.
// ошибка уже найдена
if ($result !== true) {
$errors[$param_name] = $result;
break;
}
}
}
if (!sizeof($errors)) { return false; }
return $errors;
}
//============================================================================//
//============================================================================//
/**
* Находит и запускает хук для указанного события
* @param string $event_name Название события
* @param array $params Параметры события
* @param mixed $default Умолчания, если хука нет
* @return mixed
*/
public function runHook($event_name, $params = array(), $default = null){
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 (is_readable($hook_file)){
// вызываем хук из отдельного файла
$result = $this->runExternalHook($event_name, $params);
} else {
// хука нет вообще, возвращаем данные запроса без изменений
if($default === null){
return $this->request->getData();
} else {
return $default;
}
}
}
$this->afterHook($event_name);
return $result;
}
/**
* Выполняет хук, находящийся в отдельном файле ./hooks/$event_name.php
* @param string $event_name Название события
* @param array $params Параметры события
* @return mixed
*/
public function runExternalHook($event_name, $params = []) {
$class_name = 'on' . string_to_camel('_', $this->name) . string_to_camel('_', $event_name);
if (!class_exists($class_name, false)) {
$hook_file = $this->root_path . 'hooks/' . $event_name . '.php';
if (!is_readable($hook_file)) {
cmsCore::error(ERR_FILE_NOT_FOUND . ': ' . str_replace(PATH, '', $hook_file));
}
include_once $hook_file;
}
$hook_object = new $class_name($this);
return call_user_func_array([$hook_object, 'run'], $params);
}
//============================================================================//
//============================================================================//
public function getActiveFiltersQuery() {
return $this->active_filters ? http_build_query($this->active_filters) : '';
}
public function getActiveFilters() {
return $this->active_filters;
}
public function setActiveFilter($key, $value) {
$this->active_filters[$key] = $value;
return $this;
}
//============================================================================//
//============================================================================//
/**
* Загружает и возвращает описание структуры формы
* в контексте текущего контроллера и, в свою очередь,
* его контекста - Frontend или Backend
*
* @param string $form_name Название формы
* @param array $params Параметры формы
* @param string $path_prefix Префикс путь к файлу формы относительно директории контроллера
* @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;
$form = cmsForm::getForm($form_file, $_form_name, $params, $this);
if($form === false){
return cmsCore::error(ERR_FILE_NOT_FOUND . ': '. str_replace(PATH, '', $form_file));
}
if(is_string($form)){
return cmsCore::error($form);
}
list($form, $params) = cmsEventsManager::hook('form_'.$this->name.'_'.$form_name, array($form, $params));
return $form;
}
public function getControllerForm($controller, $form_name, $params = false){
$form_file = $this->cms_config->root_path.'system/controllers/'.$controller.'/forms/form_'.$form_name.'.php';
$_form_name = $controller . $form_name;
$form = cmsForm::getForm($form_file, $_form_name, $params, $this);
if($form === false){
cmsCore::error(ERR_FILE_NOT_FOUND . ': '. str_replace(PATH, '', $form_file));
}
list($form, $params) = cmsEventsManager::hook('form_'.$controller.'_'.$form_name, array($form, $params));
return $form;
}
//============================================================================//
//============================================================================//
/**
* Загружает и возвращает описание структуры grid таблицы
* @param string $grid_name Название
* @param array $params Параметры для передачи в функцию описания grid-а
* @param string $ups_key Ключ UPS
* @return array || false
*/
public function loadDataGrid($grid_name, $params = false, $ups_key = ''){
$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,
'perpage' => 30,
'is_toolbar' => true,
'is_draggable' => false,
'drag_save_url' => '',
'is_selectable' => false,
'load_columns' => false
);
$grid_file = $this->root_path . 'grids/grid_' . $grid_name . '.php';
if (!is_readable($grid_file)){
cmsCore::error(ERR_FILE_NOT_FOUND . ': '. str_replace(PATH, '', $grid_file));
}
include($grid_file);
$args = array($this);
if ($params) {
if (!is_array($params)){
$params = [$params];
}
foreach ($params as $p) {
$args[] = $p;
}
}
$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);
list($grid, $args) = cmsEventsManager::hook('grid_'.$this->name.'_'.$grid_name.'_args', array($grid, $args));
if ($this->request->isAjax() && $this->request->has('heads')) {
$heads = $this->request->get('heads', array());
natsort($heads);
$grid_heads = array_keys($grid['columns']);
if ($grid['actions']) {
$grid_heads[] = 'dg_actions';
}
natsort($grid_heads);
if ($heads !== $grid_heads) {
$grid['options']['load_columns'] = true;
}
}
if($ups_key){
$filter_str = cmsUser::getUPS($ups_key);
if($filter_str){
parse_str($filter_str, $filter);
$grid['filter'] = $filter;
}
}
return $grid;
}
//============================================================================//
//============================================================================//
public function loadRoutes(){
$file = $this->root_path . 'routes.php';
if (!is_readable($file)){ return array(); }
include_once($file);
$routes_func = 'routes_' . $this->name;
$routes = call_user_func($routes_func);
if (!is_array($routes)) { return array(); }
return $routes;
}
//============================================================================//
//============================================================================//
public function halt($text='') {
die((string)$text);
}
public function getUniqueKey($params) {
array_unshift($params, $this->name);
return implode('.', $params);
}
public function prepareItemSeo($item, $fields, $ctype) {
list($ctype, $fields, $item) = cmsEventsManager::hook(['prepare_item_seo', 'prepare_item_'.$ctype['name'].'_seo'], [$ctype, $fields, $item]);
$_item = $item;
foreach ($fields as $field) {
if (!isset($item[$field['name']])) { $_item[$field['name']] = null; continue; }
if (empty($item[$field['name']]) && $item[$field['name']] !== '0') {
$_item[$field['name']] = null; continue;
}
if(isset($field['string_value'])){
$_item[$field['name']] = strip_tags($field['string_value']);
} else {
$_item[$field['name']] = strip_tags($field['handler']->setItem($item)->getStringValue($item[$field['name']]));
}
// Убираем шорткоды
$_item[$field['name']] = preg_replace('#{[a-z]{1}[a-z0-9_]*:[a-z0-9:_]+}#i', '', $_item[$field['name']]);
}
if(!empty($item['tags']) && is_array($item['tags'])){
$_item['tags'] = implode(', ', $item['tags']);
}
if(!isset($item['category']) && !empty($item['category_id'])){
$item['category'] = $this->model->getCategory($ctype['name'], $item['category_id']);
}
if(!empty($item['category']['title'])){
$_item['category'] = $item['category']['title'];
} else {
$_item['category'] = null;
}
return $_item;
}
//============================================================================//
//============================================================================//
/**
* Позволяет переопределить экшен перед вызовом
* @param string $action_name
* @return string
*/
public function routeAction($action_name){
// Избавляемся от index в url
if($this->unknown_action_as_index_param){
if($this->isActionExists($action_name)){
return $action_name;
}
array_unshift($this->current_params, $action_name);
return 'index';
}
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 string $url
* @param integer $code
*/
public function redirect($url, $code=303){
if ($this->request->isAjax()){
$this->cms_template->renderAsset('ui/redirect_continue', array(
'redirect_url' => href_to($url)
), $this->request);
} else {
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 string $controller
* @param string $action
* @param array $params
* @param array $query
*/
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 ? '/'.$action : '');
if ($params){ $location .= '/' . implode('/', $params); }
if ($query){ $location .= '?' . http_build_query($query, '', '&'); }
$this->redirect($location, $code);
}
/**
* Редирект на собственный экшен
* @param string $action
* @param array $params
* @param array $query
*/
public function redirectToAction($action='', $params=array(), $query=array()){
if (!$action || $action=='index') {
$location = href_to($this->root_url);
} else {
$location = href_to($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($location);
}
/**
* Возвращает предыдущий URL текущего сайта
* @return string
*/
public function getBackURL() {
$back_url = $this->cms_config->root;
if(!empty($_SERVER['HTTP_REFERER']) && strpos($_SERVER['HTTP_REFERER'], 'http') === 0){
$refer = $_SERVER['HTTP_REFERER'];
if(strpos($refer, $this->cms_config->protocol.$_SERVER['HTTP_HOST']) === 0) {
$back_url = $refer;
}
}
return $back_url;
}
/**
* Редирект на предыдущий 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 getContentTypeForModeration($name){
return array(
'id' => null,
'name' => $this->name,
'title' => $this->title
);
}
//============================================================================//
//============================================================================//
public function validate_required($value, $disable_empty = true){
if($value === '0' && !$disable_empty){ return true; }
if (empty($value)) { return ERR_VALIDATE_REQUIRED; }
return true;
}
public function validate_min($min, $value){
if (empty($value)) { $value = 0; }
if (!in_array(gettype($value), array('integer','string','double')) || !preg_match("/^([-]?)([0-9.,]+)$/i", $value)){
return ERR_VALIDATE_NUMBER;
}
if ((float)$value < $min) { return sprintf(ERR_VALIDATE_MIN, $min); }
return true;
}
public function validate_max($max, $value){
if (empty($value)) { $value = 0; }
if (!in_array(gettype($value), array('integer','string','double')) || !preg_match("/^([-]?)([0-9.,]+)$/i", $value)){
return ERR_VALIDATE_NUMBER;
}
if ((float)$value > $max) { return sprintf(ERR_VALIDATE_MAX, $max); }
return true;
}
public function validate_minfloat($min, $value){
if (empty($value)) { return true; }
if(bccomp(sprintf('%.8f', $min), sprintf('%.8f', $value), 8) === 1){
return sprintf(ERR_VALIDATE_MIN, $min);
}
return true;
}
public function validate_maxfloat($min, $value){
if (empty($value)) { return true; }
if(bccomp(sprintf('%.8f', $min), sprintf('%.8f', $value), 8) === -1){
return sprintf(ERR_VALIDATE_MAX, $min);
}
return true;
}
public function validate_min_length($length, $value){
if (empty($value)) { return true; }
if (is_array($value)){
return ERR_VALIDATE_INVALID;
}
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 (is_array($value)){
return ERR_VALIDATE_INVALID;
}
if (mb_strlen($value) > $length) { return sprintf(ERR_VALIDATE_MAX_LENGTH, $length); }
return true;
}
public function validate_array_key($array, $value){
if ($value === null || $value === false) { return true; }
if (is_array($value)) {
$result = true;
foreach ($value as $val) {
if(!isset($array[$val])){
$result = ERR_VALIDATE_INVALID; break;
}
}
return $result;
}
if (!isset($array[$value])) { return ERR_VALIDATE_INVALID; }
return true;
}
public function validate_array_keys($array, $values){
if (empty($values)) { return true; }
if (!is_array($values)) { return ERR_VALIDATE_INVALID; }
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 (!is_string($value) || filter_var($value, FILTER_VALIDATE_EMAIL) !== $value){ return ERR_VALIDATE_EMAIL; }
return true;
}
public function validate_url($value){
if (empty($value)) { return true; }
if (!is_string($value) || !preg_match('_^(?:(?:https?)://)(?:(?:(?:[a-zx{00a1}-x{ffff}0-9]+-?)*[a-zx{00a1}-x{ffff}0-9]+)(?:.(?:[a-zx{00a1}-x{ffff}0-9]+-?)*[a-zx{00a1}-x{ffff}0-9]+)*(?:.(?:[a-zx{00a1}-x{ffff}]{2,})))(?:/[^s]*)?$_iuS', $value)){ return ERR_VALIDATE_URL; }
return true;
}
public function validate_alphanumeric($value){
if (empty($value)) { return true; }
if (!is_string($value) || !preg_match("/^([a-z0-9]*)$/i", $value)){ return ERR_VALIDATE_ALPHANUMERIC; }
return true;
}
public function validate_localealphanumeric($value){
if (empty($value)) { return true; }
$regexp = "/^([w .?@,-]*)$/ui";
if(defined('LC_LANGUAGE_VALIDATE_REGEXP')){
$regexp = LC_LANGUAGE_VALIDATE_REGEXP;
}
if (!is_string($value) || !preg_match($regexp, $value)){ return ERR_VALIDATE_REGEXP; }
return true;
}
public function validate_sysname($value){
if (empty($value)) { return true; }
if (!is_string($value) || !preg_match("/^([a-z0-9_]*[a-z]+[a-z0-9_]*)$/", $value)){ return ERR_VALIDATE_SYSNAME; }
return true;
}
public function validate_phone($value){
if (empty($value)) { return true; }
if (!is_string($value) || !preg_match("/^([0-9-+()s]*)$/", $value)){ return ERR_VALIDATE_INVALID; }
return true;
}
public function validate_slug_segment($value){
if (empty($value)) { return true; }
if (!is_string($value) || !preg_match("/^([a-z0-9-]*[a-z]+[a-z0-9-]*)$/", $value)){ return ERR_VALIDATE_SLUGS; }
return true;
}
public function validate_slug($value){
if (empty($value)) { return true; }
if (!is_string($value) || !preg_match("/^([a-z0-9-/]*)$/", $value)){ return ERR_VALIDATE_SLUG; }
return true;
}
public function validate_digits($value){
if (empty($value)) { return true; }
if (!in_array(gettype($value), array('integer','string')) || !preg_match("/^([0-9]+)$/i", $value)){ return ERR_VALIDATE_DIGITS; }
return true;
}
public function validate_number($value){
if (empty($value)) { return true; }
if (!in_array(gettype($value), array('integer','string','double')) || !preg_match("/^([-]?)([0-9.,]+)$/i", $value)){ return ERR_VALIDATE_NUMBER; }
return true;
}
public function validate_color($value) {
if (empty($value)) { return true; }
if (!is_string($value)) { return ERR_VALIDATE_INVALID; }
if (strlen($value) <= 7) {
$value = ltrim($value, '#');
if (ctype_xdigit($value) && (strlen($value) == 6 || strlen($value) == 3)) {
return true;
}
} else {
if (preg_match("/^rgba((s*d+s*,){3} [d.]+)$/i", $value)) {
return true;
}
}
return ERR_VALIDATE_INVALID;
}
public function validate_regexp($regexp, $value){
if (empty($value)) { return true; }
if (!in_array(gettype($value), array('integer','string','double')) || !preg_match($regexp, $value)){ return ERR_VALIDATE_REGEXP; }
return true;
}
public function validate_unique($table_name, $field_name, $value){
if (empty($value)) { return true; }
if (!in_array(gettype($value), array('integer','string','double'))) { return ERR_VALIDATE_INVALID; }
$result = $this->cms_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; }
if (!in_array(gettype($value), array('integer','string','double'))) { return ERR_VALIDATE_INVALID; }
$result = $this->cms_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; }
if (!in_array(gettype($value), array('integer','string'))) { return ERR_VALIDATE_INVALID; }
$content_model = cmsCore::getModel('content');
$table_name = $content_model->table_prefix . $ctype_name;
if ($content_model->db->isFieldExists($table_name, $value)) { return ERR_VALIDATE_UNIQUE; }
return true;
}
public function validate_unique_ctype_dataset($ctype_id, $exclude_row_id = null, $value = null){
if (empty($value)) { return true; }
if (!in_array(gettype($value), array('integer','string'))) { return ERR_VALIDATE_INVALID; }
$value = $this->cms_core->db->escape($value);
if(is_numeric($ctype_id)){
$where = "ctype_id='{$ctype_id}' AND name='{$value}'";
} else {
$where = "target_controller='{$ctype_id}' AND name='{$value}'";
}
if ($exclude_row_id) { $where .= " AND (id <> '{$exclude_row_id}')"; }
$result = !$this->cms_core->db->getRow('content_datasets', $where);
if (!$result) { return ERR_VALIDATE_UNIQUE; }
return true;
}
public function validate_date($value){
if (empty($value)) { return true; }
if (!is_array($value)){
$time = strtotime($value);
if ($time !== false){
return true;
}
}
return ERR_VALIDATE_INVALID;
}
public function validate_date_range($value){
if (empty($value)) { return true; }
if (!empty($value['date']) && !is_array($value['date'])){
if(isset($value['hours']) && isset($value['mins']) &&
!is_array($value['hours']) && !is_array($value['mins'])){
return $this->validate_date(sprintf('%s %02d:%02d', $value['date'], $value['hours'], $value['mins']));
}
} elseif(!empty($value['from']) || !empty($value['to'])) {
if (!empty($value['from'])){
if(is_array($value['from'])){
return ERR_VALIDATE_INVALID;
}
if($this->validate_date($value['from']) !== true){
return ERR_VALIDATE_INVALID;
}
}
if (!empty($value['to'])){
if(is_array($value['to'])){
return ERR_VALIDATE_INVALID;
}
if($this->validate_date($value['to']) !== true){
return ERR_VALIDATE_INVALID;
}
}
return true;
}
return ERR_VALIDATE_INVALID;
}
}