Symfony Form - Ignoring fields - Validation groups - Doctrine Events
by itrascastro
In this situation we need to create a form for adding new users to our application. The entity has the typical fields (name, surname, username, password, …). If we want to share the same form for the create and edit actions, we need the password field only to be mandatory if we are creating the user and not if we are updating him.
The solution I have adopted is having a validation group in the User entity to know when the password must be taken in account. Only the plainPassword field will belong to that group.
Assigning the validation group to the form will be done dynamically, testing if the plainPassword is empty or not.
We also must set as not required the password field in case we are updating.
Finally we have to encode the password only if it is not empty. For that we have to use the preUpdate Doctrine Event. But that event is not triggered because plainPassword is not a field watched from Doctrine. So we have to trigger it manually from the controller.
The User entity
We set here the validation group for the plainPassword field.
The Form Class
We add a new option to our form named ‘update’ to decide from the controller whenever the password field will be required (only on create action).
Using the configureOptions method we set the validation groups to the form, depending on the plainPassword value. Default if the plainPassword is empty so we do not take the plainPassword validation in account.
Before we set de validation_groups we need to know if it is an update form:
The Service
We need now to associate a listener to doctrine preUpdate event. This is done in app/config/servives.yml
From the Doctrine Documentation:
prePersist - The prePersist event occurs for a given entity before the respective EntityManager persist operation for that entity is executed. It should be noted that this event is only triggered on initial persist of an entity (i.e. it does not trigger on future updates).
That is the reason because we need preUpdate event.
The Listener
The controller
As an update does only occur if a entity field (watched from doctrine) gets changed and so on the preupdate method is only called after a change.
PlainPassword is not a field watched from Doctrine. So we have to trigger preUpdate manually.
We also create the form setting the ‘update’ option to true for having the required parameter of the plainPassword field setted to false when updating.