From ece6501cb7994371b48e870294590f23851266e7 Mon Sep 17 00:00:00 2001 From: Mathieu Lu Date: Mon, 19 Jun 2017 22:49:50 -0400 Subject: [PATCH] CRM-16395: Installation with localized default settings (4) (#10518) CRM-16395: Installation with localized default settings This makes it possible to have a file in "civicrm/l10n/xx_YY/settings.default.json" with default settings that correspond to the locale during installation (ex: default country, currency, date formats, etc). --- CRM/Admin/Form/Setting/Localization.php | 82 +++++++++++++------ CRM/Core/BAO/OptionGroup.php | 32 ++++++++ CRM/Core/I18n.php | 12 ++- Civi/Core/Container.php | 1 + Civi/Core/LocalizationInitializer.php | 104 ++++++++++++++++++++++++ install/index.php | 19 ++--- settings/Localization.setting.php | 3 + 7 files changed, 215 insertions(+), 38 deletions(-) create mode 100644 Civi/Core/LocalizationInitializer.php diff --git a/CRM/Admin/Form/Setting/Localization.php b/CRM/Admin/Form/Setting/Localization.php index 8e2b2718ab..21cd8f8a3a 100644 --- a/CRM/Admin/Form/Setting/Localization.php +++ b/CRM/Admin/Form/Setting/Localization.php @@ -191,40 +191,16 @@ class CRM_Admin_Form_Setting_Localization extends CRM_Admin_Form_Setting { // we do this only to initialize monetary decimal point and thousand separator $config = CRM_Core_Config::singleton(); - // save enabled currencies and defaul currency in option group 'currencies_enabled' + // save enabled currencies and default currency in option group 'currencies_enabled' // CRM-1496 if (empty($values['currencyLimit'])) { $values['currencyLimit'] = array($values['defaultCurrency']); } - elseif (!in_array($values['defaultCurrency'], - $values['currencyLimit'] - ) - ) { + elseif (!in_array($values['defaultCurrency'], $values['currencyLimit'])) { $values['currencyLimit'][] = $values['defaultCurrency']; } - // sort so that when we display drop down, weights have right value - sort($values['currencyLimit']); - - // get labels for all the currencies - $options = array(); - - $currencySymbols = self::getCurrencySymbols(); - for ($i = 0; $i < count($values['currencyLimit']); $i++) { - $options[] = array( - 'label' => $currencySymbols[$values['currencyLimit'][$i]], - 'value' => $values['currencyLimit'][$i], - 'weight' => $i + 1, - 'is_active' => 1, - 'is_default' => $values['currencyLimit'][$i] == $values['defaultCurrency'], - ); - } - - $dontCare = NULL; - CRM_Core_OptionGroup::createAssoc('currencies_enabled', - $options, - $dontCare - ); + self::updateEnabledCurrencies($values['currencyLimit'], $values['defaultCurrency']); // unset currencyLimit so we dont store there unset($values['currencyLimit']); @@ -269,6 +245,38 @@ class CRM_Admin_Form_Setting_Localization extends CRM_Admin_Form_Setting { } } + + /** + * Replace available currencies by the ones provided + * + * @param $currencies array of currencies ['USD', 'CAD'] + * @param $default default currency + */ + public static function updateEnabledCurrencies($currencies, $default) { + + // sort so that when we display drop down, weights have right value + sort($currencies); + + // get labels for all the currencies + $options = array(); + + $currencySymbols = CRM_Admin_Form_Setting_Localization::getCurrencySymbols(); + for ($i = 0; $i < count($currencies); $i++) { + $options[] = array( + 'label' => $currencySymbols[$currencies[$i]], + 'value' => $currencies[$i], + 'weight' => $i + 1, + 'is_active' => 1, + 'is_default' => $currencies[$i] == $default, + ); + } + + $dontCare = NULL; + CRM_Core_OptionGroup::createAssoc('currencies_enabled', $options, $dontCare); + + } + + /** * @return array */ @@ -351,6 +359,26 @@ class CRM_Admin_Form_Setting_Localization extends CRM_Admin_Form_Setting { } } + public static function onChangeDefaultCurrency($oldCurrency, $newCurrency, $metadata) { + if ($oldCurrency == $newCurrency) { + return; + } + + // ensure that default currency is always in the list of enabled currencies + $currencies = array_keys(CRM_Core_OptionGroup::values('currencies_enabled')); + if (!in_array($newCurrency, $currencies)) { + if (empty($currencies)) { + $currencies = array($values['defaultCurrency']); + } + else { + $currencies[] = $newCurrency; + } + + CRM_Admin_Form_Setting_Localization::updateEnabledCurrencies($currencies, $newCurrency); + } + + } + /** * @return array */ diff --git a/CRM/Core/BAO/OptionGroup.php b/CRM/Core/BAO/OptionGroup.php index d0f0afc71b..b06e37251b 100644 --- a/CRM/Core/BAO/OptionGroup.php +++ b/CRM/Core/BAO/OptionGroup.php @@ -219,4 +219,36 @@ class CRM_Core_BAO_OptionGroup extends CRM_Core_DAO_OptionGroup { return \Civi::$statics[__CLASS__]['titles_by_name']; } + /** + * Set the given values to active, and set all other values to inactive. + * + * @param string $optionGroupName + * e.g "languages" + * @param array $activeValues + * e.g. array("en_CA","fr_CA") + */ + public static function setActiveValues($optionGroupName, $activeValues) { + $params = array( + 1 => array($optionGroupName, 'String'), + ); + + // convert activeValues into placeholders / params in the query + $placeholders = array(); + $i = count($params) + 1; + foreach ($activeValues as $value) { + $placeholders[] = "%{$i}"; + $params[$i] = array($value, 'String'); + $i++; + } + $placeholders = implode(', ', $placeholders); + + CRM_Core_DAO::executeQuery(" +UPDATE civicrm_option_value cov + LEFT JOIN civicrm_option_group cog ON cov.option_group_id = cog.id +SET cov.is_active = CASE WHEN cov.name IN ({$placeholders}) THEN 1 ELSE 0 END +WHERE cog.name = %1", + $params + ); + } + } diff --git a/CRM/Core/I18n.php b/CRM/Core/I18n.php index ca7706cd9d..9e20536dfe 100644 --- a/CRM/Core/I18n.php +++ b/CRM/Core/I18n.php @@ -163,6 +163,14 @@ class CRM_Core_I18n { if (!$all) { $all = CRM_Contact_BAO_Contact::buildOptions('preferred_language'); + // get labels + $rows = array(); + $labels = array(); + CRM_Core_OptionValue::getValues(array('name' => 'languages'), $rows); + foreach ($rows as $id => $row) { + $labels[$row['name']] = $row['label']; + } + // check which ones are available; add them to $all if not there already $codes = array(); if (is_dir(CRM_Core_I18n::getResourceDir()) && $dir = opendir(CRM_Core_I18n::getResourceDir())) { @@ -170,7 +178,7 @@ class CRM_Core_I18n { if (preg_match('/^[a-z][a-z]_[A-Z][A-Z]$/', $filename)) { $codes[] = $filename; if (!isset($all[$filename])) { - $all[$filename] = $filename; + $all[$filename] = $labels[$filename]; } } } @@ -186,6 +194,8 @@ class CRM_Core_I18n { unset($all[$code]); } } + + ksort($all); } if ($enabled === NULL) { diff --git a/Civi/Core/Container.php b/Civi/Core/Container.php index efe6a656c5..0c35bcd1ba 100644 --- a/Civi/Core/Container.php +++ b/Civi/Core/Container.php @@ -249,6 +249,7 @@ class Container { $dispatcher = new CiviEventDispatcher($container); $dispatcher->addListener(SystemInstallEvent::EVENT_NAME, array('\Civi\Core\InstallationCanary', 'check')); $dispatcher->addListener(SystemInstallEvent::EVENT_NAME, array('\Civi\Core\DatabaseInitializer', 'initialize')); + $dispatcher->addListener(SystemInstallEvent::EVENT_NAME, array('\Civi\Core\LocalizationInitializer', 'initialize')); $dispatcher->addListener('hook_civicrm_pre', array('\Civi\Core\Event\PreEvent', 'dispatchSubevent'), 100); $dispatcher->addListener('hook_civicrm_post', array('\Civi\Core\Event\PostEvent', 'dispatchSubevent'), 100); $dispatcher->addListener('hook_civicrm_post::Activity', array('\Civi\CCase\Events', 'fireCaseChange')); diff --git a/Civi/Core/LocalizationInitializer.php b/Civi/Core/LocalizationInitializer.php new file mode 100644 index 0000000000..6eb89355c9 --- /dev/null +++ b/Civi/Core/LocalizationInitializer.php @@ -0,0 +1,104 @@ + $value) { + if (in_array($setting, $validSettings)) { + $settingsParams[$setting] = $value; + } + + } + + // ensure we don't mess with multilingual + unset($settingsParams['languageLimit']); + + // support for enabled languages (option group) + if (isset($settings['languagesOption']) && count($settings['languagesOption']) > 0) { + \CRM_Core_BAO_OptionGroup::setActiveValues('languages', $settings['languagesOption']); + } + + // set default currency in currencies_enabled (option group) + if (isset($settings['defaultCurrency'])) { + \CRM_Admin_Form_Setting_Localization::updateEnabledCurrencies(array($settings['defaultCurrency']), $settings['defaultCurrency']); + } + + } + + } + + // in any case, enforce the seedLanguage as the default language + $settingsParams['lcMessages'] = $seedLanguage; + + // apply the config + civicrm_api3('Setting', 'create', $settingsParams); + + } + +} diff --git a/install/index.php b/install/index.php index ca739c9606..cdd7012d3c 100644 --- a/install/index.php +++ b/install/index.php @@ -177,7 +177,7 @@ foreach ($langs as $locale => $_) { } } -// Set the locale (required by CRM_Core_Config) +// Set the CMS // This is mostly sympbolic, since nothing we do during the install // really requires CIVICRM_UF to be defined. $installTypeToUF = array( @@ -189,6 +189,7 @@ $installTypeToUF = array( $uf = (isset($installTypeToUF[$installType]) ? $installTypeToUF[$installType] : 'Drupal'); define('CIVICRM_UF', $uf); +// Set the Locale (required by CRM_Core_Config) global $tsLocale; $tsLocale = 'en_US'; @@ -1487,6 +1488,13 @@ class Installer extends InstallRequirements { // now enable civicrm module. module_enable(array('civicrm', 'civicrmtheme')); + // SystemInstallEvent will be called from here with the first call of CRM_Core_Config, + // which calls Core_BAO_ConfigSetting::applyLocale(), who will default to calling + // Civi::settings()->get('lcMessages'); + // Therefore, we need to pass the seedLanguage before that. + global $civicrm_setting; + $civicrm_setting['domain']['lcMessages'] = $config['seedLanguage']; + // clear block, page, theme, and hook caches drupal_flush_all_caches(); @@ -1497,15 +1505,6 @@ class Installer extends InstallRequirements { $GLOBALS['user'] = $original_user; drupal_save_session(TRUE); - //change the default language to one chosen - if (isset($config['seedLanguage']) && $config['seedLanguage'] != 'en_US') { - civicrm_api3('Setting', 'create', array( - 'domain_id' => 'current_domain', - 'lcMessages' => $config['seedLanguage'], - ) - ); - } - $output .= ''; $output .= ''; $output .= ''; diff --git a/settings/Localization.setting.php b/settings/Localization.setting.php index dd1764d3f3..76cc771d77 100644 --- a/settings/Localization.setting.php +++ b/settings/Localization.setting.php @@ -142,6 +142,9 @@ return array( 'pseudoconstant' => array( 'callback' => 'CRM_Admin_Form_Setting_Localization::getCurrencySymbols', ), + 'on_change' => array( + 'CRM_Admin_Form_Setting_Localization::onChangeDefaultCurrency', + ), ), 'defaultContactCountry' => array( 'group_name' => 'Localization Preferences', -- 2.25.1