From d86e674f0302e00cc2827e50d224349a9ea4b631 Mon Sep 17 00:00:00 2001 From: eileen Date: Thu, 16 Feb 2017 16:41:26 +1300 Subject: [PATCH] [NFC] towards CRM-19840 & others, load date metadata for custom & core profile fields. 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 | 10 +++- CRM/Core/Form.php | 2 + CRM/Utils/Date.php | 100 +++++++++++++++++++++++++++++++++++++++ CRM/Utils/Type.php | 22 +++++++++ 4 files changed, 133 insertions(+), 1 deletion(-) diff --git a/CRM/Core/BAO/UFGroup.php b/CRM/Core/BAO/UFGroup.php index 3927476d23..a1edbefeab 100644 --- a/CRM/Core/BAO/UFGroup.php +++ b/CRM/Core/BAO/UFGroup.php @@ -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; diff --git a/CRM/Core/Form.php b/CRM/Core/Form.php index fadce93d65..68d4ceabea 100644 --- a/CRM/Core/Form.php +++ b/CRM/Core/Form.php @@ -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 diff --git a/CRM/Utils/Date.php b/CRM/Utils/Date.php index 2f2a17d055..80dd413f30 100644 --- a/CRM/Utils/Date.php +++ b/CRM/Utils/Date.php @@ -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. * diff --git a/CRM/Utils/Type.php b/CRM/Utils/Type.php index c782e5cec5..65b726c98f 100644 --- a/CRM/Utils/Type.php +++ b/CRM/Utils/Type.php @@ -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. * -- 2.25.1