Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dev/core#1597 & dev/core#1595 fix regression when deduping on custom fields #16558

Merged
merged 1 commit into from
Feb 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions CRM/Dedupe/BAO/Rule.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,13 @@ public function sql() {
// full matches, respectively)
$where = [];
$on = ["SUBSTR(t1.{$this->rule_field}, 1, {$this->rule_length}) = SUBSTR(t2.{$this->rule_field}, 1, {$this->rule_length})"];
$entity = CRM_Core_DAO_AllCoreTables::getBriefName(CRM_Core_DAO_AllCoreTables::getClassForTable($this->rule_table));
$fields = civicrm_api3($entity, 'getfields', ['action' => 'create'])['values'];

$innerJoinClauses = [
"t1.{$this->rule_field} IS NOT NULL",
"t2.{$this->rule_field} IS NOT NULL",
"t1.{$this->rule_field} = t2.{$this->rule_field}",
];
if ($fields[$this->rule_field]['type'] === CRM_Utils_Type::T_DATE) {
if ($this->getFieldType($this->rule_field) === CRM_Utils_Type::T_DATE) {
$innerJoinClauses[] = "t1.{$this->rule_field} > '1000-01-01'";
$innerJoinClauses[] = "t2.{$this->rule_field} > '1000-01-01'";
}
Expand Down Expand Up @@ -238,4 +236,26 @@ public static function validateContacts($cid, $oid) {
return $exception->find(TRUE) ? FALSE : TRUE;
}

/**
* Get the specification for the given field.
*
* @param string $fieldName
*
* @return array
* @throws \CiviCRM_API3_Exception
*/
public function getFieldType($fieldName) {
$entity = CRM_Core_DAO_AllCoreTables::getBriefName(CRM_Core_DAO_AllCoreTables::getClassForTable($this->rule_table));
if (!$entity) {
// This means we have stored a custom field rather than an entity name in rule_table, figure out the entity.
$entity = civicrm_api3('CustomGroup', 'getvalue', ['table_name' => $this->rule_table, 'return' => 'extends']);
if (in_array($entity, ['Individual', 'Household', 'Organization'])) {
$entity = 'Contact';
}
$fieldName = 'custom_' . civicrm_api3('CustomField', 'getvalue', ['column_name' => $fieldName, 'return' => 'id']);
}
$fields = civicrm_api3($entity, 'getfields', ['action' => 'create'])['values'];
return $fields[$fieldName]['type'];
}

}
60 changes: 42 additions & 18 deletions tests/phpunit/CRM/Dedupe/DedupeFinderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/
class CRM_Dedupe_DedupeFinderTest extends CiviUnitTestCase {

use CRMTraits_Custom_CustomDataTrait;
/**
* IDs of created contacts.
*
Expand All @@ -31,6 +32,10 @@ public function tearDown() {
if ($this->groupID) {
$this->callAPISuccess('group', 'delete', ['id' => $this->groupID]);
}
$this->quickCleanup(['civicrm_contact'], TRUE);
CRM_Core_DAO::executeQuery("DELETE r FROM civicrm_dedupe_rule_group rg INNER JOIN civicrm_dedupe_rule r ON rg.id = r.dedupe_rule_group_id WHERE rg.is_reserved = 0 AND used = 'General'");
CRM_Core_DAO::executeQuery("DELETE FROM civicrm_dedupe_rule_group WHERE is_reserved = 0 AND used = 'General'");

parent::tearDown();
}

Expand Down Expand Up @@ -88,15 +93,7 @@ public function testUnsupervisedWithTwoEmailFields() {
public function testCustomRule() {
$this->setupForGroupDedupe();

$ruleGroup = $this->callAPISuccess('RuleGroup', 'create', [
'contact_type' => 'Individual',
'threshold' => 8,
'used' => 'General',
'name' => 'TestRule',
'title' => 'TestRule',
'is_reserved' => 0,
]);
$rules = [];
$ruleGroup = $this->createRuleGroup();
foreach (['birth_date', 'first_name', 'last_name'] as $field) {
$rules[$field] = $this->callAPISuccess('Rule', 'create', [
'dedupe_rule_group_id' => $ruleGroup['id'],
Expand All @@ -111,6 +108,25 @@ public function testCustomRule() {

}

/**
* Test that we do not get a fatal error when our rule group is a custom date field.
*
* @throws \CRM_Core_Exception
*/
public function testCustomRuleCustomDateField() {

$ruleGroup = $this->createRuleGroup();
$this->createCustomGroupWithFieldOfType([], 'date');
$this->callAPISuccess('Rule', 'create', [
'dedupe_rule_group_id' => $ruleGroup['id'],
'rule_table' => $this->getCustomGroupTable(),
'rule_weight' => 4,
'rule_field' => $this->getCustomFieldColumnName('date'),
]);

CRM_Dedupe_Finder::dupes($ruleGroup['id']);
}

/**
* Test a custom rule with a non-default field.
*/
Expand Down Expand Up @@ -173,15 +189,7 @@ public function testRuleThreeContactFieldsEqualWeightWIthThresholdtheTotalSumOfA
public function testInclusiveRule() {
$this->setupForGroupDedupe();

$ruleGroup = $this->callAPISuccess('RuleGroup', 'create', [
'contact_type' => 'Individual',
'threshold' => 8,
'used' => 'General',
'name' => 'TestRule',
'title' => 'TestRule',
'is_reserved' => 0,
]);
$rules = [];
$ruleGroup = $this->createRuleGroup();
foreach (['first_name', 'last_name'] as $field) {
$rules[$field] = $this->callAPISuccess('Rule', 'create', [
'dedupe_rule_group_id' => $ruleGroup['id'],
Expand Down Expand Up @@ -424,4 +432,20 @@ protected function setupForGroupDedupe() {
$this->assertEquals(count($this->contactIDs), 7, 'Check for number of contacts.');
}

/**
* @return array|int
* @throws \CRM_Core_Exception
*/
protected function createRuleGroup() {
$ruleGroup = $this->callAPISuccess('RuleGroup', 'create', [
'contact_type' => 'Individual',
'threshold' => 8,
'used' => 'General',
'name' => 'TestRule',
'title' => 'TestRule',
'is_reserved' => 0,
]);
return $ruleGroup;
}

}