diff --git a/system/Router/Router.php b/system/Router/Router.php index ea5eb79b8d70..c5985f95af30 100644 --- a/system/Router/Router.php +++ b/system/Router/Router.php @@ -403,9 +403,6 @@ protected function checkRoutes(string $uri): bool // Loop through the route array looking for wildcards foreach ($routes as $routeKey => $handler) { - // Reset localeSegment - $localeSegment = null; - $routeKey = $routeKey === '/' ? $routeKey : ltrim($routeKey, '/ '); @@ -414,12 +411,7 @@ protected function checkRoutes(string $uri): bool // Are we dealing with a locale? if (strpos($routeKey, '{locale}') !== false) { - $localeSegment = array_search('{locale}', preg_split('/[\/]*((^[a-zA-Z0-9])|\(([^()]*)\))*[\/]+/m', $routeKey), true); - - // Replace it with a regex so it - // will actually match. - $routeKey = str_replace('/', '\/', $routeKey); - $routeKey = str_replace('{locale}', '[^\/]+', $routeKey); + $routeKey = str_replace('{locale}', '[^/]+', $routeKey); } // Does the RegEx match? @@ -440,10 +432,15 @@ protected function checkRoutes(string $uri): bool } // Store our locale so CodeIgniter object can // assign it to the Request. - if (isset($localeSegment)) { - // The following may be inefficient, but doesn't upset NetBeans :-/ - $temp = (explode('/', $uri)); - $this->detectedLocale = $temp[$localeSegment]; + if (strpos($matchedKey, '{locale}') !== false) { + preg_match( + '#^' . str_replace('{locale}', '(?[^/]+)', $matchedKey) . '$#u', + $uri, + $matched + ); + + $this->detectedLocale = $matched['locale']; + unset($matched); } // Are we using Closures? If so, then we need diff --git a/tests/system/Router/RouterTest.php b/tests/system/Router/RouterTest.php index d2e48bff992d..db9cd9c5e7e9 100644 --- a/tests/system/Router/RouterTest.php +++ b/tests/system/Router/RouterTest.php @@ -47,6 +47,7 @@ protected function setUp(): void 'books/(:num)/(:alpha)/(:num)' => 'Blog::show/$3/$1', 'closure/(:num)/(:alpha)' => static fn ($num, $str) => $num . '-' . $str, '{locale}/pages' => 'App\Pages::list_all', + 'test/(:any)/lang/{locale}' => 'App\Pages::list_all', 'admin/admins' => 'App\Admin\Admins::list_all', 'admin/admins/edit/(:any)' => 'App/Admin/Admins::edit_show/$1', '/some/slash' => 'App\Slash::index', @@ -402,6 +403,11 @@ public function testDetectsLocales() $this->assertTrue($router->hasLocale()); $this->assertSame('fr', $router->getLocale()); + + $router->handle('test/123/lang/bg'); + + $this->assertTrue($router->hasLocale()); + $this->assertSame('bg', $router->getLocale()); } public function testRouteResource()