@@ -34,7 +34,7 @@ Suppose that you want to save a set of colors to the database. For this, you're
3434using an immutable color object::
3535
3636 // src/AppBundle/Painting/Color.php
37- namespace App \Painting;
37+ namespace AppBundle \Painting;
3838
3939 final class Color
4040 {
@@ -78,18 +78,23 @@ one of the values is changed.
7878
7979The red, green and blue form fields have to be mapped to the constructor
8080arguments and the ``Color `` instance has to be mapped to red, green and blue
81- form fields. Recognize a familiar pattern? It's time for a data mapper::
81+ form fields. Recognize a familiar pattern? It's time for a data mapper. The
82+ easiest way to create one is by implementing :class: `Symfony\\ Component\\ Form\\ DataMapperInterface `
83+ in your form type::
8284
83- // src/AppBundle/Form/DataMapper/ColorMapper .php
84- namespace App \Form\DataMapper ;
85+ // src/AppBundle/Form/ColorType .php
86+ namespace AppBundle \Form;
8587
86- use App\Painting\Color;
88+ use AppBundle\Painting\Color;
89+ use Symfony\Component\Form\AbstractType;
8790 use Symfony\Component\Form\DataMapperInterface;
8891 use Symfony\Component\Form\Exception\UnexpectedTypeException;
8992 use Symfony\Component\Form\FormInterface;
9093
91- final class ColorMapper implements DataMapperInterface
94+ final class ColorType extends AbstractType implements DataMapperInterface
9295 {
96+ // ...
97+
9398 /**
9499 * @param Color|null $data
95100 */
@@ -139,20 +144,18 @@ form fields. Recognize a familiar pattern? It's time for a data mapper::
139144Using the Mapper
140145----------------
141146
142- You're ready to use the data mapper for the `` ColorType `` form. Use the
143- :method: `Symfony\\ Component\\ Form\\ FormConfigBuilderInterface::setDataMapper `
144- method to configure the data mapper ::
147+ After creating the data mapper, you need to configure the form to use it. This is
148+ achieved using the :method: `Symfony\\ Component\\ Form\\ FormConfigBuilderInterface::setDataMapper `
149+ method::
145150
146151 // src/AppBundle/Form/Type/ColorType.php
147- namespace App\Form\Type;
148152
149- use App\Form\DataMapper\ColorMapper;
150- use Symfony\Component\Form\AbstractType;
153+ // ...
151154 use Symfony\Component\Form\Extension\Core\Type\IntegerType;
152155 use Symfony\Component\Form\FormBuilderInterface;
153156 use Symfony\Component\OptionsResolver\OptionsResolver;
154157
155- final class ColorType extends AbstractType
158+ final class ColorType extends AbstractType implements DataMapperInterface
156159 {
157160 public function buildForm(FormBuilderInterface $builder, array $options)
158161 {
@@ -168,7 +171,8 @@ method to configure the data mapper::
168171 ->add('blue', IntegerType::class, [
169172 'empty_data' => '0',
170173 ])
171- ->setDataMapper(new ColorMapper())
174+ // configure the data mapper for this FormType
175+ ->setDataMapper($this)
172176 ;
173177 }
174178
@@ -177,19 +181,41 @@ method to configure the data mapper::
177181 // when creating a new color, the initial data should be null
178182 $resolver->setDefault('empty_data', null);
179183 }
184+
185+ // ...
180186 }
181187
182- Cool! When using the ``ColorType `` form, the custom `` ColorMapper `` will create
183- a new ``Color `` object now.
188+ Cool! When using the ``ColorType `` form, the custom data mapper methods will
189+ create a new ``Color `` object now.
184190
185191.. caution ::
186192
187193 When a form has the ``inherit_data `` option set to ``true ``, it does not use the data mapper and
188194 lets its parent map inner values.
189195
190- .. tip ::
196+ .. sidebar :: Stateful Data Mappers
197+
198+ Sometimes, data mappers need to access services or need to maintain their
199+ state. In this case, you cannot implement the methods in the form type
200+ itself. Create a separate class implementing ``DataMapperInterface `` and
201+ initialize it in your form type::
191202
192- You can also implement the ``DataMapperInterface `` in the ``ColorType `` and add
193- the ``mapDataToForms() `` and ``mapFormsToData() `` in the form type directly
194- to avoid creating a new class. You'll then have to call
195- ``$builder->setDataMapper($this) ``.
203+ // src/AppBundle/Form/Type/ColorType.php
204+
205+ // ...
206+ use AppBundle\Form\DataMapper\ColorMapper;
207+
208+ final class ColorType extends AbstractType
209+ {
210+ public function buildForm(FormBuilderInterface $builder, array $options)
211+ {
212+ $builder
213+ // ...
214+
215+ // Initialize the data mapper class and e.g. pass some state
216+ ->setDataMapper(new ColorMapper($options['opacity']))
217+ ;
218+ }
219+
220+ // ...
221+ }
0 commit comments