Skip to content

Commit 97f01a9

Browse files
committed
Merge branch '7.3' into 7.4
* 7.3: [Form] Document conditional constraints in forms without classes [Serializer] Update the getSupportedTypes() docs of custom serializers
2 parents c340fe4 + 173f8a3 commit 97f01a9

File tree

2 files changed

+61
-32
lines changed

2 files changed

+61
-32
lines changed

form/without_class.rst

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,3 +177,41 @@ in your controller::
177177
->add('firstName', TextType::class)
178178
->add('lastName', TextType::class)
179179
->getForm();
180+
181+
Conditional Constraints
182+
~~~~~~~~~~~~~~~~~~~~~~~
183+
184+
It's possible to define field constraints that depend on the value of other
185+
fields (e.g. a field must not be blank when another field has a certain value).
186+
To achieve this, use the ``expression`` option of the
187+
:doc:`When constraint </reference/constraints/When>` to reference the other field::
188+
189+
$builder
190+
->add('how_did_you_hear', ChoiceType::class, [
191+
'required' => true,
192+
'label' => 'How did you hear about us?',
193+
'choices' => [
194+
'Search engine' => 'search_engine',
195+
'Friends' => 'friends',
196+
'Other' => 'other',
197+
],
198+
'expanded' => true,
199+
'constraints' => [
200+
new Assert\NotBlank(),
201+
]
202+
])
203+
204+
// this field is only required if the value of the 'how_did_you_hear' field is 'other'
205+
->add('other_text', TextType::class, [
206+
'required' => false,
207+
'label' => 'Please specify',
208+
'constraints' => [
209+
new Assert\When(
210+
expression: 'this.getParent().get("how_did_you_hear").getData() == "other"',
211+
constraints: [
212+
new Assert\NotBlank(),
213+
],
214+
)
215+
],
216+
])
217+
;

serializer/custom_normalizer.rst

Lines changed: 23 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -126,41 +126,32 @@ If you're not using ``autoconfigure``, you have to tag the service with
126126
;
127127
};
128128
129-
Performance of Normalizers/Denormalizers
130-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
131-
132-
To figure which normalizer (or denormalizer) must be used to handle an object,
133-
the :class:`Symfony\\Component\\Serializer\\Serializer` class will call the
134-
:method:`Symfony\\Component\\Serializer\\Normalizer\\NormalizerInterface::supportsNormalization`
135-
(or :method:`Symfony\\Component\\Serializer\\Normalizer\\DenormalizerInterface::supportsDenormalization`)
136-
of all registered normalizers (or denormalizers) in a loop.
137-
138-
Additionally, both
139-
:class:`Symfony\\Component\\Serializer\\Normalizer\\NormalizerInterface`
140-
and :class:`Symfony\\Component\\Serializer\\Normalizer\\DenormalizerInterface`
141-
contain the ``getSupportedTypes()`` method. This method allows normalizers or
142-
denormalizers to declare the type of objects they can handle, and whether they
143-
are cacheable. With this info, even if the ``supports*()`` call is not cacheable,
144-
the Serializer can skip a ton of method calls to ``supports*()`` improving
145-
performance substantially in some cases.
129+
Improving Performance of Normalizers/Denormalizers
130+
--------------------------------------------------
131+
132+
Both :class:Symfony\\Component\\Serializer\\Normalizer\\NormalizerInterface
133+
and :class:Symfony\\Component\\Serializer\\Normalizer\\DenormalizerInterface
134+
define a ``getSupportedTypes()`` method to declare which types they support and
135+
whether their ``supports*()`` result can be cached.
136+
137+
This **does not** cache the actual normalization or denormalization result. It
138+
only **caches the decision** of whether a normalizer supports a given type, allowing
139+
the Serializer to skip unnecessary ``supports*()`` calls and improve performance.
146140

147141
The ``getSupportedTypes()`` method should return an array where the keys
148-
represent the supported types, and the values indicate whether the result of
149-
the ``supports*()`` method call can be cached or not. The format of the
150-
returned array is as follows:
142+
represent the supported types, and the values indicate whether the result of the
143+
corresponding ``supports*()`` call can be cached. The array format is as follows:
151144

152145
#. The special key ``object`` can be used to indicate that the normalizer or
153146
denormalizer supports any classes or interfaces.
154147
#. The special key ``*`` can be used to indicate that the normalizer or
155-
denormalizer might support any types.
156-
#. The other keys in the array should correspond to specific types that the
157-
normalizer or denormalizer supports.
158-
#. The values associated with each type should be a boolean indicating if the
159-
result of the ``supports*()`` method call for that type can be cached or not.
160-
A value of ``true`` means that the result is cacheable, while ``false`` means
161-
that the result is not cacheable.
162-
#. A ``null`` value for a type means that the normalizer or denormalizer does
163-
not support that type.
148+
denormalizer might support any type.
149+
#. Other keys should correspond to specific types that the normalizer or
150+
denormalizer supports.
151+
#. The values should be booleans indicating whether the result of the
152+
``supports*()`` call for that type is cacheable. Use ``true`` if the result
153+
can be cached, ``false`` if it cannot.
154+
#. A ``null`` value means the normalizer or denormalizer does not support that type.
164155

165156
Here is an example of how to use the ``getSupportedTypes()`` method::
166157

@@ -173,9 +164,9 @@ Here is an example of how to use the ``getSupportedTypes()`` method::
173164
public function getSupportedTypes(?string $format): array
174165
{
175166
return [
176-
'object' => null, // Doesn't support any classes or interfaces
177-
'*' => false, // Supports any other types, but the result is not cacheable
178-
MyCustomClass::class => true, // Supports MyCustomClass and result is cacheable
167+
'object' => null, // doesn't support any classes or interfaces
168+
'*' => false, // supports any other types, but the decision is not cacheable
169+
MyCustomClass::class => true, // supports MyCustomClass and decision is cacheable
179170
];
180171
}
181172
}

0 commit comments

Comments
 (0)