Towards CRM-20155 remove duplicate calls to dedupe functions.
authoreileen <emcnaughton@wikimedia.org>
Thu, 23 Mar 2017 02:18:17 +0000 (15:18 +1300)
committereileen <emcnaughton@wikimedia.org>
Thu, 23 Mar 2017 03:43:18 +0000 (16:43 +1300)
This is a partial commit which covers the best tested section of these & establishes the new functions.

I didn't want to make the commit too daunting. The bin file probably has not been used in years
hence all the require_once calls :-)

CRM/Contact/BAO/Contact.php
api/v3/Contact.php
bin/ContributionProcessor.php
tests/phpunit/CRM/Dedupe/DedupeFinderTest.php
tests/phpunit/api/v3/ContactTest.php

index ff9301f1fd497eaae9e50705e97e5307f0b69241..e057dafd4a8c20859b3ec7057be7ea3f92493673 100644 (file)
@@ -3426,4 +3426,53 @@ LEFT JOIN civicrm_address add2 ON ( add1.master_id = add2.id )
     return $clauses;
   }
 
+  /**
+   * Get any existing duplicate contacts based on the input parameters.
+   *
+   * @param array $input
+   *   Input parameters to be matched.
+   * @param string $contactType
+   * @param string $rule
+   *  - Supervised
+   *  - Unsupervised
+   * @param $excludedContactIDs
+   *   An array of ids not to be included in the results.
+   * @param bool $checkPermissions
+   * @param int $ruleGroupID
+   *   ID of the rule group to be used if an override is desirable.
+   *
+   * @return array
+   */
+  public static function getDuplicateContacts($input, $contactType, $rule = 'Unsupervised', $excludedContactIDs = array(), $checkPermissions = TRUE, $ruleGroupID = NULL) {
+    $dedupeParams = CRM_Dedupe_Finder::formatParams($input, $contactType);
+    $dedupeParams['check_permission'] = $checkPermissions;
+    $ids = CRM_Dedupe_Finder::dupesByParams($dedupeParams, $contactType, $rule, $excludedContactIDs, $ruleGroupID);
+    return $ids;
+  }
+
+  /**
+   * Get the first duplicate contacts based on the input parameters.
+   *
+   * @param array $input
+   *   Input parameters to be matched.
+   * @param string $contactType
+   * @param string $rule
+   *  - Supervised
+   *  - Unsupervised
+   * @param $excludedContactIDs
+   *   An array of ids not to be included in the results.
+   * @param bool $checkPermissions
+   * @param int $ruleGroupID
+   *   ID of the rule group to be used if an override is desirable.
+   *
+   * @return int|NULL
+   */
+  public static function getFirstDuplicateContact($input, $contactType, $rule = 'Unsupervised', $excludedContactIDs = array(), $checkPermissions = TRUE, $ruleGroupID = NULL) {
+    $ids = self::getDuplicateContacts($input, $contactType, $rule, $excludedContactIDs, $checkPermissions, $ruleGroupID);
+    if (empty($ids)) {
+      return NULL;
+    }
+    return $ids[0];
+  }
+
 }
index 773068f4bbf23e73965e62061b47433ad044e25f..e09fc91ee17bc544fc21bba3d3ea8d0c2ce0127a 100644 (file)
@@ -55,8 +55,14 @@ function civicrm_api3_contact_create($params) {
     throw new \Civi\API\Exception\UnauthorizedException('Permission denied to modify contact record');
   }
 
-  $dupeCheck = CRM_Utils_Array::value('dupe_check', $params, FALSE);
-  $values = _civicrm_api3_contact_check_params($params, $dupeCheck);
+  if (!empty($params['dupe_check'])) {
+    $ids = CRM_Contact_BAO_Contact::getDuplicateContacts($params, $params['contact_type'], 'Unsupervised', array(), $params['check_permission']);
+    if (count($ids) > 0) {
+      throw new API_Exception("Found matching contacts: " . implode(',', $ids), "duplicate", array("ids" => $ids));
+    }
+  }
+
+  $values = _civicrm_api3_contact_check_params($params);
   if ($values) {
     return $values;
   }
@@ -455,13 +461,12 @@ function civicrm_api3_contact_delete($params) {
  * This function is on it's way out.
  *
  * @param array $params
- * @param bool $dupeCheck
  *
  * @return null
  * @throws API_Exception
  * @throws CiviCRM_API3_Exception
  */
-function _civicrm_api3_contact_check_params(&$params, $dupeCheck) {
+function _civicrm_api3_contact_check_params(&$params) {
 
   switch (strtolower(CRM_Utils_Array::value('contact_type', $params))) {
     case 'household':
@@ -494,35 +499,13 @@ function _civicrm_api3_contact_check_params(&$params, $dupeCheck) {
     }
   }
 
-  if ($dupeCheck) {
-    // check for record already existing
-    $dedupeParams = CRM_Dedupe_Finder::formatParams($params, $params['contact_type']);
-
-    // CRM-6431
-    // setting 'check_permission' here means that the dedupe checking will be carried out even if the
-    // person does not have permission to carry out de-dupes
-    // this is similar to the front end form
-    if (isset($params['check_permission'])) {
-      $dedupeParams['check_permission'] = $params['check_permission'];
-    }
-
-    $ids = CRM_Dedupe_Finder::dupesByParams($dedupeParams, $params['contact_type'], 'Unsupervised', array());
-
-    if (count($ids) > 0) {
-      throw new API_Exception("Found matching contacts: " . implode(',', $ids), "duplicate", array("ids" => $ids));
-    }
-  }
-
   // The BAO no longer supports the legacy param "current_employer" so here is a shim for api backward-compatability
   if (!empty($params['current_employer'])) {
     $organizationParams = array(
       'organization_name' => $params['current_employer'],
     );
 
-    $dedupParams = CRM_Dedupe_Finder::formatParams($organizationParams, 'Organization');
-
-    $dedupParams['check_permission'] = FALSE;
-    $dupeIds = CRM_Dedupe_Finder::dupesByParams($dedupParams, 'Organization', 'Supervised');
+    $dupeIds = CRM_Contact_BAO_Contact::getDuplicateContacts($organizationParams, 'Organization', 'Supervised', array(), FALSE);
 
     // check for mismatch employer name and id
     if (!empty($params['employer_id']) && !in_array($params['employer_id'], $dupeIds)) {
@@ -1104,11 +1087,10 @@ function _civicrm_api3_contact_deprecation() {
  *   -int main_id: main contact id with whom merge has to happen
  *   -int other_id: duplicate contact which would be deleted after merge operation
  *   -string mode: "safe" skips the merge if there are no conflicts. Does a force merge otherwise.
- *   -boolean auto_flip: whether to let api decide which contact to retain and which to delete.
  *
  * @return array
  *   API Result Array
- * @throws CiviCRM_API3_Exception
+ * @throws API_Exception
  */
 function civicrm_api3_contact_merge($params) {
   if (($result = CRM_Dedupe_Merger::merge(array(
@@ -1119,7 +1101,7 @@ function civicrm_api3_contact_merge($params) {
     ), array(), $params['mode'])) != FALSE) {
     return civicrm_api3_create_success($result, $params);
   }
-  throw new CiviCRM_API3_Exception('Merge failed');
+  throw new API_Exception('Merge failed');
 }
 
 /**
@@ -1333,17 +1315,14 @@ function _civicrm_api3_contact_getlist_output($result, $request) {
  *   API formatted array
  */
 function civicrm_api3_contact_duplicatecheck($params) {
-  $dedupeParams = CRM_Dedupe_Finder::formatParams($params['match'], $params['match']['contact_type']);
-
-  // CRM-6431
-  // setting 'check_permission' here means that the dedupe checking will be carried out even if the
-  // person does not have permission to carry out de-dupes
-  // this is similar to the front end form
-  if (isset($params['check_permission'])) {
-    $dedupeParams['check_permission'] = $params['check_permission'];
-  }
-
-  $dupes = CRM_Dedupe_Finder::dupesByParams($dedupeParams, $params['match']['contact_type'], 'Unsupervised', array(), CRM_Utils_Array::value('dedupe_rule_id', $params));
+  $dupes = CRM_Contact_BAO_Contact::getDuplicateContacts(
+    $params['match'],
+    $params['match']['contact_type'],
+    'Unsupervised',
+    array(),
+    CRM_Utils_Array::value('check_permissions', $params),
+    CRM_Utils_Array::value('dedupe_rule_id', $params)
+  );
   $values = empty($dupes) ? array() : array_fill_keys($dupes, array());
   return civicrm_api3_create_success($values, $params, 'Contact', 'duplicatecheck');
 }
index 2481fb230422484a178ad16b0182c624b43c91dd..5432bc045f9aa020a025d75cc20331541c70cc9a 100644 (file)
@@ -188,10 +188,15 @@ class CiviContributeProcessor {
             $params['transaction']['is_test'] = 0;
           }
 
-          if (self::processAPIContribution($params)) {
-            CRM_Core_Error::debug_log_message("Processed - {$trxnDetails['email']}, {$trxnDetails['amt']}, {$value} ..<p>", TRUE);
+          try {
+            if (self::processAPIContribution($params)) {
+              CRM_Core_Error::debug_log_message("Processed - {$trxnDetails['email']}, {$trxnDetails['amt']}, {$value} ..<p>", TRUE);
+            }
+            else {
+              CRM_Core_Error::debug_log_message("Skipped - {$trxnDetails['email']}, {$trxnDetails['amt']}, {$value} ..<p>", TRUE);
+            }
           }
-          else {
+          catch (CiviCRM_API3_Exception $e) {
             CRM_Core_Error::debug_log_message("Skipped - {$trxnDetails['email']}, {$trxnDetails['amt']}, {$value} ..<p>", TRUE);
           }
         }
@@ -399,6 +404,10 @@ class CiviContributeProcessor {
   }
 
   /**
+   * @deprecated function.
+   *
+   * This function has probably been defunct for quite a long time.
+   *
    * @param array $params
    *
    * @return bool
@@ -408,33 +417,16 @@ class CiviContributeProcessor {
       return FALSE;
     }
 
-    // add contact using dedupe rule
-    $dedupeParams = CRM_Dedupe_Finder::formatParams($params, 'Individual');
-    $dedupeParams['check_permission'] = FALSE;
-    $dupeIds = CRM_Dedupe_Finder::dupesByParams($dedupeParams, 'Individual');
-    // if we find more than one contact, use the first one
-    if (!empty($dupeIds[0])) {
-      $params['contact_id'] = $dupeIds[0];
-    }
-    $contact = CRM_Contact_BAO_Contact::create($params);
-    if (!$contact->id) {
-      return FALSE;
-    }
+    $params['contact_id'] = CRM_Contact_BAO_Contact::getFirstDuplicateContact($params, 'Individual', 'Unsupervised', array(), FALSE);
+
+    $contact = civicrm_api3('Contact', 'create', $params);
 
     // only pass transaction params to contribution::create, if available
     if (array_key_exists('transaction', $params)) {
       $params = $params['transaction'];
-      $params['contact_id'] = $contact->id;
+      $params['contact_id'] = $contact['id'];
     }
 
-    // handle contribution custom data
-    $customFields = CRM_Core_BAO_CustomField::getFields('Contribution',
-      FALSE,
-      FALSE,
-      CRM_Utils_Array::value('financial_type_id',
-        $params
-      )
-    );
     $params['custom'] = CRM_Core_BAO_CustomField::postProcess($params,
       CRM_Utils_Array::value('id', $params, NULL),
       'Contribution'
index 7bc67795999de2db6a472aa4f18f344e2dfe508a..417fb63f79065d5021f198f44519e7b0ed212cd5 100644 (file)
@@ -203,8 +203,7 @@ class CRM_Dedupe_DedupeFinderTest extends CiviUnitTestCase {
       'street_address' => 'Ambachtstraat 23',
     );
     CRM_Core_TemporaryErrorScope::useException();
-    $dedupeParams = CRM_Dedupe_Finder::formatParams($fields, 'Individual');
-    $ids = CRM_Dedupe_Finder::dupesByParams($dedupeParams, 'Individual', 'General');
+    $ids = CRM_Contact_BAO_Contact::getDuplicateContacts($fields, 'Individual', 'General');
 
     // Check with default Individual-General rule
     $this->assertEquals(count($ids), 2, 'Check Individual-General rule for dupesByParams().');
index e79374618061f984a91dd813c4b58baed95ecd6c..406d328fbb52831363de02ca5c7b680de865b4f0 100644 (file)
@@ -2991,19 +2991,15 @@ class api_v3_ContactTest extends CiviUnitTestCase {
    * Test the duplicate check function.
    */
   public function testDuplicateCheck() {
-    $this->callAPISuccess('Contact', 'create', array(
+    $harry = array(
       'first_name' => 'Harry',
       'last_name' => 'Potter',
       'email' => 'harry@hogwarts.edu',
       'contact_type' => 'Individual',
-    ));
+    );
+    $this->callAPISuccess('Contact', 'create', $harry);
     $result = $this->callAPISuccess('Contact', 'duplicatecheck', array(
-      'match' => array(
-        'first_name' => 'Harry',
-        'last_name' => 'Potter',
-        'email' => 'harry@hogwarts.edu',
-        'contact_type' => 'Individual',
-      ),
+      'match' => $harry,
     ));
 
     $this->assertEquals(1, $result['count']);
@@ -3016,6 +3012,7 @@ class api_v3_ContactTest extends CiviUnitTestCase {
       ),
     ));
     $this->assertEquals(0, $result['count']);
+    $this->callAPIFailure('Contact', 'create', array_merge($harry, array('dupe_check' => 1)));
   }
 
   public function testGetByContactType() {