Skip to content

Commit f6c7a74

Browse files
feature #50983 [Serializer] Deprecate annotations in favor of attributes (derrabus)
This PR was merged into the 6.4 branch. Discussion ---------- [Serializer] Deprecate annotations in favor of attributes | Q | A | ------------- | --- | Branch? | 6.4 | Bug fix? | no | New feature? | yes | Deprecations? | yes | Tickets | Follows #50888 | License | MIT | Doc PR | TODO, see symfony/symfony-docs#18589 This PR deprecates using Doctrine annotations to configure serialization. Attributes shall be used instead. Existing applications can be migrated easily using [Rector](https://getrector.com/blog/how-to-upgrade-annotations-to-attributes). Deprecation errors triggered by the bundles' functional tests will be resolved once #50888 is merged. Commits ------- 9b7b397 [Serializer] Deprecate annotations in favor of attributes
2 parents 1698d1e + 9b7b397 commit f6c7a74

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+482
-358
lines changed

UPGRADE-6.4.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,9 @@ Security
7171
* `UserValueResolver` no longer implements `ArgumentValueResolverInterface`
7272
* Make `PersistentToken` immutable
7373
* Deprecate accepting only `DateTime` for `TokenProviderInterface::updateToken()`, use `DateTimeInterface` instead
74+
75+
Serializer
76+
----------
77+
78+
* Deprecate Doctrine annotations support in favor of native attributes
79+
* Deprecate passing an annotation reader to the constructor of `AnnotationLoader`

src/Symfony/Bridge/Twig/Tests/Extension/Fixtures/SerializerModelFixture.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@
99
*/
1010
class SerializerModelFixture
1111
{
12-
/**
13-
* @Groups({"read"})
14-
*/
12+
#[Groups(['read'])]
1513
public $name = 'howdy';
1614

1715
public $title = 'fixture';

src/Symfony/Bridge/Twig/Tests/Extension/SerializerExtensionTest.php

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

1212
namespace Symfony\Bridge\Twig\Tests\Extension;
1313

14-
use Doctrine\Common\Annotations\AnnotationReader;
1514
use PHPUnit\Framework\TestCase;
1615
use Symfony\Bridge\Twig\Extension\SerializerExtension;
1716
use Symfony\Bridge\Twig\Extension\SerializerRuntime;
@@ -50,7 +49,7 @@ public static function serializerDataProvider(): \Generator
5049

5150
private function getTwig(string $template): Environment
5251
{
53-
$meta = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
52+
$meta = new ClassMetadataFactory(new AnnotationLoader());
5453
$runtime = new SerializerRuntime(new Serializer([new ObjectNormalizer($meta)], [new JsonEncoder(), new YamlEncoder()]));
5554

5655
$mockRuntimeLoader = $this->createMock(RuntimeLoaderInterface::class);

src/Symfony/Bridge/Twig/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
"twig/twig": "^2.13|^3.0.4"
2222
},
2323
"require-dev": {
24-
"doctrine/annotations": "^1.12|^2",
2524
"egulias/email-validator": "^2.1.10|^3|^4",
2625
"league/html-to-markdown": "^5.0",
2726
"phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0",
@@ -62,6 +61,7 @@
6261
"symfony/http-foundation": "<5.4",
6362
"symfony/http-kernel": "<6.2",
6463
"symfony/mime": "<6.2",
64+
"symfony/serializer": "<6.2",
6565
"symfony/translation": "<5.4",
6666
"symfony/workflow": "<5.4"
6767
},

src/Symfony/Component/PropertyInfo/Tests/Extractor/SerializerExtractorTest.php

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@
1111

1212
namespace Symfony\Component\PropertyInfo\Tests\Extractor;
1313

14-
use Doctrine\Common\Annotations\AnnotationReader;
1514
use PHPUnit\Framework\TestCase;
1615
use Symfony\Component\PropertyInfo\Extractor\SerializerExtractor;
1716
use Symfony\Component\PropertyInfo\Tests\Fixtures\AdderRemoverDummy;
17+
use Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy;
1818
use Symfony\Component\PropertyInfo\Tests\Fixtures\IgnorePropertyDummy;
1919
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
2020
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
@@ -24,22 +24,19 @@
2424
*/
2525
class SerializerExtractorTest extends TestCase
2626
{
27-
/**
28-
* @var SerializerExtractor
29-
*/
30-
private $extractor;
27+
private SerializerExtractor $extractor;
3128

3229
protected function setUp(): void
3330
{
34-
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
31+
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader());
3532
$this->extractor = new SerializerExtractor($classMetadataFactory);
3633
}
3734

3835
public function testGetProperties()
3936
{
4037
$this->assertEquals(
4138
['collection'],
42-
$this->extractor->getProperties('Symfony\Component\PropertyInfo\Tests\Fixtures\Dummy', ['serializer_groups' => ['a']])
39+
$this->extractor->getProperties(Dummy::class, ['serializer_groups' => ['a']])
4340
);
4441
}
4542

src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ class Dummy extends ParentDummy
4242

4343
/**
4444
* @var \DateTimeImmutable[]
45-
* @Groups({"a", "b"})
4645
*/
46+
#[Groups(['a', 'b'])]
4747
public $collection;
4848

4949
/**

src/Symfony/Component/PropertyInfo/Tests/Fixtures/IgnorePropertyDummy.php

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,9 @@
1919
*/
2020
class IgnorePropertyDummy
2121
{
22-
/**
23-
* @Groups({"a"})
24-
*/
22+
#[Groups(['a'])]
2523
public $visibleProperty;
2624

27-
/**
28-
* @Groups({"a"})
29-
* @Ignore
30-
*/
25+
#[Groups(['a']), Ignore]
3126
private $ignoredProperty;
3227
}

src/Symfony/Component/PropertyInfo/composer.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,13 @@
3131
"symfony/cache": "^5.4|^6.0|^7.0",
3232
"symfony/dependency-injection": "^5.4|^6.0|^7.0",
3333
"phpdocumentor/reflection-docblock": "^5.2",
34-
"phpstan/phpdoc-parser": "^1.0",
35-
"doctrine/annotations": "^1.10.4|^2"
34+
"phpstan/phpdoc-parser": "^1.0"
3635
},
3736
"conflict": {
3837
"phpdocumentor/reflection-docblock": "<5.2",
3938
"phpdocumentor/type-resolver": "<1.5.1",
40-
"symfony/dependency-injection": "<5.4"
39+
"symfony/dependency-injection": "<5.4",
40+
"symfony/serializer": "<5.4"
4141
},
4242
"autoload": {
4343
"psr-4": { "Symfony\\Component\\PropertyInfo\\": "" },

src/Symfony/Component/Serializer/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
CHANGELOG
22
=========
33

4+
6.4
5+
---
6+
7+
* Deprecate Doctrine annotations support in favor of native attributes
8+
* Deprecate passing an annotation reader to the constructor of `AnnotationLoader`
9+
410
6.3
511
---
612

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

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ class AnnotationLoader implements LoaderInterface
4646
public function __construct(
4747
private readonly ?Reader $reader = null,
4848
) {
49+
if ($reader) {
50+
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__);
51+
}
4952
}
5053

5154
public function loadClassMetadata(ClassMetadataInterface $classMetadata): bool
@@ -163,10 +166,7 @@ public function loadClassMetadata(ClassMetadataInterface $classMetadata): bool
163166
return $loaded;
164167
}
165168

166-
/**
167-
* @param \ReflectionClass|\ReflectionMethod|\ReflectionProperty $reflector
168-
*/
169-
public function loadAnnotations(object $reflector): iterable
169+
public function loadAnnotations(\ReflectionMethod|\ReflectionClass|\ReflectionProperty $reflector): iterable
170170
{
171171
foreach ($reflector->getAttributes() as $attribute) {
172172
if ($this->isKnownAttribute($attribute->getName())) {
@@ -193,13 +193,13 @@ public function loadAnnotations(object $reflector): iterable
193193
}
194194

195195
if ($reflector instanceof \ReflectionClass) {
196-
yield from $this->reader->getClassAnnotations($reflector);
196+
yield from $this->getClassAnnotations($reflector);
197197
}
198198
if ($reflector instanceof \ReflectionMethod) {
199-
yield from $this->reader->getMethodAnnotations($reflector);
199+
yield from $this->getMethodAnnotations($reflector);
200200
}
201201
if ($reflector instanceof \ReflectionProperty) {
202-
yield from $this->reader->getPropertyAnnotations($reflector);
202+
yield from $this->getPropertyAnnotations($reflector);
203203
}
204204
}
205205

@@ -229,4 +229,49 @@ private function isKnownAttribute(string $attributeName): bool
229229

230230
return false;
231231
}
232+
233+
/**
234+
* @return object[]
235+
*/
236+
private function getClassAnnotations(\ReflectionClass $reflector): array
237+
{
238+
if ($annotations = array_filter(
239+
$this->reader->getClassAnnotations($reflector),
240+
fn (object $annotation): bool => $this->isKnownAttribute($annotation::class),
241+
)) {
242+
trigger_deprecation('symfony/serializer', '6.4', 'Class "%s" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.', $reflector->getName());
243+
}
244+
245+
return $annotations;
246+
}
247+
248+
/**
249+
* @return object[]
250+
*/
251+
private function getMethodAnnotations(\ReflectionMethod $reflector): array
252+
{
253+
if ($annotations = array_filter(
254+
$this->reader->getMethodAnnotations($reflector),
255+
fn (object $annotation): bool => $this->isKnownAttribute($annotation::class),
256+
)) {
257+
trigger_deprecation('symfony/serializer', '6.4', 'Method "%s::%s()" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.', $reflector->getDeclaringClass()->getName(), $reflector->getName());
258+
}
259+
260+
return $annotations;
261+
}
262+
263+
/**
264+
* @return object[]
265+
*/
266+
private function getPropertyAnnotations(\ReflectionProperty $reflector): array
267+
{
268+
if ($annotations = array_filter(
269+
$this->reader->getPropertyAnnotations($reflector),
270+
fn (object $annotation): bool => $this->isKnownAttribute($annotation::class),
271+
)) {
272+
trigger_deprecation('symfony/serializer', '6.4', 'Property "%s::$%s" uses Doctrine Annotations to configure serialization, which is deprecated. Use PHP attributes instead.', $reflector->getDeclaringClass()->getName(), $reflector->getName());
273+
}
274+
275+
return $annotations;
276+
}
232277
}

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