Skip to content

Commit 47a16e9

Browse files
committed
minor #21159 [Form][Validator] Merge all articles about using validation groups in forms (javiereguiluz)
This PR was squashed before being merged into the 6.4 branch. Discussion ---------- [Form][Validator] Merge all articles about using validation groups in forms As we mentioned in the past, tiny articles hurt readers' experience. Validation groups in Symfony forms are explained in multiple separate micro articles. Let's merge everything into a single reference article. Also, this replaces some repeated contents by links to the new article. Commits ------- 0d09f16 [Form][Validator] Merge all articles about using validation groups in forms
2 parents e6f7c4d + 0d09f16 commit 47a16e9

File tree

8 files changed

+155
-261
lines changed

8 files changed

+155
-261
lines changed

_build/redirection_map

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,3 +571,6 @@
571571
/components/serializer /serializer
572572
/serializer/custom_encoder /serializer/encoders#serializer-custom-encoder
573573
/components/string /string
574+
/form/button_based_validation /form/validation_groups
575+
/form/data_based_validation /form/validation_groups
576+
/form/validation_group_service_resolver /form/validation_groups

form/button_based_validation.rst

Lines changed: 0 additions & 36 deletions
This file was deleted.

form/data_based_validation.rst

Lines changed: 0 additions & 72 deletions
This file was deleted.

form/validation_group_service_resolver.rst

Lines changed: 0 additions & 58 deletions
This file was deleted.

form/validation_groups.rst

Lines changed: 144 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,163 @@
1-
How to Define the Validation Groups to Use
2-
==========================================
1+
Configuring Validation Groups in Forms
2+
======================================
33

4-
Validation Groups
5-
-----------------
4+
If the object handled in your form uses :doc:`validation groups </validation/groups>`,
5+
you need to specify which validation group(s) the form should apply.
66

7-
If your object takes advantage of :doc:`validation groups </validation/groups>`,
8-
you'll need to specify which validation group(s) your form should use. Pass
9-
this as an option when :ref:`creating forms in controllers <creating-forms-in-controllers>`::
7+
To define them when :ref:`creating forms in classes <creating-forms-in-classes>`,
8+
use the ``configureOptions()`` method::
9+
10+
use Symfony\Component\OptionsResolver\OptionsResolver;
11+
12+
public function configureOptions(OptionsResolver $resolver): void
13+
{
14+
$resolver->setDefaults([
15+
// ...
16+
'validation_groups' => ['registration'],
17+
]);
18+
}
19+
20+
When :ref:`creating forms in controllers <creating-forms-in-controllers>`, pass
21+
it as a form option::
1022

1123
$form = $this->createFormBuilder($user, [
1224
'validation_groups' => ['registration'],
1325
])->add(/* ... */);
1426

15-
When :ref:`creating forms in classes <creating-forms-in-classes>`, add the
16-
following to the ``configureOptions()`` method::
27+
In both cases, *only* the ``registration`` group will be used to validate the
28+
object. To apply the ``registration`` group *and* all constraints not in any
29+
other group, add the special ``Default`` group::
30+
31+
[
32+
// ...
33+
'validation_groups' => ['Default', 'registration'],
34+
]
1735

36+
.. note::
37+
38+
You can use any name for your validation groups. Symfony recommends using
39+
"lower snake case" (e.g. ``foo_bar``), while automatically generated
40+
groups use "UpperCamelCase" (e.g. ``Default``, ``SomeClassName``).
41+
42+
Choosing Validation Groups Based on the Clicked Button
43+
------------------------------------------------------
44+
45+
When your form has :doc:`multiple submit buttons </form/multiple_buttons>`, you
46+
can change the validation group based on the clicked button. For example, in a
47+
multi-step form like the following, you might want to skip validation when
48+
returning to a previous step::
49+
50+
$form = $this->createFormBuilder($task)
51+
// ...
52+
->add('nextStep', SubmitType::class)
53+
->add('previousStep', SubmitType::class)
54+
->getForm();
55+
56+
To do so, configure the validation groups of the ``previousStep`` button to
57+
``false``, which is a special value that skips validation::
58+
59+
$form = $this->createFormBuilder($task)
60+
// ...
61+
->add('previousStep', SubmitType::class, [
62+
'validation_groups' => false,
63+
])
64+
->getForm();
65+
66+
Now the form will skip your validation constraints when that button is clicked.
67+
It will still validate basic integrity constraints, such as checking whether an
68+
uploaded file was too large or whether you tried to submit text in a number field.
69+
70+
Choosing Validation Groups Based on Submitted Data
71+
--------------------------------------------------
72+
73+
To determine validation groups dynamically based on submitted data, use a
74+
callback. This is called after the form is submitted, but before validation is
75+
invoked. The callback receives the form object as its first argument::
76+
77+
use App\Entity\Client;
78+
use Symfony\Component\Form\FormInterface;
1879
use Symfony\Component\OptionsResolver\OptionsResolver;
1980

2081
public function configureOptions(OptionsResolver $resolver): void
2182
{
2283
$resolver->setDefaults([
23-
// ...
24-
'validation_groups' => ['registration'],
84+
'validation_groups' => function (FormInterface $form): array {
85+
$data = $form->getData();
86+
87+
if (Client::TYPE_PERSON === $data->getType()) {
88+
return ['Default', 'person'];
89+
}
90+
91+
return ['Default', 'company'];
92+
},
2593
]);
2694
}
2795

28-
In both of these cases, *only* the ``registration`` validation group will
29-
be used to validate the underlying object. To apply the ``registration``
30-
group *and* all constraints that are not in a group, use::
96+
.. note::
97+
98+
Adding ``Default`` to the list of validation groups is common but not mandatory.
99+
See the main :doc:`article about validation groups </validation/groups>` to
100+
learn more about validation groups and the default constraints.
31101

32-
'validation_groups' => ['Default', 'registration']
102+
You can also pass a static class method callback::
33103

34-
.. note::
104+
'validation_groups' => [Client::class, 'determineValidationGroups']
105+
106+
Choosing Validation Groups via a Service
107+
----------------------------------------
108+
109+
If validation group logic requires services or can't fit in a closure, use a
110+
dedicated validation group resolver service. The class of this service must
111+
be invokable and receives the form object as its first argument::
112+
113+
// src/Validation/ValidationGroupResolver.php
114+
namespace App\Validation;
115+
116+
use Symfony\Component\Form\FormInterface;
117+
118+
class ValidationGroupResolver
119+
{
120+
public function __construct(
121+
private object $service1,
122+
private object $service2,
123+
) {
124+
}
125+
126+
public function __invoke(FormInterface $form): array
127+
{
128+
$groups = [];
129+
130+
// ... determine which groups to return
131+
132+
return $groups;
133+
}
134+
}
135+
136+
Then use the service in your form type::
137+
138+
namespace App\Form;
139+
140+
use App\Validation\ValidationGroupResolver;
141+
use Symfony\Component\Form\AbstractType;
142+
use Symfony\Component\OptionsResolver\OptionsResolver;
143+
144+
class MyClassType extends AbstractType
145+
{
146+
public function __construct(
147+
private ValidationGroupResolver $groupResolver,
148+
) {
149+
}
150+
151+
public function configureOptions(OptionsResolver $resolver): void
152+
{
153+
$resolver->setDefaults([
154+
'validation_groups' => $this->groupResolver,
155+
]);
156+
}
157+
}
158+
159+
Learn More
160+
----------
35161

36-
You can choose any name for your validation groups, but Symfony recommends
37-
using "lower snake case" names (e.g. ``foo_bar``) in contrast with the
38-
automatic validation groups created by Symfony, which use "upper camel case"
39-
(e.g. ``Default``, ``SomeClassName``).
162+
For more information about how validation groups work, see
163+
:doc:`/validation/groups`.

forms.rst

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,8 +1003,6 @@ Validation:
10031003
:maxdepth: 1
10041004

10051005
/form/validation_groups
1006-
/form/validation_group_service_resolver
1007-
/form/button_based_validation
10081006
/form/disabling_validation
10091007

10101008
Misc.:

0 commit comments

Comments
 (0)