8000 [Routing] Remove Doctrine annotations support · symfony/symfony@0114d73 · GitHub
[go: up one dir, main page]

Skip to content

Commit 0114d73

Browse files
committed
[Routing] Remove Doctrine annotations support
1 parent dc9fb50 commit 0114d73

Some content is hidden

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

41 files changed

+149
-906
lines changed

UPGRADE-7.0.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,8 @@ Routing
198198
-------
199199

200200
* Add argument `$routeParameters` to `UrlMatcher::handleRouteRequirements()`
201+
* Remove Doctrine annotations support in favor of native attributes
202+
* Change the constructor signature of `AnnotationClassLoader` to `__construct(?string $env = null)`, passing an annotation reader as first argument is not supported anymore
201203

202204
Security
203205
--------

src/Symfony/Component/Routing/Annotation/Route.php

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,6 @@
1212
namespace Symfony\Component\Routing\Annotation;
1313

1414
/**
15-
* Annotation class for @Route().
16-
*
17-
* @Annotation
18-
* @NamedArgumentConstructor
19-
* @Target({"CLASS", "METHOD"})
20-
*
2115
* @author Fabien Potencier <fabien@symfony.com>
2216
* @author Alexander M. Turek <me@derrabus.de>
2317
*/

src/Symfony/Component/Routing/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ CHANGELOG
55
---
66

77
* Add argument `$routeParameters` to `UrlMatcher::handleRouteRequirements()`
8+
* Remove Doctrine annotations support in favor of native attributes
9+
* Change the constructor signature of `AnnotationClassLoader` to `__construct(?string $env = null)`, passing an annotation reader as first argument is not supported anymore
810

911
6.4
1012
---

src/Symfony/Component/Routing/Loader/AnnotationClassLoader.php

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

1212
namespace Symfony\Component\Routing\Loader;
1313

14-
use Doctrine\Common\Annotations\Reader;
1514
use Symfony\Component\Config\Loader\LoaderInterface;
1615
use Symfony\Component\Config\Loader\LoaderResolverInterface;
1716
use Symfony\Component\Config\Resource\FileResource;
@@ -52,49 +51,12 @@
5251
*/
5352
abstract class AnnotationClassLoader implements LoaderInterface
5453
{
55-
/**
56-
* @var Reader|null
57-
*
58-
* @deprecated in Symfony 6.4, this property will be removed in Symfony 7.
59-
*/
60-
protected $reader;
61-
62-
/**
63-
* @var string|null
64-
*/
65-
protected $env;
66-
67-
/**
68-
* @var string
69-
*/
70-
protected $routeAnnotationClass = RouteAnnotation::class;
71-
72-
/**
73-
* @var int
74-
*/
75-
protected $defaultRouteIndex = 0;
76-
77-
private bool $hasDeprecatedAnnotations = false;
78-
79-
/**
80-
* @param string|null $env
81-
*/
82-
public function __construct($env = null)
83-
{
84-
if ($env instanceof Reader || null === $env && \func_num_args() > 1 && null !== func_get_arg(1)) {
85-
trigger_deprecation('symfony/routing', '6.4', 'Passing an instance of "%s" as first and the environment as second argument to "%s" is deprecated. Pass the environment as first argument instead.', Reader::class, __METHOD__);
54+
protected string $routeAnnotationClass = RouteAnnotation::class;
55+
protected int $defaultRouteIndex = 0;
8656

87-
$this->reader = $env;
88-
$env = \func_num_args() > 1 ? func_get_arg(1) : null;
89-
}
90-
91-
if (\is_string($env) || null === $env) {
92-
$this->env = $env;
93-
} elseif ($env instanceof \Stringable || \is_scalar($env)) {
94-
$this->env = (string) $env;
95-
} else {
96-
throw new \TypeError(__METHOD__.sprintf(': Parameter $env was expected to be a string or null, "%s" given.', get_debug_type($env)));
97-
}
57+
public function __construct(
58+
protected readonly ?string $env = null,
59+
) {
9860
}
9961

10062
/**
@@ -121,48 +83,38 @@ public function load(mixed $class, string $type = null): RouteCollection
12183
throw new \InvalidArgumentException(sprintf('Annotations from class "%s" cannot be read as it is abstract.', $class->getName()));
12284
}
12385

124-
$this->hasDeprecatedAnnotations = false;
125-
126-
try {
127-
$globals = $this->getGlobals($class);
128-
$collection = new RouteCollection();
129-
$collection->addResource(new FileResource($class->getFileName()));
130-
if ($globals['env'] && $this->env !== $globals['env']) {
131-
return $collection;
132-
}
133-
$fqcnAlias = false;
134-
foreach ($class->getMethods() as $method) {
135-
$this->defaultRouteIndex = 0;
136-
$routeNamesBefore = array_keys($collection->all());
137-
foreach ($this->getAnnotations($method) as $annot) {
138-
$this->addRoute($collection, $annot, $globals, $class, $method);
139-
if ('__invoke' === $method->name) {
140-
$fqcnAlias = true;
141-
}
142-
}
143-
144-
if (1 === $collection->count() - \count($routeNamesBefore)) {
145-
$newRouteName = current(array_diff(array_keys($collection->all()), $routeNamesBefore));
146-
$collection->addAlias(sprintf('%s::%s', $class->name, $method->name), $newRouteName);
147-
}
148-
}
149-
if (0 === $collection->count() && $class->hasMethod('__invoke')) {
150-
$globals = $this->resetGlobals();
151-
foreach ($this->getAnnotations($class) as $annot) {
152-
$this->addRoute($collection, $annot, $globals, $class, $class->getMethod('__invoke'));
86+
$globals = $this->getGlobals($class);
87+
$collection = new RouteCollection();
88+
$collection->addResource(new FileResource($class->getFileName()));
89+
if ($globals['env'] && $this->env !== $globals['env']) {
90+
return $collection;
91+
}
92+
$fqcnAlias = false;
93+
foreach ($class->getMethods() as $method) {
94+
$this->defaultRouteIndex = 0;
95+
$routeNamesBefore = array_keys($collection->all());
96+
foreach ($this->getAnnotations($method) as $annot) {
97+
$this->addRoute($collection, $annot, $globals, $class, $method);
98+
if ('__invoke' === $method->name) {
15399
$fqcnAlias = true;
154100
}
155101
}
156-
if ($fqcnAlias && 1 === $collection->count()) {
157-
$collection->addAlias($class->name, $invokeRouteName = key($collection->all()));
158-
$collection->addAlias(sprintf('%s::__invoke', $class->name), $invokeRouteName);
159-
}
160102

161-
if ($this->hasDeprecatedAnnotations) {
162-
trigger_deprecation('symfony/routing', '6.4', 'Class "%s" uses Doctrine Annotations to configure routes, which is deprecated. Use PHP attributes instead.', $class->getName());
103+
if (1 === $collection->count() - \count($routeNamesBefore)) {
104+
$newRouteName = current(array_diff(array_keys($collection->all()), $routeNamesBefore));
105+
$collection->addAlias(sprintf('%s::%s', $class->name, $method->name), $newRouteName);
163106
}
164-
} finally {
165-
$this->hasDeprecatedAnnotations = false;
107+
}
108+
if (0 === $collection->count() && $class->hasMethod('__invoke')) {
109+
$globals = $this->resetGlobals();
110+
foreach ($this->getAnnotations($class) as $annot) {
111+
$this->addRoute($collection, $annot, $globals, $class, $class->getMethod('__invoke'));
112+
$fqcnAlias = true;
113+
}
114+
}
115+
if ($fqcnAlias && 1 === $collection->count()) {
116+
$collection->addAlias($class->name, $invokeRouteName = key($collection->all()));
117+
$collection->addAlias(sprintf('%s::__invoke', $class->name), $invokeRouteName);
166118
}
167119

168120
return $collection;
@@ -291,15 +243,9 @@ protected function getGlobals(\ReflectionClass $class): array
291243
{
292244
$globals = $this->resetGlobals();
293245

294-
$annot = null;
295246
if ($attribute = $class->getAttributes($this->routeAnnotationClass, \ReflectionAttribute::IS_INSTANCEOF)[0] ?? null) {
296247
$annot = $attribute->newInstance();
297-
}
298-
if (!$annot && $annot = $this->reader?->getClassAnnotation($class, $this->routeAnnotationClass)) {
299-
$this->hasDeprecatedAnnotations = true;
300-
}
301248

302-
if ($annot) {
303249
if (null !== $annot->getName()) {
304250
$globals['name'] = $annot->getName();
305251
}
@@ -387,21 +333,5 @@ private function getAnnotations(\ReflectionClass|\ReflectionMethod $reflection):
387333
foreach ($reflection->getAttributes($this->routeAnnotationClass, \ReflectionAttribute::IS_INSTANCEOF) as $attribute) {
388334
yield $attribute->newInstance();
389335
}
390-
391-
if (!$this->reader) {
392-
return;
393-
}
394-
395-
$annotations = $reflection instanceof \ReflectionClass
396-
? $this->reader->getClassAnnotations($reflection)
397-
: $this->reader->getMethodAnnotations($reflection);
398-
399-
foreach ($annotations as $annotation) {
400-
if ($annotation instanceof $this->routeAnnotationClass) {
401-
$this->hasDeprecatedAnnotations = true;
402-
403-
yield $annotation;
404-
}
405-
}
406336
}
407337
}

src/Symfony/Component/Routing/Tests/Annotation/RouteTest.php

Lines changed: 3 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -11,49 +11,19 @@
1111

1212
namespace Symfony\Component\Routing\Tests\Annotation;
1313

14-
use Doctrine\Common\Annotations\AnnotationReader;
1514
use PHPUnit\Framework\TestCase;
1615
use Symfony\Component\Routing\Annotation\Route;
17-
use Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures\FooController;
18-
use Symfony\Component\Routing\Tests\Fixtures\AttributeFixtures\FooController as FooAttributesController;
16+
use Symfony\Component\Routing\Tests\Fixtures\AttributeFixtures\FooController;
1917

2018
class RouteTest extends TestCase
2119
{
22-
private function getMethodAnnotation(string $method, bool $attributes): Route
23-
{
24-
$class = $attributes ? FooAttributesController::class : FooController::class;
25-
$reflection = new \ReflectionMethod($class, $method);
26-
27-
if ($attributes) {
28-
$attributes = $reflection->getAttributes(Route::class);
29-
$route = $attributes[0]->newInstance();
30-
} else {
31-
$reader = new AnnotationReader();
32-
$route = $reader->getMethodAnnotation($reflection, Route::class);
33-
}
34-
35-
if (!$route instanceof Route) {
36-
throw new \Exception('Can\'t parse annotation');
37-
}
38-
39-
return $route;
40-
}
41-
4220
/**
4321
* @dataProvider getValidParameters
4422
*/
45-
public function testLoadFromAttribute(string $methodName, string $getter, $expectedReturn)
23+
public function testLoadFromAttribute(string $methodName, string $getter, mixed $expectedReturn)
4624
{
47-
$route = $this->getMethodAnnotation($methodName, true);
48-
$this->assertEquals($route->$getter(), $expectedReturn);
49-
}
25+
$route = (new \ReflectionMethod(FooController::class, $methodName))->getAttributes(Route::class)[0]->newInstance();
5026

51-
/**
52-
* @dataProvider getValidParameters
53-
*/
54-
public function testLoadFromDoctrineAnnotation(string $methodName, string $getter, $expectedReturn)
55-
{
56-
$route = $this->getMethodAnnotation($methodName, false);
5727
$this->assertEquals($route->$getter(), $expectedReturn);
5828
}
5929

src/Symfony/Component/Routing/Tests/Fixtures/AnnotationFixtures/AbstractClassController.php

Lines changed: 0 additions & 7 deletions
This file was deleted.

src/Symfony/Component/Routing/Tests/Fixtures/AnnotationFixtures/ActionPathController.php

Lines changed: 0 additions & 15 deletions
This file was deleted.

src/Symfony/Component/Routing/Tests/Fixtures/AnnotationFixtures/BazClass.php

Lines changed: 0 additions & 25 deletions
This file was deleted.

src/Symfony/Component/Routing/Tests/Fixtures/AnnotationFixtures/DefaultValueController.php

Lines changed: 0 additions & 39 deletions
This file was deleted.

src/Symfony/Component/Routing/Tests/Fixtures/AnnotationFixtures/EncodingClass.php

Lines changed: 0 additions & 15 deletions
This file was deleted.

src/Symfony/Component/Routing/Tests/Fixtures/AnnotationFixtures/ExplicitLocalizedActionPathController.php

Lines changed: 0 additions & 15 deletions
This file was deleted.

0 commit comments

Comments
 (0)
0