0

要素レベルで動的検証を実装できますか?私はthisの例を使用して、他の要素の値に依存する1つの要素の検証を実装しました。しかし、この目的のために、私はこの要素(コメント)をこの検証で使用するすべての単一のフォームに対してこれを実装する必要があります。私はそのような形をたくさん持っています。要素レベルで動的検証を実装できますか?

何らかの種類の「data-comment-for」属性を使用してこのフィルタ/検証ロジックを要素レベルに持ち、親フォームから依存する要素の値を取得するには。

これが私の現在のコードである(しかし、私は今、すべてのフォームのためにそれを持っている必要がありますそれは全く優雅な見ていません。):

class CompetencyAdvanceHumanRightsAndJusticeFormFilter extends InputFilter 
{ 
    public function isValid($context = null) 
    { 
     $figradeCommentName = 'applJusticeFIGrade'.'Comment'; 

     $forGrade = $this->get('applJusticeFIGrade'); 
     $gradeComment = $this->get($figradeCommentName); 

     $applJusticeFIGradeRawValue = $forGrade->getRawValue('applJusticeFIGrade'); 

     if(is_numeric($applJusticeFIGradeRawValue)){ 
      $gradeValue = intval($applJusticeFIGradeRawValue); 
     }else{ 
      $gradeValue = $applJusticeFIGradeRawValue; 
     } 

     if ($gradeValue != 'na' && $gradeValue > 0) { 
      $gradeComment->setRequired(true); 
      $validatorChain = new Validator\ValidatorChain(); 
      $validatorChain->attach(
       new Validator\NotEmpty(), 
       true 
      ); 
      $gradeComment->setValidatorChain($validatorChain); 
     } 

     return parent::isValid($context); 
    } 

    public function __construct(){ 
     $this->add(array(
      'name' => 'id', 
      'required' => true, 
      'filters' => array(
       array('name' => 'Int'), 
      ), 
     )); 

     $this->add(array(
      'name' => 'studEvalId', 
      'required' => true, 
      'filters' => array(
       array('name' => 'Int'), 
      ), 
     )); 
    } 
} 

編集:私は、コードを追加

カスタム要素を質問に追加します。このロジックを要素レベルに配置しようとする私の試みの「残り物」があります。

comment要素

class Comment extends Element implements InputProviderInterface 
{ 

    /** 
    * @var ValidatorInterface 
    */ 
    protected $validator; 

    // set its type 
    protected $attributes = array(
     'type' => 'comment' 
    ); 


    public function init() 
    { 

     if (null === $this->validator) { 

      $validator = new StringLength(); 
      $validator->setMax(10); 

      $validator->setMessage('The comment should not exceed 1000 letters!', StringLength::INVALID); 

      $this->validator = $validator; 
     } 


    } 


    /** 
    * Get a validator if none has been set. 
    * 
    * @return ValidatorInterface 
    */ 
    public function getValidator() 
    { 
     return $this->validator; 
    } 


    /** 
    * @param ValidatorInterface $validator 
    * @return $this 
    */ 
    public function setValidator(ValidatorInterface $validator) 
    { 
     $this->validator = $validator; 
     return $this; 
    } 


    /** 
    * remove require and validator defaults because we have none 
    * 
    * @return array 
    */ 
    public function getInputSpecification() 
    { 
//  return array(
//   'name' => $this->getName(), 
//   'required' => false, 
//   'validators' => array(
//    $this->getValidator(), 
//   ), 
//   'filters' => array(
//    new FIGradeCommentDynamicBufferFilter() 
//   ), 
//  ); 


     return array(
      'name' => $this->getName(), 
      'required' => false, 
      'filters' => array(
       array('name' => 'Zend\Filter\StringTrim'), 
      ), 
      'validators' => array(
       $this->getValidator(), 
      ), 

     ); 
    } 

    // tell it where to find its view helper, so formRow and the like work correctly 
    public function getViewHelperConfig() 
    { 
     return array('type' => '\OnlineFieldEvaluation\View\Helper\FormComment'); 
    } 

} 
あなたは基本抽象入力フィルタクラスとインターフェイスを作成し、すべてのフォームのフィルタを使用すると、フォーム内の期待メソッドを持つインターフェイスを実装する基本クラスを拡張させることができ

答えて

1

クラスを正しく動作させることができます。

メソッドとのインタフェースを行います。

interface GradeCommentFormFilterInterface() 
{ 
    protected function getGradeInput(); 

    protected function getCommentInput(); 
} 

次に、あなたがあなたのベースクラスに共通するコードを移動:

abstract class BaseGradeCommentFormFilter extends InputFilter implements GradeCommentFormFilterInterface 
{ 
    protected function getGradeInput() 
    { 
     return $this->get(static::GRADE_NAME); 
    } 

    protected function getCommentInput() 
    { 
     return $this->get(static::GRADE_NAME . 'Comment'); 
    } 

    public function isValid($context = null) 
    { 
     $gradeInput = $this->getGradeInput(); 
     $commentInput = $this->getCommentInput(); 
     $rawValue = $this->getRawValue($gradeInput); 

     if(is_numeric($rawValue)) 
     { 
      $gradeValue = intval($rawValue); 
     } 
     else 
      $gradeValue = $rawValue; 

     if ($gradeValue != 'na' && $gradeValue > 0) { 
      $commentInput->setRequired(true); 
      $validatorChain = new Validator\ValidatorChain(); 
      $validatorChain->attach(
       new Validator\NotEmpty(), 
       true 
      ); 
      $commentInput->setValidatorChain($validatorChain); 
     } 
     return parent::isValid($context); 
    } 
} 

今、あなたはこのようなあなたの抽象クラスを使用することができます。

class CompetencyAdvanceHumanRightsAndJusticeFormFilter extends BaseGradeCommentFormFilter 
{ 
    const GRADE_NAME = 'applJusticeFIGrade'; 

    //... other code 
} 

すぐにあなたのケースでうまく動作しようとしましたが、これはテストされていません。これを最適化する方法はありますが、それはあなたができることのアイデアを提供します。

+0

ニース!ですから、Comment Elementの指定の中に配置する方法はないと思いますか? – vlr

+0

質問にカスタム要素のコードを追加しました。このロジックを要素レベルに配置しようとする私の試みの「残り物」があります。 – vlr

関連する問題