0

У меня Form У меня есть Fieldset, который содержит два элемента: foo и bar. Бизнес-правило для них - это то, что нужно установить. Таким образом, набор полей действителен, когда foo ИЛИ bar установлен и недействителен, когда никто не установлен.Как настроить собственное сообщение об ошибке для поля требуемой формы в Zend Framewor 2?

Я решил это следующим образом:

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

работает. Но сообщение об ошибках все еще остается проблемой: если поля бота пустые, пользователь получает для каждого поля сообщение «Значение требуется и не может быть пустым». Тогда пользователь думает, что он должен заполнить оба поля.

Как настроить сообщение об ошибке для required поля, чтобы показать правильные сообщения типа «Значение для обув является обязательным и не может быть пустым, если бар не установлен.» и «Значение для бара требуется и не может быть пустым, если foo не установлен». ?

ответ

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) 
{ .. } 

По умолчанию этот метод только возвращает истину, если ВСЕ валидаторы возвращает истину, но также имеет доступ к контексту - это означает, что вы также можете получить все другие значения поля.

Проще изменить логику, чтобы затем проверить, верны ли истинные истинные истины.

Вы тогда просто приложить все поля, которые вы хотите быть «один из них требуется»

-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 или использовать public function getValidatorConfig() в вашем module.php. Не использовать оба, это один или другой:

Как зарегистрироваться в вашей 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, чтобы проверить, пустое ли поле или нет.

Обратите внимание: Контекст witin формы isValid($value, $context = null) является формойОбъявление при звонке $form->setData($this->getRequest()->getPost()).

+0

Спасибо за ваш ответ, но он не работает в случае с «условно обязательными» полями, которые я описал в вопросе. Пожалуйста, прочитайте вопрос. – automatix

+0

Ahh okay. Я вижу, что мне было немного поскорее с моим завершением, потому что вы выделили «Как настроить сообщение об ошибке». Попробуем обновить свой ответ, так как это, скорее всего, придет к настраиваемому валидатору. – Kwido

+0

@automatix Помог ли мой обновленный ответ? Поскольку вопрос по-прежнему остается без ответа, вы нашли решение уже для него? – Kwido