Новое в Symfony 7.2: Улучшение составных ограничений
Составное ограничение позволяет группировать другие ограничения в одно многократно используемое ограничение, позволяющее применять одну и ту же валидацию в разных частях приложения. Например, можно проверить политику паролей, проверив все условия с помощью такого набора ограничений:
// src/Validator/MatchPasswordPolicy.php
use Symfony\Component\Validator\Constraints as Assert;
#[\Attribute]
class MatchPasswordPolicy extends Assert\Compound
{
protected function getConstraints(array $options): array
{
return [
new Assert\NotBlank(allowNull: false),
new Assert\Length(min: 8, max: 255),
new Assert\NotCompromisedPassword(),
new Assert\Type('string'),
new Assert\Regex('/[A-Z]+/'),
// ...
];
}
}
Затем в сущности User
можно применить это составное ограничение следующим образом:
// src/Entity/User.php
namespace App\Entity\User;
use App\Validator\Constraints as Assert;
class User
{
#[Assert\MatchPasswordPolicy]
public string $plainPassword;
// ...
}
В Symfony 7.2 были добавлены несколько возможностей для упрощения работы с составными ограничениями.
Более простые тесты составных ограничений
- Pull Request: [Validator] Add
CompoundConstraintTestCase
to ease testing Compound Constraints #49547 Alexandre Daubois
Раньше тестирование составных ограничений было неоправданно сложным. Поэтому для облегчения тестирования мы вводим новый класс CompoundConstraintTestCase
. Это абстрактный класс, требующий определения единственного метода:
abstract class CompoundConstraintTestCase extends TestCase
{
abstract protected function createCompound(): Compound;
// ...
}
Используя самое составное ограничение MatchPasswordPolicy
, продемонстрированное ранее, можно написать тест для него следующим образом:
// tests/Validator/MatchPasswordPolicyTest.php
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Test\CompoundConstraintTestCase;
class MatchPasswordPolicyTest extends CompoundConstraintTestCase
{
public function createCompound(): Assert\Compound
{
return new MatchPasswordPolicy();
}
/**
* @dataProvider provideInvalidPasswords
*/
public function testInvalid(mixed $password, string $code): void
{
$this->validateValue($password);
$this->assertViolationIsRaisedByCompound($code);
}
public static function provideInvalidPasswords(): \Generator
{
yield 'Blank' => ['', Assert\NotBlank::IS_BLANK_ERROR];
yield 'Too short' => ['a', Assert\Length::TOO_SHORT_ERROR];
yield 'Not a string' => [1, Assert\Type::INVALID_TYPE_ERROR];
// ...
}
public function testValid(): void
{
$this->validateValue('VeryStr0ngP4$$wOrD');
$this->assertNoViolation();
}
}
Добавление аргументов конструктора $groups
и $payload
- Pull Request: [Validator] Add
$groups
and$payload
toCompound
constructor #58062 Alexander M. Turek
Недавно мы добавили аргументы $groups
и $payload
в конструктор многих составных ограничений, но не добавили их в составное ограничение. В Symfony 7.2 мы добавили эти аргументы, чтобы их можно было передавать в конструктор:
class User
{
#[Assert\MatchPasswordPolicy(
groups: ['registration'],
payload: ['severity' => 'error'],
)]
public string $plainPassword;
// ...
}