Commit | Line | Data |
---|---|---|
6a488035 TO |
1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
4 | | CiviCRM version 4.3 | | |
5 | +--------------------------------------------------------------------+ | |
6 | | Copyright CiviCRM LLC (c) 2004-2013 | | |
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-2013 | |
32 | * $Id$ | |
33 | * | |
34 | */ | |
35 | ||
36 | require_once 'api/api.php'; | |
37 | class CRM_Contact_Form_Merge extends CRM_Core_Form { | |
38 | // the id of the contact that tere's a duplicate for; this one will | |
39 | // possibly inherit some of $_oid's properties and remain in the system | |
40 | var $_cid = NULL; | |
41 | ||
42 | // the id of the other contact - the duplicate one that will get deleted | |
43 | var $_oid = NULL; | |
44 | ||
45 | var $_contactType = NULL; | |
46 | ||
47 | // variable to keep all location block ids. | |
48 | protected $_locBlockIds = array(); | |
49 | ||
50 | // FIXME: QuickForm can't create advcheckboxes with value set to 0 or '0' :( | |
51 | // see HTML_QuickForm_advcheckbox::setValues() - but patching that doesn't | |
52 | // help, as QF doesn't put the 0-value elements in exportValues() anyway... | |
53 | // to side-step this, we use the below UUID as a (re)placeholder | |
54 | var $_qfZeroBug = 'e8cddb72-a257-11dc-b9cc-0016d3330ee9'; | |
55 | ||
56 | function preProcess() { | |
57 | if (!CRM_Core_Permission::check('merge duplicate contacts')) { | |
58 | CRM_Core_Error::fatal(ts('You do not have access to this page')); | |
59 | } | |
60 | ||
61 | $rows = array(); | |
62 | $cid = CRM_Utils_Request::retrieve('cid', 'Positive', $this, TRUE); | |
63 | $oid = CRM_Utils_Request::retrieve('oid', 'Positive', $this, TRUE); | |
64 | $flip = CRM_Utils_Request::retrieve('flip', 'Positive', $this, FALSE); | |
65 | ||
66 | $this->_rgid = $rgid = CRM_Utils_Request::retrieve('rgid', 'Positive', $this, FALSE); | |
67 | $this->_gid = $gid = CRM_Utils_Request::retrieve('gid', 'Positive', $this, FALSE); | |
68 | $this->_mergeId = CRM_Utils_Request::retrieve('mergeId', 'Positive', $this, FALSE); | |
69 | ||
70 | if (!CRM_Dedupe_BAO_Rule::validateContacts($cid, $oid)) { | |
71 | CRM_Core_Error::statusBounce(ts('The selected pair of contacts are marked as non duplicates. If these records should be merged, you can remove this exception on the <a href=\'%1\'>Dedupe Exceptions</a> page.', array(1 => CRM_Utils_System::url('civicrm/dedupe/exception', 'reset=1')))); | |
72 | } | |
73 | ||
74 | //load cache mechanism | |
75 | $contactType = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $cid, 'contact_type'); | |
76 | $cacheKey = "merge $contactType"; | |
77 | $cacheKey .= $rgid ? "_{$rgid}" : '_0'; | |
78 | $cacheKey .= $gid ? "_{$gid}" : '_0'; | |
79 | ||
80 | $join = "LEFT JOIN civicrm_dedupe_exception de ON ( pn.entity_id1 = de.contact_id1 AND | |
81 | pn.entity_id2 = de.contact_id2 )"; | |
82 | $where = "de.id IS NULL"; | |
83 | ||
84 | $pos = CRM_Core_BAO_PrevNextCache::getPositions($cacheKey, $cid, $oid, $this->_mergeId, $join, $where, $flip); | |
85 | ||
86 | // Block access if user does not have EDIT permissions for both contacts. | |
87 | if (!(CRM_Contact_BAO_Contact_Permission::allow($cid, CRM_Core_Permission::EDIT) && | |
88 | CRM_Contact_BAO_Contact_Permission::allow($oid, CRM_Core_Permission::EDIT) | |
89 | )) { | |
90 | CRM_Utils_System::permissionDenied(); | |
91 | } | |
92 | ||
93 | // get user info of main contact. | |
94 | $config = CRM_Core_Config::singleton(); | |
95 | $config->doNotResetCache = 1; | |
96 | ||
97 | $viewUser = CRM_Core_Permission::check('access user profiles'); | |
98 | $mainUfId = CRM_Core_BAO_UFMatch::getUFId($cid); | |
99 | $mainUser = NULL; | |
100 | if ($mainUfId) { | |
101 | // d6 compatible | |
102 | if ($config->userSystem->is_drupal == '1') { | |
103 | $mainUser = user_load($mainUfId); | |
104 | } | |
105 | elseif ($config->userFramework == 'Joomla') { | |
106 | $mainUser = JFactory::getUser($mainUfId); | |
107 | } | |
108 | ||
109 | $this->assign('mainUfId', $mainUfId); | |
110 | $this->assign('mainUfName', $mainUser ? $mainUser->name : NULL); | |
111 | } | |
112 | ||
113 | $flipUrl = CRM_Utils_system::url('civicrm/contact/merge', | |
114 | "reset=1&action=update&cid={$oid}&oid={$cid}&rgid={$rgid}&gid={$gid}" | |
115 | ); | |
116 | if (!$flip) { | |
117 | $flipUrl .= '&flip=1'; | |
118 | } | |
119 | $this->assign('flip', $flipUrl); | |
120 | ||
121 | $this->prev = $this->next = NULL; | |
122 | foreach (array( | |
123 | 'prev', 'next') as $position) { | |
124 | if (!empty($pos[$position])) { | |
125 | if ($pos[$position]['id1'] && $pos[$position]['id2']) { | |
126 | $urlParam = "reset=1&cid={$pos[$position]['id1']}&oid={$pos[$position]['id2']}&mergeId={$pos[$position]['mergeId']}&action=update"; | |
127 | ||
128 | if ($rgid) { | |
129 | $urlParam .= "&rgid={$rgid}"; | |
130 | } | |
131 | if ($gid) { | |
132 | $urlParam .= "&gid={$gid}"; | |
133 | } | |
134 | ||
135 | $this->$position = CRM_Utils_system::url('civicrm/contact/merge', $urlParam); | |
136 | $this->assign($position, $this->$position); | |
137 | } | |
138 | } | |
139 | } | |
140 | ||
141 | // get user info of other contact. | |
142 | $otherUfId = CRM_Core_BAO_UFMatch::getUFId($oid); | |
143 | $otherUser = NULL; | |
144 | ||
145 | if ($otherUfId) { | |
146 | // d6 compatible | |
147 | if ($config->userSystem->is_drupal == '1') { | |
148 | $otherUser = user_load($otherUfId); | |
149 | } | |
150 | elseif ($config->userFramework == 'Joomla') { | |
151 | $otherUser = JFactory::getUser($otherUfId); | |
152 | } | |
153 | ||
154 | $this->assign('otherUfId', $otherUfId); | |
155 | $this->assign('otherUfName', $otherUser ? $otherUser->name : NULL); | |
156 | } | |
157 | ||
158 | $cmsUser = ($mainUfId && $otherUfId) ? TRUE : FALSE; | |
159 | $this->assign('user', $cmsUser); | |
160 | ||
161 | $session = CRM_Core_Session::singleton(); | |
162 | ||
163 | // context fixed. | |
164 | if ($rgid) { | |
165 | $urlParam = "reset=1&action=browse&rgid={$rgid}"; | |
166 | if ($gid) { | |
167 | $urlParam .= "&gid={$gid}"; | |
168 | } | |
169 | $session->pushUserContext(CRM_Utils_system::url('civicrm/contact/dedupefind', $urlParam)); | |
170 | } | |
171 | ||
172 | // ensure that oid is not the current user, if so refuse to do the merge | |
173 | if ($session->get('userID') == $oid) { | |
174 | $display_name = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $oid, 'display_name'); | |
175 | $message = ts('The contact record which is linked to the currently logged in user account - \'%1\' - cannot be deleted.', | |
176 | array(1 => $display_name) | |
177 | ); | |
178 | CRM_Core_Error::statusBounce($message); | |
179 | } | |
180 | ||
181 | $rowsElementsAndInfo = CRM_Dedupe_Merger::getRowsElementsAndInfo($cid, $oid); | |
182 | $main = &$rowsElementsAndInfo['main_details']; | |
183 | $other = &$rowsElementsAndInfo['other_details']; | |
184 | ||
185 | if ($main['contact_id'] != $cid) { | |
186 | CRM_Core_Error::fatal(ts('The main contact record does not exist')); | |
187 | } | |
188 | ||
189 | if ($other['contact_id'] != $oid) { | |
190 | CRM_Core_Error::fatal(ts('The other contact record does not exist')); | |
191 | } | |
192 | ||
193 | $subtypes = CRM_Contact_BAO_ContactType::subTypePairs(NULL, TRUE, ''); | |
194 | ||
195 | $this->assign('contact_type', $main['contact_type']); | |
196 | if (isset($main['contact_sub_type'])) { | |
197 | $this->assign('main_contact_subtype', | |
198 | CRM_Utils_Array::value('contact_sub_type', $subtypes[$main['contact_sub_type'][0]]) | |
199 | ); | |
200 | } | |
201 | if (isset($other['contact_sub_type'])) { | |
202 | $this->assign('other_contact_subtype', | |
203 | CRM_Utils_Array::value('contact_sub_type', $subtypes[$other['contact_sub_type'][0]]) | |
204 | ); | |
205 | } | |
206 | $this->assign('main_name', $main['display_name']); | |
207 | $this->assign('other_name', $other['display_name']); | |
208 | $this->assign('main_cid', $main['contact_id']); | |
209 | $this->assign('other_cid', $other['contact_id']); | |
210 | ||
211 | $this->_cid = $cid; | |
212 | $this->_oid = $oid; | |
213 | $this->_rgid = $rgid; | |
214 | $this->_contactType = $main['contact_type']; | |
215 | $this->addElement('checkbox', 'toggleSelect', NULL, NULL, array('onclick' => "return toggleCheckboxVals('move_',this);")); | |
216 | ||
217 | $this->assign('mainLocBlock', json_encode($rowsElementsAndInfo['main_loc_block'])); | |
218 | $this->assign('rows', $rowsElementsAndInfo['rows']); | |
219 | ||
220 | $this->_locBlockIds = array( | |
221 | 'main' => $rowsElementsAndInfo['main_details']['loc_block_ids'], | |
222 | 'other' => $rowsElementsAndInfo['other_details']['loc_block_ids'] | |
223 | ); | |
224 | ||
225 | // add elements | |
226 | foreach ($rowsElementsAndInfo['elements'] as $element) { | |
227 | $this->addElement($element[0], | |
228 | $element[1], | |
229 | array_key_exists('2', $element) ? $element[2] : NULL, | |
230 | array_key_exists('3', $element) ? $element[3] : NULL, | |
231 | array_key_exists('4', $element) ? $element[4] : NULL, | |
232 | array_key_exists('5', $element) ? $element[5] : NULL | |
233 | ); | |
234 | } | |
235 | ||
236 | // add related table elements | |
237 | foreach ($rowsElementsAndInfo['rel_table_elements'] as $relTableElement) { | |
238 | $element = $this->addElement($relTableElement[0], $relTableElement[1]); | |
239 | $element->setChecked(TRUE); | |
240 | } | |
241 | ||
242 | $this->assign('rel_tables', $rowsElementsAndInfo['rel_tables']); | |
243 | $this->assign('userContextURL', $session->readUserContext()); | |
244 | } | |
245 | ||
246 | function setDefaultValues() { | |
247 | return array('deleteOther' => 1); | |
248 | } | |
249 | ||
250 | function addRules() {} | |
251 | ||
252 | public function buildQuickForm() { | |
253 | CRM_Utils_System::setTitle(ts('Merge %1s', array(1 => $this->_contactType))); | |
254 | $name = ts('Merge'); | |
255 | if ($this->next) { | |
256 | $name = ts('Merge and Goto Next Pair'); | |
257 | } | |
258 | ||
259 | if ($this->next || $this->prev) { | |
260 | $button = array( | |
261 | array( | |
262 | 'type' => 'next', | |
263 | 'name' => $name, | |
264 | 'isDefault' => TRUE, | |
265 | ), | |
266 | array( | |
267 | 'type' => 'submit', | |
268 | 'name' => ts('Merge and Goto Listing'), | |
269 | ), | |
270 | array( | |
271 | 'type' => 'done', | |
272 | 'name' => ts('Merge and View Result'), | |
273 | ), | |
274 | array( | |
275 | 'type' => 'cancel', | |
276 | 'name' => ts('Cancel'), | |
277 | ), | |
278 | ); | |
279 | } | |
280 | else { | |
281 | $button = array( | |
282 | array( | |
283 | 'type' => 'next', | |
284 | 'name' => $name, | |
285 | 'isDefault' => TRUE, | |
286 | ), | |
287 | array( | |
288 | 'type' => 'cancel', | |
289 | 'name' => ts('Cancel'), | |
290 | ), | |
291 | ); | |
292 | } | |
293 | ||
294 | $this->addButtons($button); | |
295 | } | |
296 | ||
297 | public function postProcess() { | |
298 | $formValues = $this->exportValues(); | |
299 | ||
300 | // reset all selected contact ids from session | |
301 | // when we came from search context, CRM-3526 | |
302 | $session = CRM_Core_Session::singleton(); | |
303 | if ($session->get('selectedSearchContactIds')) { | |
304 | $session->resetScope('selectedSearchContactIds'); | |
305 | } | |
306 | ||
307 | $formValues['main_details'] = $formValues['other_details'] = array(); | |
308 | $formValues['main_details']['contact_type'] = $this->_contactType; | |
309 | $formValues['main_details']['loc_block_ids'] = $this->_locBlockIds['main']; | |
310 | $formValues['other_details']['loc_block_ids'] = $this->_locBlockIds['other']; | |
311 | ||
312 | CRM_Dedupe_Merger::moveAllBelongings($this->_cid, $this->_oid, $formValues); | |
313 | ||
314 | CRM_Core_Session::setStatus(ts('Contact id %1 has been updated and contact id %2 has been deleted.', array(1 => $this->_cid, 2 => $this->_oid)), ts('Contacts Merged'), 'success'); | |
315 | $url = CRM_Utils_System::url('civicrm/contact/view', "reset=1&cid={$this->_cid}"); | |
316 | if (CRM_Utils_Array::value('_qf_Merge_submit', $formValues)) { | |
317 | $listParamsURL = "reset=1&action=update&rgid={$this->_rgid}"; | |
318 | if ($this->_gid) { | |
319 | $listParamsURL .= "&gid={$this->_gid}"; | |
320 | } | |
321 | $lisitingURL = CRM_Utils_System::url('civicrm/contact/dedupefind', | |
322 | $listParamsURL | |
323 | ); | |
324 | CRM_Utils_System::redirect($lisitingURL); | |
325 | } | |
326 | if (CRM_Utils_Array::value('_qf_Merge_done', $formValues)) { | |
327 | CRM_Utils_System::redirect($url); | |
328 | } | |
329 | ||
330 | if ($this->next && $this->_mergeId) { | |
331 | $cacheKey = "merge {$this->_contactType}"; | |
332 | $cacheKey .= $this->_rgid ? "_{$this->_rgid}" : '_0'; | |
333 | $cacheKey .= $this->_gid ? "_{$this->_gid}" : '_0'; | |
334 | ||
335 | $join = "LEFT JOIN civicrm_dedupe_exception de ON ( pn.entity_id1 = de.contact_id1 AND | |
336 | pn.entity_id2 = de.contact_id2 )"; | |
337 | $where = "de.id IS NULL"; | |
338 | ||
339 | $pos = CRM_Core_BAO_PrevNextCache::getPositions($cacheKey, NULL, NULL, $this->_mergeId, $join, $where); | |
340 | ||
341 | if (!empty($pos) && | |
342 | $pos['next']['id1'] && | |
343 | $pos['next']['id2'] | |
344 | ) { | |
345 | ||
346 | $urlParam = "reset=1&cid={$pos['next']['id1']}&oid={$pos['next']['id2']}&mergeId={$pos['next']['mergeId']}&action=update"; | |
347 | if ($this->_rgid) { | |
348 | $urlParam .= "&rgid={$this->_rgid}"; | |
349 | } | |
350 | if ($this->_gid) { | |
351 | $urlParam .= "&gid={$this->_gid}"; | |
352 | } | |
353 | ||
354 | $url = CRM_Utils_system::url('civicrm/contact/merge', $urlParam); | |
355 | } | |
356 | } | |
357 | ||
358 | CRM_Utils_System::redirect($url); | |
359 | } | |
360 | } | |
361 |