Skip to content

Commit

Permalink
Merge pull request #6073 from pjsde/refactor_router_locale_pattern
Browse files Browse the repository at this point in the history
feat: add routes useSupportedLocalesOnly property
  • Loading branch information
kenjis authored Jun 15, 2022
2 parents b0aa4dd + 37559cd commit 5879a3a
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 2 deletions.
5 changes: 5 additions & 0 deletions system/Exceptions/PageNotFoundException.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ public static function forMethodNotFound(string $method)
return new static(self::lang('HTTP.methodNotFound', [$method]));
}

public static function forLocaleNotSupported(string $locale)
{
return new static(self::lang('HTTP.localeNotSupported', [$locale]));
}

/**
* Get translated system message
*
Expand Down
1 change: 1 addition & 0 deletions system/Language/en/HTTP.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
'emptyController' => 'No Controller specified.',
'controllerNotFound' => 'Controller or its method is not found: {0}::{1}',
'methodNotFound' => 'Controller method is not found: {0}',
'localeNotSupported' => 'Locale is not supported: {0}',

// CSRF
// @deprecated use `Security.disallowedAction`
Expand Down
23 changes: 23 additions & 0 deletions system/Router/RouteCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,11 @@ class RouteCollection implements RouteCollectionInterface
*/
private ?string $httpHost = null;

/**
* Flag to limit or not the routes with {locale} placeholder to App::$supportedLocales
*/
protected bool $useSupportedLocalesOnly = false;

/**
* Constructor
*/
Expand Down Expand Up @@ -1466,4 +1471,22 @@ public function getRegisteredControllers(?string $verb = '*'): array

return array_unique($controllers);
}

/**
* Set The flag that limit or not the routes with {locale} placeholder to App::$supportedLocales
*/
public function useSupportedLocalesOnly(bool $useOnly): self
{
$this->useSupportedLocalesOnly = $useOnly;

return $this;
}

/**
* Get the flag that limit or not the routes with {locale} placeholder to App::$supportedLocales
*/
public function shouldUseSupportedLocalesOnly(): bool
{
return $this->useSupportedLocalesOnly;
}
}
5 changes: 5 additions & 0 deletions system/Router/RouteCollectionInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -184,4 +184,9 @@ public function isRedirect(string $from): bool;
* Grabs the HTTP status code from a redirecting Route.
*/
public function getRedirectCode(string $from): int;

/**
* Get the flag that limit or not the routes with {locale} placeholder to App::$supportedLocales
*/
public function shouldUseSupportedLocalesOnly(): bool;
}
8 changes: 8 additions & 0 deletions system/Router/Router.php
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,14 @@ protected function checkRoutes(string $uri): bool
$matched
);

if ($this->collection->shouldUseSupportedLocalesOnly()
&& ! in_array($matched['locale'], config('App')->supportedLocales, true)) {

// Throw exception to prevent the autorouter, if enabled,
// from trying to find a route
throw PageNotFoundException::forLocaleNotSupported($matched['locale']);
}

$this->detectedLocale = $matched['locale'];
unset($matched);
}
Expand Down
15 changes: 15 additions & 0 deletions tests/system/Router/RouteCollectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
namespace CodeIgniter\Router;

use CodeIgniter\Config\Services;
use CodeIgniter\Exceptions\PageNotFoundException;
use CodeIgniter\Test\CIUnitTestCase;
use Config\Modules;
use Tests\Support\Controllers\Hello;
Expand Down Expand Up @@ -1678,4 +1679,18 @@ public function testGetRegisteredControllersDoesNotReturnClosures()
$expects = [];
$this->assertSame($expects, $routes);
}

public function testUseSupportedLocalesOnly()
{
config('App')->supportedLocales = ['en'];

$routes = $this->getCollector();
$routes->useSupportedLocalesOnly(true);
$routes->get('{locale}/products', 'Products::list');

$router = new Router($routes, Services::request());

$this->expectException(PageNotFoundException::class);
$router->handle('fr/products');
}
}
8 changes: 6 additions & 2 deletions user_guide_src/source/outgoing/localization.rst
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,12 @@ segment will be your locale:
In this example, if the user tried to visit ``http://example.com/fr/books``, then the locale would be
set to ``fr``, assuming it was configured as a valid locale.

.. note:: If the value doesn't match a valid locale as defined in the App configuration file, the default
locale will be used in it's place.
If the value doesn't match a valid locale as defined in ``$supportedLocales`` in **app/Config/App.php**, the default
locale will be used in it's place, unless you set to use only the supported locales defined in the App configuration
file:

.. literalinclude:: localization/018.php


Retrieving the Current Locale
=============================
Expand Down
3 changes: 3 additions & 0 deletions user_guide_src/source/outgoing/localization/018.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<?php

$routes->useSupportedLocalesOnly(true);

0 comments on commit 5879a3a

Please sign in to comment.