From 68b2cca89954250770999c99a60d1ed12d9164a3 Mon Sep 17 00:00:00 2001 From: Pierre Rudloff Date: Mon, 29 May 2017 21:11:59 +0200 Subject: [PATCH] Detect user locale --- classes/LocaleMiddleware.php | 61 ++++++++++++++++++++++++++++ composer.json | 3 +- composer.lock | 43 +++++++++++++++++++- index.php | 7 +--- tests/LocaleMiddlewareTest.php | 73 ++++++++++++++++++++++++++++++++++ 5 files changed, 180 insertions(+), 7 deletions(-) create mode 100644 classes/LocaleMiddleware.php create mode 100644 tests/LocaleMiddlewareTest.php diff --git a/classes/LocaleMiddleware.php b/classes/LocaleMiddleware.php new file mode 100644 index 0000000..3a743e0 --- /dev/null +++ b/classes/LocaleMiddleware.php @@ -0,0 +1,61 @@ +locales as $locale) { + $parsedLocale = AcceptLanguage::parse($locale); + if (isset($proposedLocale['language']) + && $parsedLocale[1]['language'] == $proposedLocale['language'] + && $parsedLocale[1]['region'] == $proposedLocale['region'] + ) { + return $proposedLocale['language'].'_'.$proposedLocale['region']; + } + } + } + + /** + * Main middleware function + * + * @param Request $request PSR request + * @param Response $response PSR response + * @param callable $next Next middleware + * + * @return Response + */ + public function __invoke(Request $request, Response $response, callable $next) + { + $headers = $request->getHeader('Accept-Language'); + $locale = AcceptLanguage::detect([$this, 'testLocale'], 'en_US', $headers[0]); + putenv('LANG='.$locale); + setlocale(LC_ALL, [$locale, $locale.'.utf8']); + + return $next($request, $response); + } +} diff --git a/composer.json b/composer.json index fda6dc9..e977748 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,8 @@ "guzzlehttp/guzzle": "~6.2.0", "aura/session": "~2.1.0", "barracudanetworks/archivestream-php": "~1.0.5", - "smarty-gettext/smarty-gettext": "~1.5.1" + "smarty-gettext/smarty-gettext": "~1.5.1", + "zonuexe/http-accept-language": "~0.4.1" }, "require-dev": { "symfony/var-dumper": "~3.2.0", diff --git a/composer.lock b/composer.lock index f2c62ae..a4ac43a 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "9793382606938199471cea3e8c7cbb6c", + "content-hash": "44c4a3592a8eac7111a7284b22e55868", "packages": [ { "name": "aura/session", @@ -872,6 +872,47 @@ "description": "Symfony Yaml Component", "homepage": "https://symfony.com", "time": "2017-05-01T14:55:58+00:00" + }, + { + "name": "zonuexe/http-accept-language", + "version": "0.4.1", + "source": { + "type": "git", + "url": "https://github.com/BaguettePHP/http-accept-language.git", + "reference": "f71422b1200737aa9d7c7fa83f07cbe4616198d5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/BaguettePHP/http-accept-language/zipball/f71422b1200737aa9d7c7fa83f07cbe4616198d5", + "reference": "f71422b1200737aa9d7c7fa83f07cbe4616198d5", + "shasum": "" + }, + "require": { + "ext-intl": "*" + }, + "require-dev": { + "phploc/phploc": "*", + "phpunit/phpunit": "4.1.*", + "theseer/phpdox": "0.6.*" + }, + "type": "library", + "autoload": { + "psr-4": { + "Teto\\HTTP\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "USAMI Kenta", + "email": "tadsan@zonu.me" + } + ], + "description": "HTTP Accept-Language Header parser", + "time": "2014-10-19T09:22:18+00:00" } ], "packages-dev": [ diff --git a/index.php b/index.php index 5c0c8ca..0be9a33 100644 --- a/index.php +++ b/index.php @@ -1,13 +1,9 @@ add(new LocaleMiddleware()); $container = $app->getContainer(); $config = Config::getInstance(); if ($config->uglyUrls) { diff --git a/tests/LocaleMiddlewareTest.php b/tests/LocaleMiddlewareTest.php new file mode 100644 index 0000000..1f5e690 --- /dev/null +++ b/tests/LocaleMiddlewareTest.php @@ -0,0 +1,73 @@ +middleware = new LocaleMiddleware(); + } + + /** + * Test the testLocale() function. + * + * @return void + */ + public function testTestLocale() + { + $locale = [ + 'language'=>'fr', + 'region'=>'FR', + ]; + $this->assertEquals('fr_FR', $this->middleware->testLocale($locale)); + } + + /** + * Test the testLocale() function with an unsupported locale. + * + * @return void + */ + public function testLocaleWithWrongLocale() + { + $locale = [ + 'language'=>'foo', + 'region'=>'BAR' + ]; + $this->assertNull($this->middleware->testLocale($locale)); + $this->assertNull($this->middleware->testLocale([])); + } + + /** + * Test the __invoke() function. + * + * @return void + */ + public function testInvoke() + { + $request = Request::createFromEnvironment(Environment::mock()); + $this->middleware->__invoke( + $request->withHeader('Accept-Language', 'fr-FR'), + new Response(), + function () { + } + ); + $this->assertEquals('fr_FR', getenv('LANG')); + $this->assertEquals('fr_FR', setlocale(LC_ALL, null)); + } +}