Skip to content

Commit 3a59f72

Browse files
committed
feature symfony#5909 More 2.8 form updates (weaverryan)
This PR was merged into the 2.8 branch. Discussion ---------- More 2.8 form updates | Q | A |------------- | --- | Doc fix? | yes | New docs? | no | Applies to | 2.8+ | Fixed tickets | symfony#5588 This is addition to what was done in symfony#5834. These changes are HUGE, so if anyone can review this for copy-paste changes or other mistakes, that would be awesome. Also, if you can think of any other things to search for the the code base and are able to find MORE instances, let me know. Commits ------- d131449 several other tweaks feb68dd Completely updating the form type reference section for the text -> TextType changes 832a12a fixing build error 3117df5 Another huge batch of changes for the form type changes in 2.8
2 parents b094312 + d131449 commit 3a59f72

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+554
-515
lines changed

Diff for: best_practices/forms.rst

+2-19
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ some developers configure form buttons in the controller::
110110

111111
use Symfony\Component\HttpFoundation\Request;
112112
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
113+
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
113114
use AppBundle\Entity\Post;
114115
use AppBundle\Form\PostType;
115116

@@ -121,7 +122,7 @@ some developers configure form buttons in the controller::
121122
{
122123
$post = new Post();
123124
$form = $this->createForm(PostType::class, $post);
124-
$form->add('submit', 'submit', array(
125+
$form->add('submit', SubmitType::class, array(
125126
'label' => 'Create',
126127
'attr' => array('class' => 'btn btn-default pull-right')
127128
));
@@ -205,21 +206,3 @@ Second, we recommend using ``$form->isSubmitted()`` in the ``if`` statement
205206
for clarity. This isn't technically needed, since ``isValid()`` first calls
206207
``isSubmitted()``. But without this, the flow doesn't read well as it *looks*
207208
like the form is *always* processed (even on the GET request).
208-
209-
Custom Form Field Types
210-
-----------------------
211-
212-
.. best-practice::
213-
214-
Add the ``app_`` prefix to your custom form field types to avoid collisions.
215-
216-
Custom form field types inherit from the ``AbstractType`` class, which defines the
217-
``getName()`` method to configure the name of that form type. These names must
218-
be unique in the application.
219-
220-
If a custom form type uses the same name as any of the Symfony's built-in form
221-
types, it will override it. The same happens when the custom form type matches
222-
any of the types defined by the third-party bundles installed in your application.
223-
224-
Add the ``app_`` prefix to your custom form field types to avoid name collisions
225-
that can lead to hard to debug errors.

Diff for: book/forms.rst

+8-4
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,10 @@ which HTML form tag(s) is rendered for that field.
127127

128128
.. versionadded:: 2.8
129129
To denote the form type, you have to use the fully qualified class name - like
130-
TextType::class in PHP 5.5+ or ``Symfony\Component\Form\Extension\Core\Type\TextType``.
130+
``TextType::class`` in PHP 5.5+ or ``Symfony\Component\Form\Extension\Core\Type\TextType``.
131131
Before Symfony 2.8, you could use an alias for each type like ``text`` or
132-
``date``. For more details, see the `2.8 UPGRADE Log`_.
132+
``date``. The old alias syntax will still work until Symfony 3.0. For more details,
133+
see the `2.8 UPGRADE Log`_.
133134

134135
Finally, you added a submit button with a custom label for submitting the form to
135136
the server.
@@ -1005,7 +1006,7 @@ ways. If you build your form in the controller, you can use ``setAction()`` and
10051006
->setAction($this->generateUrl('target_route'))
10061007
->setMethod('GET')
10071008
->add('task', TextType::class)
1008-
->add('dueDate', DateType::clas)
1009+
->add('dueDate', DateType::class)
10091010
->add('save', SubmitType::class)
10101011
->getForm();
10111012

@@ -1018,7 +1019,10 @@ In :ref:`book-form-creating-form-classes` you will learn how to move the
10181019
form building code into separate classes. When using an external form class
10191020
in the controller, you can pass the action and method as form options::
10201021

1021-
$form = $this->createForm(new TaskType(), $task, array(
1022+
use AppBundle\Form\Type\TaskType;
1023+
// ...
1024+
1025+
$form = $this->createForm(TaskType::class, $task, array(
10221026
'action' => $this->generateUrl('target_route'),
10231027
'method' => 'GET',
10241028
));

Diff for: book/validation.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ workflow looks like the following from inside a controller::
230230
public function updateAction(Request $request)
231231
{
232232
$author = new Author();
233-
$form = $this->createForm(new AuthorType(), $author);
233+
$form = $this->createForm(AuthorType::class, $author);
234234

235235
$form->handleRequest($request);
236236

Diff for: cookbook/bundles/override.rst

+7-8
Original file line numberDiff line numberDiff line change
@@ -105,17 +105,16 @@ associations. Learn more about this feature and its limitations in
105105
Forms
106106
-----
107107

108-
In order to override a form type, it has to be registered as a service (meaning
109-
it is tagged as ``form.type``). You can then override it as you would override any
110-
service as explained in `Services & Configuration`_. This, of course, will only
111-
work if the type is referred to by its alias rather than being instantiated,
112-
e.g.::
108+
As of Symfony 2.8, form types are referred to by their fully-qualified class name::
113109

114-
$builder->add('name', 'custom_type');
110+
$builder->add('name', CustomType::class);
115111

116-
rather than::
112+
This means that you cannot override this by creating a sub-class of ``CustomType``
113+
and registering it as a service, and tagging it with ``form.type`` (you *could*
114+
do this in earlier version).
117115

118-
$builder->add('name', new CustomType());
116+
Instead, you should use a "form type extension" to modify the existing form type.
117+
For more information, see :doc:`/cookbook/form/create_form_type_extension`.
119118

120119
.. _override-validation:
121120

Diff for: cookbook/controller/upload_file.rst

+3-2
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,15 @@ Then, add a new ``brochure`` field to the form that manages the ``Product`` enti
5757
use Symfony\Component\Form\AbstractType;
5858
use Symfony\Component\Form\FormBuilderInterface;
5959
use Symfony\Component\OptionsResolver\OptionsResolver;
60+
use Symfony\Component\Form\Extension\Core\Type\FileType;
6061

6162
class ProductType extends AbstractType
6263
{
6364
public function buildForm(FormBuilderInterface $builder, array $options)
6465
{
6566
$builder
6667
// ...
67-
->add('brochure', 'file', array('label' => 'Brochure (PDF file)'))
68+
->add('brochure', FileType::class, array('label' => 'Brochure (PDF file)'))
6869
// ...
6970
;
7071
}
@@ -116,7 +117,7 @@ Finally, you need to update the code of the controller that handles the form::
116117
public function newAction(Request $request)
117118
{
118119
$product = new Product();
119-
$form = $this->createForm(new ProductType(), $product);
120+
$form = $this->createForm(ProductType::class, $product);
120121
$form->handleRequest($request);
121122

122123
if ($form->isValid()) {

Diff for: cookbook/form/create_custom_field_type.rst

+34-35
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ for form fields, which is ``<BundleName>\Form\Type``. Make sure the field extend
2525

2626
use Symfony\Component\Form\AbstractType;
2727
use Symfony\Component\OptionsResolver\OptionsResolver;
28+
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
2829

2930
class GenderType extends AbstractType
3031
{
@@ -40,12 +41,7 @@ for form fields, which is ``<BundleName>\Form\Type``. Make sure the field extend
4041

4142
public function getParent()
4243
{
43-
return 'choice';
44-
}
45-
46-
public function getName()
47-
{
48-
return 'gender';
44+
return ChoiceType::class;
4945
}
5046
}
5147

@@ -54,8 +50,12 @@ for form fields, which is ``<BundleName>\Form\Type``. Make sure the field extend
5450
The location of this file is not important - the ``Form\Type`` directory
5551
is just a convention.
5652

53+
.. versionadded:: 2.8
54+
In 2.8, the ``getName()`` method was removed. Now, fields are always referred
55+
to by their fully-qualified class name.
56+
5757
Here, the return value of the ``getParent`` function indicates that you're
58-
extending the ``choice`` field type. This means that, by default, you inherit
58+
extending the ``ChoiceType`` field. This means that, by default, you inherit
5959
all of the logic and rendering of that field type. To see some of the logic,
6060
check out the `ChoiceType`_ class. There are three methods that are particularly
6161
important:
@@ -89,24 +89,26 @@ important:
8989
Also, if you need to modify the "view" of any of your child types from
9090
your parent type, use the ``finishView()`` method.
9191

92-
The ``getName()`` method returns an identifier which should be unique in
93-
your application. This is used in various places, such as when customizing
94-
how your form type will be rendered.
95-
9692
The goal of this field was to extend the choice type to enable selection of
9793
a gender. This is achieved by fixing the ``choices`` to a list of possible
9894
genders.
9995

10096
Creating a Template for the Field
10197
---------------------------------
10298

103-
Each field type is rendered by a template fragment, which is determined in
104-
part by the value of your ``getName()`` method. For more information, see
99+
Each field type is rendered by a template fragment, which is determined in part by
100+
the class name of your type. For more information, see
105101
:ref:`cookbook-form-customization-form-themes`.
106102

107-
In this case, since the parent field is ``choice``, you don't *need* to do
108-
any work as the custom field type will automatically be rendered like a ``choice``
109-
type. But for the sake of this example, suppose that when your field is "expanded"
103+
.. note::
104+
105+
The first part of the prefix (e.g. ``gender``) comes from the class name
106+
(``GenderType`` -> ``gender``). This can be controlled by overriding ``getBlockPrefix()``
107+
in ``GenderType``.
108+
109+
In this case, since the parent field is ``ChoiceType``, you don't *need* to do
110+
any work as the custom field type will automatically be rendered like a ``ChoiceType``.
111+
But for the sake of this example, suppose that when your field is "expanded"
110112
(i.e. radio buttons or checkboxes, instead of a select field), you want to
111113
always render it in a ``ul`` element. In your form theme template (see above
112114
link for details), create a ``gender_widget`` block to handle this:
@@ -154,7 +156,7 @@ link for details), create a ``gender_widget`` block to handle this:
154156
.. note::
155157

156158
Make sure the correct widget prefix is used. In this example the name should
157-
be ``gender_widget``, according to the value returned by ``getName``.
159+
be ``gender_widget`` (see :ref:`cookbook-form-customization-form-themes`).
158160
Further, the main config file should point to the custom form template
159161
so that it's used when rendering all forms.
160162

@@ -241,18 +243,19 @@ new instance of the type in one of your forms::
241243

242244
use Symfony\Component\Form\AbstractType;
243245
use Symfony\Component\Form\FormBuilderInterface;
246+
use AppBundle\Form\Type\GenderType;
244247

245248
class AuthorType extends AbstractType
246249
{
247250
public function buildForm(FormBuilderInterface $builder, array $options)
248251
{
249-
$builder->add('gender_code', new GenderType(), array(
252+
$builder->add('gender_code', GenderType::class, array(
250253
'placeholder' => 'Choose a gender',
251254
));
252255
}
253256
}
254257

255-
But this only works because the ``GenderType()`` is very simple. What if
258+
But this only works because the ``GenderType`` is very simple. What if
256259
the gender codes were stored in configuration or in a database? The next
257260
section explains how more complex field types solve this problem.
258261

@@ -311,14 +314,14 @@ the ``genders`` parameter value as the first argument to its to-be-created
311314
arguments:
312315
- "%genders%"
313316
tags:
314-
- { name: form.type, alias: gender }
317+
- { name: form.type }
315318
316319
.. code-block:: xml
317320
318321
<!-- src/AppBundle/Resources/config/services.xml -->
319322
<service id="app.form.type.gender" class="AppBundle\Form\Type\GenderType">
320323
<argument>%genders%</argument>
321-
<tag name="form.type" alias="gender" />
324+
<tag name="form.type" />
322325
</service>
323326
324327
.. code-block:: php
@@ -331,20 +334,16 @@ the ``genders`` parameter value as the first argument to its to-be-created
331334
'AppBundle\Form\Type\GenderType',
332335
array('%genders%')
333336
))
334-
->addTag('form.type', array(
335-
'alias' => 'gender',
336-
))
337+
->addTag('form.type')
337338
;
338339
339340
.. tip::
340341

341342
Make sure the services file is being imported. See :ref:`service-container-imports-directive`
342343
for details.
343344

344-
Be sure that the ``alias`` attribute of the tag corresponds with the value
345-
returned by the ``getName`` method defined earlier. You'll see the importance
346-
of this in a moment when you use the custom field type. But first, add a ``__construct``
347-
method to ``GenderType``, which receives the gender configuration::
345+
First, add a ``__construct`` method to ``GenderType``, which receives the gender
346+
configuration::
348347

349348
// src/AppBundle/Form/Type/GenderType.php
350349
namespace AppBundle\Form\Type;
@@ -374,28 +373,28 @@ method to ``GenderType``, which receives the gender configuration::
374373
}
375374

376375
Great! The ``GenderType`` is now fueled by the configuration parameters and
377-
registered as a service. Additionally, because you used the ``form.type`` alias in its
378-
configuration, using the field is now much easier::
376+
registered as a service. Because you used the ``form.type`` alias in its configuration,
377+
your service will be used instead of creating a *new* ``GenderType``. In other words,
378+
your controller *does not need to change*, it still looks like this::
379379

380380
// src/AppBundle/Form/Type/AuthorType.php
381381
namespace AppBundle\Form\Type;
382382

383+
use Symfony\Component\Form\AbstractType;
383384
use Symfony\Component\Form\FormBuilderInterface;
384-
385-
// ...
385+
use AppBundle\Form\Type\GenderType;
386386

387387
class AuthorType extends AbstractType
388388
{
389389
public function buildForm(FormBuilderInterface $builder, array $options)
390390
{
391-
$builder->add('gender_code', 'gender', array(
391+
$builder->add('gender_code', GenderType::class, array(
392392
'placeholder' => 'Choose a gender',
393393
));
394394
}
395395
}
396396

397-
Notice that instead of instantiating a new instance, you can just refer to
398-
it by the alias used in your service configuration, ``gender``. Have fun!
397+
Have fun!
399398

400399
.. _`ChoiceType`: https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php
401400
.. _`FieldType`: https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Form/Extension/Core/Type/FieldType.php

0 commit comments

Comments
 (0)