Skip to content

Commit ab80083

Browse files
committed
Recommend using form types as data mappers in the docs
1 parent 77c8614 commit ab80083

File tree

1 file changed

+47
-21
lines changed

1 file changed

+47
-21
lines changed

form/data_mappers.rst

Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Suppose that you want to save a set of colors to the database. For this, you're
3434
using 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

7979
The red, green and blue form fields have to be mapped to the constructor
8080
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 extending :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::
139144
Using 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:: Statefull Data Mappers
197+
198+
Sometimes, data mappers need to access values from a container or contain a
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 i.e. pass some state
216+
->setDataMapper(new ColorMapper($options['opacity']))
217+
;
218+
}
219+
220+
// ...
221+
}

0 commit comments

Comments
 (0)