Skip to content

Commit

Permalink
The language negotiator will convert the locale names into canonical …
Browse files Browse the repository at this point in the history
…string before comparison (#507)
  • Loading branch information
ansata2001 authored and Marc Cámara committed Nov 11, 2017
1 parent 194435a commit e984285
Show file tree
Hide file tree
Showing 4 changed files with 395 additions and 3 deletions.
3 changes: 3 additions & 0 deletions composer.json
Expand Up @@ -19,6 +19,9 @@
"orchestra/testbench-browser-kit": "~3.4",
"phpunit/phpunit": "6.0.*"
},
"suggest": {
"ext-intl": "*"
},
"autoload": {
"classmap": [
],
Expand Down
34 changes: 31 additions & 3 deletions src/Mcamara/LaravelLocalization/LanguageNegotiator.php
Expand Up @@ -22,6 +22,11 @@ class LanguageNegotiator
*/
private $request;

/**
* @var bool
*/
private $use_intl = false;

/**
* @param string $defaultLocale
* @param array $supportedLanguages
Expand All @@ -30,7 +35,26 @@ class LanguageNegotiator
public function __construct($defaultLocale, $supportedLanguages, Request $request)
{
$this->defaultLocale = $defaultLocale;
$this->supportedLanguages = $supportedLanguages;

if (class_exists('Locale')) {
$this->use_intl = true;

foreach ($supportedLanguages as $key => $supportedLanguage) {
if ( ! isset($supportedLanguage['lang'])) {
$supportedLanguage['lang'] = Locale::canonicalize($key);
} else {
$supportedLanguage['lang'] = Locale::canonicalize($supportedLanguage['lang']);
}
if (isset($supportedLanguage['regional'])) {
$supportedLanguage['regional'] = Locale::canonicalize($supportedLanguage['regional']);
}

$this->supportedLanguages[$key] = $supportedLanguage;
}
} else {
$this->supportedLanguages = $supportedLanguages;
}

$this->request = $request;
}

Expand All @@ -57,7 +81,11 @@ public function negotiateLanguage()
if (!empty($this->supportedLanguages[$key])) {
return $key;
}


if ($this->use_intl) {
$key = Locale::canonicalize($key);
}

// Search for acceptable locale by 'regional' => 'af_ZA' or 'lang' => 'af-ZA' match.
foreach ( $this->supportedLanguages as $key_supported => $locale ) {
if ( (isset($locale['regional']) && $locale['regional'] == $key) || (isset($locale['lang']) && $locale['lang'] == $key) ) {
Expand All @@ -72,7 +100,7 @@ public function negotiateLanguage()
return key($this->supportedLanguages);
}

if (class_exists('Locale') && !empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
if ($this->use_intl && !empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
$http_accept_language = Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE']);

if (!empty($this->supportedLanguages[$http_accept_language])) {
Expand Down
44 changes: 44 additions & 0 deletions tests/LocalizerTests.php
Expand Up @@ -590,4 +590,48 @@ public function testCreateUrlFromUri()
app('laravellocalization')->createUrlFromUri('/ver/1')
);
}


/**
* @dataProvider accept_language_variations_data
*/
public function testLanguageNegotiation($accept_string, $must_resolve_to, $asd = null) {
$full_config = include __DIR__ . '/full-config/config.php';

$request = $this->createMock(\Illuminate\Http\Request::class);
$request->expects($this->any())->method('header')->with('Accept-Language')->willReturn($accept_string);

$negotiator = app(\Mcamara\LaravelLocalization\LanguageNegotiator::class,
[
'defaultLocale' => 'wrong',
'supportedLanguages' => $full_config['supportedLocales'],
'request' => $request
]
);

$language = $negotiator->negotiateLanguage();

$this->assertEquals($must_resolve_to, $language);
}

public function accept_language_variations_data() {
$variations = [
['en-GB', 'en-GB'],
['en-US', 'en-US'],
['en-ZA', 'en'],
['en', 'en'],
['az-AZ', 'az'],
['fr-CA,fr;q=0.8', 'fr-CA'],
['fr-150', 'fr'],
['zh-Hant-cn', 'zh-Hant'],
['zh-cn', 'zh']
];

$dataset = [];
foreach ($variations as $variation) {
$dataset[$variation[0]] = $variation;
}

return $dataset;
}
}

0 comments on commit e984285

Please sign in to comment.