$contactType = CRM_Core_DAO::getFieldValue('CRM_Dedupe_DAO_RuleGroup', $rgid, 'contact_type');
}
- $cacheKeyString = "merge {$contactType}_{$rgid}_{$gid}";
+ $cacheKeyString = CRM_Dedupe_Merger::getMergeCacheKeyString($rgid, $gid);
$searchRows = array();
$selectorElements = array('is_selected', 'is_selected_input', 'src_image', 'src', 'src_email', 'src_street', 'src_postcode', 'dst_image', 'dst', 'dst_email', 'dst_street', 'dst_postcode', 'conflicts', 'weight', 'actions');
}
/**
+ * Repopulate the cache of merge prospects.
+ *
* @param int $rgid
* @param int $gid
* @param NULL $cacheKeyString
+ * @param array $criteria
+ * Additional criteria to filter by.
*
* @return bool
*/
- public static function refillCache($rgid = NULL, $gid = NULL, $cacheKeyString = NULL) {
+ public static function refillCache($rgid = NULL, $gid = NULL, $cacheKeyString = NULL, $criteria = array()) {
if (!$cacheKeyString && $rgid) {
- $cacheKeyString = CRM_Dedupe_Merger::getMergeCacheKeyString($rgid, $gid);
+ $cacheKeyString = CRM_Dedupe_Merger::getMergeCacheKeyString($rgid, $gid, $criteria);
}
if (!$cacheKeyString) {
$foundDupes = CRM_Dedupe_Finder::dupesInGroup($rgid, $gid);
}
elseif ($rgid) {
- $foundDupes = CRM_Dedupe_Finder::dupes($rgid);
+ $contactIDs = array();
+ if (!empty($criteria)) {
+ $contacts = civicrm_api3('Contact', 'get', array_merge(array('options' => array('limit' => 0), 'return' => 'id'), $criteria['contact']));
+ $contactIDs = array_keys($contacts['values']);
+ }
+ $foundDupes = CRM_Dedupe_Finder::dupes($rgid, $contactIDs);
}
if (!empty($foundDupes)) {
* @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.
+ *
* @return array|bool
*/
- public static function batchMerge($rgid, $gid = NULL, $mode = 'safe', $autoFlip = TRUE, $batchLimit = 1, $isSelected = 2) {
+ public static function batchMerge($rgid, $gid = NULL, $mode = 'safe', $autoFlip = TRUE, $batchLimit = 1, $isSelected = 2, $criteria = array()) {
$redirectForPerformance = ($batchLimit > 1) ? TRUE : FALSE;
$reloadCacheIfEmpty = (!$redirectForPerformance && $isSelected == 2);
- $dupePairs = self::getDuplicatePairs($rgid, $gid, $reloadCacheIfEmpty, $batchLimit, $isSelected, '', ($mode == 'aggressive'));
+ $dupePairs = self::getDuplicatePairs($rgid, $gid, $reloadCacheIfEmpty, $batchLimit, $isSelected, '', ($mode == 'aggressive'), $criteria);
$cacheParams = array(
- 'cache_key_string' => self::getMergeCacheKeyString($rgid, $gid),
+ 'cache_key_string' => self::getMergeCacheKeyString($rgid, $gid, $criteria),
// @todo stop passing these parameters in & instead calculate them in the merge function based
// on the 'real' params like $isRespectExclusions $batchLimit and $isSelected.
'join' => self::getJoinOnDedupeTable(),
* @param bool $isSelected
* @param array $orderByClause
* @param bool $includeConflicts
+ * @param array $criteria
+ * Additional criteria to narrow down the merge group.
*
* @return array
* Array of matches meeting the criteria.
*/
- public static function getDuplicatePairs($rule_group_id, $group_id, $reloadCacheIfEmpty, $batchLimit, $isSelected, $orderByClause = '', $includeConflicts = TRUE) {
+ public static function getDuplicatePairs($rule_group_id, $group_id, $reloadCacheIfEmpty, $batchLimit, $isSelected, $orderByClause = '', $includeConflicts = TRUE, $criteria = array()) {
$where = self::getWhereString($batchLimit, $isSelected);
- $cacheKeyString = self::getMergeCacheKeyString($rule_group_id, $group_id, $includeConflicts);
+ $cacheKeyString = self::getMergeCacheKeyString($rule_group_id, $group_id, $criteria);
$join = self::getJoinOnDedupeTable();
$dupePairs = CRM_Core_BAO_PrevNextCache::retrieve($cacheKeyString, $join, $where, 0, 0, array(), $orderByClause, $includeConflicts);
if (empty($dupePairs) && $reloadCacheIfEmpty) {
// If we haven't found any dupes, probably cache is empty.
// Try filling cache and give another try. We don't need to specify include conflicts here are there will not be any
// until we have done some processing.
- CRM_Core_BAO_PrevNextCache::refillCache($rule_group_id, $group_id, $cacheKeyString);
+ CRM_Core_BAO_PrevNextCache::refillCache($rule_group_id, $group_id, $cacheKeyString, $criteria);
$dupePairs = CRM_Core_BAO_PrevNextCache::retrieve($cacheKeyString, $join, $where, 0, 0, array(), $orderByClause, $includeConflicts);
return $dupePairs;
}
*
* @param int $rule_group_id
* @param int $group_id
+ * @param array $criteria
+ * Additional criteria to narrow down the merge group.
+ * Currently we are only supporting the key 'contact' within it.
*
* @return string
*/
- public static function getMergeCacheKeyString($rule_group_id, $group_id) {
+ public static function getMergeCacheKeyString($rule_group_id, $group_id, $criteria = array()) {
$contactType = CRM_Dedupe_BAO_RuleGroup::getContactTypeForRuleGroup($rule_group_id);
$cacheKeyString = "merge {$contactType}";
$cacheKeyString .= $rule_group_id ? "_{$rule_group_id}" : '_0';
$cacheKeyString .= $group_id ? "_{$group_id}" : '_0';
+ $cacheKeyString .= !empty($criteria) ? serialize($criteria) : '_0';
return $cacheKeyString;
}
$mode = CRM_Utils_Array::value('mode', $params, 'safe');
$autoFlip = CRM_Utils_Array::value('auto_flip', $params, TRUE);
- $result = CRM_Dedupe_Merger::batchMerge($rule_group_id, $gid, $mode, $autoFlip);
+ $result = CRM_Dedupe_Merger::batchMerge($rule_group_id, $gid, $mode, $autoFlip, 1, 2, CRM_Utils_Array::value('criteria', $params, array()));
return civicrm_api3_create_success($result, $params);
}
// Retrieve pairs from prev next cache table
$select = array('pn.is_selected' => 'is_selected');
- $cacheKeyString = "merge Individual_{$dao->id}_{$this->_groupId}";
+ $cacheKeyString = "merge Individual_{$dao->id}_{$this->_groupId}_0";
$pnDupePairs = CRM_Core_BAO_PrevNextCache::retrieve($cacheKeyString, NULL, NULL, 0, 0, $select);
$this->assertEquals(count($foundDupes), count($pnDupePairs), 'Check number of dupe pairs in prev next cache.');
// Retrieve pairs from prev next cache table
$select = array('pn.is_selected' => 'is_selected');
- $cacheKeyString = "merge Individual_{$dao->id}_{$this->_groupId}";
+ $cacheKeyString = "merge Individual_{$dao->id}_{$this->_groupId}_0";
$pnDupePairs = CRM_Core_BAO_PrevNextCache::retrieve($cacheKeyString, NULL, NULL, 0, 0, $select);
$this->assertEquals(count($foundDupes), count($pnDupePairs), 'Check number of dupe pairs in prev next cache.');
), 4);
}
+ /**
+ * Test the batch merge by id range.
+ *
+ * We have 2 sets of 5 matches & set the merge only to merge the lower set.
+ */
+ public function testBatchMergeIDRange() {
+ for ($x = 0; $x <= 4; $x++) {
+ $id = $this->individualCreate(array('email' => 'batman@gotham.met'));
+ }
+ for ($x = 0; $x <= 4; $x++) {
+ $this->individualCreate(array('email' => 'robin@gotham.met'));
+ }
+ $result = $this->callAPISuccess('Job', 'process_batch_merge', array('criteria' => array('contact' => array('id' => array('<' => $id)))));
+ $this->assertEquals(4, count($result['values']['merged']));
+ $this->callAPISuccessGetCount('Contact', array('email' => 'batman@gotham.met'), 1);
+ $this->callAPISuccessGetCount('Contact', array('email' => 'robin@gotham.met'), 5);
+ $contacts = $this->callAPISuccess('Contact', 'get', array('is_deleted' => 0));
+ $deletedContacts = $this->callAPISuccess('Contact', 'get', array('is_deleted' => 0));
+ $this->callAPISuccessGetCount('Email', array(
+ 'email' => 'batman@gotham.met',
+ 'contact_id' => array('IN' => array_keys($contacts['values'])),
+ ), 1);
+ $this->callAPISuccessGetCount('Email', array(
+ 'email' => 'batman@gotham.met',
+ 'contact_id' => array('IN' => array_keys($deletedContacts['values'])),
+ ), 1);
+ $this->callAPISuccessGetCount('Email', array(
+ 'email' => 'robin@gotham.met',
+ 'contact_id' => array('IN' => array_keys($contacts['values'])),
+ ), 5);
+
+ }
+
/**
* Get data for batch merge.
*/