[Routing] Add fallback to cultureless locale for internationalized routes
This commit is contained in:
parent
4b92b96796
commit
fd2e3c36fb
|
@ -1,6 +1,11 @@
|
|||
CHANGELOG
|
||||
=========
|
||||
|
||||
4.2.0
|
||||
-----
|
||||
|
||||
* added fallback to cultureless locale for internationalized routes
|
||||
|
||||
4.0.0
|
||||
-----
|
||||
|
||||
|
|
|
@ -113,10 +113,17 @@ EOF;
|
|||
?? $this->context->getParameter('_locale')
|
||||
?: $this->defaultLocale;
|
||||
|
||||
if (null !== $locale && (self::$declaredRoutes[$name.'.'.$locale][1]['_canonical_route'] ?? null) === $name) {
|
||||
unset($parameters['_locale']);
|
||||
$name .= '.'.$locale;
|
||||
} elseif (!isset(self::$declaredRoutes[$name])) {
|
||||
if (null !== $locale) {
|
||||
do {
|
||||
if ((self::$declaredRoutes[$name.'.'.$locale][1]['_canonical_route'] ?? null) === $name) {
|
||||
unset($parameters['_locale']);
|
||||
$name .= '.'.$locale;
|
||||
break;
|
||||
}
|
||||
} while (false !== $locale = strstr($locale, '_', true));
|
||||
}
|
||||
|
||||
if (!isset(self::$declaredRoutes[$name])) {
|
||||
throw new RouteNotFoundException(sprintf('Unable to generate a URL for the named route "%s" as such route does not exist.', $name));
|
||||
}
|
||||
|
||||
|
|
|
@ -112,13 +112,21 @@ class UrlGenerator implements UrlGeneratorInterface, ConfigurableRequirementsInt
|
|||
*/
|
||||
public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH)
|
||||
{
|
||||
$route = null;
|
||||
$locale = $parameters['_locale']
|
||||
?? $this->context->getParameter('_locale')
|
||||
?: $this->defaultLocale;
|
||||
|
||||
if (null !== $locale && null !== ($route = $this->routes->get($name.'.'.$locale)) && $route->getDefault('_canonical_route') === $name) {
|
||||
unset($parameters['_locale']);
|
||||
} elseif (null === $route = $this->routes->get($name)) {
|
||||
if (null !== $locale) {
|
||||
do {
|
||||
if (null !== ($route = $this->routes->get($name.'.'.$locale)) && $route->getDefault('_canonical_route') === $name) {
|
||||
unset($parameters['_locale']);
|
||||
break;
|
||||
}
|
||||
} while (false !== $locale = strstr($locale, '_', true));
|
||||
}
|
||||
|
||||
if (null === $route = $route ?? $this->routes->get($name)) {
|
||||
throw new RouteNotFoundException(sprintf('Unable to generate a URL for the named route "%s" as such route does not exist.', $name));
|
||||
}
|
||||
|
||||
|
|
|
@ -46,8 +46,8 @@ class PhpGeneratorDumperTest extends TestCase
|
|||
|
||||
$this->routeCollection = new RouteCollection();
|
||||
$this->generatorDumper = new PhpGeneratorDumper($this->routeCollection);
|
||||
$this->testTmpFilepath = sys_get_temp_dir().DIRECTORY_SEPARATOR.'php_generator.'.$this->getName().'.php';
|
||||
$this->largeTestTmpFilepath = sys_get_temp_dir().DIRECTORY_SEPARATOR.'php_generator.'.$this->getName().'.large.php';
|
||||
$this->testTmpFilepath = sys_get_temp_dir().\DIRECTORY_SEPARATOR.'php_generator.'.$this->getName().'.php';
|
||||
$this->largeTestTmpFilepath = sys_get_temp_dir().\DIRECTORY_SEPARATOR.'php_generator.'.$this->getName().'.large.php';
|
||||
@unlink($this->testTmpFilepath);
|
||||
@unlink($this->largeTestTmpFilepath);
|
||||
}
|
||||
|
@ -84,19 +84,20 @@ class PhpGeneratorDumperTest extends TestCase
|
|||
$this->assertEquals('/app.php/testing2', $relativeUrlWithoutParameter);
|
||||
}
|
||||
|
||||
public function testDumpWithLocalizedRoutes()
|
||||
public function testDumpWithSimpleLocalizedRoutes()
|
||||
{
|
||||
$this->routeCollection->add('test', (new Route('/foo')));
|
||||
$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('_locale', 'nl')->setDefault('_canonical_route', 'test'));
|
||||
|
||||
$code = $this->generatorDumper->dump(array(
|
||||
'class' => 'LocalizedProjectUrlGenerator',
|
||||
'class' => 'SimpleLocalizedProjectUrlGenerator',
|
||||
));
|
||||
file_put_contents($this->testTmpFilepath, $code);
|
||||
include $this->testTmpFilepath;
|
||||
|
||||
$context = new RequestContext('/app.php');
|
||||
$projectUrlGenerator = new \LocalizedProjectUrlGenerator($context, null, 'en');
|
||||
$projectUrlGenerator = new \SimpleLocalizedProjectUrlGenerator($context, null, 'en');
|
||||
|
||||
$urlWithDefaultLocale = $projectUrlGenerator->generate('test');
|
||||
$urlWithSpecifiedLocale = $projectUrlGenerator->generate('test', array('_locale' => 'nl'));
|
||||
|
@ -109,6 +110,57 @@ class PhpGeneratorDumperTest extends TestCase
|
|||
$this->assertEquals('/app.php/testen/is/leuk', $urlWithSpecifiedLocale);
|
||||
$this->assertEquals('/app.php/testing/is/fun', $urlWithEnglishContext);
|
||||
$this->assertEquals('/app.php/testen/is/leuk', $urlWithDutchContext);
|
||||
|
||||
// test with full route name
|
||||
$this->assertEquals('/app.php/testing/is/fun', $projectUrlGenerator->generate('test.en'));
|
||||
|
||||
$context->setParameter('_locale', 'de_DE');
|
||||
// test that it fall backs to another route when there is no matching localized route
|
||||
$this->assertEquals('/app.php/foo', $projectUrlGenerator->generate('test'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Routing\Exception\RouteNotFoundException
|
||||
* @expectedExceptionMessage Unable to generate a URL for the named route "test" as such route does not exist.
|
||||
*/
|
||||
public function testDumpWithRouteNotFoundLocalizedRoutes()
|
||||
{
|
||||
$this->routeCollection->add('test.en', (new Route('/testing/is/fun'))->setDefault('_locale', 'en')->setDefault('_canonical_route', 'test'));
|
||||
|
||||
$code = $this->generatorDumper->dump(array(
|
||||
'class' => 'RouteNotFoundLocalizedProjectUrlGenerator',
|
||||
));
|
||||
file_put_contents($this->testTmpFilepath, $code);
|
||||
include $this->testTmpFilepath;
|
||||
|
||||
$projectUrlGenerator = new \RouteNotFoundLocalizedProjectUrlGenerator(new RequestContext('/app.php'), null, 'pl_PL');
|
||||
$projectUrlGenerator->generate('test');
|
||||
}
|
||||
|
||||
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'));
|
||||
|
||||
$code = $this->generatorDumper->dump(array(
|
||||
'class' => 'FallbackLocaleLocalizedProjectUrlGenerator',
|
||||
));
|
||||
file_put_contents($this->testTmpFilepath, $code);
|
||||
include $this->testTmpFilepath;
|
||||
|
||||
$context = new RequestContext('/app.php');
|
||||
$context->setParameter('_locale', 'en_GB');
|
||||
$projectUrlGenerator = new \FallbackLocaleLocalizedProjectUrlGenerator($context, null, null);
|
||||
|
||||
// test with context _locale
|
||||
$this->assertEquals('/app.php/testing/is/fun', $projectUrlGenerator->generate('test'));
|
||||
// test with parameters _locale
|
||||
$this->assertEquals('/app.php/testen/is/leuk', $projectUrlGenerator->generate('test', array('_locale' => 'nl_BE')));
|
||||
|
||||
$projectUrlGenerator = new \FallbackLocaleLocalizedProjectUrlGenerator(new RequestContext('/app.php'), null, 'fr_CA');
|
||||
// test with default locale
|
||||
$this->assertEquals('/app.php/tester/est/amusant', $projectUrlGenerator->generate('test'));
|
||||
}
|
||||
|
||||
public function testDumpWithTooManyRoutes()
|
||||
|
|
Reference in New Issue