From 14a673c61a2779518ec6e02e0b226d8db9e20fc4 Mon Sep 17 00:00:00 2001 From: Eileen McNaughton Date: Fri, 20 Jan 2023 14:16:14 +1300 Subject: [PATCH] Remove interaction with complex legacy getTree function --- CRM/Core/BAO/CustomField.php | 79 ++++++++++++++++++++++++++++++++++++ CRM/Dedupe/Merger.php | 66 ++++++------------------------ 2 files changed, 91 insertions(+), 54 deletions(-) diff --git a/CRM/Core/BAO/CustomField.php b/CRM/Core/BAO/CustomField.php index 7f4aed8d55..9ecbb2359a 100644 --- a/CRM/Core/BAO/CustomField.php +++ b/CRM/Core/BAO/CustomField.php @@ -15,6 +15,8 @@ * @copyright CiviCRM LLC https://civicrm.org/licensing */ +use Civi\Api4\CustomField; + /** * Business objects for managing custom data fields. */ @@ -610,6 +612,83 @@ class CRM_Core_BAO_CustomField extends CRM_Core_DAO_CustomField { return self::$_importFields[$cacheKey]; } + /** + * Get all active custom fields (cached wrapper). + * + * @param false|int $permissionType + * - Either FALSE (do not check) or CRM_Core_Permission::VIEW or CRM_Core_Permission::EDIT + * + * @return array + * List of customField details keyed by customFieldID + * @throws \CRM_Core_Exception + */ + public static function getAllCustomFields($permissionType): array { + if ($permissionType !== FALSE && !is_int($permissionType)) { + throw new CRM_Core_Exception('permissionCheck must be FALSE or CRM_Core_Permission::VIEW or CRM_Core_Permission::EDIT'); + } + $cacheString = __CLASS__ . __FUNCTION__ . CRM_Core_Config::domainID() . '_' . CRM_Core_I18n::getLocale(); + if ($permissionType) { + $cacheString .= 'check_' . $permissionType . '_user_' . CRM_Core_Session::getLoggedInContactID(); + } + if (!Civi::cache('metadata')->has($cacheString)) { + $apiCall = CustomField::get(FALSE) + ->addOrderBy('custom_group_id.title') + ->addOrderBy('custom_group_id.weight') + ->addOrderBy('weight') + ->addOrderBy('label') + ->addSelect('*') + ->addSelect('custom_group_id.extends') + ->addSelect('custom_group_id.extends_entity_column_id') + ->addSelect('custom_group_id.extends_entity_column_value') + ->addSelect('custom_group_id.is_active') + ->addSelect('custom_group_id.name') + ->addSelect('custom_group_id.table_name') + ->addSelect('custom_group_id.is_public'); + if ($permissionType && !CRM_Core_Permission::customGroupAdmin()) { + $availableGroups = CRM_Core_Permission::customGroup($permissionType); + $apiCall->addWhere('custom_group_id', 'IN', empty($availableGroups) ? [0] : $availableGroups); + } + + $types = (array) $apiCall->execute()->indexBy('id'); + + Civi::cache('metadata')->set($cacheString, $types); + } + return Civi::cache('metadata')->get($cacheString); + } + + /** + * Get all active custom fields for the given contact type. + * + * This is formatted as an apiv4 Style array. + * + * @param string $contactType + * @param bool|int $permissionType + * - Either FALSE (do not check) or CRM_Core_Permission::VIEW or CRM_Core_Permission::EDIT + * @param array $contactSubTypes + * + * @return array $fields + * + * @throws \CRM_Core_Exception + */ + public static function getCustomFieldsForContactType(string $contactType, $permissionType, array $contactSubTypes = []): array { + $fields = []; + foreach (self::getAllCustomFields($permissionType) as $field) { + if ($field['custom_group_id.extends'] === $contactType || $field['custom_group_id.extends'] === 'Contact') { + if (empty($contactSubTypes) || empty($field['custom_group_id.extends_entity_column_value'])) { + $fields[$field['id']] = $field; + } + else { + foreach ($contactSubTypes as $contactSubType) { + if (in_array($contactSubType, $field['custom_group_id.extends_entity_column_value'], TRUE)) { + $fields[$field['id']] = $field; + } + } + } + } + } + return $fields; + } + /** * Return field ids and names (with groups). * diff --git a/CRM/Dedupe/Merger.php b/CRM/Dedupe/Merger.php index e0f7be4600..85f5b2a0bc 100644 --- a/CRM/Dedupe/Merger.php +++ b/CRM/Dedupe/Merger.php @@ -2105,34 +2105,29 @@ ORDER BY civicrm_custom_group.weight, 'groupName' => 'postal_greeting', ]; CRM_Core_OptionGroup::lookupValues($submitted, $names, TRUE); - // fix custom fields so they're edible by createProfileContact() - $cFields = self::getCustomFieldMetadata($contactType); if (!isset($submitted)) { $submitted = []; } + + // Move view only custom fields CRM-5362 + $viewOnlyCustomFields = []; foreach ($submitted as $key => $value) { if (strpos($key, 'custom_') === 0) { $fieldID = (int) substr($key, 7); - if (empty($cFields[$fieldID])) { - $htmlType = $cFields[$fieldID]['attributes']['html_type']; - $isSerialized = CRM_Core_BAO_CustomField::isSerialized($cFields[$fieldID]['attributes']); - $isView = $cFields[$fieldID]['attributes']['is_view']; + $fieldMetadata = CRM_Core_BAO_CustomField::getCustomFieldsForContactType($contactType, FALSE)[$fieldID] ?? NULL; + if ($fieldMetadata) { + $htmlType = $fieldMetadata['html_type']; + $isSerialized = CRM_Core_BAO_CustomField::isSerialized($fieldMetadata); + $isView = $fieldMetadata['is_view']; + if ($isView) { + $viewOnlyCustomFields[$key] = $value; + } $submitted = self::processCustomFields($mainId, $key, $submitted, $value, $fieldID, $isView, $htmlType, $isSerialized); - } } } - // move view only custom fields CRM-5362 - $viewOnlyCustomFields = []; - foreach ($submitted as $key => $value) { - $fid = CRM_Core_BAO_CustomField::getKeyID($key); - if ($fid && array_key_exists($fid, $cFields) && !empty($cFields[$fid]['attributes']['is_view']) - ) { - $viewOnlyCustomFields[$key] = $value; - } - } // special case to set values for view only, CRM-5362 if (!empty($viewOnlyCustomFields)) { $viewOnlyCustomFields['entityID'] = $mainId; @@ -2149,7 +2144,7 @@ ORDER BY civicrm_custom_group.weight, 'return' => ['created_date'], ])['created_date']; if ($otherCreatedDate < $mainCreatedDate && !empty($otherCreatedDate)) { - CRM_Core_DAO::executeQuery("UPDATE civicrm_contact SET created_date = %1 WHERE id = %2", [ + CRM_Core_DAO::executeQuery('UPDATE civicrm_contact SET created_date = %1 WHERE id = %2', [ 1 => [$otherCreatedDate, 'String'], 2 => [$mainId, 'Positive'], ]); @@ -2612,43 +2607,6 @@ ORDER BY civicrm_custom_group.weight, return $submitted; } - /** - * Get metadata for the custom fields for the merge. - * - * @param string $contactType - * - * @return array - * @throws \CRM_Core_Exception - */ - protected static function getCustomFieldMetadata($contactType) { - $treeCache = []; - if (!array_key_exists($contactType, $treeCache)) { - $treeCache[$contactType] = CRM_Core_BAO_CustomGroup::getTree( - $contactType, - NULL, - NULL, - -1, - [], - NULL, - TRUE, - NULL, - FALSE, - FALSE - ); - } - - $cFields = []; - foreach ($treeCache[$contactType] as $key => $group) { - if (!isset($group['fields'])) { - continue; - } - foreach ($group['fields'] as $fid => $field) { - $cFields[$fid]['attributes'] = $field; - } - } - return $cFields; - } - /** * Get conflicts for proposed merge pair. * -- 2.25.1