CRM-18958 add limit to dedupe screen
authoreileen <emcnaughton@wikimedia.org>
Wed, 15 Jun 2016 02:31:29 +0000 (14:31 +1200)
committereileen <emcnaughton@wikimedia.org>
Sat, 25 Jun 2016 01:07:03 +0000 (13:07 +1200)
CRM/Contact/BAO/Group.php
CRM/Contact/Form/DedupeFind.php
CRM/Contact/Page/DedupeFind.php
CRM/Dedupe/BAO/RuleGroup.php
CRM/Dedupe/Finder.php
templates/CRM/Contact/Form/DedupeFind.tpl

index 075d926d70cf184d60799c44928233dc7beb4dac..df0ae58ae88151a2c6907f6fc215ea7f6bbb1ba4 100644 (file)
@@ -193,14 +193,16 @@ class CRM_Contact_BAO_Group extends CRM_Contact_DAO_Group {
    *
    * @param int $groupID
    * @param bool $useCache
+   * @param int $limit
+   *   Number to limit to (or 0 for unlimited).
    *
    * @return array
    *   this array contains the list of members for this group id
    */
-  public static function &getMember($groupID, $useCache = TRUE) {
+  public static function getMember($groupID, $useCache = TRUE, $limit = 0) {
     $params = array(array('group', '=', $groupID, 0, 0));
     $returnProperties = array('contact_id');
-    list($contacts, $_) = CRM_Contact_BAO_Query::apiQuery($params, $returnProperties, NULL, NULL, 0, 0, $useCache);
+    list($contacts) = CRM_Contact_BAO_Query::apiQuery($params, $returnProperties, NULL, NULL, 0, $limit, $useCache);
 
     $aMembers = array();
     foreach ($contacts as $contact) {
index cf8bb23b8ff00a8eb482ebb851cbe40862a8c67a..a6717bc3051b76e0e3c2335d8f50130284ed7835 100644 (file)
@@ -51,6 +51,7 @@ class CRM_Contact_Form_DedupeFind extends CRM_Admin_Form {
     $groupList = array('' => ts('- All Contacts -')) + CRM_Core_PseudoConstant::nestedGroup();
 
     $this->add('select', 'group_id', ts('Select Group'), $groupList, FALSE, array('class' => 'crm-select2 huge'));
+    $this->add('text', 'limit', ts('No of contacts to find matches for '));
     $this->addButtons(array(
         array(
           'type' => 'next',
@@ -69,6 +70,7 @@ class CRM_Contact_Form_DedupeFind extends CRM_Admin_Form {
   }
 
   public function setDefaultValues() {
+    $this->_defaults['limit'] = 1000;
     return $this->_defaults;
   }
 
@@ -82,11 +84,13 @@ class CRM_Contact_Form_DedupeFind extends CRM_Admin_Form {
       CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contact/deduperules', 'reset=1'));
       return;
     }
+    $url = CRM_Utils_System::url('civicrm/contact/dedupefind', "reset=1&action=update&rgid={$this->rgid}");
     if ($values['group_id']) {
-      $url = CRM_Utils_System::url('civicrm/contact/dedupefind', "reset=1&action=update&rgid={$this->rgid}&gid={$values['group_id']}");
+      $url .= "&gid={$values['group_id']}";
     }
-    else {
-      $url = CRM_Utils_System::url('civicrm/contact/dedupefind', "reset=1&action=update&rgid={$this->rgid}");
+
+    if ($values['limit']) {
+      $url .= '&limit=' . $values['limit'];
     }
 
     CRM_Utils_System::redirect($url);
index 498981eefa45e5664d5714c08cad36cbcb38a0b3..4bc94a6a1e8ee39e7acd4143ab9adbb4f4bf47c9 100644 (file)
@@ -59,6 +59,7 @@ class CRM_Contact_Page_DedupeFind extends CRM_Core_Page_Basic {
     $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);
 
     $session = CRM_Core_Session::singleton();
     $contactIds = $session->get('selectedSearchContactIds');
@@ -174,7 +175,7 @@ class CRM_Contact_Page_DedupeFind extends CRM_Core_Page_Basic {
         if ($gid) {
           $foundDupes = $this->get("dedupe_dupes_$gid");
           if (!$foundDupes) {
-            $foundDupes = CRM_Dedupe_Finder::dupesInGroup($rgid, $gid);
+            $foundDupes = CRM_Dedupe_Finder::dupesInGroup($rgid, $gid, $limit);
           }
           $this->set("dedupe_dupes_$gid", $foundDupes);
         }
@@ -188,7 +189,7 @@ class CRM_Contact_Page_DedupeFind extends CRM_Core_Page_Basic {
         else {
           $foundDupes = $this->get('dedupe_dupes');
           if (!$foundDupes) {
-            $foundDupes = CRM_Dedupe_Finder::dupes($rgid);
+            $foundDupes = CRM_Dedupe_Finder::dupes($rgid, array(), TRUE, $limit);
           }
           $this->set('dedupe_dupes', $foundDupes);
         }
@@ -225,8 +226,7 @@ class CRM_Contact_Page_DedupeFind extends CRM_Core_Page_Basic {
           // (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');
+          $userId = CRM_Core_Session::singleton()->getLoggedInContactID();
           $mainContacts = $permission = array();
 
           foreach ($foundDupes as $dupes) {
index 56081b4036aaaded1578cceb4b41b6c8c898787b..5ac720a49e85279a475dcb8610320a953fa126ee 100644 (file)
@@ -44,6 +44,15 @@ class CRM_Dedupe_BAO_RuleGroup extends CRM_Dedupe_DAO_RuleGroup {
    */
   var $contactIds = array();
 
+  /**
+   * Set the contact IDs to restrict the dedupe to.
+   *
+   * @param array $contactIds
+   */
+  public function setContactIds($contactIds) {
+    $this->contactIds = $contactIds;
+  }
+
   /**
    * Params to dedupe against (queries against the whole contact set otherwise)
    */
@@ -142,10 +151,8 @@ class CRM_Dedupe_BAO_RuleGroup extends CRM_Dedupe_DAO_RuleGroup {
     if ($this->is_reserved &&
       CRM_Utils_File::isIncludable("CRM/Dedupe/BAO/QueryBuilder/{$this->name}.php")
     ) {
-      include_once "CRM/Dedupe/BAO/QueryBuilder/{$this->name}.php";
-      $class = "CRM_Dedupe_BAO_QueryBuilder_{$this->name}";
       $command = empty($this->params) ? 'internal' : 'record';
-      $queries = call_user_func(array($class, $command), $this);
+      $queries = call_user_func(array("CRM_Dedupe_BAO_QueryBuilder_{$this->name}", $command), $this);
     }
     else {
       // All other rule groups have queries generated by the member dedupe
index 38fdf81e7aff8ffb10254f2a887c0bd5b4598731..02e937c48b48ee01afd0526039dd7f4edb6fdffe 100644 (file)
@@ -55,13 +55,21 @@ class CRM_Dedupe_Finder {
    *   Array of (cid1, cid2, weight) dupe triples
    * @throws \Exception
    */
-  public static function dupes($rgid, $cids = array(), $checkPermissions = TRUE) {
+  public static function dupes($rgid, $cids = array(), $checkPermissions = TRUE, $limit = NULL) {
     $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($limit)) {
+      $limitedContacts = civicrm_api3('Contact', 'get', array(
+        'return' => 'id',
+        'contact_type' => $rgBao->contact_type,
+        'options' => array('limit' => $limit),
+      ));
+      $rgBao->contactIds = array_keys($limitedContacts['values']);
+    }
 
     $rgBao->fillTable();
     $dao = new CRM_Core_DAO();
@@ -153,11 +161,12 @@ class CRM_Dedupe_Finder {
    * @param int $gid
    *   Contact group id (currently, works only with non-smart groups).
    *
+   * @param int $limit
    * @return array
    *   array of (cid1, cid2, weight) dupe triples
    */
-  public static function dupesInGroup($rgid, $gid) {
-    $cids = array_keys(CRM_Contact_BAO_Group::getMember($gid));
+  public static function dupesInGroup($rgid, $gid, $limit = NULL) {
+    $cids = array_keys(CRM_Contact_BAO_Group::getMember($gid, $limit));
     if (!empty($cids)) {
       return self::dupes($rgid, $cids);
     }
index 457d84d1edb8f7504c01ba3da9bb25a0d19baca9..f3d993107302c6ecc4678def728aeeeed0ae9dfb 100644 (file)
 *}
 <div class="crm-block crm-form-block crm-dedupe-find-form-block">
 <div class="help">
-    {ts}You can search all contacts for duplicates or limit the search to a specific group.{/ts}
+    {ts}You can search all contacts for duplicates or limit the results for better performance.
+      If you limit by group then it will look for matches with that group both inside and outside of the group.
+      You can also limit the contacts in the group to be matched by specifying the number of contacts to match. This can be done in conjunction with a group or separately and is recommended for performance reasons.
+    {/ts}
 </div>
    <div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location="top"}</div>
    <table class="form-layout-compressed">
        <td class="label">{$form.group_id.label}</td>
        <td>{$form.group_id.html}</td>
      </tr>
+       <tr class="crm-dedupe-find-form-block-limit">
+        <td class="label">{$form.limit.label}</td>
+        <td>{$form.limit.html}</td>
+       </tr>
    </table>
   <div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location="bottom"}</div>
 </div>