Update Copywrite year to be 2019
[civicrm-core.git] / CRM / Admin / Form / SettingTrait.php
index 4ecd397a459127fdf6404e0aac11e8e87b7d8744..bbc755092621ec79714e44f1b2f8f4bd1ce817e9 100644 (file)
@@ -3,7 +3,7 @@
  +--------------------------------------------------------------------+
  | CiviCRM version 5                                                  |
  +--------------------------------------------------------------------+
- | Copyright CiviCRM LLC (c) 2004-2018                                |
+ | Copyright CiviCRM LLC (c) 2004-2019                                |
  +--------------------------------------------------------------------+
  | This file is a part of CiviCRM.                                    |
  |                                                                    |
@@ -28,7 +28,7 @@
 /**
  *
  * @package CRM
- * @copyright CiviCRM LLC (c) 2004-2018
+ * @copyright CiviCRM LLC (c) 2004-2019
  */
 
 /**
@@ -74,7 +74,16 @@ trait CRM_Admin_Form_SettingTrait {
    * @return array
    */
   protected function getSettingsToSetByMetadata($params) {
-    return array_intersect_key($params, $this->_settings);
+    $setValues = array_intersect_key($params, $this->_settings);
+    // Checkboxes will be unset rather than empty so we need to add them back in.
+    // Handle quickform hateability just once, right here right now.
+    $unsetValues = array_diff_key($this->_settings, $params);
+    foreach ($unsetValues as $key => $unsetValue) {
+      if ($this->getQuickFormType($this->getSettingMetadata($key)) === 'CheckBox') {
+        $setValues[$key] = [$key => 0];
+      }
+    }
+    return $setValues;
   }
 
   /**
@@ -116,39 +125,42 @@ trait CRM_Admin_Form_SettingTrait {
     $settingMetaData = $this->getSettingsMetaData();
     $descriptions = [];
     foreach ($settingMetaData as $setting => $props) {
-      if (isset($props['quick_form_type'])) {
+      $quickFormType = $this->getQuickFormType($props);
+      if (isset($quickFormType)) {
+        $options = CRM_Utils_Array::value('options', $props);
         if (isset($props['pseudoconstant'])) {
           $options = civicrm_api3('Setting', 'getoptions', [
             'field' => $setting,
-          ]);
+          ])['values'];
         }
-        else {
-          $options = NULL;
+        if ($props['type'] === 'Boolean') {
+          $options = [$props['title'] => $props['name']];
         }
+
         //Load input as readonly whose values are overridden in civicrm.settings.php.
         if (Civi::settings()->getMandatory($setting)) {
           $props['html_attributes']['readonly'] = TRUE;
           $this->includesReadOnlyFields = TRUE;
         }
 
-        $add = 'add' . $props['quick_form_type'];
+        $add = 'add' . $quickFormType;
         if ($add == 'addElement') {
           $this->$add(
             $props['html_type'],
             $setting,
             ts($props['title']),
-            ($options !== NULL) ? $options['values'] : CRM_Utils_Array::value('html_attributes', $props, []),
+            ($options !== NULL) ? $options : CRM_Utils_Array::value('html_attributes', $props, []),
             ($options !== NULL) ? CRM_Utils_Array::value('html_attributes', $props, []) : NULL
           );
         }
         elseif ($add == 'addSelect') {
-          $this->addElement('select', $setting, ts($props['title']), $options['values'], CRM_Utils_Array::value('html_attributes', $props));
+          $this->addElement('select', $setting, ts($props['title']), $options, CRM_Utils_Array::value('html_attributes', $props));
         }
         elseif ($add == 'addCheckBox') {
-          $this->addCheckBox($setting, ts($props['title']), $options['values'], NULL, CRM_Utils_Array::value('html_attributes', $props), NULL, NULL, ['  ']);
+          $this->addCheckBox($setting, '', $options, NULL, CRM_Utils_Array::value('html_attributes', $props), NULL, NULL, ['  ']);
         }
         elseif ($add == 'addCheckBoxes') {
-          $options = array_flip($options['values']);
+          $options = array_flip($options);
           $newOptions = [];
           foreach ($options as $key => $val) {
             $newOptions[$key] = $val;
@@ -168,12 +180,19 @@ trait CRM_Admin_Form_SettingTrait {
         elseif ($add == 'addMonthDay') {
           $this->add('date', $setting, ts($props['title']), CRM_Core_SelectValues::date(NULL, 'M d'));
         }
+        elseif ($add === 'addEntityRef') {
+          $this->$add($setting, ts($props['title']), $props['entity_reference_options']);
+        }
+        elseif ($add === 'addYesNo' && ($props['type'] === 'Boolean')) {
+          $this->addRadio($setting, ts($props['title']), array(1 => 'Yes', 0 => 'No'), NULL, '  ');
+        }
         else {
-          $this->$add($setting, ts($props['title']));
+          $this->$add($setting, ts($props['title']), $options);
         }
         // Migrate to using an array as easier in smart...
-        $descriptions[$setting] = ts($props['description']);
-        $this->assign("{$setting}_description", ts($props['description']));
+        $description = CRM_Utils_Array::value('description', $props);
+        $descriptions[$setting] = $description;
+        $this->assign("{$setting}_description", $description);
         if ($setting == 'max_attachments') {
           //temp hack @todo fix to get from metadata
           $this->addRule('max_attachments', ts('Value should be a positive number'), 'positiveInteger');
@@ -188,9 +207,42 @@ trait CRM_Admin_Form_SettingTrait {
     // setting_description should be deprecated - see Mail.tpl for metadata based tpl.
     $this->assign('setting_descriptions', $descriptions);
     $this->assign('settings_fields', $settingMetaData);
+    $this->assign('fields', $settingMetaData);
   }
 
+  /**
+   * Get the quickform type for the given html type.
+   *
+   * @param array $spec
+   *
+   * @return string
+   */
+  protected function getQuickFormType($spec) {
+    if (isset($spec['quick_form_type']) &&
+    !($spec['quick_form_type'] === 'Element' && !empty($spec['html_type']))) {
+      // This is kinda transitional
+      return $spec['quick_form_type'];
+    }
 
+    // The spec for settings has been updated for consistency - we provide deprecation notices for sites that have
+    // not made this change.
+    $htmlType = $spec['html_type'];
+    if ($htmlType !== strtolower($htmlType)) {
+      CRM_Core_Error::deprecatedFunctionWarning(ts('Settings fields html_type should be lower case - see https://docs.civicrm.org/dev/en/latest/framework/setting/ - this needs to be fixed for ' . $spec['name']));
+      $htmlType = strtolower($spec['html_type']);
+    }
+    $mapping = [
+      'checkboxes' => 'CheckBoxes',
+      'checkbox' => 'CheckBox',
+      'radio' => 'Radio',
+      'select' => 'Select',
+      'textarea' => 'Element',
+      'text' => 'Element',
+      'entity_reference' => 'EntityRef',
+      'advmultiselect' => 'Element',
+    ];
+    return $mapping[$htmlType];
+  }
   /**
    * Get the defaults for all fields defined in the metadata.
    *
@@ -204,9 +256,12 @@ trait CRM_Admin_Form_SettingTrait {
       if (!empty($spec['serialize'])) {
         $this->_defaults[$setting] = CRM_Core_DAO::unSerializeField($this->_defaults[$setting], $spec['serialize']);
       }
-      if ($spec['quick_form_type'] === 'CheckBoxes') {
+      if ($this->getQuickFormType($spec) === 'CheckBoxes') {
         $this->_defaults[$setting] = array_fill_keys($this->_defaults[$setting], 1);
       }
+      if ($this->getQuickFormType($spec) === 'CheckBox') {
+        $this->_defaults[$setting] = [$setting => $this->_defaults[$setting]];
+      }
     }
   }
 
@@ -217,9 +272,13 @@ trait CRM_Admin_Form_SettingTrait {
   protected function saveMetadataDefinedSettings($params) {
     $settings = $this->getSettingsToSetByMetadata($params);
     foreach ($settings as $setting => $settingValue) {
-      if ($this->getSettingMetadataItem($setting, 'quick_form_type') === 'CheckBoxes') {
+      if ($this->getQuickFormType($this->getSettingMetadata($setting)) === 'CheckBoxes') {
         $settings[$setting] = array_keys($settingValue);
       }
+      if ($this->getQuickFormType($this->getSettingMetadata($setting)) === 'CheckBox') {
+        // This will be an array with one value.
+        $settings[$setting] = (int) reset($settings[$setting]);
+      }
     }
     civicrm_api3('setting', 'create', $settings);
   }