-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Routing] Fix i18n routing when the url contains the locale #35101
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,7 +40,6 @@ public function generate($name, $parameters = [], $referenceType = self::ABSOLUT | |
if (null !== $locale) { | ||
do { | ||
if (($this->compiledRoutes[$name.'.'.$locale][1]['_canonical_route'] ?? null) === $name) { | ||
unset($parameters['_locale']); | ||
$name .= '.'.$locale; | ||
break; | ||
} | ||
|
@@ -53,6 +52,14 @@ public function generate($name, $parameters = [], $referenceType = self::ABSOLUT | |
|
||
list($variables, $defaults, $requirements, $tokens, $hostTokens, $requiredSchemes) = $this->compiledRoutes[$name]; | ||
|
||
if (isset($defaults['_canonical_route']) && isset($defaults['_locale'])) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This if = we are in i18n routing. Checking isset($defaults['_locale']) is a safety. |
||
if (!\in_array('_locale', $variables, true)) { | ||
unset($parameters['_locale']); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We always unset the _locale parameter if the url does not have the _locale variable because the good i18n route has already been found and we don't want the parameter. |
||
} elseif (!isset($parameters['_locale'])) { | ||
$parameters['_locale'] = $defaults['_locale']; | ||
} | ||
} | ||
|
||
return $this->doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $referenceType, $hostTokens, $requiredSchemes); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -131,9 +131,9 @@ public function testDumpWithRouteNotFoundLocalizedRoutes() | |
|
||
public function testDumpWithFallbackLocaleLocalizedRoutes() | ||
{ | ||
$this->routeCollection->add('test.en', (new Route('/testing/is/fun'))->setDefault('_canonical_route', 'test')); | ||
$this->routeCollection->add('test.nl', (new Route('/testen/is/leuk'))->setDefault('_canonical_route', 'test')); | ||
$this->routeCollection->add('test.fr', (new Route('/tester/est/amusant'))->setDefault('_canonical_route', 'test')); | ||
$this->routeCollection->add('test.en', (new Route('/testing/is/fun'))->setDefault('_locale', 'en')->setDefault('_canonical_route', 'test')); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When a route is i18n, it always has a default _locale. The test must reflect that (same for the other ones). |
||
$this->routeCollection->add('test.nl', (new Route('/testen/is/leuk'))->setDefault('_locale', 'nl')->setDefault('_canonical_route', 'test')); | ||
$this->routeCollection->add('test.fr', (new Route('/tester/est/amusant'))->setDefault('_locale', 'fr')->setDefault('_canonical_route', 'test')); | ||
|
||
$code = $this->generatorDumper->dump(); | ||
file_put_contents($this->testTmpFilepath, $code); | ||
|
@@ -231,4 +231,29 @@ public function testDumpWithSchemeRequirement() | |
$this->assertEquals('https://localhost/app.php/testing', $absoluteUrl); | ||
$this->assertEquals('/app.php/testing', $relativeUrl); | ||
} | ||
|
||
public function testDumpWithLocalizedRoutesPreserveTheGoodLocaleInTheUrl() | ||
{ | ||
$this->routeCollection->add('foo.en', (new Route('/{_locale}/foo'))->setDefault('_locale', 'en')->setDefault('_canonical_route', 'foo')); | ||
$this->routeCollection->add('foo.fr', (new Route('/{_locale}/foo'))->setDefault('_locale', 'fr')->setDefault('_canonical_route', 'foo')); | ||
$this->routeCollection->add('fun.en', (new Route('/fun'))->setDefault('_locale', 'en')->setDefault('_canonical_route', 'fun')); | ||
$this->routeCollection->add('fun.fr', (new Route('/amusant'))->setDefault('_locale', 'fr')->setDefault('_canonical_route', 'fun')); | ||
|
||
file_put_contents($this->testTmpFilepath, $this->generatorDumper->dump()); | ||
|
||
$requestContext = new RequestContext(); | ||
$requestContext->setParameter('_locale', 'fr'); | ||
|
||
$compiledUrlGenerator = new CompiledUrlGenerator(require $this->testTmpFilepath, $requestContext, null, null); | ||
|
||
$this->assertSame('/fr/foo', $compiledUrlGenerator->generate('foo')); | ||
$this->assertSame('/en/foo', $compiledUrlGenerator->generate('foo.en')); | ||
fancyweb marked this conversation as resolved.
Show resolved
Hide resolved
|
||
$this->assertSame('/en/foo', $compiledUrlGenerator->generate('foo', ['_locale' => 'en'])); | ||
$this->assertSame('/en/foo', $compiledUrlGenerator->generate('foo.fr', ['_locale' => 'en'])); | ||
fancyweb marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
$this->assertSame('/amusant', $compiledUrlGenerator->generate('fun')); | ||
$this->assertSame('/fun', $compiledUrlGenerator->generate('fun.en')); | ||
$this->assertSame('/fun', $compiledUrlGenerator->generate('fun', ['_locale' => 'en'])); | ||
$this->assertSame('/amusant', $compiledUrlGenerator->generate('fun.fr', ['_locale' => 'en'])); | ||
fancyweb marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not needed anymore because it is handled by the new code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wouldn't it be OK to do
$parameters['_locale'] = $locale
here, and remove the other changes?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No because it's not enough to handle the case where the generator locale is "fr" + you just ask for the "foo.en" route. In this case the locale remains "fr".