Created
September 29, 2016 15:54
-
-
Save geerteltink/c5be44df8e5ce6262eb904f1b09b034c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\I18n; | |
use Psr\Http\Message\ResponseInterface as Response; | |
use Psr\Http\Message\ServerRequestInterface as Request; | |
use Zend\Diactoros\Response\RedirectResponse; | |
use Zend\I18n\Translator\Translator; | |
use Zend\Stratigility\MiddlewareInterface; | |
class LocalizationMiddleware implements MiddlewareInterface | |
{ | |
const LOCALE_ATTRIBUTE = 'locale'; | |
private $translator; | |
private $languages; | |
public function __construct(Translator $translator, array $languages) | |
{ | |
$this->translator = $translator; | |
$this->languages = $languages; | |
} | |
public function __invoke(Request $request, Response $response, callable $next = null) | |
{ | |
$locale = $requestLocale = $request->getAttribute('locale'); | |
// If there is no or an invalid locale | |
if (! $locale || ! in_array(substr(trim($locale), 0, 2), $this->languages, true)) { | |
// Fallback to first language | |
$locale = $this->languages[0]; | |
// Try the user preferred locales | |
foreach ($this->getLocales($request) as $userLocale => $factor) { | |
if (in_array(substr(trim($userLocale), 0, 2), $this->languages, true)) { | |
$locale = $userLocale; | |
break; | |
} | |
} | |
} | |
// Only the language is needed | |
$locale = substr(trim($locale), 0, 2); | |
if ($request->getUri()->getPath() === '/') { | |
// Redirect and set the locale for the homepage | |
return new RedirectResponse('/' . $locale); | |
} | |
// Set current locale | |
$this->translator->setLocale($locale); | |
// Get response first, apply content language later | |
if (null !== $next) { | |
$response = $next($request->withAttribute(self::LOCALE_ATTRIBUTE, $locale), $response); | |
} | |
// Add the content language to the response | |
return $response->withHeader('Content-Language', $locale); | |
} | |
private function getLocales(Request $request) | |
{ | |
$locales = []; | |
if (! array_key_exists('HTTP_ACCEPT_LANGUAGE', $request->getServerParams())) { | |
return $locales; | |
} | |
// break up string into pieces (locales and q factors) | |
preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[\d]+))?/i', | |
$request->getServerParams()['HTTP_ACCEPT_LANGUAGE'], $matches); | |
if (count($matches[1])) { | |
// create a list like "en" => 0.8 | |
$locales = array_combine($matches[1], $matches[4]); | |
// set default to 1 for any without q factor | |
foreach ($locales as $locale => $factor) { | |
if ($factor === '') { | |
$locales[$locale] = 1; | |
} | |
} | |
// sort list based on value | |
arsort($locales, SORT_NUMERIC); | |
} | |
return $locales; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment