Skip to content

Commit 9762db6

Browse files
committed
Merge branch '6.1' into 6.2
* 6.1: Change secure.php.net link to php.net [Validator] Combine #13898 with recent changes [Serializer] Remove note about installing the FrameworkExtraBundle for using annotations [Validator] Unit Tests
2 parents 793c3cb + 7f8c5f8 commit 9762db6

File tree

4 files changed

+90
-38
lines changed

4 files changed

+90
-38
lines changed

console.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ the console::
264264
'',
265265
]);
266266

267-
// the value returned by someMethod() can be an iterator (https://secure.php.net/iterator)
267+
// the value returned by someMethod() can be an iterator (https://php.net/iterator)
268268
// that generates and returns the messages with the 'yield' PHP keyword
269269
$output->writeln($this->someMethod());
270270

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
If the ``input`` option is set to ``string``, this option specifies the format
22
of the date. This must be a valid `PHP date format`_.
33

4-
.. _`PHP date format`: https://secure.php.net/manual/en/function.date.php
4+
.. _`PHP date format`: https://php.net/manual/en/function.date.php

reference/forms/types/time.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,4 +236,4 @@ Form Variables
236236
| | | contains the input type to use (``datetime``, ``date`` or ``time``). |
237237
+--------------+-------------+----------------------------------------------------------------------+
238238

239-
.. _`PHP time format`: https://secure.php.net/manual/en/function.date.php
239+
.. _`PHP time format`: https://php.net/manual/en/function.date.php

validation/custom_constraint.rst

Lines changed: 87 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@ First you need to create a Constraint class and extend :class:`Symfony\\Componen
2626
#[\Attribute]
2727
class ContainsAlphanumeric extends Constraint
2828
{
29-
public $message = 'The string "{{ string }}" contains an illegal character: it can only contain letters or numbers.';
30-
public $mode = 'strict'; // If the constraint has configuration options, define them as public properties
29+
public string $message = 'The string "{{ string }}" contains an illegal character: it can only contain letters or numbers.';
30+
// If the constraint has configuration options, define them as public properties
31+
public string $mode = 'strict';
3132
}
3233
3334
Add ``@Annotation`` or ``#[\Attribute]`` to the constraint class if you want to
@@ -116,7 +117,7 @@ The validator class only has one required method ``validate()``::
116117

117118
class ContainsAlphanumericValidator extends ConstraintValidator
118119
{
119-
public function validate($value, Constraint $constraint)
120+
public function validate($value, Constraint $constraint): void
120121
{
121122
if (!$constraint instanceof ContainsAlphanumeric) {
122123
throw new UnexpectedTypeException($constraint, ContainsAlphanumeric::class);
@@ -150,7 +151,7 @@ The validator class only has one required method ``validate()``::
150151
}
151152
}
152153

153-
Inside ``validate``, you don't need to return a value. Instead, you add violations
154+
Inside ``validate()``, you don't need to return a value. Instead, you add violations
154155
to the validator's ``context`` property and a value will be considered valid
155156
if it causes no violations. The ``buildViolation()`` method takes the error
156157
message as its argument and returns an instance of
@@ -178,15 +179,15 @@ You can use custom validators like the ones provided by Symfony itself:
178179
179180
#[Assert\NotBlank]
180181
#[AcmeAssert\ContainsAlphanumeric(mode: 'loose')]
181-
protected $name;
182+
protected string $name;
182183
183184
// ...
184185
}
185186
186187
.. code-block:: yaml
187188
188189
# config/validator/validation.yaml
189-
App\Entity\AcmeEntity:
190+
App\Entity\User:
190191
properties:
191192
name:
192193
- NotBlank: ~
@@ -201,7 +202,7 @@ You can use custom validators like the ones provided by Symfony itself:
201202
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
202203
xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
203204
204-
<class name="App\Entity\AcmeEntity">
205+
<class name="App\Entity\User">
205206
<property name="name">
206207
<constraint name="NotBlank"/>
207208
<constraint name="App\Validator\ContainsAlphanumeric">
@@ -213,18 +214,20 @@ You can use custom validators like the ones provided by Symfony itself:
213214
214215
.. code-block:: php
215216
216-
// src/Entity/AcmeEntity.php
217+
// src/Entity/User.php
217218
namespace App\Entity;
218219
219220
use App\Validator\ContainsAlphanumeric;
220221
use Symfony\Component\Validator\Constraints\NotBlank;
221222
use Symfony\Component\Validator\Mapping\ClassMetadata;
222223
223-
class AcmeEntity
224+
class User
224225
{
225-
public $name;
226+
protected string $name = '';
227+
228+
// ...
226229
227-
public static function loadValidatorMetadata(ClassMetadata $metadata)
230+
public static function loadValidatorMetadata(ClassMetadata $metadata): void
228231
{
229232
$metadata->addPropertyConstraint('name', new NotBlank());
230233
$metadata->addPropertyConstraint('name', new ContainsAlphanumeric(['mode' => 'loose']));
@@ -253,22 +256,62 @@ Class Constraint Validator
253256
~~~~~~~~~~~~~~~~~~~~~~~~~~
254257

255258
Besides validating a single property, a constraint can have an entire class
256-
as its scope. You only need to add this to the ``Constraint`` class::
259+
as its scope.
260+
261+
For instance, imagine you also have a ``PaymentReceipt`` entity and you
262+
need to make sure the email of the receipt payload matches the user's
263+
email. First, create a constraint and override the ``getTargets()`` method::
264+
265+
// src/Validator/ConfirmedPaymentReceipt.php
266+
namespace App\Validator;
267+
268+
use Symfony\Component\Validator\Constraint;
257269

258-
public function getTargets()
270+
/**
271+
* @Annotation
272+
*/
273+
class ConfirmedPaymentReceipt extends Constraint
259274
{
260-
return self::CLASS_CONSTRAINT;
275+
public string $userDoesNotMatchMessage = 'User\'s e-mail address does not match that of the receipt';
276+
277+
public function getTargets(): string
278+
{
279+
return self::CLASS_CONSTRAINT;
280+
}
261281
}
262282

263-
With this, the validator's ``validate()`` method gets an object as its first argument::
283+
Now, the constraint validator will get an object as the first argument to
284+
``validate()``::
285+
286+
// src/Validator/ConfirmedPaymentReceiptValidator.php
287+
namespace App\Validator;
288+
289+
use Symfony\Component\Validator\Constraint;
290+
use Symfony\Component\Validator\ConstraintValidator;
291+
use Symfony\Component\Validator\Exception\UnexpectedValueException;
264292

265-
class ProtocolClassValidator extends ConstraintValidator
293+
class ConfirmedPaymentReceiptValidator extends ConstraintValidator
266294
{
267-
public function validate($protocol, Constraint $constraint)
295+
/**
296+
* @param PaymentReceipt $receipt
297+
*/
298+
public function validate($receipt, Constraint $constraint): void
268299
{
269-
if ($protocol->getFoo() != $protocol->getBar()) {
270-
$this->context->buildViolation($constraint->message)
271-
->atPath('foo')
300+
if (!$receipt instanceof PaymentReceipt) {
301+
throw new UnexpectedValueException($receipt, PaymentReceipt::class);
302+
}
303+
304+
if (!$constraint instanceof ConfirmedPaymentReceipt) {
305+
throw new UnexpectedValueException($constraint, ConfirmedPaymentReceipt::class);
306+
}
307+
308+
$receiptEmail = $receipt->getPayload()['email'] ?? null;
309+
$userEmail = $receipt->getUser()->getEmail();
310+
311+
if ($userEmail !== $receiptEmail) {
312+
$this->context
313+
->buildViolation($constraint->userDoesNotMatchMessage)
314+
->atPath('user.email')
272315
->addViolation();
273316
}
274317
}
@@ -280,8 +323,7 @@ With this, the validator's ``validate()`` method gets an object as its first arg
280323
associated. Use any :doc:`valid PropertyAccess syntax </components/property_access>`
281324
to define that property.
282325

283-
A class constraint validator is applied to the class itself, and
284-
not to the property:
326+
A class constraint validator must be applied to the class itself:
285327

286328
.. configuration-block::
287329

@@ -301,44 +343,54 @@ not to the property:
301343
.. code-block:: yaml
302344
303345
# config/validator/validation.yaml
304-
App\Entity\AcmeEntity:
346+
App\Entity\PaymentReceipt:
305347
constraints:
306-
- App\Validator\ProtocolClass: ~
348+
- App\Validator\ConfirmedPaymentReceipt: ~
307349
308350
.. code-block:: xml
309351
310352
<!-- config/validator/validation.xml -->
311-
<class name="App\Entity\AcmeEntity">
312-
<constraint name="App\Validator\ProtocolClass"/>
313-
</class>
353+
<?xml version="1.0" encoding="UTF-8" ?>
354+
<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
355+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
356+
xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping
357+
https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
358+
359+
<class name="App\Entity\PaymentReceipt">
360+
<constraint name="App\Validator\ConfirmedPaymentReceipt"/>
361+
</class>
362+
</constraint-mapping>
314363
315364
.. code-block:: php
316365
317-
// src/Entity/AcmeEntity.php
366+
// src/Entity/PaymentReceipt.php
318367
namespace App\Entity;
319368
320-
use App\Validator\ProtocolClass;
369+
use App\Validator\ConfirmedPaymentReceipt;
321370
use Symfony\Component\Validator\Mapping\ClassMetadata;
322371
323-
class AcmeEntity
372+
class PaymentReceipt
324373
{
325374
// ...
326375
327-
public static function loadValidatorMetadata(ClassMetadata $metadata)
376+
public static function loadValidatorMetadata(ClassMetadata $metadata): void
328377
{
329-
$metadata->addConstraint(new ProtocolClass());
378+
$metadata->addConstraint(new ConfirmedPaymentReceipt());
330379
}
331380
}
332381
333382
Testing Custom Constraints
334383
--------------------------
335384

336-
Use the ``ConstraintValidatorTestCase`` utility to simplify the creation of
337-
unit tests for your custom constraints::
385+
Use the :class:`Symfony\\Component\\Validator\\Test\\ConstraintValidatorTestCase``
386+
class to simplify writing unit tests for your custom constraints::
387+
388+
// tests/Validator/ContainsAlphanumericValidatorTest.php
389+
namespace App\Tests\Validator;
338390

339-
// ...
340391
use App\Validator\ContainsAlphanumeric;
341392
use App\Validator\ContainsAlphanumericValidator;
393+
use Symfony\Component\Validator\Test\ConstraintValidatorTestCase;
342394

343395
class ContainsAlphanumericValidatorTest extends ConstraintValidatorTestCase
344396
{

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy