Merge pull request #5493 from owncloud/fix-language-detection

Fix HTTP language detection
This commit is contained in:
Thomas Müller 2013-10-28 16:37:12 -07:00
commit aaefb64306
2 changed files with 68 additions and 23 deletions

View File

@ -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];
}
return $available[$key];
}
foreach($available as $l) {
if ( $temp[0] == substr($l, 0, 2) ) {
// 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 = $l;
self::$language = $available_language;
}
return $l;
return $available_language;
}
}
foreach($available as $available_language) {
if (substr($preferred_language, 0, 2) === $available_language) {
if (is_null($app)) {
self::$language = $available_language;
}
return $available_language;
}
}
}

View File

@ -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'),
);
}
}