diff --git a/CRM/Contact/Import/Parser/Contact.php b/CRM/Contact/Import/Parser/Contact.php index e81a34394e78..f723ee88a37e 100644 --- a/CRM/Contact/Import/Parser/Contact.php +++ b/CRM/Contact/Import/Parser/Contact.php @@ -230,7 +230,7 @@ public function preview(&$values) { * CRM_Import_Parser::ERROR or CRM_Import_Parser::VALID */ public function summary(&$values): int { - $rowNumber = (int) ($values[count($values) - 1]); + $rowNumber = (int) ($values[array_key_last($values)]); try { $this->validateValues($values); } @@ -270,6 +270,7 @@ public function getAllFields() { * @throws \API_Exception */ public function import($onDuplicate, &$values) { + $rowNumber = (int) $values[array_key_last($values)]; $this->_unparsedStreetAddressContacts = []; if (!$this->getSubmittedValue('doGeocodeAddress')) { // CRM-5854, reset the geocode method to null to prevent geocoding @@ -282,7 +283,7 @@ public function import($onDuplicate, &$values) { if ($response != CRM_Import_Parser::VALID) { $this->setImportStatus((int) $values[count($values) - 1], 'Invalid', "Invalid (Error Code: $response)"); - return $response; + return FALSE; } $params = $this->getMappedRow($values); @@ -302,7 +303,7 @@ public function import($onDuplicate, &$values) { } catch (CRM_Core_Exception $e) { $statuses = [CRM_Import_Parser::DUPLICATE => 'DUPLICATE', CRM_Import_Parser::ERROR => 'ERROR', CRM_Import_Parser::NO_MATCH => 'invalid_no_match']; - $this->setImportStatus((int) $values[count($values) - 1], $statuses[$e->getErrorCode()], $e->getMessage()); + $this->setImportStatus($rowNumber, $statuses[$e->getErrorCode()], $e->getMessage()); return FALSE; } @@ -334,10 +335,8 @@ public function import($onDuplicate, &$values) { elseif (CRM_Core_Error::isAPIError($newContact, CRM_Core_Error::DUPLICATE_CONTACT)) { // if duplicate, no need of further processing if ($onDuplicate == CRM_Import_Parser::DUPLICATE_SKIP) { - $errorMessage = "Skipping duplicate record"; - array_unshift($values, $errorMessage); - $this->setImportStatus((int) $values[count($values) - 1], 'DUPLICATE', $errorMessage); - return CRM_Import_Parser::DUPLICATE; + $this->setImportStatus($rowNumber, 'DUPLICATE', 'Skipping duplicate record'); + return FALSE; } // CRM-10433/CRM-20739 - IDs could be string or array; handle accordingly @@ -427,10 +426,8 @@ public function import($onDuplicate, &$values) { } } else { - $errorMessage = $relatedNewContact['error_message']; - array_unshift($values, $errorMessage); - $this->setImportStatus((int) $values[count($values) - 1], 'ERROR', $errorMessage); - return CRM_Import_Parser::ERROR; + $this->setImportStatus((int) $values[count($values) - 1], 'ERROR', $relatedNewContact['error_message']); + return FALSE; } } else { @@ -449,9 +446,8 @@ public function import($onDuplicate, &$values) { } if (!empty($relatedCsType) && (!CRM_Contact_BAO_ContactType::isAllowEdit($matchedIDs[0], $relatedCsType) && $relatedCsType != CRM_Utils_Array::value('contact_sub_type', $formatting))) { - $errorMessage = ts("Mismatched or Invalid contact subtype found for this related contact."); - array_unshift($values, $errorMessage); - return CRM_Import_Parser::NO_MATCH; + $this->setImportStatus((int) $values[count($values) - 1], 'invalid_no_match', 'Mismatched or Invalid contact subtype found for this related contact.'); + return FALSE; } else { $updatedContact = $this->createContact($formatting, $contactFields, $onDuplicate, $matchedIDs[0]); @@ -550,10 +546,8 @@ public function import($onDuplicate, &$values) { return $this->handleDuplicateError($newContact, $values, $onDuplicate, $formatted, $contactFields); } // Not a dupe, so we had an error - $errorMessage = $newContact['error_message']; - array_unshift($values, $errorMessage); - $this->setImportStatus((int) $values[count($values) - 1], 'ERROR', $errorMessage); - return CRM_Import_Parser::ERROR; + $this->setImportStatus((int) $values[count($values) - 1], 'ERROR', $newContact['error_message']); + return FALSE; } @@ -1910,15 +1904,8 @@ public function run( $prevTimestamp = $this->progressImport($statusID, FALSE, $startTimestamp, $prevTimestamp, $totalRowCount); } } - else { - $returnCode = self::ERROR; - } - - if ($returnCode & self::NO_MATCH) { - $this->setImportStatus((int) $values[count($values) - 1], 'invalid_no_match', array_shift($values)); - } - - if ($returnCode & self::UNPARSED_ADDRESS_WARNING) { + // @todo this should be done within import - it probably is! + if (isset($returnCode) && $returnCode === self::UNPARSED_ADDRESS_WARNING) { $this->setImportStatus((int) $values[count($values) - 1], 'warning_unparsed_address', array_shift($values)); } } diff --git a/tests/phpunit/CRM/Contact/Import/Parser/ContactTest.php b/tests/phpunit/CRM/Contact/Import/Parser/ContactTest.php index 619b06f97b4a..cd3864d0ec39 100644 --- a/tests/phpunit/CRM/Contact/Import/Parser/ContactTest.php +++ b/tests/phpunit/CRM/Contact/Import/Parser/ContactTest.php @@ -555,7 +555,7 @@ public function testImportPrimaryAddress() { * * @throws \Exception */ - public function testIgnoreLocationTypeId() { + public function testIgnoreLocationTypeId(): void { // Create a rule that matches on last name and street address. $rgid = $this->createRuleGroup()['id']; $this->callAPISuccess('Rule', 'create', [ @@ -1539,6 +1539,8 @@ protected function runImport(array $originalValues, $onDuplicateAction, $expecte $fields = array_keys($originalValues); } $values = array_values($originalValues); + // Stand in for rowNumber. + $values[] = 1; $mapper = []; foreach ($fields as $index => $field) { $mapper[] = [$field, $mapperLocType[$index] ?? NULL, $field === 'phone' ? 1 : NULL]; @@ -1756,6 +1758,8 @@ public function testImportParserDoesNotMatchPrimaryToRelated(): void { $fields = array_keys($contactImportValues); $values = array_values($contactImportValues); $values[] = 'tim.cook@apple.com'; + // Stand in for row number. + $values[] = 1; $userJobID = $this->getUserJobID([ 'mapper' => $mapper, @@ -1764,9 +1768,11 @@ public function testImportParserDoesNotMatchPrimaryToRelated(): void { $parser = new CRM_Contact_Import_Parser_Contact($fields); $parser->setUserJobID($userJobID); - $parser->init(); + $dataSource = new CRM_Import_DataSource_CSV($userJobID); - $this->assertEquals(CRM_Import_Parser::ERROR, $parser->import(CRM_Import_Parser::DUPLICATE_UPDATE, $values), 'Return code from parser import was not as expected'); + $parser->init(); + $parser->import(CRM_Import_Parser::DUPLICATE_UPDATE, $values); + $this->assertEquals(1, $dataSource->getRowCount([CRM_Import_Parser::ERROR])); $this->callAPISuccessGetSingle('Contact', [ 'first_name' => 'Bob', 'last_name' => 'Dobbs',