dev/core#1187 Fix bug where import will not do 2 phone types of the same location
authoreileen <emcnaughton@wikimedia.org>
Mon, 2 Sep 2019 08:51:08 +0000 (20:51 +1200)
committereileen <emcnaughton@wikimedia.org>
Mon, 2 Sep 2019 08:54:17 +0000 (20:54 +1200)
CRM/Contact/Import/Parser.php
CRM/Import/ImportProcessor.php
tests/phpunit/CRM/Contact/Import/Parser/ContactTest.php

index c0fac2ee073fdaf05268afc9d0db450b2ee3cec2..7b7e027308d62f4bf3d3125daef3ddf63ebed564 100644 (file)
@@ -1207,6 +1207,7 @@ abstract class CRM_Contact_Import_Parser extends CRM_Import_Parser {
       if (!array_key_exists($blockFieldName, $values)) {
         continue;
       }
+      $blockIndex = $values['location_type_id'] . (!empty($values['phone_type_id']) ? '_' . $values['phone_type_id'] : '');
 
       // block present in value array.
       if (!array_key_exists($blockFieldName, $params) || !is_array($params[$blockFieldName])) {
@@ -1221,13 +1222,13 @@ abstract class CRM_Contact_Import_Parser extends CRM_Import_Parser {
       }
 
       _civicrm_api3_store_values($fields[$block], $values,
-        $params[$blockFieldName][$values['location_type_id']]
+        $params[$blockFieldName][$blockIndex]
       );
 
-      $this->fillPrimary($params[$blockFieldName][$values['location_type_id']], $values, $block, CRM_Utils_Array::value('id', $params));
+      $this->fillPrimary($params[$blockFieldName][$blockIndex], $values, $block, CRM_Utils_Array::value('id', $params));
 
       if (empty($params['id']) && (count($params[$blockFieldName]) == 1)) {
-        $params[$blockFieldName][$values['location_type_id']]['is_primary'] = TRUE;
+        $params[$blockFieldName][$blockIndex]['is_primary'] = TRUE;
       }
 
       // we only process single block at a time.
index 535e641f8b2abf75aadbf8b95afa18531ae86610..089bb820dfaa587d27cadecd5a3efed9ed2d3df3 100644 (file)
@@ -170,6 +170,8 @@ class CRM_Import_ImportProcessor {
   }
 
   /**
+   * Get the contact type for the import.
+   *
    * @return string
    */
   public function getContactType(): string {
@@ -212,9 +214,27 @@ class CRM_Import_ImportProcessor {
   }
 
   /**
+   * Set mapping fields.
+   *
+   * We do a little cleanup here too.
+   *
+   * We ensure that column numbers are set and that the fields are ordered by them.
+   *
+   * This would mean the fields could be loaded unsorted.
+   *
    * @param array $mappingFields
    */
   public function setMappingFields(array $mappingFields) {
+    $i = 0;
+    foreach ($mappingFields as &$mappingField) {
+      if (!isset($mappingField['column_number'])) {
+        $mappingField['column_number'] = $i;
+      }
+      if ($mappingField['column_number'] > $i) {
+        $i = $mappingField['column_number'];
+      }
+      $i++;
+    }
     $this->mappingFields = $this->rekeyBySortedColumnNumbers($mappingFields);
   }
 
index 22325812f5b1d2a84f384824d9f0f0ca8001179b..92619e0480375535085ab215de17088e8b3f315e 100644 (file)
@@ -463,6 +463,32 @@ class CRM_Contact_Import_Parser_ContactTest extends CiviUnitTestCase {
     $this->callAPISuccess('Contact', 'delete', ['id' => $contact['id']]);
   }
 
+  /**
+   * Test importing 2 phones of different types.
+   *
+   * @throws \CRM_Core_Exception
+   * @throws \CiviCRM_API3_Exception
+   */
+  public function testImportTwoPhonesDifferentTypes() {
+    $processor = new CRM_Import_ImportProcessor();
+    $processor->setContactType('Individual');
+    $processor->setMappingFields(
+      [
+        ['name' => 'first_name'],
+        ['name' => 'last_name'],
+        ['name' => 'email'],
+        ['name' => 'phone', 'location_type_id' => 1, 'phone_type_id' => 2],
+        ['name' => 'phone', 'location_type_id' => 1, 'phone_type_id' => 1],
+      ]
+    );
+    $importer = $processor->getImporterObject();
+    $fields = ['First Name', 'new last name', 'bob@example.com', '1234', '5678'];
+    $importer->import(CRM_Import_Parser::DUPLICATE_UPDATE, $fields);
+    $contact = $this->callAPISuccessGetSingle('Contact', ['last_name' => 'new last name']);
+    $phones = $this->callAPISuccess('Phone', 'get', ['contact_id' => $contact['id']])['values'];
+    $this->assertCount(2, $phones);
+  }
+
   /**
    * Test that the import parser adds the address to the primary location.
    *