php - How to map one class variable to two form fields in Symfony
I wold like to use Symfony 2.8 to create a form for data class, e.g.
Task as used in the Symfony docs.
Task class uses an integer field
flags to store a collection different bool values. For example the value of
is completed is stored as the first bit and
is urgent as the second bit:
- Task is not completed and not urgent --> flags = 0
- Task is completed and not urgent --> flags = 1
- Task is not completed and urgent --> flags = 2
- Task is completed and urgent --> flags = 3
The problem: How can this single class field be mapped to two different form fields and back?
$builder // map first bit to checkbox ->add('is_complete', CheckboxType::class, array( ... ) ) // map second bit to selection box "normal"/"urgent" ->add('is_urgend', ChoiceType::class, array( ... ) ) ...
What is the correct solution to solve this? Can this be handled by a Data Transformers? As far as I know, a transformer can translate a field of one to type to another type, but not one field to two fields. Is that correct?
The only solution I found so far, is to create a wrapper class
TaskWrapper which does not use flags but offers different bool fields for the each flag value. This class could than be passed to the form instead of the original
Task class. Once the form is submitted the returned wrapper object could than be manually translated back to a
This would work, but it is not a clean solution. Is this the way to go or is there a better solution using Symfony tools?
I would go for multiple boolean properties. It is easier at form-level and at persistence-level.
If you require to use that
$flagsproperty and you are using Doctrine, you can take use of the multiple boolean properties without mapping them. When submitting a form the fields are mapped directly to the entity properties except for those with
mapped = false: http://symfony.com/doc/current/reference/forms/types/form.html#mapped
Then implement an eventlistener for events
preUpdatethat set the
flagsproperty before creating/updating the Task:
For keeping consistency you can set the
$completeproperty values through
setFlags(), since it will only be called either manually or when loading the entity.