diff options
author | Morris Jobke <hey@morrisjobke.de> | 2018-06-29 08:03:43 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-06-29 08:03:43 +0200 |
commit | 61842f66ee9d5b5ceb5ac925e5c213047d5a5e19 (patch) | |
tree | ccc8412bb3e0e3eb3fba7086ef3f3f1b23616685 /lib/private | |
parent | 89b6ee1a45f165346ddcc9120195714087287b47 (diff) | |
parent | c1682f4228e29cfe9203fed63e7f203dc582482b (diff) | |
download | nextcloud-server-61842f66ee9d5b5ceb5ac925e5c213047d5a5e19.tar.gz nextcloud-server-61842f66ee9d5b5ceb5ac925e5c213047d5a5e19.zip |
Merge pull request #5623 from nextcloud/locale-setting
Add user locale/region setting
Diffstat (limited to 'lib/private')
-rw-r--r-- | lib/private/L10N/Factory.php | 92 | ||||
-rw-r--r-- | lib/private/L10N/L10N.php | 39 | ||||
-rw-r--r-- | lib/private/Settings/Personal/PersonalInfo.php | 39 | ||||
-rw-r--r-- | lib/private/TemplateLayout.php | 3 |
4 files changed, 158 insertions, 15 deletions
diff --git a/lib/private/L10N/Factory.php b/lib/private/L10N/Factory.php index e8a734f412c..8c8735836bb 100644 --- a/lib/private/L10N/Factory.php +++ b/lib/private/L10N/Factory.php @@ -55,6 +55,11 @@ class Factory implements IFactory { protected $availableLanguages = []; /** + * @var array + */ + protected $availableLocales = []; + + /** * @var array Structure: string => callable */ protected $pluralFunctions = []; @@ -97,9 +102,10 @@ class Factory implements IFactory { * * @param string $app * @param string|null $lang + * @param string|null $locale * @return \OCP\IL10N */ - public function get($app, $lang = null) { + public function get($app, $lang = null, $locale = null) { $app = \OC_App::cleanAppId($app); if ($lang !== null) { $lang = str_replace(array('\0', '/', '\\', '..'), '', (string) $lang); @@ -110,13 +116,22 @@ class Factory implements IFactory { $lang = $forceLang; } + $forceLocale = $this->config->getSystemValue('force_locale', false); + if (is_string($forceLocale)) { + $locale = $forceLocale; + } + if ($lang === null || !$this->languageExists($app, $lang)) { $lang = $this->findLanguage($app); } + if ($locale === null || !$this->localeExists($locale)) { + $locale = $this->findLocale($lang); + } + if (!isset($this->instances[$lang][$app])) { $this->instances[$lang][$app] = new L10N( - $this, $app, $lang, + $this, $app, $lang, $locale, $this->getL10nFilesForApp($app, $lang) ); } @@ -186,6 +201,48 @@ class Factory implements IFactory { } /** + * find the best locale + * + * @param string $lang + * @return null|string + */ + public function findLocale($lang = null) { + $forceLocale = $this->config->getSystemValue('force_locale', false); + if (is_string($forceLocale) && $this->localeExists($forceLocale)) { + return $forceLocale; + } + + if ($this->config->getSystemValue('installed', false)) { + $userId = null !== $this->userSession->getUser() ? $this->userSession->getUser()->getUID() : null; + $userLocale = null; + if (null !== $userId) { + $userLocale = $this->config->getUserValue($userId, 'core', 'locale', null); + } + } else { + $userId = null; + $userLocale = null; + } + + if ($userLocale && $this->localeExists($userLocale)) { + return $userLocale; + } + + // Default : use system default locale + $defaultLocale = $this->config->getSystemValue('default_locale', false); + if ($defaultLocale !== false && $this->localeExists($defaultLocale)) { + return $defaultLocale; + } + + // If no user locale set, use lang as locale + if (null !== $lang && $this->localeExists($lang)) { + return $lang; + } + + // At last, return USA + return 'en_US'; + } + + /** * Find all available languages for an app * * @param string|null $app App id or null for core @@ -237,6 +294,20 @@ class Factory implements IFactory { } /** + * @return array|mixed + */ + public function findAvailableLocales() { + if (!empty($this->availableLocales)) { + return $this->availableLocales; + } + + $localeData = file_get_contents(\OC::$SERVERROOT . '/resources/locales.json'); + $this->availableLocales = \json_decode($localeData, true); + + return $this->availableLocales; + } + + /** * @param string|null $app App id or null for core * @param string $lang * @return bool @@ -251,6 +322,23 @@ class Factory implements IFactory { } /** + * @param string $locale + * @return bool + */ + public function localeExists($locale) { + if ($locale === 'en') { //english is always available + return true; + } + + $locales = $this->findAvailableLocales(); + $userLocale = array_filter($locales, function($value) use ($locale) { + return $locale === $value['code']; + }); + + return !empty($userLocale); + } + + /** * @param string|null $app * @return string * @throws LanguageNotFoundException diff --git a/lib/private/L10N/L10N.php b/lib/private/L10N/L10N.php index a9b1b7377aa..a12375c4214 100644 --- a/lib/private/L10N/L10N.php +++ b/lib/private/L10N/L10N.php @@ -5,6 +5,7 @@ declare(strict_types=1); * * @author Georg Ehrke <oc.list@georgehrke.com> * @author Joas Schilling <coding@schilljs.com> + * @author Thomas Citharel <tcit@tcit.fr> * @author Roeland Jago Douma <roeland@famdouma.nl> * * @license AGPL-3.0 @@ -41,6 +42,9 @@ class L10N implements IL10N { /** @var string Language of this object */ protected $lang; + /** @var string Locale of this object */ + protected $locale; + /** @var string Plural forms (string) */ private $pluralFormString = 'nplurals=2; plural=(n != 1);'; @@ -54,12 +58,14 @@ class L10N implements IL10N { * @param IFactory $factory * @param string $app * @param string $lang + * @param string $locale * @param array $files */ - public function __construct(IFactory $factory, $app, $lang, array $files) { + public function __construct(IFactory $factory, $app, $lang, $locale, array $files) { $this->factory = $factory; $this->app = $app; $this->lang = $lang; + $this->locale = $locale; foreach ($files as $languageFile) { $this->load($languageFile); @@ -76,6 +82,15 @@ class L10N implements IL10N { } /** + * The code (en_US, fr_CA, ...) of the locale that is used for this instance + * + * @return string locale + */ + public function getLocaleCode(): string { + return $this->locale; + } + + /** * Translating * @param string $text The text we need a translation for * @param array|string $parameters default:array() Parameters for sprintf @@ -143,17 +158,19 @@ class L10N implements IL10N { * - jsdate: Returns the short JS date format */ public function l(string $type, $data = null, array $options = []) { - // Use the language of the instance - $locale = $this->getLanguageCode(); - if ($locale === 'sr@latin') { - $locale = 'sr_latn'; + if (null === $this->locale) { + // Use the language of the instance + $this->locale = $this->getLanguageCode(); + } + if ($this->locale === 'sr@latin') { + $this->locale = 'sr_latn'; } if ($type === 'firstday') { - return (int) Calendar::getFirstWeekday($locale); + return (int) Calendar::getFirstWeekday($this->locale); } if ($type === 'jsdate') { - return (string) Calendar::getDateFormat('short', $locale); + return (string) Calendar::getDateFormat('short', $this->locale); } $value = new \DateTime(); @@ -171,13 +188,13 @@ class L10N implements IL10N { $width = $options['width']; switch ($type) { case 'date': - return (string) Calendar::formatDate($value, $width, $locale); + return (string) Calendar::formatDate($value, $width, $this->locale); case 'datetime': - return (string) Calendar::formatDatetime($value, $width, $locale); + return (string) Calendar::formatDatetime($value, $width, $this->locale); case 'time': - return (string) Calendar::formatTime($value, $width, $locale); + return (string) Calendar::formatTime($value, $width, $this->locale); case 'weekdayName': - return (string) Calendar::getWeekdayName($value, $width, $locale); + return (string) Calendar::getWeekdayName($value, $width, $this->locale); default: return false; } diff --git a/lib/private/Settings/Personal/PersonalInfo.php b/lib/private/Settings/Personal/PersonalInfo.php index 305e3fb0a4d..f4a8548e8f1 100644 --- a/lib/private/Settings/Personal/PersonalInfo.php +++ b/lib/private/Settings/Personal/PersonalInfo.php @@ -4,6 +4,7 @@ * * @author Arthur Schiwon <blizzz@arthur-schiwon.de> * @author Morris Jobke <hey@morrisjobke.de> + * @author Thomas Citharel <tcit@tcit.fr> * * @license GNU AGPL version 3 or any later version * @@ -106,6 +107,7 @@ class PersonalInfo implements ISettings { } $languageParameters = $this->getLanguages($user); + $localeParameters = $this->getLocales($user); $messageParameters = $this->getMessageParameters($userData); $parameters = [ @@ -134,7 +136,7 @@ class PersonalInfo implements ISettings { 'twitterVerification' => $userData[AccountManager::PROPERTY_TWITTER]['verified'], 'groups' => $this->getGroups($user), 'passwordChangeSupported' => $user->canChangePassword(), - ] + $messageParameters + $languageParameters; + ] + $messageParameters + $languageParameters + $localeParameters; return new TemplateResponse('settings', 'settings/personal/personal.info', $parameters, ''); @@ -218,6 +220,41 @@ class PersonalInfo implements ISettings { ); } + private function getLocales(IUser $user) { + $forceLanguage = $this->config->getSystemValue('force_locale', false); + if($forceLanguage !== false) { + return []; + } + + $uid = $user->getUID(); + + $userLocaleString = $this->config->getUserValue($uid, 'core', 'locale', 'en_US'); + + $userLang = $this->config->getUserValue($uid, 'core', 'lang', $this->l10nFactory->findLanguage()); + + $localeCodes = $this->l10nFactory->findAvailableLocales(); + + $userLocale = array_filter($localeCodes, function($value) use ($userLocaleString) { + return $userLocaleString === $value['code']; + }); + + if (!empty($userLocale)) + { + $userLocale = reset($userLocale); + } + + $localesForLanguage = array_filter($localeCodes, function($localeCode) use ($userLang) { + return 0 === strpos($localeCode['code'], $userLang); + }); + + return [ + 'activelocaleLang' => $userLocaleString, + 'activelocale' => $userLocale, + 'locales' => $localeCodes, + 'localesForLanguage' => $localesForLanguage, + ]; + } + /** * @param array $userData * @return array diff --git a/lib/private/TemplateLayout.php b/lib/private/TemplateLayout.php index c378396c727..5e6719593a3 100644 --- a/lib/private/TemplateLayout.php +++ b/lib/private/TemplateLayout.php @@ -131,10 +131,11 @@ class TemplateLayout extends \OC_Template { parent::__construct('core', 'layout.base'); } - // Send the language to our layouts + // Send the language and the locale to our layouts $lang = \OC::$server->getL10NFactory()->findLanguage(); $lang = str_replace('_', '-', $lang); $this->assign('language', $lang); + $this->assign('locale', \OC::$server->getL10NFactory()->findLocale($lang)); if(\OC::$server->getSystemConfig()->getValue('installed', false)) { if (empty(self::$versionHash)) { |