6

私には要素があります。カスタムバリデーターとカスタムフィルターを追加したいと思います。バリデーターは、入力がいくつかの許可された値の1つであることを確認してから、フィルターがいくつかのカスタム値を入力に追加します。これは、フィルターを実行する前に、最初に元の入力を検証する必要があることを意味します。この順番でやります

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

しかし、この順序は尊重されていません。フィルタが最初に実行されてデータが変更され、次にバリデーターがフィルタリングされたデータに対して実行されます。つまり、有効な入力に対しても常に失敗します。ドキュメントから、これは意図的なもののようです

注:検証はフィルター処理された値で動作しますZend_Form_Element :: isValid()は、検証の前に、提供されたフィルターチェーンを介して値をフィルター処理します。詳細については、「フィルター」セクションを参照してください。

バリデーターとフィルターが実行される順序を指定するにはどうすればよいですか?

4

4 に答える 4

7

確かに、検証後のフィルタリングをサポートするカスタム要素を作成するのが道のようです。これはどう:

/**
 * 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を肥大化/変更して、キーなどでフィルターを追加/削除することができます。

ファディアは思いますか?

于 2011-01-28T13:57:51.267 に答える
4

たぶん、フィルターをまったく追加しないでください。最初にコントローラーでコンテンツを検証してから、フィルターを個別に使用します。

$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
}

私はこれを行ったことはありませんが、これ (または同様のもの) が機能する可能性があると思います。

于 2011-01-28T00:38:01.953 に答える
1

達成したいのは、テキスト要素の処理方法のデフォルトの動作を変更することです。したがって、Zend_Form_Element_Text を拡張し、その isValid() メソッドをオーバーロードする独自の要素 (例: My_Form_Element_Text) を作成できると思います。

具体的には、元の isValid() メソッドの 2 行目を から に変更するだけ $value = $this->getValue();です$value = $this->getUnfilteredValue();。このようにして、フィルタリングされていない値を使用して検証が実行されます。

于 2011-01-28T03:16:20.637 に答える
1

いい視点ね !、

AFAIKフィルターは、入力を検証する前に実行する必要があるか、実行する必要があります: ZFドキュメントから

検証の前に、入力に対して何らかの正規化を実行することが有用である、または必要な場合がよくあります。たとえば、すべての HTML を削除したい場合がありますが、送信が有効であることを確認するために残っているものに対して検証を実行します。または、StringLength バリデーターが先頭または末尾の空白文字をカウントせずに入力の正しい長さを使用するように、入力の周囲の空白を削除することもできます。

しかし、ミンゴスの答えを解決できない場合にのみ、助けにならなければなりません

于 2011-01-28T00:42:59.787 に答える