У меня есть форма 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
, и в пределах этого входного фильтра я могу сделать то же самое для моего набора полей. Однако, похоже, есть две проблемы с этим подходом:
Profile
чтобы я мог добавить фильтр ввода в набор полей Account
даже если мне не нужно добавлять какие-либо валидаторы или что-либо в поле Profile
. Это не работает, если я попытаюсь добавить фильтр в поле ввода 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). Но, возможно, это более личное предпочтение.