if ($customTableToCopyFrom !== NULL) {
// @todo this duplicates cidRefs?
CRM_Core_DAO::appendCustomTablesExtendingContacts($customTables);
+ CRM_Core_DAO::appendCustomContactReferenceFields($customTables);
$customTables = array_keys($customTables);
}
// skipping non selected single-value custom table's value migration
if (!in_array($table, $multi_value_tables)) {
if ($customTableToCopyFrom !== NULL && in_array($table, $customTables) && !in_array($table, $customTableToCopyFrom)) {
- continue;
+ if (isset($cidRefs[$table]) && ($delCol = array_search('entity_id', $cidRefs[$table])) !== FALSE) {
+ // remove entity_id from the field list
+ unset($cidRefs[$table][$delCol]);
+ }
}
}
$preOperationSqls = self::operationSql($mainId, $otherId, $table, $tableOperations);
$sqls = array_merge($sqls, $preOperationSqls);
- if ($customTableToCopyFrom !== NULL && in_array($table, $customTableToCopyFrom) && !self::customRecordExists($mainId, $table, $field)) {
+ if ($customTableToCopyFrom !== NULL && in_array($table, $customTableToCopyFrom) && !self::customRecordExists($mainId, $table, $field) && $field == 'entity_id') {
+ // this is the entity_id column of a custom field group where:
+ // - the custom table should be copied as indicated by $customTableToCopyFrom
+ // e.g. because a field in the group was selected in a form
+ // - AND no record exists yet for the $mainId contact
+ // we only do this for column "entity_id" as we wouldn't want to
+ // run this INSERT for ContactReference fields
$sqls[] = "INSERT INTO $table ($field) VALUES ($mainId)";
}
$sqls[] = "UPDATE IGNORE $table SET $field = $mainId WHERE $field = $otherId";
* If not set explicitly this is calculated but it is preferred that it be set
* per comments on isSelected above.
*
+ * @param int $searchLimit
+ * Limit on number of contacts to search for duplicates for.
+ * This means that if the limit is 1000 then only duplicates for the first 1000 contacts
+ * matching criteria will be found and batchMerged (the number of merges could be less than or greater than 100)
+ *
* @return array|bool
+ *
+ * @throws \CRM_Core_Exception
+ * @throws \CiviCRM_API3_Exception
*/
- public static function batchMerge($rgid, $gid = NULL, $mode = 'safe', $batchLimit = 1, $isSelected = 2, $criteria = [], $checkPermissions = TRUE, $reloadCacheIfEmpty = NULL) {
+ public static function batchMerge($rgid, $gid = NULL, $mode = 'safe', $batchLimit = 1, $isSelected = 2, $criteria = [], $checkPermissions = TRUE, $reloadCacheIfEmpty = NULL, $searchLimit = 0) {
$redirectForPerformance = ($batchLimit > 1) ? TRUE : FALSE;
if (!isset($reloadCacheIfEmpty)) {
$dupePairs = self::getDuplicatePairs($rgid, $gid, $reloadCacheIfEmpty, $batchLimit, $isSelected, ($mode == 'aggressive'), $criteria, $checkPermissions);
$cacheParams = [
- 'cache_key_string' => self::getMergeCacheKeyString($rgid, $gid, $criteria, $checkPermissions),
+ 'cache_key_string' => self::getMergeCacheKeyString($rgid, $gid, $criteria, $checkPermissions, $searchLimit),
// @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(),
* @throws \CiviCRM_API3_Exception
*/
public static function getDuplicatePairs($rule_group_id, $group_id, $reloadCacheIfEmpty, $batchLimit, $isSelected, $includeConflicts = TRUE, $criteria = [], $checkPermissions = TRUE, $searchLimit = 0) {
- $dupePairs = self::getCachedDuplicateMatches($rule_group_id, $group_id, $batchLimit, $isSelected, $includeConflicts, $criteria, $checkPermissions);
+ $dupePairs = self::getCachedDuplicateMatches($rule_group_id, $group_id, $batchLimit, $isSelected, $includeConflicts, $criteria, $checkPermissions, $searchLimit);
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, $criteria, $checkPermissions, $searchLimit);
- return self::getCachedDuplicateMatches($rule_group_id, $group_id, $batchLimit, $isSelected, FALSE, $criteria, $checkPermissions);
+ return self::getCachedDuplicateMatches($rule_group_id, $group_id, $batchLimit, $isSelected, FALSE, $criteria, $checkPermissions, $searchLimit);
}
return $dupePairs;
}
* @param array $criteria
* Additional criteria to narrow down the merge group.
* Currently we are only supporting the key 'contact' within it.
- *
* @param bool $checkPermissions
* Respect the users permissions.
+ * @param int $searchLimit
+ * Number of contacts to seek dupes for (we need this because if
+ * we change it the results won't be refreshed otherwise. Changing the limit
+ * from 100 to 1000 SHOULD result in a new dedupe search).
*
* @return string
*/
- public static function getMergeCacheKeyString($rule_group_id, $group_id, $criteria = [], $checkPermissions = TRUE) {
+ public static function getMergeCacheKeyString($rule_group_id, $group_id, $criteria, $checkPermissions, $searchLimit) {
$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 .= '_' . (int) $searchLimit;
$cacheKeyString .= !empty($criteria) ? md5(serialize($criteria)) : '_0';
if ($checkPermissions) {
$contactID = CRM_Core_Session::getLoggedInContactID();
* @param bool $includeConflicts
* @param array $criteria
* @param int $checkPermissions
+ * @param int $searchLimit
*
* @return array
*/
- protected static function getCachedDuplicateMatches($rule_group_id, $group_id, $batchLimit, $isSelected, $includeConflicts, $criteria, $checkPermissions) {
+ protected static function getCachedDuplicateMatches($rule_group_id, $group_id, $batchLimit, $isSelected, $includeConflicts, $criteria, $checkPermissions, $searchLimit = 0) {
return CRM_Core_BAO_PrevNextCache::retrieve(
- self::getMergeCacheKeyString($rule_group_id, $group_id, $criteria, $checkPermissions),
+ self::getMergeCacheKeyString($rule_group_id, $group_id, $criteria, $checkPermissions, $searchLimit),
self::getJoinOnDedupeTable(),
self::getWhereString($isSelected),
0, $batchLimit,