Esempio n. 1
0
 public function postProcess()
 {
     $formValues = $this->exportValues();
     // reset all selected contact ids from session
     // when we came from search context, CRM-3526
     $session = CRM_Core_Session::singleton();
     if ($session->get('selectedSearchContactIds')) {
         $session->resetScope('selectedSearchContactIds');
     }
     $formValues['main_details'] = $formValues['other_details'] = array();
     $formValues['main_details']['contact_type'] = $this->_contactType;
     $formValues['main_details']['loc_block_ids'] = $this->_locBlockIds['main'];
     $formValues['other_details']['loc_block_ids'] = $this->_locBlockIds['other'];
     CRM_Dedupe_Merger::moveAllBelongings($this->_cid, $this->_oid, $formValues);
     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');
     $url = CRM_Utils_System::url('civicrm/contact/view', "reset=1&cid={$this->_cid}");
     if (CRM_Utils_Array::value('_qf_Merge_submit', $formValues)) {
         $listParamsURL = "reset=1&action=update&rgid={$this->_rgid}";
         if ($this->_gid) {
             $listParamsURL .= "&gid={$this->_gid}";
         }
         $lisitingURL = CRM_Utils_System::url('civicrm/contact/dedupefind', $listParamsURL);
         CRM_Utils_System::redirect($lisitingURL);
     }
     if (CRM_Utils_Array::value('_qf_Merge_done', $formValues)) {
         CRM_Utils_System::redirect($url);
     }
     if ($this->next && $this->_mergeId) {
         $cacheKey = "merge {$this->_contactType}";
         $cacheKey .= $this->_rgid ? "_{$this->_rgid}" : '_0';
         $cacheKey .= $this->_gid ? "_{$this->_gid}" : '_0';
         $join = "LEFT JOIN civicrm_dedupe_exception de ON ( pn.entity_id1 = de.contact_id1 AND\n                                                                 pn.entity_id2 = de.contact_id2 )";
         $where = "de.id IS NULL";
         $pos = CRM_Core_BAO_PrevNextCache::getPositions($cacheKey, NULL, NULL, $this->_mergeId, $join, $where);
         if (!empty($pos) && $pos['next']['id1'] && $pos['next']['id2']) {
             $urlParam = "reset=1&cid={$pos['next']['id1']}&oid={$pos['next']['id2']}&mergeId={$pos['next']['mergeId']}&action=update";
             if ($this->_rgid) {
                 $urlParam .= "&rgid={$this->_rgid}";
             }
             if ($this->_gid) {
                 $urlParam .= "&gid={$this->_gid}";
             }
             $url = CRM_Utils_System::url('civicrm/contact/merge', $urlParam);
         }
     }
     CRM_Utils_System::redirect($url);
 }
Esempio n. 2
0
 /**
  * Merge given set of contacts. Performs core operation.
  *
  * @param array $dupePairs
  *   Set of pair of contacts for whom merge is to be done.
  * @param array $cacheParams
  *   Prev-next-cache params based on which next pair of contacts are computed.
  *                              Generally used with batch-merge.
  * @param string $mode
  *   Helps decide how to behave when there are conflicts.
  *                             A 'safe' value skips the merge if there are any un-resolved conflicts.
  *                             Does a force merge otherwise (aggressive mode).
  * @param bool $autoFlip to let api decide which contact to retain and which to delete.
  *   Wether to let api decide which contact to retain and which to delete.
  *
  *
  * @param bool $redirectForPerformance
  *
  * @return array|bool
  */
 public static function merge($dupePairs = array(), $cacheParams = array(), $mode = 'safe', $autoFlip = TRUE, $redirectForPerformance = FALSE)
 {
     $cacheKeyString = CRM_Utils_Array::value('cache_key_string', $cacheParams);
     $resultStats = array('merged' => array(), 'skipped' => array());
     // we don't want dupe caching to get reset after every-merge, and therefore set the
     // doNotResetCache flag
     $config = CRM_Core_Config::singleton();
     $config->doNotResetCache = 1;
     while (!empty($dupePairs)) {
         foreach ($dupePairs as $dupes) {
             CRM_Utils_Hook::merge('flip', $dupes, $dupes['dstID'], $dupes['srcID']);
             $mainId = $dupes['dstID'];
             $otherId = $dupes['srcID'];
             $isAutoFlip = CRM_Utils_Array::value('auto_flip', $dupes, $autoFlip);
             // if we can, make sure that $mainId is the one with lower id number
             if ($isAutoFlip && $mainId > $otherId) {
                 $mainId = $dupes['srcID'];
                 $otherId = $dupes['dstID'];
             }
             if (!$mainId || !$otherId) {
                 // return error
                 return FALSE;
             }
             // Generate var $migrationInfo. The variable structure is exactly same as
             // $formValues submitted during a UI merge for a pair of contacts.
             $rowsElementsAndInfo = CRM_Dedupe_Merger::getRowsElementsAndInfo($mainId, $otherId);
             $migrationInfo =& $rowsElementsAndInfo['migration_info'];
             // add additional details that we might need to resolve conflicts
             $migrationInfo['main_details'] =& $rowsElementsAndInfo['main_details'];
             $migrationInfo['other_details'] =& $rowsElementsAndInfo['other_details'];
             $migrationInfo['main_loc_block'] =& $rowsElementsAndInfo['main_loc_block'];
             $migrationInfo['rows'] =& $rowsElementsAndInfo['rows'];
             // go ahead with merge if there is no conflict
             if (!CRM_Dedupe_Merger::skipMerge($mainId, $otherId, $migrationInfo, $mode)) {
                 CRM_Dedupe_Merger::moveAllBelongings($mainId, $otherId, $migrationInfo);
                 $resultStats['merged'][] = array('main_id' => $mainId, 'other_id' => $otherId);
             } else {
                 $resultStats['skipped'][] = array('main_id' => $mainId, 'other_id' => $otherId);
             }
             // delete entry from PrevNextCache table so we don't consider the pair next time
             // pair may have been flipped, so make sure we delete using both orders
             CRM_Core_BAO_PrevNextCache::deletePair($mainId, $otherId, $cacheKeyString);
             CRM_Core_BAO_PrevNextCache::deletePair($otherId, $mainId, $cacheKeyString);
             CRM_Core_DAO::freeResult();
             unset($rowsElementsAndInfo, $migrationInfo);
         }
         if ($cacheKeyString && !$redirectForPerformance) {
             // retrieve next pair of dupes
             $dupePairs = CRM_Core_BAO_PrevNextCache::retrieve($cacheKeyString, $cacheParams['join'], $cacheParams['where']);
         } else {
             // do not proceed. Terminate the loop
             unset($dupePairs);
         }
     }
     return $resultStats;
 }
Esempio n. 3
0
 public function postProcess()
 {
     $formValues = $this->exportValues();
     // reset all selected contact ids from session
     // when we came from search context, CRM-3526
     $session = CRM_Core_Session::singleton();
     if ($session->get('selectedSearchContactIds')) {
         $session->resetScope('selectedSearchContactIds');
     }
     $formValues['main_details'] = $this->_mainDetails;
     $formValues['other_details'] = $this->_otherDetails;
     $migrationData = array('migration_info' => $formValues);
     CRM_Utils_Hook::merge('form', $migrationData, $this->_cid, $this->_oid);
     CRM_Dedupe_Merger::moveAllBelongings($this->_cid, $this->_oid, $migrationData['migration_info']);
     $name = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $this->_cid, 'display_name');
     $message = '<ul><li>' . ts('%1 has been updated.', array(1 => $name)) . '</li><li>' . ts('Contact ID %1 has been deleted.', array(1 => $this->_oid)) . '</li></ul>';
     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}";
     if (!empty($formValues['_qf_Merge_submit'])) {
         $urlParams .= "&action=update";
         $lisitingURL = CRM_Utils_System::url('civicrm/contact/dedupefind', $urlParams);
         CRM_Utils_System::redirect($lisitingURL);
     }
     if (!empty($formValues['_qf_Merge_done'])) {
         CRM_Utils_System::redirect($url);
     }
     if ($this->next && $this->_mergeId) {
         $cacheKey = CRM_Dedupe_Merger::getMergeCacheKeyString($this->_rgid, $this->_gid);
         $join = CRM_Dedupe_Merger::getJoinOnDedupeTable();
         $where = "de.id IS NULL";
         $pos = CRM_Core_BAO_PrevNextCache::getPositions($cacheKey, NULL, NULL, $this->_mergeId, $join, $where);
         if (!empty($pos) && $pos['next']['id1'] && $pos['next']['id2']) {
             $urlParams .= "&cid={$pos['next']['id1']}&oid={$pos['next']['id2']}&mergeId={$pos['next']['mergeId']}&action=update";
             $url = CRM_Utils_System::url('civicrm/contact/merge', $urlParams);
         }
     }
     CRM_Utils_System::redirect($url);
 }
Esempio n. 4
0
 public function postProcess()
 {
     $formValues = $this->exportValues();
     // reset all selected contact ids from session
     // when we came from search context, CRM-3526
     $session = CRM_Core_Session::singleton();
     if ($session->get('selectedSearchContactIds')) {
         $session->resetScope('selectedSearchContactIds');
     }
     $formValues['main_details'] = $this->_mainDetails;
     $formValues['other_details'] = $this->_otherDetails;
     CRM_Dedupe_Merger::moveAllBelongings($this->_cid, $this->_oid, $formValues);
     $name = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $this->_cid, 'display_name');
     $message = '<ul><li>' . ts('%1 has been updated.', array(1 => $name)) . '</li><li>' . ts('Contact ID %1 has been deleted.', array(1 => $this->_oid)) . '</li></ul>';
     CRM_Core_Session::setStatus($message, ts('Contacts Merged'), 'success');
     //create activity for merge
     //To do: this should be refactored into BAO layer at some point.
     $messageActivity = ts('Contact ID %1 has been merged and deleted.', array(1 => $this->_oid));
     $activityParams = array('subject' => $messageActivity, 'source_contact_id' => $session->get('userID'), 'target_contact_id' => $this->_cid, 'activity_type_id' => CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_Activity', 'activity_type_id', 'Contact Merged'), 'status_id' => 'Completed', 'priority_id' => 'Normal', 'activity_date_time' => date('YmdHis'));
     civicrm_api3('activity', 'create', $activityParams);
     $url = CRM_Utils_System::url('civicrm/contact/view', "reset=1&cid={$this->_cid}");
     if (!empty($formValues['_qf_Merge_submit'])) {
         $listParamsURL = "reset=1&action=update&rgid={$this->_rgid}";
         if ($this->_gid) {
             $listParamsURL .= "&gid={$this->_gid}";
         }
         $lisitingURL = CRM_Utils_System::url('civicrm/contact/dedupefind', $listParamsURL);
         CRM_Utils_System::redirect($lisitingURL);
     }
     if (!empty($formValues['_qf_Merge_done'])) {
         CRM_Utils_System::redirect($url);
     }
     if ($this->next && $this->_mergeId) {
         $cacheKey = "merge {$this->_contactType}";
         $cacheKey .= $this->_rgid ? "_{$this->_rgid}" : '_0';
         $cacheKey .= $this->_gid ? "_{$this->_gid}" : '_0';
         $join = "LEFT JOIN civicrm_dedupe_exception de ON ( pn.entity_id1 = de.contact_id1 AND\n                                                                 pn.entity_id2 = de.contact_id2 )";
         $where = "de.id IS NULL";
         $pos = CRM_Core_BAO_PrevNextCache::getPositions($cacheKey, NULL, NULL, $this->_mergeId, $join, $where);
         if (!empty($pos) && $pos['next']['id1'] && $pos['next']['id2']) {
             $urlParam = "reset=1&cid={$pos['next']['id1']}&oid={$pos['next']['id2']}&mergeId={$pos['next']['mergeId']}&action=update";
             if ($this->_rgid) {
                 $urlParam .= "&rgid={$this->_rgid}";
             }
             if ($this->_gid) {
                 $urlParam .= "&gid={$this->_gid}";
             }
             $url = CRM_Utils_System::url('civicrm/contact/merge', $urlParam);
         }
     }
     CRM_Utils_System::redirect($url);
 }
Esempio n. 5
0
 /**
  * Dedupe a pair of contacts.
  *
  * @param array $migrationInfo
  * @param array $resultStats
  * @param array $deletedContacts
  * @param string $mode
  * @param bool $checkPermissions
  * @param int $mainId
  * @param int $otherId
  * @param string $cacheKeyString
  */
 protected static function dedupePair(&$migrationInfo, &$resultStats, &$deletedContacts, $mode, $checkPermissions, $mainId, $otherId, $cacheKeyString)
 {
     // go ahead with merge if there is no conflict
     $conflicts = array();
     if (!CRM_Dedupe_Merger::skipMerge($mainId, $otherId, $migrationInfo, $mode, $conflicts)) {
         CRM_Dedupe_Merger::moveAllBelongings($mainId, $otherId, $migrationInfo, $checkPermissions);
         $resultStats['merged'][] = array('main_id' => $mainId, 'other_id' => $otherId);
         $deletedContacts[] = $otherId;
     } else {
         $resultStats['skipped'][] = array('main_id' => $mainId, 'other_id' => $otherId);
     }
     // store any conflicts
     if (!empty($conflicts)) {
         foreach ($conflicts as $key => $dnc) {
             $conflicts[$key] = "{$migrationInfo['rows'][$key]['title']}: '{$migrationInfo['rows'][$key]['main']}' vs. '{$migrationInfo['rows'][$key]['other']}'";
         }
         CRM_Core_BAO_PrevNextCache::markConflict($mainId, $otherId, $cacheKeyString, $conflicts);
     } else {
         // delete entry from PrevNextCache table so we don't consider the pair next time
         // pair may have been flipped, so make sure we delete using both orders
         CRM_Core_BAO_PrevNextCache::deletePair($mainId, $otherId, $cacheKeyString, TRUE);
     }
     CRM_Core_DAO::freeResult();
 }
Esempio n. 6
0
 /**
  * Merge given set of contacts. Performs core operation.
  *
  * @param array $dupePairs
  *   Set of pair of contacts for whom merge is to be done.
  * @param array $cacheParams
  *   Prev-next-cache params based on which next pair of contacts are computed.
  *                              Generally used with batch-merge.
  * @param string $mode
  *   Helps decide how to behave when there are conflicts.
  *                             A 'safe' value skips the merge if there are any un-resolved conflicts.
  *                             Does a force merge otherwise (aggressive mode).
  * @param bool $autoFlip to let api decide which contact to retain and which to delete.
  *   Whether to let api decide which contact to retain and which to delete.
  *
  * @param bool $redirectForPerformance
  *   Redirect to a url for batch processing.
  *
  * @param bool $checkPermissions
  *   Respect logged in user permissions.
  *
  * @return array|bool
  */
 public static function merge($dupePairs = array(), $cacheParams = array(), $mode = 'safe', $autoFlip = TRUE, $redirectForPerformance = FALSE, $checkPermissions = TRUE)
 {
     $cacheKeyString = CRM_Utils_Array::value('cache_key_string', $cacheParams);
     $resultStats = array('merged' => array(), 'skipped' => array());
     // we don't want dupe caching to get reset after every-merge, and therefore set the
     // doNotResetCache flag
     $config = CRM_Core_Config::singleton();
     $config->doNotResetCache = 1;
     $deletedContacts = array();
     while (!empty($dupePairs)) {
         foreach ($dupePairs as $index => $dupes) {
             if (in_array($dupes['dstID'], $deletedContacts) || in_array($dupes['srcID'], $deletedContacts)) {
                 unset($dupePairs[$index]);
                 continue;
             }
             CRM_Utils_Hook::merge('flip', $dupes, $dupes['dstID'], $dupes['srcID']);
             $mainId = $dupes['dstID'];
             $otherId = $dupes['srcID'];
             if (!$mainId || !$otherId) {
                 // return error
                 return FALSE;
             }
             // Generate var $migrationInfo. The variable structure is exactly same as
             // $formValues submitted during a UI merge for a pair of contacts.
             $rowsElementsAndInfo = CRM_Dedupe_Merger::getRowsElementsAndInfo($mainId, $otherId, $checkPermissions);
             $migrationInfo =& $rowsElementsAndInfo['migration_info'];
             // add additional details that we might need to resolve conflicts
             $migrationInfo['main_details'] =& $rowsElementsAndInfo['main_details'];
             $migrationInfo['other_details'] =& $rowsElementsAndInfo['other_details'];
             $migrationInfo['rows'] =& $rowsElementsAndInfo['rows'];
             // go ahead with merge if there is no conflict
             $conflicts = array();
             if (!CRM_Dedupe_Merger::skipMerge($mainId, $otherId, $migrationInfo, $mode, $conflicts)) {
                 CRM_Dedupe_Merger::moveAllBelongings($mainId, $otherId, $migrationInfo, $checkPermissions);
                 $resultStats['merged'][] = array('main_id' => $mainId, 'other_id' => $otherId);
                 $deletedContacts[] = $otherId;
             } else {
                 $resultStats['skipped'][] = array('main_id' => $mainId, 'other_id' => $otherId);
             }
             // store any conflicts
             if (!empty($conflicts)) {
                 foreach ($conflicts as $key => $dnc) {
                     $conflicts[$key] = "{$migrationInfo['rows'][$key]['title']}: '{$migrationInfo['rows'][$key]['main']}' vs. '{$migrationInfo['rows'][$key]['other']}'";
                 }
                 CRM_Core_BAO_PrevNextCache::markConflict($mainId, $otherId, $cacheKeyString, $conflicts);
             } else {
                 // delete entry from PrevNextCache table so we don't consider the pair next time
                 // pair may have been flipped, so make sure we delete using both orders
                 CRM_Core_BAO_PrevNextCache::deletePair($mainId, $otherId, $cacheKeyString, TRUE);
             }
             CRM_Core_DAO::freeResult();
             unset($rowsElementsAndInfo, $migrationInfo);
         }
         if ($cacheKeyString && !$redirectForPerformance) {
             // retrieve next pair of dupes
             // @todo call getDuplicatePairs.
             $dupePairs = CRM_Core_BAO_PrevNextCache::retrieve($cacheKeyString, $cacheParams['join'], $cacheParams['where'], 0, 0, array(), '', FALSE);
         } else {
             // do not proceed. Terminate the loop
             unset($dupePairs);
         }
     }
     CRM_Dedupe_Merger::updateMergeStats($cacheKeyString, $resultStats);
     return $resultStats;
 }