Skip to content

Commit 8b51e8e

Browse files
committed
[Validator] Deprecate annotations in favor of attributes
1 parent 80f1096 commit 8b51e8e

19 files changed

+337
-119
lines changed

UPGRADE-6.4.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,11 @@ Security
6262
* `UserValueResolver` no longer implements `ArgumentValueResolverInterface`
6363
* Make `PersistentToken` immutable
6464
* Deprecate accepting only `DateTime` for `TokenProviderInterface::updateToken()`, use `DateTimeInterface` instead
65+
66+
Validator
67+
---------
68+
69+
* Deprecate Doctrine annotations support in favor of native attributes
70+
* Deprecate passing an annotation reader to the constructor signature of `AnnotationLoader`
71+
* Deprecate `ValidatorBuilder::setDoctrineAnnotationReader()`
72+
* Deprecate `ValidatorBuilder::addDefaultDoctrineAnnotationReader()`

src/Symfony/Bridge/Doctrine/Tests/Validator/DoctrineLoaderTest.php

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
use Symfony\Component\Validator\Mapping\ClassMetadata;
2929
use Symfony\Component\Validator\Mapping\PropertyMetadata;
3030
use Symfony\Component\Validator\Mapping\TraversalStrategy;
31-
use Symfony\Component\Validator\Tests\Fixtures\Entity;
31+
use Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\Entity;
3232
use Symfony\Component\Validator\Validation;
3333

3434
/**
@@ -40,7 +40,6 @@ public function testLoadClassMetadata()
4040
{
4141
$validator = Validation::createValidatorBuilder()
4242
->enableAnnotationMapping(true)
43-
->addDefaultDoctrineAnnotationReader()
4443
->addLoader(new DoctrineLoader(DoctrineTestHelper::createTestEntityManager(), '{^Symfony\\\\Bridge\\\\Doctrine\\\\Tests\\\\Fixtures\\\\DoctrineLoader}'))
4544
->getValidator()
4645
;
@@ -144,7 +143,6 @@ public function testExtractEnum()
144143
$validator = Validation::createValidatorBuilder()
145144
->addMethodMapping('loadValidatorMetadata')
146145
->enableAnnotationMapping(true)
147-
->addDefaultDoctrineAnnotationReader()
148146
->addLoader(new DoctrineLoader(DoctrineTestHelper::createTestEntityManager(), '{^Symfony\\\\Bridge\\\\Doctrine\\\\Tests\\\\Fixtures\\\\DoctrineLoader}'))
149147
->getValidator()
150148
;
@@ -162,7 +160,6 @@ public function testFieldMappingsConfiguration()
162160
{
163161
$validator = Validation::createValidatorBuilder()
164162
->enableAnnotationMapping(true)
165-
->addDefaultDoctrineAnnotationReader()
166163
->addXmlMappings([__DIR__.'/../Resources/validator/BaseUser.xml'])
167164
->addLoader(
168165
new DoctrineLoader(
@@ -204,7 +201,6 @@ public function testClassNoAutoMapping()
204201
{
205202
$validator = Validation::createValidatorBuilder()
206203
->enableAnnotationMapping(true)
207-
->addDefaultDoctrineAnnotationReader()
208204
->addLoader(new DoctrineLoader(DoctrineTestHelper::createTestEntityManager(), '{.*}'))
209205
->getValidator();
210206

src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/ValidatorCacheWarmerTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public function testWarmUp()
2626
$validatorBuilder->addXmlMapping(__DIR__.'/../Fixtures/Validation/Resources/person.xml');
2727
$validatorBuilder->addYamlMapping(__DIR__.'/../Fixtures/Validation/Resources/author.yml');
2828
$validatorBuilder->addMethodMapping('loadValidatorMetadata');
29-
$validatorBuilder->enableAnnotationMapping(true)->addDefaultDoctrineAnnotationReader();
29+
$validatorBuilder->enableAnnotationMapping();
3030

3131
$file = sys_get_temp_dir().'/cache-validator.php';
3232
@unlink($file);
@@ -46,7 +46,7 @@ public function testWarmUpWithAnnotations()
4646
{
4747
$validatorBuilder = new ValidatorBuilder();
4848
$validatorBuilder->addYamlMapping(__DIR__.'/../Fixtures/Validation/Resources/categories.yml');
49-
$validatorBuilder->enableAnnotationMapping(true)->addDefaultDoctrineAnnotationReader();
49+
$validatorBuilder->enableAnnotationMapping();
5050

5151
$file = sys_get_temp_dir().'/cache-validator-with-annotations.php';
5252
@unlink($file);

src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Validation/Category.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ class Category
1010

1111
public $id;
1212

13-
/**
14-
* @Assert\Type("string")
15-
*/
13+
#[Assert\Type('string')]
1614
public $name;
1715
}

src/Symfony/Component/Validator/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ CHANGELOG
66

77
* Allow single integer for the `versions` option of the `Uuid` constraint
88
* Allow single constraint to be passed to the `constraints` option of the `When` constraint
9+
* Deprecate Doctrine annotations support in favor of native attributes
10+
* Deprecate passing an annotation reader to the constructor signature of `AnnotationLoader`
11+
* Deprecate `ValidatorBuilder::setDoctrineAnnotationReader()`
12+
* Deprecate `ValidatorBuilder::addDefaultDoctrineAnnotationReader()`
913

1014
6.3
1115
---

src/Symfony/Component/Validator/Mapping/Loader/AnnotationLoader.php

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,19 @@
2727
*/
2828
class AnnotationLoader implements LoaderInterface
2929
{
30+
/**
31+
* @deprecated since Symfony 6.4, this property will be removed in 7.0
32+
*
33+
* @var Reader|null
34+
*/
3035
protected $reader;
3136

3237
public function __construct(Reader $reader = null)
3338
{
39+
if ($reader) {
40+
trigger_deprecation('symfony/validator', '6.4', 'Passing a "%s" instance as argument 1 to "%s()" is deprecated, pass null or omit the parameter instead.', get_debug_type($reader), __METHOD__);
41+
}
42+
3443
$this->reader = $reader;
3544
}
3645

@@ -87,10 +96,7 @@ public function loadClassMetadata(ClassMetadata $metadata): bool
8796
return $success;
8897
}
8998

90-
/**
91-
* @param \ReflectionClass|\ReflectionMethod|\ReflectionProperty $reflection
92-
*/
93-
private function getAnnotations(object $reflection): iterable
99+
private function getAnnotations(\ReflectionMethod|\ReflectionClass|\ReflectionProperty $reflection): iterable
94100
{
95101
$dedup = [];
96102

@@ -112,14 +118,14 @@ private function getAnnotations(object $reflection): iterable
112118

113119
$annotations = [];
114120

115-
if ($reflection instanceof \ReflectionClass) {
116-
$annotations = $this->reader->getClassAnnotations($reflection);
121+
if ($reflection instanceof \ReflectionClass && $annotations = $this->reader->getClassAnnotations($reflection)) {
122+
trigger_deprecation('symfony/validator', '6.4', 'Class "%s" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.', $reflection->getName());
117123
}
118-
if ($reflection instanceof \ReflectionMethod) {
119-
$annotations = $this->reader->getMethodAnnotations($reflection);
124+
if ($reflection instanceof \ReflectionMethod && $annotations = $this->reader->getMethodAnnotations($reflection)) {
125+
trigger_deprecation('symfony/validator', '6.4', 'Method "%s::%s()" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.', $reflection->getDeclaringClass()->getName(), $reflection->getName());
120126
}
121-
if ($reflection instanceof \ReflectionProperty) {
122-
$annotations = $this->reader->getPropertyAnnotations($reflection);
127+
if ($reflection instanceof \ReflectionProperty && $annotations = $this->reader->getPropertyAnnotations($reflection)) {
128+
trigger_deprecation('symfony/validator', '6.4', 'Property "%s::$%s" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.', $reflection->getDeclaringClass()->getName(), $reflection->getName());
123129
}
124130

125131
foreach ($dedup as $annotation) {

src/Symfony/Component/Validator/Tests/Command/DebugCommandTest.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
namespace Symfony\Component\Validator\Tests\Command;
1313

14-
use Doctrine\Common\Annotations\AnnotationReader;
1514
use PHPUnit\Framework\TestCase;
1615
use Symfony\Component\Console\Tester\CommandTester;
1716
use Symfony\Component\Validator\Command\DebugCommand;
@@ -27,7 +26,7 @@ class DebugCommandTest extends TestCase
2726
{
2827
public function testOutputWithClassArgument()
2928
{
30-
$command = new DebugCommand(new LazyLoadingMetadataFactory(new AnnotationLoader(new AnnotationReader())));
29+
$command = new DebugCommand(new LazyLoadingMetadataFactory(new AnnotationLoader()));
3130

3231
$tester = new CommandTester($command);
3332
$tester->execute(['class' => DummyClassOne::class], ['decorated' => false]);
@@ -68,7 +67,7 @@ public function testOutputWithClassArgument()
6867

6968
public function testOutputWithPathArgument()
7069
{
71-
$command = new DebugCommand(new LazyLoadingMetadataFactory(new AnnotationLoader(new AnnotationReader())));
70+
$command = new DebugCommand(new LazyLoadingMetadataFactory(new AnnotationLoader()));
7271

7372
$tester = new CommandTester($command);
7473
$tester->execute(['class' => __DIR__.'/../Dummy'], ['decorated' => false]);

src/Symfony/Component/Validator/Tests/Constraints/ValidValidatorTest.php

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,14 @@
1313

1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\Validator\Constraints as Assert;
16-
use Symfony\Component\Validator\Constraints\ValidValidator;
1716
use Symfony\Component\Validator\ValidatorBuilder;
1817

1918
class ValidValidatorTest extends TestCase
2019
{
2120
public function testPropertyPathsArePassedToNestedContexts()
2221
{
2322
$validatorBuilder = new ValidatorBuilder();
24-
$validator = $validatorBuilder->enableAnnotationMapping()->addDefaultDoctrineAnnotationReader()->getValidator();
23+
$validator = $validatorBuilder->enableAnnotationMapping()->getValidator();
2524

2625
$violations = $validator->validate(new Foo(), null, ['nested']);
2726

@@ -32,26 +31,19 @@ public function testPropertyPathsArePassedToNestedContexts()
3231
public function testNullValues()
3332
{
3433
$validatorBuilder = new ValidatorBuilder();
35-
$validator = $validatorBuilder->enableAnnotationMapping()->addDefaultDoctrineAnnotationReader()->getValidator();
34+
$validator = $validatorBuilder->enableAnnotationMapping()->getValidator();
3635

3736
$foo = new Foo();
3837
$foo->fooBar = null;
3938
$violations = $validator->validate($foo, null, ['nested']);
4039

4140
$this->assertCount(0, $violations);
4241
}
43-
44-
protected function createValidator()
45-
{
46-
return new ValidValidator();
47-
}
4842
}
4943

5044
class Foo
5145
{
52-
/**
53-
* @Assert\Valid(groups={"nested"})
54-
*/
46+
#[Assert\Valid(groups: ['nested'])]
5547
public $fooBar;
5648

5749
public function __construct()
@@ -62,9 +54,7 @@ public function __construct()
6254

6355
class FooBar
6456
{
65-
/**
66-
* @Assert\Valid(groups={"nested"})
67-
*/
57+
#[Assert\Valid(groups: ['nested'])]
6858
public $fooBarBaz;
6959

7060
public function __construct()
@@ -75,8 +65,6 @@ public function __construct()
7565

7666
class FooBarBaz
7767
{
78-
/**
79-
* @Assert\NotBlank(groups={"nested"})
80-
*/
68+
#[Assert\NotBlank(groups: ['nested'])]
8169
public $foo;
8270
}

src/Symfony/Component/Validator/Tests/Constraints/WhenTest.php

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Doctrine\Common\Annotations\AnnotationReader;
1515
use PHPUnit\Framework\TestCase;
16+
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
1617
use Symfony\Component\Validator\Constraints\Callback;
1718
use Symfony\Component\Validator\Constraints\NotBlank;
1819
use Symfony\Component\Validator\Constraints\NotNull;
@@ -25,6 +26,8 @@
2526

2627
final class WhenTest extends TestCase
2728
{
29+
use ExpectDeprecationTrait;
30+
2831
public function testMissingOptionsExceptionIsThrown()
2932
{
3033
$this->expectException(MissingOptionsException::class);
@@ -42,11 +45,22 @@ public function testNonConstraintsAreRejected()
4245
]);
4346
}
4447

48+
/**
49+
* @group legacy
50+
*/
4551
public function testAnnotations()
4652
{
53+
$this->expectDeprecation('Since symfony/validator 6.4: Passing a "Doctrine\Common\Annotations\AnnotationReader" instance as argument 1 to "Symfony\Component\Validator\Mapping\Loader\AnnotationLoader::__construct()" is deprecated, pass null or omit the parameter instead.');
54+
4755
$loader = new AnnotationLoader(new AnnotationReader());
4856
$metadata = new ClassMetadata(WhenTestWithAnnotations::class);
4957

58+
$this->expectDeprecation('Since symfony/validator 6.4: Class "Symfony\Component\Validator\Tests\Constraints\WhenTestWithAnnotations" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.');
59+
$this->expectDeprecation('Since symfony/validator 6.4: Property "Symfony\Component\Validator\Tests\Constraints\WhenTestWithAnnotations::$foo" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.');
60+
$this->expectDeprecation('Since symfony/validator 6.4: Property "Symfony\Component\Validator\Tests\Constraints\WhenTestWithAnnotations::$bar" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.');
61+
$this->expectDeprecation('Since symfony/validator 6.4: Property "Symfony\Component\Validator\Tests\Constraints\WhenTestWithAnnotations::$qux" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.');
62+
$this->expectDeprecation('Since symfony/validator 6.4: Method "Symfony\Component\Validator\Tests\Constraints\WhenTestWithAnnotations::getBaz()" uses Doctrine Annotations to configure validation constraints, which is deprecated. Use PHP attributes instead.');
63+
5064
self::assertTrue($loader->loadClassMetadata($metadata));
5165

5266
[$classConstraint] = $metadata->getConstraints();
@@ -114,12 +128,9 @@ public function testAnnotations()
114128
self::assertSame(['Default', 'WhenTestWithAnnotations'], $bazConstraint->groups);
115129
}
116130

117-
/**
118-
* @requires PHP 8.1
119-
*/
120131
public function testAttributes()
121132
{
122-
$loader = new AnnotationLoader(new AnnotationReader());
133+
$loader = new AnnotationLoader();
123134
$metadata = new ClassMetadata(WhenTestWithAttributes::class);
124135

125136
self::assertTrue($loader->loadClassMetadata($metadata));

src/Symfony/Component/Validator/Tests/Dummy/DummyClassOne.php

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,18 @@
1313

1414
use Symfony\Component\Validator\Constraints as Assert;
1515

16-
/**
17-
* @Assert\Expression(expression="1 + 1 = 2")
18-
*/
16+
#[Assert\Expression(expression: '1 + 1 = 2')]
1917
class DummyClassOne
2018
{
2119
/**
2220
* @var string|null
23-
*
24-
* @Assert\NotBlank
2521
*/
22+
#[Assert\NotBlank]
2623
public $code;
2724

2825
/**
2926
* @var string|null
30-
*
31-
* @Assert\Email
3227
*/
28+
#[Assert\Email]
3329
public $email;
3430
}

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