/** * Page will try and merge as many contacts as possible into the household, * and give an overview of the current status * * @param (via URL) hid household ID * @param (via URL) oids other contact IDs, comma separated, to be merged int hid */ public function run() { CRM_Utils_System::setTitle(ts('Merge Contacts into Household', array('domain' => 'de.systopia.householdmerge'))); // extract IDs $household_id = (int) CRM_Utils_Array::value('hid', $_REQUEST); $other_ids = array(); $oids = preg_split('#,#', CRM_Utils_Array::value('oids', $_REQUEST, "")); foreach ($oids as $oid) { $oid = (int) $oid; if ($oid) { $other_ids[] = $oid; } } // verify parameters if (empty($household_id) || empty($other_ids)) { CRM_Core_Session::setStatus(ts('Household-Merge page cannot be called without "hid" or "oids" parameter.', array('domain' => 'de.systopia.householdmerge')), ts('Error', array('domain' => 'de.systopia.householdmerge')), 'error'); CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/dashboard')); return; } // NOW: load all contacts $household = civicrm_api3('Contact', 'getsingle', array('id' => $household_id)); $other_contacts = array(); foreach ($other_ids as $other_id) { $other_contact = civicrm_api3('Contact', 'getsingle', array('id' => $other_id)); $other_contact['was_merged'] = (bool) (!empty($other_contact['contact_is_deleted'])); $other_contacts[] = $other_contact; } // AND: try to merge the (remaining) contacts $merge_controller = new CRM_Householdmerge_MergeController(); $merge_controller->registerHHMerge($household_id, $other_ids); $merge_complete = TRUE; foreach ($other_contacts as &$other_contact) { if ($other_contact['was_merged']) { continue; } $cacheParams = array(); $mode = 'safe'; $dupePairs = array(); $dupePairs[] = array('srcID' => $other_contact['id'], 'dstID' => $household_id); $result = CRM_Dedupe_Merger::merge($dupePairs, $cacheParams, $mode, FALSE); // process result if (!empty($result['skipped'])) { $other_contact['was_merged'] = FALSE; $merge_complete = FALSE; } else { $other_contact['was_merged'] = TRUE; } } // set the conflict counts $hhmerge_controller = new CRM_Householdmerge_MergeController(); foreach ($other_contacts as &$other_contact) { $other_contact['conflict_count'] = $hhmerge_controller->getConflictCount($household_id, $other_contact['id']); } $this->assign('household', $household); $this->assign('other', $other_contacts); $this->assign('merge_complete', $merge_complete); if ($merge_complete) { $merge_controller->unregisterHHMerge($household_id); } parent::run(); }
/** * Batch merge a set of contacts based on rule-group and group. * * @param int $rgid * Rule group id. * @param int $gid * Group id. * @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. * @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 batchMerge($rgid, $gid = NULL, $mode = 'safe', $autoFlip = TRUE, $redirectForPerformance = FALSE) { $contactType = CRM_Core_DAO::getFieldValue('CRM_Dedupe_DAO_RuleGroup', $rgid, 'contact_type'); $cacheKeyString = "merge {$contactType}"; $cacheKeyString .= $rgid ? "_{$rgid}" : '_0'; $cacheKeyString .= $gid ? "_{$gid}" : '_0'; $join = "LEFT JOIN civicrm_dedupe_exception de ON ( pn.entity_id1 = de.contact_id1 AND\n pn.entity_id2 = de.contact_id2 )"; $limit = $redirectForPerformance ? 75 : 1; $where = "de.id IS NULL LIMIT {$limit}"; $dupePairs = CRM_Core_BAO_PrevNextCache::retrieve($cacheKeyString, $join, $where); if (empty($dupePairs) && !$redirectForPerformance) { // If we haven't found any dupes, probably cache is empty. // Try filling cache and give another try. CRM_Core_BAO_PrevNextCache::refillCache($rgid, $gid, $cacheKeyString); $dupePairs = CRM_Core_BAO_PrevNextCache::retrieve($cacheKeyString, $join, $where); } $cacheParams = array('cache_key_string' => $cacheKeyString, 'join' => $join, 'where' => $where); return CRM_Dedupe_Merger::merge($dupePairs, $cacheParams, $mode, $autoFlip, $redirectForPerformance); }
/** * Merges given pair of duplicate contacts. * * @param array $params * Allowed array keys are: * -int main_id: main contact id with whom merge has to happen * -int other_id: duplicate contact which would be deleted after merge operation * -string mode: "safe" skips the merge if there are no conflicts. Does a force merge otherwise. * -boolean auto_flip: whether to let api decide which contact to retain and which to delete. * * @return array * API Result Array * @throws CiviCRM_API3_Exception */ function civicrm_api3_contact_merge($params) { if (($result = CRM_Dedupe_Merger::merge(array(array('srcID' => $params['to_remove_id'], 'dstID' => $params['to_keep_id'])), array(), $params['mode'], $params['auto_flip'])) != FALSE) { return civicrm_api3_create_success($result, $params); } throw new CiviCRM_API3_Exception('Merge failed'); }
/** * Merges given pair of duplicate contacts. * * @param array $params * Allowed array keys are: * -int main_id: main contact id with whom merge has to happen * -int other_id: duplicate contact which would be deleted after merge operation * -string mode: "safe" skips the merge if there are no conflicts. Does a force merge otherwise. * -boolean auto_flip: whether to let api decide which contact to retain and which to delete. * * @return array * API Result Array */ function civicrm_api3_contact_merge($params) { $mode = CRM_Utils_Array::value('mode', $params, 'safe'); $autoFlip = CRM_Utils_Array::value('auto_flip', $params, TRUE); $dupePairs = array(array('srcID' => CRM_Utils_Array::value('main_id', $params), 'dstID' => CRM_Utils_Array::value('other_id', $params))); $result = CRM_Dedupe_Merger::merge($dupePairs, array(), $mode, $autoFlip); if ($result['is_error'] == 0) { return civicrm_api3_create_success(); } else { return civicrm_api3_create_error($result['messages']); } }
/** * Merges given pair of duplicate contacts. * * @param array $params * Allowed array keys are: * -int main_id: main contact id with whom merge has to happen * -int other_id: duplicate contact which would be deleted after merge operation * -string mode: "safe" skips the merge if there are no conflicts. Does a force merge otherwise. * -boolean auto_flip: whether to let api decide which contact to retain and which to delete. * * @return array * API Result Array * @throws CiviCRM_API3_Exception */ function civicrm_api3_contact_merge($params) { $mode = CRM_Utils_Array::value('mode', $params, 'safe'); $autoFlip = CRM_Utils_Array::value('auto_flip', $params, TRUE); $dupePairs = array(array('srcID' => CRM_Utils_Array::value('main_id', $params), 'dstID' => CRM_Utils_Array::value('other_id', $params))); if (($result = CRM_Dedupe_Merger::merge($dupePairs, array(), $mode, $autoFlip)) != FALSE) { return civicrm_api3_create_success($result, $params); } throw new CiviCRM_API3_Exception('Merge failed'); }
/** * Batch merge a set of contacts based on rule-group and group. * * @param int $rgid * Rule group id. * @param int $gid * Group id. * @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, wheras 'aggressive' * mode does a force merge. * @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 int $batchLimit number of merges to carry out in one batch. * @param int $isSelected if records with is_selected column needs to be processed. * * @param array $criteria * Criteria to use in the filter. * * @param bool $checkPermissions * Respect logged in user permissions. * * @return array|bool */ public static function batchMerge($rgid, $gid = NULL, $mode = 'safe', $autoFlip = TRUE, $batchLimit = 1, $isSelected = 2, $criteria = array(), $checkPermissions = TRUE) { $redirectForPerformance = $batchLimit > 1 ? TRUE : FALSE; $reloadCacheIfEmpty = !$redirectForPerformance && $isSelected == 2; $dupePairs = self::getDuplicatePairs($rgid, $gid, $reloadCacheIfEmpty, $batchLimit, $isSelected, '', $mode == 'aggressive', $criteria, $checkPermissions); $cacheParams = array('cache_key_string' => self::getMergeCacheKeyString($rgid, $gid, $criteria, $checkPermissions), 'join' => self::getJoinOnDedupeTable(), 'where' => self::getWhereString($batchLimit, $isSelected)); return CRM_Dedupe_Merger::merge($dupePairs, $cacheParams, $mode, $autoFlip, $redirectForPerformance, $checkPermissions); }