Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CRM-16395: Installation with localized default settings (3) #10517

Closed
wants to merge 12 commits into from
Closed
82 changes: 55 additions & 27 deletions CRM/Admin/Form/Setting/Localization.php
Original file line number Diff line number Diff line change
Expand Up @@ -191,40 +191,16 @@ public function postProcess() {
// 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']);
Expand Down Expand Up @@ -269,6 +245,38 @@ public function postProcess() {
}
}


/**
* 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
*/
Expand Down Expand Up @@ -351,6 +359,26 @@ public static function onChangeLcMessages($oldLocale, $newLocale, $metadata, $do
}
}

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
*/
Expand Down
32 changes: 32 additions & 0 deletions CRM/Core/BAO/OptionGroup.php
Original file line number Diff line number Diff line change
Expand Up @@ -219,4 +219,36 @@ public static function getTitlesByNames() {
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
);
}

}
12 changes: 11 additions & 1 deletion CRM/Core/I18n.php
Original file line number Diff line number Diff line change
Expand Up @@ -163,14 +163,22 @@ public static function languages($justEnabled = FALSE) {
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())) {
while ($filename = readdir($dir)) {
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];
}
}
}
Expand All @@ -186,6 +194,8 @@ public static function languages($justEnabled = FALSE) {
unset($all[$code]);
}
}

ksort($all);
}

if ($enabled === NULL) {
Expand Down
1 change: 1 addition & 0 deletions Civi/Core/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ public function createEventDispatcher($container) {
$dispatcher->addListener(SystemInstallEvent::EVENT_NAME, array('\Civi\Core\DatabaseInitializer', '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(SystemInstallEvent::EVENT_NAME, array('\Civi\Core\LocalizationInitializer', 'initialize'));
$dispatcher->addListener('hook_civicrm_post::Activity', array('\Civi\CCase\Events', 'fireCaseChange'));
$dispatcher->addListener('hook_civicrm_post::Case', array('\Civi\CCase\Events', 'fireCaseChange'));
$dispatcher->addListener('hook_civicrm_caseChange', array('\Civi\CCase\Events', 'delegateToXmlListeners'));
Expand Down
104 changes: 104 additions & 0 deletions Civi/Core/LocalizationInitializer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<?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);

}

}
17 changes: 7 additions & 10 deletions install/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@
}
}

// 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(
Expand All @@ -189,6 +189,7 @@
$uf = (isset($installTypeToUF[$installType]) ? $installTypeToUF[$installType] : 'Drupal');
define('CIVICRM_UF', $uf);

// Set the Locale (required by CRM_Core_Config)
global $tsLocale;

$tsLocale = 'en_US';
Expand Down Expand Up @@ -1487,6 +1488,11 @@ public function install($config) {
// now enable civicrm module.
module_enable(array('civicrm', 'civicrmtheme'));

// SystemInstallEvent will be call from here with the first call of CiviCRM_Core_Settings
// 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();

Expand All @@ -1497,15 +1503,6 @@ public function install($config) {
$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>';
Expand Down
3 changes: 3 additions & 0 deletions settings/Localization.setting.php
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@
'pseudoconstant' => array(
'callback' => 'CRM_Admin_Form_Setting_Localization::getCurrencySymbols',
),
'on_change' => array(
'CRM_Admin_Form_Setting_Localization::onChangeDefaultCurrency',
),
),
'defaultContactCountry' => array(
'group_name' => 'Localization Preferences',
Expand Down