diff --git a/lib/classes/JsonApi/Middlewares/Language.php b/lib/classes/JsonApi/Middlewares/Language.php index 4cde6997357069d4fa57f02a90d2a3520205bf9f..547e9f04e2f9657beb5bc61e8ec5fbc7a810b7f5 100644 --- a/lib/classes/JsonApi/Middlewares/Language.php +++ b/lib/classes/JsonApi/Middlewares/Language.php @@ -4,6 +4,7 @@ namespace JsonApi\Middlewares; use Negotiation\LanguageNegotiator; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface as Request; +use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface as RequestHandler; /** @@ -12,7 +13,7 @@ use Psr\Http\Server\RequestHandlerInterface as RequestHandler; * * @author Jan-Hendrik Willms <tleilax+studip@gmail.com> */ -class Language +final class Language implements MiddlewareInterface { /** * @param Request $request das Request-Objekt @@ -20,79 +21,13 @@ class Language * * @return ResponseInterface das neue Response-Objekt */ - public function __invoke(Request $request, RequestHandler $handler) + public function process(Request $request, RequestHandler $handler): ResponseInterface { - $language = $this->detectValidLanguageFromRequest($request); - $language_before = false; + $language = $_SESSION['_language'] ?? get_accepted_languages($request); - // Set language if detected - if ($language) { - $language_before = $_SESSION['_language']; - $_SESSION['_language'] = $language; - setTempLanguage(false, $language); - } + init_i18n($language); + $_SESSION['_language'] = $language; - $response = $handler->handle($request); - - if ($language) { - $_SESSION['_language'] = $language_before; - restoreLanguage(); - } - - return $response; - } - - /** - * Tries to detect a valid installed language from the request. - * - * @param Request $request - * @return string|null The detected language (if any) - */ - private function detectValidLanguageFromRequest(Request $request): ?string - { - if (!$request->hasHeader('Accept-Language')) { - return null; - } - - $negotiator = new LanguageNegotiator(); - $best_language = $negotiator->getBest( - $request->getHeaderLine('Accept-Language'), - $this->getStudIPLanguagePriorities() - ); - - if (!$best_language) { - return null; - } - - return $this->normalizeLanguageForStudIP($best_language->getType()); - } - - /** - * Returns a list of the normalized installed languages for the Stud.IP - * system. - * - * @return array - */ - private function getStudIPLanguagePriorities(): array - { - return array_map( - function ($language) { - return str_replace('_', '-', $language); - }, - array_keys($GLOBALS['INSTALLED_LANGUAGES']) - ); - } - - /** - * Normalizes the given language string (<language>-<variety>, e.g. de-de) - * for Stud.IP (e.g. de_DE). - * - * @param string $language - * @return string - */ - private function normalizeLanguageForStudIP(string $language): string - { - $tags = explode('-', $language); - return $tags[0] . '_' . strtoupper($tags[1]); + return $handler->handle($request); } } diff --git a/lib/classes/JsonApi/middleware.php b/lib/classes/JsonApi/middleware.php index f65231c886184106d15a54f1a4a9b68df63f84cd..e00b41bf55f1088a555057808e4abd9996b92b67 100644 --- a/lib/classes/JsonApi/middleware.php +++ b/lib/classes/JsonApi/middleware.php @@ -27,7 +27,7 @@ return function (App $app) { $app->addRoutingMiddleware(); // Add language middleware - $app->add(new Middlewares\Language()); + $app->add(Middlewares\Language::class); /** @var array|null */ $corsOrigin = \Config::get()->getValue('JSONAPI_CORS_ORIGIN'); diff --git a/lib/language.inc.php b/lib/language.inc.php index 2168d1612945b077ff5a8a869aff871501ebb6e8..fbe847175548f7789cf4a33d32c3196834074723 100644 --- a/lib/language.inc.php +++ b/lib/language.inc.php @@ -35,7 +35,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // +---------------------------------------------------------------------------+ - +use Negotiation\AcceptHeader; /** * This function tries to find the preferred language @@ -47,22 +47,38 @@ * @return string preferred user language, given in "en_GB"-style * */ -function get_accepted_languages() { - global $INSTALLED_LANGUAGES; - - $_language = Config::get()->DEFAULT_LANGUAGE; - $accepted_languages = explode(",", getenv("HTTP_ACCEPT_LANGUAGE")); - if (is_array($accepted_languages) && count($accepted_languages)) { - foreach ($accepted_languages as $temp_accepted_language) { - foreach ($INSTALLED_LANGUAGES as $temp_language => $temp_language_settings) { - if (mb_substr(trim($temp_accepted_language), 0, 2) == mb_substr($temp_language, 0, 2)) { - $_language = $temp_language; - break 2; - } - } - } +function get_accepted_languages(Psr\Http\Message\RequestInterface $request = null) { + $accepted_languages = null; + if ($request === null) { + $accepted_languages = $_SERVER['HTTP_ACCEPT_LANGUAGE']; + } elseif ($request->hasHeader('Accept-Language')) { + $accepted_languages = $request->getHeaderLine('Accept-Language'); + } + + // No languages found from http header, set default + if (!$accepted_languages) { + return Config::get()->DEFAULT_LANGUAGE; } - return $_language; + + // Use negotiator to identify best match + $negotiator = new Negotiation\LanguageNegotiator(); + $best_language = $negotiator->getBest( + $accepted_languages, + array_map( + function ($language) { + return str_replace('_', '-', $language); + }, + array_keys($GLOBALS['INSTALLED_LANGUAGES']) + ) + ); + + // No best match, set default + if (!$best_language) { + return Config::get()->DEFAULT_LANGUAGE; + } + + // Normalize language definition for stud.ip + return $best_language->getBasePart() . '_' . strtoupper($best_language->getSubPart()); } @@ -192,7 +208,7 @@ function restoreLanguage() { * @access public */ function setLocaleEnv($language, $language_domain = ''){ - putenv('LANGUAGE'); //unset language preference + putenv('LANGUAGE'); //unset language preference $ret = setlocale(LC_ALL, $language . '.UTF-8'); setlocale(LC_NUMERIC, 'C'); if ($language_domain) {