I have a form Register, which has a fieldset Profile, which in turn has a fieldset Account. The fieldsets implement InputFilterProviderInterface and thus the getInputFilterSpecification method. This is where I have added general validators and filters that should be used whenever the fieldsets are used.
Now, in my registration form, I want to validate that an account with a given username does not already exist. Therefore I need to add a validator to complement the validators that are defined on the Account fieldset. This is where I got in trouble. After digging around a bit, I found a way to add input filters to fieldsets. This way, I figured, I could add an additional input filter to my Account fieldset.
class Register extends Zend\InputFilter\InputFilter
{
public function __construct()
{
$this->add(new RegisterProfileFilter(), 'profile');
}
}
With the above code, I am able to add an input filter to my Profile fieldset, and within that input filter, I can do the same for my account fieldset. However, it looks like there are two problems with this approach:
- It seems as if I have to create an input filter for each of my fieldsets in the hierarchy; in this case I have to create an input filter for the
Profilefieldset just so that I can add an input filter to theAccountfieldset - even if I don't need to add any validators or anything to theProfilefieldset. It doesn't work if I try to add the filter to theaccountfieldset directly - It seems as if adding an input filter object to a fieldset wipes out the filter that I have defined in the fieldset's
getInputFilterSpecificationmethod instead of merging the two like I want
Is there a way to merge the input filter specification defined on my fieldsets with an additional specification (or instance of Zend\InputFilter\InputFilter such that I don't have to copy my fieldset specification into my input filter class? That would be duplicate code and not be very maintainable. Or did I miss something causing me to be on the wrong track?
Below is my code if it is helpful in any way.
// 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
);
}
}
Merging InputFilters isn't very well covered in the Zend\Form component. Someone must really refactor the whole thing.
Anyway, what will work and therefore I would recommend in your situation, is adding the validator after the whole InputFilter has been created by overriding the getInputFilter method in your Form.
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;
}
}
As a sidenote I would recommend defining InputFilters per Form basis and not per Fieldset, since elements in a Fieldset often have different "validation requirements" in different contexts(=Form). But maybe that's more a personal preference.
来源:https://stackoverflow.com/questions/23201577/adding-input-filter-to-fieldset-in-zf2