From 209cedd99a1e1cdc194fa41d2285fda4dcfa6ad0 Mon Sep 17 00:00:00 2001 From: Eileen McNaughton Date: Thu, 26 May 2022 17:37:55 +1200 Subject: [PATCH] Update Member import to use labels not names in mapping --- CRM/Member/Import/Form/MapField.php | 76 +++----- CRM/Member/Import/Form/Preview.php | 11 +- CRM/Member/Import/Parser/Membership.php | 172 +++++------------- CRM/Upgrade/Incremental/php/FiveFiftyOne.php | 27 +++ .../Member/Import/Parser/MembershipTest.php | 90 +++++---- 5 files changed, 151 insertions(+), 225 deletions(-) diff --git a/CRM/Member/Import/Form/MapField.php b/CRM/Member/Import/Form/MapField.php index b5cccd9dfc..08fc3605bd 100644 --- a/CRM/Member/Import/Form/MapField.php +++ b/CRM/Member/Import/Form/MapField.php @@ -106,7 +106,7 @@ class CRM_Member_Import_Form_MapField extends CRM_Import_Form_MapField { else { $savedMapping = $this->get('savedMapping'); - list($mappingName) = CRM_Core_BAO_Mapping::getMappingFields($savedMapping); + [$mappingName] = CRM_Core_BAO_Mapping::getMappingFields($savedMapping); $mappingName = $mappingName[1]; @@ -169,10 +169,7 @@ class CRM_Member_Import_Form_MapField extends CRM_Import_Form_MapField { $jsSet = FALSE; if ($this->get('savedMapping')) { if (isset($mappingName[$i])) { - if ($mappingName[$i] != ts('- do not import -')) { - - $mappingHeader = array_keys($this->_mapperFields, $mappingName[$i]); - + if ($mappingName[$i] != ts('do_not_import')) { //When locationType is not set $js .= "{$formName}['mapper[$i][1]'].style.display = 'none';\n"; @@ -181,7 +178,7 @@ class CRM_Member_Import_Form_MapField extends CRM_Import_Form_MapField { $js .= "{$formName}['mapper[$i][3]'].style.display = 'none';\n"; - $defaults["mapper[$i]"] = array($mappingHeader[0]); + $defaults["mapper[$i]"] = [$mappingName[$i]]; $jsSet = TRUE; } else { @@ -208,7 +205,7 @@ class CRM_Member_Import_Form_MapField extends CRM_Import_Form_MapField { } else { $js .= "swapOptions($formName, 'mapper[$i]', 0, 3, 'hs_mapper_" . $i . "_');\n"; - if ($hasHeaders) { + if ($this->getSubmittedValue('skipColumnHeader')) { // Infer the default from the skipped headers if we have them $defaults["mapper[$i]"] = array( $this->defaultFromHeader($this->_columnHeaders[$i], @@ -293,27 +290,27 @@ class CRM_Member_Import_Form_MapField extends CRM_Import_Form_MapField { 'membership_start_date' => ts('Membership Start Date'), ); - $contactTypeId = $self->get('contactType'); - $contactTypes = array( - CRM_Import_Parser::CONTACT_INDIVIDUAL => 'Individual', - CRM_Import_Parser::CONTACT_HOUSEHOLD => 'Household', - CRM_Import_Parser::CONTACT_ORGANIZATION => 'Organization', - ); - $params = array( - 'used' => 'Unsupervised', - 'contact_type' => $contactTypes[$contactTypeId], - ); + $contactTypeId = $self->get('contactType'); + $contactTypes = array( + CRM_Import_Parser::CONTACT_INDIVIDUAL => 'Individual', + CRM_Import_Parser::CONTACT_HOUSEHOLD => 'Household', + CRM_Import_Parser::CONTACT_ORGANIZATION => 'Organization', + ); + $params = array( + 'used' => 'Unsupervised', + 'contact_type' => $contactTypes[$contactTypeId], + ); list($ruleFields, $threshold) = CRM_Dedupe_BAO_DedupeRuleGroup::dedupeRuleFieldsWeight($params); - $weightSum = 0; - foreach ($importKeys as $key => $val) { - if (array_key_exists($val, $ruleFields)) { - $weightSum += $ruleFields[$val]; + $weightSum = 0; + foreach ($importKeys as $key => $val) { + if (array_key_exists($val, $ruleFields)) { + $weightSum += $ruleFields[$val]; + } + } + $fieldMessage = ''; + foreach ($ruleFields as $field => $weight) { + $fieldMessage .= ' ' . $field . '(weight ' . $weight . ')'; } - } - $fieldMessage = ''; - foreach ($ruleFields as $field => $weight) { - $fieldMessage .= ' ' . $field . '(weight ' . $weight . ')'; - } foreach ($requiredFields as $field => $title) { if (!in_array($field, $importKeys)) { @@ -395,24 +392,8 @@ class CRM_Member_Import_Form_MapField extends CRM_Import_Form_MapField { } //Updating Mapping Records if (!empty($params['updateMapping'])) { - $mappingFields = new CRM_Core_DAO_MappingField(); - $mappingFields->mapping_id = $params['mappingId']; - $mappingFields->find(); - - $mappingFieldsId = []; - while ($mappingFields->fetch()) { - if ($mappingFields->id) { - $mappingFieldsId[$mappingFields->column_number] = $mappingFields->id; - } - } - for ($i = 0; $i < $this->_columnCount; $i++) { - $updateMappingFields = new CRM_Core_DAO_MappingField(); - $updateMappingFields->id = $mappingFieldsId[$i]; - $updateMappingFields->mapping_id = $params['mappingId']; - $updateMappingFields->column_number = $i; - $updateMappingFields->name = $mapper[$i]; - $updateMappingFields->save(); + $this->saveMappingField($params['mappingId'], $i, TRUE); } } @@ -426,14 +407,9 @@ class CRM_Member_Import_Form_MapField extends CRM_Import_Form_MapField { $saveMapping = CRM_Core_BAO_Mapping::add($mappingParams); for ($i = 0; $i < $this->_columnCount; $i++) { - - $saveMappingFields = new CRM_Core_DAO_MappingField(); - $saveMappingFields->mapping_id = $saveMapping->id; - $saveMappingFields->column_number = $i; - $saveMappingFields->name = $mapper[$i]; - $saveMappingFields->save(); + $this->saveMappingField($saveMapping->id, $i); } - $this->set('savedMapping', $saveMappingFields->mapping_id); + $this->set('savedMapping', $saveMapping->id); } $parser = new CRM_Member_Import_Parser_Membership($mapperKeysMain); diff --git a/CRM/Member/Import/Form/Preview.php b/CRM/Member/Import/Form/Preview.php index f7d45b71d4..673dd472b0 100644 --- a/CRM/Member/Import/Form/Preview.php +++ b/CRM/Member/Import/Form/Preview.php @@ -75,17 +75,8 @@ class CRM_Member_Import_Form_Preview extends CRM_Import_Form_Preview { $onDuplicate = $this->get('onDuplicate'); $mapper = $this->controller->exportValue('MapField', 'mapper'); - $mapperKeys = []; - // Note: we keep the multi-dimension array (even thought it's not - // needed in the case of memberships import) so that we can merge - // the common code with contacts import later and subclass contact - // and membership imports from there - foreach ($mapper as $key => $value) { - $mapperKeys[$key] = $mapper[$key][0]; - } - $parser = new CRM_Member_Import_Parser_Membership($mapperKeys); - $parser->setUserJobID($this->getUserJobID()); + $parser = $this->getParser(); $mapFields = $this->get('fields'); diff --git a/CRM/Member/Import/Parser/Membership.php b/CRM/Member/Import/Parser/Membership.php index 923771f8e2..51abea6107 100644 --- a/CRM/Member/Import/Parser/Membership.php +++ b/CRM/Member/Import/Parser/Membership.php @@ -22,9 +22,6 @@ class CRM_Member_Import_Parser_Membership extends CRM_Import_Parser { protected $_mapperKeys; - private $_membershipTypeIndex; - private $_membershipStatusIndex; - /** * Array of metadata for all available fields. * @@ -39,7 +36,6 @@ class CRM_Member_Import_Parser_Membership extends CRM_Import_Parser { */ protected $_newMemberships; - protected $_fileName; /** @@ -288,7 +284,8 @@ class CRM_Member_Import_Parser_Membership extends CRM_Import_Parser { * @return array * (reference ) associative array of name/value pairs */ - public function &getActiveFieldParams() { + public function getParams() { + $this->getSubmittedValue('mapper'); $params = []; for ($i = 0; $i < $this->_activeFieldCount; $i++) { if (isset($this->_activeFields[$i]->_value) @@ -302,6 +299,24 @@ class CRM_Member_Import_Parser_Membership extends CRM_Import_Parser { return $params; } + /** + * Get the row from the csv mapped to our parameters. + * + * @param array $values + * + * @return array + * @throws \API_Exception + */ + public function getMappedRow(array $values): array { + $params = []; + foreach ($this->getFieldMappings() as $i => $mappedField) { + if ($mappedField['name']) { + $params[$this->getFieldMetadata($mappedField['name'])['name']] = $this->getTransformedFieldValue($mappedField['name'], $values[$i]); + } + } + return $params; + } + /** * @param string $name * @param $title @@ -341,9 +356,7 @@ class CRM_Member_Import_Parser_Membership extends CRM_Import_Parser { $store->set('fileSize', $this->_fileSize); $store->set('lineCount', $this->_lineCount); $store->set('separator', $this->_separator); - $store->set('fields', $this->getSelectValues()); - $store->set('headerPatterns', $this->getHeaderPatterns()); $store->set('dataPatterns', $this->getDataPatterns()); $store->set('columnCount', $this->_activeFieldCount); @@ -429,25 +442,6 @@ class CRM_Member_Import_Parser_Membership extends CRM_Import_Parser { $this->_newMemberships = []; $this->setActiveFields($this->_mapperKeys); - - // FIXME: we should do this in one place together with Form/MapField.php - $this->_membershipTypeIndex = -1; - $this->_membershipStatusIndex = -1; - - $index = 0; - foreach ($this->_mapperKeys as $key) { - switch ($key) { - - case 'membership_type_id': - $this->_membershipTypeIndex = $index; - break; - - case 'status_id': - $this->_membershipStatusIndex = $index; - break; - } - $index++; - } } /** @@ -473,28 +467,16 @@ class CRM_Member_Import_Parser_Membership extends CRM_Import_Parser { * the result of this processing */ public function summary(&$values) { + $params = $this->getMappedRow($values); - $this->setActiveFieldValues($values); - - $errorRequired = FALSE; - - if ($this->_membershipTypeIndex < 0) { - $errorRequired = TRUE; - } - else { - $errorRequired = !CRM_Utils_Array::value($this->_membershipTypeIndex, $values); - } - - if ($errorRequired) { + if (empty($params['membership_type_id'])) { array_unshift($values, ts('Missing required fields')); return CRM_Import_Parser::ERROR; } - - $params = $this->getActiveFieldParams(); $errorMessage = NULL; //To check whether start date or join date is provided - if (empty($params['membership_start_date']) && empty($params['membership_join_date'])) { + if (empty($params['start_date']) && empty($params['join_date'])) { $errorMessage = 'Membership Start Date is required to create a memberships.'; CRM_Contact_Import_Parser_Contact::addToErrorMsg('Start Date', $errorMessage); } @@ -506,7 +488,7 @@ class CRM_Member_Import_Parser_Membership extends CRM_Import_Parser { if ($val) { switch ($key) { - case 'membership_join_date': + case 'join_date': if (CRM_Utils_Date::convertToDefaultDate($params, $dateType, $key)) { if (!CRM_Utils_Rule::date($params[$key])) { CRM_Contact_Import_Parser_Contact::addToErrorMsg('Member Since', $errorMessage); @@ -517,7 +499,7 @@ class CRM_Member_Import_Parser_Membership extends CRM_Import_Parser { } break; - case 'membership_start_date': + case 'start_date': if (CRM_Utils_Date::convertToDefaultDate($params, $dateType, $key)) { if (!CRM_Utils_Rule::date($params[$key])) { CRM_Contact_Import_Parser_Contact::addToErrorMsg('Start Date', $errorMessage); @@ -528,7 +510,7 @@ class CRM_Member_Import_Parser_Membership extends CRM_Import_Parser { } break; - case 'membership_end_date': + case 'end_date': if (CRM_Utils_Date::convertToDefaultDate($params, $dateType, $key)) { if (!CRM_Utils_Rule::date($params[$key])) { CRM_Contact_Import_Parser_Contact::addToErrorMsg('End date', $errorMessage); @@ -608,50 +590,25 @@ class CRM_Member_Import_Parser_Membership extends CRM_Import_Parser { if ($response != CRM_Import_Parser::VALID) { return $response; } - - $params = $this->getActiveFieldParams(); + $params = $this->getMappedRow($values); //assign join date equal to start date if join date is not provided - if (empty($params['membership_join_date']) && !empty($params['membership_start_date'])) { - $params['membership_join_date'] = $params['membership_start_date']; + if (empty($params['join_date']) && !empty($params['start_date'])) { + $params['join_date'] = $params['start_date']; } $session = CRM_Core_Session::singleton(); $dateType = CRM_Core_Session::singleton()->get('dateTypes'); - $formatted = []; + $formatted = $params; + $customDataType = !empty($params['contact_type']) ? $params['contact_type'] : 'Membership'; $customFields = CRM_Core_BAO_CustomField::getFields($customDataType); // don't add to recent items, CRM-4399 $formatted['skipRecentView'] = TRUE; - $dateLabels = [ - 'membership_join_date' => ts('Member Since'), - 'membership_start_date' => ts('Start Date'), - 'membership_end_date' => ts('End Date'), - ]; foreach ($params as $key => $val) { if ($val) { switch ($key) { - case 'membership_join_date': - case 'membership_start_date': - case 'membership_end_date': - if (CRM_Utils_Date::convertToDefaultDate($params, $dateType, $key)) { - if (!CRM_Utils_Rule::date($params[$key])) { - CRM_Contact_Import_Parser_Contact::addToErrorMsg($dateLabels[$key], $errorMessage); - } - } - else { - CRM_Contact_Import_Parser_Contact::addToErrorMsg($dateLabels[$key], $errorMessage); - } - break; - - case 'membership_type_id': - if (!is_numeric($val)) { - unset($params['membership_type_id']); - $params['membership_type'] = $val; - } - break; - case 'status_id': // @todo - we can do this based on the presence of 'pseudoconstant' in the metadata rather than field specific. $params[$key] = $this->parsePseudoConstantField($val, $this->fieldMetadata[$key]); @@ -694,7 +651,7 @@ class CRM_Member_Import_Parser_Membership extends CRM_Import_Parser { else { //fix for CRM-2219 Update Membership // onDuplicate == CRM_Import_Parser::DUPLICATE_UPDATE - if (!empty($formatted['member_is_override']) && empty($formatted['status_id'])) { + if (!empty($formatted['is_override']) && empty($formatted['status_id'])) { array_unshift($values, 'Required parameter missing: Status'); return CRM_Import_Parser::ERROR; } @@ -734,7 +691,7 @@ class CRM_Member_Import_Parser_Membership extends CRM_Import_Parser { $endDate = CRM_Utils_Date::customFormat(CRM_Utils_Array::value('end_date', $formatted), '%Y-%m-%d'); $joinDate = CRM_Utils_Date::customFormat(CRM_Utils_Array::value('join_date', $formatted), '%Y-%m-%d'); - if (!$this->isContactIDColumnPresent()) { + if (empty($formatValues['contact_id'])) { $error = $this->checkContactDuplicate($formatValues); if (CRM_Core_Error::isAPIError($error, CRM_Core_ERROR::DUPLICATE_CONTACT)) { @@ -758,7 +715,7 @@ class CRM_Member_Import_Parser_Membership extends CRM_Import_Parser { //fix for CRM-3570, exclude the statuses those having is_admin = 1 //now user can import is_admin if is override is true. $excludeIsAdmin = FALSE; - if (empty($formatted['member_is_override'])) { + if (empty($formatted['is_override'])) { $formatted['exclude_is_admin'] = $excludeIsAdmin = TRUE; } $calcStatus = CRM_Member_BAO_MembershipStatus::getMembershipStatusByDate($startDate, @@ -773,7 +730,7 @@ class CRM_Member_Import_Parser_Membership extends CRM_Import_Parser { if (empty($formatted['status_id'])) { $formatted['status_id'] = $calcStatus['id']; } - elseif (empty($formatted['member_is_override'])) { + elseif (empty($formatted['is_override'])) { if (empty($calcStatus)) { array_unshift($values, 'Status in import row (' . $formatValues['status_id'] . ') does not match calculated status based on your configured Membership Status Rules. Record was not imported.'); return CRM_Import_Parser::ERROR; @@ -848,7 +805,7 @@ class CRM_Member_Import_Parser_Membership extends CRM_Import_Parser { //fix for CRM-3570, exclude the statuses those having is_admin = 1 //now user can import is_admin if is override is true. $excludeIsAdmin = FALSE; - if (empty($formatted['member_is_override'])) { + if (empty($formatted['is_override'])) { $formatted['exclude_is_admin'] = $excludeIsAdmin = TRUE; } $calcStatus = CRM_Member_BAO_MembershipStatus::getMembershipStatusByDate($startDate, @@ -862,7 +819,7 @@ class CRM_Member_Import_Parser_Membership extends CRM_Import_Parser { if (empty($formatted['status_id'])) { $formatted['status_id'] = $calcStatus['id'] ?? NULL; } - elseif (empty($formatted['member_is_override'])) { + elseif (empty($formatted['is_override'])) { if (empty($calcStatus)) { array_unshift($values, 'Status in import row (' . CRM_Utils_Array::value('status_id', $formatValues) . ') does not match calculated status based on your configured Membership Status Rules. Record was not imported.'); return CRM_Import_Parser::ERROR; @@ -960,7 +917,7 @@ class CRM_Member_Import_Parser_Membership extends CRM_Import_Parser { } switch ($key) { - case 'membership_contact_id': + case 'contact_id': if (!CRM_Utils_Rule::integer($value)) { throw new Exception("contact_id not valid: $value"); } @@ -972,8 +929,7 @@ class CRM_Member_Import_Parser_Membership extends CRM_Import_Parser { if (!$svq) { throw new Exception("Invalid Contact ID: There is no contact record with contact_id = $value."); } - $values['contact_id'] = $values['membership_contact_id']; - unset($values['membership_contact_id']); + $values[$key] = $value; break; case 'membership_type_id': @@ -983,68 +939,22 @@ class CRM_Member_Import_Parser_Membership extends CRM_Import_Parser { $values[$key] = $value; break; - case 'membership_type': - $membershipTypeId = CRM_Utils_Array::key(ucfirst($value), - CRM_Member_PseudoConstant::membershipType() - ); - if ($membershipTypeId) { - if (!empty($values['membership_type_id']) && - $membershipTypeId != $values['membership_type_id'] - ) { - throw new Exception('Mismatched membership Type and Membership Type Id'); - } - } - else { - throw new Exception('Invalid Membership Type'); - } - $values['membership_type_id'] = $membershipTypeId; - break; - default: break; } } - if ($create) { - // CRM_Member_BAO_Membership::create() handles membership_start_date, membership_join_date, - // membership_end_date and membership_source. So, if $values contains - // membership_start_date, membership_end_date, membership_join_date or membership_source, - // convert it to start_date, end_date, join_date or source - $changes = [ - 'membership_join_date' => 'join_date', - 'membership_start_date' => 'start_date', - 'membership_end_date' => 'end_date', - 'membership_source' => 'source', - ]; - - foreach ($changes as $orgVal => $changeVal) { - if (isset($values[$orgVal])) { - $values[$changeVal] = $values[$orgVal]; - unset($values[$orgVal]); - } - } - } - return NULL; } - /** - * Is the contact ID mapped. - * - * @return bool - */ - protected function isContactIDColumnPresent(): bool { - return in_array('membership_contact_id', $this->_mapperKeys, TRUE); - } - /** * Set field metadata. */ protected function setFieldMetadata(): void { if (empty($this->importableFieldsMetadata)) { - $metadata = CRM_Member_BAO_Membership::importableFields($this->_contactType, FALSE); + $metadata = CRM_Member_BAO_Membership::importableFields($this->getContactType(), FALSE); - foreach ($this->fieldMetadata as $name => $field) { + foreach ($metadata as $name => $field) { // @todo - we don't really need to do all this.... fieldMetadata is just fine to use as is. $field['type'] = CRM_Utils_Array::value('type', $field, CRM_Utils_Type::T_INT); $field['dataPattern'] = CRM_Utils_Array::value('dataPattern', $field, '//'); diff --git a/CRM/Upgrade/Incremental/php/FiveFiftyOne.php b/CRM/Upgrade/Incremental/php/FiveFiftyOne.php index 3de256e0ff..f3a8f2dff4 100644 --- a/CRM/Upgrade/Incremental/php/FiveFiftyOne.php +++ b/CRM/Upgrade/Incremental/php/FiveFiftyOne.php @@ -91,6 +91,7 @@ class CRM_Upgrade_Incremental_php_FiveFiftyOne extends CRM_Upgrade_Incremental_B $fieldMap[ts(ts('Payment Method'))] = 'payment_instrument_id'; $fieldMap[ts('- do not import -')] = 'do_not_import'; + // Membership fields foreach ($mappings as $mapping) { if (!empty($fieldMap[$mapping['name']])) { MappingField::update(FALSE) @@ -99,6 +100,32 @@ class CRM_Upgrade_Incremental_php_FiveFiftyOne extends CRM_Upgrade_Incremental_B ->execute(); } } + + // Membership fields... + // Yes - I know they could be combined - but it's also less confusing this way. + $mappings = MappingField::get(FALSE) + ->setSelect(['id', 'name']) + ->addWhere('mapping_id.mapping_type_id:name', '=', 'Import Membership') + ->execute(); + $fields = CRM_Member_BAO_Membership::importableFields('All', FALSE);; + $fieldMap = []; + foreach ($fields as $fieldName => $field) { + $fieldMap[$field['title']] = $fieldName; + if (!empty($field['html']['label'])) { + $fieldMap[$field['html']['label']] = $fieldName; + } + } + $fieldMap[ts('- do not import -')] = 'do_not_import'; + + foreach ($mappings as $mapping) { + if (!empty($fieldMap[$mapping['name']])) { + MappingField::update(FALSE) + ->addWhere('id', '=', $mapping['id']) + ->addValue('name', $fieldMap[$mapping['name']]) + ->execute(); + } + } + return TRUE; } diff --git a/tests/phpunit/CRM/Member/Import/Parser/MembershipTest.php b/tests/phpunit/CRM/Member/Import/Parser/MembershipTest.php index 4c2ff9bfc3..62ad200bf2 100644 --- a/tests/phpunit/CRM/Member/Import/Parser/MembershipTest.php +++ b/tests/phpunit/CRM/Member/Import/Parser/MembershipTest.php @@ -1,7 +1,7 @@ . */ +use Civi\Api4\UserJob; + /** - * Test CRM/Member/BAO Membership Log add , delete functions - * * @package CiviCRM * @group headless */ @@ -103,6 +103,7 @@ class CRM_Member_Import_Parser_MembershipTest extends CiviUnitTestCase { 'civicrm_contribution', 'civicrm_membership_payment', 'civicrm_contact', + 'civicrm_email', ]; $this->relationshipTypeDelete($this->_relationshipTypeId); $this->membershipTypeDelete(['id' => $this->_membershipTypeID]); @@ -162,14 +163,10 @@ class CRM_Member_Import_Parser_MembershipTest extends CiviUnitTestCase { */ public function testImportOverriddenMembershipButWithoutStatus() { $this->individualCreate(['email' => 'anthony_anderson2@civicrm.org']); - - $fieldMapper = [ - 'mapper[0][0]' => 'email', - 'mapper[1][0]' => 'membership_type_id', - 'mapper[2][0]' => 'membership_start_date', - 'mapper[3][0]' => 'member_is_override', - ]; - $membershipImporter = new CRM_Member_Import_Parser_Membership($fieldMapper); + $membershipImporter = new CRM_Member_Import_Parser_Membership(); + $membershipImporter->setUserJobID($this->getUserJobID([ + ['email'], ['membership_type_id'], ['membership_start_date'], ['member_is_override'], + ])); $membershipImporter->init(); $membershipImporter->_contactType = 'Individual'; @@ -212,20 +209,13 @@ class CRM_Member_Import_Parser_MembershipTest extends CiviUnitTestCase { $this->assertEquals(CRM_Import_Parser::VALID, $importResponse); } - public function testImportOverriddenMembershipWithValidOverrideEndDate() { + public function testImportOverriddenMembershipWithValidOverrideEndDate(): void { $this->individualCreate(['email' => 'anthony_anderson4@civicrm.org']); - - $fieldMapper = [ - 'mapper[0][0]' => 'email', - 'mapper[1][0]' => 'membership_type_id', - 'mapper[2][0]' => 'membership_start_date', - 'mapper[3][0]' => 'member_is_override', - 'mapper[4][0]' => 'status_id', - 'mapper[5][0]' => 'status_override_end_date', - ]; - $membershipImporter = new CRM_Member_Import_Parser_Membership($fieldMapper); + $membershipImporter = new CRM_Member_Import_Parser_Membership(); + $membershipImporter->setUserJobID($this->getUserJobID([ + 'mapper' => [['email'], ['membership_type_id'], ['membership_start_date'], ['member_is_override'], ['status_id'], ['status_override_end_date']], + ])); $membershipImporter->init(); - $membershipImporter->_contactType = 'Individual'; $importValues = [ 'anthony_anderson4@civicrm.org', @@ -240,20 +230,14 @@ class CRM_Member_Import_Parser_MembershipTest extends CiviUnitTestCase { $this->assertEquals(CRM_Import_Parser::VALID, $importResponse); } - public function testImportOverriddenMembershipWithInvalidOverrideEndDate() { + public function testImportOverriddenMembershipWithInvalidOverrideEndDate(): void { $this->individualCreate(['email' => 'anthony_anderson5@civicrm.org']); - $fieldMapper = [ - 'mapper[0][0]' => 'email', - 'mapper[1][0]' => 'membership_type_id', - 'mapper[2][0]' => 'membership_start_date', - 'mapper[3][0]' => 'member_is_override', - 'mapper[4][0]' => 'status_id', - 'mapper[5][0]' => 'status_override_end_date', - ]; - $membershipImporter = new CRM_Member_Import_Parser_Membership($fieldMapper); + $membershipImporter = new CRM_Member_Import_Parser_Membership(); + $membershipImporter->setUserJobID($this->getUserJobID([ + ['email'], ['membership_type_id'], ['membership_start_date'], ['member_is_override'], ['status_id'], ['status_override_end_date'], + ])); $membershipImporter->init(); - $membershipImporter->_contactType = 'Individual'; $importValues = [ 'anthony_anderson5@civicrm.org', @@ -320,15 +304,53 @@ class CRM_Member_Import_Parser_MembershipTest extends CiviUnitTestCase { */ protected function createImportObject(array $fields): \CRM_Member_Import_Parser_Membership { $fieldMapper = []; + $mapper = []; foreach ($fields as $index => $field) { $fieldMapper['mapper[' . $index . '][0]'] = $field; + $mapper[] = [$field]; } + $membershipImporter = new CRM_Member_Import_Parser_Membership($fieldMapper); + $membershipImporter->setUserJobID($this->getUserJobID(['mapper' => $mapper])); $membershipImporter->init(); $membershipImporter->_contactType = 'Individual'; return $membershipImporter; } + /** + * @param array $submittedValues + * + * @return int + * + * @throws \API_Exception + * @throws \CRM_Core_Exception + */ + protected function getUserJobID(array $submittedValues = []): int { + $userJobID = UserJob::create()->setValues([ + 'metadata' => [ + 'submitted_values' => array_merge([ + 'contactType' => CRM_Import_Parser::CONTACT_INDIVIDUAL, + 'contactSubType' => '', + 'dataSource' => 'CRM_Import_DataSource_SQL', + 'sqlQuery' => 'SELECT first_name FROM civicrm_contact', + 'onDuplicate' => CRM_Import_Parser::DUPLICATE_SKIP, + 'dedupe_rule_id' => NULL, + 'dateFormats' => CRM_Core_Form_Date::DATE_yyyy_mm_dd, + ], $submittedValues), + ], + 'status_id:name' => 'draft', + 'type_id:name' => 'contact_import', + ])->execute()->first()['id']; + if ($submittedValues['dataSource'] ?? NULL === 'CRM_Import_DataSource') { + $dataSource = new CRM_Import_DataSource_CSV($userJobID); + } + else { + $dataSource = new CRM_Import_DataSource_SQL($userJobID); + } + $dataSource->initialize(); + return $userJobID; + } + /** * Test importing to a custom field. * -- 2.25.1