summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config/app.php2
-rw-r--r--includes/engelsystem.php6
-rw-r--r--includes/helper/email_helper.php8
-rw-r--r--includes/helper/internationalization_helper.php80
-rw-r--r--includes/includes.php1
-rw-r--r--includes/sys_form.php5
-rw-r--r--includes/sys_menu.php26
-rw-r--r--src/Helpers/TranslationServiceProvider.php58
-rw-r--r--src/Helpers/Translator.php105
-rw-r--r--src/Middleware/SetLocale.php49
-rw-r--r--src/helpers.php35
-rw-r--r--tests/Unit/Helpers/TranslationServiceProviderTest.php86
-rw-r--r--tests/Unit/Helpers/TranslatorTest.php69
-rw-r--r--tests/Unit/HelpersTest.php26
-rw-r--r--tests/Unit/Middleware/SetLocaleTest.php71
15 files changed, 534 insertions, 93 deletions
diff --git a/config/app.php b/config/app.php
index 13d4d22b..ea394b8e 100644
--- a/config/app.php
+++ b/config/app.php
@@ -14,6 +14,7 @@ return [
\Engelsystem\Database\DatabaseServiceProvider::class,
\Engelsystem\Http\RequestServiceProvider::class,
\Engelsystem\Http\SessionServiceProvider::class,
+ \Engelsystem\Helpers\TranslationServiceProvider::class,
\Engelsystem\Http\ResponseServiceProvider::class,
\Engelsystem\Http\Psr7ServiceProvider::class,
\Engelsystem\Middleware\RouteDispatcherServiceProvider::class,
@@ -24,6 +25,7 @@ return [
'middleware' => [
\Engelsystem\Middleware\SendResponseHandler::class,
\Engelsystem\Middleware\ExceptionHandler::class,
+ \Engelsystem\Middleware\SetLocale::class,
\Engelsystem\Middleware\RouteDispatcher::class,
\Engelsystem\Middleware\RequestHandler::class,
],
diff --git a/includes/engelsystem.php b/includes/engelsystem.php
index eb5b220a..4c096b43 100644
--- a/includes/engelsystem.php
+++ b/includes/engelsystem.php
@@ -22,12 +22,6 @@ if ($app->get('config')->get('maintenance')) {
/**
- * Init translations
- */
-gettext_init();
-
-
-/**
* Init authorization
*/
load_auth();
diff --git a/includes/helper/email_helper.php b/includes/helper/email_helper.php
index c223d026..8d1cb794 100644
--- a/includes/helper/email_helper.php
+++ b/includes/helper/email_helper.php
@@ -15,14 +15,16 @@ function engelsystem_email_to_user($recipient_user, $title, $message, $not_if_it
return true;
}
- gettext_locale($recipient_user['Sprache']);
+ /** @var \Engelsystem\Helpers\Translator $translator */
+ $translator = app()->get('translator');
+ $locale = $translator->getLocale();
+ $translator->setLocale($recipient_user['Sprache']);
$message = sprintf(_('Hi %s,'), $recipient_user['Nick']) . "\n\n"
. _('here is a message for you from the engelsystem:') . "\n\n"
. $message . "\n\n"
. _('This email is autogenerated and has not been signed. You got this email because you are registered in the engelsystem.');
-
- gettext_locale();
+ $translator->setLocale($locale);
return engelsystem_email($recipient_user['email'], $title, $message);
}
diff --git a/includes/helper/internationalization_helper.php b/includes/helper/internationalization_helper.php
deleted file mode 100644
index bb6d0abd..00000000
--- a/includes/helper/internationalization_helper.php
+++ /dev/null
@@ -1,80 +0,0 @@
-<?php
-
-/**
- * Return currently active locale
- *
- * @return string
- */
-function locale()
-{
- return session()->get('locale');
-}
-
-/**
- * Returns two letter language code from currently active locale
- *
- * @return string
- */
-function locale_short()
-{
- return substr(locale(), 0, 2);
-}
-
-/**
- * Initializes gettext for internationalization and updates the sessions locale to use for translation.
- */
-function gettext_init()
-{
- $locales = config('locales');
- $request = request();
- $session = session();
-
- if ($request->has('set_locale') && isset($locales[$request->input('set_locale')])) {
- $session->set('locale', $request->input('set_locale'));
- } elseif (!$session->has('locale')) {
- $session->set('locale', config('default_locale'));
- }
-
- gettext_locale();
- bindtextdomain('default', app('path.lang'));
- bind_textdomain_codeset('default', 'UTF-8');
- textdomain('default');
-}
-
-/**
- * Swich gettext locale.
- *
- * @param string $locale
- */
-function gettext_locale($locale = null)
-{
- if (empty($locale)) {
- $locale = session()->get('locale');
- }
-
- putenv('LC_ALL=' . $locale);
- setlocale(LC_ALL, $locale);
-}
-
-/**
- * Renders language selection.
- *
- * @return array
- */
-function make_langselect()
-{
- $request = app('request');
-
- $items = [];
- foreach (config('locales') as $locale => $name) {
- $url = url($request->getPathInfo(), ['set_locale' => $locale]);
-
- $items[] = toolbar_item_link(
- htmlspecialchars($url),
- '',
- $name,
- $locale == locale()
- );
- }
- return $items;
-}
diff --git a/includes/includes.php b/includes/includes.php
index e316e550..7a68c3c9 100644
--- a/includes/includes.php
+++ b/includes/includes.php
@@ -61,7 +61,6 @@ $includeFiles = [
__DIR__ . '/../includes/controller/user_worklog_controller.php',
__DIR__ . '/../includes/helper/graph_helper.php',
- __DIR__ . '/../includes/helper/internationalization_helper.php',
__DIR__ . '/../includes/helper/message_helper.php',
__DIR__ . '/../includes/helper/error_helper.php',
__DIR__ . '/../includes/helper/email_helper.php',
diff --git a/includes/sys_form.php b/includes/sys_form.php
index 05df4c15..9cb6f38d 100644
--- a/includes/sys_form.php
+++ b/includes/sys_form.php
@@ -66,6 +66,9 @@ function form_date($name, $label, $value, $start_date = '', $end_date = '')
$value = is_numeric($value) ? date('Y-m-d', $value) : '';
$start_date = is_numeric($start_date) ? date('Y-m-d', $start_date) : '';
$end_date = is_numeric($end_date) ? date('Y-m-d', $end_date) : '';
+ $locale = $locale = session()->get('locale');
+ $shortLocale = substr($locale, 0, 2);
+
return form_element($label, '
<div class="input-group date" id="' . $dom_id . '">
<input name="' . $name . '" class="form-control" value="' . htmlspecialchars($value) . '">'
@@ -74,7 +77,7 @@ function form_date($name, $label, $value, $start_date = '', $end_date = '')
<script type="text/javascript">
$(function(){
$("#' . $dom_id . '").datepicker({
- language: "' . locale_short() . '",
+ language: "' . $shortLocale . '",
todayBtn: "linked",
format: "yyyy-mm-dd",
startDate: "' . $start_date . '",
diff --git a/includes/sys_menu.php b/includes/sys_menu.php
index 85ef1287..58d4bab3 100644
--- a/includes/sys_menu.php
+++ b/includes/sys_menu.php
@@ -110,7 +110,7 @@ function make_user_submenu()
{
global $privileges, $page;
- $user_submenu = make_langselect();
+ $user_submenu = make_language_select();
if (in_array('user_settings', $privileges) || in_array('logout', $privileges)) {
$user_submenu[] = toolbar_item_divider();
@@ -228,6 +228,30 @@ function make_room_navigation($menu)
}
/**
+ * Renders language selection.
+ *
+ * @return array
+ */
+function make_language_select()
+{
+ $request = app('request');
+ $activeLocale = session()->get('locale');
+
+ $items = [];
+ foreach (config('locales') as $locale => $name) {
+ $url = url($request->getPathInfo(), ['set-locale' => $locale]);
+
+ $items[] = toolbar_item_link(
+ htmlspecialchars($url),
+ '',
+ $name,
+ $locale == $activeLocale
+ );
+ }
+ return $items;
+}
+
+/**
* @return string
*/
function make_menu()
diff --git a/src/Helpers/TranslationServiceProvider.php b/src/Helpers/TranslationServiceProvider.php
new file mode 100644
index 00000000..9d86df7d
--- /dev/null
+++ b/src/Helpers/TranslationServiceProvider.php
@@ -0,0 +1,58 @@
+<?php
+
+namespace Engelsystem\Helpers;
+
+use Engelsystem\Config\Config;
+use Engelsystem\Container\ServiceProvider;
+use Symfony\Component\HttpFoundation\Session\Session;
+
+class TranslationServiceProvider extends ServiceProvider
+{
+ public function register()
+ {
+ /** @var Config $config */
+ $config = $this->app->get('config');
+ /** @var Session $session */
+ $session = $this->app->get('session');
+
+ $locales = $config->get('locales');
+ $locale = $config->get('default_locale');
+
+ $sessionLocale = $session->get('locale', $locale);
+ if (isset($locales[$sessionLocale])) {
+ $locale = $sessionLocale;
+ }
+
+ $this->initGettext();
+ $session->set('locale', $locale);
+
+ $translator = $this->app->make(
+ Translator::class,
+ ['locale' => $locale, 'locales' => $locales, 'localeChangeCallback' => [$this, 'setLocale']]
+ );
+ $this->app->instance(Translator::class, $translator);
+ $this->app->instance('translator', $translator);
+ }
+
+ /**
+ * @param string $textDomain
+ * @param string $encoding
+ * @codeCoverageIgnore
+ */
+ protected function initGettext($textDomain = 'default', $encoding = 'UTF-8')
+ {
+ bindtextdomain($textDomain, $this->app->get('path.lang'));
+ bind_textdomain_codeset($textDomain, $encoding);
+ textdomain($textDomain);
+ }
+
+ /**
+ * @param string $locale
+ * @codeCoverageIgnore
+ */
+ public function setLocale($locale)
+ {
+ putenv('LC_ALL=' . $locale);
+ setlocale(LC_ALL, $locale);
+ }
+}
diff --git a/src/Helpers/Translator.php b/src/Helpers/Translator.php
new file mode 100644
index 00000000..1e953a21
--- /dev/null
+++ b/src/Helpers/Translator.php
@@ -0,0 +1,105 @@
+<?php
+
+namespace Engelsystem\Helpers;
+
+class Translator
+{
+ /** @var string[] */
+ protected $locales;
+
+ /** @var string */
+ protected $locale;
+
+ /** @var callable */
+ protected $localeChangeCallback;
+
+ /**
+ * Translator constructor.
+ *
+ * @param string $locale
+ * @param string[] $locales
+ * @param callable $localeChangeCallback
+ */
+ public function __construct(string $locale, array $locales = [], callable $localeChangeCallback = null)
+ {
+ $this->localeChangeCallback = $localeChangeCallback;
+
+ $this->setLocale($locale);
+ $this->setLocales($locales);
+ }
+
+ /**
+ * Get the translation for a given key
+ *
+ * @param string $key
+ * @param array $replace
+ * @return string
+ */
+ public function translate(string $key, array $replace = []): string
+ {
+ $translated = $this->translateGettext($key);
+
+ if (!empty($replace)) {
+ $translated = call_user_func_array('sprintf', array_merge([$translated], $replace));
+ }
+
+ return $translated;
+ }
+
+ /**
+ * Translate the key via gettext
+ *
+ * @param string $key
+ * @return string
+ * @codeCoverageIgnore
+ */
+ protected function translateGettext(string $key): string
+ {
+ return _($key);
+ }
+
+ /**
+ * @return string
+ */
+ public function getLocale(): string
+ {
+ return $this->locale;
+ }
+
+ /**
+ * @param string $locale
+ */
+ public function setLocale(string $locale)
+ {
+ $this->locale = $locale;
+
+ if (is_callable($this->localeChangeCallback)) {
+ call_user_func_array($this->localeChangeCallback, [$locale]);
+ }
+ }
+
+ /**
+ * @return string[]
+ */
+ public function getLocales(): array
+ {
+ return $this->locales;
+ }
+
+ /**
+ * @param string $locale
+ * @return bool
+ */
+ public function hasLocale(string $locale): bool
+ {
+ return isset($this->locales[$locale]);
+ }
+
+ /**
+ * @param string[] $locales
+ */
+ public function setLocales(array $locales)
+ {
+ $this->locales = $locales;
+ }
+}
diff --git a/src/Middleware/SetLocale.php b/src/Middleware/SetLocale.php
new file mode 100644
index 00000000..86fa0b7f
--- /dev/null
+++ b/src/Middleware/SetLocale.php
@@ -0,0 +1,49 @@
+<?php
+
+namespace Engelsystem\Middleware;
+
+use Engelsystem\Helpers\Translator;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\MiddlewareInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+use Symfony\Component\HttpFoundation\Session\Session;
+
+class SetLocale implements MiddlewareInterface
+{
+ /** @var Translator */
+ protected $translator;
+
+ /** @var Session */
+ protected $session;
+
+ /**
+ * @param Translator $translator
+ * @param Session $session
+ */
+ public function __construct(Translator $translator, Session $session)
+ {
+ $this->translator = $translator;
+ $this->session = $session;
+ }
+
+ /**
+ * Process an incoming server request and setting the locale if required
+ *
+ * @param ServerRequestInterface $request
+ * @param RequestHandlerInterface $handler
+ * @return ResponseInterface
+ */
+ public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
+ {
+ $query = $request->getQueryParams();
+ if (isset($query['set-locale']) && $this->translator->hasLocale($query['set-locale'])) {
+ $locale = $query['set-locale'];
+
+ $this->translator->setLocale($locale);
+ $this->session->set('locale', $locale);
+ }
+
+ return $handler->handle($request);
+ }
+}
diff --git a/src/helpers.php b/src/helpers.php
index 336f81fe..3a182bf7 100644
--- a/src/helpers.php
+++ b/src/helpers.php
@@ -3,6 +3,7 @@
use Engelsystem\Application;
use Engelsystem\Config\Config;
+use Engelsystem\Helpers\Translator;
use Engelsystem\Http\Request;
use Engelsystem\Http\Response;
use Engelsystem\Http\UrlGenerator;
@@ -119,6 +120,40 @@ function session($key = null, $default = null)
}
/**
+ * Translate the given message
+ *
+ * @param string $key
+ * @param array $replace
+ * @return string|Translator
+ */
+function trans($key = null, $replace = [])
+{
+ /** @var Translator $translator */
+ $translator = app('translator');
+
+ if (is_null($key)) {
+ return $translator;
+ }
+
+ return $translator->translate($key, $replace);
+}
+
+/**
+ * Translate the given message
+ *
+ * @param string $key
+ * @param array $replace
+ * @return string
+ */
+function __($key, $replace = [])
+{
+ /** @var Translator $translator */
+ $translator = app('translator');
+
+ return $translator->translate($key, $replace);
+}
+
+/**
* @param string $path
* @param array $parameters
* @return UrlGenerator|string
diff --git a/tests/Unit/Helpers/TranslationServiceProviderTest.php b/tests/Unit/Helpers/TranslationServiceProviderTest.php
new file mode 100644
index 00000000..c5ba7386
--- /dev/null
+++ b/tests/Unit/Helpers/TranslationServiceProviderTest.php
@@ -0,0 +1,86 @@
+<?php
+
+namespace Engelsystem\Test\Unit\Helpers;
+
+use Engelsystem\Config\Config;
+use Engelsystem\Helpers\TranslationServiceProvider;
+use Engelsystem\Helpers\Translator;
+use Engelsystem\Test\Unit\ServiceProviderTest;
+use PHPUnit\Framework\MockObject\MockObject;
+use Symfony\Component\HttpFoundation\Session\Session;
+
+class TranslationServiceProviderTest extends ServiceProviderTest
+{
+ /**
+ * @covers \Engelsystem\Helpers\TranslationServiceProvider::register()
+ */
+ public function testRegister()
+ {
+ $app = $this->getApp(['make', 'instance', 'get']);
+ /** @var Config|MockObject $config */
+ $config = $this->createMock(Config::class);
+ /** @var Session|MockObject $session */
+ $session = $this->createMock(Session::class);
+ /** @var Translator|MockObject $translator */
+ $translator = $this->createMock(Translator::class);
+
+ /** @var TranslationServiceProvider|MockObject $serviceProvider */
+ $serviceProvider = $this->getMockBuilder(TranslationServiceProvider::class)
+ ->setConstructorArgs([$app])
+ ->setMethods(['initGettext', 'setLocale'])
+ ->getMock();
+
+ $serviceProvider->expects($this->once())
+ ->method('initGettext');
+
+ $app->expects($this->exactly(2))
+ ->method('get')
+ ->withConsecutive(['config'], ['session'])
+ ->willReturnOnConsecutiveCalls($config, $session);
+
+ $defaultLocale = 'fo_OO';
+ $locale = 'te_ST.WTF-9';
+ $locales = ['fo_OO' => 'Foo', 'fo_OO.BAR' => 'Foo (Bar)', 'te_ST.WTF-9' => 'WTF\'s Testing?'];
+ $config->expects($this->exactly(2))
+ ->method('get')
+ ->withConsecutive(
+ ['locales'],
+ ['default_locale']
+ )
+ ->willReturnOnConsecutiveCalls(
+ $locales,
+ $defaultLocale
+ );
+
+ $session->expects($this->once())
+ ->method('get')
+ ->with('locale', $defaultLocale)
+ ->willReturn($locale);
+ $session->expects($this->once())
+ ->method('set')
+ ->with('locale', $locale);
+
+ $app->expects($this->once())
+ ->method('make')
+ ->with(
+ Translator::class,
+ [
+ 'locale' => $locale,
+ 'locales' => $locales,
+ 'localeChangeCallback' => [$serviceProvider, 'setLocale']
+ ]
+ )
+ ->willReturn($translator);
+
+ $app->expects($this->exactly(2))
+ ->method('instance')
+ ->withConsecutive(
+ [Translator::class, $translator],
+ ['translator', $translator]
+ );
+
+ $serviceProvider->register();
+ }
+}
+
+
diff --git a/tests/Unit/Helpers/TranslatorTest.php b/tests/Unit/Helpers/TranslatorTest.php
new file mode 100644
index 00000000..396d2b65
--- /dev/null
+++ b/tests/Unit/Helpers/TranslatorTest.php
@@ -0,0 +1,69 @@
+<?php
+
+namespace Engelsystem\Test\Unit\Helpers;
+
+use Engelsystem\Helpers\Translator;
+use Engelsystem\Test\Unit\ServiceProviderTest;
+use PHPUnit\Framework\MockObject\MockObject;
+use stdClass;
+
+class TranslatorTest extends ServiceProviderTest
+{
+ /**
+ * @covers \Engelsystem\Helpers\Translator::__construct()
+ * @covers \Engelsystem\Helpers\Translator::setLocale()
+ * @covers \Engelsystem\Helpers\Translator::setLocales()
+ * @covers \Engelsystem\Helpers\Translator::getLocale()
+ * @covers \Engelsystem\Helpers\Translator::getLocales()
+ * @covers \Engelsystem\Helpers\Translator::hasLocale()
+ */
+ public function testInit()
+ {
+ $locales = ['te_ST.ER-01' => 'Tests', 'fo_OO' => 'SomeFOO'];
+ $locale = 'te_ST.ER-01';
+
+ /** @var callable|MockObject $callable */
+ $callable = $this->getMockBuilder(stdClass::class)
+ ->setMethods(['__invoke'])
+ ->getMock();
+ $callable->expects($this->exactly(2))
+ ->method('__invoke')
+ ->withConsecutive(['te_ST.ER-01'], ['fo_OO']);
+
+ $translator = new Translator($locale, $locales, $callable);
+
+ $this->assertEquals($locales, $translator->getLocales());
+ $this->assertEquals($locale, $translator->getLocale());
+
+ $translator->setLocale('fo_OO');
+ $this->assertEquals('fo_OO', $translator->getLocale());
+
+ $newLocales = ['lo_RM' => 'Lorem', 'ip_SU-M' => 'Ipsum'];
+ $translator->setLocales($newLocales);
+ $this->assertEquals($newLocales, $translator->getLocales());
+
+ $this->assertTrue($translator->hasLocale('ip_SU-M'));
+ $this->assertFalse($translator->hasLocale('te_ST.ER-01'));
+ }
+
+ /**
+ * @covers \Engelsystem\Helpers\Translator::translate()
+ */
+ public function testTranslate()
+ {
+ /** @var Translator|MockObject $translator */
+ $translator = $this->getMockBuilder(Translator::class)
+ ->setConstructorArgs(['de_DE.UTF-8', ['de_DE.UTF-8' => 'Deutsch']])
+ ->setMethods(['translateGettext'])
+ ->getMock();
+ $translator->expects($this->once())
+ ->method('translateGettext')
+ ->with('My favourite number is %u!')
+ ->willReturn('Meine Lieblingszahl ist die %u!');
+
+ $return = $translator->translate('My favourite number is %u!', [3]);
+ $this->assertEquals('Meine Lieblingszahl ist die 3!', $return);
+ }
+}
+
+
diff --git a/tests/Unit/HelpersTest.php b/tests/Unit/HelpersTest.php
index b59b11ee..20d3c2de 100644
--- a/tests/Unit/HelpersTest.php
+++ b/tests/Unit/HelpersTest.php
@@ -5,10 +5,11 @@ namespace Engelsystem\Test\Unit;
use Engelsystem\Application;
use Engelsystem\Config\Config;
use Engelsystem\Container\Container;
+use Engelsystem\Helpers\Translator;
use Engelsystem\Http\Request;
use Engelsystem\Http\Response;
-use Engelsystem\Renderer\Renderer;
use Engelsystem\Http\UrlGenerator;
+use Engelsystem\Renderer\Renderer;
use PHPUnit\Framework\TestCase;
use PHPUnit_Framework_MockObject_MockObject as MockObject;
use Symfony\Component\HttpFoundation\Session\Session;
@@ -195,6 +196,29 @@ class HelpersTest extends TestCase
}
/**
+ * @covers \__
+ * @covers \trans
+ */
+ public function testTrans()
+ {
+ /** @var Translator|MockObject $translator */
+ $translator = $this->getMockBuilder(Translator::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->getAppMock('translator', $translator);
+
+ $translator->expects($this->exactly(2))
+ ->method('translate')
+ ->with('Lorem %s Ipsum', ['foo'])
+ ->willReturn('Lorem foo Ipsum');
+
+ $this->assertEquals($translator, trans());
+ $this->assertEquals('Lorem foo Ipsum', trans('Lorem %s Ipsum', ['foo']));
+ $this->assertEquals('Lorem foo Ipsum', __('Lorem %s Ipsum', ['foo']));
+ }
+
+ /**
* @covers \url
*/
public function testUrl()
diff --git a/tests/Unit/Middleware/SetLocaleTest.php b/tests/Unit/Middleware/SetLocaleTest.php
new file mode 100644
index 00000000..c4e9d2a4
--- /dev/null
+++ b/tests/Unit/Middleware/SetLocaleTest.php
@@ -0,0 +1,71 @@
+<?php
+
+namespace Engelsystem\Test\Unit\Middleware;
+
+use Engelsystem\Helpers\Translator;
+use Engelsystem\Middleware\SetLocale;
+use PHPUnit\Framework\TestCase;
+use PHPUnit_Framework_MockObject_MockObject as MockObject;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+use Symfony\Component\HttpFoundation\Session\Session;
+
+class SetLocaleTest extends TestCase
+{
+ /**
+ * @covers \Engelsystem\Middleware\SetLocale::__construct
+ * @covers \Engelsystem\Middleware\SetLocale::process
+ */
+ public function testRegister()
+ {
+ /** @var Translator|MockObject $translator */
+ $translator = $this->createMock(Translator::class);
+ /** @var Session|MockObject $session */
+ $session = $this->createMock(Session::class);
+ /** @var ServerRequestInterface|MockObject $request */
+ $request = $this->getMockForAbstractClass(ServerRequestInterface::class);
+ /** @var RequestHandlerInterface|MockObject $handler */
+ $handler = $this->getMockForAbstractClass(RequestHandlerInterface::class);
+ /** @var ResponseInterface|MockObject $response */
+ $response = $this->getMockForAbstractClass(ResponseInterface::class);
+
+ $locale = 'te_ST.UTF8';
+
+ $request->expects($this->exactly(3))
+ ->method('getQueryParams')
+ ->willReturnOnConsecutiveCalls(
+ [],
+ ['set-locale' => 'en_US.UTF8'],
+ ['set-locale' => $locale]
+ );
+
+ $translator->expects($this->exactly(2))
+ ->method('hasLocale')
+ ->withConsecutive(
+ ['en_US.UTF8'],
+ [$locale]
+ )
+ ->willReturnOnConsecutiveCalls(
+ false,
+ true
+ );
+ $translator->expects($this->once())
+ ->method('setLocale')
+ ->with($locale);
+
+ $session->expects($this->once())
+ ->method('set')
+ ->with('locale', $locale);
+
+ $handler->expects($this->exactly(3))
+ ->method('handle')
+ ->with($request)
+ ->willReturn($response);
+
+ $middleware = new SetLocale($translator, $session);
+ $middleware->process($request, $handler);
+ $middleware->process($request, $handler);
+ $middleware->process($request, $handler);
+ }
+}