jenkins-bot has submitted this change and it was merged. ( 
https://gerrit.wikimedia.org/r/373155 )

Change subject: Add ability to find duplicates for selected contacts.
......................................................................


Add ability to find duplicates for selected contacts.

Notes:

- This is not in my mind a final implementation. I wish to merge to core as 
part of
extracting the code to an extension & version iteration & hence some choices 
may not
be permanent
- In the extension context the addition of the task may be by hook rather than
adding to the array. I could not see any reason for the weird CONST numbering 
scheme in core
for the task list & ignored it.
- I wanted to confirm whether it is necessary to extend the task class
which seems unwieldly to me & so have done this just extending CRM_Core_Form.
-It occurs to me there are 2 separate actions we are interested in
  1) select a bunch of contacts & find all the matches for them (based on either
default rule or selecting a rule).
  2) dedupe the contacts selected against each other.

The patch here adds an action to contact search results (Find duplicates for 
these contacts)
that uses the default rule to find all matches for selected contacts. This is 
the simpler
option of those listed. Implementing 2 will require some more work on the 
cacheKey mechanism
since we are trying to by-pass the rules.

Normally I would try to focus on what I can get into core first but in this case
I'm looking for a user win & to explore the code more to plan the next step
upstream, which will involve refactoring.

Bug: T151270

Change-Id: I2da53510e879c6260be8cee4a455d4a0a2d54693
---
M CRM/Contact/Form/Merge.php
A CRM/Contact/Form/Task/FindDuplicates.php
M CRM/Contact/Page/AJAX.php
M CRM/Contact/Page/DedupeFind.php
M CRM/Contact/Page/DedupeMerge.php
M CRM/Contact/Task.php
M templates/CRM/Contact/Page/DedupeFind.tpl
7 files changed, 138 insertions(+), 17 deletions(-)

Approvals:
  jenkins-bot: Verified
  Ejegg: Looks good to me, approved



diff --git a/CRM/Contact/Form/Merge.php b/CRM/Contact/Form/Merge.php
index 6381852..1be1904 100644
--- a/CRM/Contact/Form/Merge.php
+++ b/CRM/Contact/Form/Merge.php
@@ -45,6 +45,11 @@
   var $_contactType = NULL;
 
   /**
+   * @var array
+   */
+  public $criteria = array();
+
+  /**
    * Query limit to be retained in the urls.
    *
    * @var int
@@ -74,7 +79,9 @@
       $this->_gid = $gid = CRM_Utils_Request::retrieve('gid', 'Positive', 
$this, FALSE);
       $this->_mergeId = CRM_Utils_Request::retrieve('mergeId', 'Positive', 
$this, FALSE);
       $this->limit = CRM_Utils_Request::retrieve('limit', 'Positive', $this, 
FALSE);
-      $urlParams = "reset=1&rgid={$this->_rgid}&gid={$this->_gid}&limit=" . 
$this->limit;
+      $this->criteria = CRM_Utils_Request::retrieve('criteria', 'String', 
$this, FALSE, '{}');
+
+      $urlParams = "reset=1&rgid={$this->_rgid}&gid={$this->_gid}&limit=" . 
$this->limit . '&criteria=' . $this->criteria;
 
       $this->bounceIfInvalid($this->_cid, $this->_oid);
 
@@ -83,7 +90,7 @@
         'return' => 'contact_type',
       ));
 
-      $browseUrl = CRM_Utils_System::url('civicrm/contact/dedupefind', 
$urlParams . '&action=browse');
+      $browseUrl = CRM_Utils_System::url('civicrm/contact/dedupefind', 
$urlParams . '&action=browse', FALSE, NULL, FALSE);
 
       if (!$this->_rgid) {
         // Unset browse URL as we have come from the search screen.
@@ -99,7 +106,7 @@
         CRM_Core_Session::singleton()->pushUserContext($browseUrl);
       }
 
-      $cacheKey = CRM_Dedupe_Merger::getMergeCacheKeyString($this->_rgid, 
$gid);
+      $cacheKey = CRM_Dedupe_Merger::getMergeCacheKeyString($this->_rgid, 
$gid, json_decode($this->criteria, TRUE));
 
       $join = CRM_Dedupe_Merger::getJoinOnDedupeTable();
       $where = "de.id IS NULL";
@@ -126,7 +133,7 @@
       }
 
       $flipUrl = CRM_Utils_System::url('civicrm/contact/merge',
-        
"reset=1&action=update&cid={$this->_oid}&oid={$this->_cid}&rgid={$this->_rgid}&gid={$gid}"
+        
"reset=1&action=update&cid={$this->_oid}&oid={$this->_cid}&rgid={$this->_rgid}&gid={$gid}&criteria={$this->criteria}"
       );
       if (!$flip) {
         $flipUrl .= '&flip=1';
@@ -294,7 +301,7 @@
     CRM_Core_Session::setStatus($message, ts('Contacts Merged'), 'success');
 
     $url = CRM_Utils_System::url('civicrm/contact/view', 
"reset=1&cid={$this->_cid}");
-    $urlParams = 
"reset=1&gid={$this->_gid}&rgid={$this->_rgid}&limit={$this->limit}";
+    $urlParams = "reset=1&rgid={$this->_rgid}&gid={$this->_gid}&limit=" . 
$this->limit . '&criteria=' . $this->criteria;
 
     if (!empty($formValues['_qf_Merge_submit'])) {
       $urlParams .= "&action=update";
@@ -308,7 +315,7 @@
     }
 
     if ($this->next && $this->_mergeId) {
-      $cacheKey = CRM_Dedupe_Merger::getMergeCacheKeyString($this->_rgid, 
$this->_gid);
+      $cacheKey = CRM_Dedupe_Merger::getMergeCacheKeyString($this->_rgid, 
$this->_gid, json_decode($this->criteria, TRUE));
 
       $join = CRM_Dedupe_Merger::getJoinOnDedupeTable();
       $where = "de.id IS NULL";
@@ -321,7 +328,7 @@
       ) {
 
         $urlParams .= 
"&cid={$pos['next']['id1']}&oid={$pos['next']['id2']}&mergeId={$pos['next']['mergeId']}&action=update";
-        $url = CRM_Utils_System::url('civicrm/contact/merge', $urlParams);
+        $url = CRM_Utils_System::url('civicrm/contact/merge', $urlParams, 
FALSE, NULL, FALSE);
       }
     }
 
diff --git a/CRM/Contact/Form/Task/FindDuplicates.php 
b/CRM/Contact/Form/Task/FindDuplicates.php
new file mode 100644
index 0000000..cc7cfa6
--- /dev/null
+++ b/CRM/Contact/Form/Task/FindDuplicates.php
@@ -0,0 +1,89 @@
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 4.7                                                |
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC (c) 2004-2017                                |
+ +--------------------------------------------------------------------+
+ | This file is a part of CiviCRM.                                    |
+ |                                                                    |
+ | CiviCRM is free software; you can copy, modify, and distribute it  |
+ | under the terms of the GNU Affero General Public License           |
+ | Version 3, 19 November 2007 and the CiviCRM Licensing Exception.   |
+ |                                                                    |
+ | CiviCRM is distributed in the hope that it will be useful, but     |
+ | WITHOUT ANY WARRANTY; without even the implied warranty of         |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.               |
+ | See the GNU Affero General Public License for more details.        |
+ |                                                                    |
+ | You should have received a copy of the GNU Affero General Public   |
+ | License and the CiviCRM Licensing Exception along                  |
+ | with this program; if not, contact CiviCRM LLC                     |
+ | at info[AT]civicrm[DOT]org. If you have questions about the        |
+ | GNU Affero General Public License or the licensing of CiviCRM,     |
+ | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
+ +--------------------------------------------------------------------+
+ */
+
+/**
+ *
+ * @package CRM
+ * @copyright CiviCRM LLC (c) 2004-2017
+ */
+
+/**
+ * This class provides the functionality to find potential matches.
+ */
+class CRM_Contact_Form_Task_FindDuplicates extends CRM_Core_Form {
+
+  /**
+   * Name of temporary table holding contacts.
+   *
+   * @var string
+   */
+  public $_componentTable;
+
+  /**
+   * Selected contact ids.
+   *
+   * @var array
+   */
+  public $_contactIds = array();
+
+  /**
+   * Build all the data structures needed to build the form.
+   */
+  public function preProcess() {
+    CRM_Contact_Form_Task::preProcessCommon($this, TRUE);
+    // Some issues with how we are passing these need dealing with at some 
stage.
+    // ie. switch to dedupe table first & load. For now limit.
+    $limit = 100;
+    $contactIDs = CRM_Core_DAO::singleValueQuery('SELECT 
GROUP_CONCAT(contact_id) FROM (SELECT contact_id FROM ' . 
$this->_componentTable . " LIMIT {$limit}) as d");
+    $contactType = CRM_Core_DAO::singleValueQuery(
+      "SELECT GROUP_CONCAT(DISTINCT contact_type) FROM civicrm_contact WHERE 
id IN ({$contactIDs}) "
+    );
+
+    if (CRM_Core_DAO::singleValueQuery("SELECT count(*) FROM 
{$this->_componentTable}") > $limit) {
+      CRM_Core_Session::setStatus(ts("Only the first $limit have been selected 
for deduping"));
+    }
+    try {
+      $rule_group_id = civicrm_api3('RuleGroup', 'getvalue', array(
+        'contact_type' => $contactType,
+        'used' => 'Unsupervised',
+        'return' => 'id',
+        'options' => array('limit' => 1),
+      ));
+    }
+    catch (CiviCRM_API3_Exception $e) {
+      CRM_Core_Error::statusBounce(ts('It was not possible to identify a 
default rule that was applicable to all selected contacts. You must choose only 
one contact type. You chose %1', array($contactType)));
+    }
+
+    
CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contact/dedupefind', 
array(
+      'reset' => 1,
+      'action' => 'update',
+      'rgid' => $rule_group_id,
+      'criteria' => json_encode(array('contact' => array('id' => array('IN' => 
explode(',', $contactIDs))))),
+      'limit' => count($contactIDs),
+    )));
+  }
+}
\ No newline at end of file
diff --git a/CRM/Contact/Page/AJAX.php b/CRM/Contact/Page/AJAX.php
index cfdff39..6d861b9 100644
--- a/CRM/Contact/Page/AJAX.php
+++ b/CRM/Contact/Page/AJAX.php
@@ -649,13 +649,16 @@
 
     $gid = CRM_Utils_Request::retrieve('gid', 'Positive');
     $rgid = CRM_Utils_Request::retrieve('rgid', 'Positive');
+    $null = NULL;
+    $criteria = CRM_Utils_Request::retrieve('criteria', 'String', $null, 
FALSE, '{}');
     $selected    = isset($_REQUEST['selected']) ? 
CRM_Utils_Type::escape($_REQUEST['selected'], 'Integer') : 0;
     if ($rowCount < 0) {
       $rowCount = 0;
     }
 
     $whereClause = $orderByClause = '';
-    $cacheKeyString   = CRM_Dedupe_Merger::getMergeCacheKeyString($rgid, $gid);
+    $cacheKeyString   = CRM_Dedupe_Merger::getMergeCacheKeyString($rgid, $gid, 
json_decode($criteria, TRUE));
+
     $searchRows       = array();
 
     $searchParams = self::getSearchOptionsFromRequest();
@@ -811,7 +814,7 @@
       $searchRows[$count]['weight'] = CRM_Utils_Array::value('weight', $pair);
 
       if (!empty($pairInfo['data']['canMerge'])) {
-        $mergeParams = 
"reset=1&cid={$pairInfo['entity_id1']}&oid={$pairInfo['entity_id2']}&action=update&rgid={$rgid}&limit="
 . CRM_Utils_Request::retrieve('limit', 'Integer');
+        $mergeParams = 
"reset=1&cid={$pairInfo['entity_id1']}&oid={$pairInfo['entity_id2']}&action=update&rgid={$rgid}&criteria={$criteria}&limit="
 . CRM_Utils_Request::retrieve('limit', 'Integer');
         if ($gid) {
           $mergeParams .= "&gid={$gid}";
         }
@@ -1010,8 +1013,9 @@
     $gid  = CRM_Utils_Type::escape($_REQUEST['gid'], 'Integer');
     $pnid = $_REQUEST['pnid'];
     $isSelected = CRM_Utils_Type::escape($_REQUEST['is_selected'], 'Boolean');
+    $criteria = CRM_Utils_Request::retrieve('criteria', 'String', $null, 
FALSE, '{}');
 
-    $cacheKeyString = CRM_Dedupe_Merger::getMergeCacheKeyString($rgid, $gid);
+    $cacheKeyString = CRM_Dedupe_Merger::getMergeCacheKeyString($rgid, $gid, 
json_decode($criteria, TRUE));
 
     $params = array(
       1 => array($isSelected, 'Boolean'),
diff --git a/CRM/Contact/Page/DedupeFind.php b/CRM/Contact/Page/DedupeFind.php
index 5b09ef6..decfdbc 100644
--- a/CRM/Contact/Page/DedupeFind.php
+++ b/CRM/Contact/Page/DedupeFind.php
@@ -63,8 +63,9 @@
     $limit = CRM_Utils_Request::retrieve('limit', 'Integer', $this);
     $rgid = CRM_Utils_Request::retrieve('rgid', 'Positive', $this);
     $cid = CRM_Utils_Request::retrieve('cid', 'Positive', $this, FALSE, 0);
-    // Using a placeholder for criteria as it is intended to be able to pass 
this later.
-    $criteria = array();
+    $criteria = CRM_Utils_Request::retrieve('criteria', 'String', $this, 
FALSE, '{}');
+    $this->assign('criteria', $criteria);
+
     $isConflictMode = ($context == 'conflicts');
     if ($cid) {
       $this->_cid = $cid;
@@ -79,8 +80,10 @@
       'rgid' => $rgid,
       'gid' => $gid,
       'limit' => $limit,
+      'criteria' => $criteria,
     );
     $this->assign('urlQuery', CRM_Utils_System::makeQueryString($urlQry));
+    $criteria = json_decode($criteria, TRUE);
 
     if ($context == 'search') {
       $context = 'search';
diff --git a/CRM/Contact/Page/DedupeMerge.php b/CRM/Contact/Page/DedupeMerge.php
index df91a14..1c95481 100644
--- a/CRM/Contact/Page/DedupeMerge.php
+++ b/CRM/Contact/Page/DedupeMerge.php
@@ -55,15 +55,25 @@
    * Build a queue of tasks by dividing dupe pairs in batches.
    */
   public static function getRunner() {
+    $null = NULL;
     $rgid = CRM_Utils_Request::retrieve('rgid', 'Positive');
     $gid  = CRM_Utils_Request::retrieve('gid', 'Positive');
     $limit  = CRM_Utils_Request::retrieve('limit', 'Positive');
     $action = CRM_Utils_Request::retrieve('action', 'String');
-    $mode   = CRM_Utils_Request::retrieve('mode', 'String', 
CRM_Core_DAO::$_nullObject, FALSE, 'safe');
+    $mode   = CRM_Utils_Request::retrieve('mode', 'String', $null, FALSE, 
'safe');
+    $criteria = CRM_Utils_Request::retrieve('criteria', 'String', $null, 
FALSE, '{}');
 
-    $cacheKeyString = CRM_Dedupe_Merger::getMergeCacheKeyString($rgid, $gid);
+    $urlQry = array(
+      'reset' => 1,
+      'action' => 'update',
+      'rgid' => $rgid,
+      'gid' => $gid,
+      'limit' => $limit,
+      'criteria' => $criteria,
+    );
 
-    $urlQry = "reset=1&action=update&rgid={$rgid}&gid={$gid}&limit={$limit}";
+    $criteria = json_decode($criteria, TRUE);
+    $cacheKeyString = CRM_Dedupe_Merger::getMergeCacheKeyString($rgid, $gid, 
$criteria);
 
     if ($mode == 'aggressive' && !CRM_Core_Permission::check('force merge 
duplicate contacts')) {
       CRM_Core_Session::setStatus(ts('You do not have permission to force 
merge duplicate contact records'), ts('Permission Denied'), 'error');
diff --git a/CRM/Contact/Task.php b/CRM/Contact/Task.php
index 503c511..d78200d 100644
--- a/CRM/Contact/Task.php
+++ b/CRM/Contact/Task.php
@@ -228,6 +228,11 @@
           'class' => 'CRM_Contact_Form_Task_Merge',
           'result' => TRUE,
         );
+        self::$_tasks['find_duplicates'] = array(
+          'title' => ts('Find duplicates for these contacts'),
+          'class' => 'CRM_Contact_Form_Task_FindDuplicates',
+          'result' => TRUE,
+        );
       }
 
       //CRM-4418, check for delete
diff --git a/templates/CRM/Contact/Page/DedupeFind.tpl 
b/templates/CRM/Contact/Page/DedupeFind.tpl
index c770655..ca4e491 100644
--- a/templates/CRM/Contact/Page/DedupeFind.tpl
+++ b/templates/CRM/Contact/Page/DedupeFind.tpl
@@ -122,7 +122,7 @@
       {foreach from=$dupe_contacts[$cid] item=dupe_name key=dupe_id}
         {if $dupe_name}
           {capture assign=link}<a href="{crmURL p='civicrm/contact/view' 
q="reset=1&cid=$dupe_id"}">{$dupe_name}</a>{/capture}
-          {capture assign=merge}<a href="{crmURL p='civicrm/contact/merge' 
q="reset=1&cid=$cid&oid=$dupe_id"}">{ts}merge{/ts}</a>{/capture}
+          {capture assign=merge}<a href="{crmURL p='civicrm/contact/merge' 
q="`$urlQuery`&reset=1&cid=$cid&oid=$dupe_id"}">{ts}merfe{/ts}</a>{/capture}
           <tr class="{cycle values="odd-row,even-row"}">
       <td>{$link}</td>
       <td style="text-align: right">{$merge}</td>
@@ -339,6 +339,9 @@
       var is_selected = CRM.$('.crm-dedupe-select-all').prop('checked') ? 1 : 
0;
     }
 
+    var criteria = {/literal}'{$criteria}'{literal};
+    criteria  = criteria.length > 0 ? criteria : 0;
+
     var dataUrl = {/literal}"{crmURL p='civicrm/ajax/toggleDedupeSelect' h=0 
q='snippet=4'}"{literal};
     var rgid = {/literal}"{$rgid}"{literal};
     var gid = {/literal}"{$gid}"{literal};
@@ -346,7 +349,7 @@
     rgid = rgid.length > 0 ? rgid : 0;
     gid  = gid.length > 0 ? gid : 0;
 
-    CRM.$.post(dataUrl, {pnid: id, rgid: rgid, gid: gid, is_selected: 
is_selected}, function (data) {
+    CRM.$.post(dataUrl, {pnid: id, rgid: rgid, gid: gid, is_selected: 
is_selected, criteria : criteria}, function (data) {
       // nothing to do for now
     }, 'json');
   }

-- 
To view, visit https://gerrit.wikimedia.org/r/373155
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I2da53510e879c6260be8cee4a455d4a0a2d54693
Gerrit-PatchSet: 16
Gerrit-Project: wikimedia/fundraising/crm/civicrm
Gerrit-Branch: master
Gerrit-Owner: Eileen <emcnaugh...@wikimedia.org>
Gerrit-Reviewer: Eileen <emcnaugh...@wikimedia.org>
Gerrit-Reviewer: Ejegg <ej...@ejegg.com>
Gerrit-Reviewer: Mepps <me...@wikimedia.org>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to