Merge pull request #15156 from eileenmcnaughton/dedupe5
[civicrm-core.git] / CRM / Dedupe / Finder.php
index ef50af8ed03bf72809ad20e19b2c9686e858b94c..63725439a91682537e8bbe6a607bcfffb67bbb2c 100644 (file)
@@ -51,39 +51,25 @@ class CRM_Dedupe_Finder {
    * @param bool $checkPermissions
    *   Respect logged in user permissions.
    *
-   * @param int $searchLimit
-   *  Limit for the number of contacts to be used for comparison.
-   *  The search methodology finds all matches for the searchedContacts so this limits
-   *  the number of searched contacts, not the matches found.
-   *
    * @return array
    *   Array of (cid1, cid2, weight) dupe triples
    *
-   * @throws CiviCRM_API3_Exception
    * @throws Exception
    */
-  public static function dupes($rgid, $cids = array(), $checkPermissions = TRUE, $searchLimit = 0) {
+  public static function dupes($rgid, $cids = [], $checkPermissions = TRUE) {
     $rgBao = new CRM_Dedupe_BAO_RuleGroup();
     $rgBao->id = $rgid;
     $rgBao->contactIds = $cids;
     if (!$rgBao->find(TRUE)) {
-      CRM_Core_Error::fatal("Dedupe rule not found for selected contacts");
-    }
-    if (empty($rgBao->contactIds) && !empty($searchLimit)) {
-      $limitedContacts = civicrm_api3('Contact', 'get', array(
-        'return' => 'id',
-        'contact_type' => $rgBao->contact_type,
-        'options' => array('limit' => $searchLimit),
-      ));
-      $rgBao->contactIds = array_keys($limitedContacts['values']);
+      throw new CRM_Core_Exception('Dedupe rule not found for selected contacts');
     }
 
     $rgBao->fillTable();
     $dao = new CRM_Core_DAO();
     $dao->query($rgBao->thresholdQuery($checkPermissions));
-    $dupes = array();
+    $dupes = [];
     while ($dao->fetch()) {
-      $dupes[] = array($dao->id1, $dao->id2, $dao->weight);
+      $dupes[] = [$dao->id1, $dao->id2, $dao->weight];
     }
     $dao->query($rgBao->tableDropQuery());
 
@@ -113,17 +99,18 @@ class CRM_Dedupe_Finder {
    *
    * @return array
    *   matching contact ids
+   * @throws \CRM_Core_Exception
    */
   public static function dupesByParams(
     $params,
     $ctype,
     $used = 'Unsupervised',
-    $except = array(),
+    $except = [],
     $ruleGroupID = NULL
   ) {
     // If $params is empty there is zero reason to proceed.
     if (!$params) {
-      return array();
+      return [];
     }
     $checkPermission = CRM_Utils_Array::value('check_permission', $params, TRUE);
     // This may no longer be required - see https://github.com/civicrm/civicrm-core/pull/13176
@@ -144,7 +131,7 @@ class CRM_Dedupe_Finder {
       $rgBao->contact_type = $ctype;
       $rgBao->used = $used;
       if (!$rgBao->find(TRUE)) {
-        CRM_Core_Error::fatal("$used rule for $ctype does not exist");
+        throw new CRM_Core_Exception("$used rule for $ctype does not exist");
       }
     }
 
@@ -156,7 +143,7 @@ class CRM_Dedupe_Finder {
     $rgBao->fillTable();
     $dao = new CRM_Core_DAO();
     $dao->query($rgBao->thresholdQuery($checkPermission));
-    $dupes = array();
+    $dupes = [];
     while ($dao->fetch()) {
       if (isset($dao->id) && $dao->id) {
         $dupes[] = $dao->id;
@@ -181,13 +168,14 @@ class CRM_Dedupe_Finder {
    *
    * @return array
    *   array of (cid1, cid2, weight) dupe triples
+   * @throws \CiviCRM_API3_Exception
    */
   public static function dupesInGroup($rgid, $gid, $searchLimit = 0) {
     $cids = array_keys(CRM_Contact_BAO_Group::getMember($gid, TRUE, $searchLimit));
     if (!empty($cids)) {
       return self::dupes($rgid, $cids);
     }
-    return array();
+    return [];
   }
 
   /**
@@ -201,18 +189,19 @@ class CRM_Dedupe_Finder {
    *
    * @return array
    *   valid $params array for dedupe
+   * @throws \CRM_Core_Exception
    */
   public static function formatParams($fields, $ctype) {
-    $flat = array();
+    $flat = [];
     CRM_Utils_Array::flatten($fields, $flat);
 
     // FIXME: This may no longer be necessary - check inputs
-    $replace_these = array(
+    $replace_these = [
       'individual_prefix' => 'prefix_id',
       'individual_suffix' => 'suffix_id',
       'gender' => 'gender_id',
-    );
-    foreach (array('individual_suffix', 'individual_prefix', 'gender') as $name) {
+    ];
+    foreach (['individual_suffix', 'individual_prefix', 'gender'] as $name) {
       if (!empty($fields[$name])) {
         $flat[$replace_these[$name]] = $flat[$name];
         unset($flat[$name]);
@@ -220,10 +209,10 @@ class CRM_Dedupe_Finder {
     }
 
     // handle {birth,deceased}_date
-    foreach (array(
+    foreach ([
       'birth_date',
       'deceased_date',
-    ) as $date) {
+    ] as $date) {
       if (!empty($fields[$date])) {
         $flat[$date] = $fields[$date];
         if (is_array($flat[$date])) {
@@ -240,7 +229,7 @@ class CRM_Dedupe_Finder {
 
     // handle preferred_communication_method
     if (!empty($fields['preferred_communication_method'])) {
-      $methods = array_intersect($fields['preferred_communication_method'], array('1'));
+      $methods = array_intersect($fields['preferred_communication_method'], ['1']);
       $methods = array_keys($methods);
       sort($methods);
       if ($methods) {
@@ -277,15 +266,16 @@ class CRM_Dedupe_Finder {
     // FIXME: CRM-5026 should be fixed here; the below clobbers all address info; we should split off address fields and match
     // the -digit to civicrm_address.location_type_id and -Primary to civicrm_address.is_primary
     foreach ($flat as $key => $value) {
-      $matches = array();
+      $matches = [];
       if (preg_match('/(.*)-(Primary-[\d+])$|(.*)-(\d+|Primary)$/', $key, $matches)) {
         $return = array_values(array_filter($matches));
-        $flat[$return[1]] = $value;
+        // make sure the first occurrence is kept, not the last
+        $flat[$return[1]] = empty($flat[$return[1]]) ? $value : $flat[$return[1]];
         unset($flat[$key]);
       }
     }
 
-    $params = array();
+    $params = [];
     $supportedFields = CRM_Dedupe_BAO_RuleGroup::supportedFields($ctype);
     if (is_array($supportedFields)) {
       foreach ($supportedFields as $table => $fields) {
@@ -293,22 +283,22 @@ class CRM_Dedupe_Finder {
           // for matching on civicrm_address fields, we also need the location_type_id
           $fields['location_type_id'] = '';
           // FIXME: we also need to do some hacking for id and name fields, see CRM-3902’s comments
-          $fixes = array(
+          $fixes = [
             'address_name' => 'name',
             'country' => 'country_id',
             'state_province' => 'state_province_id',
             'county' => 'county_id',
-          );
+          ];
           foreach ($fixes as $orig => $target) {
             if (!empty($flat[$orig])) {
               $params[$table][$target] = $flat[$orig];
             }
           }
         }
-        if ($table == 'civicrm_phone') {
-          $fixes = array(
+        if ($table === 'civicrm_phone') {
+          $fixes = [
             'phone' => 'phone_numeric',
-          );
+          ];
           foreach ($fixes as $orig => $target) {
             if (!empty($flat[$orig])) {
               $params[$table][$target] = $flat[$orig];
@@ -331,7 +321,7 @@ class CRM_Dedupe_Finder {
    * @param array $foundDupes
    * @param string $cacheKeyString
    *
-   * @return array Dupe pairs with the keys
+   * @return array
    *   Dupe pairs with the keys
    *   -srcID
    *   -srcName
@@ -339,11 +329,9 @@ class CRM_Dedupe_Finder {
    *   -dstName
    *   -weight
    *   -canMerge
-   *
-   * @throws CRM_Core_Exception
    */
   public static function parseAndStoreDupePairs($foundDupes, $cacheKeyString) {
-    $cids = array();
+    $cids = [];
     foreach ($foundDupes as $dupe) {
       $cids[$dupe[0]] = 1;
       $cids[$dupe[1]] = 1;
@@ -351,7 +339,7 @@ class CRM_Dedupe_Finder {
     $cidString = implode(', ', array_keys($cids));
 
     $dao = CRM_Core_DAO::executeQuery("SELECT id, display_name FROM civicrm_contact WHERE id IN ($cidString) ORDER BY sort_name");
-    $displayNames = array();
+    $displayNames = [];
     while ($dao->fetch()) {
       $displayNames[$dao->id] = $dao->display_name;
     }
@@ -366,19 +354,18 @@ class CRM_Dedupe_Finder {
         $dstID = $userId;
       }
 
-      $mainContacts[] = $row = array(
+      $mainContacts[] = $row = [
         'dstID' => $dstID,
         'dstName' => $displayNames[$dstID],
         'srcID' => $srcID,
         'srcName' => $displayNames[$srcID],
         'weight' => $dupes[2],
         'canMerge' => TRUE,
-      );
+      ];
 
       $data = CRM_Core_DAO::escapeString(serialize($row));
-      $values[] = " ( 'civicrm_contact', $dstID, $srcID, '$cacheKeyString', '$data' ) ";
+      CRM_Core_BAO_PrevNextCache::setItem('civicrm_contact', $dstID, $srcID, $cacheKeyString, $data);
     }
-    CRM_Core_BAO_PrevNextCache::setItem($values);
     return $mainContacts;
   }