From 3b66f502a51aab10e91264b9ac9d12ef08fb8992 Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Mon, 14 Dec 2015 21:21:01 -0500 Subject: [PATCH] CRM-17646 - CustomField displayValue refactoring --- CRM/Core/BAO/CustomField.php | 238 +++++++++++++++++------------------ CRM/Core/PseudoConstant.php | 3 +- 2 files changed, 116 insertions(+), 125 deletions(-) diff --git a/CRM/Core/BAO/CustomField.php b/CRM/Core/BAO/CustomField.php index e6764f9697..6110650326 100644 --- a/CRM/Core/BAO/CustomField.php +++ b/CRM/Core/BAO/CustomField.php @@ -57,6 +57,11 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField { */ public static $_importFields = NULL; + /** + * @var array + */ + public static $displayInfoCache = array(); + /** * Build and retrieve the list of data types and descriptions. * @@ -366,9 +371,8 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField { * @param string $context * @return array|bool */ - public function getOptions($context = 'get') { + public function getOptions($context = NULL) { CRM_Core_DAO::buildOptionsContext($context); - $options = FALSE; if (!$this->id) { return FALSE; @@ -387,16 +391,17 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField { !($context == 'validate' || $context == 'get') ); } + elseif ($this->data_type === 'StateProvince') { + $options = CRM_Core_Pseudoconstant::stateProvince(); + } + elseif ($this->data_type === 'Country') { + $options = $context == 'validate' ? CRM_Core_Pseudoconstant::countryIsoCode() : CRM_Core_Pseudoconstant::country(); + } + elseif ($this->data_type === 'Boolean') { + $options = $context == 'validate' ? array(0, 1) : CRM_Core_SelectValues::boolean(); + } else { - if ($this->data_type === 'StateProvince') { - $options = CRM_Core_Pseudoconstant::stateProvince(); - } - elseif ($this->data_type === 'Country') { - $options = $context == 'validate' ? CRM_Core_Pseudoconstant::countryIsoCode() : CRM_Core_Pseudoconstant::country(); - } - elseif ($this->data_type === 'Boolean') { - $options = $context == 'validate' ? array(0, 1) : CRM_Core_SelectValues::boolean(); - } + return false; } CRM_Utils_Hook::customFieldOptions($this->id, $options, FALSE); $entity = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomGroup', $this->custom_group_id, 'extends'); @@ -1141,30 +1146,52 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField { } /** - * Find the display value for this field. + * @param string|int|array|null $value + * @param CRM_Core_BAO_CustomField|int $field + * @param $contactId + * + * @return array|int|null|string + */ + public static function displayValue($value, $field, $contactId = NULL) { + $fieldId = is_object($field) ? $field->id : $field; + + if (!isset(self::$displayInfoCache[$fieldId])) { + if (!is_a($field, 'CRM_Core_BAO_CustomField')) { + $field = new CRM_Core_BAO_CustomField(); + $field->id = $fieldId; + } + $options = $field->getOptions(); + self::$displayInfoCache[$fieldId] = array( + 'id' => $fieldId, + 'html_type' => $field->html_type, + 'data_type' => $field->data_type, + 'options' => $options, + ); + } + return self::formatDisplayValue($value, self::$displayInfoCache[$fieldId], $contactId); + } + + /** + * Legacy display value getter. + * + * @deprecated * * @param mixed $value * The custom field value. - * @param int $id + * @param int $fieldID * The custom field id. * @param array $options * The assoc array of option name/value pairs. - * * @param int $contactID - * @param int $fieldID * * @return string * the display value */ - public static function getDisplayValue($value, $id, &$options, $contactID = NULL, $fieldID = NULL) { - $option = &$options[$id]; + public static function getDisplayValue($value, $fieldID, &$options, $contactID = NULL) { + $option = &$options[$fieldID]; $attributes = &$option['attributes']; $html_type = $attributes['html_type']; $data_type = $attributes['data_type']; - // set $id as $fieldID if not passed in the params. - if (empty($fieldID)) { - $fieldID = $id; - } return self::getDisplayValueCommon($value, $option, @@ -1176,7 +1203,9 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField { } /** - * Get display value. + * Legacy display value formatter. + * + * @deprecated * * @param string $value * @param array $option @@ -1189,13 +1218,12 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField { */ public static function getDisplayValueCommon( $value, - &$option, + $option, $html_type, $data_type, $contactID = NULL, $fieldID = NULL ) { - $display = $value; if ($fieldID && (($html_type == 'Radio' && $data_type != 'Boolean') || @@ -1209,86 +1237,74 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField { CRM_Utils_Hook::customFieldOptions($fieldID, $option); } - switch ($html_type) { - case 'Radio': - if ($data_type == 'Boolean') { - $options = array('No', 'Yes'); - } - else { - $options = $option; - } - if (is_array($value)) { - $display = NULL; - foreach ($value as $data) { - $display .= $display ? ', ' . $options[$data] : $options[$data]; - } - } - else { - $display = CRM_Utils_Array::value($value, $options); - } - break; + if ($data_type == 'Boolean') { + $option = CRM_Core_SelectValues::boolean(); + } - case 'Autocomplete-Select': - if ($data_type == 'ContactReference' && - $value - ) { - $display = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $value, 'display_name'); - } - elseif (is_array($value)) { - $display = NULL; - foreach ($value as $data) { - $display .= $display ? ', ' . $option[$data] : $option[$data]; - } - } - else { - $display = CRM_Utils_Array::value($value, $option); - } - break; + if ($data_type == 'Country') { + $option = CRM_Core_PseudoConstant::country(FALSE, FALSE); + } + + if ($data_type == 'StateProvince') { + $option = CRM_Core_PseudoConstant::stateProvince(FALSE, FALSE); + } + + $field = array( + 'id' => $fieldID, + 'html_type' => $html_type, + 'data_type' => $data_type, + 'options' => $option, + ); + + return self::formatDisplayValue($value, $field, $contactID); + } - case 'Select': - if (is_array($value)) { - $display = NULL; - foreach ($value as $data) { - $display .= $display ? ', ' . $option[$data] : $option[$data]; - } - } - else { - $display = CRM_Utils_Array::value($value, $option); - } - break; + /** + * Lower-level logic for rendering a custom field value + * + * @param string|array $value + * @param array $field + * @param int|null $contactID + * + * @return string|array|int|null + */ + private static function formatDisplayValue($value, $field, $contactID = NULL) { + $display = $value; + + if (self::isSerialized($field) && !is_array($value)) { + $value = (array) CRM_Utils_Array::explodePadded($value); + } + // CRM-12989 fix + if ($field['html_type'] == 'CheckBox') { + CRM_Utils_Array::formatArrayKeys($value); + } + + switch ($field['html_type']) { + + case 'Select': + case 'Autocomplete-Select': + case 'Radio': + case 'Select Country': + case 'Select State/Province': case 'CheckBox': case 'AdvMulti-Select': case 'Multi-Select': - if (is_array($value)) { - if ($html_type == 'CheckBox') { - // CRM-12989 fix - CRM_Utils_Array::formatArrayKeys($value); - } - - $checkedData = $value; + case 'Multi-Select State/Province': + case 'Multi-Select Country': + if ($field['data_type'] == 'ContactReference' && $value) { + $display = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $value, 'display_name'); } - else { - $checkedData = explode(CRM_Core_DAO::VALUE_SEPARATOR, - substr($value, 1, -1) - ); - if ($html_type == 'CheckBox') { - $newData = array(); - foreach ($checkedData as $v) { - $v = str_replace(CRM_Core_DAO::VALUE_SEPARATOR, '', $v); - $newData[] = $v; - } - $checkedData = $newData; + elseif (is_array($value)) { + $v = array(); + foreach ($value as $key => $val) { + $v[] = CRM_Utils_Array::value($val, $field['options']); } - } - - $v = array(); - foreach ($checkedData as $key => $val) { - $v[] = CRM_Utils_Array::value($val, $option); - } - if (!empty($v)) { $display = implode(', ', $v); } + else { + $display = CRM_Utils_Array::value($value, $field['options']); + } break; case 'Select Date': @@ -1299,38 +1315,17 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField { } else { // remove time element display if time is not set - if (empty($option['attributes']['time_format'])) { + if (empty($field['options']['attributes']['time_format'])) { $value = substr($value, 0, 10); } $display = CRM_Utils_Date::customFormat($value); } break; - case 'Select State/Province': - case 'Multi-Select State/Province': - case 'Select Country': - case 'Multi-Select Country': - if (strstr($html_type, 'State/Province')) { - $option = CRM_Core_PseudoConstant::stateProvince(FALSE, FALSE); - } - else { - $option = CRM_Core_PseudoConstant::country(FALSE, FALSE); - } - // process multi-select state/country field values - if (!is_array($value)) { - $value = explode(CRM_Core_DAO::VALUE_SEPARATOR, $value); - } - - $display = NULL; - foreach ($value as $data) { - $display .= ($display && !empty($option[$data])) ? ', ' . $option[$data] : $option[$data]; - } - break; - case 'File': // In the context of displaying a profile, show file/image if ($contactID && $value) { - $url = self::getFileURL($contactID, $fieldID, $value); + $url = self::getFileURL($contactID, $field['id'], $value); if ($url) { $display = $url['file_url']; } @@ -1353,12 +1348,7 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField { case 'Link': case 'Text': - if (empty($value)) { - $display = ''; - } - else { - $display = is_array($value) ? implode(', ', $value) : $value; - } + $display = is_array($value) ? implode(', ', $value) : $value; } return $display ? $display : $value; } @@ -2501,7 +2491,7 @@ WHERE cf.id = %1 AND cg.is_multiple = 1"; } /** - * Get options for field. + * Set pseudoconstant properties for field metadata. * * @param array $field * @param string|null $optionGroupName diff --git a/CRM/Core/PseudoConstant.php b/CRM/Core/PseudoConstant.php index 4734ff0b23..93a0ad2e73 100644 --- a/CRM/Core/PseudoConstant.php +++ b/CRM/Core/PseudoConstant.php @@ -407,7 +407,7 @@ class CRM_Core_PseudoConstant { // Return "Yes" and "No" for boolean fields elseif (CRM_Utils_Array::value('type', $fieldSpec) === CRM_Utils_Type::T_BOOLEAN) { - $output = $context == 'validate' ? array(0, 1) : array(1 => ts('Yes'), 0 => ts('No')); + $output = $context == 'validate' ? array(0, 1) : CRM_Core_SelectValues::boolean(); CRM_Utils_Hook::fieldOptions($entity, $fieldName, $output, $params); return $flip ? array_flip($output) : $output; } @@ -591,6 +591,7 @@ class CRM_Core_PseudoConstant { } if ($name == 'cache') { CRM_Core_OptionGroup::flushAll(); + CRM_Core_BAO_CustomField::$displayInfoCache = array(); } } -- 2.25.1