Skip to content

Commit

Permalink
dev/core#1597 & dev/core#1595 fix regression when deduping on custom …
Browse files Browse the repository at this point in the history
…fields
  • Loading branch information
eileenmcnaughton committed Feb 17, 2020
1 parent 075e18d commit 8b7b236
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 22 deletions.
2 changes: 1 addition & 1 deletion CRM/Core/DAO.php
Original file line number Diff line number Diff line change
Expand Up @@ -2578,7 +2578,7 @@ public static function buildOptionsContext($context = NULL) {
* @param string $fieldName
* @return bool|array
*/
public function getFieldSpec($fieldName) {
public function getFieldType($fieldName) {
$fields = $this->fields();
$fieldKeys = $this->fieldKeys();

Expand Down
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;
}

}

0 comments on commit 8b7b236

Please sign in to comment.