Проверка нескольких необязательных полей формы с помощью Zend Framework

Я пытаюсь проверить Zend_Form, у которого есть несколько необязательных полей, и я хочу, чтобы было заполнено хотя бы одно из них. В моем случае у меня есть номера мобильных, домашних и офисных телефонов, и я хочу, чтобы был предоставлен хотя бы один из них.

Я пытаюсь добиться этого с помощью контекста проверки (как предлагается здесь ) путем создания настраиваемого валидатора, расширяющего Zend_Validate_Abstract. Проблема в том, что если все необязательные поля пусты, они отсутствуют в форме $ context (передается классу валидатора) и таким образом вообще не проверяется. Итак, если вы заполните один или несколько из трех вариантов (мобильный, домашний, рабочий), все они будут проверены (что нормально, но для этого не требуется настраиваемый валидатор), но если вы не заполните ни один из них, будет нет возможности заставить клиента заполнить хотя бы одно из полей (что является моей целью).

Вот что у меня есть:

1. моя форма

<?php

class Application_Form_Application extends Zend_Form {

  public function init() {
    $this->setName('application');

    // attach sub forms to main form
    $this->addSubForms(array(
      'application' => $this->application(),
      ...
    ));
  }

  private function application() {
    $application = new Zend_Form_SubForm();
    // custom phone validation
    $phone_validation = array('phone_mobile' => 'Mobile', 'phone_home' => 'Home', 'phone_work' => 'Work');
    // phone mobile
    $app['phone_mobile'] = new Zend_Form_Element_Text('phone_mobile');
    $app['phone_mobile']->setLabel('Mobile')
                        ->addFilter('StripTags')
                        ->addFilter('StringTrim')
                        ->addValidator('Regex', false, array('/^[0-9]{8}$/i'))
                        ->addValidator(new Application_Form_PhoneMobileHomeWork($phone_validation), false);
    // phone home
    $app['phone_home'] = new Zend_Form_Element_Text('phone_home');
    $app['phone_home']->setLabel('Home')
                      ->addFilter('StripTags')
                      ->addFilter('StringTrim')
                      ->addValidator('Regex', false, array('/^[0-9]{8}$/i'))
                      ->addValidator(new Application_Form_PhoneMobileHomeWork($phone_validation), false);
    // phone work
    $app['phone_work'] = new Zend_Form_Element_Text('phone_work');
    $app['phone_work']->setLabel('Work')
                      ->addFilter('StripTags')
                      ->addFilter('StringTrim')
                      ->addValidator('Regex', false, array('/^[0-9]{8}$/i'))
                      ->addValidator(new Application_Form_PhoneMobileHomeWork($phone_validation), false);
    $application->AddElements($app);
  }

}
?>

2. пользовательский валидатор

<?php

class Application_Form_PhoneMobileHomeWork extends Zend_Validate_Abstract {

  const NOT_PRESENT = 'notPresent';

  protected $_messageTemplates = array(
    self::NOT_PRESENT => 'At least one contact phone shall be provided!'
  );

  protected $_listOfFields;

  public function __construct(array $listOfFields) {
    $this->_listOfFields = $listOfFields;
    var_dump($listOfFields);exit;
  }

  public function isValid($value, $context = null) {
    var_dump($context);exit;
    ...
  }
?>

Валидатор всегда проходит через первый дамп ($ listOfFields), но если я его удалю, isValid () никогда не будет вызван, если некоторые данные не введены в некоторые поля телефона (что мы хотим предотвратить).

Когда я проверил дальше, я нашел решение в расширении класса Zend_Validate, передав пустые поля в параметр $ context, но я хотел бы получить лучшее решение, если кто-то знает.

Подводя итог - как проверить определенную форму, заставив пользователя заполнить хотя бы одно из нескольких необязательных полей?


person gogh    schedule 16.04.2012    source источник


Ответы (2)


Если я вас правильно понимаю, вы хотите, чтобы ваши элементы формы не были обязательными, но чтобы они не были пустыми (кроме случаев, когда один из них не пуст) с помощью настраиваемого валидатора? Затем, чтобы не пропустить цепочку проверки, вам нужно предотвратить их пустоту, вызывая метод setAllowEmpty(false) в каждом из ваших элементов.

Наконец, в вашем настраиваемом валидаторе у вас будет что-то вроде этого:

foreach ($this->_listOfFields as $field) {
    if (isset($context[$field]) AND $context[$field])
    {
        return true;
    }
}

Также убедитесь, что ваши элементы не требуются (setRequired(false)).

person Liyali    schedule 16.04.2012
comment
Действительно, setAllowEmpty (false) принудительно проходит через цепочку проверки, но это не всегда требуется, например если у вас есть дополнительные проверки, они будут активированы, и таким образом клиент будет вынужден заполнить каждое поле. Но в целом ваше предложение требует проверки пользовательских правил, что отвечает на мой вопрос. Обратите внимание, что я новичок в Zend Framework. Спасибо за подсказку, я думаю, что смогу с этим справиться. - person gogh; 16.04.2012

Проблема в том, что если какое-либо поле заполнено, элемент multi_checkbox не существует в форме, и тогда он не будет проверен.

Одно из решений заключается в следующем: используйте скрытый параметр, который всегда проверяется, и убедитесь, что он всегда проверяется, это больше, чем один из других.

person josepmra    schedule 27.03.2013