CRM-14232, CRM-16373 - Fix saving of contact_default_language
[civicrm-core.git] / CRM / Core / Config / MagicMerge.php
index 377c035f213660c7874eb8bc8d2d46062d360553..30931d19cf15f72618cc7c61e1a9d3b01db77652 100644 (file)
@@ -56,6 +56,8 @@ class CRM_Core_Config_MagicMerge {
 
   private $runtime, $locals, $settings;
 
+  private $cache = array();
+
   public function __construct() {
     $this->map = self::getPropertyMap();
   }
@@ -65,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() {
@@ -73,6 +83,7 @@ class CRM_Core_Config_MagicMerge {
     // Other parameters may be specified, depending on the type.
     return array(
       'backtrace' => array('setting'),
+      'contact_default_language' => array('contact_default_language'),
       'countryLimit' => array('setting'),
       'dashboardCacheTimeout' => array('setting'),
       'dateInputFormat' => array('setting'),
@@ -121,12 +132,14 @@ class CRM_Core_Config_MagicMerge {
       'recaptchaOptions' => array('setting'),
       'recaptchaPublicKey' => array('setting'),
       'recaptchaPrivateKey' => array('setting'),
+      'replyTo' => array('setting'),
       'secondDegRelPermissions' => array('setting'),
       'smartGroupCacheTimeout' => array('setting'),
       'timeInputFormat' => array('setting'),
       'userFrameworkLogging' => array('setting'),
       'userFrameworkUsersTableName' => array('setting'),
       'verpSeparator' => array('setting'),
+      'versionCheck' => array('setting'),
       'wkhtmltopdfPath' => array('setting'),
       'wpBasePage' => array('setting'),
       'wpLoadPhp' => array('setting'),
@@ -134,15 +147,16 @@ class CRM_Core_Config_MagicMerge {
       'doNotResetCache' => array('local'),
       'inCiviCRM' => array('local'),
       'userFrameworkFrontend' => array('local'),
-      'initialized' => array('local'),
 
       'dsn' => array('runtime'),
+      'initialized' => array('runtime'),
       'userFramework' => array('runtime'),
       'userFrameworkBaseURL' => array('runtime'),
       'userFrameworkClass' => array('runtime'),
       'userFrameworkDSN' => array('runtime'),
       'useFrameworkRelativeBase' => array('runtime', 'useFrameworkRelativeBase'),
       'userFrameworkURLVar' => array('runtime'),
+      'userFrameworkVersion' => array('runtime'),
       'userPermissionClass' => array('runtime'),
       'userPermissionTemp' => array('runtime'),
       'userSystem' => array('runtime'),
@@ -152,21 +166,21 @@ class CRM_Core_Config_MagicMerge {
       'templateCompileDir' => array('runtime'),
       'templateDir' => array('runtime'),
 
-      'customFileUploadDir' => array('setting-path', NULL, '[civicrm.files]/custom/', array('mkdir', 'restrict')),
+      'customFileUploadDir' => array('setting-path', NULL, array('mkdir', 'restrict')),
       'customPHPPathDir' => array('setting-path'),
       'customTemplateDir' => array('setting-path'),
       'extensionsDir' => array('setting-path'),
-      'imageUploadDir' => array('setting-path', NULL, '[civicrm.files]/persist/contribute/', array('mkdir')),
-      'uploadDir' => array('setting-path', NULL, '[civicrm.files]/upload/', array('mkdir', 'restrict')),
+      'imageUploadDir' => array('setting-path', NULL, array('mkdir')),
+      'uploadDir' => array('setting-path', NULL, array('mkdir', 'restrict')),
 
       'customCSSURL' => array('setting-url-abs'),
       'extensionsURL' => array('setting-url-abs'),
-      'imageUploadURL' => array('setting-url-abs', NULL, '[civicrm.files]/persist/contribute/'),
-      'resourceBase' => array('setting-url-rel', 'userFrameworkResourceURL', '[civicrm]/.'),
-      'userFrameworkResourceURL' => array('setting-url-abs', NULL, '[civicrm]/.'),
+      'imageUploadURL' => array('setting-url-abs'),
+      'resourceBase' => array('setting-url-rel', 'userFrameworkResourceURL'),
+      'userFrameworkResourceURL' => array('setting-url-abs'),
 
       'geocodeMethod' => array('callback', 'CRM_Utils_Geocode', 'getProviderClass'),
-      'defaultCurrencySymbol' => array('callback', 'CRM_Core_Config_Defaults', 'getDefaultCurrencySymbol'),
+      'defaultCurrencySymbol' => array('callback', 'CRM_Core_BAO_Country', 'getDefaultCurrencySymbol'),
     );
   }
 
@@ -174,6 +188,9 @@ class CRM_Core_Config_MagicMerge {
     if (!isset($this->map[$k])) {
       throw new \CRM_Core_Exception("Cannot read unrecognized property CRM_Core_Config::\${$k}.");
     }
+    if (isset($this->cache[$k])) {
+      return $this->cache[$k];
+    }
 
     $type = $this->map[$k][0];
     $name = isset($this->map[$k][1]) ? $this->map[$k][1] : $k;
@@ -183,38 +200,30 @@ class CRM_Core_Config_MagicMerge {
         return $this->getSettings()->get($name);
 
       case 'setting-path':
-        // Array(0 => $type, 1 => $setting, 2 => $default, 3 => $actions).
+        // Array(0 => $type, 1 => $setting, 2 => $actions).
         $value = $this->getSettings()->get($name);
-        if (empty($value) && isset($this->map[$k][2])) {
-          $value = $this->map[$k][2];
-        }
         $value = Civi::paths()->getPath($value);
         if ($value) {
           $value = CRM_Utils_File::addTrailingSlash($value);
-          if (isset($this->map[$k][3]) && in_array('mkdir', $this->map[$k][3])) {
+          if (isset($this->map[$k][2]) && in_array('mkdir', $this->map[$k][2])) {
             CRM_Utils_File::createDir($value);
           }
-          if (isset($this->map[$k][3]) && in_array('restrict', $this->map[$k][3])) {
+          if (isset($this->map[$k][2]) && in_array('restrict', $this->map[$k][2])) {
             CRM_Utils_File::restrictAccess($value);
           }
         }
+        $this->cache[$k] = $value;
         return $value;
 
       case 'setting-url-abs':
-        // Array(0 => $type, 1 => $setting, 2 => $default).
         $value = $this->getSettings()->get($name);
-        if (empty($value) && isset($this->map[$k][2])) {
-          $value = $this->map[$k][2];
-        }
-        return Civi::paths()->getUrl($value, 'absolute');
+        $this->cache[$k] = Civi::paths()->getUrl($value, 'absolute');
+        return $this->cache[$k];
 
       case 'setting-url-rel':
-        // Array(0 => $type, 1 => $setting, 2 => $default).
         $value = $this->getSettings()->get($name);
-        if (empty($value) && isset($this->map[$k][2])) {
-          $value = $this->map[$k][2];
-        }
-        return Civi::paths()->getUrl($value, 'relative');
+        $this->cache[$k] = Civi::paths()->getUrl($value, 'relative');
+        return $this->cache[$k];
 
       case 'runtime':
         return $this->getRuntime()->{$name};
@@ -242,15 +251,19 @@ class CRM_Core_Config_MagicMerge {
     if (!isset($this->map[$k])) {
       throw new \CRM_Core_Exception("Cannot set unrecognized property CRM_Core_Config::\${$k}");
     }
-    list ($type, $name) = $this->map[$k];
+    unset($this->cache[$k]);
+    $type = $this->map[$k][0];
+    $name = isset($this->map[$k][1]) ? $this->map[$k][1] : $k;
 
     switch ($type) {
       case 'setting':
-        $this->getSettings()->set($name, $v);
-        return;
-
+      case 'setting-path':
+      case 'setting-url-abs':
+      case 'setting-url-rel':
       case 'runtime':
-        $this->getRuntime()->{$name} = $v;
+      case 'callback':
+        // In the past, changes to $config were not persisted automatically.
+        $this->cache[$name] = $v;
         return;
 
       case 'local':
@@ -258,14 +271,6 @@ class CRM_Core_Config_MagicMerge {
         $this->locals[$name] = $v;
         return;
 
-      case 'callback':
-        // Array(0 => $type, 1 => $obj, 2 => $getter, 3 => $setter, 4 => $unsetter).
-        if (!isset($this->map[$k][1], $this->map[$k][3])) {
-          throw new \CRM_Core_Exception("Cannot find setter for property CRM_Core_Config::\${$k}");
-        }
-        \Civi\Core\Resolver::singleton()->call(array($this->map[$k][1], $this->map[$k][3]), array($k, $v));
-        return;
-
       default:
         throw new \CRM_Core_Exception("Cannot set property CRM_Core_Config::\${$k} ($type)");
     }
@@ -279,7 +284,9 @@ class CRM_Core_Config_MagicMerge {
     if (!isset($this->map[$k])) {
       throw new \CRM_Core_Exception("Cannot unset unrecognized property CRM_Core_Config::\${$k}");
     }
-    list ($type, $name) = $this->map[$k];
+    unset($this->cache[$k]);
+    $type = $this->map[$k][0];
+    $name = isset($this->map[$k][1]) ? $this->map[$k][1] : $k;
 
     switch ($type) {
       case 'setting':