CRM-19035 Remove code duplication in the processing of duplicate matches
[civicrm-core.git] / CRM / Contact / Page / DedupeFind.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.7 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2016 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
26 */
27
28 /**
29 *
30 * @package CRM
31 * @copyright CiviCRM LLC (c) 2004-2016
32 */
33 class CRM_Contact_Page_DedupeFind extends CRM_Core_Page_Basic {
34 protected $_cid = NULL;
35 protected $_rgid;
36 protected $_mainContacts;
37 protected $_gid;
38
39 /**
40 * Get BAO Name.
41 *
42 * @return string
43 * Classname of BAO.
44 */
45 public function getBAOName() {
46 return 'CRM_Dedupe_BAO_RuleGroup';
47 }
48
49 /**
50 * Get action Links.
51 */
52 public function &links() {
53 }
54
55 /**
56 * Browse all rule groups.
57 */
58 public function run() {
59 $gid = CRM_Utils_Request::retrieve('gid', 'Positive', $this, FALSE, 0);
60 $action = CRM_Utils_Request::retrieve('action', 'String', $this, FALSE, 0);
61 $context = CRM_Utils_Request::retrieve('context', 'String', $this);
62 $limit = CRM_Utils_Request::retrieve('limit', 'Integer', $this);
63
64 $session = CRM_Core_Session::singleton();
65 $contactIds = $session->get('selectedSearchContactIds');
66 if ($context == 'search' || !empty($contactIds)) {
67 $context = 'search';
68 $this->assign('backURL', $session->readUserContext());
69 }
70
71 if ($action & CRM_Core_Action::RENEW) {
72 // empty cache
73 $rgid = CRM_Utils_Request::retrieve('rgid', 'Positive', $this, FALSE, 0);
74
75 if ($rgid) {
76 CRM_Core_BAO_PrevNextCache::deleteItem(NULL, CRM_Dedupe_Merger::getMergeCacheKeyString($rgid, $gid));
77 }
78 $urlQry = "reset=1&action=update&rgid={$rgid}";
79 if ($gid) {
80 $urlQry .= "&gid={$gid}";
81 }
82 CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contact/dedupefind', $urlQry));
83 }
84 elseif ($action & CRM_Core_Action::MAP) {
85 // do a batch merge if requested
86 $rgid = CRM_Utils_Request::retrieve('rgid', 'Positive', $this, FALSE, 0);
87 $result = CRM_Dedupe_Merger::batchMerge($rgid, $gid, 'safe', TRUE, 75);
88
89 $skippedCount = CRM_Utils_Request::retrieve('skipped', 'Positive', $this, FALSE, 0);
90 $skippedCount = $skippedCount + count($result['skipped']);
91 $mergedCount = CRM_Utils_Request::retrieve('merged', 'Positive', $this, FALSE, 0);
92 $mergedCount = $mergedCount + count($result['merged']);
93
94 if (empty($result['merged']) && empty($result['skipped'])) {
95 $message = '';
96 if ($mergedCount >= 1) {
97 $message = ts("%1 pairs of duplicates were merged", array(1 => $mergedCount));
98 }
99 if ($skippedCount >= 1) {
100 $message = $message ? "{$message} and " : '';
101 $message .= ts("%1 pairs of duplicates were skipped due to conflict",
102 array(1 => $skippedCount)
103 );
104 }
105 $message .= ts(" during the batch merge process with safe mode.");
106 CRM_Core_Session::setStatus($message, ts('Merge Complete'), 'success');
107
108 $urlQry = "reset=1&action=update&rgid={$rgid}";
109 if ($gid) {
110 $urlQry .= "&gid={$gid}";
111 }
112 CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contact/dedupefind', $urlQry));
113 }
114 else {
115 $urlQry = "reset=1&action=map&rgid={$rgid}";
116 if ($gid) {
117 $urlQry .= "&gid={$gid}";
118 }
119 $urlQry .= "&skipped={$skippedCount}&merged={$mergedCount}";
120 CRM_Utils_System::jsRedirect(
121 CRM_Utils_System::url('civicrm/contact/dedupefind', $urlQry),
122 ts('Batch Merge Task in progress'),
123 ts('The batch merge task is still in progress. This page will be refreshed automatically.')
124 );
125 }
126 }
127
128 if ($action & CRM_Core_Action::UPDATE ||
129 $action & CRM_Core_Action::BROWSE
130 ) {
131 $cid = CRM_Utils_Request::retrieve('cid', 'Positive', $this, FALSE, 0);
132 $rgid = CRM_Utils_Request::retrieve('rgid', 'Positive', $this, FALSE, 0);
133 $this->action = CRM_Core_Action::UPDATE;
134
135 $sourceParams = 'snippet=4';
136 if ($gid) {
137 $sourceParams .= "&gid={$gid}";
138 }
139 if ($rgid) {
140 $sourceParams .= "&rgid={$rgid}";
141 }
142 if ($context == 'conflicts') {
143 $sourceParams .= "&selected=1";
144 }
145
146 $this->assign('sourceUrl', CRM_Utils_System::url('civicrm/ajax/dedupefind', $sourceParams, FALSE, NULL, FALSE));
147
148 //reload from cache table
149 $cacheKeyString = CRM_Dedupe_Merger::getMergeCacheKeyString($rgid, $gid);
150
151 $stats = CRM_Dedupe_Merger::getMergeStatsMsg($cacheKeyString);
152 if ($stats) {
153 CRM_Core_Session::setStatus($stats);
154 // reset so we not displaying same message again
155 CRM_Dedupe_Merger::resetMergeStats($cacheKeyString);
156 }
157 $join = CRM_Dedupe_Merger::getJoinOnDedupeTable();
158 $where = "de.id IS NULL";
159 if ($context == 'conflicts') {
160 $where .= " AND pn.is_selected = 1";
161 }
162 $this->_mainContacts = CRM_Core_BAO_PrevNextCache::retrieve($cacheKeyString, $join, $where);
163 if (empty($this->_mainContacts)) {
164 if ($context == 'conflicts') {
165 // if the current screen was intended to list only selected contacts, move back to full dupe list
166 $sourceParams = 'reset=1&action=update';
167 if ($gid) {
168 $sourceParams .= "&gid={$gid}";
169 }
170 if ($rgid) {
171 $sourceParams .= "&rgid={$rgid}";
172 }
173 CRM_Utils_System::redirect(CRM_Utils_System::url(CRM_Utils_System::currentPath(), $sourceParams));
174 }
175 if ($gid) {
176 $foundDupes = $this->get("dedupe_dupes_$gid");
177 if (!$foundDupes) {
178 $foundDupes = CRM_Dedupe_Finder::dupesInGroup($rgid, $gid, $limit);
179 }
180 $this->set("dedupe_dupes_$gid", $foundDupes);
181 }
182 elseif (!empty($contactIds)) {
183 $foundDupes = $this->get("search_dedupe_dupes_$gid");
184 if (!$foundDupes) {
185 $foundDupes = CRM_Dedupe_Finder::dupes($rgid, $contactIds);
186 }
187 $this->get("search_dedupe_dupes_$gid", $foundDupes);
188 }
189 else {
190 $foundDupes = $this->get('dedupe_dupes');
191 if (!$foundDupes) {
192 $foundDupes = CRM_Dedupe_Finder::dupes($rgid, array(), TRUE, $limit);
193 }
194 $this->set('dedupe_dupes', $foundDupes);
195 }
196 if (!$foundDupes) {
197 $ruleGroup = new CRM_Dedupe_BAO_RuleGroup();
198 $ruleGroup->id = $rgid;
199 $ruleGroup->find(TRUE);
200
201 $session = CRM_Core_Session::singleton();
202 $session->setStatus(ts('No possible duplicates were found using %1 rule.', array(1 => $ruleGroup->name)), ts('None Found'), 'info');
203 $url = CRM_Utils_System::url('civicrm/contact/deduperules', 'reset=1');
204 if ($context == 'search') {
205 $url = $session->readUserContext();
206 }
207 CRM_Utils_System::redirect($url);
208 }
209 else {
210 // FIXME: sort the contacts; $displayName
211 // is already sort_name-sorted, so use that
212 // (also, consider sorting by dupe count first)
213 // lobo - change the sort to by threshold value
214 // so the more likely dupes are sorted first
215
216 $mainContacts = CRM_Dedupe_Finder::parseAndStoreDupePairs($foundDupes, $cacheKeyString);
217
218 if ($cid) {
219 $this->_cid = $cid;
220 }
221 if ($gid) {
222 $this->_gid = $gid;
223 }
224 $this->_rgid = $rgid;
225 $this->_mainContacts = $mainContacts;
226
227 $session = CRM_Core_Session::singleton();
228 if ($this->_cid) {
229 $session->pushUserContext(CRM_Utils_System::url('civicrm/contact/deduperules',
230 "action=update&rgid={$this->_rgid}&gid={$this->_gid}&cid={$this->_cid}"
231 ));
232 }
233 else {
234 $session->pushUserContext(CRM_Utils_System::url('civicrm/contact/dedupefind',
235 "reset=1&action=update&rgid={$this->_rgid}"
236 ));
237 }
238 }
239 }
240 else {
241 if ($cid) {
242 $this->_cid = $cid;
243 }
244 if ($gid) {
245 $this->_gid = $gid;
246 }
247 $this->_rgid = $rgid;
248 }
249
250 $this->assign('action', $this->action);
251 $this->browse();
252 }
253 else {
254 $this->action = CRM_Core_Action::UPDATE;
255 $this->edit($this->action);
256 $this->assign('action', $this->action);
257 }
258 $this->assign('context', $context);
259
260 // parent run
261 return parent::run();
262 }
263
264 /**
265 * Browse all rule groups.
266 */
267 public function browse() {
268 $this->assign('main_contacts', $this->_mainContacts);
269
270 if ($this->_cid) {
271 $this->assign('cid', $this->_cid);
272 }
273 if (isset($this->_gid) || $this->_gid) {
274 $this->assign('gid', $this->_gid);
275 }
276 $this->assign('rgid', $this->_rgid);
277 }
278
279 /**
280 * Get name of edit form.
281 *
282 * @return string
283 * classname of edit form
284 */
285 public function editForm() {
286 return 'CRM_Contact_Form_DedupeFind';
287 }
288
289 /**
290 * Get edit form name.
291 *
292 * @return string
293 * name of this page
294 */
295 public function editName() {
296 return 'DedupeFind';
297 }
298
299 /**
300 * Get user context.
301 *
302 * @param null $mode
303 *
304 * @return string
305 * user context
306 */
307 public function userContext($mode = NULL) {
308 return 'civicrm/contact/dedupefind';
309 }
310
311 }