[NFC] towards CRM-19840 & others, load date metadata for custom & core profile fields.
authoreileen <emcnaughton@wikimedia.org>
Thu, 16 Feb 2017 03:41:26 +0000 (16:41 +1300)
committereileen <emcnaughton@wikimedia.org>
Thu, 16 Feb 2017 03:41:26 +0000 (16:41 +1300)
This is further NFC change towards CRM-19840 and a range of other date fixes. It ensures that date data is available on date fields
allowing us to reduce code elsewhere

CRM/Core/BAO/UFGroup.php
CRM/Core/Form.php
CRM/Utils/Date.php
CRM/Utils/Type.php

index 3927476d2369c9683e4f680b223b5ac4ece211c3..a1edbefeab13b2034b67c89ef4aaca27a8fe2213 100644 (file)
@@ -476,6 +476,7 @@ class CRM_Core_BAO_UFGroup extends CRM_Core_DAO_UFGroup {
     if (isset($field->phone_type_id)) {
       $name .= "-{$field->phone_type_id}";
     }
+    $fieldMetaData = CRM_Utils_Array::value($name, $importableFields, (isset($importableFields[$field->field_name]) ? $importableFields[$field->field_name] : array()));
 
     // No lie: this is bizarre; why do we need to mix so many UFGroup properties into UFFields?
     // I guess to make field self sufficient with all the required data and avoid additional calls
@@ -513,8 +514,11 @@ class CRM_Core_BAO_UFGroup extends CRM_Core_DAO_UFGroup {
         CRM_Utils_Array::value($field->field_name, $importableFields)
       ),
       'skipDisplay' => 0,
+      'data_type' => CRM_Utils_Type::getDataTypeFromFieldMetadata($fieldMetaData),
     );
 
+    $formattedField = CRM_Utils_Date::addDateMetadataToField($fieldMetaData, $formattedField);
+
     //adding custom field property
     if (substr($field->field_name, 0, 6) == 'custom' ||
       substr($field->field_name, 0, 14) === 'address_custom'
@@ -525,12 +529,16 @@ class CRM_Core_BAO_UFGroup extends CRM_Core_DAO_UFGroup {
         $formattedField['is_search_range'] = $customFields[$field->field_name]['is_search_range'];
         // fix for CRM-1994
         $formattedField['options_per_line'] = $customFields[$field->field_name]['options_per_line'];
-        $formattedField['data_type'] = $customFields[$field->field_name]['data_type'];
         $formattedField['html_type'] = $customFields[$field->field_name]['html_type'];
 
         if (CRM_Utils_Array::value('html_type', $formattedField) == 'Select Date') {
           $formattedField['date_format'] = $customFields[$field->field_name]['date_format'];
           $formattedField['time_format'] = $customFields[$field->field_name]['time_format'];
+          $formattedField['php_datetime_format'] = CRM_Utils_Date::getPhpDateFormatFromInputStyleDateFormat($customFields[$field->field_name]['date_format']);
+          if ($formattedField['time_format']) {
+            $formattedField['php_datetime_format'] .= ' H-i-s';
+          }
+          $formattedField['is_datetime_field'] = TRUE;
         }
 
         $formattedField['is_multi_summary'] = $field->is_multi_summary;
index fadce93d65a196bd7b2ed04ebe999ddccfe49726..68d4ceabea4575ac43618b789175d68075324b29 100644 (file)
@@ -337,6 +337,8 @@ class CRM_Core_Form extends HTML_QuickForm_Page {
    * @param bool $required
    * @param array $extra
    *   (attributes for select elements).
+   *   For datepicker elements this is consistent with the data
+   *   from CRM_Utils_Date::getDatePickerExtra
    *
    * @return HTML_QuickForm_Element
    *   Could be an error object
index 2f2a17d055b0ad9af5273abdf0a17c405783676a..80dd413f30a579524fd3aa1cf90f4570a6d2fb10 100644 (file)
@@ -1741,6 +1741,106 @@ class CRM_Utils_Date {
     return $mysqlDate;
   }
 
+  /**
+   * Convert a Civi-special date string to a standard php date string.
+   *
+   * For historical reasons CiviCRM has it's own (possibly Smarty derived)
+   * format for defined date strings. This renders something php can use.
+   *
+   * @param string $dateFormatString
+   *   e.g mm/dd/yy
+   *   These map to the values used in the date_format field in civicrm_custom_field.date_format.
+   *
+   * @return string
+   *   A proper php strotime formatted equivalent of the string.
+   *   eg m/d/y for the above.
+   *
+   *   http://php.net/manual/en/function.strtotime.php
+   */
+  public static function getPhpDateFormatFromInputStyleDateFormat($dateFormatString) {
+    $formats = CRM_Core_SelectValues::datePluginToPHPFormats();
+    return $formats[$dateFormatString];
+  }
+
+  /**
+   * Add the metadata about a date field to the field.
+   *
+   * This metadata will work with the call $form->add('datepicker', ...
+   *
+   * @param array $fieldMetaData
+   * @param array $field
+   *
+   * @return array
+   */
+  public static function addDateMetadataToField($fieldMetaData, $field) {
+    if (isset($fieldMetaData['html'])) {
+      $field['html_type'] = $fieldMetaData['html']['type'];
+      if ($field['html_type'] === 'Select Date' && !isset($field['date_format'])) {
+        $dateAttributes = CRM_Core_SelectValues::date($fieldMetaData['html']['formatType'], NULL, NULL, NULL, 'Input');
+        $field['start_date_years'] = $dateAttributes['minYear'];
+        $field['end_date_years'] = $dateAttributes['maxYear'];
+        $field['date_format'] = $dateAttributes['format'];
+        $field['is_datetime_field'] = TRUE;
+        $field['time_format'] = $dateAttributes['time'];
+        $field['php_datetime_format'] = CRM_Utils_Date::getPhpDateFormatFromInputStyleDateFormat($field['date_format']);
+        if ($field['time_format']) {
+          $field['php_datetime_format'] .= ' H-i-s';
+        }
+      }
+      $field['datepicker']['extra'] = self::getDatePickerExtra($field);
+      $field['datepicker']['attributes'] = self::getDatePickerAttributes($field);
+    }
+    return $field;
+  }
+
+
+  /**
+   * Get the fields required for the 'extra' parameter when adding a datepicker.
+   *
+   * @param array $field
+   *
+   * @return array
+   */
+  public static function getDatePickerExtra($field) {
+    $extra = array();
+    if (isset($field['date_format'])) {
+      $extra['date'] = $field['date_format'];
+      $extra['time'] = $field['time_format'];
+    }
+    $thisYear = date('Y');
+    if (isset($field['start_date_years'])) {
+      $extra['minDate'] = date('Y-m-d', strtotime('-' . ($thisYear - $field['start_date_years']) . ' years'));
+    }
+    if (isset($field['end_date_years'])) {
+      $extra['maxDate'] = date('Y-m-d', strtotime('-' . ($thisYear - $field['end_date_years']) . ' years'));
+    }
+    return $extra;
+  }
+
+  /**
+   * Get the attributes parameters required for datepicker.
+   *
+   * @param array $field
+   *   Field metadata
+   *
+   * @return array
+   *   Array ready to pass to $this->addForm('datepicker' as attributes.
+   */
+  public static function getDatePickerAttributes(&$field) {
+    $attributes = array();
+    $dateAttributes = array(
+      'start_date_years' => 'minYear',
+      'end_date_years' => 'maxYear',
+      'date_format' => 'format',
+    );
+    foreach ($dateAttributes as $dateAttribute => $mapTo) {
+      if (isset($field[$dateAttribute])) {
+        $attributes[$mapTo] = $field[$dateAttribute];
+      }
+    }
+    return $attributes;
+  }
+
   /**
    * Function to convert mysql to date plugin format.
    *
index c782e5cec5a6c8574bba69db091b1d3bdb82271d..65b726c98f04b7353ed46b90b424d2060dba5aec 100644 (file)
@@ -143,6 +143,28 @@ class CRM_Utils_Type {
     return (isset($string)) ? $string : "";
   }
 
+  /**
+   * Get the data_type for the field.
+   *
+   * @param array $fieldMetadata
+   *   Metadata about the field.
+   *
+   * @return string
+   */
+  public static function getDataTypeFromFieldMetadata($fieldMetadata) {
+    if (isset($fieldMetadata['data_type'])) {
+      return $fieldMetadata['data_type'];
+    }
+    if (empty($fieldMetadata['type'])) {
+      // I would prefer to throw an e-notice but there is some,
+      // probably unnecessary logic, that only retrieves activity fields
+      // if they are 'in the profile' and probably they are not 'in'
+      // until they are added - which might lead to ? who knows!
+      return '';
+    }
+    return self::typeToString($fieldMetadata['type']);
+  }
+
   /**
    * Helper function to call escape on arrays.
    *