public function testFuzzyDupes()
 {
     // make dupe checks based on based on following contact sets:
     // FIRST - LAST - EMAIL
     // ---------------------------------
     // robin  - hood - robin@example.com
     // robin  - hood - hood@example.com
     // robin  - dale - robin@example.com
     // little - dale - dale@example.com
     // will   - dale - dale@example.com
     // will   - dale - will@example.com
     // will   - dale - will@example.com
     // create a group to hold contacts, so that dupe checks don't consider any other contacts in the DB
     $params = array('name' => 'Dupe Group', 'title' => 'New Test Dupe Group', 'domain_id' => 1, 'is_active' => 1, 'visibility' => 'Public Pages', 'version' => 3);
     // TODO: This is not an API test!!
     $result = civicrm_api('group', 'create', $params);
     $groupId = $result['id'];
     // contact data set
     // FIXME: move create params to separate function
     $params = array(array('first_name' => 'robin', 'last_name' => 'hood', 'email' => '*****@*****.**', 'contact_type' => 'Individual'), array('first_name' => 'robin', 'last_name' => 'hood', 'email' => '*****@*****.**', 'contact_type' => 'Individual'), array('first_name' => 'robin', 'last_name' => 'dale', 'email' => '*****@*****.**', 'contact_type' => 'Individual'), array('first_name' => 'little', 'last_name' => 'dale', 'email' => '*****@*****.**', 'contact_type' => 'Individual'), array('first_name' => 'will', 'last_name' => 'dale', 'email' => '*****@*****.**', 'contact_type' => 'Individual'), array('first_name' => 'will', 'last_name' => 'dale', 'email' => '*****@*****.**', 'contact_type' => 'Individual'), array('first_name' => 'will', 'last_name' => 'dale', 'email' => '*****@*****.**', 'contact_type' => 'Individual'));
     $count = 1;
     // TODO: This is not an API test!!
     foreach ($params as $param) {
         $param['version'] = 3;
         $contact = civicrm_api('contact', 'create', $param);
         $contactIds[$count++] = $contact['id'];
         $grpParams = array('contact_id' => $contact['id'], 'group_id' => $groupId, 'version' => 3);
         $res = civicrm_api('group_contact', 'create', $grpParams);
     }
     // verify that all contacts have been created separately
     $this->assertEquals(count($contactIds), 7, 'Check for number of contacts.');
     $dao = new CRM_Dedupe_DAO_RuleGroup();
     $dao->contact_type = 'Individual';
     $dao->level = 'Fuzzy';
     $dao->is_default = 1;
     $dao->find(TRUE);
     $foundDupes = CRM_Dedupe_Finder::dupesInGroup($dao->id, $groupId);
     // -------------------------------------------------------------------------
     // default dedupe rule: threshold = 20 => (First + Last + Email) Matches ( 1 pair )
     // --------------------------------------------------------------------------
     // will   - dale - will@example.com
     // will   - dale - will@example.com
     // so 1 pair for - first + last + mail
     $this->assertEquals(count($foundDupes), 1, 'Check Individual-Fuzzy dupe rule for dupesInGroup().');
     // delete all created contacts
     foreach ($contactIds as $contactId) {
         Contact::delete($contactId);
     }
     // delete dupe group
     $params = array('id' => $groupId, 'version' => 3);
     civicrm_api('group', 'delete', $params);
 }
 /**
  * Browse all rule groups.
  */
 public function run()
 {
     $gid = CRM_Utils_Request::retrieve('gid', 'Positive', $this, FALSE, 0);
     $action = CRM_Utils_Request::retrieve('action', 'String', $this, FALSE, 0);
     $context = CRM_Utils_Request::retrieve('context', 'String', $this);
     $session = CRM_Core_Session::singleton();
     $contactIds = $session->get('selectedSearchContactIds');
     if ($context == 'search' || !empty($contactIds)) {
         $context = 'search';
         $this->assign('backURL', $session->readUserContext());
     }
     if ($action & CRM_Core_Action::RENEW) {
         // empty cache
         $rgid = CRM_Utils_Request::retrieve('rgid', 'Positive', $this, FALSE, 0);
         if ($rgid) {
             $contactType = CRM_Core_DAO::getFieldValue('CRM_Dedupe_DAO_RuleGroup', $rgid, 'contact_type');
             $cacheKeyString = "merge {$contactType}";
             $cacheKeyString .= $rgid ? "_{$rgid}" : '_0';
             $cacheKeyString .= $gid ? "_{$gid}" : '_0';
             CRM_Core_BAO_PrevNextCache::deleteItem(NULL, $cacheKeyString);
         }
         $urlQry = "reset=1&action=update&rgid={$rgid}";
         if ($gid) {
             $urlQry .= "&gid={$gid}";
         }
         CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contact/dedupefind', $urlQry));
     } elseif ($action & CRM_Core_Action::MAP) {
         // do a batch merge if requested
         $rgid = CRM_Utils_Request::retrieve('rgid', 'Positive', $this, FALSE, 0);
         $result = CRM_Dedupe_Merger::batchMerge($rgid, $gid, 'safe', TRUE, 75);
         $skippedCount = CRM_Utils_Request::retrieve('skipped', 'Positive', $this, FALSE, 0);
         $skippedCount = $skippedCount + count($result['skipped']);
         $mergedCount = CRM_Utils_Request::retrieve('merged', 'Positive', $this, FALSE, 0);
         $mergedCount = $mergedCount + count($result['merged']);
         if (empty($result['merged']) && empty($result['skipped'])) {
             $message = '';
             if ($mergedCount >= 1) {
                 $message = ts("%1 pairs of duplicates were merged", array(1 => $mergedCount));
             }
             if ($skippedCount >= 1) {
                 $message = $message ? "{$message} and " : '';
                 $message .= ts("%1 pairs of duplicates were skipped due to conflict", array(1 => $skippedCount));
             }
             $message .= ts(" during the batch merge process with safe mode.");
             CRM_Core_Session::setStatus($message, ts('Merge Complete'), 'success');
             $urlQry = "reset=1&action=update&rgid={$rgid}";
             if ($gid) {
                 $urlQry .= "&gid={$gid}";
             }
             CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contact/dedupefind', $urlQry));
         } else {
             $urlQry = "reset=1&action=map&rgid={$rgid}";
             if ($gid) {
                 $urlQry .= "&gid={$gid}";
             }
             $urlQry .= "&skipped={$skippedCount}&merged={$mergedCount}";
             CRM_Utils_System::jsRedirect(CRM_Utils_System::url('civicrm/contact/dedupefind', $urlQry), ts('Batch Merge Task in progress'), ts('The batch merge task is still in progress. This page will be refreshed automatically.'));
         }
     }
     if ($action & CRM_Core_Action::UPDATE || $action & CRM_Core_Action::BROWSE) {
         $cid = CRM_Utils_Request::retrieve('cid', 'Positive', $this, FALSE, 0);
         $rgid = CRM_Utils_Request::retrieve('rgid', 'Positive', $this, FALSE, 0);
         $this->action = CRM_Core_Action::UPDATE;
         //calculate the $contactType
         if ($rgid) {
             $contactType = CRM_Core_DAO::getFieldValue('CRM_Dedupe_DAO_RuleGroup', $rgid, 'contact_type');
         }
         $sourceParams = 'snippet=4';
         if ($gid) {
             $sourceParams .= "&gid={$gid}";
         }
         if ($rgid) {
             $sourceParams .= "&rgid={$rgid}";
         }
         if ($context == 'conflicts') {
             $sourceParams .= "&selected=1";
         }
         $this->assign('sourceUrl', CRM_Utils_System::url('civicrm/ajax/dedupefind', $sourceParams, FALSE, NULL, FALSE));
         //reload from cache table
         $cacheKeyString = "merge {$contactType}";
         $cacheKeyString .= $rgid ? "_{$rgid}" : '_0';
         $cacheKeyString .= $gid ? "_{$gid}" : '_0';
         $stats = CRM_Dedupe_Merger::getMergeStatsMsg($cacheKeyString);
         if ($stats) {
             CRM_Core_Session::setStatus($stats);
             // reset so we not displaying same message again
             CRM_Dedupe_Merger::resetMergeStats($cacheKeyString);
         }
         $join = "LEFT JOIN civicrm_dedupe_exception de ON ( pn.entity_id1 = de.contact_id1 AND\n                                                                 pn.entity_id2 = de.contact_id2 )";
         $where = "de.id IS NULL";
         if ($context == 'conflicts') {
             $where .= " AND pn.is_selected = 1";
         }
         $this->_mainContacts = CRM_Core_BAO_PrevNextCache::retrieve($cacheKeyString, $join, $where);
         if (empty($this->_mainContacts)) {
             if ($context == 'conflicts') {
                 // if the current screen was intended to list only selected contacts, move back to full dupe list
                 $sourceParams = 'reset=1&action=update';
                 if ($gid) {
                     $sourceParams .= "&gid={$gid}";
                 }
                 if ($rgid) {
                     $sourceParams .= "&rgid={$rgid}";
                 }
                 CRM_Utils_System::redirect(CRM_Utils_System::url(CRM_Utils_System::currentPath(), $sourceParams));
             }
             if ($gid) {
                 $foundDupes = $this->get("dedupe_dupes_{$gid}");
                 if (!$foundDupes) {
                     $foundDupes = CRM_Dedupe_Finder::dupesInGroup($rgid, $gid);
                 }
                 $this->set("dedupe_dupes_{$gid}", $foundDupes);
             } elseif (!empty($contactIds)) {
                 $foundDupes = $this->get("search_dedupe_dupes_{$gid}");
                 if (!$foundDupes) {
                     $foundDupes = CRM_Dedupe_Finder::dupes($rgid, $contactIds);
                 }
                 $this->get("search_dedupe_dupes_{$gid}", $foundDupes);
             } else {
                 $foundDupes = $this->get('dedupe_dupes');
                 if (!$foundDupes) {
                     $foundDupes = CRM_Dedupe_Finder::dupes($rgid);
                 }
                 $this->set('dedupe_dupes', $foundDupes);
             }
             if (!$foundDupes) {
                 $ruleGroup = new CRM_Dedupe_BAO_RuleGroup();
                 $ruleGroup->id = $rgid;
                 $ruleGroup->find(TRUE);
                 $session = CRM_Core_Session::singleton();
                 $session->setStatus(ts('No possible duplicates were found using %1 rule.', array(1 => $ruleGroup->name)), ts('None Found'), 'info');
                 $url = CRM_Utils_System::url('civicrm/contact/deduperules', 'reset=1');
                 if ($context == 'search') {
                     $url = $session->readUserContext();
                 }
                 CRM_Utils_System::redirect($url);
             } else {
                 $cids = array();
                 foreach ($foundDupes as $dupe) {
                     $cids[$dupe[0]] = 1;
                     $cids[$dupe[1]] = 1;
                 }
                 $cidString = implode(', ', array_keys($cids));
                 $sql = "SELECT id, display_name FROM civicrm_contact WHERE id IN ({$cidString}) ORDER BY sort_name";
                 $dao = new CRM_Core_DAO();
                 $dao->query($sql);
                 $displayNames = array();
                 while ($dao->fetch()) {
                     $displayNames[$dao->id] = $dao->display_name;
                 }
                 // FIXME: sort the contacts; $displayName
                 // is already sort_name-sorted, so use that
                 // (also, consider sorting by dupe count first)
                 // lobo - change the sort to by threshold value
                 // so the more likely dupes are sorted first
                 $session = CRM_Core_Session::singleton();
                 $userId = $session->get('userID');
                 $mainContacts = $permission = array();
                 foreach ($foundDupes as $dupes) {
                     $srcID = $dupes[0];
                     $dstID = $dupes[1];
                     if ($dstID == $userId) {
                         $srcID = $dupes[1];
                         $dstID = $dupes[0];
                     }
                     /***
                      * Eliminate this since it introduces 3 queries PER merge row
                      * and hence is very expensive
                      * CRM-8822
                      * if ( !array_key_exists( $srcID, $permission ) ) {
                      * $permission[$srcID] = CRM_Contact_BAO_Contact_Permission::allow( $srcID, CRM_Core_Permission::EDIT );
                      * }
                      * if ( !array_key_exists( $dstID, $permission ) ) {
                      * $permission[$dstID] = CRM_Contact_BAO_Contact_Permission::allow( $dstID, CRM_Core_Permission::EDIT );
                      * }
                      *
                      * $canMerge = ( $permission[$dstID] && $permission[$srcID] );
                      *
                      */
                     // we'll do permission checking during the merge process
                     $canMerge = TRUE;
                     $mainContacts[] = $row = array('srcID' => $srcID, 'srcName' => $displayNames[$srcID], 'dstID' => $dstID, 'dstName' => $displayNames[$dstID], 'weight' => $dupes[2], 'canMerge' => $canMerge);
                     $data = CRM_Core_DAO::escapeString(serialize($row));
                     $values[] = " ( 'civicrm_contact', {$srcID}, {$dstID}, '{$cacheKeyString}', '{$data}' ) ";
                 }
                 if ($cid) {
                     $this->_cid = $cid;
                 }
                 if ($gid) {
                     $this->_gid = $gid;
                 }
                 $this->_rgid = $rgid;
                 $this->_mainContacts = $mainContacts;
                 CRM_Core_BAO_PrevNextCache::setItem($values);
                 $session = CRM_Core_Session::singleton();
                 if ($this->_cid) {
                     $session->pushUserContext(CRM_Utils_System::url('civicrm/contact/deduperules', "action=update&rgid={$this->_rgid}&gid={$this->_gid}&cid={$this->_cid}"));
                 } else {
                     $session->pushUserContext(CRM_Utils_System::url('civicrm/contact/dedupefind', "reset=1&action=update&rgid={$this->_rgid}"));
                 }
             }
         } else {
             if ($cid) {
                 $this->_cid = $cid;
             }
             if ($gid) {
                 $this->_gid = $gid;
             }
             $this->_rgid = $rgid;
         }
         $this->assign('action', $this->action);
         $this->browse();
     } else {
         $this->action = CRM_Core_Action::UPDATE;
         $this->edit($this->action);
         $this->assign('action', $this->action);
     }
     $this->assign('context', $context);
     // parent run
     return parent::run();
 }
 /**
  * Browse all rule groups
  *  
  * @return void
  * @access public
  */
 function run()
 {
     $gid = CRM_Utils_Request::retrieve('gid', 'Positive', $this, false, 0);
     $action = CRM_Utils_Request::retrieve('action', 'String', $this, false, 0);
     $context = CRM_Utils_Request::retrieve('context', 'String', $this);
     $session = CRM_Core_Session::singleton();
     $contactIds = $session->get('selectedSearchContactIds');
     if ($context == 'search' || !empty($contactIds)) {
         $context = 'search';
         $this->assign('backURL', $session->readUserContext());
     }
     if ($action & CRM_Core_Action::UPDATE || $action & CRM_Core_Action::BROWSE) {
         $cid = CRM_Utils_Request::retrieve('cid', 'Positive', $this, false, 0);
         $rgid = CRM_Utils_Request::retrieve('rgid', 'Positive', $this, false, 0);
         $this->action = CRM_Core_Action::UPDATE;
         if ($gid) {
             $foundDupes = $this->get("dedupe_dupes_{$gid}");
             if (!$foundDupes) {
                 $foundDupes = CRM_Dedupe_Finder::dupesInGroup($rgid, $gid);
             }
             $this->set("dedupe_dupes_{$gid}", $foundDupes);
         } else {
             if (!empty($contactIds)) {
                 $foundDupes = $this->get("search_dedupe_dupes_{$gid}");
                 if (!$foundDupes) {
                     $foundDupes = CRM_Dedupe_Finder::dupes($rgid, $contactIds);
                 }
                 $this->get("search_dedupe_dupes_{$gid}", $foundDupes);
             } else {
                 $foundDupes = $this->get("dedupe_dupes");
                 if (!$foundDupes) {
                     $foundDupes = CRM_Dedupe_Finder::dupes($rgid);
                 }
                 $this->set("dedupe_dupes", $foundDupes);
             }
         }
         if (!$foundDupes) {
             $ruleGroup = new CRM_Dedupe_BAO_RuleGroup();
             $ruleGroup->id = $rgid;
             $ruleGroup->find(true);
             $session = CRM_Core_Session::singleton();
             $session->setStatus("No possible duplicates were found using {$ruleGroup->name} rule.");
             $url = CRM_Utils_System::url('civicrm/contact/deduperules', "reset=1");
             if ($context == 'search') {
                 $url = $session->readUserContext();
             }
             CRM_Utils_System::redirect($url);
         } else {
             $cids = array();
             foreach ($foundDupes as $dupe) {
                 $cids[$dupe[0]] = 1;
                 $cids[$dupe[1]] = 1;
             }
             $cidString = implode(', ', array_keys($cids));
             $sql = "SELECT id, display_name FROM civicrm_contact WHERE id IN ({$cidString}) ORDER BY sort_name";
             $dao = new CRM_Core_DAO();
             $dao->query($sql);
             $displayNames = array();
             while ($dao->fetch()) {
                 $displayNames[$dao->id] = $dao->display_name;
             }
             // FIXME: sort the contacts; $displayName
             // is already sort_name-sorted, so use that
             // (also, consider sorting by dupe count first)
             // lobo - change the sort to by threshold value
             // so the more likely dupes are sorted first
             $session = CRM_Core_Session::singleton();
             $userId = $session->get('userID');
             $mainContacts = array();
             foreach ($foundDupes as $dupes) {
                 $srcID = $dupes[0];
                 $dstID = $dupes[1];
                 if ($dstID == $userId) {
                     $srcID = $dupes[1];
                     $dstID = $dupes[0];
                 }
                 $canMerge = CRM_Contact_BAO_Contact_Permission::allow($dstID, CRM_Core_Permission::EDIT) && CRM_Contact_BAO_Contact_Permission::allow($srcID, CRM_Core_Permission::EDIT);
                 $mainContacts[] = array('srcID' => $srcID, 'srcName' => $displayNames[$srcID], 'dstID' => $dstID, 'dstName' => $displayNames[$dstID], 'weight' => $dupes[2], 'canMerge' => $canMerge);
             }
             if ($cid) {
                 $this->_cid = $cid;
             }
             if ($gid) {
                 $this->_gid = $gid;
             }
             $this->_rgid = $rgid;
             $this->_mainContacts = $mainContacts;
             $session = CRM_Core_Session::singleton();
             if ($this->_cid) {
                 $session->pushUserContext(CRM_Utils_System::url('civicrm/contact/deduperules', "action=update&rgid={$this->_rgid}&gid={$this->_gid}&cid={$this->_cid}"));
             } else {
                 $session->pushUserContext(CRM_Utils_System::url('civicrm/contact/dedupefind', "reset=1&action=update&rgid={$this->_rgid}"));
             }
         }
         $this->assign('action', $this->action);
         $this->browse();
     } else {
         $this->action = CRM_Core_Action::UPDATE;
         $this->edit($this->action);
         $this->assign('action', $this->action);
     }
     $this->assign('context', $context);
     // parent run
     parent::run();
 }
Exemple #4
0
 public function testBatchMergeAllDuplicates()
 {
     $this->createDupeContacts();
     // verify that all contacts have been created separately
     $this->assertEquals(count($this->_contactIds), 9, 'Check for number of contacts.');
     $dao = new CRM_Dedupe_DAO_RuleGroup();
     $dao->contact_type = 'Individual';
     $dao->name = 'IndividualSupervised';
     $dao->is_default = 1;
     $dao->find(TRUE);
     $foundDupes = CRM_Dedupe_Finder::dupesInGroup($dao->id, $this->_groupId);
     // -------------------------------------------------------------------------
     // Name and Email (reserved) Matches ( 3 pairs )
     // --------------------------------------------------------------------------
     // robin  - hood - robin@example.com
     // robin  - hood - robin@example.com
     // little - dale - dale@example.com
     // little - dale - dale@example.com
     // will   - dale - will@example.com
     // will   - dale - will@example.com
     // so 3 pairs for - first + last + mail
     $this->assertEquals(count($foundDupes), 3, 'Check Individual-Supervised dupe rule for dupesInGroup().');
     // Run dedupe finder as the browser would
     $_SERVER['REQUEST_METHOD'] = 'GET';
     //avoid invalid key error
     $object = new CRM_Contact_Page_DedupeFind();
     $object->set('gid', $this->_groupId);
     $object->set('rgid', $dao->id);
     $object->set('action', CRM_Core_Action::UPDATE);
     @$object->run();
     // Retrieve pairs from prev next cache table
     $select = array('pn.is_selected' => 'is_selected');
     $cacheKeyString = "merge Individual_{$dao->id}_{$this->_groupId}";
     $pnDupePairs = CRM_Core_BAO_PrevNextCache::retrieve($cacheKeyString, NULL, NULL, 0, 0, $select);
     $this->assertEquals(count($foundDupes), count($pnDupePairs), 'Check number of dupe pairs in prev next cache.');
     // batch merge all dupes
     $result = CRM_Dedupe_Merger::batchMerge($dao->id, $this->_groupId, 'safe', TRUE, 5, 2);
     $this->assertEquals(count($result['merged']), 3, 'Check number of merged pairs.');
     // retrieve pairs from prev next cache table
     $pnDupePairs = CRM_Core_BAO_PrevNextCache::retrieve($cacheKeyString, NULL, NULL, 0, 0, $select);
     $this->assertEquals(count($pnDupePairs), 0, 'Check number of remaining dupe pairs in prev next cache.');
     $this->deleteDupeContacts();
 }
 /**
  * @param int $rgid
  * @param int $gid
  * @param NULL $cacheKeyString
  *
  * @return bool
  */
 public static function refillCache($rgid = NULL, $gid = NULL, $cacheKeyString = NULL)
 {
     if (!$cacheKeyString && $rgid) {
         $contactType = CRM_Core_DAO::getFieldValue('CRM_Dedupe_DAO_RuleGroup', $rgid, 'contact_type');
         $cacheKeyString = "merge {$contactType}";
         $cacheKeyString .= $rgid ? "_{$rgid}" : '_0';
         $cacheKeyString .= $gid ? "_{$gid}" : '_0';
     }
     if (!$cacheKeyString) {
         return FALSE;
     }
     // 1. Clear cache if any
     $sql = "DELETE FROM civicrm_prevnext_cache WHERE  cacheKey LIKE %1";
     CRM_Core_DAO::executeQuery($sql, array(1 => array("{$cacheKeyString}%", 'String')));
     // FIXME: we need to start using temp tables / queries here instead of arrays.
     // And cleanup code in CRM/Contact/Page/DedupeFind.php
     // 2. FILL cache
     $foundDupes = array();
     if ($rgid && $gid) {
         $foundDupes = CRM_Dedupe_Finder::dupesInGroup($rgid, $gid);
     } elseif ($rgid) {
         $foundDupes = CRM_Dedupe_Finder::dupes($rgid);
     }
     if (!empty($foundDupes)) {
         $cids = $displayNames = $values = array();
         foreach ($foundDupes as $dupe) {
             $cids[$dupe[0]] = 1;
             $cids[$dupe[1]] = 1;
         }
         $cidString = implode(', ', array_keys($cids));
         $sql = "SELECT id, display_name FROM civicrm_contact WHERE id IN ({$cidString}) ORDER BY sort_name";
         $dao = new CRM_Core_DAO();
         $dao->query($sql);
         while ($dao->fetch()) {
             $displayNames[$dao->id] = $dao->display_name;
         }
         $session = CRM_Core_Session::singleton();
         $userId = $session->get('userID');
         foreach ($foundDupes as $dupes) {
             $srcID = $dupes[0];
             $dstID = $dupes[1];
             if ($dstID == $userId) {
                 $srcID = $dupes[1];
                 $dstID = $dupes[0];
             }
             $row = array('srcID' => $srcID, 'srcName' => $displayNames[$srcID], 'dstID' => $dstID, 'dstName' => $displayNames[$dstID], 'weight' => $dupes[2], 'canMerge' => TRUE);
             $data = CRM_Core_DAO::escapeString(serialize($row));
             $values[] = " ( 'civicrm_contact', {$srcID}, {$dstID}, '{$cacheKeyString}', '{$data}' ) ";
         }
         self::setItem($values);
     }
 }
 /**
  * Repopulate the cache of merge prospects.
  *
  * @param int $rgid
  * @param int $gid
  * @param NULL $cacheKeyString
  * @param array $criteria
  *   Additional criteria to filter by.
  *
  * @param bool $checkPermissions
  *   Respect logged in user's permissions.
  *
  * @return bool
  * @throws \CRM_Core_Exception
  * @throws \CiviCRM_API3_Exception
  */
 public static function refillCache($rgid, $gid, $cacheKeyString, $criteria, $checkPermissions)
 {
     if (!$cacheKeyString && $rgid) {
         $cacheKeyString = CRM_Dedupe_Merger::getMergeCacheKeyString($rgid, $gid, $criteria, $checkPermissions);
     }
     if (!$cacheKeyString) {
         return FALSE;
     }
     // 1. Clear cache if any
     $sql = "DELETE FROM civicrm_prevnext_cache WHERE  cacheKey LIKE %1";
     CRM_Core_DAO::executeQuery($sql, array(1 => array("{$cacheKeyString}%", 'String')));
     // FIXME: we need to start using temp tables / queries here instead of arrays.
     // And cleanup code in CRM/Contact/Page/DedupeFind.php
     // 2. FILL cache
     $foundDupes = array();
     if ($rgid && $gid) {
         $foundDupes = CRM_Dedupe_Finder::dupesInGroup($rgid, $gid);
     } elseif ($rgid) {
         $contactIDs = array();
         if (!empty($criteria)) {
             $contacts = civicrm_api3('Contact', 'get', array_merge(array('options' => array('limit' => 0), 'return' => 'id'), $criteria['contact']));
             $contactIDs = array_keys($contacts['values']);
         }
         $foundDupes = CRM_Dedupe_Finder::dupes($rgid, $contactIDs, $checkPermissions);
     }
     if (!empty($foundDupes)) {
         CRM_Dedupe_Finder::parseAndStoreDupePairs($foundDupes, $cacheKeyString);
     }
 }
Exemple #7
0
 /**
  * Browse all rule groups.
  */
 public function run()
 {
     $gid = CRM_Utils_Request::retrieve('gid', 'Positive', $this, FALSE, 0);
     $action = CRM_Utils_Request::retrieve('action', 'String', $this, FALSE, 0);
     $context = CRM_Utils_Request::retrieve('context', 'String', $this);
     $limit = CRM_Utils_Request::retrieve('limit', 'Integer', $this);
     $rgid = CRM_Utils_Request::retrieve('rgid', 'Positive');
     $urlQry = "reset=1&rgid={$rgid}&gid={$gid}&limit={$limit}";
     $this->assign('urlQuery', $urlQry);
     $session = CRM_Core_Session::singleton();
     $contactIds = $session->get('selectedSearchContactIds');
     if ($context == 'search' || !empty($contactIds)) {
         $context = 'search';
         $this->assign('backURL', $session->readUserContext());
     }
     if ($action & CRM_Core_Action::RENEW) {
         // empty cache
         if ($rgid) {
             CRM_Core_BAO_PrevNextCache::deleteItem(NULL, CRM_Dedupe_Merger::getMergeCacheKeyString($rgid, $gid));
         }
         CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contact/dedupefind', $urlQry . "&action=update"));
     } elseif ($action & CRM_Core_Action::MAP) {
         // do a batch merge if requested
         $result = CRM_Dedupe_Merger::batchMerge($rgid, $gid, 'safe', TRUE, 75);
         $skippedCount = CRM_Utils_Request::retrieve('skipped', 'Positive', $this, FALSE, 0);
         $skippedCount = $skippedCount + count($result['skipped']);
         $mergedCount = CRM_Utils_Request::retrieve('merged', 'Positive', $this, FALSE, 0);
         $mergedCount = $mergedCount + count($result['merged']);
         if (empty($result['merged']) && empty($result['skipped'])) {
             $message = '';
             if ($mergedCount >= 1) {
                 $message = ts("%1 pairs of duplicates were merged", array(1 => $mergedCount));
             }
             if ($skippedCount >= 1) {
                 $message = $message ? "{$message} and " : '';
                 $message .= ts("%1 pairs of duplicates were skipped due to conflict", array(1 => $skippedCount));
             }
             $message .= ts(" during the batch merge process with safe mode.");
             CRM_Core_Session::setStatus($message, ts('Merge Complete'), 'success');
             CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contact/dedupefind', $urlQry . "&action=update"));
         } else {
             $urlQry .= "&action=map&skipped={$skippedCount}&merged={$mergedCount}";
             CRM_Utils_System::jsRedirect(CRM_Utils_System::url('civicrm/contact/dedupefind', $urlQry), ts('Batch Merge Task in progress'), ts('The batch merge task is still in progress. This page will be refreshed automatically.'));
         }
     }
     if ($action & CRM_Core_Action::UPDATE || $action & CRM_Core_Action::BROWSE) {
         $cid = CRM_Utils_Request::retrieve('cid', 'Positive', $this, FALSE, 0);
         $this->action = CRM_Core_Action::UPDATE;
         $urlQry .= '&snippet=4';
         if ($context == 'conflicts') {
             $urlQry .= "&selected=1";
         }
         $this->assign('sourceUrl', CRM_Utils_System::url('civicrm/ajax/dedupefind', $urlQry, FALSE, NULL, FALSE));
         //reload from cache table
         $cacheKeyString = CRM_Dedupe_Merger::getMergeCacheKeyString($rgid, $gid);
         $stats = CRM_Dedupe_Merger::getMergeStatsMsg($cacheKeyString);
         if ($stats) {
             CRM_Core_Session::setStatus($stats);
             // reset so we not displaying same message again
             CRM_Dedupe_Merger::resetMergeStats($cacheKeyString);
         }
         $join = CRM_Dedupe_Merger::getJoinOnDedupeTable();
         $where = "de.id IS NULL";
         if ($context == 'conflicts') {
             $where .= " AND pn.is_selected = 1";
         }
         $this->_mainContacts = CRM_Core_BAO_PrevNextCache::retrieve($cacheKeyString, $join, $where);
         if (empty($this->_mainContacts)) {
             if ($context == 'conflicts') {
                 // if the current screen was intended to list only selected contacts, move back to full dupe list
                 CRM_Utils_System::redirect(CRM_Utils_System::url(CRM_Utils_System::currentPath(), $urlQry . '&action=update'));
             }
             if ($gid) {
                 $foundDupes = $this->get("dedupe_dupes_{$gid}");
                 if (!$foundDupes) {
                     $foundDupes = CRM_Dedupe_Finder::dupesInGroup($rgid, $gid, $limit);
                 }
                 $this->set("dedupe_dupes_{$gid}", $foundDupes);
             } elseif (!empty($contactIds)) {
                 $foundDupes = $this->get("search_dedupe_dupes_{$gid}");
                 if (!$foundDupes) {
                     $foundDupes = CRM_Dedupe_Finder::dupes($rgid, $contactIds);
                 }
                 $this->set("search_dedupe_dupes_{$gid}", $foundDupes);
             } else {
                 $foundDupes = $this->get('dedupe_dupes');
                 if (!$foundDupes) {
                     $foundDupes = CRM_Dedupe_Finder::dupes($rgid, array(), TRUE, $limit);
                 }
                 $this->set('dedupe_dupes', $foundDupes);
             }
             if (!$foundDupes) {
                 $ruleGroup = new CRM_Dedupe_BAO_RuleGroup();
                 $ruleGroup->id = $rgid;
                 $ruleGroup->find(TRUE);
                 $session = CRM_Core_Session::singleton();
                 $session->setStatus(ts('No possible duplicates were found using %1 rule.', array(1 => $ruleGroup->name)), ts('None Found'), 'info');
                 $url = CRM_Utils_System::url('civicrm/contact/deduperules', 'reset=1');
                 if ($context == 'search') {
                     $url = $session->readUserContext();
                 }
                 CRM_Utils_System::redirect($url);
             } else {
                 $mainContacts = CRM_Dedupe_Finder::parseAndStoreDupePairs($foundDupes, $cacheKeyString);
                 if ($cid) {
                     $this->_cid = $cid;
                 }
                 if ($gid) {
                     $this->_gid = $gid;
                 }
                 $this->_rgid = $rgid;
                 $this->_mainContacts = $mainContacts;
                 $session = CRM_Core_Session::singleton();
                 if ($this->_cid) {
                     $session->pushUserContext(CRM_Utils_System::url('civicrm/contact/deduperules', $urlQry . "&action=update&cid={$this->_cid}"));
                 } else {
                     $session->pushUserContext(CRM_Utils_System::url('civicrm/contact/dedupefind', $urlQry . "&action=update"));
                 }
             }
         } else {
             if ($cid) {
                 $this->_cid = $cid;
             }
             if ($gid) {
                 $this->_gid = $gid;
             }
             $this->_rgid = $rgid;
         }
         $this->assign('action', $this->action);
         $this->browse();
     } else {
         $this->action = CRM_Core_Action::UPDATE;
         $this->edit($this->action);
         $this->assign('action', $this->action);
     }
     $this->assign('context', $context);
     // parent run
     return parent::run();
 }