Skip to content

Commit 9159e13

Browse files
committed
Merge branch '5.4' into 6.0
* 5.4: [Validator] Add attributes documentation of composite constraints Fix custom password hasher doc
2 parents ab47291 + 8c6086b commit 9159e13

File tree

5 files changed

+129
-17
lines changed

5 files changed

+129
-17
lines changed

reference/constraints/All.rst

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,23 @@ entry in that array:
3636
protected $favoriteColors = [];
3737
}
3838
39+
.. code-block:: php-attributes
40+
41+
// src/Entity/User.php
42+
namespace App\Entity;
43+
44+
use Symfony\Component\Validator\Constraints as Assert;
45+
46+
// IMPORTANT: nested attributes requires PHP 8.1 or higher
47+
class User
48+
{
49+
#[Assert\All([
50+
new Assert\NotBlank,
51+
new Assert\Length(min: 5),
52+
])]
53+
protected $favoriteColors = [];
54+
}
55+
3956
.. code-block:: yaml
4057
4158
# config/validator/validation.yaml
@@ -90,6 +107,11 @@ entry in that array:
90107
}
91108
}
92109
110+
.. versionadded:: 5.4
111+
112+
The ``#[All]`` PHP attribute was introduced in Symfony 5.4 and requires
113+
PHP 8.1 (which added nested attribute support).
114+
93115
Now, each entry in the ``favoriteColors`` array will be validated to not
94116
be blank and to be at least 5 characters long.
95117

reference/constraints/AtLeastOneOf.rst

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,31 @@ The following constraints ensure that:
5050
protected $grades;
5151
}
5252
53+
.. code-block:: php-attributes
54+
55+
// src/Entity/Student.php
56+
namespace App\Entity;
57+
58+
use Symfony\Component\Validator\Constraints as Assert;
59+
60+
// IMPORTANT: nested attributes requires PHP 8.1 or higher
61+
class Student
62+
{
63+
#[Assert\AtLeastOneOf([
64+
new Assert\Regex('/#/'),
65+
new Assert\Length(min: 10),
66+
])]
67+
protected $plainPassword;
68+
69+
#[Assert\AtLeastOneOf([
70+
new Assert\Count(min: 3),
71+
new Assert\All(
72+
new Assert\GreaterThanOrEqual(5)
73+
),
74+
])]
75+
protected $grades;
76+
}
77+
5378
.. code-block:: yaml
5479
5580
# config/validator/validation.yaml
@@ -139,6 +164,11 @@ The following constraints ensure that:
139164
}
140165
}
141166
167+
.. versionadded:: 5.4
168+
169+
The ``#[AtLeastOneOf]`` PHP attribute was introduced in Symfony 5.4 and
170+
requires PHP 8.1 (which added nested attribute support).
171+
142172
Options
143173
-------
144174

reference/constraints/Collection.rst

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,35 @@ following:
8181
];
8282
}
8383
84+
.. code-block:: php-attributes
85+
86+
// src/Entity/Author.php
87+
namespace App\Entity;
88+
89+
use Symfony\Component\Validator\Constraints as Assert;
90+
91+
// IMPORTANT: nested attributes requires PHP 8.1 or higher
92+
class Author
93+
{
94+
#[Assert\Collection(
95+
fields: [
96+
'personal_email' => new Assert\Email,
97+
'short_bio' => [
98+
new Assert\NotBlank,
99+
new Assert\Length(
100+
max: 100,
101+
maxMessage: 'Your short bio is too long!'
102+
)
103+
]
104+
],
105+
allowMissingFields: true,
106+
)]
107+
protected $profileData = [
108+
'personal_email' => '...',
109+
'short_bio' => '...',
110+
];
111+
}
112+
84113
.. code-block:: yaml
85114
86115
# config/validator/validation.yaml
@@ -155,6 +184,11 @@ following:
155184
}
156185
}
157186
187+
.. versionadded:: 5.4
188+
189+
The ``#[Collection]`` PHP attribute was introduced in Symfony 5.4 and
190+
requires PHP 8.1 (which added nested attribute support).
191+
158192
Presence and Absence of Fields
159193
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
160194

reference/constraints/Sequentially.rst

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,27 @@ You can validate each of these constraints sequentially to solve these issues:
6060
public $address;
6161
}
6262
63+
.. code-block:: php-attributes
64+
65+
// src/Localization/Place.php
66+
namespace App\Localization;
67+
68+
use App\Validator\Constraints as AcmeAssert;
69+
use Symfony\Component\Validator\Constraints as Assert;
70+
71+
// IMPORTANT: nested attributes requires PHP 8.1 or higher
72+
class Place
73+
{
74+
#[Assert\Sequentially([
75+
new Assert\NotNull,
76+
new Assert\Type('string'),
77+
new Assert\Length(min: 10),
78+
new Assert\Regex(Place::ADDRESS_REGEX),
79+
new AcmeAssert\Geolocalizable,
80+
])]
81+
public $address;
82+
}
83+
6384
.. code-block:: yaml
6485
6586
# config/validator/validation.yaml
@@ -121,6 +142,11 @@ You can validate each of these constraints sequentially to solve these issues:
121142
}
122143
}
123144
145+
.. versionadded:: 5.4
146+
147+
The ``#[Sequentially]`` PHP attribute was introduced in Symfony 5.4 and
148+
requires PHP 8.1 (which added nested attribute support).
149+
124150
Options
125151
-------
126152

security/passwords.rst

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -770,12 +770,12 @@ Creating a custom Password Hasher
770770

771771
If you need to create your own, it needs to follow these rules:
772772

773-
#. The class must implement :class:`Symfony\\Component\\PasswordHasher\\Hasher\\UserPasswordHasherInterface`
774-
(you can also extend :class:`Symfony\\Component\\PasswordHasher\\Hasher\\UserPasswordHasher`);
773+
#. The class must implement :class:`Symfony\\Component\\PasswordHasher\\PasswordHasherInterface`
774+
(you can also implement :class:`Symfony\\Component\\PasswordHasher\\LegacyPasswordHasherInterface` if your hash algorithm uses a separate salt);
775775

776776
#. The implementations of
777-
:method:`Symfony\\Component\\PasswordHasher\\Hasher\\UserPasswordHasherInterface::hashPassword`
778-
and :method:`Symfony\\Component\\PasswordHasher\\Hasher\\UserPasswordHasherInterface::isPasswordValid`
777+
:method:`Symfony\\Component\\PasswordHasher\\PasswordHasherInterface::hash`
778+
and :method:`Symfony\\Component\\PasswordHasher\\PasswordHasherInterface::verify`
779779
**must validate that the password length is no longer than 4096
780780
characters.** This is for security reasons (see `CVE-2013-5750`_).
781781

@@ -784,31 +784,31 @@ If you need to create your own, it needs to follow these rules:
784784

785785
.. code-block:: php
786786
787-
// src/Security/CustomVerySecureHasher.php
788-
namespace App\Security;
787+
// src/Security/Hasher/CustomVerySecureHasher.php
788+
namespace App\Security\Hasher;
789789
790+
use Symfony\Component\PasswordHasher\Exception\InvalidPasswordException;
790791
use Symfony\Component\PasswordHasher\Hasher\CheckPasswordLengthTrait;
791-
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasher;
792-
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
792+
use Symfony\Component\PasswordHasher\PasswordHasherInterface;
793793
794-
class CustomVerySecureHasher extends UserPasswordHasher
794+
class CustomVerySecureHasher implements PasswordHasherInterface
795795
{
796796
use CheckPasswordLengthTrait;
797797
798-
public function hashPassword(UserInterface $user, string $plainPassword): string
798+
public function hash(string $plainPassword): string
799799
{
800-
if ($this->isPasswordTooLong($user->getPassword())) {
801-
throw new BadCredentialsException('Invalid password.');
800+
if ($this->isPasswordTooLong($plainPassword)) {
801+
throw new InvalidPasswordException();
802802
}
803803
804804
// ... hash the plain password in a secure way
805805
806806
return $hashedPassword;
807807
}
808808
809-
public function isPasswordValid(UserInterface $user, string $plainPassword): bool
809+
public function verify(string $hashedPassword, string $plainPassword): bool
810810
{
811-
if ($this->isPasswordTooLong($user->getPassword())) {
811+
if ('' === $plainPassword || $this->isPasswordTooLong($plainPassword)) {
812812
return false;
813813
}
814814
@@ -849,21 +849,21 @@ Now, define a password hasher using the ``id`` setting:
849849
<!-- ... -->
850850
<!-- id: the service ID of your custom hasher (the FQCN using the default services.yaml) -->
851851
<security:password_hasher class="app_hasher"
852-
id="App\Security\Hasher\MyCustomPasswordHasher"/>
852+
id="App\Security\Hasher\CustomVerySecureHasher"/>
853853
</config>
854854
</srv:container>
855855
856856
.. code-block:: php
857857
858858
// config/packages/security.php
859-
use App\Security\Hasher\MyCustomPasswordHasher;
859+
use App\Security\Hasher\CustomVerySecureHasher;
860860
use Symfony\Config\SecurityConfig;
861861
862862
return static function (SecurityConfig $security) {
863863
// ...
864864
$security->passwordHasher('app_hasher')
865865
// the service ID of your custom hasher (the FQCN using the default services.yaml)
866-
->id(MyCustomPasswordHasher::class)
866+
->id(CustomVerySecureHasher::class)
867867
;
868868
};
869869

0 commit comments

Comments
 (0)