From 85639a3990ed8c74e85bc86d5b0ceb5e333fc079 Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Thu, 30 Jan 2014 13:17:15 +0100 Subject: [PATCH] Add language selection to general config and preference forms refs #5533 --- application/forms/Config/GeneralForm.php | 32 +++++++++++++ application/forms/Preference/GeneralForm.php | 46 ++++++++++++++++++- .../Application/ApplicationBootstrap.php | 2 +- library/Icinga/Util/Translator.php | 32 +++++++++++-- 4 files changed, 107 insertions(+), 5 deletions(-) diff --git a/application/forms/Config/GeneralForm.php b/application/forms/Config/GeneralForm.php index 376e0dbc0..d6eb5db91 100644 --- a/application/forms/Config/GeneralForm.php +++ b/application/forms/Config/GeneralForm.php @@ -37,6 +37,7 @@ use \Zend_View_Helper_DateFormat; use \Icinga\Application\Config as IcingaConfig; use \Icinga\Data\ResourceFactory; use \Icinga\Web\Form; +use \Icinga\Util\Translator; use \Icinga\Web\Form\Validator\WritablePathValidator; use \Icinga\Web\Form\Validator\TimeFormatValidator; use \Icinga\Web\Form\Validator\DateFormatValidator; @@ -161,6 +162,35 @@ class GeneralForm extends Form } + /** + * Add a select field for setting the default language + * + * Possible values are determined by Translator::getAvailableLocaleCodes. + * + * @param Zend_Config $cfg The "global" section of the config.ini + */ + private function addLanguageSelection(Zend_Config $cfg) + { + $languages = array(); + foreach (Translator::getAvailableLocaleCodes() as $language) { + $languages[$language] = $language; + } + $languages[Translator::DEFAULT_LOCALE] = Translator::DEFAULT_LOCALE; + + $this->addElement( + 'select', + 'language', + array( + 'label' => t('Default Language'), + 'required' => true, + 'multiOptions' => $languages, + 'helptext' => t('Select the language to use by default. Can be' + . ' overwritten by a user in his preferences.'), + 'value' => $cfg->get('language', Translator::DEFAULT_LOCALE) + ) + ); + } + /** * Add a select field for setting the default timezone. * @@ -353,6 +383,7 @@ class GeneralForm extends Form } $this->setName('form_config_general'); $this->addDevelopmentCheckbox($global); + $this->addLanguageSelection($global); $this->addTimezoneSelection($global); $this->addModuleSettings($global); $this->addDateFormatSettings($global); @@ -389,6 +420,7 @@ class GeneralForm extends Form $values = $this->getValues(); $cfg = clone $config; $cfg->global->environment = ($values['environment'] == 1) ? 'development' : 'production'; + $cfg->global->language = $values['language']; $cfg->global->timezone = $values['timezone']; $cfg->global->moduleFolder = $values['module_folder']; $cfg->global->modulePath = $values['module_path']; diff --git a/application/forms/Preference/GeneralForm.php b/application/forms/Preference/GeneralForm.php index f91a5f504..5b671e3b2 100644 --- a/application/forms/Preference/GeneralForm.php +++ b/application/forms/Preference/GeneralForm.php @@ -37,6 +37,7 @@ use \Zend_View_Helper_DateFormat; use \Icinga\Web\Form; use \Icinga\Web\Form\Validator\TimeFormatValidator; use \Icinga\Web\Form\Validator\DateFormatValidator; +use \Icinga\Util\Translator; /** * General user preferences @@ -73,13 +74,54 @@ class GeneralForm extends Form $this->dateHelper = $dateHelper; } + /** + * Add a select field for setting the user's language + * + * Possible values are determined by Translator::getAvailableLocaleCodes. + * Also, a 'use default format' checkbox is added in order to allow a user to discard his overwritten setting + * + * @param Zend_Config $cfg The "global" section of the config.ini to be used as default value + */ + private function addLanguageSelection(Zend_Config $cfg) + { + $languages = array(); + foreach (Translator::getAvailableLocaleCodes() as $language) { + $languages[$language] = $language; + } + $languages[Translator::DEFAULT_LOCALE] = Translator::DEFAULT_LOCALE; + $prefs = $this->getUserPreferences(); + $useDefaultLanguage = $this->getRequest()->getParam('default_language', !$prefs->has('app.language')); + + $this->addElement( + 'checkbox', + 'default_language', + array( + 'label' => t('Use Default Language'), + 'value' => !$prefs->has('app.language'), + 'required' => true + ) + ); + $selectOptions = array( + 'label' => t('Your Current Language'), + 'required' => !$useDefaultLanguage, + 'multiOptions' => $languages, + 'helptext' => t('Use the following language to display texts and messages'), + 'value' => $prefs->get('app.language', $cfg->get('language', Translator::DEFAULT_LOCALE)) + ); + if ($useDefaultLanguage) { + $selectOptions['disabled'] = 'disabled'; + } + $this->addElement('select', 'language', $selectOptions); + $this->enableAutoSubmit(array('default_language')); + } + /** * Add a select field for setting the user's timezone. * * Possible values are determined by DateTimeZone::listIdentifiers * Also, a 'use default format' checkbox is added in order to allow a user to discard his overwritten setting * - * @param Zend_Config $cfg The "global" section of the config.ini to be used as default valuse + * @param Zend_Config $cfg The "global" section of the config.ini to be used as default value */ private function addTimezoneSelection(Zend_Config $cfg) { @@ -210,6 +252,7 @@ class GeneralForm extends Form $global = new Zend_Config(array()); } + $this->addLanguageSelection($global); $this->addTimezoneSelection($global); $this->addDateFormatSettings($global); @@ -234,6 +277,7 @@ class GeneralForm extends Form { $values = $this->getValues(); return array( + 'app.language' => $values['language'], 'app.timezone' => $values['timezone'], 'app.dateFormat' => $values['date_format'], 'app.timeFormat' => $values['time_format'], diff --git a/library/Icinga/Application/ApplicationBootstrap.php b/library/Icinga/Application/ApplicationBootstrap.php index 8ee4151bb..67eb61630 100755 --- a/library/Icinga/Application/ApplicationBootstrap.php +++ b/library/Icinga/Application/ApplicationBootstrap.php @@ -435,7 +435,7 @@ abstract class ApplicationBootstrap */ protected function setupInternationalization() { - Translator::setupLocale($this->config->global->get('language', 'en_US')); + Translator::setupLocale($this->config->global->get('language', Translator::DEFAULT_LOCALE)); $localeDir = $this->getApplicationDir('locale'); if (file_exists($localeDir) && is_dir($localeDir)) { diff --git a/library/Icinga/Util/Translator.php b/library/Icinga/Util/Translator.php index c38a3a0b4..7c2264241 100644 --- a/library/Icinga/Util/Translator.php +++ b/library/Icinga/Util/Translator.php @@ -42,7 +42,12 @@ class Translator const DEFAULT_DOMAIN = 'icinga'; /** - * Known gettext domains + * The locale code that is used in the project + */ + const DEFAULT_LOCALE = 'en_US'; + + /** + * Known gettext domains and directories * * @var array */ @@ -62,7 +67,7 @@ class Translator */ public static function translate($text, $domain) { - if ($domain !== self::DEFAULT_DOMAIN && !in_array($domain, self::$knownDomains)) { + if ($domain !== self::DEFAULT_DOMAIN && !array_key_exists($domain, self::$knownDomains)) { throw new Exception("Cannot translate string '$text' with unknown domain '$domain'"); } @@ -87,7 +92,7 @@ class Translator throw new Exception("Cannot register domain '$name' with path '$directory'"); } bind_textdomain_codeset($name, 'UTF-8'); - self::$knownDomains[] = $name; + self::$knownDomains[$name] = $directory; } /** @@ -105,4 +110,25 @@ class Translator putenv('LC_ALL=' . $localeName . '.UTF-8'); // Failsafe, Win and Unix putenv('LANG=' . $localeName . '.UTF-8'); // Windows fix, untested } + + /** + * Return a list of all locale codes currently available in the known domains + * + * @return array + */ + public static function getAvailableLocaleCodes() + { + $codes = array(); + + foreach (array_values(self::$knownDomains) as $directory) { + $dh = opendir($directory); + while (false !== ($name = readdir($dh))) { + if (!preg_match('@\.|\.\.@', $name) && is_dir($directory . DIRECTORY_SEPARATOR . $name)) { + $codes[] = $name; + } + } + } + + return $codes; + } }