0

在我的Form我有一個Fieldset,它包含foobar兩個元素。他們的業務規則是,必須設定。因此,當設置foobar時,字段集有效,並且在設置無人時爲無效。如何在Zend Framewor 2中爲所需的表單字段設置自定義錯誤消息?

我解決了這個如下:

public function getInputFilterSpecification() 
{ 
    return [ 
     'foo' => [ 
      'required' => empty($this->get('bar')->getValue()) 
     ], 
     'bar' => [ 
      'required' => empty($this->get('foo')->getValue()) 
     ], 
    ]; 
} 

工作。但是,錯誤消息仍然存在問題:如果bot字段爲空,則用戶會爲每個字段獲取消息「值是必需的且不能爲空」。用戶認爲,他必須填寫這兩個字段。

如何自定義錯誤消息的required,以顯示正確的一樣的消息「是必需的foo的價值,不能爲空,如果沒有設置吧。」並且「如果foo未設置,則bar的值是必需的,並且不能爲空。」

回答

0

你可以通過擴展默認鏈

WIRTE定製ValidatorChain然後,您可以重寫此方法:

/** 
* Returns true if and only if $value passes all validations in the chain 
* 
* Validators are run in the order in which they were added to the chain (FIFO). 
* 
* @param mixed $value 
* @param mixed $context Extra "context" to provide the validator 
* @return bool 
*/ 
public function isValid($value, $context = null) 
{ .. } 

默認情況下,如果所有驗證返回true這種方法只會返回true,但它也可以訪問上下文 - 這意味着您也可以獲得所有其他字段值。

修改邏輯很簡單,然後檢查兩個驗證器之一是否真實返回true。

然後,您只需連接所有你想成爲

-1

您probaly與自定義驗證這樣結束了「這些需要一個」字段:

class MyCustomValidator extends ZendAbstractValidator 
{ 
    const FIELDS_EMPTY = 'fieldsEmpty'; 

    /** 
    * Error messages 
    * 
    * @var array 
    */ 
    protected $abstractMessageTemplates = [ 
     self::FIELDS_EMPTY => "Vale for %field1% is required and can't be empty, if %field2% is not set.", 
    ]; 

    /** 
    * Variables which can be used in the message templates 
    * 
    * @var array 
    */ 
    protected $abstractMessageVariables = [ 
     'field1' => 'field1', 
     'field2' => 'field2', 
    ]; 

    /** 
    * Value of the field 
    * @var mixed 
    */ 
    protected $value; 

    /** 
    * Name of the first field to check, which the validator is bind to 
    * @var mixed 
    */ 
    protected $field1; 

    /** 
    * Name of the second field to check 
    * @var string 
    */ 
    protected $field2; 

    /** 
    * MyCustomValidator constructor. 
    * 
    * @param array|null|\Traversable $options 
    * 
    * @throws \Exception 
    */ 
    public function __construct($options) 
    { 
     if ($options instanceof Traversable) { 
      $options = ArrayUtils::iteratorToArray($options); 
     } 

     if (!array_key_exists('field1', $options) || !array_key_exists('field2', $options)) { 
      throw new \Exception('Options should include both fields to be defined within the form context'); 
     } 

     $this->field1 = $options['field1']; 
     $this->field2 = $options['field2']; 

     parent::__construct($options); 
    } 

    /** 
    * Returns true if and only if $value meets the validation requirements 
    * If $value fails validation, then this method returns false, and 
    * getMessages() will return an array of messages that explain why the 
    * validation failed. 
    * 
    * @param mixed $value 
    * @param array $context 
    * 
    * @return bool 
    */ 
    public function isValid($value, $context = []) 
    { 
     $this->setValue($value); 

     if (empty($value) && (array_key_exists($this->field2, $context) || empty($context[$this->field2]))) { 
      $this->error(self::FIELDS_EMPTY); 

      return false; 
     } 

     return true; 
    } 
} 

那麼如何使用它:

public function getInputFilterSpecification() 
{ 
    return [ 
     'foo' => [ 
      'validators' => [ 
       [ 
        'name' => MyCustomValidator::class, 
        'options' => [ 
         'field1' => 'foo', 
         'field2' => 'bar', 
        ] 
       ] 
      ] 
     ], 
     'bar' => [ 
      'validators' => [ 
       [ 
        'name' => MyCustomValidator::class, 
        'options' => [ 
         'field1' => 'bar', 
         'field2' => 'foo', 
        ] 
       ] 
      ] 
     ], 
    ]; 
} 

對於那些誰不知道如何註冊MyCustomValidator - 在你module.config.php或您的Module.php內使用public function getValidatorConfig()。不要同時使用,它是一個或另一個:

如何在module.config.php註冊

'validators' => array(
    'factories' => array(
     MyCustomValidator::class => MyCustomValidatorFactory::class, 
    ), 
), 

如何在module.php註冊:

/** 
* Expected to return \Zend\ServiceManager\Config object or array to 
* seed such an object. 
* @return array|\Zend\ServiceManager\Config 
*/ 
public function getValidatorConfig() 
{ 
    return [ 
     'aliases' => [ 
      'myCustomValidator' => MyCustomValidator::class, 
      'MyCustomValidator' => MyCustomValidator::class, 
      'mycustomvalidator' => MyCustomValidator::class, 
     ], 
     'factories' => [ 
      MyCustomValidator::class => MyCustomValidatorFactory::class, 
     ], 
    ]; 
} 

的工廠類:

class MyCustomValidatorFactory implements FactoryInterface, MutableCreationOptionsInterface 
{ 
    /** 
    * Options for the InputFilter 
    * 
    * @var array 
    */ 
    protected $options; 

    /** 
    * Create InputFilter 
    * 
    * @param ServiceLocatorInterface $serviceLocator 
    * 
    * @return BlockChangeOnSerialsValidator 
    */ 
    public function createService(ServiceLocatorInterface $serviceLocator) 
    { 
     return new MyCustomValidator($this->options); 
    } 

    /** 
    * Set creation options 
    * 
    * @param array $options 
    * 
    * @return void 
    */ 
    public function setCreationOptions(array $options) 
    { 
     $this->setOptions($options); 
    } 

    /** 
    * Set options 
    * 
    * @param array $options 
    */ 
    public function setOptions(array $options) 
    { 
     $this->options = $options; 
    } 
} 

注意,我不停的驗證isValid()方法,我不知道這是ç很簡單凌駕你的情況,但這是爲了幫助你朝正確的方向前進。但是可以進行的改進是重複使用NotEmpty驗證器來檢查該字段是否爲空。

請注意,當您調用$form->setData($this->getRequest()->getPost())時,isValid($value, $context = null)窗體中的上下文是formData。

+0

非常感謝您的回答,但在問題描述的「有條件需求」字段中不起作用。請閱讀這個問題。 – automatix

+0

啊,好吧。由於突出顯示了「如何自定義錯誤消息的消息」,因此我發現我的結論很可能很快。將嘗試更新我的答案,因爲它可能會來一個自定義驗證器。 – Kwido

+0

@automatix我的更新回答對你有幫助嗎?由於問題仍未得到解答,您是否找到了解決方案? – Kwido

相關問題