class CRM_Dedupe_Merger

Methods

static array
relTables()

FIXME: consider creating a common structure with cidRefs() and eidRefs() FIXME: the sub-pages references by the URLs should be loaded dynamically on the merge form instead

static array
getActiveRelTables(int $cid)

Returns the related tables groups for which a contact has any info entered.

static 
cidRefs()

Get array tables and fields that reference civicrm_contact.id.

static 
eidRefs()

Return tables and their fields referencing civicrm_contact.contact_id with entity_id

static 
locTables()

Return tables using locations.

static 
getMultiValueCustomSets(string $request)

We treat multi-valued custom sets as "related tables" similar to activities, contributions, etc.

static 
cpTables()

Tables which require custom processing should declare functions to call here.

static 
paymentTables()

Return payment related table.

static array
paymentSql(string $tableName, int $mainContactId, int $otherContactId)

Return payment update Query.

static array
operationSql(int $mainId, int $otherId, string $tableName, array $tableOperations = array(), string $mode = 'add')

No description

static 
moveContactBelongings(int $mainId, int $otherId, bool $tables = FALSE, array $tableOperations = array())

Based on the provided two contact_ids and a set of tables, move the belongings of the other contact to the main one.

static array
retrieveFields(array $main, array $other)

Load all non-empty fields for the contacts

static array|bool
batchMerge(int $rgid, int $gid = NULL, string $mode = 'safe', int $batchLimit = 1, int $isSelected = 2, array $criteria = array(), bool $checkPermissions = TRUE)

Batch merge a set of contacts based on rule-group and group.

static string
getJoinOnDedupeTable()

Get the string to join the prevnext cache to the dedupe table.

static string
getWhereString(int $batchLimit, bool $isSelected)

Get where string for dedupe join.

static 
updateMergeStats(string $cacheKeyString, array $result = array())

Update the statistics for the merge set.

static 
resetMergeStats($cacheKeyString)

Delete information about merges for the given string.

static array
getMergeStats(string $cacheKeyString)

Get merge outcome statistics.

static string
getMergeStatsMsg(string $cacheKeyString)

Get merge statistics message.

static array|bool
merge(array $dupePairs = array(), array $cacheParams = array(), string $mode = 'safe', bool $redirectForPerformance = FALSE, bool $checkPermissions = TRUE)

Merge given set of contacts. Performs core operation.

static bool
skipMerge(int $mainId, int $otherId, array $migrationInfo, string $mode = 'safe', array $conflicts = array())

A function which uses various rules / algorithms for choosing which contact to bias to when there's a conflict (to handle "gotchas"). Plus the safest route to merge.

static bool
locationIsSame(array $mainAddress, array $comparisonAddress)

Compare 2 addresses to see if they are the same.

static array
getLocationBlockInfo()

A function to build an array of information about location blocks that is required when merging location fields

static array|bool|int
getRowsElementsAndInfo(int $mainId, int $otherId, bool $checkPermissions = TRUE)

A function to build an array of information required by merge function and the merge UI.

static bool
moveAllBelongings(int $mainId, int $otherId, $migrationInfo, bool $checkPermissions = TRUE)

Based on the provided two contact_ids and a set of tables, move the belongings of the other contact to the main one - be it Location / CustomFields or Contact .

static array
getContactFields()

Get fields in the contact table suitable for merging.

static 
addMembershipToRealtedContacts(int $contactID)

Added for CRM-12695 Based on the contactID provided add/update membership(s) to related contacts

static 
addCustomTablesExtendingContactsToCidRefs(array $cidRefs)

Add custom tables that extend contacts to the list of contact references.

static 
createMergeActivities(int $mainId, int $otherId)

Create activities tracking the merge on affected contacts.

static array
getDuplicatePairs(int $rule_group_id, int $group_id, bool $reloadCacheIfEmpty, int $batchLimit, bool $isSelected, array|string $orderByClause = '', bool $includeConflicts = TRUE, array $criteria = array(), bool $checkPermissions = TRUE)

Get Duplicate Pairs based on a rule for a group.

static string
getMergeCacheKeyString(int $rule_group_id, int $group_id, array $criteria = array(), bool $checkPermissions = TRUE)

Get the cache key string for the merge action.

static array
getSpecialValues(array $contact)

No description

static array
getMergeFieldsMetadata()

Get the metadata for the merge fields.

static array
getMergeContactDetails(int $contact_id)

Get the details of the contact to be merged.

static 
mergeLocations(int $mainId, int $otherId, array $locationMigrationInfo, array $migrationInfo)

Merge location.

static 
dedupePair(array $migrationInfo, array $resultStats, array $deletedContacts, string $mode, bool $checkPermissions, int $mainId, int $otherId, string $cacheKeyString)

Dedupe a pair of contacts.

Details

at line 41
static array relTables()

FIXME: consider creating a common structure with cidRefs() and eidRefs() FIXME: the sub-pages references by the URLs should be loaded dynamically on the merge form instead

Return Value

array

at line 169
static array getActiveRelTables(int $cid)

Returns the related tables groups for which a contact has any info entered.

Parameters

int $cid

Return Value

array

at line 211
static cidRefs()

Get array tables and fields that reference civicrm_contact.id.

This includes core tables, custom group tables, tables added by the merge hook and (somewhat randomly) the entity_tag table.

Refer to CRM-17454 for information on the danger of querying the information schema to derive this.

This function calls the merge hook but the entityTypes hook is the recommended way to add tables to this result.

at line 238
static eidRefs()

Return tables and their fields referencing civicrm_contact.contact_id with entity_id

at line 261
static locTables()

Return tables using locations.

at line 278
static getMultiValueCustomSets(string $request)

We treat multi-valued custom sets as "related tables" similar to activities, contributions, etc.

Parameters

string $request 'relTables' or 'cidRefs'.

See also

CRM-13836

at line 307
static cpTables()

Tables which require custom processing should declare functions to call here.

Doing so will override normal processing.

at line 324
static paymentTables()

Return payment related table.

at line 341
static array paymentSql(string $tableName, int $mainContactId, int $otherContactId)

Return payment update Query.

Parameters

string $tableName
int $mainContactId
int $otherContactId

Return Value

array

at line 393
static array operationSql(int $mainId, int $otherId, string $tableName, array $tableOperations = array(), string $mode = 'add')

Parameters

int $mainId
int $otherId
string $tableName
array $tableOperations
string $mode

Return Value

array

at line 441
static moveContactBelongings(int $mainId, int $otherId, bool $tables = FALSE, array $tableOperations = array())

Based on the provided two contact_ids and a set of tables, move the belongings of the other contact to the main one.

Parameters

int $mainId
int $otherId
bool $tables
array $tableOperations

at line 551
static array retrieveFields(array $main, array $other)

Load all non-empty fields for the contacts

Parameters

array $main Contact details.
array $other Contact details.

Return Value

array

at line 603
static array|bool batchMerge(int $rgid, int $gid = NULL, string $mode = 'safe', int $batchLimit = 1, int $isSelected = 2, array $criteria = array(), bool $checkPermissions = TRUE)

Batch merge a set of contacts based on rule-group and group.

Parameters

int $rgid Rule group id.
int $gid Group id.
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.
int $batchLimit number of merges to carry out in one batch.
int $isSelected if records with is_selected column needs to be processed.
array $criteria Criteria to use in the filter.
bool $checkPermissions Respect logged in user permissions.

Return Value

array|bool

at line 624
static string getJoinOnDedupeTable()

Get the string to join the prevnext cache to the dedupe table.

Return Value

string The join string to join prevnext cache on the dedupe table.

at line 641
static protected string getWhereString(int $batchLimit, bool $isSelected)

Get where string for dedupe join.

Parameters

int $batchLimit
bool $isSelected

Return Value

string

at line 658
static updateMergeStats(string $cacheKeyString, array $result = array())

Update the statistics for the merge set.

Parameters

string $cacheKeyString
array $result

at line 698
static resetMergeStats($cacheKeyString)

Delete information about merges for the given string.

Parameters

$cacheKeyString

at line 710
static array getMergeStats(string $cacheKeyString)

Get merge outcome statistics.

Parameters

string $cacheKeyString

Return Value

array Array of how many were merged and how many were skipped.

at line 725
static string getMergeStatsMsg(string $cacheKeyString)

Get merge statistics message.

Parameters

string $cacheKeyString

Return Value

string

at line 758
static array|bool merge(array $dupePairs = array(), array $cacheParams = array(), string $mode = 'safe', bool $redirectForPerformance = FALSE, bool $checkPermissions = TRUE)

Merge given set of contacts. Performs core operation.

Parameters

array $dupePairs Set of pair of contacts for whom merge is to be done.
array $cacheParams Prev-next-cache params based on which next pair of contacts are computed. Generally used with batch-merge.
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).
bool $redirectForPerformance Redirect to a url for batch processing.
bool $checkPermissions Respect logged in user permissions.

Return Value

array|bool

at line 837
static bool skipMerge(int $mainId, int $otherId, array $migrationInfo, string $mode = 'safe', array $conflicts = array())

A function which uses various rules / algorithms for choosing which contact to bias to when there's a conflict (to handle "gotchas"). Plus the safest route to merge.

Parameters

int $mainId Main contact with whom merge has to happen.
int $otherId Duplicate contact which would be deleted after merge operation.
array $migrationInfo Array of information about which elements to merge.
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).
array $conflicts

Return Value

bool

at line 948
static bool locationIsSame(array $mainAddress, array $comparisonAddress)

Compare 2 addresses to see if they are the same.

Parameters

array $mainAddress
array $comparisonAddress

Return Value

bool

at line 967
static array getLocationBlockInfo()

A function to build an array of information about location blocks that is required when merging location fields

Return Value

array

at line 1057
static array|bool|int getRowsElementsAndInfo(int $mainId, int $otherId, bool $checkPermissions = TRUE)

A function to build an array of information required by merge function and the merge UI.

Parameters

int $mainId Main contact with whom merge has to happen.
int $otherId Duplicate contact which would be deleted after merge operation.
bool $checkPermissions Should the logged in user's permissions be ignore. Setting this to false is highly risky as it could cause data to be lost due to conflicts not showing up. OTOH there is a risk a merger might view custom data they do not have permission to. Hence for now only making this really explicit and making it reflect perms in an api call.

Return Value

array|bool|int rows => An array of arrays, each is row of merge information for the table Format: move_fieldname, eg: move_contact_type main => Value associated with the main contact other => Value associated with the other contact title => The title of the field to display in the merge table

elements => An array of form elements for the merge UI

rel_table_elements => An array of form elements for the merge UI for entities related to the contact (eg: checkbox to move 'mailings')

rel_tables => Stores the tables that have related entities for the contact for example mailings, groups

main_details => An array of core contact field values, eg: first_name, etc. location_blocks => An array of location block data for the main contact stored as the 'result' of an API call. eg: main_details['location_blocks']['address'][0]['id'] eg: main_details['location_blocks']['email'][1]['id']

other_details => As above, but for the 'other' contact

migration_info => Stores the 'default' merge actions for each field which is used when programatically merging contacts. It contains instructions to move all fields from the 'other' contact to the 'main' contact, as though the form had been submitted with those options.

Exceptions

CRM_Core_Exception
CiviCRM_API3_Exception
Exception

at line 1459
static bool moveAllBelongings(int $mainId, int $otherId, $migrationInfo, bool $checkPermissions = TRUE)

Based on the provided two contact_ids and a set of tables, move the belongings of the other contact to the main one - be it Location / CustomFields or Contact .

. related info. A superset of moveContactBelongings() function.

Parameters

int $mainId Main contact with whom merge has to happen.
int $otherId Duplicate contact which would be deleted after merge operation.
$migrationInfo
bool $checkPermissions Respect logged in user permissions.

Return Value

bool

at line 1758
static array getContactFields()

Get fields in the contact table suitable for merging.

Return Value

array Array of field names to be potentially merged.

at line 1786
static addMembershipToRealtedContacts(int $contactID)

Added for CRM-12695 Based on the contactID provided add/update membership(s) to related contacts

Parameters

int $contactID

at line 1824
static addCustomTablesExtendingContactsToCidRefs(array $cidRefs)

Add custom tables that extend contacts to the list of contact references.

CRM_Core_BAO_CustomGroup::getAllCustomGroupsByBaseEntity seems like a safe-ish function to be sure all are retrieved & we don't miss subtypes or inactive or multiples - the down side is it is not cached.

Further changes should be include tests in the CRM_Core_MergerTest class to ensure that disabled, subtype, multiple etc groups are still captured.

Parameters

array $cidRefs

at line 1840
static createMergeActivities(int $mainId, int $otherId)

Create activities tracking the merge on affected contacts.

Parameters

int $mainId
int $otherId

Exceptions

CiviCRM_API3_Exception

at line 1885
static array getDuplicatePairs(int $rule_group_id, int $group_id, bool $reloadCacheIfEmpty, int $batchLimit, bool $isSelected, array|string $orderByClause = '', bool $includeConflicts = TRUE, array $criteria = array(), bool $checkPermissions = TRUE)

Get Duplicate Pairs based on a rule for a group.

Parameters

int $rule_group_id
int $group_id
bool $reloadCacheIfEmpty
int $batchLimit
bool $isSelected
array|string $orderByClause
bool $includeConflicts
array $criteria Additional criteria to narrow down the merge group.
bool $checkPermissions Respect logged in user permissions.

Return Value

array Array of matches meeting the criteria.

at line 1915
static string getMergeCacheKeyString(int $rule_group_id, int $group_id, array $criteria = array(), bool $checkPermissions = TRUE)

Get the cache key string for the merge action.

Parameters

int $rule_group_id
int $group_id
array $criteria Additional criteria to narrow down the merge group. Currently we are only supporting the key 'contact' within it.
bool $checkPermissions Respect the users permissions.

Return Value

string

at line 1940
static array getSpecialValues(array $contact)

Parameters

array $contact

Return Value

array $specialValues

at line 1975
static array getMergeFieldsMetadata()

Get the metadata for the merge fields.

This is basically the contact metadata, augmented with fields to represent email greeting, postal greeting & addressee.

Return Value

array

at line 2000
static array getMergeContactDetails(int $contact_id)

Get the details of the contact to be merged.

Parameters

int $contact_id

Return Value

array

Exceptions

CRM_Core_Exception

at line 2044
static mergeLocations(int $mainId, int $otherId, array $locationMigrationInfo, array $migrationInfo)

Merge location.

Based on the data in the $locationMigrationInfo merge the locations for 2 contacts.

The data is in the format received from the merge form (which is a fairly confusing format).

It is converted into an array of DAOs which is passed to the alterLocationMergeData hook before saving or deleting the DAOs. A new hook is added to allow these to be altered after they have been calculated and before saving because - the existing format & hook combo is so confusing it is hard for developers to change & inherently fragile - passing to a hook right before save means calculations only have to be done once - the existing pattern of passing dissimilar data to the same (merge) hook with a different 'type' is just ugly.

The use of the new hook is tested, including the fact it is called before contributions are merged, as this is likely to be significant data in merge hooks.

Parameters

int $mainId
int $otherId
array $locationMigrationInfo Portion of the migration_info that holds location migration information.
array $migrationInfo Migration info for the merge. This is passed to the hook as informational only.

at line 2179
static protected dedupePair(array $migrationInfo, array $resultStats, array $deletedContacts, string $mode, bool $checkPermissions, int $mainId, int $otherId, string $cacheKeyString)

Dedupe a pair of contacts.

Parameters

array $migrationInfo
array $resultStats
array $deletedContacts
string $mode
bool $checkPermissions
int $mainId
int $otherId
string $cacheKeyString