diff --git a/src/Symfony/Component/HttpKernel/EventListener/RouterListener.php b/src/Symfony/Component/HttpKernel/EventListener/RouterListener.php index fb4bd60bc3fce..dd6f5bb214d73 100644 --- a/src/Symfony/Component/HttpKernel/EventListener/RouterListener.php +++ b/src/Symfony/Component/HttpKernel/EventListener/RouterListener.php @@ -117,7 +117,14 @@ public function onKernelRequest(RequestEvent $event): void $attributes = []; foreach ($parameters as $parameter => $value) { - $attribute = $mapping[$parameter] ?? $parameter; + if (!isset($mapping[$parameter])) { + $attribute = $parameter; + } elseif (\is_array($mapping[$parameter])) { + [$attribute, $parameter] = $mapping[$parameter]; + $mappedAttributes[$attribute] = ''; + } else { + $attribute = $mapping[$parameter]; + } if (!isset($mappedAttributes[$attribute])) { $attributes[$attribute] = $value; diff --git a/src/Symfony/Component/HttpKernel/Tests/EventListener/RouterListenerTest.php b/src/Symfony/Component/HttpKernel/Tests/EventListener/RouterListenerTest.php index d13093db0c55c..ca7bb1b1f6d9e 100644 --- a/src/Symfony/Component/HttpKernel/Tests/EventListener/RouterListenerTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/EventListener/RouterListenerTest.php @@ -323,5 +323,49 @@ public static function provideRouteMapping(): iterable ], ], ]; + + yield [ + [ + 'conference' => ['slug' => 'vienna-2024'], + ], + [ + 'slug' => 'vienna-2024', + '_route_mapping' => [ + 'slug' => [ + 'conference', + 'slug', + ], + ], + ], + ]; + + yield [ + [ + 'article' => [ + 'id' => 'abc123', + 'date' => '2024-04-24', + 'slug' => 'symfony-rocks', + ], + ], + [ + 'id' => 'abc123', + 'date' => '2024-04-24', + 'slug' => 'symfony-rocks', + '_route_mapping' => [ + 'id' => [ + 'article', + 'id' + ], + 'date' => [ + 'article', + 'date', + ], + 'slug' => [ + 'article', + 'slug', + ], + ], + ], + ]; } } diff --git a/src/Symfony/Component/Routing/Route.php b/src/Symfony/Component/Routing/Route.php index 0364fdd072492..1ed484f71237b 100644 --- a/src/Symfony/Component/Routing/Route.php +++ b/src/Symfony/Component/Routing/Route.php @@ -418,15 +418,15 @@ private function extractInlineDefaultsAndRequirements(string $pattern): string $mapping = $this->getDefault('_route_mapping') ?? []; - $pattern = preg_replace_callback('#\{(!?)([\w\x80-\xFF]++)(:[\w\x80-\xFF]++)?(<.*?>)?(\?[^\}]*+)?\}#', function ($m) use (&$mapping) { - if (isset($m[5][0])) { - $this->setDefault($m[2], '?' !== $m[5] ? substr($m[5], 1) : null); + $pattern = preg_replace_callback('#\{(!?)([\w\x80-\xFF]++)(:([\w\x80-\xFF]++)(\.[\w\x80-\xFF]++)?)?(<.*?>)?(\?[^\}]*+)?\}#', function ($m) use (&$mapping) { + if (isset($m[7][0])) { + $this->setDefault($m[2], '?' !== $m[6] ? substr($m[7], 1) : null); } - if (isset($m[4][0])) { - $this->setRequirement($m[2], substr($m[4], 1, -1)); + if (isset($m[6][0])) { + $this->setRequirement($m[2], substr($m[6], 1, -1)); } - if (isset($m[3][0])) { - $mapping[$m[2]] = substr($m[3], 1); + if (isset($m[4][0])) { + $mapping[$m[2]] = isset($m[5][0]) ? [$m[4], substr($m[5], 1)] : $mapping[$m[2]] = [$m[4], $m[2]]; } return '{'.$m[1].$m[2].'}'; diff --git a/src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php b/src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php index c426e071f3b96..0c2756e48be49 100644 --- a/src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php +++ b/src/Symfony/Component/Routing/Tests/Matcher/UrlMatcherTest.php @@ -1011,7 +1011,30 @@ public function testMapping() '_route' => 'a', 'slug' => 'vienna-2024', '_route_mapping' => [ - 'slug' => 'conference', + 'slug' => [ + 'conference', + 'slug', + ], + ], + ]; + $this->assertEquals($expected, $matcher->match('/conference/vienna-2024')); + } + + public function testMappingwithAlias() + { + $collection = new RouteCollection(); + $collection->add('a', new Route('/conference/{conferenceSlug:conference.slug}')); + + $matcher = $this->getUrlMatcher($collection); + + $expected = [ + '_route' => 'a', + 'conferenceSlug' => 'vienna-2024', + '_route_mapping' => [ + 'conferenceSlug' => [ + 'conference', + 'slug', + ], ], ]; $this->assertEquals($expected, $matcher->match('/conference/vienna-2024'));