Skip to content

Commit 54a5808

Browse files
committed
minor #11765 [Forms] Reworded the article about creating custom form types (javiereguiluz)
This PR was squashed before being merged into the 4.2 branch (closes #11765). Discussion ---------- [Forms] Reworded the article about creating custom form types The new contents are completely different from the original ones, so you may prefer to review this by reading the rendered result: https://github.com/javiereguiluz/symfony-docs/blob/7bbd69e56621f450f5ca0e2fd78e397e0abbf947/form/create_custom_field_type.rst Commits ------- ac08120 [Forms] Reworded the article about creating custom form types
2 parents fd2e03d + ac08120 commit 54a5808

10 files changed

+417
-369
lines changed

_images/form/form-custom-type-postal-address-fragment-names.svg

Lines changed: 1 addition & 0 deletions
Loading

_images/form/form-custom-type-postal-address.svg

Lines changed: 1 addition & 0 deletions
Loading
Binary file not shown.
Binary file not shown.

form/create_custom_field_type.rst

Lines changed: 386 additions & 213 deletions
Large diffs are not rendered by default.

form/create_form_type_extension.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,9 @@ For more information on what those methods do, see the
6060
Registering your Form Type Extension as a Service
6161
-------------------------------------------------
6262

63-
Form type extensions must be registered as services and :doc:`tagged </service_container/tags>`
64-
with the ``form.type_extension`` tag. If you're using the
63+
Form type extensions must be :ref:`registered as services <service-container-creating-service>`
64+
and :doc:`tagged </service_container/tags>` with the ``form.type_extension`` tag.
65+
If you're using the
6566
:ref:`default services.yaml configuration <service-container-services-load-example>`,
6667
this is already done for you, thanks to :ref:`autoconfiguration <services-autoconfigure>`.
6768

form/data_transformers.rst

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -291,14 +291,13 @@ and type-hint the new class::
291291
// ...
292292
}
293293

294-
That's it! As long as you're using :ref:`autowire <services-autowire>` and
295-
:ref:`autoconfigure <services-autoconfigure>`, Symfony will automatically
296-
know to pass your ``TaskType`` an instance of the ``IssueToNumberTransformer``.
297-
298-
.. tip::
299-
300-
For more information about defining form types as services, read
301-
:doc:`register your form type as a service </form/form_dependencies>`.
294+
That's it! If you're using the
295+
:ref:`default services.yaml configuration <service-container-services-load-example>`,
296+
Symfony will automatically know to pass your ``TaskType`` an instance of the
297+
``IssueToNumberTransformer`` thanks to :ref:`autowire <services-autowire>` and
298+
:ref:`autoconfigure <services-autoconfigure>`.
299+
Otherwise, :ref:`register the form class as a service <service-container-creating-service>`
300+
and :doc:`tag it </service_container/tags>` with the ``form.type`` tag.
302301

303302
Now, you can use your ``TaskType``::
304303

form/dynamic_form_modification.rst

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -326,10 +326,11 @@ security helper to fill in the listener logic::
326326
Using the Form
327327
~~~~~~~~~~~~~~
328328

329-
If you're using :ref:`autowire <services-autowire>` and
330-
:ref:`autoconfigure <services-autoconfigure>`, your form is ready to be used!
331-
Otherwise, see :doc:`/form/form_dependencies` to learn how to register your form
332-
type as a service.
329+
If you're using the :ref:`default services.yaml configuration <service-container-services-load-example>`,
330+
your form is ready to be used thanks to :ref:`autowire <services-autowire>` and
331+
:ref:`autoconfigure <services-autoconfigure>`.
332+
Otherwise, :ref:`register the form class as a service <service-container-creating-service>`
333+
and :doc:`tag it </service_container/tags>` with the ``form.type`` tag.
333334

334335
In a controller, create the form like normal::
335336

form/form_dependencies.rst

Lines changed: 9 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -1,144 +1,12 @@
11
How to Access Services or Config from Inside a Form
22
===================================================
33

4-
Sometimes, you may need to access a :doc:`service </service_container>` or other
5-
configuration from inside of your form class. To do this, you have 2 options:
6-
7-
1) Pass Options to your Form
8-
----------------------------
9-
10-
The simplest way to pass services or configuration to your form is via form *options*.
11-
Suppose you need to access the Doctrine entity manager so that you can make a
12-
query. First, allow (in fact, require) a new ``entity_manager`` option to be
13-
passed to your form::
14-
15-
// src/Form/TaskType.php
16-
// ...
17-
18-
class TaskType extends AbstractType
19-
{
20-
// ...
21-
22-
public function configureOptions(OptionsResolver $resolver)
23-
{
24-
// ...
25-
26-
$resolver->setRequired('entity_manager');
27-
}
28-
}
29-
30-
Now that you've done this, you *must* pass an ``entity_manager`` option when you
31-
create your form::
32-
33-
// src/Controller/DefaultController.php
34-
use App\Form\TaskType;
35-
36-
// ...
37-
public function new()
38-
{
39-
$entityManager = $this->getDoctrine()->getManager();
40-
41-
$task = ...;
42-
$form = $this->createForm(TaskType::class, $task, [
43-
'entity_manager' => $entityManager,
44-
]);
45-
46-
// ...
47-
}
48-
49-
Finally, the ``entity_manager`` option is accessible in the ``$options`` argument
50-
of your ``buildForm()`` method::
51-
52-
// src/Form/TaskType.php
53-
// ...
54-
55-
class TaskType extends AbstractType
56-
{
57-
public function buildForm(FormBuilderInterface $builder, array $options)
58-
{
59-
/** @var \Doctrine\ORM\EntityManager $entityManager */
60-
$entityManager = $options['entity_manager'];
61-
// ...
62-
}
63-
64-
// ...
65-
}
66-
67-
Use this method to pass *anything* to your form.
68-
69-
2) Define your Form as a Service
70-
--------------------------------
71-
72-
Alternatively, you can define your form class as a service. This is a good idea if
73-
you want to re-use the form in several places - registering it as a service makes
74-
this easier.
75-
76-
Suppose you need to access the :ref:`EntityManager <doctrine-entity-manager>` object
77-
so that you can make a query. First, add this as an argument to your form class::
78-
79-
// src/Form/TaskType.php
80-
use Doctrine\ORM\EntityManagerInterface;
81-
// ...
82-
83-
class TaskType extends AbstractType
84-
{
85-
private $entityManager;
86-
87-
public function __construct(EntityManagerInterface $entityManager)
88-
{
89-
$this->entityManager = $entityManager;
90-
}
91-
92-
// ...
93-
}
94-
95-
If you're using :ref:`autowire <services-autowire>` and
96-
:ref:`autoconfigure <services-autoconfigure>`, then you don't need to do *anything*
97-
else: Symfony will automatically know how to pass the correct ``EntityManager`` object
98-
to your ``__construct()`` method.
99-
100-
If you are **not using autowire and autoconfigure**, register your form as a service
101-
manually and tag it with ``form.type``:
102-
103-
.. configuration-block::
104-
105-
.. code-block:: yaml
106-
107-
# config/services.yaml
108-
services:
109-
App\Form\TaskType:
110-
arguments: ['@doctrine.orm.entity_manager']
111-
tags: [form.type]
112-
113-
.. code-block:: xml
114-
115-
<!-- config/services.xml -->
116-
<?xml version="1.0" encoding="UTF-8" ?>
117-
<container xmlns="http://symfony.com/schema/dic/services"
118-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
119-
xsi:schemaLocation="http://symfony.com/schema/dic/services
120-
https://symfony.com/schema/dic/services/services-1.0.xsd">
121-
122-
<services>
123-
<service id="App\Form\TaskType">
124-
<argument type="service" id="doctrine.orm.entity_manager"/>
125-
<tag name="form.type"/>
126-
</service>
127-
</services>
128-
</container>
129-
130-
.. code-block:: php
131-
132-
// config/services.php
133-
use App\Form\TaskType;
134-
use Symfony\Component\DependencyInjection\Reference;
135-
136-
$container->register(TaskType::class)
137-
->addArgument(new Reference('doctrine.orm.entity_manager'))
138-
->addTag('form.type')
139-
;
140-
141-
That's it! Your controller - where you create the form - doesn't need to change
142-
at all: Symfony is smart enough to load the ``TaskType`` from the container.
143-
144-
Read :ref:`form-field-service` for more information.
4+
The content of this article is no longer relevant because in current Symfony
5+
versions, form classes are services by default and you can inject services in
6+
them using the :doc:`service autowiring </service_container/autowiring>` feature.
7+
8+
Read the article about :doc:`creating custom form types </form/create_custom_field_type>`
9+
to see an example of how to inject the database service into a form type. In the
10+
same article you can also read about
11+
:ref:`configuration options for form types <form-type-config-options>`, which is
12+
another way of passing services to forms.

form/use_empty_data.rst

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,11 @@ The point is, you can set ``empty_data`` to the exact "new" object that you want
7575
.. tip::
7676

7777
In order to pass arguments to the ``BlogType`` constructor, you'll need to
78-
:doc:`register it as a service and tag with form.type </form/form_dependencies>`.
78+
:ref:`register the form as a service <service-container-creating-service>`
79+
and :doc:`tag it </service_container/tags>` with ``form.type``.
80+
If you're using the
81+
:ref:`default services.yaml configuration <service-container-services-load-example>`,
82+
this is already done for you.
7983

8084
.. _forms-empty-data-closure:
8185

0 commit comments

Comments
 (0)