Добавление входного фильтра в набор полей в ZF2

У меня есть форма Register , у которой есть Profile Fieldset Profile , который, в свою очередь, имеет Account fieldset. InputFilterProviderInterface реализуют InputFilterProviderInterface и, следовательно, метод getInputFilterSpecification . Здесь я добавил общие валидаторы и фильтры, которые должны использоваться всякий раз, когда используются поля.

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

 class Register extends Zend\InputFilter\InputFilter { public function __construct() { $this->add(new RegisterProfileFilter(), 'profile'); } } 

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

  1. Кажется, мне нужно создать фильтр ввода для каждого из моих полей в иерархии; в этом случае мне нужно создать входной фильтр для поля Profile чтобы я мог добавить фильтр ввода в набор полей Account даже если мне не нужно добавлять какие-либо валидаторы или что-либо в поле Profile . Это не работает, если я попытаюсь добавить фильтр в поле ввода
  2. Кажется, что добавление объекта входного фильтра в набор полей уничтожает фильтр, который я определил в методе getInputFilterSpecification метода fieldset вместо слияния двух, как я хочу

Есть ли способ объединить спецификацию входного фильтра, определенную на моих полях с дополнительной спецификацией (или экземпляр Zend\InputFilter\InputFilter , так что мне не нужно копировать спецификацию fieldset в свой класс входных фильтров? Это будет дублировать код и не быть очень легко обслуживаемым. Или я пропустил что-то, что привело меня к неправильному пути?

Ниже мой код, если он полезен в любом случае.

 // The code has been altered to be more self-explanatory and shorter class RegisterForm extends \Zend\Form\Form { public function __construct() { parent::__construct('register'); // Elements are added here $profileFieldset = new ProfileFieldset(); $profileFieldset->setUseAsBaseFieldset(true); $this->add($profileFieldset); } } class ProfileFieldset extends \Zend\Form\Fieldset implements InputFilterProviderInterface { public function __construct() { parent::__construct('profile'); // Elements are added here $this->add(new AccountFieldset()); } public function getInputFilterSpecification() { return array( /***** The below is apparently cleared when adding an input filter to this fieldset *****/ 'some_element1' => array( 'required' => false, ), 'some_element2' => array( 'required' => false, ), ); } } class AccountFieldset extends \Zend\Form\Fieldset implements InputFilterProviderInterface { public function __construct() { parent::__construct('account'); // Elements are added here } public function getInputFilterSpecification() { return array( /***** This is the element that I want to add an additional validator to in a specific context (form) *****/ 'username' => array( 'required' => true, 'validators' => array( new Validator\StringLength(array( 'min' => 4, 'max' => 15, )), new I18nValidator\Alnum(false), ), ), // Other elements here ); } } 

Слияние InputFilters не очень хорошо освещено в компоненте Zend\Form . Кто-то должен действительно реорганизовать все это.

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

 class RegisterForm extends \Zend\Form\Form { public function __construct() { // add stuff } public function getInputFilter() { $formInputFilter = parent::getInputFilter(); $usernameInput = $formInputFilter->get('profile')->get('account')->get('username'); $myValidator = new Validator\SomeValidator(); $usernameInput->getValidatorChain()->addValidator($myValidator); return $formInputFilter; } } 

В качестве побочного элемента я бы рекомендовал определить InputFilters каждой Form а не для Fieldset , поскольку элементы в Fieldset часто имеют разные «требования проверки» в разных контекстах (= Form). Но, возможно, это более личное предпочтение.