Reputation: 291
I have a Form, which I create using the annotation builder like this:
$builder = new AnnotationBuilder();
$fieldset = $builder->createForm(new \Application\Entity\Example());
$this->add($fieldset);
$this->setBaseFieldset($fieldset);
In the controller everything is standard:
$entity = new \Application\Entity\Example();
$form = new \Application\Form\Example();
$form->bind($entity);
if($this->getRequest()->isPost()) {
$form->setData($this->getRequest()->getPost());
if($form->isValid()) {
// save ....
}
}
The problem is, that $form->isValid() always returns true, even when empty or invalid form is submitted. What is even more weird is that the form element error messages are all set, hinting that they are not valid.
I have looked into the ZF2 Form / InputFilter / Input classes and found out that: Input->isValid() is called twice: once in the Form->isValid() and once in Form->bindValues() In the first call the validator chain in Input->isValid() ($this->getValidatorChain) is empty and in the second call (from bindValues) it is correct.
What may got wrong?
PS. Using devel version 2.1
Upvotes: 2
Views: 904
Reputation: 146
I am also experiencing the same problem. When I use Annotations to create Fieldsets @Annotation\Type("fieldset") in a form, isValid() always returns true.
Looking at the code for Zend\Form\Factory, when we are creating a Fieldset the configureFieldset() function does not call prepareAndInjectInputFilter(), even where there is an input_filter as part of the form specification.
Only when we are creating a Form, does the Zend\Form\Factory::configureForm() function call prepareAndInjectInputFilter().
So it seems that input filters, and validation groups are only created by the AnnotationBuilder when its type is set to create a form.
I created an input filter myself, from the annotations by adding the code below to my form:
$fspec = ArrayUtils::iteratorToArray($builder->getFormSpecification($entity));
$outerfilter = new InputFilter();
$iffactory = new \Zend\InputFilter\Factory ();
$filter = $iffactory->createInputFilter($fspec['input_filter']);
$outerfilter->add($filter, 'shop'); // Use the name of your fieldset here.
$this->setInputFilter($outerfilter);
Upvotes: 0
Reputation: 291
I found out what was causing it.
It turns out, that the annotation builder was never intended to work this way. The annotation builder creates a \Zend\Form\Form instance, which I placed in as a fieldset in my base form. I am not sure why, but this was causing the base form not to validate. So in order to make the above code work, there should be no extra Form class and in controller we should have:
$entity = new \Application\Entity\Example();
$builder = new AnnotationBuilder();
$form = $builder->createForm($entity);
$form->bind($entity);
if($this->getRequest()->isPost()) {
$form->setData($this->getRequest()->getPost());
if($form->isValid()) {
// save ....
}
}
Maybe there will be a createFieldset function in the AnnotationBuilder in the future, but for now this seems to be the only way. Hope this helps someone. :)
Upvotes: 1