Commit f806379b authored by totten's avatar totten

CRM-16373 - Migrate config_backend to civicrm_setting

There are two steps at which we convert config_backend:

 * In loading the upgrade environment, we may need access to old settings.
   So SettingsBag supports reading config_backend for the active domain.
 * As a specific upgrade step (for 4.7.alpha1), we migrate all values
   for all domains (unless there's already a setting).
parent 606999ec
......@@ -67,6 +67,14 @@ class CRM_Core_Config_MagicMerge {
}
/**
* Get a list of $config properties and the entities to which they map.
*
* This is used for two purposes:
*
* 1. Runtime: Provide backward-compatible interface for reading these
* properties.
* 2. Upgrade: Migrate old properties of config_backend into settings.
*
* @return array
*/
public static function getPropertyMap() {
......
......@@ -722,15 +722,8 @@ SET version = '$version'
// Seems extraneous in context, but we'll preserve old behavior
$upgrade->setVersion($latestVer);
// lets rebuild the config array in case we've made a few changes in the
// code base
// this also helps us always store the latest version of civi in the DB
$params = array();
CRM_Core_BAO_ConfigSetting::add($params);
// CRM-12804 comment-51411 : add any missing settings
// at the end of upgrade
CRM_Core_BAO_Setting::updateSettingsFromMetaData();
// Clear cached metadata.
Civi::service('settings_manager')->flush();
// cleanup caches CRM-8739
$config = CRM_Core_Config::singleton();
......
......@@ -102,6 +102,7 @@ class CRM_Upgrade_Incremental_php_FourSeven extends CRM_Upgrade_Incremental_Base
public function upgrade_4_7_alpha1($rev) {
$this->addTask(ts('Migrate \'on behalf of\' information to module_data'), 'migrateOnBehalfOfInfo');
$this->addTask(ts('Upgrade DB to %1: SQL', array(1 => $rev)), 'runSql', $rev);
$this->addTask(ts('Migrate Settings to %1', array(1 => $rev)), 'migrateSettings', $rev);
$this->addTask(ts('Add Getting Started dashlet to %1: SQL', array(1 => $rev)), 'addGettingStartedDashlet', $rev);
}
......@@ -120,6 +121,82 @@ class CRM_Upgrade_Incremental_php_FourSeven extends CRM_Upgrade_Incremental_Base
return $editorID;
}
/**
* Migrate any last remaining options from `civicrm_domain.config_backend` to `civicrm_setting`.
* Cleanup setting schema.
*
* @param CRM_Queue_TaskContext $ctx
* @return bool
*/
public function migrateSettings(CRM_Queue_TaskContext $ctx) {
CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_setting DROP INDEX index_group_name');
CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_setting DROP COLUMN group_name');
CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_setting ADD UNIQUE INDEX index_domain_contact_name (domain_id, contact_id, name)');
$domainDao = CRM_Core_DAO::executeQuery('SELECT id, config_backend FROM civicrm_domain');
while ($domainDao->fetch()) {
$settings = CRM_Upgrade_Incremental_php_FourSeven::convertBackendToSettings($domainDao->id, $domainDao->config_backend);
CRM_Core_Error::debug_var('convertBackendToSettings', array(
'domainId' => $domainDao->id,
'backend' => $domainDao->config_backend,
'settings' => $settings,
));
foreach ($settings as $name => $value) {
$rowParams = array(
1 => array($domainDao->id, 'Positive'),
2 => array($name, 'String'),
3 => array(serialize($value), 'String'),
);
$settingId = CRM_Core_DAO::singleValueQuery(
'SELECT id FROM civicrm_setting WHERE domain_id = %1 AND name = %2',
$rowParams);
if (!$settingId) {
CRM_Core_DAO::executeQuery(
'INSERT INTO civicrm_setting (domain_id, name, value, is_domain) VALUES (%1,%2,%3,1)',
$rowParams);
}
}
}
// TODO Should drop config_backend, but keeping it during alpha/beta cycle in case we miss something.
// CRM_Core_DAO::executeQuery('ALTER TABLE civicrm_domain DROP COLUMN config_backend');
return TRUE;
}
/**
* Take a config_backend blob and produce an equivalent list of settings.
*
* @param int $domainId
* Domain ID.
* @param string $config_backend
* Serialized blob.
* @return array
*/
public static function convertBackendToSettings($domainId, $config_backend) {
if (!$config_backend) {
return array();
}
$backend = unserialize($config_backend);
if (!$backend) {
return array();
}
$mappings = \CRM_Core_Config_MagicMerge::getPropertyMap();
$settings = array();
foreach ($backend as $propertyName => $propertyValue) {
if (isset($mappings[$propertyName][0]) && preg_match('/^setting/', $mappings[$propertyName][0])) {
// $mapping format: $propertyName => Array(0 => $type, 1 => $setting|NULL).
$settingName = isset($mappings[$propertyName][1]) ? $mappings[$propertyName][1] : $propertyName;
$settings[$settingName] = $propertyValue;
}
}
return $settings;
}
/**
* Add Getting Started dashlet to dashboard
*
......
......@@ -130,14 +130,35 @@ class SettingsBag {
* @return $this
*/
public function loadValues() {
$this->values = array();
// Note: Don't use Setting DAO. It requires fields() which requires
// Note: Don't use DAO child classes. They require fields() which require
// translations -- which are keyed off settings!
$dao = \CRM_Core_DAO::executeQuery($this->createQuery()->toSQL());
while ($dao->fetch()) {
$this->values[$dao->name] = ($dao->value !== NULL) ? unserialize($dao->value) : NULL;
}
$this->values = array();
$this->combined = NULL;
// Ordinarily, we just load values from `civicrm_setting`. But upgrades require care.
// In v4.0 and earlier, all values were stored in `civicrm_domain.config_backend`.
// In v4.1-v4.6, values were split between `civicrm_domain` and `civicrm_setting`.
// In v4.7+, all values are stored in `civicrm_setting`.
// Whenever a value is available in civicrm_setting, it will take precedence.
$isUpgradeMode = \CRM_Core_Config::isUpgradeMode();
if ($isUpgradeMode && empty($this->contactId) && \CRM_Core_DAO::checkFieldExists('civicrm_domain', 'config_backend', FALSE)) {
$config_backend = \CRM_Core_DAO::singleValueQuery('SELECT config_backend FROM civicrm_domain WHERE id = %1',
array(1 => array($this->domainId, 'Positive')));
$oldSettings = \CRM_Upgrade_Incremental_php_FourSeven::convertBackendToSettings($this->domainId, $config_backend);
\CRM_Utils_Array::extend($this->values, $oldSettings);
}
// Normal case. Aside: Short-circuit prevents unnecessary query.
if (!$isUpgradeMode || \CRM_Core_DAO::checkTableExists('civicrm_setting')) {
$dao = \CRM_Core_DAO::executeQuery($this->createQuery()->toSQL());
while ($dao->fetch()) {
$this->values[$dao->name] = ($dao->value !== NULL) ? unserialize($dao->value) : NULL;
}
}
return $this;
}
......@@ -265,7 +286,7 @@ class SettingsBag {
*/
protected function createQuery() {
$select = \CRM_Utils_SQL_Select::from('civicrm_setting')
->select('id, group_name, name, value, domain_id, contact_id, is_domain, component_id, created_date, created_id')
->select('id, name, value, domain_id, contact_id, is_domain, component_id, created_date, created_id')
->where('domain_id = #id', array(
'id' => $this->domainId,
));
......@@ -336,7 +357,6 @@ class SettingsBag {
$dao->is_domain = 1;
}
$dao->find(TRUE);
$dao->group_name = '';
if (isset($metadata['on_change'])) {
foreach ($metadata['on_change'] as $callback) {
......
......@@ -61,60 +61,6 @@ VALUES
( @domainID, 'Always' , NULL, 'Process Survey Respondents', 'Releases reserved survey respondents when they have been reserved for longer than the Release Frequency days specified for that survey.', 'job', 'process_respondent',NULL, 0),
( @domainID, 'Hourly' , NULL, 'Clean-up Temporary Data and Files','Removes temporary data and files, and clears old data from cache tables. Recommend running this job every hour to help prevent database and file system bloat.', 'job', 'cleanup', NULL, 0);
-- Initial default state of system settings
INSERT INTO civicrm_setting
( domain_id, contact_id, is_domain, group_name, name, value )
VALUES
( @domainID, NULL, 1, 'CiviCRM Preferences', 'contact_view_options', 's:28:"123456789101113";' ),
( @domainID, NULL, 1, 'CiviCRM Preferences', 'contact_edit_options', 's:22:"12345678911";' ),
( @domainID, NULL, 1, 'CiviCRM Preferences', 'advanced_search_options', 's:46:"123456789101112131516171819";' ),
( @domainID, NULL, 1, 'CiviCRM Preferences', 'user_dashboard_options', 's:15:"1234578";' ),
( @domainID, NULL, 1, 'CiviCRM Preferences', 'address_options', 's:23:"123456891011";' ),
( @domainID, NULL, 1, 'CiviCRM Preferences', 'address_format', 's:198:"{contact.address_name}
{contact.street_address}
{contact.supplemental_address_1}
{contact.supplemental_address_2}
{contact.city}{, }{contact.state_province}{ }{contact.postal_code}
{contact.country}";' ),
( @domainID, NULL, 1, 'CiviCRM Preferences', 'mailing_format', 's:195:"{contact.addressee}
{contact.street_address}
{contact.supplemental_address_1}
{contact.supplemental_address_2}
{contact.city}{, }{contact.state_province}{ }{contact.postal_code}
{contact.country}";' ),
( @domainID, NULL, 1, 'CiviCRM Preferences', 'display_name_format', 's:102:"{contact.individual_prefix}{ }{contact.first_name}{ }{contact.last_name}{ }{contact.individual_suffix}";' ),
( @domainID, NULL, 1, 'CiviCRM Preferences', 'sort_name_format', 's:43:"{contact.last_name}{, }{contact.first_name}";' ),
( @domainID, NULL, 1, 'CiviCRM Preferences', 'editor_id', 's:1:"2";' ),
( @domainID, NULL, 1, 'CiviCRM Preferences', 'contact_ajax_check_similar', 's:1:"1";' ),
( @domainID, NULL, 1, 'CiviCRM Preferences', 'activity_assignee_notification', 's:1:"1";' ),
( @domainID, NULL, 1, 'CiviCRM Preferences', 'contact_autocomplete_options', 's:5:"12";' ),
( @domainID, NULL, 1, 'CiviCRM Preferences', 'contact_reference_options', 's:5:"12";' ),
( @domainID, NULL, 1, 'Address Standardization Preferences', 'address_standardization_provider', NULL ),
( @domainID, NULL, 1, 'Address Standardization Preferences', 'address_standardization_userid', NULL ),
( @domainID, NULL, 1, 'Address Standardization Preferences', 'address_standardization_url', NULL ),
( @domainID, NULL, 1, 'Campaign Preferences', 'tag_unconfirmed', 's:11:"Unconfirmed";' ),
( @domainID, NULL, 1, 'Campaign Preferences', 'petition_contacts', 's:17:"Petition Contacts";' ),
( @domainID, NULL, 1, 'Event Preferences' , 'enable_cart', 's:1:"0";' ),
( @domainID, NULL, 1, 'Mailing Preferences', 'profile_double_optin', 's:1:"1";' ),
( @domainID, NULL, 1, 'Mailing Preferences', 'profile_add_to_group_double_optin', 's:1:"0";' ),
( @domainID, NULL, 1, 'Mailing Preferences', 'track_civimail_replies', 's:1:"0";' ),
( @domainID, NULL, 1, 'Mailing Preferences', 'civimail_workflow', 's:1:"0";' ),
( @domainID, NULL, 1, 'Mailing Preferences', 'civimail_server_wide_lock', 's:1:"0";' ),
( @domainID, NULL, 1, 'Mailing Preferences', 'mailing_backend', 'a:1:{s:15:"outBound_option";s:1:"3";}' ),
( @domainID, NULL, 1, 'Member Preferences' , 'default_renewal_contribution_page', NULL ),
( @domainID, NULL, 1, 'Multi Site Preferences', 'is_enabled', 's:1:"0";' ),
( @domainID, NULL, 1, 'Multi Site Preferences', 'uniq_email_per_site', 's:1:"0";' ),
( @domainID, NULL, 1, 'Multi Site Preferences', 'domain_group_id', 's:1:"0";' ),
( @domainID, NULL, 1, 'Multi Site Preferences', 'event_price_set_domain_id', 's:1:"0";' ),
( @domainID, NULL, 1, 'Directory Preferences', 'uploadDir' , NULL ),
( @domainID, NULL, 1, 'Directory Preferences', 'imageUploadDir' , NULL ),
( @domainID, NULL, 1, 'Directory Preferences', 'customFileUploadDir', NULL ),
( @domainID, NULL, 1, 'Directory Preferences', 'customTemplateDir' , NULL ),
( @domainID, NULL, 1, 'Directory Preferences', 'customPHPPathDir' , NULL ),
( @domainID, NULL, 1, 'Directory Preferences', 'extensionsDir' , NULL ),
( @domainID, NULL, 1, 'URL Preferences', 'userFrameworkResourceURL' , NULL ),
( @domainID, NULL, 1, 'URL Preferences', 'imageUploadURL' , NULL ),
( @domainID, NULL, 1, 'URL Preferences', 'customCSSURL' , NULL ),
( @domainID, NULL, 1, 'URL Preferences', 'extensionsURL' , NULL );
INSERT INTO `civicrm_dashboard`
( `domain_id`, `label`, `url`, `permission`, `permission_operator`, `column_no`, `is_minimized`, `is_active`, `weight`, `fullscreen_url`, `is_fullscreen`, `is_reserved`)
......
......@@ -98,7 +98,7 @@ class CRM_Core_BAO_SettingTest extends CiviUnitTestCase {
$this->assertEquals('/test/dataride', $values['databaseSetting']);
// CRM-14974 tear down
unset($civicrm_setting['Test Preferences']);
$query = "DELETE FROM civicrm_setting WHERE group_name = 'Test Preferences';";
$query = "DELETE FROM civicrm_setting WHERE name IN ('overrideSetting', 'databaseSetting');";
CRM_Core_DAO::executeQuery($query);
}
......
......@@ -25,6 +25,7 @@
<required>true</required>
<comment>group name for setting element, useful in caching setting elements</comment>
<add>4.1</add>
<drop>4.7</drop>
</field>
<field>
<name>name</name>
......@@ -39,6 +40,7 @@
<fieldName>group_name</fieldName>
<fieldName>name</fieldName>
<add>4.1</add>
<drop>4.7</drop>
</index>
<field>
<name>value</name>
......@@ -129,4 +131,13 @@
<add>4.1</add>
<onDelete>SET NULL</onDelete>
</foreignKey>
<index>
<name>index_domain_contact_name</name>
<fieldName>domain_id</fieldName>
<fieldName>contact_id</fieldName>
<fieldName>name</fieldName>
<unique>true</unique>
<add>4.7</add>
</index>
</table>
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