Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6f598f9

Browse files
committed
feature #59904 [Routing] Add alias in {foo:bar} syntax in route parameter (eltharin)
This PR was squashed before being merged into the 7.3 branch. Discussion ---------- [Routing] Add alias in `{foo:bar}` syntax in route parameter | Q | A | ------------- | --- | Branch? | 7.3 | Bug fix? | no | New feature? | yes | Deprecations? | no | License | MIT Since #54720 we can/have to write route parameters with "destination" as slug:bar, but if we have two properties with same name example : `/search-book/{name:author}/{name:category}` we get the error message : Route pattern "/search-book/{name}/{name}" cannot reference variable name "name" more than once. Actually to prevent this error we have to use MapEntity as : ```php public function bookSearch( #[MapEntity(mapping: ['authorName' => 'name'])] Author $author, #[MapEntity(mapping: ['categoryName' => 'name'])] Category $category): Response { ``` and we have to remove Mapped Route Parameters : `#[Route('/search-book/{authorName}/{categoryName}')` This PR proposal is to remove MapEntity attributes and keep Mapped Route Parameters by adding an alias on it : `/search-book/{authorName:author.name}/{categoryName:category.name}` With that, EntityValueResolver will search name in author Entity and name in Category Entity. We can have url with : `{{ path('bookSearch', {authorName: 'KING', categoryName: 'Horror'}) }}` Commits ------- 4e2c638 [Routing] Add alias in `{foo:bar}` syntax in route parameter
2 parents 322995c + 4e2c638 commit 6f598f9

File tree

4 files changed

+83
-9
lines changed

4 files changed

+83
-9
lines changed

src/Symfony/Component/HttpKernel/EventListener/RouterListener.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,14 @@ public function onKernelRequest(RequestEvent $event): void
117117
$attributes = [];
118118

119119
foreach ($parameters as $parameter => $value) {
120-
$attribute = $mapping[$parameter] ?? $parameter;
120+
if (!isset($mapping[$parameter])) {
121+
$attribute = $parameter;
122+
} elseif (\is_array($mapping[$parameter])) {
123+
[$attribute, $parameter] = $mapping[$parameter];
124+
$mappedAttributes[$attribute] = '';
125+
} else {
126+
$attribute = $mapping[$parameter];
127+
}
121128

122129
if (!isset($mappedAttributes[$attribute])) {
123130
$attributes[$attribute] = $value;

src/Symfony/Component/HttpKernel/Tests/EventListener/RouterListenerTest.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,5 +323,49 @@ public static function provideRouteMapping(): iterable
323323
],
324324
],
325325
];
326+
327+
yield [
328+
[
329+
'conference' => ['slug' => 'vienna-2024'],
330+
],
331+
[
332+
'slug' => 'vienna-2024',
333+
'_route_mapping' => [
334+
'slug' => [
335+
'conference',
336+
'slug',
337+
],
338+
],
339+
],
340+
];
341+
342+
yield [
343+
[
344+
'article' => [
345+
'id' => 'abc123',
346+
'date' => '2024-04-24',
347+
'slug' => 'symfony-rocks',
348+
],
349+
],
350+
[
351+
'id' => 'abc123',
352+
'date' => '2024-04-24',
353+
'slug' => 'symfony-rocks',
354+
'_route_mapping' => [
355+
'id' => [
356+
'article',
357+
'id'
358+
],
359+
'date' => [
360+
'article',
361+
'date',
362+
],
363+
'slug' => [
364+
'article',
365+
'slug',
366+
],
367+
],
368+
],
369+
];
326370
}
327371
}

src/Symfony/Component/Routing/Route.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -418,15 +418,15 @@ private function extractInlineDefaultsAndRequirements(string $pattern): string
418418

419419
$mapping = $this->getDefault('_route_mapping') ?? [];
420420

421-
$pattern = preg_replace_callback('#\{(!?)([\w\x80-\xFF]++)(:[\w\x80-\xFF]++)?(<.*?>)?(\?[^\}]*+)?\}#', function ($m) use (&$mapping) {
422-
if (isset($m[5][0])) {
423-
$this->setDefault($m[2], '?' !== $m[5] ? substr($m[5], 1) : null);
421+
$pattern = preg_replace_callback('#\{(!?)([\w\x80-\xFF]++)(:([\w\x80-\xFF]++)(\.[\w\x80-\xFF]++)?)?(<.*?>)?(\?[^\}]*+)?\}#', function ($m) use (&$mapping) {
422+
if (isset($m[7][0])) {
423+
$this->setDefault($m[2], '?' !== $m[6] ? substr($m[7], 1) : null);
424424
}
425-
if (isset($m[4][0])) {
426-
$this->setRequirement($m[2], substr($m[4], 1, -1));
425+
if (isset($m[6][0])) {
426+
$this->setRequirement($m[2], substr($m[6], 1, -1));
427427
}
428-
if (isset($m[3][0])) {
429-
$mapping[$m[2]] = substr($m[3], 1);
428+
if (isset($m[4][0])) {
429+
$mapping[$m[2]] = isset($m[5][0]) ? [$m[4], substr($m[5], 1)] : $mapping[$m[2]] = [$m[4], $m[2]];
430430
}
431431

432432
return '{'.$m[1].$m[2].'}';

src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1011,7 +1011,30 @@ public function testMapping()
10111011
'_route' => 'a',
10121012
'slug' => 'vienna-2024',
10131013
'_route_mapping' => [
1014-
'slug' => 'conference',
1014+
'slug' => [
1015+
'conference',
1016+
'slug',
1017+
],
1018+
],
1019+
];
1020+
$this->assertEquals($expected, $matcher->match('/conference/vienna-2024'));
1021+
}
1022+
1023+
public function testMappingwithAlias()
1024+
{
1025+
$collection = new RouteCollection();
1026+
$collection->add('a', new Route('/conference/{conferenceSlug:conference.slug}'));
1027+
1028+
$matcher = $this->getUrlMatcher($collection);
1029+
1030+
$expected = [
1031+
'_route' => 'a',
1032+
'conferenceSlug' => 'vienna-2024',
1033+
'_route_mapping' => [
1034+
'conferenceSlug' => [
1035+
'conference',
1036+
'slug',
1037+
],
10151038
],
10161039
];
10171040
$this->assertEquals($expected, $matcher->match('/conference/vienna-2024'));

0 commit comments

Comments
 (0)