Skip to content
This repository was archived by the owner on Jan 25, 2023. It is now read-only.

Commit b63c08b

Browse files
authored
Merge pull request #101 from maxcoe/master
Fix and improve language detection
2 parents 4927f7c + 61762ad commit b63c08b

File tree

2 files changed

+25
-5
lines changed

2 files changed

+25
-5
lines changed

src/LanguageDetector.php

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,32 +14,45 @@ class LanguageDetector implements DetectorInterface
1414
*/
1515
public static function detect(Language $language, AcceptLanguage $acceptLanguage)
1616
{
17+
// Accept-Language header convention:
18+
// https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4
19+
1720
$acceptLanguageString = $acceptLanguage->getAcceptLanguageString();
1821
$languages = array();
1922
$language->setLanguages($languages);
2023

2124
if (!empty($acceptLanguageString)) {
25+
// Split by ranges (en-US,en;q=0.8) and keep priority value (0.8)
2226
$httpLanguages = preg_split(
2327
'/q=([\d\.]*)/',
2428
$acceptLanguageString,
2529
-1,
2630
PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE
2731
);
2832

33+
// Group by priority
2934
$key = 0;
3035
foreach (array_reverse($httpLanguages) as $value) {
3136
$value = trim($value, ',; .');
3237
if (is_numeric($value)) {
3338
$key = $value;
34-
} else {
35-
$languages[$key] = explode(',', $value);
39+
} elseif ($value) {
40+
$languages[$key] = preg_split('/[^\w-]+/', $value);
3641
}
3742
}
43+
44+
// Sort by priority
3845
krsort($languages);
3946

40-
foreach ($languages as $value) {
41-
$language->setLanguages(array_merge($language->getLanguages(), $value));
47+
// Flatten array and remove duplicates
48+
$result = [];
49+
foreach ($languages as $values) {
50+
foreach ($values as $value) {
51+
$result[$value] = true;
52+
}
4253
}
54+
55+
$language->setLanguages(array_keys($result));
4356
}
4457
}
4558
}

tests/BrowserDetector/Tests/LanguageTest.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ public function testGetLanguage()
2727

2828
public function testGetLanguages()
2929
{
30-
$this->assertGreaterThan(0, count($this->language->getLanguages()));
30+
$languages = ['fr-CA', 'fr', 'en-CA', 'en', 'en-US'];
31+
$this->assertSame($languages, $this->language->getLanguages());
3132
}
3233

3334
public function testGetLanguageLocal()
@@ -55,4 +56,10 @@ public function testGetLanguageLocale()
5556
$language = new Language('ru,en-us;q=0.5,en;q=0.3');
5657
$this->assertSame('ru', $language->getLanguageLocale());
5758
}
59+
60+
public function testGetLanguagesFromBogusHeader()
61+
{
62+
$language = new Language(';q=0.8, de, en;q=0.2, de-CH, de;q=0.4');
63+
$this->assertSame(['de-CH', 'de', 'en'], $language->getLanguages());
64+
}
5865
}

0 commit comments

Comments
 (0)