[Routing] Fix i18n routing when the url contains the locale
This commit is contained in:
parent
f3d8fd2521
commit
cd40bb8604
@ -40,7 +40,6 @@ class CompiledUrlGenerator extends UrlGenerator
|
|||||||
if (null !== $locale) {
|
if (null !== $locale) {
|
||||||
do {
|
do {
|
||||||
if (($this->compiledRoutes[$name.'.'.$locale][1]['_canonical_route'] ?? null) === $name) {
|
if (($this->compiledRoutes[$name.'.'.$locale][1]['_canonical_route'] ?? null) === $name) {
|
||||||
unset($parameters['_locale']);
|
|
||||||
$name .= '.'.$locale;
|
$name .= '.'.$locale;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -53,6 +52,14 @@ class CompiledUrlGenerator extends UrlGenerator
|
|||||||
|
|
||||||
list($variables, $defaults, $requirements, $tokens, $hostTokens, $requiredSchemes) = $this->compiledRoutes[$name];
|
list($variables, $defaults, $requirements, $tokens, $hostTokens, $requiredSchemes) = $this->compiledRoutes[$name];
|
||||||
|
|
||||||
|
if (isset($defaults['_canonical_route']) && isset($defaults['_locale'])) {
|
||||||
|
if (!\in_array('_locale', $variables, true)) {
|
||||||
|
unset($parameters['_locale']);
|
||||||
|
} elseif (!isset($parameters['_locale'])) {
|
||||||
|
$parameters['_locale'] = $defaults['_locale'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $this->doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $referenceType, $hostTokens, $requiredSchemes);
|
return $this->doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $referenceType, $hostTokens, $requiredSchemes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,7 +120,6 @@ EOF;
|
|||||||
if (null !== $locale && null !== $name) {
|
if (null !== $locale && null !== $name) {
|
||||||
do {
|
do {
|
||||||
if ((self::$declaredRoutes[$name.'.'.$locale][1]['_canonical_route'] ?? null) === $name) {
|
if ((self::$declaredRoutes[$name.'.'.$locale][1]['_canonical_route'] ?? null) === $name) {
|
||||||
unset($parameters['_locale']);
|
|
||||||
$name .= '.'.$locale;
|
$name .= '.'.$locale;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -133,6 +132,14 @@ EOF;
|
|||||||
|
|
||||||
list($variables, $defaults, $requirements, $tokens, $hostTokens, $requiredSchemes) = self::$declaredRoutes[$name];
|
list($variables, $defaults, $requirements, $tokens, $hostTokens, $requiredSchemes) = self::$declaredRoutes[$name];
|
||||||
|
|
||||||
|
if (isset($defaults['_canonical_route']) && isset($defaults['_locale'])) {
|
||||||
|
if (!\in_array('_locale', $variables, true)) {
|
||||||
|
unset($parameters['_locale']);
|
||||||
|
} elseif (!isset($parameters['_locale'])) {
|
||||||
|
$parameters['_locale'] = $defaults['_locale'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $this->doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $referenceType, $hostTokens, $requiredSchemes);
|
return $this->doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $referenceType, $hostTokens, $requiredSchemes);
|
||||||
}
|
}
|
||||||
EOF;
|
EOF;
|
||||||
|
@ -134,7 +134,6 @@ class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInt
|
|||||||
if (null !== $locale) {
|
if (null !== $locale) {
|
||||||
do {
|
do {
|
||||||
if (null !== ($route = $this->routes->get($name.'.'.$locale)) && $route->getDefault('_canonical_route') === $name) {
|
if (null !== ($route = $this->routes->get($name.'.'.$locale)) && $route->getDefault('_canonical_route') === $name) {
|
||||||
unset($parameters['_locale']);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (false !== $locale = strstr($locale, '_', true));
|
} while (false !== $locale = strstr($locale, '_', true));
|
||||||
@ -147,7 +146,18 @@ class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInt
|
|||||||
// the Route has a cache of its own and is not recompiled as long as it does not get modified
|
// the Route has a cache of its own and is not recompiled as long as it does not get modified
|
||||||
$compiledRoute = $route->compile();
|
$compiledRoute = $route->compile();
|
||||||
|
|
||||||
return $this->doGenerate($compiledRoute->getVariables(), $route->getDefaults(), $route->getRequirements(), $compiledRoute->getTokens(), $parameters, $name, $referenceType, $compiledRoute->getHostTokens(), $route->getSchemes());
|
$defaults = $route->getDefaults();
|
||||||
|
$variables = $compiledRoute->getVariables();
|
||||||
|
|
||||||
|
if (isset($defaults['_canonical_route']) && isset($defaults['_locale'])) {
|
||||||
|
if (!\in_array('_locale', $variables, true)) {
|
||||||
|
unset($parameters['_locale']);
|
||||||
|
} elseif (!isset($parameters['_locale'])) {
|
||||||
|
$parameters['_locale'] = $defaults['_locale'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->doGenerate($variables, $defaults, $route->getRequirements(), $compiledRoute->getTokens(), $parameters, $name, $referenceType, $compiledRoute->getHostTokens(), $route->getSchemes());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -131,9 +131,9 @@ class CompiledUrlGeneratorDumperTest extends TestCase
|
|||||||
|
|
||||||
public function testDumpWithFallbackLocaleLocalizedRoutes()
|
public function testDumpWithFallbackLocaleLocalizedRoutes()
|
||||||
{
|
{
|
||||||
$this->routeCollection->add('test.en', (new Route('/testing/is/fun'))->setDefault('_canonical_route', 'test'));
|
$this->routeCollection->add('test.en', (new Route('/testing/is/fun'))->setDefault('_locale', 'en')->setDefault('_canonical_route', 'test'));
|
||||||
$this->routeCollection->add('test.nl', (new Route('/testen/is/leuk'))->setDefault('_canonical_route', 'test'));
|
$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('_canonical_route', 'test'));
|
$this->routeCollection->add('test.fr', (new Route('/tester/est/amusant'))->setDefault('_locale', 'fr')->setDefault('_canonical_route', 'test'));
|
||||||
|
|
||||||
$code = $this->generatorDumper->dump();
|
$code = $this->generatorDumper->dump();
|
||||||
file_put_contents($this->testTmpFilepath, $code);
|
file_put_contents($this->testTmpFilepath, $code);
|
||||||
@ -231,4 +231,29 @@ class CompiledUrlGeneratorDumperTest extends TestCase
|
|||||||
$this->assertEquals('https://localhost/app.php/testing', $absoluteUrl);
|
$this->assertEquals('https://localhost/app.php/testing', $absoluteUrl);
|
||||||
$this->assertEquals('/app.php/testing', $relativeUrl);
|
$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'));
|
||||||
|
$this->assertSame('/en/foo', $compiledUrlGenerator->generate('foo', ['_locale' => 'en']));
|
||||||
|
$this->assertSame('/en/foo', $compiledUrlGenerator->generate('foo.fr', ['_locale' => 'en']));
|
||||||
|
|
||||||
|
$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']));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -140,9 +140,9 @@ class PhpGeneratorDumperTest extends TestCase
|
|||||||
|
|
||||||
public function testDumpWithFallbackLocaleLocalizedRoutes()
|
public function testDumpWithFallbackLocaleLocalizedRoutes()
|
||||||
{
|
{
|
||||||
$this->routeCollection->add('test.en', (new Route('/testing/is/fun'))->setDefault('_canonical_route', 'test'));
|
$this->routeCollection->add('test.en', (new Route('/testing/is/fun'))->setDefault('_locale', 'en')->setDefault('_canonical_route', 'test'));
|
||||||
$this->routeCollection->add('test.nl', (new Route('/testen/is/leuk'))->setDefault('_canonical_route', 'test'));
|
$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('_canonical_route', 'test'));
|
$this->routeCollection->add('test.fr', (new Route('/tester/est/amusant'))->setDefault('_locale', 'fr')->setDefault('_canonical_route', 'test'));
|
||||||
|
|
||||||
$code = $this->generatorDumper->dump([
|
$code = $this->generatorDumper->dump([
|
||||||
'class' => 'FallbackLocaleLocalizedProjectUrlGenerator',
|
'class' => 'FallbackLocaleLocalizedProjectUrlGenerator',
|
||||||
@ -250,4 +250,32 @@ class PhpGeneratorDumperTest extends TestCase
|
|||||||
$this->assertEquals('https://localhost/app.php/testing', $absoluteUrl);
|
$this->assertEquals('https://localhost/app.php/testing', $absoluteUrl);
|
||||||
$this->assertEquals('/app.php/testing', $relativeUrl);
|
$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([
|
||||||
|
'class' => 'PreserveTheGoodLocaleInTheUrlGenerator',
|
||||||
|
]));
|
||||||
|
include $this->testTmpFilepath;
|
||||||
|
|
||||||
|
$requestContext = new RequestContext();
|
||||||
|
$requestContext->setParameter('_locale', 'fr');
|
||||||
|
|
||||||
|
$phpGenerator = new \PreserveTheGoodLocaleInTheUrlGenerator($requestContext);
|
||||||
|
|
||||||
|
$this->assertSame('/fr/foo', $phpGenerator->generate('foo'));
|
||||||
|
$this->assertSame('/en/foo', $phpGenerator->generate('foo.en'));
|
||||||
|
$this->assertSame('/en/foo', $phpGenerator->generate('foo', ['_locale' => 'en']));
|
||||||
|
$this->assertSame('/en/foo', $phpGenerator->generate('foo.fr', ['_locale' => 'en']));
|
||||||
|
|
||||||
|
$this->assertSame('/amusant', $phpGenerator->generate('fun'));
|
||||||
|
$this->assertSame('/fun', $phpGenerator->generate('fun.en'));
|
||||||
|
$this->assertSame('/fun', $phpGenerator->generate('fun', ['_locale' => 'en']));
|
||||||
|
$this->assertSame('/amusant', $phpGenerator->generate('fun.fr', ['_locale' => 'en']));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -236,6 +236,29 @@ class UrlGeneratorTest extends TestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testDumpWithLocalizedRoutesPreserveTheGoodLocaleInTheUrl()
|
||||||
|
{
|
||||||
|
$routeCollection = new RouteCollection();
|
||||||
|
|
||||||
|
$routeCollection->add('foo.en', (new Route('/{_locale}/foo'))->setDefault('_locale', 'en')->setDefault('_canonical_route', 'foo'));
|
||||||
|
$routeCollection->add('foo.fr', (new Route('/{_locale}/foo'))->setDefault('_locale', 'fr')->setDefault('_canonical_route', 'foo'));
|
||||||
|
$routeCollection->add('fun.en', (new Route('/fun'))->setDefault('_locale', 'en')->setDefault('_canonical_route', 'fun'));
|
||||||
|
$routeCollection->add('fun.fr', (new Route('/amusant'))->setDefault('_locale', 'fr')->setDefault('_canonical_route', 'fun'));
|
||||||
|
|
||||||
|
$urlGenerator = $this->getGenerator($routeCollection);
|
||||||
|
$urlGenerator->getContext()->setParameter('_locale', 'fr');
|
||||||
|
|
||||||
|
$this->assertSame('/app.php/fr/foo', $urlGenerator->generate('foo'));
|
||||||
|
$this->assertSame('/app.php/en/foo', $urlGenerator->generate('foo.en'));
|
||||||
|
$this->assertSame('/app.php/en/foo', $urlGenerator->generate('foo', ['_locale' => 'en']));
|
||||||
|
$this->assertSame('/app.php/en/foo', $urlGenerator->generate('foo.fr', ['_locale' => 'en']));
|
||||||
|
|
||||||
|
$this->assertSame('/app.php/amusant', $urlGenerator->generate('fun'));
|
||||||
|
$this->assertSame('/app.php/fun', $urlGenerator->generate('fun.en'));
|
||||||
|
$this->assertSame('/app.php/fun', $urlGenerator->generate('fun', ['_locale' => 'en']));
|
||||||
|
$this->assertSame('/app.php/amusant', $urlGenerator->generate('fun.fr', ['_locale' => 'en']));
|
||||||
|
}
|
||||||
|
|
||||||
public function testGenerateWithoutRoutes()
|
public function testGenerateWithoutRoutes()
|
||||||
{
|
{
|
||||||
$this->expectException('Symfony\Component\Routing\Exception\RouteNotFoundException');
|
$this->expectException('Symfony\Component\Routing\Exception\RouteNotFoundException');
|
||||||
|
Reference in New Issue
Block a user