I have several fields, and I would like to create an input filter class for each of them. The idea is that for each of my forms I can create an input filter class that consists of other input filters. For example, when creating an account through the registration form, I would like to use the basic input filter Account for my Account object and use it in a new class of input filters, which can change inputs or add additional ones, Something like below.
class Register extends InputFilter { public function __construct(ObjectRepository $accountRepository, Account $accountFilter) { /***** Add inputs from input filters *****/ $this->inputs = $accountFilter->getInputs(); /***** Add additional validation rules *****/ // Username $usernameAvailability = new NoObjectExists(array( 'object_repository' => $accountRepository, 'fields' => array('username'), )); $username = $this->get('username'); $username->getValidatorChain() ->attach($usernameAvailability, true); // E-mail $emailAvailability = new NoObjectExists(array( 'object_repository' => $accountRepository, 'fields' => array('email'), )); $email = $this->get('email'); $email->getValidatorChain() ->attach($emailAvailability, true); } }
I pass the input filter to the constructor, and I want to add the inputs of this filter to my Register filter and change the inputs.
The problem I am facing is that only some of my inputs seem to confirm what was supposed to, and I cannot understand why. When I submit my form, only some inputs are checked as expected:

Interestingly, when filling out an email that already exists in my database, email input does not behave as expected. The result should be a validation error that already exists, but this does not happen. If I debug and look through my form, I found the following:

The form filter has the correct inputs with the correct validators, and as shown in the image above, the username input seems to be validated correctly. But for some reason this is not visually reflected in my form.
Below is my code.
Fieldsets
class Profile extends Fieldset { public function __construct(ObjectManager $objectManager) { parent::__construct('profile'); $this->setHydrator(new DoctrineHydrator($objectManager)) ->setObject(new ProfileEntity()); // Elements go here $this->add(new AccountFieldset($objectManager)); } } class Account extends Fieldset { public function __construct() { parent::__construct('account'); $username = new Element\Text('username'); $username->setLabel('Username'); $password = new Element\Password('password'); $password->setLabel('Password'); $repeatPassword = new Element\Password('repeatPassword'); $repeatPassword->setLabel('Repeat password'); $email = new Element\Email('email'); $email->setLabel('E-mail address'); $birthdate = new Element\DateSelect('birthdate'); $birthdate->setLabel('Birth date'); $gender = new Element\Select('gender'); $gender->setLabel('Gender') ->setEmptyOption('Please choose') ->setValueOptions(array( 1 => 'Male', 2 => 'Female', )); $this->add($username); $this->add($password); $this->add($repeatPassword); $this->add($email); $this->add($birthdate); $this->add($gender); $this->add(new CityFieldset()); } }
The form
class Register extends Form { public function __construct() { parent::__construct('register'); // Terms and Conditions $terms = new Element\Checkbox('terms'); $terms->setLabel('I accept the Terms and Conditions'); $terms->setCheckedValue('yes'); $terms->setUncheckedValue(''); $terms->setAttribute('id', $terms->getName()); // Submit button $submit = new Element\Submit('btnRegister'); $submit->setValue('Register'); $profileFieldset = new ProfileFieldset($objectManager); $profileFieldset->setUseAsBaseFieldset(true); // Add elements to form $this->add($terms); $this->add($profileFieldset); $this->add($submit); } }
View
$form->prepare(); echo $this->form()->openTag($form); $profile = $form->get('profile'); $account = $profile->get('account'); echo $this->formRow($account->get('username')); echo $this->formRow($account->get('password')); echo $this->formRow($account->get('repeatPassword')); echo $this->formRow($account->get('email')); echo $this->formRow($account->get('birthdate')); echo $this->formRow($account->get('gender')); $city = $account->get('city'); echo $this->formRow($city->get('postalCode')); echo $this->formRow($form->get('terms')); echo $this->formSubmit($form->get('btnRegister')); echo $this->form()->closeTag();
controller
$form = new Form\Register(); $profile = new Profile(); if ($this->request->isPost()) { $form->bind($profile); $form->setData($this->request->getPost()); $form->setInputFilter($this->serviceLocator->get('Profile\Form\Filter\Register')); if ($form->isValid()) {
I do not understand something? Is there a better way to do this while still having multiple input filter classes? I would rather keep my code maintained in this way, rather than copy validation rules for different forms. Sorry for the long post - it was very difficult to explain this problem!