diff --git a/composer.json b/composer.json index 294cfd2..8d5223b 100644 --- a/composer.json +++ b/composer.json @@ -5,6 +5,7 @@ "license": "MIT", "require": { "php": ">=8.1", + "ext-intl": "*", "ext-json": "*", "bedita/core": "^5.0.0", "bedita/i18n": "^4.0", diff --git a/src/Middleware/LocaleMiddleware.php b/src/Middleware/LocaleMiddleware.php index eefbbef..e037e94 100644 --- a/src/Middleware/LocaleMiddleware.php +++ b/src/Middleware/LocaleMiddleware.php @@ -6,10 +6,14 @@ use Cake\Core\Configure; use Cake\Http\ServerRequest; use Cake\I18n\I18n; +use Cake\Log\Log; +use Cake\Utility\Hash; +use Locale; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface; +use ResourceBundle; /** * Locale middleware @@ -27,8 +31,14 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface $locale = $request->getParam('locale'); if (!empty($locale)) { - I18n::setLocale($locale); - Configure::write('I18n.lang', $locale); + $availableLocales = ResourceBundle::getLocales(''); + $parsedLocale = Hash::get(Locale::parseLocale($locale), 'language'); + if (!in_array($parsedLocale, $availableLocales)) { + Log::debug(sprintf('Requested locale "%s" is not available', $parsedLocale)); + } else { + I18n::setLocale($locale); + Configure::write('I18n.lang', $locale); + } } return $handler->handle($request); diff --git a/tests/TestCase/Middleware/LocaleMiddlewareTest.php b/tests/TestCase/Middleware/LocaleMiddlewareTest.php new file mode 100644 index 0000000..76942f5 --- /dev/null +++ b/tests/TestCase/Middleware/LocaleMiddlewareTest.php @@ -0,0 +1,60 @@ + [null, 'xk'], + 'invalid language code (ISO 639-2)' => [null, 'xkc'], + 'invalid language code (ISO 639-1 + ISO 3166-1 alpha-2)' => [null, 'xk_CD'], + 'correct language code (ISO 639-1)' => ['en', 'en'], + 'correct language code (ISO 639-2)' => ['eng', 'eng'], + 'correct language code (ISO 639-1 + ISO 3166-1 alpha-2)' => ['en_GB', 'en_GB'], + ]; + } + + /** + * Test {@see \Chialab\FrontendKit\Middleware\LocaleMiddleware::process()}. + * + * @param string|null $expectedLocale Expected configured locale. + * @param string $locale Requested locale. + * @return void + * @dataProvider localeProvider()) + */ + public function testLocale(?string $expectedLocale, string $locale): void + { + $middleware = new LocaleMiddleware(); + $request = new ServerRequest(['params' => compact('locale')]); + $handler = new class implements RequestHandlerInterface { + public function handle(ServerRequestInterface $request): ResponseInterface + { + return new EmptyResponse(); + } + }; + $middleware->process($request, $handler); + $actualLocale = Configure::read('I18n.lang'); + + static::assertEquals($expectedLocale, $actualLocale); + } +} diff --git a/tests/TestCase/Middleware/TrustedProxiesMiddlewareTest.php b/tests/TestCase/Middleware/TrustedProxiesMiddlewareTest.php index 6121beb..617639b 100644 --- a/tests/TestCase/Middleware/TrustedProxiesMiddlewareTest.php +++ b/tests/TestCase/Middleware/TrustedProxiesMiddlewareTest.php @@ -47,7 +47,7 @@ public function invokeProvider(): array * Test {@see TrustedProxiesMiddleware}. * * @param string|null $expectedClientIp Expected client IP after middleware execution. - * @param string|null $expectedTrustedProxies Expected trusted proxies list after middleware execution. + * @param array|null $expectedTrustedProxies Expected trusted proxies list after middleware execution. * @param \Chialab\FrontendKit\Middleware\TrustedProxiesMiddleware $middleware Middleware instance. * @param \Psr\Http\Message\ServerRequestInterface $request Incoming request. * @return void