Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
No results found
Select Git revision
Show changes
Commits on Source (2)
  • Reiter, Christoph's avatar
    Add a locale service for working with the the active locale · 00cef2a7
    Reiter, Christoph authored
    We currently configure symfony to apply the "Accept-Language"
    header to all requests, so there remain only two cases where
    we need to manually adjust things:
    
    * In case an endpoint renders HTML that is displayed in an iframe
    or popup we still need to provide an option to pass a language via
    a query parameter. This then takes precedence over the header.
    
    * In case we need a language identifier for another service, where
    we need to request an external resource for a specific language.
    In this case we either need to take the request language or in case
    we are in a CLI context the default locale configured in symfony.
    00cef2a7
  • Reiter, Christoph's avatar
    release · cc22deb2
    Reiter, Christoph authored
    cc22deb2
......@@ -18,6 +18,7 @@ $config->setRules([
'strict_param' => true,
'declare_strict_types' => true,
'method_argument_space' => ['on_multiline' => 'ignore'],
'phpdoc_to_comment' => false,
])
->setRiskyAllowed(true)
->setFinder($finder);
......
# v0.1.52
* new Locale service for setting a locale from a requests and forwarding
to other services
# v0.1.45
* dbp:relay:core:migrate: Work around issues in DoctrineMigrationsBundle which
......
......@@ -29,7 +29,8 @@
"symfony/twig-bundle": "^5.4",
"symfony/uid": "^5.4",
"symfony/validator": "^5.4",
"symfony/yaml": "^5.4"
"symfony/yaml": "^5.4",
"ext-intl": "*"
},
"require-dev": {
"brainmaestro/composer-git-hooks": "^2.8.5",
......
......@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "9c42ac8c7816cdf96cd4c2f000cabaf3",
"content-hash": "6ddd4889d724c8beabfe6b3b58bf35d7",
"packages": [
{
"name": "api-platform/core",
......@@ -9843,7 +9843,8 @@
"platform": {
"php": ">=7.3",
"ext-fileinfo": "*",
"ext-json": "*"
"ext-json": "*",
"ext-intl": "*"
},
"platform-dev": [],
"platform-overrides": {
......
<?php
declare(strict_types=1);
namespace Dbp\Relay\CoreBundle\Locale;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
/**
* A service which can be injected, which provides the current active language and allows setting the active
* language based on a query parameters.
*
* This assumes that Symfony is configured to apply the 'Accept-Language' header by default to all requests.
*/
class Locale
{
/** @var RequestStack */
private $requestStack;
/**
* @var ParameterBagInterface
*/
private $parameters;
public function __construct(RequestStack $requestStack, ParameterBagInterface $parameters)
{
$this->requestStack = $requestStack;
$this->parameters = $parameters;
}
/**
* Returns the primary language (in ISO 639‑1 format) for the current context.
* In case there is a request then the request language, otherwise the default language.
*/
public function getCurrentPrimaryLanguage(): string
{
$locale = $this->getCurrentLocale();
$lang = \Locale::getPrimaryLanguage($locale);
/** @psalm-suppress RedundantCondition */
assert($lang !== null);
return $lang;
}
/**
* Sets the locale for the active request via a query parameter.
* The query parameter format is the same as the 'Accept-Language' HTTP header format.
* In case the query parameter isn't part of the request then nothing changes.
*/
public function setCurrentRequestLocaleFromQuery(string $queryParam = 'lang'): void
{
$request = $this->requestStack->getCurrentRequest();
if ($request === null) {
throw new \RuntimeException('No active request');
}
self::setRequestLocaleFromQuery($request, $queryParam);
}
/**
* Returns the current locale, either from the active request, or the default one.
*/
private function getCurrentLocale(): string
{
$request = $this->requestStack->getCurrentRequest();
if ($request !== null) {
$locale = $request->getLocale();
} else {
$locale = $this->parameters->get('kernel.default_locale');
assert(is_string($locale));
}
return $locale;
}
private static function setRequestLocaleFromQuery(Request $request, string $queryParam): void
{
if ($request->query->has($queryParam)) {
$lang = $request->query->get($queryParam);
assert(is_string($lang));
$locale = \Locale::acceptFromHttp($lang);
if ($locale === false) {
throw new \RuntimeException('Failed to parse Accept-Language');
}
$request->setLocale($locale);
}
}
}
......@@ -100,3 +100,7 @@ services:
Dbp\Relay\CoreBundle\Authorization\DebugCommand:
autowire: true
autoconfigure: true
Dbp\Relay\CoreBundle\Locale\Locale:
autowire: true
autoconfigure: true
<?php
declare(strict_types=1);
namespace Dbp\Relay\CoreBundle\Tests;
use Dbp\Relay\CoreBundle\Locale\Locale;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
class LocaleTest extends TestCase
{
public function testWithRequest()
{
$stack = new RequestStack();
$request = new Request(['lang' => 'de']);
$request->setLocale(\Locale::acceptFromHttp('en'));
$stack->push($request);
$params = new ParameterBag([]);
$service = new Locale($stack, $params);
$lang = $service->getCurrentPrimaryLanguage();
$this->assertSame('en', $lang);
$service->setCurrentRequestLocaleFromQuery('lang');
$lang = $service->getCurrentPrimaryLanguage();
$this->assertSame('de', $lang);
}
public function testWithoutRequest()
{
$stack = new RequestStack();
$params = new ParameterBag(['kernel.default_locale' => \Locale::acceptFromHttp('de')]);
$service = new Locale($stack, $params);
$lang = $service->getCurrentPrimaryLanguage();
$this->assertSame('de', $lang);
}
}