forked from ezsystems/ezpublish-kernel
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
EZP-29932: As a Developer I want list of Languages based on User's br…
…owser settings (ezsystems#2507) * EZP-29932: As a Developer I want list of Languages based on User's browser settings * EZP-29932: proper kernel docblocks * EZP-29925: Extract UserLanguagePreferenceProviderInterface * EZP-29932: Add fallback for getName and getDescription when mainLanguageCode is not provided
- Loading branch information
Showing
6 changed files
with
244 additions
and
2 deletions.
There are no files selected for viewing
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
89 changes: 89 additions & 0 deletions
89
eZ/Publish/Core/MVC/Symfony/Locale/Tests/UserLanguagePreferenceProviderTest.php
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
<?php | ||
|
||
/** | ||
* @copyright Copyright (C) eZ Systems AS. All rights reserved. | ||
* @license For full copyright and license information view LICENSE file distributed with this source code. | ||
*/ | ||
declare(strict_types=1); | ||
|
||
namespace eZ\Publish\Core\MVC\Symfony\Locale\Tests; | ||
|
||
use eZ\Publish\Core\MVC\Symfony\Locale\UserLanguagePreferenceProvider; | ||
use PHPUnit\Framework\TestCase; | ||
use Symfony\Component\HttpFoundation\HeaderBag; | ||
use Symfony\Component\HttpFoundation\Request; | ||
use Symfony\Component\HttpFoundation\RequestStack; | ||
use Symfony\Component\Yaml\Yaml; | ||
|
||
class UserLanguagePreferenceProviderTest extends TestCase | ||
{ | ||
/** | ||
* @var \eZ\Publish\Core\MVC\Symfony\Locale\UserLanguagePreferenceProviderInterface | ||
*/ | ||
private $userLanguagePreferenceProvider; | ||
|
||
/** | ||
* @var \PHPUnit\Framework\MockObject\MockObject|\Symfony\Component\HttpFoundation\RequestStack | ||
*/ | ||
private $requestStackMock; | ||
|
||
public function setUp() | ||
{ | ||
$this->requestStackMock = $this->createMock(RequestStack::class); | ||
|
||
$this->userLanguagePreferenceProvider = new UserLanguagePreferenceProvider( | ||
$this->requestStackMock, | ||
$this->getLanguageCodesMap() | ||
); | ||
} | ||
|
||
/** | ||
* @dataProvider providerForTestGetPreferredLanguages | ||
* | ||
* @param array $userLanguages | ||
* @param array $expectedEzLanguageCodes | ||
*/ | ||
public function testGetPreferredLanguages(array $userLanguages, array $expectedEzLanguageCodes) | ||
{ | ||
$request = new Request(); | ||
$request->headers = new HeaderBag( | ||
[ | ||
'Accept-Language' => implode(', ', $userLanguages), | ||
] | ||
); | ||
$this | ||
->requestStackMock | ||
->expects($this->once()) | ||
->method('getCurrentRequest') | ||
->willReturn($request); | ||
|
||
self::assertEquals( | ||
$expectedEzLanguageCodes, | ||
$this->userLanguagePreferenceProvider->getPreferredLanguages() | ||
); | ||
} | ||
|
||
/** | ||
* @see testGetPreferredLanguages | ||
* | ||
* @return array | ||
*/ | ||
public function providerForTestGetPreferredLanguages(): array | ||
{ | ||
return [ | ||
[['pl'], ['pol-PL']], | ||
[['pol-PL'], ['pol-PL']], | ||
[['fr'], ['fre-FR']], | ||
[['en'], ['eng-GB', 'eng-US']], | ||
]; | ||
} | ||
|
||
private function getLanguageCodesMap(): array | ||
{ | ||
$config = Yaml::parseFile( | ||
realpath(dirname(__DIR__, 6) . '/Bundle/EzPublishCoreBundle/Resources/config/locale.yml') | ||
); | ||
|
||
return $config['parameters']['ezpublish.locale.browser_map']; | ||
} | ||
} |
70 changes: 70 additions & 0 deletions
70
eZ/Publish/Core/MVC/Symfony/Locale/UserLanguagePreferenceProvider.php
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
<?php | ||
|
||
/** | ||
* @copyright Copyright (C) eZ Systems AS. All rights reserved. | ||
* @license For full copyright and license information view LICENSE file distributed with this source code. | ||
*/ | ||
declare(strict_types=1); | ||
|
||
namespace eZ\Publish\Core\MVC\Symfony\Locale; | ||
|
||
use Symfony\Component\HttpFoundation\Request; | ||
use Symfony\Component\HttpFoundation\RequestStack; | ||
|
||
class UserLanguagePreferenceProvider implements UserLanguagePreferenceProviderInterface | ||
{ | ||
/** | ||
* @var \Symfony\Component\HttpFoundation\RequestStack | ||
*/ | ||
private $requestStack; | ||
|
||
/** | ||
* @var array | ||
*/ | ||
private $languageCodesMap; | ||
|
||
/** | ||
* @param \Symfony\Component\HttpFoundation\RequestStack $requestStack | ||
* @param array $languageCodesMap | ||
*/ | ||
public function __construct(RequestStack $requestStack, array $languageCodesMap) | ||
{ | ||
$this->requestStack = $requestStack; | ||
$this->languageCodesMap = $languageCodesMap; | ||
} | ||
|
||
public function getPreferredLocales(Request $request = null): array | ||
{ | ||
$request = $request ?? $this->requestStack->getCurrentRequest(); | ||
$preferredLocales = $request->headers->get('Accept-Language') ?? ''; | ||
$preferredLocales = array_reduce( | ||
explode(',', $preferredLocales), | ||
function (array $result, string $languageWithQuality) { | ||
[$language, $quality] = array_merge(explode(';q=', $languageWithQuality), [1]); | ||
$result[$language] = (float) $quality; | ||
|
||
return $result; | ||
}, | ||
[] | ||
); | ||
arsort($preferredLocales); | ||
|
||
return array_keys($preferredLocales); | ||
} | ||
|
||
public function getPreferredLanguages(): array | ||
{ | ||
$languageCodes = []; | ||
foreach ($this->getPreferredLocales() as $locale) { | ||
$locale = strtolower($locale); | ||
if (isset($this->languageCodesMap[$locale])) { | ||
$languageCodes = array_merge($languageCodes, $this->languageCodesMap[$locale]); | ||
} elseif (preg_match('/^([a-z]{3})-([a-z]{2})$/', $locale, $matches)) { | ||
// if the given locale is already in the eZ format | ||
$languageCodes[] = strtolower($matches[1]) . '-' . strtoupper($matches[2]); | ||
} | ||
} | ||
|
||
return array_unique($languageCodes); | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
eZ/Publish/Core/MVC/Symfony/Locale/UserLanguagePreferenceProviderInterface.php
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<?php | ||
|
||
/** | ||
* @copyright Copyright (C) eZ Systems AS. All rights reserved. | ||
* @license For full copyright and license information view LICENSE file distributed with this source code. | ||
*/ | ||
declare(strict_types=1); | ||
|
||
namespace eZ\Publish\Core\MVC\Symfony\Locale; | ||
|
||
use Symfony\Component\HttpFoundation\Request; | ||
|
||
/** | ||
* Provides list of user-preferred languages. | ||
*/ | ||
interface UserLanguagePreferenceProviderInterface | ||
{ | ||
/** | ||
* Return a list of user's browser preferred locales directly from Accept-Language header. | ||
* | ||
* @param \Symfony\Component\HttpFoundation\Request request to retrieve information from, use current if null | ||
* | ||
* @return string[] | ||
*/ | ||
public function getPreferredLocales(Request $request = null): array; | ||
|
||
/** | ||
* List of eZ Language codes. | ||
* | ||
* @return string[] | ||
*/ | ||
public function getPreferredLanguages(): array; | ||
} |
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
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