Как заставить этот фильтр работать после этого валидатора - PullRequest
6 голосов
/ 28 января 2011

У меня есть элемент. Я хочу добавить собственный валидатор и собственный фильтр. Валидатор проверяет, является ли входное значение одним из нескольких разрешенных значений, затем фильтр добавляет некоторые пользовательские значения к входным данным. Это означает, что я должен проверить исходный ввод перед запуском фильтра. Я делаю это в следующем порядке

$element = new Zend_Form_Element_Text('element');
$element->addValidator('PermittedValue', false);
$element->addFilter('TotalHyphen', false);
$this->addElement($element);

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

Примечание: проверка работает при фильтрации Значения Zend_Form_Element :: isValid () фильтрует значения через предоставленные Цепочка фильтров до проверки. Увидеть раздел Фильтры для более информация.

Как указать порядок запуска валидаторов и фильтров?

Ответы [ 4 ]

7 голосов
/ 28 января 2011

Конечно, похоже, что создание настраиваемого элемента, который поддерживает фильтрацию после проверки, будет правильным решением. Как насчет этого:

/**
 * An element that supports post-validation filtering
 */
class My_Form_Element_PostValidateFilterable extends Zend_Form_Element_Text
{
    protected $_postValidateFilters = array();

    public function setPostValidateFilters(array $filters)
    {
        $this->_postValidateFilters = $filters;
        return $this;
    }

    public function getPostValidateFilters()
    {
        return $this->_postValidateFilters;
    }

    public function isValid($value, $context = null)
    {
        $isValid = parent::isValid($value, $context);
        if ($isValid){
            foreach ($this->getPostValidateFilters() as $filter){
                $value = $filter->filter($value);
            }
            $this->setValue($value);
        }
        return $isValid;
    }
}

Использование будет примерно таким:

$elt = $form->addElement('PostValidateFilterable', 'myElement', array(
     'label' => 'MyLabel',
     'filters' => array(
         'StringTrim',
         // etc
     ),
     'validators' => array(
         'NotEmpty',
         // etc 
     ),
     // here comes the good stuff
     'postValidateFilters' => array(
         new My_Filter_RunAfterValidateOne(),
         new My_Filter_RunAfterValidateTwo(),
     ),
));

Это сохраняет проверку и фильтрацию в форме - поддерживая контроллер в тонком состоянии.

Не проверено, просто удар в темноте. И, конечно же, вы можете добавить / изменить API для добавления / удаления фильтров по ключу и т. Д.

Что ты думаешь?

4 голосов
/ 28 января 2011

Может быть, не добавлять фильтр вообще. Сначала проверьте содержимое в контроллере, а затем используйте фильтр отдельно:

$request = $this->getRequest();
if ($request->isPost() && $form->isValid($request->getParams())) {
    $filter = new Filter_Whatever();
    $val = $filter->filter($request->getParam('element'));
    ... //call your model or whatever
}

Я никогда не делал этого, но я полагаю, что это (или что-то подобное) может работать.

1 голос
/ 28 января 2011

То, чего вы хотите добиться, это изменить поведение по умолчанию при обработке текстового элемента.Таким образом, я думаю, что вы можете создать свой собственный элемент (например, My_Form_Element_Text), который расширяет Zend_Form_Element_Text и перегружает его метод isValid ().

В частности, вы можете просто изменить вторую строку в оригинальном методе isValid () с $value = $this->getValue(); на $value = $this->getUnfilteredValue();.Таким образом, ваша проверка будет выполняться с использованием нефильтрованных значений.

1 голос
/ 28 января 2011

Хороший вопрос!,

Фильтры AFAIK должны или должны работать перед проверкой ввода: из Документы ZF

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

, но если и только если вы в случае, которыйне может решить Mingos ответ должен быть помощь

...