Merge pull request #14252 from jitendrapurohit/core-961
authorEileen McNaughton <emcnaughton@wikimedia.org>
Fri, 2 Aug 2019 01:11:37 +0000 (13:11 +1200)
committerGitHub <noreply@github.com>
Fri, 2 Aug 2019 01:11:37 +0000 (13:11 +1200)
dev/core#961 - Contribution page including 2 email fields does not re…

1  2 
CRM/Dedupe/Finder.php
tests/phpunit/CRM/Dedupe/DedupeFinderTest.php

diff --combined CRM/Dedupe/Finder.php
index 8d5e4462c47b27d5069020eeb34f6d9b593a1f2d,810a7b4c468406b420a1080ae8e3e2b692547e3c..f3fa9a01b75ed8bd753d266f5cd57954648456d9
@@@ -280,7 -280,8 +280,8 @@@ class CRM_Dedupe_Finder 
        $matches = [];
        if (preg_match('/(.*)-(Primary-[\d+])$|(.*)-(\d+|Primary)$/', $key, $matches)) {
          $return = array_values(array_filter($matches));
-         $flat[$return[1]] = $value;
+         // make sure the first occurrence is kept, not the last
+         $flat[$return[1]] = empty($flat[$return[1]]) ? $value : $flat[$return[1]];
          unset($flat[$key]);
        }
      }
        ];
  
        $data = CRM_Core_DAO::escapeString(serialize($row));
 -      $values[] = " ( 'civicrm_contact', $dstID, $srcID, '$cacheKeyString', '$data' ) ";
 +      CRM_Core_BAO_PrevNextCache::setItem('civicrm_contact', $dstID, $srcID, $cacheKeyString, $data);
      }
 -    CRM_Core_BAO_PrevNextCache::setItem($values);
      return $mainContacts;
    }
  
index 6dca289540e2e8026105383fc29fd47e9d60ba60,370fd2bfc32ad9312a6cbd1582acb31db2d77d12..00ff33f9d53c159703788abcb1331a7b339dc058
@@@ -11,7 -11,7 +11,7 @@@ class CRM_Dedupe_DedupeFinderTest exten
     *
     * @var array
     */
 -  protected $contactIDs = array();
 +  protected $contactIDs = [];
  
    /**
     * ID of the group holding the contacts.
@@@ -29,7 -29,7 +29,7 @@@
        $this->contactDelete($contactId);
      }
      if ($this->groupID) {
 -      $this->callAPISuccess('group', 'delete', array('id' => $this->groupID));
 +      $this->callAPISuccess('group', 'delete', ['id' => $this->groupID]);
      }
      parent::tearDown();
    }
@@@ -40,7 -40,7 +40,7 @@@
     * @throws \Exception
     */
    public function testUnsupervisedDupes() {
-     // make dupe checks based on based on following contact sets:
+     // make dupe checks based on following contact sets:
      // FIRST - LAST - EMAIL
      // ---------------------------------
      // robin  - hood - robin@example.com
      // will   - dale - will@example.com
      $this->setupForGroupDedupe();
  
 -    $ruleGroup = $this->callAPISuccessGetSingle('RuleGroup', array('is_reserved' => 1, 'contact_type' => 'Individual', 'used' => 'Unsupervised'));
 +    $ruleGroup = $this->callAPISuccessGetSingle('RuleGroup', ['is_reserved' => 1, 'contact_type' => 'Individual', 'used' => 'Unsupervised']);
  
      $foundDupes = CRM_Dedupe_Finder::dupesInGroup($ruleGroup['id'], $this->groupID);
      $this->assertEquals(count($foundDupes), 3, 'Check Individual-Fuzzy dupe rule for dupesInGroup().');
    }
  
+   /**
+    * Test duplicate contact retrieval with 2 email fields.
+    */
+   public function testUnsupervisedWithTwoEmailFields() {
+     $this->setupForGroupDedupe();
+     $emails = [
+       ['hood@example.com', ''],
+       ['', 'hood@example.com'],
+     ];
+     for ($i = 0; $i < 2; $i++) {
+       $fields = [
+         'first_name' => 'robin',
+         'last_name' => 'hood',
+         'email-1' => $emails[$i][0],
+         'email-2' => $emails[$i][1],
+       ];
+       $dedupeParams = CRM_Dedupe_Finder::formatParams($fields, 'Individual');
+       $dedupeResults = CRM_Dedupe_Finder::dupesByParams($dedupeParams, 'Individual');
+       $this->assertEquals(count($dedupeResults), 1);
+     }
+   }
    /**
     * Test that a rule set to is_reserved = 0 works.
     *
    public function testCustomRule() {
      $this->setupForGroupDedupe();
  
 -    $ruleGroup = $this->callAPISuccess('RuleGroup', 'create', array(
 +    $ruleGroup = $this->callAPISuccess('RuleGroup', 'create', [
        'contact_type' => 'Individual',
        'threshold' => 8,
        'used' => 'General',
        'name' => 'TestRule',
        'title' => 'TestRule',
        'is_reserved' => 0,
 -    ));
 +    ]);
      $rules = [];
 -    foreach (array('birth_date', 'first_name', 'last_name') as $field) {
 +    foreach (['birth_date', 'first_name', 'last_name'] as $field) {
        $rules[$field] = $this->callAPISuccess('Rule', 'create', [
          'dedupe_rule_group_id' => $ruleGroup['id'],
          'rule_table' => 'civicrm_contact',
    public function testCustomRuleWithAddress() {
      $this->setupForGroupDedupe();
  
 -    $ruleGroup = $this->callAPISuccess('RuleGroup', 'create', array(
 +    $ruleGroup = $this->callAPISuccess('RuleGroup', 'create', [
        'contact_type' => 'Individual',
        'threshold' => 10,
        'used' => 'General',
        'name' => 'TestRule',
        'title' => 'TestRule',
        'is_reserved' => 0,
 -    ));
 +    ]);
      $rules = [];
 -    foreach (array('postal_code') as $field) {
 +    foreach (['postal_code'] as $field) {
        $rules[$field] = $this->callAPISuccess('Rule', 'create', [
          'dedupe_rule_group_id' => $ruleGroup['id'],
          'rule_table' => 'civicrm_address',
     */
    public function testSupervisedDupes() {
      $this->setupForGroupDedupe();
 -    $ruleGroup = $this->callAPISuccessGetSingle('RuleGroup', array('is_reserved' => 1, 'contact_type' => 'Individual', 'used' => 'Supervised'));
 +    $ruleGroup = $this->callAPISuccessGetSingle('RuleGroup', ['is_reserved' => 1, 'contact_type' => 'Individual', 'used' => 'Supervised']);
      $foundDupes = CRM_Dedupe_Finder::dupesInGroup($ruleGroup['id'], $this->groupID);
      // -------------------------------------------------------------------------
      // default dedupe rule: threshold = 20 => (First + Last + Email) Matches ( 1 pair )
  
      // contact data set
      // FIXME: move create params to separate function
 -    $params = array(
 -      array(
 +    $params = [
 +      [
          'first_name' => 'robin',
          'last_name' => 'hood',
          'email' => 'robin@example.com',
          'contact_type' => 'Individual',
 -      ),
 -      array(
 +      ],
 +      [
          'first_name' => 'robin',
          'last_name' => 'hood',
          'email' => 'hood@example.com',
          'contact_type' => 'Individual',
 -      ),
 -      array(
 +      ],
 +      [
          'first_name' => 'robin',
          'last_name' => 'dale',
          'email' => 'robin@example.com',
          'contact_type' => 'Individual',
 -      ),
 -      array(
 +      ],
 +      [
          'first_name' => 'little',
          'last_name' => 'dale',
          'email' => 'dale@example.com',
          'contact_type' => 'Individual',
 -      ),
 -      array(
 +      ],
 +      [
          'first_name' => 'will',
          'last_name' => 'dale',
          'email' => 'dale@example.com',
          'contact_type' => 'Individual',
 -      ),
 -      array(
 +      ],
 +      [
          'first_name' => 'will',
          'last_name' => 'dale',
          'email' => 'will@example.com',
          'contact_type' => 'Individual',
 -      ),
 -      array(
 +      ],
 +      [
          'first_name' => 'will',
          'last_name' => 'dale',
          'email' => 'will@example.com',
          'contact_type' => 'Individual',
 -      ),
 -    );
 +      ],
 +    ];
  
 -    $this->hookClass->setHook('civicrm_findDuplicates', array($this, 'hook_civicrm_findDuplicates'));
 +    $this->hookClass->setHook('civicrm_findDuplicates', [$this, 'hook_civicrm_findDuplicates']);
  
      $count = 1;
  
      foreach ($params as $param) {
        $contact = $this->callAPISuccess('contact', 'create', $param);
 -      $params = array(
 +      $params = [
          'contact_id' => $contact['id'],
          'street_address' => 'Ambachtstraat 23',
          'location_type_id' => 1,
 -      );
 +      ];
        $this->callAPISuccess('address', 'create', $params);
        $contactIds[$count++] = $contact['id'];
      }
      // verify that all contacts have been created separately
      $this->assertEquals(count($contactIds), 7, 'Check for number of contacts.');
  
 -    $fields = array(
 +    $fields = [
        'first_name' => 'robin',
        'last_name' => 'hood',
        'email' => 'hood@example.com',
        'street_address' => 'Ambachtstraat 23',
 -    );
 +    ];
      CRM_Core_TemporaryErrorScope::useException();
      $ids = CRM_Contact_BAO_Contact::getDuplicateContacts($fields, 'Individual', 'General', [], TRUE, NULL, ['event_id' => 1]);
  
     * Set up a group of dedupable contacts.
     */
    protected function setupForGroupDedupe() {
 -    $params = array(
 +    $params = [
        'name' => 'Dupe Group',
        'title' => 'New Test Dupe Group',
        'domain_id' => 1,
        'is_active' => 1,
        'visibility' => 'Public Pages',
 -    );
 +    ];
  
      $result = $this->callAPISuccess('group', 'create', $params);
      $this->groupID = $result['id'];
  
 -    $params = array(
 -      array(
 +    $params = [
 +      [
          'first_name' => 'robin',
          'last_name' => 'hood',
          'email' => 'robin@example.com',
          'contact_type' => 'Individual',
          'birth_date' => '2016-01-01',
          'api.Address.create' => ['location_type_id' => 'Billing', 'postal_code' => '99999'],
 -      ),
 -      array(
 +      ],
 +      [
          'first_name' => 'robin',
          'last_name' => 'hood',
          'email' => 'hood@example.com',
          'contact_type' => 'Individual',
          'birth_date' => '2016-01-01',
          'api.Address.create' => ['location_type_id' => 'Billing', 'postal_code' => '99999'],
 -      ),
 -      array(
 +      ],
 +      [
          'first_name' => 'robin',
          'last_name' => 'dale',
          'email' => 'robin@example.com',
          'contact_type' => 'Individual',
 -      ),
 -      array(
 +      ],
 +      [
          'first_name' => 'little',
          'last_name' => 'dale',
          'email' => 'dale@example.com',
          'contact_type' => 'Individual',
 -      ),
 -      array(
 +      ],
 +      [
          'first_name' => 'will',
          'last_name' => 'dale',
          'email' => 'dale@example.com',
          'contact_type' => 'Individual',
 -      ),
 -      array(
 +      ],
 +      [
          'first_name' => 'will',
          'last_name' => 'dale',
          'email' => 'will@example.com',
          'contact_type' => 'Individual',
 -      ),
 -      array(
 +      ],
 +      [
          'first_name' => 'will',
          'last_name' => 'dale',
          'email' => 'will@example.com',
          'contact_type' => 'Individual',
 -      ),
 -    );
 +      ],
 +    ];
  
      $count = 1;
      foreach ($params as $param) {
        $contact = $this->callAPISuccess('contact', 'create', $param);
        $this->contactIDs[$count++] = $contact['id'];
  
 -      $grpParams = array(
 +      $grpParams = [
          'contact_id' => $contact['id'],
          'group_id' => $this->groupID,
 -      );
 +      ];
        $this->callAPISuccess('group_contact', 'create', $grpParams);
      }