From 152f6da6b4270c18a48919e25ff3efc0f8f350e8 Mon Sep 17 00:00:00 2001 From: Eileen McNaughton Date: Thu, 6 Jan 2022 15:26:07 +1300 Subject: [PATCH] Duplicate legacyCreateMultiple to contact_utils Having a lot of trouble fixing a bug via this method so gonn break up & clean up the function in this context (leaves on the import class & a JMA extension calling it. --- CRM/Contact/BAO/Contact/Utils.php | 129 +++++++++++++++++++++++++++++- CRM/Contact/BAO/Relationship.php | 5 ++ 2 files changed, 133 insertions(+), 1 deletion(-) diff --git a/CRM/Contact/BAO/Contact/Utils.php b/CRM/Contact/BAO/Contact/Utils.php index b70eee50af..6e7fdaa6d8 100644 --- a/CRM/Contact/BAO/Contact/Utils.php +++ b/CRM/Contact/BAO/Contact/Utils.php @@ -290,7 +290,7 @@ WHERE id IN ( $idString ) 'contact_check' => [$organization => TRUE], ]; list($valid, $invalid, $duplicate, $saved, $relationshipIds) - = CRM_Contact_BAO_Relationship::legacyCreateMultiple($relationshipParams, $cid); + = self::legacyCreateMultiple($relationshipParams, $cid); // In case we change employer, clean previous employer related records. if (!$previousEmployerID && !$newContact) { @@ -311,6 +311,133 @@ WHERE id IN ( $idString ) } } + /** + * Previously shared function in need of cleanup. + * + * Takes an associative array and creates a relationship object. + * + * @deprecated For single creates use the api instead (it's tested). + * For multiple a new variant of this function needs to be written and migrated to as this is a bit + * nasty + * + * @param array $params + * (reference ) an assoc array of name/value pairs. + * @param array $ids + * The array that holds all the db ids. + * per http://wiki.civicrm.org/confluence/display/CRM/Database+layer + * "we are moving away from the $ids param " + * + * @return array + * @throws \CRM_Core_Exception + */ + private static function legacyCreateMultiple(&$params, $ids = []) { + $valid = $invalid = $duplicate = $saved = 0; + $relationships = $relationshipIds = []; + $relationshipId = CRM_Utils_Array::value('relationship', $ids, CRM_Utils_Array::value('id', $params)); + + //CRM-9015 - the hooks are called here & in add (since add doesn't call create) + // but in future should be tidied per ticket + if (empty($relationshipId)) { + $hook = 'create'; + } + else { + $hook = 'edit'; + } + + // @todo pre hook is called from add - remove it from here + CRM_Utils_Hook::pre($hook, 'Relationship', $relationshipId, $params); + + if (!$relationshipId) { + // creating a new relationship + $dataExists = CRM_Contact_BAO_Relationship::dataExists($params); + if (!$dataExists) { + return [FALSE, TRUE, FALSE, FALSE, NULL]; + } + $relationshipIds = []; + foreach ($params['contact_check'] as $key => $value) { + // check if the relationship is valid between contacts. + // step 1: check if the relationship is valid if not valid skip and keep the count + // step 2: check the if two contacts already have a relationship if yes skip and keep the count + // step 3: if valid relationship then add the relation and keep the count + + // step 1 + $contactFields = CRM_Contact_BAO_Relationship::setContactABFromIDs($params, $ids, $key); + $errors = CRM_Contact_BAO_Relationship::checkValidRelationship($contactFields, $ids, $key); + if ($errors) { + $invalid++; + continue; + } + + //CRM-16978:check duplicate relationship as per case id. + if ($caseId = CRM_Utils_Array::value('case_id', $params)) { + $contactFields['case_id'] = $caseId; + } + if ( + CRM_Contact_BAO_Relationship::checkDuplicateRelationship( + $contactFields, + CRM_Utils_Array::value('contact', $ids), + // step 2 + $key + ) + ) { + $duplicate++; + continue; + } + + $singleInstanceParams = array_merge($params, $contactFields); + $relationship = CRM_Contact_BAO_Relationship::add($singleInstanceParams); + $relationshipIds[] = $relationship->id; + $relationships[$relationship->id] = $relationship; + $valid++; + } + // editing the relationship + } + else { + // check for duplicate relationship + // @todo this code doesn't cope well with updates - causes e-Notices. + // API has a lot of code to work around + // this but should review this code & remove the extra handling from the api + // it seems doubtful any of this is relevant if the contact fields & relationship + // type fields are not set + if ( + CRM_Contact_BAO_Relationship::checkDuplicateRelationship( + $params, + CRM_Utils_Array::value('contact', $ids), + $ids['contactTarget'], + $relationshipId + ) + ) { + $duplicate++; + return [$valid, $invalid, $duplicate, $saved, NULL]; + } + + $validContacts = TRUE; + //validate contacts in update mode also. + $contactFields = CRM_Contact_BAO_Relationship::setContactABFromIDs($params, $ids, $ids['contactTarget']); + if (!empty($ids['contact']) && !empty($ids['contactTarget'])) { + if (CRM_Contact_BAO_Relationship::checkValidRelationship($contactFields, $ids, $ids['contactTarget'])) { + $validContacts = FALSE; + $invalid++; + } + } + if ($validContacts) { + // editing an existing relationship + $singleInstanceParams = array_merge($params, $contactFields); + $relationship = CRM_Contact_BAO_Relationship::add($singleInstanceParams, $ids, $ids['contactTarget']); + $relationshipIds[] = $relationship->id; + $relationships[$relationship->id] = $relationship; + $saved++; + } + } + + // do not add to recent items for import, CRM-4399 + if (!(!empty($params['skipRecentView']) || $invalid || $duplicate)) { + CRM_Contact_BAO_Relationship::addRecent($params, $relationship); + } + + return [$valid, $invalid, $duplicate, $saved, $relationshipIds, $relationships]; + } + /** * Create related memberships for current employer. * diff --git a/CRM/Contact/BAO/Relationship.php b/CRM/Contact/BAO/Relationship.php index 4c968676ba..dd94e3daa2 100644 --- a/CRM/Contact/BAO/Relationship.php +++ b/CRM/Contact/BAO/Relationship.php @@ -141,6 +141,11 @@ class CRM_Contact_BAO_Relationship extends CRM_Contact_DAO_Relationship { } /** + * Only called from import now... plus one place outside of core & tests. + * + * @todo - deprecate more aggressively - will involve copying to the import + * class, adding a deprecation notice here & removing from tests. + * * Takes an associative array and creates a relationship object. * * @deprecated For single creates use the api instead (it's tested). -- 2.25.1