diff --git a/CRM/Contact/Import/Parser.php b/CRM/Contact/Import/Parser.php index c0fac2ee073f..acfb2f525844 100644 --- a/CRM/Contact/Import/Parser.php +++ b/CRM/Contact/Import/Parser.php @@ -1207,6 +1207,7 @@ protected function formatLocationBlock(&$values, &$params) { 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 @@ protected function formatLocationBlock(&$values, &$params) { } _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. diff --git a/CRM/Import/ImportProcessor.php b/CRM/Import/ImportProcessor.php index 535e641f8b2a..089bb820dfaa 100644 --- a/CRM/Import/ImportProcessor.php +++ b/CRM/Import/ImportProcessor.php @@ -170,6 +170,8 @@ public function setMappingID(int $mappingID) { } /** + * Get the contact type for the import. + * * @return string */ public function getContactType(): string { @@ -212,9 +214,27 @@ public function getMappingFields(): array { } /** + * 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); } diff --git a/tests/phpunit/CRM/Contact/Import/Parser/ContactTest.php b/tests/phpunit/CRM/Contact/Import/Parser/ContactTest.php index 22325812f5b1..92619e048037 100644 --- a/tests/phpunit/CRM/Contact/Import/Parser/ContactTest.php +++ b/tests/phpunit/CRM/Contact/Import/Parser/ContactTest.php @@ -463,6 +463,32 @@ public function testImportTwoAddressFirstPrimary() { $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. *