@@ -34,7 +34,7 @@ Suppose that you want to save a set of colors to the database. For this, you're
34
34
using an immutable color object::
35
35
36
36
// src/AppBundle/Painting/Color.php
37
- namespace App \Painting;
37
+ namespace AppBundle \Painting;
38
38
39
39
final class Color
40
40
{
@@ -78,18 +78,23 @@ one of the values is changed.
78
78
79
79
The red, green and blue form fields have to be mapped to the constructor
80
80
arguments 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::
82
84
83
- // src/AppBundle/Form/DataMapper/ColorMapper .php
84
- namespace App \Form\DataMapper ;
85
+ // src/AppBundle/Form/ColorType .php
86
+ namespace AppBundle \Form;
85
87
86
- use App\Painting\Color;
88
+ use AppBundle\Painting\Color;
89
+ use Symfony\Component\Form\AbstractType;
87
90
use Symfony\Component\Form\DataMapperInterface;
88
91
use Symfony\Component\Form\Exception\UnexpectedTypeException;
89
92
use Symfony\Component\Form\FormInterface;
90
93
91
- final class ColorMapper implements DataMapperInterface
94
+ final class ColorType extends AbstractType implements DataMapperInterface
92
95
{
96
+ // ...
97
+
93
98
/**
94
99
* @param Color|null $data
95
100
*/
@@ -139,20 +144,18 @@ form fields. Recognize a familiar pattern? It's time for a data mapper::
139
144
Using the Mapper
140
145
----------------
141
146
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::
145
150
146
151
// src/AppBundle/Form/Type/ColorType.php
147
- namespace App\Form\Type;
148
152
149
- use App\Form\DataMapper\ColorMapper;
150
- use Symfony\Component\Form\AbstractType;
153
+ // ...
151
154
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
152
155
use Symfony\Component\Form\FormBuilderInterface;
153
156
use Symfony\Component\OptionsResolver\OptionsResolver;
154
157
155
- final class ColorType extends AbstractType
158
+ final class ColorType extends AbstractType implements DataMapperInterface
156
159
{
157
160
public function buildForm(FormBuilderInterface $builder, array $options)
158
161
{
@@ -168,7 +171,8 @@ method to configure the data mapper::
168
171
->add('blue', IntegerType::class, [
169
172
'empty_data' => '0',
170
173
])
171
- ->setDataMapper(new ColorMapper())
174
+ // configure the data mapper for this FormType
175
+ ->setDataMapper($this)
172
176
;
173
177
}
174
178
@@ -177,19 +181,41 @@ method to configure the data mapper::
177
181
// when creating a new color, the initial data should be null
178
182
$resolver->setDefault('empty_data', null);
179
183
}
184
+
185
+ // ...
180
186
}
181
187
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.
184
190
185
191
.. caution ::
186
192
187
193
When a form has the ``inherit_data `` option set to ``true ``, it does not use the data mapper and
188
194
lets its parent map inner values.
189
195
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::
191
202
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