Skip to content

Commit 49a89b1

Browse files
committed
[Routing] Prevent localized routes _locale default & requirement from being overridden
1 parent 4124d62 commit 49a89b1

File tree

2 files changed

+82
-0
lines changed

2 files changed

+82
-0
lines changed

Route.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,10 @@ public function setDefaults(array $defaults)
376376
*/
377377
public function addDefaults(array $defaults)
378378
{
379+
if (isset($defaults['_locale']) && $this->isLocalized()) {
380+
unset($defaults['_locale']);
381+
}
382+
379383
foreach ($defaults as $name => $default) {
380384
$this->defaults[$name] = $default;
381385
}
@@ -418,6 +422,10 @@ public function hasDefault($name)
418422
*/
419423
public function setDefault($name, $default)
420424
{
425+
if ('_locale' === $name && $this->isLocalized()) {
426+
return $this;
427+
}
428+
421429
$this->defaults[$name] = $default;
422430
$this->compiled = null;
423431

@@ -461,6 +469,10 @@ public function setRequirements(array $requirements)
461469
*/
462470
public function addRequirements(array $requirements)
463471
{
472+
if (isset($requirements['_locale']) && $this->isLocalized()) {
473+
unset($requirements['_locale']);
474+
}
475+
464476
foreach ($requirements as $key => $regex) {
465477
$this->requirements[$key] = $this->sanitizeRequirement($key, $regex);
466478
}
@@ -503,6 +515,10 @@ public function hasRequirement($key)
503515
*/
504516
public function setRequirement($key, $regex)
505517
{
518+
if ('_locale' === $key && $this->isLocalized()) {
519+
return $this;
520+
}
521+
506522
$this->requirements[$key] = $this->sanitizeRequirement($key, $regex);
507523
$this->compiled = null;
508524

@@ -577,4 +593,9 @@ private function sanitizeRequirement(string $key, $regex)
577593

578594
return $regex;
579595
}
596+
597+
private function isLocalized(): bool
598+
{
599+
return isset($this->defaults['_locale']) && isset($this->defaults['_canonical_route']) && ($this->requirements['_locale'] ?? null) === preg_quote($this->defaults['_locale'], RouteCompiler::REGEX_DELIMITER);
600+
}
580601
}

Tests/RouteTest.php

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,4 +271,65 @@ public function testSerializedRepresentationKeepsWorking()
271271
$this->assertEquals($route, $unserialized);
272272
$this->assertNotSame($route, $unserialized);
273273
}
274+
275+
/**
276+
* @dataProvider provideNonLocalizedRoutes
277+
*/
278+
public function testLocaleDefaultWithNonLocalizedRoutes(Route $route)
279+
{
280+
$this->assertNotSame('fr', $route->getDefault('_locale'));
281+
$route->setDefault('_locale', 'fr');
282+
$this->assertSame('fr', $route->getDefault('_locale'));
283+
}
284+
285+
/**
286+
* @dataProvider provideLocalizedRoutes
287+
*/
288+
public function testLocaleDefaultWithLocalizedRoutes(Route $route)
289+
{
290+
$expected = $route->getDefault('_locale');
291+
$this->assertIsString($expected);
292+
$this->assertNotSame('fr', $expected);
293+
$route->setDefault('_locale', 'fr');
294+
$this->assertSame($expected, $route->getDefault('_locale'));
295+
}
296+
297+
/**
298+
* @dataProvider provideNonLocalizedRoutes
299+
*/
300+
public function testLocaleRequirementWithNonLocalizedRoutes(Route $route)
301+
{
302+
$this->assertNotSame('fr', $route->getRequirement('_locale'));
303+
$route->setRequirement('_locale', 'fr');
304+
$this->assertSame('fr', $route->getRequirement('_locale'));
305+
}
306+
307+
/**
308+
* @dataProvider provideLocalizedRoutes
309+
*/
310+
public function testLocaleRequirementWithLocalizedRoutes(Route $route)
311+
{
312+
$expected = $route->getRequirement('_locale');
313+
$this->assertIsString($expected);
314+
$this->assertNotSame('fr', $expected);
315+
$route->setRequirement('_locale', 'fr');
316+
$this->assertSame($expected, $route->getRequirement('_locale'));
317+
}
318+
319+
public function provideNonLocalizedRoutes()
320+
{
321+
return [
322+
[(new Route('/foo'))],
323+
[(new Route('/foo'))->setDefault('_locale', 'en')],
324+
[(new Route('/foo'))->setDefault('_locale', 'en')->setDefault('_canonical_route', 'foo')],
325+
[(new Route('/foo'))->setDefault('_locale', 'en')->setDefault('_canonical_route', 'foo')->setRequirement('_locale', 'foobar')],
326+
];
327+
}
328+
329+
public function provideLocalizedRoutes()
330+
{
331+
return [
332+
[(new Route('/foo'))->setDefault('_locale', 'en')->setDefault('_canonical_route', 'foo')->setRequirement('_locale', 'en')],
333+
];
334+
}
274335
}

0 commit comments

Comments
 (0)