Skip to content

Commit e984285

Browse files
ansata2001Marc Cámara
authored and
Marc Cámara
committed
The language negotiator will convert the locale names into canonical string before comparison (#507)
1 parent 194435a commit e984285

File tree

4 files changed

+395
-3
lines changed

4 files changed

+395
-3
lines changed

composer.json

+3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
"orchestra/testbench-browser-kit": "~3.4",
2020
"phpunit/phpunit": "6.0.*"
2121
},
22+
"suggest": {
23+
"ext-intl": "*"
24+
},
2225
"autoload": {
2326
"classmap": [
2427
],

src/Mcamara/LaravelLocalization/LanguageNegotiator.php

+31-3
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ class LanguageNegotiator
2222
*/
2323
private $request;
2424

25+
/**
26+
* @var bool
27+
*/
28+
private $use_intl = false;
29+
2530
/**
2631
* @param string $defaultLocale
2732
* @param array $supportedLanguages
@@ -30,7 +35,26 @@ class LanguageNegotiator
3035
public function __construct($defaultLocale, $supportedLanguages, Request $request)
3136
{
3237
$this->defaultLocale = $defaultLocale;
33-
$this->supportedLanguages = $supportedLanguages;
38+
39+
if (class_exists('Locale')) {
40+
$this->use_intl = true;
41+
42+
foreach ($supportedLanguages as $key => $supportedLanguage) {
43+
if ( ! isset($supportedLanguage['lang'])) {
44+
$supportedLanguage['lang'] = Locale::canonicalize($key);
45+
} else {
46+
$supportedLanguage['lang'] = Locale::canonicalize($supportedLanguage['lang']);
47+
}
48+
if (isset($supportedLanguage['regional'])) {
49+
$supportedLanguage['regional'] = Locale::canonicalize($supportedLanguage['regional']);
50+
}
51+
52+
$this->supportedLanguages[$key] = $supportedLanguage;
53+
}
54+
} else {
55+
$this->supportedLanguages = $supportedLanguages;
56+
}
57+
3458
$this->request = $request;
3559
}
3660

@@ -57,7 +81,11 @@ public function negotiateLanguage()
5781
if (!empty($this->supportedLanguages[$key])) {
5882
return $key;
5983
}
60-
84+
85+
if ($this->use_intl) {
86+
$key = Locale::canonicalize($key);
87+
}
88+
6189
// Search for acceptable locale by 'regional' => 'af_ZA' or 'lang' => 'af-ZA' match.
6290
foreach ( $this->supportedLanguages as $key_supported => $locale ) {
6391
if ( (isset($locale['regional']) && $locale['regional'] == $key) || (isset($locale['lang']) && $locale['lang'] == $key) ) {
@@ -72,7 +100,7 @@ public function negotiateLanguage()
72100
return key($this->supportedLanguages);
73101
}
74102

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

78106
if (!empty($this->supportedLanguages[$http_accept_language])) {

tests/LocalizerTests.php

+44
Original file line numberDiff line numberDiff line change
@@ -590,4 +590,48 @@ public function testCreateUrlFromUri()
590590
app('laravellocalization')->createUrlFromUri('/ver/1')
591591
);
592592
}
593+
594+
595+
/**
596+
* @dataProvider accept_language_variations_data
597+
*/
598+
public function testLanguageNegotiation($accept_string, $must_resolve_to, $asd = null) {
599+
$full_config = include __DIR__ . '/full-config/config.php';
600+
601+
$request = $this->createMock(\Illuminate\Http\Request::class);
602+
$request->expects($this->any())->method('header')->with('Accept-Language')->willReturn($accept_string);
603+
604+
$negotiator = app(\Mcamara\LaravelLocalization\LanguageNegotiator::class,
605+
[
606+
'defaultLocale' => 'wrong',
607+
'supportedLanguages' => $full_config['supportedLocales'],
608+
'request' => $request
609+
]
610+
);
611+
612+
$language = $negotiator->negotiateLanguage();
613+
614+
$this->assertEquals($must_resolve_to, $language);
615+
}
616+
617+
public function accept_language_variations_data() {
618+
$variations = [
619+
['en-GB', 'en-GB'],
620+
['en-US', 'en-US'],
621+
['en-ZA', 'en'],
622+
['en', 'en'],
623+
['az-AZ', 'az'],
624+
['fr-CA,fr;q=0.8', 'fr-CA'],
625+
['fr-150', 'fr'],
626+
['zh-Hant-cn', 'zh-Hant'],
627+
['zh-cn', 'zh']
628+
];
629+
630+
$dataset = [];
631+
foreach ($variations as $variation) {
632+
$dataset[$variation[0]] = $variation;
633+
}
634+
635+
return $dataset;
636+
}
593637
}

0 commit comments

Comments
 (0)