2011-07-29 10 views
2

フォームには複数選択要素があります。選択されているアイテムの数を確認する必要があります(最小値と最大値)。Zendは複数選択値を検証します

要素が複数の値を持つことができる場合、各値は別々に検証されるという問題があります。

私は私のカスタムバリデータArraySizeで値を検証するためにfalseisArrayを設定しようとしましたが、新たな問題が登場:配列全体値はInArrayバリデータに渡され、検証が失敗します。だから私はregisterInArrayValidatorfalseに設定してそれをオフにしなければならなかった。

ここでは、選択した値の数の値を検証できますが、指定されたオプションへの対応を検証することはできません。

もう1つのカスタムバリデータを作成せずに問題を解決する方法はありますか?

+2

私は解決策は、カスタムバリデータの作成だと思うが。 http://framework.zend.com/manual/en/zend.validate.writing_validators.html – JellyBelly

答えて

-1

カスタムバリデーターを書かなくてもすばらしいことはありますが、普通のやり方から少しだけ何かを行う必要があるときは、何かを書いても間違いありません。

このようなケースのようです。

+0

実際には何も問題はありませんが、カスタムバリデーター(配列全体を検証する)を作成する方法は見当たりません。他の標準または非標準のバリデータと一緒に再利用することができます(validat配列の各要素は別々に)。 私の初期のタスクはカスタムバリデーターを書くことで解決できますが、私はそのためにいくつかのより一般的なアプローチについて疑問を抱いていました。 –

0

注:私はこれはZendの1

であると仮定してきた私はこれを行うには見ることができる唯一の方法は、複数選択を拡張し、カスタムのisValidを使用することでした。この方法では、一度に1つの値だけでなく、値の完全な配列を見ることができます。以下は

私のカスタム複数選択クラスは

<?php 
/** 
* My_MinMaxMultiselect 
*/ 
class My_MinMaxMultiselect extends Zend_Form_Element_Multiselect 
{ 
    /** 
    * Validate element contains the correct number of 
    * selected items. Check value against minValue/maxValue 
    * 
    * @param mixed $value 
    * @param mixed $context 
    * @return boolean 
    */ 
    public function isValid($value, $context = null) 
    { 
     // Call Parent first to cause chain and setValue 
     $parentValid = parent::isValid($value, $context); 

     $valid = true; 

     if ((('' === $value) || (null === $value)) 
      && !$this->isRequired() 
      && $this->getAllowEmpty() 
     ) { 
      return $valid; 
     } 

     // Get All Values 
     $minValue = $this->getMinValue(); 
     $maxValue = $this->getMaxValue(); 

     $count = 0; 
     if (is_array($value)) { 
      $count = count($value); 
     } 

     if ($minValue && $count < $minValue) { 
      $valid = false; 
      $this->addError('The number of selected items must be greater than or equal to ' . $minValue); 
     } 

     if ($maxValue && $count > $maxValue) { 
      $valid = false; 
      $this->addError('The number of selected items must be less than or equal to ' . $maxValue); 
     } 

     return ($parentValid && $valid); 
    } 

    /** 
    * Get the Minimum number of selected values 
    * 
    * @access public 
    * @return int 
    */ 
    public function getMinValue() 
    { 
     return $this->getAttrib('min_value'); 
    } 

    /** 
    * Get the Maximum number of selected values 
    * 
    * @access public 
    * @return int 
    */ 
    public function getMaxValue() 
    { 
     return $this->getAttrib('max_value'); 
    } 

    /** 
    * Set the Minimum number of selected Values 
    * 
    * @param int $minValue 
    * @return $this 
    * @throws Bad_Exception 
    * @throws Zend_Form_Exception 
    */ 
    public function setMinValue($minValue) 
    { 
     if (is_int($minValue)) { 
      if ($minValue > 0) { 
       $this->setAttrib('min_value', $minValue); 
      } 

      return $this; 
     } else { 
      throw new Bad_Exception ('Invalid value supplied to setMinValue'); 
     } 
    } 

    /** 
    * Set the Maximum number of selected values 
    * 
    * @param int $maxValue 
    * @return $this 
    * @throws Bad_Exception 
    * @throws Zend_Form_Exception 
    */ 
    public function setMaxValue($maxValue) 
    { 
     if (is_int($maxValue)) { 
      if ($maxValue > 0) { 
       $this->setAttrib('max_value', $maxValue); 
      } 

      return $this; 
     } else { 
      throw new Bad_Exception ('Invalid value supplied to setMaxValue'); 
     } 
    } 

    /** 
    * Retrieve error messages and perform translation and value substitution. 
    * Overridden to avoid errors from above being output once per value 
    * 
    * @return array 
    */ 
    protected function _getErrorMessages() 
    { 
     $translator = $this->getTranslator(); 
     $messages = $this->getErrorMessages(); 
     $value = $this->getValue(); 
     foreach ($messages as $key => $message) { 
      if (null !== $translator) { 
       $message = $translator->translate($message); 
      } 
      if (($this->isArray() || is_array($value)) 
       && !empty($value) 
      ) { 
       $aggregateMessages = array(); 
       foreach ($value as $val) { 
        $aggregateMessages[] = str_replace('%value%', $val, $message); 
       } 
       // Add additional array unique to avoid the same error for all values 
       $messages[$key] = implode($this->getErrorMessageSeparator(), array_unique($aggregateMessages)); 
      } else { 
       $messages[$key] = str_replace('%value%', $value, $message); 
      } 
     } 

     return $messages; 
    } 
} 

ユーザーは正確に3つのオプションを選択しなければならない形でこれを使用することです:

$favouriteSports = new MinMaxMultiselect('favourite_sports'); 
    $favouriteSports 
     ->addMultiOptions(array(
      'Football', 
      'Cricket', 
      'Golf', 
      'Squash', 
      'Rugby' 
     )) 
     ->setRequired() 
     ->setLabel('Favourite Sports') 
     ->setMinValue(3) 
     ->setMaxValue(3); 
関連する問題