3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.3 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2013 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
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. |
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. |
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 +--------------------------------------------------------------------+
31 * @copyright CiviCRM LLC (c) 2004-2013
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
42 // the id of the other contact - the duplicate one that will get deleted
45 var $_contactType = NULL;
47 // variable to keep all location block ids.
48 protected $_locBlockIds = array();
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';
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'));
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);
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);
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'))));
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';
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";
84 $pos = CRM_Core_BAO_PrevNextCache
::getPositions($cacheKey, $cid, $oid, $this->_mergeId
, $join, $where, $flip);
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
)
90 CRM_Utils_System
::permissionDenied();
93 // get user info of main contact.
94 $config = CRM_Core_Config
::singleton();
95 $config->doNotResetCache
= 1;
97 $viewUser = CRM_Core_Permission
::check('access user profiles');
98 $mainUfId = CRM_Core_BAO_UFMatch
::getUFId($cid);
102 if ($config->userSystem
->is_drupal
== '1') {
103 $mainUser = user_load($mainUfId);
105 elseif ($config->userFramework
== 'Joomla') {
106 $mainUser = JFactory
::getUser($mainUfId);
109 $this->assign('mainUfId', $mainUfId);
110 $this->assign('mainUfName', $mainUser ?
$mainUser->name
: NULL);
113 $flipUrl = CRM_Utils_system
::url('civicrm/contact/merge',
114 "reset=1&action=update&cid={$oid}&oid={$cid}&rgid={$rgid}&gid={$gid}"
117 $flipUrl .= '&flip=1';
119 $this->assign('flip', $flipUrl);
121 $this->prev
= $this->next
= NULL;
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";
129 $urlParam .= "&rgid={$rgid}";
132 $urlParam .= "&gid={$gid}";
135 $this->$position = CRM_Utils_system
::url('civicrm/contact/merge', $urlParam);
136 $this->assign($position, $this->$position);
141 // get user info of other contact.
142 $otherUfId = CRM_Core_BAO_UFMatch
::getUFId($oid);
147 if ($config->userSystem
->is_drupal
== '1') {
148 $otherUser = user_load($otherUfId);
150 elseif ($config->userFramework
== 'Joomla') {
151 $otherUser = JFactory
::getUser($otherUfId);
154 $this->assign('otherUfId', $otherUfId);
155 $this->assign('otherUfName', $otherUser ?
$otherUser->name
: NULL);
158 $cmsUser = ($mainUfId && $otherUfId) ?
TRUE : FALSE;
159 $this->assign('user', $cmsUser);
161 $session = CRM_Core_Session
::singleton();
165 $urlParam = "reset=1&action=browse&rgid={$rgid}";
167 $urlParam .= "&gid={$gid}";
169 $session->pushUserContext(CRM_Utils_system
::url('civicrm/contact/dedupefind', $urlParam));
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)
178 CRM_Core_Error
::statusBounce($message);
181 $rowsElementsAndInfo = CRM_Dedupe_Merger
::getRowsElementsAndInfo($cid, $oid);
182 $main = &$rowsElementsAndInfo['main_details'];
183 $other = &$rowsElementsAndInfo['other_details'];
185 if ($main['contact_id'] != $cid) {
186 CRM_Core_Error
::fatal(ts('The main contact record does not exist'));
189 if ($other['contact_id'] != $oid) {
190 CRM_Core_Error
::fatal(ts('The other contact record does not exist'));
193 $subtypes = CRM_Contact_BAO_ContactType
::subTypePairs(NULL, TRUE, '');
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]])
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]])
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']);
213 $this->_rgid
= $rgid;
214 $this->_contactType
= $main['contact_type'];
215 $this->addElement('checkbox', 'toggleSelect', NULL, NULL, array('onclick' => "return toggleCheckboxVals('move_',this);"));
217 $this->assign('mainLocBlock', json_encode($rowsElementsAndInfo['main_loc_block']));
218 $this->assign('rows', $rowsElementsAndInfo['rows']);
220 $this->_locBlockIds
= array(
221 'main' => $rowsElementsAndInfo['main_details']['loc_block_ids'],
222 'other' => $rowsElementsAndInfo['other_details']['loc_block_ids']
226 foreach ($rowsElementsAndInfo['elements'] as $element) {
227 $this->addElement($element[0],
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
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);
242 $this->assign('rel_tables', $rowsElementsAndInfo['rel_tables']);
243 $this->assign('userContextURL', $session->readUserContext());
246 function setDefaultValues() {
247 return array('deleteOther' => 1);
250 function addRules() {}
252 public function buildQuickForm() {
253 CRM_Utils_System
::setTitle(ts('Merge %1s', array(1 => $this->_contactType
)));
256 $name = ts('Merge and Goto Next Pair');
259 if ($this->next ||
$this->prev
) {
268 'name' => ts('Merge and Goto Listing'),
272 'name' => ts('Merge and View Result'),
276 'name' => ts('Cancel'),
289 'name' => ts('Cancel'),
294 $this->addButtons($button);
297 public function postProcess() {
298 $formValues = $this->exportValues();
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');
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'];
312 CRM_Dedupe_Merger
::moveAllBelongings($this->_cid
, $this->_oid
, $formValues);
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}";
319 $listParamsURL .= "&gid={$this->_gid}";
321 $lisitingURL = CRM_Utils_System
::url('civicrm/contact/dedupefind',
324 CRM_Utils_System
::redirect($lisitingURL);
326 if (CRM_Utils_Array
::value('_qf_Merge_done', $formValues)) {
327 CRM_Utils_System
::redirect($url);
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';
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";
339 $pos = CRM_Core_BAO_PrevNextCache
::getPositions($cacheKey, NULL, NULL, $this->_mergeId
, $join, $where);
342 $pos['next']['id1'] &&
346 $urlParam = "reset=1&cid={$pos['next']['id1']}&oid={$pos['next']['id2']}&mergeId={$pos['next']['mergeId']}&action=update";
348 $urlParam .= "&rgid={$this->_rgid}";
351 $urlParam .= "&gid={$this->_gid}";
354 $url = CRM_Utils_system
::url('civicrm/contact/merge', $urlParam);
358 CRM_Utils_System
::redirect($url);