Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit ec47816

Browse filesBrowse files
committed
[Routing] Fix localized paths
1 parent dd919a7 commit ec47816
Copy full SHA for ec47816

File tree

4 files changed

+209
-36
lines changed
Filter options

4 files changed

+209
-36
lines changed

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/Routing/Annotation/Route.php
+14-2Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
* @author Fabien Potencier <fabien@symfony.com>
2222
* @author Alexander M. Turek <me@derrabus.de>
2323
*/
24-
#[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD)]
24+
//[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD)]
2525
class Route
2626
{
2727
private $path;
@@ -69,7 +69,19 @@ public function __construct(
6969
} elseif (!\is_array($data)) {
7070
throw new \TypeError(sprintf('"%s": Argument $data is expected to be a string or array, got "%s".', __METHOD__, get_debug_type($data)));
7171
} elseif ([] !== $data) {
72-
trigger_deprecation('symfony/routing', '5.3', 'Passing an array as first argument to "%s" is deprecated. Use named arguments instead.', __METHOD__);
72+
$deprecation = false;
73+
foreach ($data as $key => $val) {
74+
if (\in_array($key, ['path', 'name', 'requirements', 'options', 'defaults', 'host', 'methods', 'schemes', 'condition', 'priority', 'locale', 'format', 'utf8', 'stateless', 'env', 'value'])) {
75+
$deprecation = true;
76+
}
77+
}
78+
79+
if ($deprecation) {
80+
trigger_deprecation('symfony/routing', '5.3', 'Passing an array as first argument to "%s" is deprecated. Use named arguments instead.', __METHOD__);
81+
} else {
82+
$localizedPaths = $data;
83+
$data = ['path' => $localizedPaths];
84+
}
7385
}
7486
if (null !== $path && !\is_string($path) && !\is_array($path)) {
7587
throw new \TypeError(sprintf('"%s": Argument $path is expected to be a string, array or null, got "%s".', __METHOD__, get_debug_type($path)));

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/Routing/Tests/Annotation/RouteTest.php
+59-34Lines changed: 59 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -11,73 +11,98 @@
1111

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

14+
use Doctrine\Common\Annotations\AnnotationReader;
1415
use PHPUnit\Framework\TestCase;
1516
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
1617
use Symfony\Component\Routing\Annotation\Route;
18+
use Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures\FooController;
19+
use Symfony\Component\Routing\Tests\Fixtures\AttributeFixtures\FooController as FooAttributesController;
1720

1821
class RouteTest extends TestCase
1922
{
2023
use ExpectDeprecationTrait;
2124

22-
/**
23-
* @group legacy
24-
*/
25-
public function testInvalidRouteParameter()
25+
private function getMethodAnnotation(string $method, bool $attributes): Route
2626
{
27-
$this->expectException(\BadMethodCallException::class);
28-
new Route(['foo' => 'bar']);
27+
$class = $attributes ? FooAttributesController::class : FooController::class;
28+
$reflection = new \ReflectionMethod($class, $method);
29+
30+
if ($attributes) {
31+
$attributes = $reflection->getAttributes(Route::class);
32+
$route = $attributes[0]->newInstance();
33+
} else {
34+
$reader = new AnnotationReader();
35+
$route = $reader->getMethodAnnotation($reflection, Route::class);
36+
}
37+
38+
if (!$route instanceof Route) {
39+
throw new \Exception('Can\'t parse annotation');
40+
}
41+
42+
return $route;
43+
}
44+
45+
public function provideDeprecationArrayAsFirstArgument()
46+
{
47+
return [
48+
['requirements', ['locale' => 'en'], 'getRequirements'],
49+
['options', ['compiler_class' => 'RouteCompiler'], 'getOptions'],
50+
['name', 'blog_index', 'getName'],
51+
['defaults', ['_controller' => 'MyBlogBundle:Blog:index'], 'getDefaults'],
52+
['schemes', ['https'], 'getSchemes'],
53+
['methods', ['GET', 'POST'], 'getMethods'],
54+
['host', '{locale}.example.com', 'getHost'],
55+
['condition', 'context.getMethod() == "GET"', 'getCondition'],
56+
['value', '/Blog', 'getPath'],
57+
['value', ['nl' => '/hier', 'en' => '/here'], 'getLocalizedPaths'],
58+
];
2959
}
3060

3161
/**
3262
* @group legacy
63+
* @dataProvider provideDeprecationArrayAsFirstArgument
3364
*/
34-
public function testTryingToSetLocalesDirectly()
65+
public function testDeprecationArrayAsFirstArgument(string $parameter, $value, string $getter)
3566
{
36-
$this->expectException(\BadMethodCallException::class);
37-
new Route(['locales' => ['nl' => 'bar']]);
67+
$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.');
68+
69+
$route = new Route([$parameter => $value]);
70+
$this->assertEquals($route->$getter(), $value);
3871
}
3972

4073
/**
4174
* @requires PHP 8
4275
* @dataProvider getValidParameters
4376
*/
44-
public function testRouteParameters(string $parameter, $value, string $getter)
77+
public function testRouteParameters(string $methodName, string $getter, $expectedReturn)
4578
{
46-
$route = new Route(...[$parameter => $value]);
47-
$this->assertEquals($route->$getter(), $value);
79+
$route = $this->getMethodAnnotation($methodName, true);
80+
$this->assertEquals($route->$getter(), $expectedReturn);
4881
}
4982

5083
/**
5184
* @group legacy
52-
* @dataProvider getLegacyValidParameters
85+
* @dataProvider getValidParameters
5386
*/
54-
public function testLegacyRouteParameters(string $parameter, $value, string $getter)
87+
public function testLegacyRouteParameters(string $methodName, string $getter, $expectedReturn)
5588
{
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-
58-
$route = new Route([$parameter => $value]);
59-
$this->assertEquals($route->$getter(), $value);
89+
$route = $this->getMethodAnnotation($methodName, false);
90+
$this->assertEquals($route->$getter(), $expectedReturn);
6091
}
6192

6293
public function getValidParameters(): iterable
6394
{
6495
return [
65-
['requirements', ['locale' => 'en'], 'getRequirements'],
66-
['options', ['compiler_class' => 'RouteCompiler'], 'getOptions'],
67-
['name', 'blog_index', 'getName'],
68-
['defaults', ['_controller' => 'MyBlogBundle:Blog:index'], 'getDefaults'],
69-
['schemes', ['https'], 'getSchemes'],
70-
['methods', ['GET', 'POST'], 'getMethods'],
71-
['host', '{locale}.example.com', 'getHost'],
72-
['condition', 'context.getMethod() == "GET"', 'getCondition'],
96+
['simplePath', 'getPath', '/Blog'],
97+
['localized', 'getLocalizedPaths', ['nl' => '/hier', 'en' => '/here']],
98+
['requirements', 'getRequirements', ['locale' => 'en']],
99+
['options', 'getOptions', ['compiler_class' => 'RouteCompiler']],
100+
['name', 'getName', 'blog_index'],
101+
['defaults', 'getDefaults', ['_controller' => 'MyBlogBundle:Blog:index']],
102+
['schemes', 'getSchemes', ['https']],
103+
['methods', 'getMethods', ['GET', 'POST']],
104+
['host', 'getHost', '{locale}.example.com'],
105+
['condition', 'getCondition', 'context.getMethod() == \'GET\''],
73106
];
74107
}
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-
}
83108
}
+78Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<?php
2+
3+
namespace Symfony\Component\Routing\Tests\Fixtures\AnnotationFixtures;
4+
5+
use Symfony\Component\Routing\Annotation\Route;
6+
7+
class FooController
8+
{
9+
/**
10+
* @Route("/Blog")
11+
*/
12+
public function simplePath()
13+
{
14+
}
15+
16+
/**
17+
* @Route({"nl":"/hier","en":"/here"})
18+
*/
19+
public function localized()
20+
{
21+
}
22+
23+
/**
24+
* @Route(requirements={"locale":"en"})
25+
*/
26+
public function requirements()
27+
{
28+
}
29+
30+
/**
31+
* @Route(options={"compiler_class":"RouteCompiler"})
32+
*/
33+
public function options()
34+
{
35+
}
36+
37+
/**
38+
* @Route(name="blog_index")
39+
*/
40+
public function name()
41+
{
42+
}
43+
44+
/**
45+
* @Route(defaults={"_controller":"MyBlogBundle:Blog:index"})
46+
*/
47+
public function defaults()
48+
{
49+
}
50+
51+
/**
52+
* @Route(schemes={"https"})
53+
*/
54+
public function schemes()
55+
{
56+
}
57+
58+
/**
59+
* @Route(methods={"GET","POST"})
60+
*/
61+
public function methods()
62+
{
63+
}
64+
65+
/**
66+
* @Route(host="{locale}.example.com")
67+
*/
68+
public function host()
69+
{
70+
}
71+
72+
/**
73+
* @Route(condition="context.getMethod() == 'GET'")
74+
*/
75+
public function condition()
76+
{
77+
}
78+
}
+58Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
3+
namespace Symfony\Component\Routing\Tests\Fixtures\AttributeFixtures;
4+
5+
use Symfony\Component\Routing\Annotation\Route;
6+
7+
class FooController
8+
{
9+
#[Route('/Blog')]
10+
public function simplePath()
11+
{
12+
}
13+
14+
#[Route(['nl' => '/hier', 'en' => '/here'])]
15+
public function localized()
16+
{
17+
}
18+
19+
#[Route(requirements: ['locale' => 'en'])]
20+
public function requirements()
21+
{
22+
}
23+
24+
#[Route(options: ['compiler_class' => 'RouteCompiler'])]
25+
public function options()
26+
{
27+
}
28+
29+
#[Route(name: 'blog_index')]
30+
public function name()
31+
{
32+
}
33+
34+
#[Route(defaults: ['_controller' => 'MyBlogBundle:Blog:index'])]
35+
public function defaults()
36+
{
37+
}
38+
39+
#[Route(schemes: ['https'])]
40+
public function schemes()
41+
{
42+
}
43+
44+
#[Route(methods: ['GET', 'POST'])]
45+
public function methods()
46+
{
47+
}
48+
49+
#[Route(host: '{locale}.example.com')]
50+
public function host()
51+
{
52+
}
53+
54+
#[Route(condition: 'context.getMethod() == \'GET\'')]
55+
public function condition()
56+
{
57+
}
58+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.