Merge pull request #16577 from civicrm/5.23
authorEileen McNaughton <emcnaughton@wikimedia.org>
Mon, 17 Feb 2020 22:57:11 +0000 (11:57 +1300)
committerGitHub <noreply@github.com>
Mon, 17 Feb 2020 22:57:11 +0000 (11:57 +1300)
5.23 to master

CRM/Dedupe/BAO/Rule.php
tests/phpunit/CRM/Dedupe/DedupeFinderTest.php

index 73048c846c610e9db08ebfb689991c68922d9045..58aed5c24671cf62eb00c50a12a0cdcf4c9a7eb0 100644 (file)
@@ -61,15 +61,13 @@ class CRM_Dedupe_BAO_Rule extends CRM_Dedupe_DAO_Rule {
     // 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'";
     }
@@ -245,4 +243,26 @@ class CRM_Dedupe_BAO_Rule extends CRM_Dedupe_DAO_Rule {
     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'];
+  }
+
 }
index 0e5f599a35c31a3a924771629e0e172565bc516f..6ba4c131bacc28e081df0951b0fe93e901708c7d 100644 (file)
@@ -6,6 +6,7 @@
  */
 class CRM_Dedupe_DedupeFinderTest extends CiviUnitTestCase {
 
+  use CRMTraits_Custom_CustomDataTrait;
   /**
    * IDs of created contacts.
    *
@@ -33,6 +34,10 @@ class CRM_Dedupe_DedupeFinderTest extends CiviUnitTestCase {
     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();
   }
 
@@ -94,15 +99,7 @@ class CRM_Dedupe_DedupeFinderTest extends CiviUnitTestCase {
   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'],
@@ -117,6 +114,25 @@ class CRM_Dedupe_DedupeFinderTest extends CiviUnitTestCase {
 
   }
 
+  /**
+   * 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.
    *
@@ -185,15 +201,7 @@ class CRM_Dedupe_DedupeFinderTest extends CiviUnitTestCase {
   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'],
@@ -440,4 +448,20 @@ class CRM_Dedupe_DedupeFinderTest extends CiviUnitTestCase {
     $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;
+  }
+
 }