Esempio n. 1
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
             $conflicts = array();
             if (!CRM_Dedupe_Merger::skipMerge($mainId, $otherId, $migrationInfo, $mode, $conflicts)) {
                 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);
             }
             // 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
             $dupePairs = CRM_Core_BAO_PrevNextCache::retrieve($cacheKeyString, $cacheParams['join'], $cacheParams['where']);
         } else {
             // do not proceed. Terminate the loop
             unset($dupePairs);
         }
     }
     CRM_Dedupe_Merger::updateMergeStats($cacheKeyString, $resultStats);
     return $resultStats;
 }
Esempio n. 2
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();
 }