summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Müller <thomas.mueller@tmit.eu>2013-10-28 16:37:12 -0700
committerThomas Müller <thomas.mueller@tmit.eu>2013-10-28 16:37:12 -0700
commitaaefb643069c3bd681b439fe25725ef636004e65 (patch)
tree5cb9a731fc1a6e42799166521cda7694f94a6ef4
parent6716c9f00aab3f6b041c3c65dc81b547b137caa3 (diff)
parent66813e9df6eb96a960462a3dc8dbe1de4df5314c (diff)
downloadnextcloud-server-aaefb643069c3bd681b439fe25725ef636004e65.tar.gz
nextcloud-server-aaefb643069c3bd681b439fe25725ef636004e65.zip
Merge pull request #5493 from owncloud/fix-language-detection
Fix HTTP language detection
-rw-r--r--lib/private/l10n.php46
-rw-r--r--tests/lib/l10n.php41
2 files changed, 66 insertions, 21 deletions
diff --git a/lib/private/l10n.php b/lib/private/l10n.php
index 3e84c306dc2..2d440850459 100644
--- a/lib/private/l10n.php
+++ b/lib/private/l10n.php
@@ -419,7 +419,7 @@ class OC_L10N implements \OCP\IL10N {
/**
* @brief find the best language
* @param $app Array or string, details below
- * @returns language
+ * @returns string language
*
* If $app is an array, ownCloud assumes that these are the available
* languages. Otherwise ownCloud tries to find the files in the l10n
@@ -438,8 +438,7 @@ class OC_L10N implements \OCP\IL10N {
if(is_array($app)) {
$available = $app;
$lang_exists = array_search($lang, $available) !== false;
- }
- else {
+ } else {
$lang_exists = self::languageExists($app, $lang);
}
if($lang_exists) {
@@ -447,35 +446,40 @@ class OC_L10N implements \OCP\IL10N {
}
}
- $default_language = OC_Config::getValue('default_language', false);
+ $default_language = OC_Config::getValue('default_language', false);
- if($default_language !== false) {
- return $default_language;
- }
+ if($default_language !== false) {
+ return $default_language;
+ }
if(isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
- $accepted_languages = preg_split('/,\s*/', strtolower($_SERVER['HTTP_ACCEPT_LANGUAGE']));
if(is_array($app)) {
$available = $app;
- }
- else{
+ } else {
$available = self::findAvailableLanguages($app);
}
- foreach($accepted_languages as $i) {
- $temp = explode(';', $i);
- $temp[0] = str_replace('-', '_', $temp[0]);
- if( ($key = array_search($temp[0], $available)) !== false) {
- if (is_null($app)) {
- self::$language = $available[$key];
+
+ // E.g. make sure that 'de' is before 'de_DE'.
+ sort($available);
+
+ $preferences = preg_split('/,\s*/', strtolower($_SERVER['HTTP_ACCEPT_LANGUAGE']));
+ foreach($preferences as $preference) {
+ list($preferred_language) = explode(';', $preference);
+ $preferred_language = str_replace('-', '_', $preferred_language);
+ foreach($available as $available_language) {
+ if ($preferred_language === strtolower($available_language)) {
+ if (is_null($app)) {
+ self::$language = $available_language;
+ }
+ return $available_language;
}
- return $available[$key];
}
- foreach($available as $l) {
- if ( $temp[0] == substr($l, 0, 2) ) {
+ foreach($available as $available_language) {
+ if (substr($preferred_language, 0, 2) === $available_language) {
if (is_null($app)) {
- self::$language = $l;
+ self::$language = $available_language;
}
- return $l;
+ return $available_language;
}
}
}
diff --git a/tests/lib/l10n.php b/tests/lib/l10n.php
index 12eac818f84..5ddf2290c35 100644
--- a/tests/lib/l10n.php
+++ b/tests/lib/l10n.php
@@ -64,4 +64,45 @@ class Test_L10n extends PHPUnit_Framework_TestCase {
$l = new OC_L10N('test');
$this->assertSame('February 13, 2009 23:31', $l->l('datetime', 1234567890));
}
+
+ /**
+ * @dataProvider findLanguageData
+ */
+ public function testFindLanguage($default, $preference, $expected) {
+ OC_User::setUserId(null);
+ if (is_null($default)) {
+ OC_Config::deleteKey('default_language');
+ } else {
+ OC_Config::setValue('default_language', $default);
+ }
+ $_SERVER['HTTP_ACCEPT_LANGUAGE'] = $preference;
+
+ $reflection = new \ReflectionClass('OC_L10N');
+ $prop = $reflection->getProperty('language');
+ $prop->setAccessible(1);
+ $prop->setValue('');
+ $prop->setAccessible(0);
+
+ $this->assertSame($expected, OC_L10N::findLanguage());
+ }
+
+ public function findLanguageData() {
+ return array(
+ // Exact match
+ array(null, 'de-DE,en;q=0.5', 'de_DE'),
+ array(null, 'de-DE,en-US;q=0.8,en;q=0.6', 'de_DE'),
+
+ // Best match
+ array(null, 'de-US,en;q=0.5', 'de'),
+ array(null, 'de-US,en-US;q=0.8,en;q=0.6', 'de'),
+
+ // The default_language config setting overrides browser preferences.
+ array('es_AR', 'de-DE,en;q=0.5', 'es_AR'),
+ array('es_AR', 'de-DE,en-US;q=0.8,en;q=0.6', 'es_AR'),
+
+ // Worst case default to english
+ array(null, '', 'en'),
+ array(null, null, 'en'),
+ );
+ }
}