[Routing] Prevent localized routes _locale default & requirement from being overridden
This commit is contained in:
parent
2bd76fa32c
commit
096dc0aeef
@ -376,6 +376,10 @@ class Route implements \Serializable
|
|||||||
*/
|
*/
|
||||||
public function addDefaults(array $defaults)
|
public function addDefaults(array $defaults)
|
||||||
{
|
{
|
||||||
|
if (isset($defaults['_locale']) && $this->isLocalized()) {
|
||||||
|
unset($defaults['_locale']);
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($defaults as $name => $default) {
|
foreach ($defaults as $name => $default) {
|
||||||
$this->defaults[$name] = $default;
|
$this->defaults[$name] = $default;
|
||||||
}
|
}
|
||||||
@ -418,6 +422,10 @@ class Route implements \Serializable
|
|||||||
*/
|
*/
|
||||||
public function setDefault($name, $default)
|
public function setDefault($name, $default)
|
||||||
{
|
{
|
||||||
|
if ('_locale' === $name && $this->isLocalized()) {
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
$this->defaults[$name] = $default;
|
$this->defaults[$name] = $default;
|
||||||
$this->compiled = null;
|
$this->compiled = null;
|
||||||
|
|
||||||
@ -461,6 +469,10 @@ class Route implements \Serializable
|
|||||||
*/
|
*/
|
||||||
public function addRequirements(array $requirements)
|
public function addRequirements(array $requirements)
|
||||||
{
|
{
|
||||||
|
if (isset($requirements['_locale']) && $this->isLocalized()) {
|
||||||
|
unset($requirements['_locale']);
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($requirements as $key => $regex) {
|
foreach ($requirements as $key => $regex) {
|
||||||
$this->requirements[$key] = $this->sanitizeRequirement($key, $regex);
|
$this->requirements[$key] = $this->sanitizeRequirement($key, $regex);
|
||||||
}
|
}
|
||||||
@ -503,6 +515,10 @@ class Route implements \Serializable
|
|||||||
*/
|
*/
|
||||||
public function setRequirement($key, $regex)
|
public function setRequirement($key, $regex)
|
||||||
{
|
{
|
||||||
|
if ('_locale' === $key && $this->isLocalized()) {
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
$this->requirements[$key] = $this->sanitizeRequirement($key, $regex);
|
$this->requirements[$key] = $this->sanitizeRequirement($key, $regex);
|
||||||
$this->compiled = null;
|
$this->compiled = null;
|
||||||
|
|
||||||
@ -577,4 +593,9 @@ class Route implements \Serializable
|
|||||||
|
|
||||||
return $regex;
|
return $regex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function isLocalized(): bool
|
||||||
|
{
|
||||||
|
return isset($this->defaults['_locale']) && isset($this->defaults['_canonical_route']) && ($this->requirements['_locale'] ?? null) === preg_quote($this->defaults['_locale'], RouteCompiler::REGEX_DELIMITER);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -271,4 +271,65 @@ class RouteTest extends TestCase
|
|||||||
$this->assertEquals($route, $unserialized);
|
$this->assertEquals($route, $unserialized);
|
||||||
$this->assertNotSame($route, $unserialized);
|
$this->assertNotSame($route, $unserialized);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider provideNonLocalizedRoutes
|
||||||
|
*/
|
||||||
|
public function testLocaleDefaultWithNonLocalizedRoutes(Route $route)
|
||||||
|
{
|
||||||
|
$this->assertNotSame('fr', $route->getDefault('_locale'));
|
||||||
|
$route->setDefault('_locale', 'fr');
|
||||||
|
$this->assertSame('fr', $route->getDefault('_locale'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider provideLocalizedRoutes
|
||||||
|
*/
|
||||||
|
public function testLocaleDefaultWithLocalizedRoutes(Route $route)
|
||||||
|
{
|
||||||
|
$expected = $route->getDefault('_locale');
|
||||||
|
$this->assertIsString($expected);
|
||||||
|
$this->assertNotSame('fr', $expected);
|
||||||
|
$route->setDefault('_locale', 'fr');
|
||||||
|
$this->assertSame($expected, $route->getDefault('_locale'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider provideNonLocalizedRoutes
|
||||||
|
*/
|
||||||
|
public function testLocaleRequirementWithNonLocalizedRoutes(Route $route)
|
||||||
|
{
|
||||||
|
$this->assertNotSame('fr', $route->getRequirement('_locale'));
|
||||||
|
$route->setRequirement('_locale', 'fr');
|
||||||
|
$this->assertSame('fr', $route->getRequirement('_locale'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider provideLocalizedRoutes
|
||||||
|
*/
|
||||||
|
public function testLocaleRequirementWithLocalizedRoutes(Route $route)
|
||||||
|
{
|
||||||
|
$expected = $route->getRequirement('_locale');
|
||||||
|
$this->assertIsString($expected);
|
||||||
|
$this->assertNotSame('fr', $expected);
|
||||||
|
$route->setRequirement('_locale', 'fr');
|
||||||
|
$this->assertSame($expected, $route->getRequirement('_locale'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideNonLocalizedRoutes()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[(new Route('/foo'))],
|
||||||
|
[(new Route('/foo'))->setDefault('_locale', 'en')],
|
||||||
|
[(new Route('/foo'))->setDefault('_locale', 'en')->setDefault('_canonical_route', 'foo')],
|
||||||
|
[(new Route('/foo'))->setDefault('_locale', 'en')->setDefault('_canonical_route', 'foo')->setRequirement('_locale', 'foobar')],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideLocalizedRoutes()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[(new Route('/foo'))->setDefault('_locale', 'en')->setDefault('_canonical_route', 'foo')->setRequirement('_locale', 'en')],
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user