Skip to content

Commit 2a5aba7

Browse files
committed
feature #40266 [Routing] Construct Route annotations using named arguments (derrabus)
This PR was merged into the 5.3-dev branch. Discussion ---------- [Routing] Construct Route annotations using named arguments | Q | A | ------------- | --- | Branch? | 5.x | Bug fix? | no | New feature? | no | Deprecations? | yes | Tickets | N/A | License | MIT | Doc PR | Not needed This PR proposes to bump the `doctrine/annotations` library to 1.12 to gain access to its emulation layer for named arguments. Furthermore, constructing a `Route` annotation the old way by passing an array of parameters is deprecated. ### Reasons for this change The constructors of our annotation classes have become unnecessarily complicated because we have to support two ways of calling them: * An array of parameters, passed as first argument, because that's the default behavior `doctrine/annotations`. * A set of named arguments because that's how PHP 8 attributes work. Since we can now tell the Doctrine annotation reader to use named arguments as well, we can simplify the constructors of our annotations significantly. ### Drawback After this change, there is no easy way anymore to construct instances of the `Route` annotation class directly on PHP 7. The PR has been built under the assumption that instances of this class are usually created using either Doctrine annotations or a PHP 8 attribute. Thus, most applications should be unaffected by this change. Commits ------- 29b0f96046 [Routing] Construct Route annotations using named arguments
2 parents aeb03fb + 45e7ca9 commit 2a5aba7

File tree

5 files changed

+39
-6
lines changed

5 files changed

+39
-6
lines changed

Annotation/Route.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
* Annotation class for @Route().
1616
*
1717
* @Annotation
18+
* @NamedArgumentConstructor
1819
* @Target({"CLASS", "METHOD"})
1920
*
2021
* @author Fabien Potencier <[email protected]>
@@ -67,6 +68,8 @@ public function __construct(
6768
$data = ['path' => $data];
6869
} elseif (!\is_array($data)) {
6970
throw new \TypeError(sprintf('"%s": Argument $data is expected to be a string or array, got "%s".', __METHOD__, get_debug_type($data)));
71+
} elseif ([] !== $data) {
72+
trigger_deprecation('symfony/routing', '5.3', 'Passing an array as first argument to "%s" is deprecated. Use named arguments instead.', __METHOD__);
7073
}
7174
if (null !== $path && !\is_string($path) && !\is_array($path)) {
7275
throw new \TypeError(sprintf('"%s": Argument $path is expected to be a string, array or null, got "%s".', __METHOD__, get_debug_type($path)));

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ CHANGELOG
66

77
* Already encoded slashes are not decoded nor double-encoded anymore when generating URLs
88
* Add support for per-env configuration in loaders
9+
* Deprecate creating instances of the `Route` annotation class by passing an array of parameters
910

1011
5.2.0
1112
-----

Tests/Annotation/RouteTest.php

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,35 +12,56 @@
1212
namespace Symfony\Component\Routing\Tests\Annotation;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
1516
use Symfony\Component\Routing\Annotation\Route;
1617

1718
class RouteTest extends TestCase
1819
{
20+
use ExpectDeprecationTrait;
21+
22+
/**
23+
* @group legacy
24+
*/
1925
public function testInvalidRouteParameter()
2026
{
2127
$this->expectException(\BadMethodCallException::class);
2228
new Route(['foo' => 'bar']);
2329
}
2430

31+
/**
32+
* @group legacy
33+
*/
2534
public function testTryingToSetLocalesDirectly()
2635
{
2736
$this->expectException(\BadMethodCallException::class);
2837
new Route(['locales' => ['nl' => 'bar']]);
2938
}
3039

3140
/**
41+
* @requires PHP 8
3242
* @dataProvider getValidParameters
3343
*/
34-
public function testRouteParameters($parameter, $value, $getter)
44+
public function testRouteParameters(string $parameter, $value, string $getter)
45+
{
46+
$route = new Route(...[$parameter => $value]);
47+
$this->assertEquals($route->$getter(), $value);
48+
}
49+
50+
/**
51+
* @group legacy
52+
* @dataProvider getLegacyValidParameters
53+
*/
54+
public function testLegacyRouteParameters(string $parameter, $value, string $getter)
3555
{
56+
$this->expectDeprecation('Since symfony/routing 5.3: Passing an array as first argument to "Symfony\Component\Routing\Annotation\Route::__construct" is deprecated. Use named arguments instead.');
57+
3658
$route = new Route([$parameter => $value]);
3759
$this->assertEquals($route->$getter(), $value);
3860
}
3961

40-
public function getValidParameters()
62+
public function getValidParameters(): iterable
4163
{
4264
return [
43-
['value', '/Blog', 'getPath'],
4465
['requirements', ['locale' => 'en'], 'getRequirements'],
4566
['options', ['compiler_class' => 'RouteCompiler'], 'getOptions'],
4667
['name', 'blog_index', 'getName'],
@@ -49,7 +70,14 @@ public function getValidParameters()
4970
['methods', ['GET', 'POST'], 'getMethods'],
5071
['host', '{locale}.example.com', 'getHost'],
5172
['condition', 'context.getMethod() == "GET"', 'getCondition'],
52-
['value', ['nl' => '/hier', 'en' => '/here'], 'getLocalizedPaths'],
5373
];
5474
}
75+
76+
public function getLegacyValidParameters(): iterable
77+
{
78+
yield from $this->getValidParameters();
79+
80+
yield ['value', '/Blog', 'getPath'];
81+
yield ['value', ['nl' => '/hier', 'en' => '/here'], 'getLocalizedPaths'];
82+
}
5583
}

Tests/Loader/AnnotationFileLoaderTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public function testLoadFileWithoutStartTag()
5151

5252
public function testLoadVariadic()
5353
{
54-
$route = new Route(['path' => '/path/to/{id}']);
54+
$route = new Route('/path/to/{id}');
5555
$this->reader->expects($this->once())->method('getClassAnnotation');
5656
$this->reader->expects($this->once())->method('getMethodAnnotations')
5757
->willReturn([$route]);

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,11 @@
2626
"symfony/yaml": "^4.4|^5.0",
2727
"symfony/expression-language": "^4.4|^5.0",
2828
"symfony/dependency-injection": "^4.4|^5.0",
29-
"doctrine/annotations": "^1.10.4",
29+
"doctrine/annotations": "^1.12",
3030
"psr/log": "~1.0"
3131
},
3232
"conflict": {
33+
"doctrine/annotations": "<1.12",
3334
"symfony/config": "<5.3",
3435
"symfony/dependency-injection": "<4.4",
3536
"symfony/yaml": "<4.4"

0 commit comments

Comments
 (0)