Обработка форм, валидация ввода

A1x

Новичок
whirlwind ok валидация модели - хорошая идея, убедили...
при декомпозиции да, важно уметь вовремя остановиться)
 

Духовность™

Продвинутый новичок
Сегодня ночью я озаботился тем, что модель у меня могла принимать все подряд и решил сделать валидацию в модели согласно сказанному в этом топике.

Решено было создать к карте свойств модели дополнительный массив данных, описывающий правила валидации для поступающих в модель данных. Теперь описание свойств модели выглядит так: http://pastebin.com/yAE2ngC7
Массивы validators в описаниях свойств модели указывает правила и параметры валидации.
Валидация происходит в момент, когда пустому объекту модели присваиваются значения через виртуальные методы или __set:

PHP:
    protected function post()
    {
        // создаем объект модели из POST-a
        // в этом методе создается пустой объект модели
        // и данные из POST-запроса присваиваются модели.
        // если данные не проходят валидацию, объект модели будет знать об этом
        // и содержать всю информацию об ошибках 
        $this->user = $this->user_mapper->createFromPost( $this->getRequest()->getPost('user') );

        // ошибки есть - информируем об этом view 
        if ($errors = $this->user->getValidateErrors())
        {
            foreach ($errors as $key => $data)
            {
                // ...
            }
        }  
// ...
Валидаторы выглядят примерно так:
http://pastebin.com/m1yM7KLA
http://pastebin.com/4pPii7mN
http://pastebin.com/Ar5ZvuWN

Всё получилось, но право "схавывать все подряд" я оставил за моделью. Почему - это удобно для View - в шаблоне можно использовать модель с "ошибочными" значениями, когда, например, произошла ошибка POST-запроса и ошибочные значения нужно показывать в полях ввода. Т.е. я не делаю assign каждой переменной шаблона, а отдаю во view объект модели и там вывожу необходимые свойства модели, используя всю мощь объектной модели:

PHP:
   <tr>
        <th colspan="2"><h4>
            <? if($this->user->getId()): ?>
                Редактирование настроект пользователя <?=$this->user->getFullName() // модель во view - это удобно!?>
            <? else: ?>
                Добавление пользователя
            <? endif; ?></h4>
        </th>
    </tr>

<? if($this->user->getVisitdate()): ?>
    <tr>
        <!-- без явного объекта модели во view пришлось бы гонять данные туда-сюда  -->
        <td>Последнее посещение:</td><td><?=$this->user->getVisitdate()->format('d.m.Y H:i:s')?>
    </tr>
<? endif; ?>
 

A1x

Новичок
Валидация происходит в момент, когда пустому объекту модели присваиваются значения через виртуальные методы или __set:
т.е. валидация будет происходить при каждом присвоении значения каждому свойству?

я бы сделал в модели какой-то флаг isValidated и сбрасывал его по __set
потом например перед сохранением если isValidated == false - выполняем валидацию и выставляем isValidated в случае успеха
 

Духовность™

Продвинутый новичок
т.е. валидация будет происходить при каждом присвоении значения каждому свойству?
конечно. Как иначе то?

-~{}~ 20.08.10 17:46:

я бы сделал в модели какой-то флаг isValidated
массив ошибок в модели - это есть флаг валидации, точнее результат валидации. Зачем ещё какие-то флаги вводить?
 

A1x

Новичок
чтобы делать валидацию не отдельных полей а всей модели, иногда проверка поля может зависеть от других полей
 

whirlwind

TDD infected, paranoid
право "схавывать все подряд" я оставил за моделью. Почему - это удобно для View - в шаблоне можно использовать модель с "ошибочными" значениями, когда, например, произошла ошибка POST-запроса и ошибочные значения нужно показывать в полях ввода.
На предыдущих страницах я намекал как это можно по другому решить
PHP:
    function toModel($attr, $value) {
        $this->object->on('invalidate', 'onAttributeInvalidate', $this);
        $this->object->on('modified', 'onAttributeModified', $this);
        $setter = "set{$attr}";
        $this->object->$setter($value);
        $this->object->un('invalidate', 'onAttributeInvalidate', $this);
        $this->object->un('modified', 'onAttributeModified', $this);
    } 
    
    function onAttributeInvalidate($attr, $value, $object) {
        $view = $this->context->getView();
        $view->setVar("{$attr}Err", true);
        $view->setVar($attr, $value);
        $this->errors ++;
    }
    
    function onAttributeModified($attr, $value, $object) {
        $view = $this->context->getView();
        $view->setVar("{$attr}Err", false);
        $view->setVar($attr, $value);
    }
 

weregod

unserializer
A1x
+1

валидацию изменения каждого поля можно иметь только в отладочном коде
 
Сверху