I'm quite confused about what the function isValid actually does, can anyone help me to understand?
Here a function from the ZF album tutorial:
public function addAction()
{
$form = new AlbumForm();
$form->get('submit')->setValue('Add');
$request = $this->getRequest();
if ($request->isPost()) {
$album = new Album();
$form->setInputFilter($album->getInputFilter());
$form->setData($request->getPost());
if ($form->isValid()) {
$album->exchangeArray($form->getData());
$this->getAlbumTable()->saveAlbum($album);
// Redirect to list of albums
return $this->redirect()->toRoute('album');
}
}
return array('form' => $form);
}
My question is:
When the form is validated there is an explicit redirect to the route /album (list action). If the validation fails however, the function automatically redirects to /album/add (the action where the form is located).
Is it possible to NOT redirect/refresh but instead handle the error messages in a different way? (ex. forwarding them to a different action as an array)
The isValid()
method does all kinds of things. Not in the least checking whether the data you've set on the form (with $form->setData($request->getPost())
) is correct.
First of all, the isValid()
method requires that data be present to check. To be able to check a Model and an InputFilter is required.
An InputFilter may contain a few generic things (such as 'required' => false/true
and can also contain Filters and Validators per Input.
As you trigger the the isValid()
method, ZF2 dives into checking the $form
object and its data. For this it will use the InputFilters you've provided for the $form
object.
First of all it checks the generic stuff (required, allowed empty, etc). Next it runs through the data and applies the Filters to the data. For this it matches up the names (keys in the received data array) to the names of the Inputs of the Form.
After applying the Filters it goes on to validate the data using the Validators, again matching the array key's to the Input names to find which to use. When the validation (ValidatorChain's) have run, a simple true/false
is applies to the $valid
variable, which in the end is returned to your isValid()
"question" in the if ($form->isValid()){..}
statement.
To answer your second question: yes, you could do other stuff after/before/during your form validation.
For example, in the module.config.php
you could register the ViewJsonStrategy
. This allows you to, instead of rendering and returning a page (causing a refresh), to return data as JSON. So, instead of return $this->redirect()->toRoute('album')
you could do:
if ($this->getRequest()->isXmlHttpRequest()) {
return new JsonModel([
'form' => $form,
'messages' => $form->getMessages(),
]);
}
// Redirect to list of albums (triggered if above if() is not true)
return $this->redirect()->toRoute('album');
Extra: to register the ViewJsonStrategy
, add this to the module.config.php
file of the module (or a general module), makes the above snippet work :) :
'view_manager' => [
/* ... */
'strategies' => [
'ViewJsonStrategy',
],
],
Above is the answer. This is extra:
Since you're learning, chapeau, continue that tutorial. When you're done I would suggest you look at combining the more advanced topics that Zend offers as tutorials, such as usage of Fieldsets when playing with Forms. Also using Factories is a good thing to learn. When you're through with that (count on it taking a while, though worth it in my opinion), have a look at combining Zend Framework with Doctrine ORM. You'll find you have a lot less "model work" to do. There aren't many tutorials out there to learn how to combine the 2, so I'm going to point you to my own "ZF2 + Doctrine 2 blog tutorial" tutorial. I wrote it for beginners with the two, but here 'n' there it might be dated (published halfway 2016).