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

class cmsForm {

    public 
$is_tabbed false;

    private 
$params = array();
    private 
$structure = array();
    private 
$disabled_fields = array();

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

    /**
     * Заполняет массив полей формы
     * Должен быть переопределен в наследуемом классе
     */
//    public function init(){
//        return array();
//    }

    
public function setStructure($structure=array()){
        
$this->structure $structure;
    }

    
/**
     * Возвращает массив полей формы
     * @return array
     */
    
public function getStructure(){
        return 
$this->structure;
    }

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

    
public function setParams($params=array()){
        
$this->params $params;
    }

    public function 
getParams(){
        return 
$this->params;
    }

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

    
public function addHtmlBlock($id$content=null){

        
$this->structure[$id] = array(
            
'type' => 'html',
            
'content' => $content
        
);

        return 
$id;

    }

    public function 
addHtmlBlockToBeginning($id$content=null){

        
$block = array(
            
'type' => 'html',
            
'content' => $content
        
);

        
$this->structure = array($id => $block) + $this->structure;

        return 
$id;

    }

    public function 
addHtmlBlockAfter($after_id$id$content=null){

        
$block = array(
            
'type' => 'html',
            
'content' => $content
        
);

        
$pos array_search($after_idarray_keys($this->structure));

        
$before array_slice($this->structure0$pos+1);
        
$after array_slice($this->structure$pos 1);

        
$this->structure $before + array($id => $block) + $after;

        return 
$id;

    }

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

    /**
     * Добавляет набор полей в форму.
     * Возращает id набора полей
     * @param string $title Заголовок набора полей
     * @param string $id ID набора полей
     * @return mixed
     */
    
public function addFieldset($title=''$id=null$options=array()){

        if (
is_null($id)){
            
$id sizeof($this->structure);
        }

        
$fieldset = array(
            
'type' => 'fieldset',
            
'title' => $title,
            
'childs' => array()
        );

        
$fieldset array_merge($fieldset$options);

        
$this->structure[$id] = $fieldset;

        return 
$id;

    }

    public function 
addFieldsetToBeginning($title=''$id=null$options=array()){

        if (
is_null($id)){
            
$id sizeof($this->structure);
        }

        
$fieldset = array(
            
'type' => 'fieldset',
            
'title' => $title,
            
'childs' => array()
        );

        
$fieldset array_merge($fieldset$options);

        
$this->structure = array($id => $fieldset) + $this->structure;

        return 
$id;

    }

    public function 
addFieldsetAfter($after_id$title=''$id=null$options=array()){

        if (
is_null($id)){
            
$id sizeof($this->structure);
        }

        
$fieldset = array(
            
'type' => 'fieldset',
            
'title' => $title,
            
'childs' => array()
        );

        
$fieldset array_merge($fieldset$options);

        
$pos array_search($after_idarray_keys($this->structure));

        
$before array_slice($this->structure0$pos+1);
        
$after array_slice($this->structure$pos 1);

        
$this->structure $before + array($id => $fieldset) + $after;

        return 
$id;

    }

    public function 
getLastFieldsetId(){
        
        
$ids array_keys($this->structure);
        
        return 
$ids[count($ids)-1];
        
    }
    
    
/**
     * Добавляет поле в указанный набор полей формы
     * @param string $fieldset_id ID набора полей
     * @param string $name Название поля
     * @param array $params Параметры поля
     */
    
public function addField($fieldset_id$field){

        
$this->structure$fieldset_id ]['childs'][] = $field;

    }

    public function 
addFieldToBeginning($fieldset_id$field){

        
$this->structure$fieldset_id ]['childs'] = array($field->name => $field) + $this->structure$fieldset_id ]['childs'];

    }

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

    /**
     * Изменяет аттрибут набора полей в форме
     * @param string $fieldset_id ID набора полей
     * @param string $attr_name Название аттрибута
     * @param mixed $value Новое значение
     */
    
public function setFieldsetAttribute($fieldset_id$attr_name$value){

        
$this->structure$fieldset_id ][ $attr_name ] = $value;

    }

    
/**
     * Изменяет аттрибут поля в форме
     * @param string $fieldset_id ID набора полей
     * @param string $field_name Название поля
     * @param string $attr_name Название аттрибута
     * @param mixed $value Новое значение
     */
    
public function setFieldAttribute($fieldset_id$field_name$attr_name$value){
        foreach( 
$this->structure$fieldset_id ]['childs'] as $field) {
            if (
$field->getName() == $field_name){
                
$field->setOption($attr_name$value);
                break;
            }
        }
    }

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

    /**
     * Скрывает набор полей в форме
     * @param string $fieldset_id ID набора полей
     */
    
public function hideFieldset($fieldset_id){

        
$this->setFieldsetAttribute($fieldset_id'is_hidden'true);

    }

    
/**
     * Скрывает поле в форме
     * @param string $fieldset_id ID набора полей
     * @param string $field_name Название поля
     */
    
public function hideField($fieldset_id$field_name){

        
$this->setFieldAttribute($fieldset_id$field_name'is_hidden'true);

    }

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

    /**
     * Удаляет набор полей из формы
     * @param string $fieldset_id ID набора полей
     */
    
public function removeFieldset($fieldset_id){
        unset(
$this->structure$fieldset_id ]);
    }

    
/**
     * Удаляет поле из формы
     * @param string $fieldset_id ID набора полей
     * @param string $field_name Название поля
     */
    
public function removeField($fieldset_id$field_name){
        foreach( 
$this->structure$fieldset_id ]['childs'] as $field_id => $field) {
            if (
$field->getName() == $field_name){
                unset(
$this->structure$fieldset_id ]['childs'][ $field_id ]);
                break;
            }
        }
    }

    
/**
     * Отключает поле в форме
     * Поле не удаляется, но перестает участвовать в парсинге и валидации
     *
     * @param string $field_name Название поля
     */
    
public function disableField($field_name){
        
$this->disabled_fields[] = $field_name;
    }

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

    /**
     * Возвращает массив полей формы, заполнив их значениями переданными в запросе $request
     * @param cmsRequest $request
     * @param bool $is_submitted
     * @param array $item
     * @return array
     */
    
public function parse($request$is_submitted=false$item=false){

        
$result = array();

        foreach(
$this->structure as $fieldset){

            if (!isset(
$fieldset['childs'])) { continue; }

            foreach(
$fieldset['childs'] as $field){

                
$name $field->getName();

                
// если поле отключено, пропускаем поле
                
if (in_array($name$this->disabled_fields)){ continue; }

                
$is_array strstr($name':');

                
$value $request->get($namenull);

                if (
is_null($value) && $field->hasDefaultValue() && !$is_submitted) { $value $field->getDefaultValue(); }

                
$old_value $item ? (isset($item[$name]) ? $item[$name] : null) : null;

                
$field->setItem($item);

                
$value $field->store($value$is_submitted$old_value);

                if (
$value === false) { continue; }

                if (!
$is_array){
                    
$result[$name] = $value;
                }

                if (
$is_array){
                    
$name_parts explode(':'$name);
                    
$result[$name_parts[0]][$name_parts[1]] = $value;
                }

            }

        }

        return 
$result;

    }

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

    /**
     * Проверяет соответствие массива $data правилам
     * валидации указанным для полей формы
     * @param cmsController $controller
     * @param array $data
     * @param bool $is_check_csrf
     * @return bool Если ошибки не найдены, возвращает false
     */
    
public function validate($controller$data$is_check_csrf true){

        
$errors = array();

        
//
        // Проверяем CSRF-token
        //
        
if ($is_check_csrf){
            
$csrf_token $controller->request->get('csrf_token');
            if ( !
self::validateCSRFToken$csrf_token ) ){
                return 
true;
            }
        }

        
//
        // Перебираем поля формы
        //
        
foreach($this->structure as $fieldset){

            if (!isset(
$fieldset['childs'])) { continue; }

            foreach(
$fieldset['childs'] as $field){

                
$name $field->getName();

                
// если поле отключено, пропускаем поле
                
if (in_array($name$this->disabled_fields)){ continue; }

                
// если нет правил, пропускаем поле
                
if (!$field->getRules()){ continue; }

                
// проверяем является ли поле элементом массива
                
$is_array strstr($name':');

                
//
                // получаем значение поля из массива данных
                //
                
if (!$is_array){
                    
$value = isset($data[$name]) ? $data[$name] : '';
                }

                if (
$is_array){
                    
$name_parts explode(':'$name);
                    
$value = isset($data[$name_parts[0]][$name_parts[1]]) ? $data[$name_parts[0]][$name_parts[1]] : '';
                }

                if (
$data) { $field->setItem($data); }

                
//
                // перебираем правила для поля
                // и проверяем каждое из них
                //
                
foreach($field->getRules() as $rule){

                    if (!
$rule) { continue; }

                    
// каждое правило это массив
                    // первый элемент - название функции-валидатора
                    
$validate_function "validate_{$rule[0]}";

                    
// к остальным элементам добавляем $value, т.к.
                    // в валидаторах $value всегда последний аргумент
                    
$rule[] = $value;

                    
// убираем название валидатора из массива,
                    // оставляем только параметры (аргументы)
                    
unset($rule[0]);

                    
// вызываем валидатор и объединяем результат
                    // с предыдущими
                    
$result call_user_func_array(array($controller$validate_function), $rule);

                    
// если получилось false, то дальше не проверяем, т.к.
                    // ошибка уже найдена
                    
if ($result !== true) {
                        
$errors[$name] = $result;
                        break;
                    }

                }

            }

        }

        if (!
sizeof($errors)) { return false; }

        return 
$errors;

    }

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

    
public static function getCSRFToken(){

        if (
cmsUser::isSessionSet('csrf_token')){
            return 
cmsUser::sessionGet('csrf_token');
        }

        return 
self::generateCSRFToken();

    }

    
/**
     * Создает, сохраняет в сессии и возвращает CSRF-token
     * @return string
     */
    
public static function generateCSRFToken(){

        
$hash implode('::', array(session_id(), rand(09999), microtime(true)));
        
$token md5($hash);

        
cmsUser::sessionSet('csrf_token'$token);

        return 
$token;

    }

    
/**
     * Проверяет валидность CSRF-токена
     * @param string $csrf_token
     * @return bool
     */
    
public static function validateCSRFToken($csrf_token){
        return (
cmsUser::sessionGet('csrf_token') == $csrf_token);
    }

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

    
public static function mapFieldsToFieldsets($fields$callback=null$values=null){

        
$fieldsets = array();

        
$current null;

        
$index 0;

        
$fieldsets$index ] = array(
            
'title' => $current,
            
'fields' => array()
        );

        
$user cmsUser::getInstance();

        foreach(
$fields as $field){

            if (
is_callable($callback)){
                if (!
$callback$field$user )) { continue; }
            }

            if (
is_array($values)){
                if (empty(
$values$field['name'] ])){ continue; }
            }

            if (
$current != $field['fieldset']){

                
$current $field['fieldset'];
                
$index += 1;

                
$fieldsets$index ] = array(
                    
'title' => $current,
                    
'fields' => array()
                );

            }

            
$fieldsets$index ]['fields'][] = $field;

        }

        return 
$fieldsets;


    }

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

    /**
     * Загружает файлы с классами всех типов полей для генерации форм
     */
    
public static function loadFormFields(){

        return 
cmsCore::getFilesList('system/fields''*.php'falsetrue);

    }

    
/**
     * Возвращает список всех имеющихся типов полей
     * @return array
     */
    
public static function getAvailableFormFields($only_public true){

        
$fields_types   = array();
        
$fields_files   cmsCore::getFilesList('system/fields''*.php'truetrue);

        foreach (
$fields_files as $name) {

            
$class  'field' string_to_camel('_'$name);

            
$field = new $class(nullnull);

            if (
$only_public && !$field->is_public){ continue; }

            
$fields_types[$name] = $field->getTitle();

        }

        return 
$fields_types;

    }

    public static function 
getForm($form_file$form_name$params=false){

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

        
cmsForm::loadFormFields();

        include_once 
$form_file;

        
$form_class 'form' string_to_camel('_'$form_name);

        
$form = new $form_class();

        if (
$params){
            
$form->setParams($params);
            
$form->setStructurecall_user_func_array(array($form'init'), $params) );
        } else {
            
$form->setStructure$form->init() );
        }

        return 
$form;

    }

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

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