Provide for a custom entity to add a supported field and query to the DedupeRuleGroup class
Overview
Using hook_civicrm_dupeQuery a programmer may add to the list of supported fields available in the select list when adding or editing a Rule Group via "civicrm/contact/deduperules".
However, when the rule is run and exception is thrown because the function which creates the query CRM_Dedupe_BAO_DedupeRule::sql() throws an error, as it only supports hard-coded tables.
Therefore, hook_civicrm_dupeQuery with the option 'table' is never called.
If, the above function were to return NULL instead of throwing an error. hook_civicrm_dupeQuery would be called allowing the programmer to return the query required for their supported field.
However, the above produces two further issues. Via CRM_Dedupe_BAO_DedupeRuleGroup::fillTable():
noRules will be set to TRUE in the tableQuery() function if the custom supported field is the only field used in the rule.
The noRules affects the type of temp table created and also the threshold query returned:
if ($this->params && !$this->noRules) {
$this->temporaryTables['dedupe'] = CRM_Utils_SQL_TempTable::build() ...
And the programmer needs to be aware that the table key can only be found via the following search pattern:
$patternColumn = '/t1.(\w+)/';
...
preg_match($patternColumn, $query, $matches);
Proposed behaviour
I propose modifying CRM_Dedupe_BAO_DedupeRule::sql() so it either magically determines the name of the field in the custom entities table which links to the contact record (i.e. contact_id) and also optionally determines if the entity_type field also needs to be added in the where clause.
The above would allow a custom entity to easily provide their fields for use in User created Dedupe Rule Groups. The sql does a lot of heavy lifting and tableQuery requires a rather specific query.
Comments
I don't know of a magical way to find the right contact_id column.
Another option is to split the sql function up so a programmer can call it from the dupeQuery with their own id and entity_table field name.
dedupeIndexes is awfully lonesome out in CRM_Contact_Form_DedupeRules. Maybe that functionality can be brought back into the CRM_Dedupe_DAO_DedupeRule class: