diff --git a/system/Router/Router.php b/system/Router/Router.php index f0f9555ad1ac..02426fcc9106 100644 --- a/system/Router/Router.php +++ b/system/Router/Router.php @@ -457,20 +457,6 @@ protected function checkRoutes(string $uri): bool // Does the RegEx match? if (preg_match('#^' . $routeKey . '$#u', $uri, $matches)) { - // Is this route supposed to redirect to another? - if ($this->collection->isRedirect($routeKey)) { - // replacing matched route groups with references: post/([0-9]+) -> post/$1 - $redirectTo = preg_replace_callback('/(\([^\(]+\))/', static function (): string { - static $i = 1; - - return '$' . $i++; - }, is_array($handler) ? key($handler) : $handler); - - throw new RedirectException( - preg_replace('#\A' . $routeKey . '\z#u', $redirectTo, $uri), - $this->collection->getRedirectCode($routeKey), - ); - } // Store our locale so CodeIgniter object can // assign it to the Request. if (str_contains($matchedKey, '{locale}')) { @@ -491,6 +477,25 @@ protected function checkRoutes(string $uri): bool unset($matched); } + // Is this route supposed to redirect to another? + if ($this->collection->isRedirect($matchedKey)) { + // replacing matched route groups with references: post/([0-9]+) -> post/$1 + $redirectTo = preg_replace_callback('/(\([^\(]+\))/', static function (): string { + static $i = 1; + + return '$' . $i++; + }, is_array($handler) ? key($handler) : $handler); + + if (str_contains($matchedKey, '{locale}')) { + $redirectTo = str_replace('{locale}', $this->detectedLocale, $redirectTo); + } + + throw new RedirectException( + preg_replace('#\A' . $routeKey . '\z#u', $redirectTo, $uri), + $this->collection->getRedirectCode($matchedKey), + ); + } + // Are we using Closures? If so, then we need // to collect the params into an array // so it can be passed to the controller method later. diff --git a/tests/system/Router/RouterTest.php b/tests/system/Router/RouterTest.php index 6e22c95ed4f9..88f10ca54140 100644 --- a/tests/system/Router/RouterTest.php +++ b/tests/system/Router/RouterTest.php @@ -958,6 +958,7 @@ public function testRedirectRoute( $this->expectException(RedirectException::class); $this->expectExceptionMessage($expectedPath); + $this->expectExceptionCode(302); $router = new Router($collection, $this->request); $router->handle($url); @@ -976,9 +977,32 @@ public static function provideRedirectRoute(): iterable ['post/(:num)', 'article/(:num)', 'alias', '/article/1', 'post/1', 'alias'], ['post/(:num)/comment/(:any)', 'article/(:num)/(:any)', 'post/$1/comment/$2', '/article/1/2', 'post/1/comment/2', 'alias'], ['post/(:segment)/comment/(:any)', 'article/(:num)/(:any)', 'alias', '/article/1/2', 'post/1/comment/2', 'alias'], + ['posts', '{locale}/articles', 'posts', '/en/articles', 'posts', 'alias'], + ['{locale}/posts', '{locale}/articles', '{locale}/posts', '/en/articles', 'en/posts', 'alias'], + ['{locale}/posts', '{locale}/articles', 'alias', '/en/articles', 'en/posts', 'alias'], + ['{locale}/post/(:num)', '{locale}/article/(:num)', '{locale}/post/$1', '/en/article/1', 'en/post/1', 'alias'], + ['{locale}/post/(:num)', '{locale}/article/(:num)', 'alias', '/en/article/1', 'en/post/1', 'alias'], ]; } + public function testRedirectRouteWithUnsupportedLocale(): void + { + $config = config(App::class); + $config->supportedLocales = ['en']; + + $collection = clone $this->collection; + $collection->resetRoutes(); + $collection->useSupportedLocalesOnly(true); + + $collection->get('{locale}/posts', 'Controller::method'); + $collection->addRedirect('{locale}/articles', '{locale}/posts'); + + $this->expectException(PageNotFoundException::class); + + $router = new Router($collection, $this->request); + $router->handle('/fr/articles'); + } + public function testRoutePlaceholderAnyWithMultipleSegmentsParamFalse(): void { $this->createRouteCollection();