diff --git a/data/docs/rest.md b/data/docs/rest.md index 09147518..35f18e2a 100644 --- a/data/docs/rest.md +++ b/data/docs/rest.md @@ -15,6 +15,12 @@ Statuses: [TODO] +## Language + +In order to set the application language, you have to pass it by using the Accept-Language header. + +If not provided or provided language is not supported, english (en_US) will be used. + ## Endpoints #### Authenticate diff --git a/module/Rest/config/middleware-pipeline.config.php b/module/Rest/config/middleware-pipeline.config.php index 78c20c38..aa9889f1 100644 --- a/module/Rest/config/middleware-pipeline.config.php +++ b/module/Rest/config/middleware-pipeline.config.php @@ -8,6 +8,7 @@ return [ 'path' => '/rest', 'middleware' => [ Middleware\CheckAuthenticationMiddleware::class, + Middleware\LocaleMiddleware::class, Middleware\CrossDomainMiddleware::class, ], 'priority' => 5, diff --git a/module/Rest/config/services.config.php b/module/Rest/config/services.config.php index aff4cc96..093e6e41 100644 --- a/module/Rest/config/services.config.php +++ b/module/Rest/config/services.config.php @@ -19,6 +19,7 @@ return [ Middleware\CrossDomainMiddleware::class => InvokableFactory::class, Middleware\CheckAuthenticationMiddleware::class => AnnotatedFactory::class, + Middleware\LocaleMiddleware::class => AnnotatedFactory::class, ], ], diff --git a/module/Rest/config/translator.config.php b/module/Rest/config/translator.config.php new file mode 100644 index 00000000..ae120db3 --- /dev/null +++ b/module/Rest/config/translator.config.php @@ -0,0 +1,14 @@ + [ + 'translation_file_patterns' => [ + [ + 'type' => 'gettext', + 'base_dir' => __DIR__ . '/../lang', + 'pattern' => '%s.mo', + ], + ], + ], + +]; diff --git a/module/Rest/src/Middleware/LocaleMiddleware.php b/module/Rest/src/Middleware/LocaleMiddleware.php new file mode 100644 index 00000000..f3a4ddde --- /dev/null +++ b/module/Rest/src/Middleware/LocaleMiddleware.php @@ -0,0 +1,82 @@ +translator = $translator; + } + + /** + * Process an incoming request and/or response. + * + * Accepts a server-side request and a response instance, and does + * something with them. + * + * If the response is not complete and/or further processing would not + * interfere with the work done in the middleware, or if the middleware + * wants to delegate to another process, it can use the `$out` callable + * if present. + * + * If the middleware does not return a value, execution of the current + * request is considered complete, and the response instance provided will + * be considered the response to return. + * + * Alternately, the middleware may return a response instance. + * + * Often, middleware will `return $out();`, with the assumption that a + * later middleware will return a response. + * + * @param Request $request + * @param Response $response + * @param null|callable $out + * @return null|Response + */ + public function __invoke(Request $request, Response $response, callable $out = null) + { + if (! $request->hasHeader('Accept-Language')) { + return $out($request, $response); + } + + $locale = $request->getHeaderLine('Accept-Language'); + $this->translator->setLocale($this->normalizeLocale($locale)); + return $out($request, $response); + } + + /** + * @param string $locale + * @return string + */ + protected function normalizeLocale($locale) + { + $parts = explode('_', $locale); + if (count($parts) > 1) { + return $parts[0]; + } + + $parts = explode('-', $locale); + if (count($parts) > 1) { + return $parts[0]; + } + + return $locale; + } +}