Skip to content

Commit 5d4973c

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 symfony/symfony#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 ------- 4e2c6386912 [Routing] Add alias in `{foo:bar}` syntax in route parameter
2 parents 5801dd9 + 6accdb7 commit 5d4973c

File tree

2 files changed

+31
-8
lines changed

2 files changed

+31
-8
lines changed

Route.php

+7-7
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].'}';

Tests/Matcher/UrlMatcherTest.php

+24-1
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)