Commit ece6501c authored by bgm's avatar bgm Committed by GitHub

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).
parent 7f27f357
......@@ -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
*/
......
......@@ -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<string> $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
);
}
}
......@@ -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) {
......
......@@ -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'));
......
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.7 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2015 |
+--------------------------------------------------------------------+
| This file is a part of CiviCRM. |
| |
| CiviCRM is free software; you can copy, modify, and distribute it |
| under the terms of the GNU Affero General Public License |
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
| |
| CiviCRM 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 and the CiviCRM Licensing Exception along |
| with this program; if not, contact CiviCRM LLC |
| at info[AT]civicrm[DOT]org. If you have questions about the |
| GNU Affero General Public License or the licensing of CiviCRM, |
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
+--------------------------------------------------------------------+
*/
namespace Civi\Core;
use Civi;
use Civi\Core\Event\SystemInstallEvent;
/**
* Class LocalizationInitializer
* @package Civi\Core
*/
class LocalizationInitializer {
/**
* Load the locale settings based on the installation language
*
* @param \Civi\Core\Event\SystemInstallEvent $event
* @throws \CRM_Core_Exception
*/
public static function initialize(SystemInstallEvent $event) {
// get the current installation language
global $tsLocale;
$seedLanguage = $tsLocale;
if (!$seedLanguage) {
return;
}
// get the corresponding settings file if any
$localeDir = \CRM_Core_I18n::getResourceDir();
$fileName = $localeDir . $seedLanguage . DIRECTORY_SEPARATOR . 'settings.default.json';
// initalization
$settingsParams = array();
if (file_exists($fileName)) {
// load the file and parse it
$json = file_get_contents($fileName);
$settings = json_decode($json, TRUE);
if (!empty($settings)) {
// get all valid settings
$results = civicrm_api3('Setting', 'getfields', array());
$validSettings = array_keys($results['values']);
// add valid settings to params to send to api
foreach ($settings as $setting => $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);
}
}
......@@ -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 .= '</ul>';
$output .= '</div>';
$output .= '</body>';
......
......@@ -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',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment