dev/core#1838 Ensure that no fatal error is triggered if you try to access a merged...
authorSeamus Lee <seamuslee001@gmail.com>
Tue, 22 Sep 2020 22:50:03 +0000 (08:50 +1000)
committerSeamus Lee <seamuslee001@gmail.com>
Tue, 29 Sep 2020 11:27:19 +0000 (21:27 +1000)
Move exception capturing into the page layer and extend unit test to cover page function

Update status message as per MikeĆ½'s comment

CRM/Contact/Page/View.php
tests/phpunit/api/v3/ContactTest.php

index faeb0cb8cfcf03611a8aced9fff676b28c9b0ff5..ce076fe83c89d94e7652d5ef7f6d248864db0f67 100644 (file)
@@ -311,7 +311,13 @@ class CRM_Contact_Page_View extends CRM_Core_Page {
     }
     if ($isDeleted) {
       $title = "<del>{$title}</del>";
-      $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'];
index 4d99ff2562ecc7bed31dfef901f65a44476dd9ad..df25b45c005223465152e09c61ac1ced5ee0dd55 100644 (file)
@@ -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&amp;reset=1&amp;gid=7&amp;id=3&amp;snippet=4', $title);
+  }
+
   /**
    * Test merging 2 contacts with delete to trash off.
    *