From 739acba7a63f85b99dad1e484c0125b577abe92a Mon Sep 17 00:00:00 2001 From: Eileen McNaughton Date: Wed, 8 Jun 2022 13:52:14 +1200 Subject: [PATCH] Fix custom import to work again (broke in master) --- CRM/Contribute/Import/Form/Summary.php | 7 - CRM/Custom/Import/Form/DataSource.php | 16 - CRM/Custom/Import/Form/MapField.php | 164 +----- CRM/Custom/Import/Form/Preview.php | 111 ---- CRM/Custom/Import/Form/Summary.php | 13 +- CRM/Custom/Import/Parser/Api.php | 535 ++---------------- CRM/Event/Import/Form/MapField.php | 81 +-- CRM/Import/Form/DataSource.php | 12 +- CRM/Import/Form/MapField.php | 84 +++ CRM/Import/Forms.php | 1 + templates/CRM/Custom/Import/Form/MapField.tpl | 2 +- 11 files changed, 181 insertions(+), 845 deletions(-) diff --git a/CRM/Contribute/Import/Form/Summary.php b/CRM/Contribute/Import/Form/Summary.php index c1d5d06b6f..3d01d46709 100644 --- a/CRM/Contribute/Import/Form/Summary.php +++ b/CRM/Contribute/Import/Form/Summary.php @@ -20,11 +20,4 @@ */ class CRM_Contribute_Import_Form_Summary extends CRM_Import_Form_Summary { - /** - * Set variables up before form is built. - */ - public function preProcess() { - parent::preProcess(); - } - } diff --git a/CRM/Custom/Import/Form/DataSource.php b/CRM/Custom/Import/Form/DataSource.php index 1032e422a6..20eb8340a9 100644 --- a/CRM/Custom/Import/Form/DataSource.php +++ b/CRM/Custom/Import/Form/DataSource.php @@ -89,22 +89,6 @@ class CRM_Custom_Import_Form_DataSource extends CRM_Import_Form_DataSource { $this->addContactTypeSelector(); } - /** - * Process the uploaded file. - * - * @return void - */ - public function postProcess() { - $this->storeFormValues([ - 'contactType', - 'dateFormats', - 'savedMapping', - 'multipleCustomData', - ]); - - $this->submitFileForMapping('CRM_Custom_Import_Parser_Api', 'multipleCustomData'); - } - /** * @return CRM_Custom_Import_Parser_Api */ diff --git a/CRM/Custom/Import/Form/MapField.php b/CRM/Custom/Import/Form/MapField.php index 79bb9e4376..aa1391cb03 100644 --- a/CRM/Custom/Import/Form/MapField.php +++ b/CRM/Custom/Import/Form/MapField.php @@ -3,45 +3,7 @@ /** * Class CRM_Custom_Import_Form_MapField */ -class CRM_Custom_Import_Form_MapField extends CRM_Contact_Import_Form_MapField { - protected $_parser = 'CRM_Custom_Import_Parser_Api'; - protected $_mappingType = 'Import Multi value custom data'; - /** - * Entity being imported to. - * @var string - */ - protected $_entity; - - /** - * Set variables up before form is built. - * - * @return void - */ - public function preProcess() { - $this->_mapperFields = $this->get('fields'); - asort($this->_mapperFields); - $this->_columnCount = $this->get('columnCount'); - $this->assign('columnCount', $this->_columnCount); - $this->_dataValues = $this->get('dataValues'); - $highlightedFields = ['contact_id', 'external_identifier']; - - //Separate column names from actual values. - $columnNames = $this->_dataValues[0]; - //actual values need to be in 2d array ($array[$i][$j]) format to be parsed by the template. - $dataValues[] = $this->_dataValues[1]; - $this->assign('dataValues', $dataValues); - - $this->_entity = $this->_multipleCustomData = $this->get('multipleCustomData'); - $skipColumnHeader = $this->controller->exportValue('DataSource', 'skipColumnHeader'); - $this->_onDuplicate = $this->get('onDuplicate'); - if ($skipColumnHeader) { - $this->assign('columnNames', $columnNames); - /* if we had a column header to skip, stash it for later */ - $this->_columnHeaders = $this->_dataValues[0]; - } - $this->assign('rowDisplayCount', 2); - $this->assign('highlightedFields', $highlightedFields); - } +class CRM_Custom_Import_Form_MapField extends CRM_Import_Form_MapField { /** * Build the form object. @@ -49,22 +11,11 @@ class CRM_Custom_Import_Form_MapField extends CRM_Contact_Import_Form_MapField { * @return void */ public function buildQuickForm() { - parent::buildQuickForm(); + $savedMappingID = (int) $this->getSubmittedValue('savedMapping'); + $this->buildSavedMappingFields($savedMappingID); $this->addFormRule(['CRM_Custom_Import_Form_MapField', 'formRule']); - } - - /** - * Override contact import metadata with multi-value custom fields. - * - * Used to match saved mapping fields. - * - * @return array - */ - protected function getContactImportMetadata(): array { - $contactFields = CRM_Contact_BAO_Contact::importableFields('All', FALSE, FALSE, FALSE, TRUE, TRUE); - $contactFields['contact_id'] = $contactFields['id']; - $contactFields['contact_id']['name'] = 'contact_id'; - return $contactFields; + $this->addMapper(); + $this->addFormButtons(); } /** @@ -77,6 +28,7 @@ class CRM_Custom_Import_Form_MapField extends CRM_Contact_Import_Form_MapField { * list of errors to be posted back to the form */ public static function formRule($fields) { + // todo - this could be shared with other mapFields forms. $errors = []; if (!array_key_exists('savedMapping', $fields)) { $importKeys = []; @@ -126,100 +78,24 @@ class CRM_Custom_Import_Form_MapField extends CRM_Contact_Import_Form_MapField { } /** - * Process the mapped fields and map it into the uploaded file. - * preview the file and extract some summary statistics - * - * @return void + * @return \CRM_Custom_Import_Parser_Api() */ - public function postProcess() { - $params = $this->controller->exportValues('MapField'); - $this->set('multipleCustomData', $this->_multipleCustomData); - - //reload the mapfield if load mapping is pressed - if (!empty($params['savedMapping'])) { - $this->set('savedMapping', $params['savedMapping']); - $this->controller->resetPage($this->_name); - return; + protected function getParser():CRM_Custom_Import_Parser_Api { + if (!$this->parser) { + $this->parser = new CRM_Custom_Import_Parser_Api(); + $this->parser->setUserJobID($this->getUserJobID()); + $this->parser->init(); } - - $this->_entity = $this->controller->exportValue('DataSource', 'entity'); - - $mapper = []; - $mapperKeys = $this->controller->exportValue($this->_name, 'mapper'); - $mapperKeysMain = []; - - for ($i = 0; $i < $this->_columnCount; $i++) { - $mapper[$i] = $this->_mapperFields[$mapperKeys[$i][0]]; - $mapperKeysMain[$i] = $mapperKeys[$i][0]; - } - - $this->set('mapper', $mapper); - - // store mapping Id to display it in the preview page - $this->set('loadMappingId', CRM_Utils_Array::value('mappingId', $params)); - - //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 = $this->getMappingFieldName($mapper[$i]); - $updateMappingFields->save(); - } - } - - //Saving Mapping Details and Records - if (!empty($params['saveMapping'])) { - $mappingParams = [ - 'name' => $params['saveMappingName'], - 'description' => $params['saveMappingDesc'], - 'mapping_type_id' => CRM_Core_PseudoConstant::getKey('CRM_Core_BAO_Mapping', 'mapping_type_id', $this->_mappingType), - ]; - $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 = $this->getMappingFieldName($mapper[$i]); - $saveMappingFields->save(); - } - $this->set('savedMapping', $saveMappingFields->mapping_id); - } - $this->set('_entity', $this->_entity); - - $parser = new $this->_parser($mapperKeysMain); - $parser->setEntity($this->_multipleCustomData); - $parser->run($this->getSubmittedValue('uploadFile'), $this->getSubmittedValue('fieldSeparator'), $mapper, $this->getSubmittedValue('skipColumnHeader'), - CRM_Import_Parser::MODE_PREVIEW, $this->get('contactType') - ); - // add all the necessary variables to the form - $parser->set($this); + return $this->parser; } - private function getMappingFieldName($label) { - $name = array_search($label, $this->_mapperFields); - // The `CRM_Import_ImportProcessor::getNameFromLabel` function expects custom fields like "fieldLabel :: groupLabel" - if ($name && strpos($name, 'custom_') === 0) { - return $label . ' :: ' . CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomGroup', $this->_multipleCustomData, 'title'); - } - return $label; + /** + * Get the type of used for civicrm_mapping.mapping_type_id. + * + * @return string + */ + public function getMappingTypeName(): string { + return 'Import Multi value custom data'; } } diff --git a/CRM/Custom/Import/Form/Preview.php b/CRM/Custom/Import/Form/Preview.php index a86abbb7fe..8a214d4cd0 100644 --- a/CRM/Custom/Import/Form/Preview.php +++ b/CRM/Custom/Import/Form/Preview.php @@ -4,117 +4,6 @@ * Class CRM_Custom_Import_Form_Preview */ class CRM_Custom_Import_Form_Preview extends CRM_Import_Form_Preview { - public $_parser = 'CRM_Custom_Import_Parser_Api'; - protected $_importParserUrl = '&parser=CRM_Custom_Import_Parser_Api'; - - /** - * Set variables up before form is built. - * - * @return void - */ - public function preProcess() { - parent::preProcess(); - //get the data from the session - $dataValues = $this->get('dataValues'); - $mapper = $this->get('mapper'); - $invalidRowCount = $this->get('invalidRowCount'); - $entity = $this->get('_entity'); - - //get the mapping name displayed if the mappingId is set - $mappingId = $this->get('loadMappingId'); - if ($mappingId) { - $mapDAO = new CRM_Core_DAO_Mapping(); - $mapDAO->id = $mappingId; - $mapDAO->find(TRUE); - } - $this->assign('savedMappingName', $mappingId ? $mapDAO->name : NULL); - - if ($invalidRowCount) { - $urlParams = 'type=' . CRM_Import_Parser::ERROR . $this->_importParserUrl; - $this->set('downloadErrorRecordsUrl', CRM_Utils_System::url('civicrm/export', $urlParams)); - } - - $properties = [ - 'mapper', - 'dataValues', - 'columnCount', - 'totalRowCount', - 'validRowCount', - 'invalidRowCount', - 'downloadErrorRecordsUrl', - ]; - - foreach ($properties as $property) { - $this->assign($property, $this->get($property)); - } - } - - /** - * Process the mapped fields and map it into the uploaded file. - * preview the file and extract some summary statistics - * - * @return void - */ - public function postProcess() { - $fileName = $this->getSubmittedValue('uploadFile'); - $invalidRowCount = $this->get('invalidRowCount'); - $onDuplicate = $this->get('onDuplicate'); - $entity = $this->get('_entity'); - - $mapper = $this->controller->exportValue('MapField', 'mapper'); - $mapperKeys = []; - - foreach ($mapper as $key => $value) { - $mapperKeys[$key] = $mapper[$key][0]; - } - - $parser = new $this->_parser($mapperKeys); - $parser->setUserJobID($this->getUserJobID()); - $parser->setEntity($entity); - - $mapFields = $this->get('fields'); - - foreach ($mapper as $key => $value) { - $header = []; - if (isset($mapFields[$mapper[$key][0]])) { - $header[] = $mapFields[$mapper[$key][0]]; - } - $mapperFields[] = implode(' - ', $header); - } - $parser->run($this->getSubmittedValue('uploadFile'), $this->getSubmittedValue('fieldSeparator'), - $mapperFields, - $this->getSubmittedValue('skipColumnHeader'), - CRM_Import_Parser::MODE_IMPORT, - $this->get('contactType'), - $onDuplicate - ); - - // add all the necessary variables to the form - $parser->set($this, CRM_Import_Parser::MODE_IMPORT); - - // check if there is any error occurred - - $errorStack = CRM_Core_Error::singleton(); - $errors = $errorStack->getErrors(); - $errorMessage = []; - - if (is_array($errors)) { - foreach ($errors as $key => $value) { - $errorMessage[] = $value['message']; - } - - $errorFile = $fileName['name'] . '.error.log'; - - if ($fd = fopen($errorFile, 'w')) { - fwrite($fd, implode('\n', $errorMessage)); - } - fclose($fd); - - $this->set('errorFile', $errorFile); - $urlParams = 'type=' . CRM_Import_Parser::ERROR . $this->_importParserUrl; - $this->set('downloadErrorRecordsUrl', CRM_Utils_System::url('civicrm/export', $urlParams)); - } - } /** * @return CRM_Custom_Import_Parser_Api diff --git a/CRM/Custom/Import/Form/Summary.php b/CRM/Custom/Import/Form/Summary.php index 716e59f1f9..e0f0896e9c 100644 --- a/CRM/Custom/Import/Form/Summary.php +++ b/CRM/Custom/Import/Form/Summary.php @@ -3,17 +3,6 @@ /** * Class CRM_Custom_Import_Form_Summary */ -class CRM_Custom_Import_Form_Summary extends CRM_Contact_Import_Form_Summary { - - /** - * Set variables up before form is built. - * - * @return void - */ - public function preProcess() { - parent::preProcess(); - $session = CRM_Core_Session::singleton(); - $session->pushUserContext(CRM_Utils_System::url('civicrm/import/custom', 'reset=1')); - } +class CRM_Custom_Import_Form_Summary extends CRM_Import_Form_Summary { } diff --git a/CRM/Custom/Import/Parser/Api.php b/CRM/Custom/Import/Parser/Api.php index c3a9293a6d..db0783cc79 100644 --- a/CRM/Custom/Import/Parser/Api.php +++ b/CRM/Custom/Import/Parser/Api.php @@ -1,80 +1,25 @@ _mapperKeys = &$mapperKeys; - } - - public function setFields() { - $customGroupID = $this->_multipleCustomData; - $importableFields = $this->getGroupFieldsForImport($customGroupID, $this); - $this->_fields = array_merge([ - 'do_not_import' => ['title' => ts('- do not import -')], - 'contact_id' => ['title' => ts('Contact ID')], - 'external_identifier' => ['title' => ts('External Identifier')], - ], $importableFields); - } - /** * The initializer code, called before the processing * * @return void */ public function init() { - $this->setFields(); - $fields = $this->_fields; + // Force user job to reload. + unset($this->userJob); + $this->setFieldMetadata(); + $fields = $this->importableFieldsMetadata; $hasLocationType = FALSE; foreach ($fields as $name => $field) { @@ -83,122 +28,74 @@ class CRM_Custom_Import_Parser_Api extends CRM_Import_Parser { $field['headerPattern'] = CRM_Utils_Array::value('headerPattern', $field, '//'); $this->addField($name, $field['title'], $field['type'], $field['headerPattern'], $field['dataPattern'], $hasLocationType); } - $this->setActiveFields($this->_mapperKeys); - } - - /** - * Handle the values in preview mode. - * - * @param array $values - * The array of values belonging to this line. - * - * @return bool - * the result of this processing - */ - public function preview(&$values) { - return $this->summary($values); - } - - /** - * @param array $values - * The array of values belonging to this line. - * - * @return bool - * the result of this processing - * It is called from both the preview & the import actions - * - * @see CRM_Custom_Import_Parser_BaseClass::summary() - */ - public function summary(&$values) { - $this->setActiveFieldValues($values); - $errorRequired = FALSE; - $missingField = ''; - $this->_params = &$this->getActiveFieldParams(); - - $this->_updateWithId = FALSE; - $this->_parseStreetAddress = CRM_Utils_Array::value('street_address_parsing', CRM_Core_BAO_Setting::valueOptions(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'address_options'), FALSE); - - $this->_params = $this->getActiveFieldParams(); - foreach ($this->_requiredFields as $requiredField) { - if (empty($this->_params[$requiredField])) { - $errorRequired = TRUE; - $missingField .= ' ' . $requiredField; - CRM_Contact_Import_Parser_Contact::addToErrorMsg($this->_entity, $requiredField); - } - } - - if ($errorRequired) { - array_unshift($values, ts('Missing required field(s) :') . $missingField); - return CRM_Import_Parser::ERROR; - } - - $errorMessage = NULL; - - $contactType = $this->_contactType ? $this->_contactType : 'Organization'; - $this->isErrorInCustomData($this->_params + ['contact_type' => $contactType], $errorMessage, $this->_contactSubType, NULL); - - // pseudoconstants - if ($errorMessage) { - $tempMsg = "Invalid value for field(s) : $errorMessage"; - array_unshift($values, $tempMsg); - $errorMessage = NULL; - return CRM_Import_Parser::ERROR; - } - return CRM_Import_Parser::VALID; } /** - * Handle the values in import mode. + * Main import function. * - * @param int $onDuplicate - * The code for what action to take on duplicates. * @param array $values * The array of values belonging to this line. - * - * @return bool - * the result of this processing */ - public function import($onDuplicate, &$values) { + public function import($values) { + $rowNumber = (int) $values[array_key_last($values)]; try { - $response = $this->summary($values); - if ($response != CRM_Import_Parser::VALID) { - return $response; + $params = $this->getMappedRow($values); + $formatted = []; + foreach ($params as $key => $value) { + if ($value !== '') { + $formatted[$key] = $value; + } } - $this->_updateWithId = FALSE; - $this->_parseStreetAddress = CRM_Utils_Array::value('street_address_parsing', CRM_Core_BAO_Setting::valueOptions(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'address_options'), FALSE); - - $contactType = $this->_contactType ? $this->_contactType : 'Organization'; - $formatted = [ - 'contact_type' => $contactType, - ]; - - if (isset($this->_params['external_identifier']) && !isset($this->_params['contact_id'])) { + if (isset($params['external_identifier']) && !isset($params['contact_id'])) { $checkCid = new CRM_Contact_DAO_Contact(); - $checkCid->external_identifier = $this->_params['external_identifier']; + $checkCid->external_identifier = $params['external_identifier']; $checkCid->find(TRUE); $formatted['id'] = $checkCid->id; } else { - $formatted['id'] = $this->_params['contact_id']; + $formatted['id'] = $params['contact_id']; } - $this->formatCommonData($this->_params, $formatted); + $this->formatCommonData($params, $formatted); foreach ($formatted['custom'] as $key => $val) { - $this->_params['custom_' . $key] = $val[-1]['value']; + $params['custom_' . $key] = $val[-1]['value']; } - $this->_params['skipRecentView'] = TRUE; - $this->_params['check_permissions'] = TRUE; - $this->_params['entity_id'] = $formatted['id']; - civicrm_api3('custom_value', 'create', $this->_params); + $params['skipRecentView'] = TRUE; + $params['check_permissions'] = TRUE; + $params['entity_id'] = $formatted['id']; + $contactID = civicrm_api3('custom_value', 'create', $params)['id']; + $this->setImportStatus($rowNumber, 'IMPORTED', '', $contactID); } catch (CiviCRM_API3_Exception $e) { - $error = $e->getMessage(); - array_unshift($values, $error); - return CRM_Import_Parser::ERROR; + $this->setImportStatus($rowNumber, 'ERROR', '', $e->getMessage()); + } + } + + /** + * Set the import metadata. + */ + public function setFieldMetadata(): void { + if (!$this->importableFieldsMetadata) { + $customGroupID = $this->getSubmittedValue('multipleCustomData'); + $importableFields = $this->getGroupFieldsForImport($customGroupID); + $this->importableFieldsMetadata = array_merge([ + 'do_not_import' => ['title' => ts('- do not import -')], + 'contact_id' => ['title' => ts('Contact ID'), 'name' => 'contact_id', 'type' => CRM_Utils_Type::T_INT, 'options' => FALSE], + 'external_identifier' => ['title' => ts('External Identifier'), 'name' => 'external_identifier', 'type' => CRM_Utils_Type::T_INT, 'options' => FALSE], + ], $importableFields); } } + /** + * Get the required fields. + * + * @return array + */ + public function getRequiredFields(): array { + return ['contact_id' => ts('Contact ID'), 'external_identifier' => ts('External Identifier')]; + } + /** * Adapted from CRM_Contact_Import_Parser_Contact::formatCommonData * @@ -213,29 +110,6 @@ class CRM_Custom_Import_Parser_Api extends CRM_Import_Parser { $customFields = CRM_Core_BAO_CustomField::getFields(NULL); - //format date first - $session = CRM_Core_Session::singleton(); - $dateType = $session->get("dateTypes"); - foreach ($params as $key => $val) { - $customFieldID = CRM_Core_BAO_CustomField::getKeyID($key); - if ($customFieldID) { - //we should not update Date to null, CRM-4062 - if ($val && ($customFields[$customFieldID]['data_type'] == 'Date')) { - //CRM-21267 - $this->formatCustomDate($params, $formatted, $dateType, $key); - } - elseif ($customFields[$customFieldID]['data_type'] == 'Boolean') { - if (empty($val) && !is_numeric($val)) { - //retain earlier value when Import mode is `Fill` - unset($params[$key]); - } - else { - $params[$key] = CRM_Utils_String::strtoboolstr($val); - } - } - } - } - //now format custom data. foreach ($params as $key => $field) { @@ -293,32 +167,24 @@ class CRM_Custom_Import_Parser_Api extends CRM_Import_Parser { } } - /** - * Set import entity. - * @param string $entity - */ - public function setEntity($entity) { - $this->_entity = $entity; - $this->_multipleCustomData = $entity; - } - /** * Return the field ids and names (with groups) for import purpose. * - * @param int $id + * @param int $customGroupID * Custom group ID. * * @return array * */ - public function getGroupFieldsForImport($id) { + private function getGroupFieldsForImport($customGroupID) { $importableFields = []; - $params = ['custom_group_id' => $id]; + $params = ['custom_group_id' => $customGroupID]; + $group = CustomGroup::get(FALSE)->addSelect('extends')->addWhere('id', '=', $customGroupID)->execute()->first(); $allFields = civicrm_api3('custom_field', 'get', $params); $fields = $allFields['values']; foreach ($fields as $id => $values) { $datatype = $values['data_type'] ?? NULL; - if ($datatype == 'File') { + if ($datatype === 'File') { continue; } /* generate the key for the fields array */ @@ -333,297 +199,20 @@ class CRM_Custom_Import_Parser_Api extends CRM_Import_Parser { 'options_per_line' => $values['options_per_line'] ?? NULL, 'data_type' => $values['data_type'] ?? NULL, 'html_type' => $values['html_type'] ?? NULL, + 'type' => CRM_Core_BAO_CustomField::dataToType()[$values['data_type']], 'is_search_range' => $values['is_search_range'] ?? NULL, + 'date_format' => $values['date_format'] ?? NULL, + 'time_format' => $values['time_format'] ?? NULL, + 'extends' => $group['extends'], ]; - if (CRM_Utils_Array::value('html_type', $values) == 'Select Date') { - $importableFields[$key]['date_format'] = $values['date_format'] ?? NULL; - $importableFields[$key]['time_format'] = $values['time_format'] ?? NULL; - $this->_dateFields[] = $key; - } } return $importableFields; } /** - * @param string $fileName - * @param string $separator - * @param int $mapper - * @param bool $skipColumnHeader - * @param int|string $mode - * @param int|string $contactType - * @param int $onDuplicate - * - * @return mixed - * @throws Exception - */ - public function run( - $fileName, - $separator, - $mapper, - $skipColumnHeader = FALSE, - $mode = self::MODE_PREVIEW, - $contactType = self::CONTACT_INDIVIDUAL, - $onDuplicate = self::DUPLICATE_SKIP - ) { - if (!is_array($fileName)) { - throw new CRM_Core_Exception('Unable to determine import file'); - } - $fileName = $fileName['name']; - - switch ($contactType) { - case CRM_Import_Parser::CONTACT_INDIVIDUAL: - $this->_contactType = 'Individual'; - break; - - case CRM_Import_Parser::CONTACT_HOUSEHOLD: - $this->_contactType = 'Household'; - break; - - case CRM_Import_Parser::CONTACT_ORGANIZATION: - $this->_contactType = 'Organization'; - } - $this->init(); - - $this->_haveColumnHeader = $skipColumnHeader; - - $this->_separator = $separator; - - $fd = fopen($fileName, "r"); - if (!$fd) { - return FALSE; - } - - $this->_lineCount = $this->_warningCount = 0; - $this->_invalidRowCount = $this->_validCount = 0; - $this->_totalCount = 0; - - $this->_errors = []; - $this->_warnings = []; - - $this->_fileSize = number_format(filesize($fileName) / 1024.0, 2); - - if ($mode == self::MODE_MAPFIELD) { - $this->_rows = []; - } - else { - $this->_activeFieldCount = count($this->_activeFields); - } - - while (!feof($fd)) { - $this->_lineCount++; - - $values = fgetcsv($fd, 8192, $separator); - if (!$values) { - continue; - } - - self::encloseScrub($values); - - // skip column header if we're not in mapfield mode - if ($mode != self::MODE_MAPFIELD && $skipColumnHeader) { - $skipColumnHeader = FALSE; - continue; - } - - /* trim whitespace around the values */ - - $empty = TRUE; - foreach ($values as $k => $v) { - $values[$k] = trim($v, " \t\r\n"); - } - - if (CRM_Utils_System::isNull($values)) { - continue; - } - - $this->_totalCount++; - - if ($mode == self::MODE_MAPFIELD) { - $returnCode = CRM_Import_Parser::VALID; - } - elseif ($mode == self::MODE_PREVIEW) { - $returnCode = $this->preview($values); - } - elseif ($mode == self::MODE_SUMMARY) { - $returnCode = $this->summary($values); - } - elseif ($mode == self::MODE_IMPORT) { - $returnCode = $this->import($onDuplicate, $values); - } - else { - $returnCode = self::ERROR; - } - - // note that a line could be valid but still produce a warning - if ($returnCode & self::VALID) { - $this->_validCount++; - if ($mode == self::MODE_MAPFIELD) { - $this->_rows[] = $values; - $this->_activeFieldCount = max($this->_activeFieldCount, count($values)); - } - } - - if ($returnCode & self::WARNING) { - $this->_warningCount++; - if ($this->_warningCount < $this->_maxWarningCount) { - $this->_warnings[] = $this->_lineCount; - } - } - - if ($returnCode & self::ERROR) { - $this->_invalidRowCount++; - $recordNumber = $this->_lineCount; - if ($this->_haveColumnHeader) { - $recordNumber--; - } - array_unshift($values, $recordNumber); - $this->_errors[] = $values; - } - - if ($returnCode & self::DUPLICATE) { - $this->_duplicateCount++; - $recordNumber = $this->_lineCount; - if ($this->_haveColumnHeader) { - $recordNumber--; - } - array_unshift($values, $recordNumber); - $this->_duplicates[] = $values; - if ($onDuplicate != self::DUPLICATE_SKIP) { - $this->_validCount++; - } - } - - // if we are done processing the maxNumber of lines, break - if ($this->_maxLinesToProcess > 0 && $this->_validCount >= $this->_maxLinesToProcess) { - break; - } - } - - fclose($fd); - - if ($mode == self::MODE_PREVIEW || $mode == self::MODE_IMPORT) { - $customHeaders = $mapper; - - $customfields = CRM_Core_BAO_CustomField::getFields('Activity'); - foreach ($customHeaders as $key => $value) { - if ($id = CRM_Core_BAO_CustomField::getKeyID($value)) { - $customHeaders[$key] = $customfields[$id][0]; - } - } - if ($this->_invalidRowCount) { - // removed view url for invlaid contacts - $headers = array_merge([ - ts('Line Number'), - ts('Reason'), - ], $customHeaders); - $this->_errorFileName = self::errorFileName(self::ERROR); - CRM_Contact_Import_Parser_Contact::exportCSV($this->_errorFileName, $headers, $this->_errors); - } - - if ($this->_duplicateCount) { - $headers = array_merge([ - ts('Line Number'), - ts('View Activity History URL'), - ], $customHeaders); - - $this->_duplicateFileName = self::errorFileName(self::DUPLICATE); - CRM_Contact_Import_Parser_Contact::exportCSV($this->_duplicateFileName, $headers, $this->_duplicates); - } - } - } - - /** - * Given a list of the importable field keys that the user has selected - * set the active fields array to this list - * - * @param array $fieldKeys mapped array of values - * - * @return void - */ - public function setActiveFields($fieldKeys) { - $this->_activeFieldCount = count($fieldKeys); - foreach ($fieldKeys as $key) { - if (empty($this->_fields[$key])) { - $this->_activeFields[] = new CRM_Custom_Import_Field('', ts('- do not import -')); - } - else { - $this->_activeFields[] = clone($this->_fields[$key]); - } - } - } - - /** - * Format the field values for input to the api. + * @deprecated stores metadata in the old format that + * a few functions in the parent class still use. * - * @return array - * (reference ) associative array of name/value pairs - */ - public function &getActiveFieldParams() { - $params = []; - for ($i = 0; $i < $this->_activeFieldCount; $i++) { - if (isset($this->_activeFields[$i]->_value) - && !isset($params[$this->_activeFields[$i]->_name]) - && !isset($this->_activeFields[$i]->_related) - ) { - $params[$this->_activeFields[$i]->_name] = $this->_activeFields[$i]->_value; - } - } - return $params; - } - - /** - * Store parser values. - * - * @param CRM_Core_Session $store - * - * @param int $mode - * - * @return void - */ - public function set($store, $mode = self::MODE_SUMMARY) { - $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); - $store->set('_entity', $this->_entity); - $store->set('totalRowCount', $this->_totalCount); - $store->set('validRowCount', $this->_validCount); - $store->set('invalidRowCount', $this->_invalidRowCount); - - switch ($this->_contactType) { - case 'Individual': - $store->set('contactType', CRM_Import_Parser::CONTACT_INDIVIDUAL); - break; - - case 'Household': - $store->set('contactType', CRM_Import_Parser::CONTACT_HOUSEHOLD); - break; - - case 'Organization': - $store->set('contactType', CRM_Import_Parser::CONTACT_ORGANIZATION); - } - - if ($this->_invalidRowCount) { - $store->set('errorsFileName', $this->_errorFileName); - } - - if (isset($this->_rows) && !empty($this->_rows)) { - $store->set('dataValues', $this->_rows); - } - - if ($mode == self::MODE_IMPORT) { - $store->set('duplicateRowCount', $this->_duplicateCount); - if ($this->_duplicateCount) { - $store->set('duplicatesFileName', $this->_duplicateFileName); - } - } - } - - /** * @param string $name * @param $title * @param int $type @@ -631,7 +220,7 @@ class CRM_Custom_Import_Parser_Api extends CRM_Import_Parser { * @param string $dataPattern * @param bool $hasLocationType */ - public function addField( + private function addField( $name, $title, $type = CRM_Utils_Type::T_INT, $headerPattern = '//', $dataPattern = '//', $hasLocationType = FALSE diff --git a/CRM/Event/Import/Form/MapField.php b/CRM/Event/Import/Form/MapField.php index 9695e21f24..2c260c1d87 100644 --- a/CRM/Event/Import/Form/MapField.php +++ b/CRM/Event/Import/Form/MapField.php @@ -57,84 +57,7 @@ class CRM_Event_Import_Form_MapField extends CRM_Import_Form_MapField { $savedMappingID = (int) $this->getSubmittedValue('savedMapping'); $this->buildSavedMappingFields($savedMappingID); $this->addFormRule(array('CRM_Event_Import_Form_MapField', 'formRule'), $this); - - $defaults = []; - $mapperKeys = array_keys($this->_mapperFields); - $hasHeaders = $this->getSubmittedValue('skipColumnHeader'); - $headerPatterns = $this->getHeaderPatterns(); - $dataPatterns = $this->getDataPatterns(); - $fieldMappings = $this->getFieldMappings(); - /* Initialize all field usages to false */ - - foreach ($mapperKeys as $key) { - $this->_fieldUsed[$key] = FALSE; - } - $this->_location_types = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Address', 'location_type_id'); - $sel1 = $this->_mapperFields; - - $js = "\n"; - $this->assign('initHideBoxes', $js); - $this->setDefaults($defaults); - + $this->addMapper(); $this->addFormButtons(); } @@ -154,7 +77,7 @@ class CRM_Event_Import_Form_MapField extends CRM_Import_Form_MapField { $errors = []; // define so we avoid notices below $errors['_qf_default'] = ''; - $contactFieldsBelowWeightMessage = NULL; + if (!array_key_exists('savedMapping', $fields)) { $importKeys = []; foreach ($fields['mapper'] as $mapperPart) { diff --git a/CRM/Import/Form/DataSource.php b/CRM/Import/Form/DataSource.php index 306fe2d755..ddf8bf452b 100644 --- a/CRM/Import/Form/DataSource.php +++ b/CRM/Import/Form/DataSource.php @@ -149,10 +149,18 @@ abstract class CRM_Import_Form_DataSource extends CRM_Import_Forms { } } + /** + * Common postProcessing. + */ + public function postProcess() { + $this->processDatasource(); + $this->controller->resetPage('MapField'); + parent::postProcess(); + } + /** * Common form postProcess. - * - * @param string $parserClassName + * @deprecated - just use postProcess. * * @param string|null $entity * Entity to set for paraser currently only for custom import diff --git a/CRM/Import/Form/MapField.php b/CRM/Import/Form/MapField.php index 99f8fd6372..9714773130 100644 --- a/CRM/Import/Form/MapField.php +++ b/CRM/Import/Form/MapField.php @@ -340,4 +340,88 @@ abstract class CRM_Import_Form_MapField extends CRM_Import_Forms { return []; } + /** + * Add the mapper hierarchical select field to the form. + * + * @return array + */ + protected function addMapper(): array { + $defaults = []; + $mapperKeys = array_keys($this->_mapperFields); + $hasHeaders = $this->getSubmittedValue('skipColumnHeader'); + $headerPatterns = $this->getHeaderPatterns(); + $dataPatterns = $this->getDataPatterns(); + $fieldMappings = $this->getFieldMappings(); + /* Initialize all field usages to false */ + + foreach ($mapperKeys as $key) { + $this->_fieldUsed[$key] = FALSE; + } + $sel1 = $this->_mapperFields; + + $js = "\n"; + $this->assign('initHideBoxes', $js); + $this->setDefaults($defaults); + return [$sel, $headerPatterns]; + } + } diff --git a/CRM/Import/Forms.php b/CRM/Import/Forms.php index cd81aa4585..00b4a6fe3a 100644 --- a/CRM/Import/Forms.php +++ b/CRM/Import/Forms.php @@ -118,6 +118,7 @@ class CRM_Import_Forms extends CRM_Core_Form { 'onDuplicate' => 'DataSource', 'disableUSPS' => 'DataSource', 'doGeocodeAddress' => 'DataSource', + 'multipleCustomData' => 'DataSource', // Note we don't add the save mapping instructions for MapField here // (eg 'updateMapping') - as they really are an action for that form // rather than part of the mapping config. diff --git a/templates/CRM/Custom/Import/Form/MapField.tpl b/templates/CRM/Custom/Import/Form/MapField.tpl index aa6b3d1bca..8564c9b70f 100644 --- a/templates/CRM/Custom/Import/Form/MapField.tpl +++ b/templates/CRM/Custom/Import/Form/MapField.tpl @@ -7,4 +7,4 @@ | and copyright information, see https://civicrm.org/licensing | +--------------------------------------------------------------------+ *} -{include file="CRM/Contact/Import/Form/MapField.tpl"} +{include file="CRM/Import/Form/MapField.tpl"} -- 2.25.1