Merge pull request #1259 from nextcloud/language_order
ACCEPT_LANGUAGE goes before default_langauge
This commit is contained in:
commit
db6a3367ad
|
@ -550,6 +550,7 @@ return array(
|
||||||
'OC\\IntegrityCheck\\Iterator\\ExcludeFoldersByPathFilterIterator' => $baseDir . '/lib/private/IntegrityCheck/Iterator/ExcludeFoldersByPathFilterIterator.php',
|
'OC\\IntegrityCheck\\Iterator\\ExcludeFoldersByPathFilterIterator' => $baseDir . '/lib/private/IntegrityCheck/Iterator/ExcludeFoldersByPathFilterIterator.php',
|
||||||
'OC\\L10N\\Factory' => $baseDir . '/lib/private/L10N/Factory.php',
|
'OC\\L10N\\Factory' => $baseDir . '/lib/private/L10N/Factory.php',
|
||||||
'OC\\L10N\\L10N' => $baseDir . '/lib/private/L10N/L10N.php',
|
'OC\\L10N\\L10N' => $baseDir . '/lib/private/L10N/L10N.php',
|
||||||
|
'OC\\L10N\\LanguageNotFoundException' => $baseDir . '/lib/private/L10N/LanguageNotFoundException.php',
|
||||||
'OC\\LargeFileHelper' => $baseDir . '/lib/private/LargeFileHelper.php',
|
'OC\\LargeFileHelper' => $baseDir . '/lib/private/LargeFileHelper.php',
|
||||||
'OC\\Lock\\AbstractLockingProvider' => $baseDir . '/lib/private/Lock/AbstractLockingProvider.php',
|
'OC\\Lock\\AbstractLockingProvider' => $baseDir . '/lib/private/Lock/AbstractLockingProvider.php',
|
||||||
'OC\\Lock\\DBLockingProvider' => $baseDir . '/lib/private/Lock/DBLockingProvider.php',
|
'OC\\Lock\\DBLockingProvider' => $baseDir . '/lib/private/Lock/DBLockingProvider.php',
|
||||||
|
|
|
@ -580,6 +580,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
|
||||||
'OC\\IntegrityCheck\\Iterator\\ExcludeFoldersByPathFilterIterator' => __DIR__ . '/../../..' . '/lib/private/IntegrityCheck/Iterator/ExcludeFoldersByPathFilterIterator.php',
|
'OC\\IntegrityCheck\\Iterator\\ExcludeFoldersByPathFilterIterator' => __DIR__ . '/../../..' . '/lib/private/IntegrityCheck/Iterator/ExcludeFoldersByPathFilterIterator.php',
|
||||||
'OC\\L10N\\Factory' => __DIR__ . '/../../..' . '/lib/private/L10N/Factory.php',
|
'OC\\L10N\\Factory' => __DIR__ . '/../../..' . '/lib/private/L10N/Factory.php',
|
||||||
'OC\\L10N\\L10N' => __DIR__ . '/../../..' . '/lib/private/L10N/L10N.php',
|
'OC\\L10N\\L10N' => __DIR__ . '/../../..' . '/lib/private/L10N/L10N.php',
|
||||||
|
'OC\\L10N\\LanguageNotFoundException' => __DIR__ . '/../../..' . '/lib/private/L10N/LanguageNotFoundException.php',
|
||||||
'OC\\LargeFileHelper' => __DIR__ . '/../../..' . '/lib/private/LargeFileHelper.php',
|
'OC\\LargeFileHelper' => __DIR__ . '/../../..' . '/lib/private/LargeFileHelper.php',
|
||||||
'OC\\Lock\\AbstractLockingProvider' => __DIR__ . '/../../..' . '/lib/private/Lock/AbstractLockingProvider.php',
|
'OC\\Lock\\AbstractLockingProvider' => __DIR__ . '/../../..' . '/lib/private/Lock/AbstractLockingProvider.php',
|
||||||
'OC\\Lock\\DBLockingProvider' => __DIR__ . '/../../..' . '/lib/private/Lock/DBLockingProvider.php',
|
'OC\\Lock\\DBLockingProvider' => __DIR__ . '/../../..' . '/lib/private/Lock/DBLockingProvider.php',
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
||||||
|
* @copyright 2016 Roeland Jago Douma <roeland@famdouma.nl>
|
||||||
*
|
*
|
||||||
* @author Bart Visscher <bartv@thisnet.nl>
|
* @author Bart Visscher <bartv@thisnet.nl>
|
||||||
* @author Joas Schilling <coding@schilljs.com>
|
* @author Joas Schilling <coding@schilljs.com>
|
||||||
|
@ -8,6 +9,7 @@
|
||||||
* @author Morris Jobke <hey@morrisjobke.de>
|
* @author Morris Jobke <hey@morrisjobke.de>
|
||||||
* @author Robin Appelman <robin@icewind.nl>
|
* @author Robin Appelman <robin@icewind.nl>
|
||||||
* @author Robin McCorkell <robin@mccorkell.me.uk>
|
* @author Robin McCorkell <robin@mccorkell.me.uk>
|
||||||
|
* @author Roeland Jago Douma <roeland@famdouma.nl>
|
||||||
*
|
*
|
||||||
* @license AGPL-3.0
|
* @license AGPL-3.0
|
||||||
*
|
*
|
||||||
|
@ -147,18 +149,23 @@ class Factory implements IFactory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$defaultLanguage = $this->config->getSystemValue('default_language', false);
|
try {
|
||||||
|
// Try to get the language from the Request
|
||||||
if ($defaultLanguage !== false && $this->languageExists($app, $defaultLanguage)) {
|
$lang = $this->getLanguageFromRequest($app);
|
||||||
return $defaultLanguage;
|
if ($userId !== null && $app === null && !$userLang) {
|
||||||
|
$this->config->setUserValue($userId, 'core', 'lang', $lang);
|
||||||
|
}
|
||||||
|
return $lang;
|
||||||
|
} catch (LanguageNotFoundException $e) {
|
||||||
|
// Finding language from request failed fall back to default language
|
||||||
|
$defaultLanguage = $this->config->getSystemValue('default_language', false);
|
||||||
|
if ($defaultLanguage !== false && $this->languageExists($app, $defaultLanguage)) {
|
||||||
|
return $defaultLanguage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$lang = $this->setLanguageFromRequest($app);
|
// We could not find any language so fall back to english
|
||||||
if ($userId !== null && $app === null && !$userLang) {
|
return 'en';
|
||||||
$this->config->setUserValue($userId, 'core', 'lang', $lang);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $lang;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -227,10 +234,11 @@ class Factory implements IFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string|null $app App id or null for core
|
* @param string|null $app
|
||||||
* @return string
|
* @return string
|
||||||
|
* @throws LanguageNotFoundException
|
||||||
*/
|
*/
|
||||||
public function setLanguageFromRequest($app = null) {
|
private function getLanguageFromRequest($app) {
|
||||||
$header = $this->request->getHeader('ACCEPT_LANGUAGE');
|
$header = $this->request->getHeader('ACCEPT_LANGUAGE');
|
||||||
if ($header) {
|
if ($header) {
|
||||||
$available = $this->findAvailableLanguages($app);
|
$available = $this->findAvailableLanguages($app);
|
||||||
|
@ -245,9 +253,6 @@ class Factory implements IFactory {
|
||||||
|
|
||||||
foreach ($available as $available_language) {
|
foreach ($available as $available_language) {
|
||||||
if ($preferred_language === strtolower($available_language)) {
|
if ($preferred_language === strtolower($available_language)) {
|
||||||
if ($app === null && !$this->requestLanguage) {
|
|
||||||
$this->requestLanguage = $available_language;
|
|
||||||
}
|
|
||||||
return $available_language;
|
return $available_language;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -255,19 +260,31 @@ class Factory implements IFactory {
|
||||||
// Fallback from de_De to de
|
// Fallback from de_De to de
|
||||||
foreach ($available as $available_language) {
|
foreach ($available as $available_language) {
|
||||||
if (substr($preferred_language, 0, 2) === $available_language) {
|
if (substr($preferred_language, 0, 2) === $available_language) {
|
||||||
if ($app === null && !$this->requestLanguage) {
|
|
||||||
$this->requestLanguage = $available_language;
|
|
||||||
}
|
|
||||||
return $available_language;
|
return $available_language;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($app === null && !$this->requestLanguage) {
|
throw new LanguageNotFoundException();
|
||||||
$this->requestLanguage = 'en';
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string|null $app App id or null for core
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function setLanguageFromRequest($app = null) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
$requestLanguage = $this->getLanguageFromRequest($app);
|
||||||
|
} catch (LanguageNotFoundException $e) {
|
||||||
|
$requestLanguage = 'en';
|
||||||
}
|
}
|
||||||
return 'en'; // Last try: English
|
|
||||||
|
if ($app === null && !$this->requestLanguage) {
|
||||||
|
$this->requestLanguage = $requestLanguage;
|
||||||
|
}
|
||||||
|
return $requestLanguage;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Roeland Jago Douma <roeland@famdouma.nl>
|
||||||
|
*
|
||||||
|
* @license GNU AGPL version 3 or any later version
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
namespace OC\L10N;
|
||||||
|
|
||||||
|
class LanguageNotFoundException extends \Exception {
|
||||||
|
|
||||||
|
}
|
|
@ -9,6 +9,10 @@
|
||||||
namespace Test\L10N;
|
namespace Test\L10N;
|
||||||
|
|
||||||
use OC\L10N\Factory;
|
use OC\L10N\Factory;
|
||||||
|
use OCP\IConfig;
|
||||||
|
use OCP\IRequest;
|
||||||
|
use OCP\IUser;
|
||||||
|
use OCP\IUserSession;
|
||||||
use Test\TestCase;
|
use Test\TestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -18,13 +22,13 @@ use Test\TestCase;
|
||||||
*/
|
*/
|
||||||
class FactoryTest extends TestCase {
|
class FactoryTest extends TestCase {
|
||||||
|
|
||||||
/** @var \OCP\IConfig|\PHPUnit_Framework_MockObject_MockObject */
|
/** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */
|
||||||
protected $config;
|
protected $config;
|
||||||
|
|
||||||
/** @var \OCP\IRequest|\PHPUnit_Framework_MockObject_MockObject */
|
/** @var IRequest|\PHPUnit_Framework_MockObject_MockObject */
|
||||||
protected $request;
|
protected $request;
|
||||||
|
|
||||||
/** @var \OCP\IUserSession|\PHPUnit_Framework_MockObject_MockObject */
|
/** @var IUserSession|\PHPUnit_Framework_MockObject_MockObject */
|
||||||
protected $userSession;
|
protected $userSession;
|
||||||
|
|
||||||
/** @var string */
|
/** @var string */
|
||||||
|
@ -33,17 +37,15 @@ class FactoryTest extends TestCase {
|
||||||
public function setUp() {
|
public function setUp() {
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
|
||||||
/** @var \OCP\IConfig $request */
|
$this->config = $this->getMockBuilder(IConfig::class)
|
||||||
$this->config = $this->getMockBuilder('OCP\IConfig')
|
|
||||||
->disableOriginalConstructor()
|
->disableOriginalConstructor()
|
||||||
->getMock();
|
->getMock();
|
||||||
|
|
||||||
/** @var \OCP\IRequest $request */
|
$this->request = $this->getMockBuilder(IRequest::class)
|
||||||
$this->request = $this->getMockBuilder('OCP\IRequest')
|
|
||||||
->disableOriginalConstructor()
|
->disableOriginalConstructor()
|
||||||
->getMock();
|
->getMock();
|
||||||
|
|
||||||
$this->userSession = $this->getMockBuilder('\OCP\IUserSession')
|
$this->userSession = $this->getMockBuilder(IUserSession::class)
|
||||||
->disableOriginalConstructor()
|
->disableOriginalConstructor()
|
||||||
->getMock();
|
->getMock();
|
||||||
|
|
||||||
|
@ -56,7 +58,7 @@ class FactoryTest extends TestCase {
|
||||||
*/
|
*/
|
||||||
protected function getFactory(array $methods = []) {
|
protected function getFactory(array $methods = []) {
|
||||||
if (!empty($methods)) {
|
if (!empty($methods)) {
|
||||||
return $this->getMockBuilder('OC\L10N\Factory')
|
return $this->getMockBuilder(Factory::class)
|
||||||
->setConstructorArgs([
|
->setConstructorArgs([
|
||||||
$this->config,
|
$this->config,
|
||||||
$this->request,
|
$this->request,
|
||||||
|
@ -111,7 +113,7 @@ class FactoryTest extends TestCase {
|
||||||
->method('getSystemValue')
|
->method('getSystemValue')
|
||||||
->with('installed', false)
|
->with('installed', false)
|
||||||
->willReturn(true);
|
->willReturn(true);
|
||||||
$user = $this->getMockBuilder('\OCP\IUser')
|
$user = $this->getMockBuilder(IUser::class)
|
||||||
->getMock();
|
->getMock();
|
||||||
$user->expects($this->once())
|
$user->expects($this->once())
|
||||||
->method('getUID')
|
->method('getUID')
|
||||||
|
@ -145,7 +147,7 @@ class FactoryTest extends TestCase {
|
||||||
->method('getSystemValue')
|
->method('getSystemValue')
|
||||||
->with('installed', false)
|
->with('installed', false)
|
||||||
->willReturn(true);
|
->willReturn(true);
|
||||||
$user = $this->getMockBuilder('\OCP\IUser')
|
$user = $this->getMockBuilder(IUser::class)
|
||||||
->getMock();
|
->getMock();
|
||||||
$user->expects($this->once())
|
$user->expects($this->once())
|
||||||
->method('getUID')
|
->method('getUID')
|
||||||
|
@ -188,7 +190,7 @@ class FactoryTest extends TestCase {
|
||||||
->method('getSystemValue')
|
->method('getSystemValue')
|
||||||
->with('installed', false)
|
->with('installed', false)
|
||||||
->willReturn(true);
|
->willReturn(true);
|
||||||
$user = $this->getMockBuilder('\OCP\IUser')
|
$user = $this->getMockBuilder(IUser::class)
|
||||||
->getMock();
|
->getMock();
|
||||||
$user->expects($this->once())
|
$user->expects($this->once())
|
||||||
->method('getUID')
|
->method('getUID')
|
||||||
|
@ -234,7 +236,7 @@ class FactoryTest extends TestCase {
|
||||||
->method('getSystemValue')
|
->method('getSystemValue')
|
||||||
->with('installed', false)
|
->with('installed', false)
|
||||||
->willReturn(true);
|
->willReturn(true);
|
||||||
$user = $this->getMockBuilder('\OCP\IUser')
|
$user = $this->getMockBuilder(IUser::class)
|
||||||
->getMock();
|
->getMock();
|
||||||
$user->expects($this->once())
|
$user->expects($this->once())
|
||||||
->method('getUID')
|
->method('getUID')
|
||||||
|
@ -460,4 +462,86 @@ class FactoryTest extends TestCase {
|
||||||
$fn = $factory->createPluralFunction($function);
|
$fn = $factory->createPluralFunction($function);
|
||||||
$this->assertEquals($expected, $fn($count));
|
$this->assertEquals($expected, $fn($count));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function dataFindLanguage() {
|
||||||
|
return [
|
||||||
|
// Not logged in
|
||||||
|
[false, [], 'en'],
|
||||||
|
[false, ['fr'], 'fr'],
|
||||||
|
[false, ['de', 'fr'], 'de'],
|
||||||
|
[false, ['nl', 'de', 'fr'], 'de'],
|
||||||
|
|
||||||
|
[true, [], 'en'],
|
||||||
|
[true, ['fr'], 'fr'],
|
||||||
|
[true, ['de', 'fr'], 'de'],
|
||||||
|
[true, ['nl', 'de', 'fr'], 'nl'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider dataFindLanguage
|
||||||
|
*
|
||||||
|
* @param bool $loggedIn
|
||||||
|
* @param array $availableLang
|
||||||
|
* @param string $expected
|
||||||
|
*/
|
||||||
|
public function testFindLanguage($loggedIn, $availableLang, $expected) {
|
||||||
|
$userLang = 'nl';
|
||||||
|
$browserLang = 'de';
|
||||||
|
$defaultLang = 'fr';
|
||||||
|
|
||||||
|
$this->config->expects($this->any())
|
||||||
|
->method('getSystemValue')
|
||||||
|
->will($this->returnCallback(function($var, $default) use ($defaultLang) {
|
||||||
|
if ($var === 'installed') {
|
||||||
|
return true;
|
||||||
|
} else if ($var === 'default_language') {
|
||||||
|
return $defaultLang;
|
||||||
|
} else {
|
||||||
|
return $default;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
if ($loggedIn) {
|
||||||
|
$user = $this->getMockBuilder(IUser::class)
|
||||||
|
->getMock();
|
||||||
|
$user->expects($this->any())
|
||||||
|
->method('getUID')
|
||||||
|
->willReturn('MyUserUid');
|
||||||
|
$this->userSession
|
||||||
|
->expects($this->any())
|
||||||
|
->method('getUser')
|
||||||
|
->willReturn($user);
|
||||||
|
$this->config->expects($this->any())
|
||||||
|
->method('getUserValue')
|
||||||
|
->with('MyUserUid', 'core', 'lang', null)
|
||||||
|
->willReturn($userLang);
|
||||||
|
} else {
|
||||||
|
$this->userSession
|
||||||
|
->expects($this->any())
|
||||||
|
->method('getUser')
|
||||||
|
->willReturn(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->request->expects($this->any())
|
||||||
|
->method('getHeader')
|
||||||
|
->with($this->equalTo('ACCEPT_LANGUAGE'))
|
||||||
|
->willReturn($browserLang);
|
||||||
|
|
||||||
|
$factory = $this->getFactory(['languageExists', 'findAvailableLanguages']);
|
||||||
|
$factory->expects($this->any())
|
||||||
|
->method('languageExists')
|
||||||
|
->will($this->returnCallback(function ($app, $lang) use ($availableLang) {
|
||||||
|
return in_array($lang, $availableLang);
|
||||||
|
}));
|
||||||
|
$factory->expects($this->any())
|
||||||
|
->method('findAvailableLanguages')
|
||||||
|
->will($this->returnCallback(function ($app) use ($availableLang) {
|
||||||
|
return $availableLang;
|
||||||
|
}));
|
||||||
|
|
||||||
|
$lang = $factory->findLanguage(null);
|
||||||
|
$this->assertSame($expected, $lang);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue