You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Add input filter validation to fieldset tutorial #68
In the in-depth tutorial you add the use of laminas-form and laminas-form-fieldset and in the Controller check for validity of the inputs. In the conclusion of that section, it is claimed that we've learnt how to validate input but we haven't: the input to the fields is not validated because we haven't created an input filter or attached any validators to the form or to the fieldset containing the form data.
I think it is particularly important to cover this topic as you are using fieldset in the form for the object hydrator and this can make setting data on the form and collecting data back from valid forms difficult with input filters. Can you cover it in more detail please?
Thanks for the report @Redcentaur - you are welcome to send a patch to improve the docs if you are able… It could be a case of adding links to other existing docs in the pertinent places.
@gsteel I'd love to be in a position to help and perhaps one day soon I will be able to, but I don't think I know enough about Laminas at this stage to add to the tutorial competently (which is why I'm doing the tutorial :) )
the input to the fields is not validated because we haven't created an input filter or attached any validators to the form or to the fieldset containing the form data
Good point because the used form elements Text and Textarea do not come with validators like Email, MultiCheckbox, DateSelect or Number.
the input to the fields is not validated because we haven't created an input filter or attached any validators to the form or to the fieldset containing the form data
Good point because the used form elements Text and Textarea do not come with validators like Email, MultiCheckbox, DateSelect or Number.
No they don't, but they can and should still have filters (StripTags/StringTrim) and validators (StringLength) etc relevant to the expected input.
What I'm not sure about is how to inject the inputFilter for the form, set the data on it, validate the data and retrieve the data from it in the Controller when the form has a fieldset. I get form validation errors saying the fields are required and cannot be empty, when they have been populated.
No they don't, but they can and should still have filters (StripTags/StringTrim) and validators (StringLength) etc relevant to the expected input.
Correct and I didn't want to doubt this, on the contrary, this part is missing in the tutorial. I will add this part.
What I'm not sure about is how to inject the inputFilter for the form, set the data on it, validate the data and retrieve the data from it in the Controller when the form has a fieldset.
I have done some research and got an InputFilter working with the tutorial code. I'm not sure if this is best practice or not?
First, in the Post.php file, add the references, Interface implementation and create a parameter to hold the InputFilter:
// module/Blog/Model/Post.php
use DomainException;
use Laminas\Filter\StringTrim;
use Laminas\Filter\StripTags;
use Laminas\Validator\StringLength;
use Laminas\Filter\ToInt;
use Laminas\InputFilter\InputFilterAwareInterface;
use Laminas\INputFilter\InputFilterInterface;
class Post implements InputFilterAwareInterface
{
/* ... */
/**
* @var InputFilterInterface
*/
private $inputFilter;
/* ... */
Then create the InputFilter setter and getter methods at the end of the Post class:
Next, in the WriteController, we need to add the Post reference at the top of the file:
use Blog\Model\Post;
Then we need to alter the addAction() to create a new Post entity. We do this so we can call the InputFilter from the model.
// module/Blog/src/Controller/WriteController.php
/* ... */
// In public function addAction()
// change this line:
// $post = $this->form->getData();
$post = new Post('', '');
Now we can set the form's InputFilter using the InputFilter get method from the Post entity. Because we used a Fieldset in our form, we need to set a validation group on the form, so that the InputFilter is applied to the correct fieldset:
The setValidationGroup() method takes an associative array using the name of the fieldset as its index ('post') associated with an array of the fields that are present to be validated and filtered (in this case, 'title' and 'text'). Note, because 'id' is not present in the addAction() form, we have to leave it out, otherwise the form will never validate because the id is not present and does not contain a value.
Finally, for addAction(), we can retrieve the data and save it to the database:
In the editAction(), we already have a Post entity, which we bound to the form, so all we need to do is retrieve the InputFilter from it and set it on the form, set the data and eventually post it:
// module/Blog/src/Controller/WriteController.php
// public function editAction():
if (! $request->isPost()) {
return $viewModel;
}
// ADD the following three lines:
$this->form->setInputFilter($post->getInputFilter());
$this->form->setValidationGroup(['post' => ['id', 'title', 'text']]);
$this->form->setData($request->getPost());
/* ... */
// ... and finally in the try/catch statement, change the updatePost line:
$post = $this->command->updatePost($this->form->getData());
Activity
gsteel commentedon Jun 14, 2024
Thanks for the report @Redcentaur - you are welcome to send a patch to improve the docs if you are able… It could be a case of adding links to other existing docs in the pertinent places.
Redcentaur commentedon Jun 14, 2024
@gsteel I'd love to be in a position to help and perhaps one day soon I will be able to, but I don't think I know enough about Laminas at this stage to add to the tutorial competently (which is why I'm doing the tutorial :) )
gsteel commentedon Jun 14, 2024
👍 - Good luck with it, and don't forget the forum and slack if you run into any trouble :)
froschdesign commentedon Jun 17, 2024
Good point because the used form elements
TextandTextareado not come with validators likeEmail,MultiCheckbox,DateSelectorNumber.Redcentaur commentedon Jun 17, 2024
No they don't, but they can and should still have filters (StripTags/StringTrim) and validators (StringLength) etc relevant to the expected input.
What I'm not sure about is how to inject the inputFilter for the form, set the data on it, validate the data and retrieve the data from it in the Controller when the form has a fieldset. I get form validation errors saying the fields are required and cannot be empty, when they have been populated.
froschdesign commentedon Jun 17, 2024
Correct and I didn't want to doubt this, on the contrary, this part is missing in the tutorial. I will add this part.
There are some more tutorials: "Application Integrations"
For example:
Redcentaur commentedon Jun 20, 2024
Hi Frank
I have done some research and got an InputFilter working with the tutorial code. I'm not sure if this is best practice or not?
First, in the Post.php file, add the references, Interface implementation and create a parameter to hold the InputFilter:
Then create the InputFilter setter and getter methods at the end of the Post class:
Next, in the WriteController, we need to add the Post reference at the top of the file:
Then we need to alter the
addAction()to create a new Post entity. We do this so we can call the InputFilter from the model.Now we can set the form's InputFilter using the InputFilter get method from the Post entity. Because we used a Fieldset in our form, we need to set a validation group on the form, so that the InputFilter is applied to the correct fieldset:
The
setValidationGroup()method takes an associative array using the name of the fieldset as its index ('post') associated with an array of the fields that are present to be validated and filtered (in this case,'title'and'text'). Note, because'id'is not present in theaddAction()form, we have to leave it out, otherwise the form will never validate because the id is not present and does not contain a value.Finally, for
addAction(), we can retrieve the data and save it to the database:In the
editAction(), we already have a Post entity, which we bound to the form, so all we need to do is retrieve the InputFilter from it and set it on the form, set the data and eventually post it:Is this correct and does it make sense?
froschdesign commentedon Jun 25, 2024
Too complicated. 😜
Define the input filter in a form and you are done. Follow the description I have given you above:
https://docs.laminas.dev/laminas-inputfilter/cookbook/input-filter-in-forms/#define-the-input-filter-in-a-form
You will find the same procedure in the documentation of laminas-form:
https://docs.laminas.dev/laminas-form/v3/application-integration/usage-in-a-laminas-mvc-application/
For further questions, please use our forum or the chat.