From: Seamus Lee Date: Tue, 22 Sep 2020 22:50:03 +0000 (+1000) Subject: dev/core#1838 Ensure that no fatal error is triggered if you try to access a merged... X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=50bdbb5ba90a1f81ceaa61bcd8f31d0ecc925fc2;p=civicrm-core.git dev/core#1838 Ensure that no fatal error is triggered if you try to access a merged contact and the contact that it was merged into has been permanently deleted Move exception capturing into the page layer and extend unit test to cover page function Update status message as per MikeĆ½'s comment --- diff --git a/CRM/Contact/Page/View.php b/CRM/Contact/Page/View.php index faeb0cb8cf..ce076fe83c 100644 --- a/CRM/Contact/Page/View.php +++ b/CRM/Contact/Page/View.php @@ -311,7 +311,13 @@ class CRM_Contact_Page_View extends CRM_Core_Page { } if ($isDeleted) { $title = "{$title}"; - $mergedTo = civicrm_api3('Contact', 'getmergedto', ['contact_id' => $contactId, 'api.Contact.get' => ['return' => 'display_name']]); + try { + $mergedTo = civicrm_api3('Contact', 'getmergedto', ['contact_id' => $contactId, 'api.Contact.get' => ['return' => 'display_name']]); + } + catch (CiviCRM_API3_Exception $e) { + CRM_Core_Session::singleton()->setStatus(ts('This contact was deleted during a merge operation. The contact it was merged into cannot be found and may have been deleted.')); + $mergedTo = ['count' => 0]; + } if ($mergedTo['count']) { $mergedToContactID = $mergedTo['id']; $mergedToDisplayName = $mergedTo['values'][$mergedToContactID]['api.Contact.get']['values'][0]['display_name']; diff --git a/tests/phpunit/api/v3/ContactTest.php b/tests/phpunit/api/v3/ContactTest.php index 4d99ff2562..df25b45c00 100644 --- a/tests/phpunit/api/v3/ContactTest.php +++ b/tests/phpunit/api/v3/ContactTest.php @@ -4166,6 +4166,30 @@ class api_v3_ContactTest extends CiviUnitTestCase { $this->assertEquals($mergedContactIds, array_keys($result)); } + /** + * Test retrieving merged contacts. + * + * The goal here is to start with a contact deleted by merged and find out the contact that is the current version of them. + * + * @throws \CRM_Core_Exception + */ + public function testMergedGetWithPermanentlyDeletedContact() { + $this->contactIDs[] = $this->individualCreate(); + $this->contactIDs[] = $this->individualCreate(); + $this->contactIDs[] = $this->individualCreate(); + $this->contactIDs[] = $this->individualCreate(); + + // First do an 'unnatural merge' - they 'like to merge into the lowest but this will mean that contact 0 merged to contact [3]. + // When the batch merge runs.... the new lowest contact is contact[1]. All contacts will merge into that contact, + // including contact[3], resulting in only 3 existing at the end. For each contact the correct answer to 'who did I eventually + // wind up being should be [1] + $this->callAPISuccess('Contact', 'merge', ['to_remove_id' => $this->contactIDs[0], 'to_keep_id' => $this->contactIDs[3]]); + $this->callAPISuccess('Contact', 'delete', ['id' => $this->contactIDs[3], 'skip_undelete' => TRUE]); + $this->callAPIFailure('Contact', 'getmergedto', ['sequential' => 1, 'contact_id' => $this->contactIDs[0]]); + $title = CRM_Contact_Page_View::setTitle($this->contactIDs[0], TRUE); + $this->assertContains('civicrm/profile/view&reset=1&gid=7&id=3&snippet=4', $title); + } + /** * Test merging 2 contacts with delete to trash off. *