Fix custom import to work again (broke in master)
authorEileen McNaughton <emcnaughton@wikimedia.org>
Wed, 8 Jun 2022 01:52:14 +0000 (13:52 +1200)
committerEileen McNaughton <emcnaughton@wikimedia.org>
Wed, 8 Jun 2022 05:28:36 +0000 (17:28 +1200)
CRM/Contribute/Import/Form/Summary.php
CRM/Custom/Import/Form/DataSource.php
CRM/Custom/Import/Form/MapField.php
CRM/Custom/Import/Form/Preview.php
CRM/Custom/Import/Form/Summary.php
CRM/Custom/Import/Parser/Api.php
CRM/Event/Import/Form/MapField.php
CRM/Import/Form/DataSource.php
CRM/Import/Form/MapField.php
CRM/Import/Forms.php
templates/CRM/Custom/Import/Form/MapField.tpl

index c1d5d06b6fba6b93a0f4d45c59792121ef9acbc4..3d01d46709ff87ce1d4c76db1fdeb17aab1c8dbb 100644 (file)
  */
 class CRM_Contribute_Import_Form_Summary extends CRM_Import_Form_Summary {
 
-  /**
-   * Set variables up before form is built.
-   */
-  public function preProcess() {
-    parent::preProcess();
-  }
-
 }
index 1032e422a63eb23c92dd8a1985c5af4ef630a4ad..20eb8340a988aab7bc5baaa6bd26c99771614129 100644 (file)
@@ -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
    */
index 79bb9e437643bb1f9c648541c2add0e171e73a28..aa1391cb03e4228ff1852f2d519e3d3a952473ac 100644 (file)
@@ -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';
   }
 
 }
index a86abbb7fee9d0e9ec16536bba9db6c6f8e8089f..8a214d4cd020200e027ac7be31c4e837f890d902 100644 (file)
@@ -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
index 716e59f1f9518bc9b80f518f6465be7fb9b9812e..e0f0896e9c114236f4fbdc1951bdd30b02cec319 100644 (file)
@@ -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 {
 
 }
index c3a9293a6d2bca23a2e168e08ea18b14b84e8b72..db0783cc797b8e45de5506654d31fcce56f327aa 100644 (file)
@@ -1,80 +1,25 @@
 <?php
 
+use Civi\Api4\CustomGroup;
+
 /**
  * Class CRM_Custom_Import_Parser_Api
  */
 class CRM_Custom_Import_Parser_Api extends CRM_Import_Parser {
 
-  protected $_entity = '';
   protected $_fields = [];
-  protected $_requiredFields = [];
-  protected $_dateFields = [];
   protected $_multipleCustomData = '';
 
-  /**
-   * Params for the current entity being prepared for the api.
-   * @var array
-   */
-  protected $_params = [];
-
-  protected $_fileName;
-
-  /**
-   * Imported file size.
-   *
-   * @var int
-   */
-  protected $_fileSize;
-
-  /**
-   * Separator being used
-   * @var string
-   */
-  protected $_separator;
-
-  /**
-   * Total number of lines in file
-   * @var int
-   */
-  protected $_lineCount;
-
-  /**
-   * Whether the file has a column header or not
-   *
-   * @var bool
-   */
-  protected $_haveColumnHeader;
-
-  /**
-   * Class constructor.
-   *
-   * @param array $mapperKeys
-   * @param null $mapperLocType
-   * @param null $mapperPhoneType
-   */
-  public function __construct(&$mapperKeys = [], $mapperLocType = NULL, $mapperPhoneType = NULL) {
-    parent::__construct();
-    $this->_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
index 9695e21f24f16d2d3659a952ac31490530e81e20..2c260c1d8734edf7eb09cbdd3cd08669d647a6fe 100644 (file)
@@ -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 = "<script type='text/javascript'>\n";
-    $formName = 'document.forms.' . $this->_name;
-
-    foreach ($this->getColumnHeaders() as $i => $columnHeader) {
-      $sel = &$this->addElement('hierselect', "mapper[$i]", ts('Mapper for Field %1', array(1 => $i)), NULL);
-      $jsSet = FALSE;
-      if ($this->getSubmittedValue('savedMapping')) {
-        $fieldMapping = $fieldMappings[$i] ?? NULL;
-        if (isset($fieldMappings[$i])) {
-          if ($fieldMapping['name'] !== ts('do_not_import')) {
-            $js .= "{$formName}['mapper[$i][3]'].style.display = 'none';\n";
-            $defaults["mapper[$i]"] = [$fieldMapping['name']];
-            $jsSet = TRUE;
-          }
-          else {
-            $defaults["mapper[$i]"] = [];
-          }
-          if (!$jsSet) {
-            for ($k = 1; $k < 4; $k++) {
-              $js .= "{$formName}['mapper[$i][$k]'].style.display = 'none';\n";
-            }
-          }
-        }
-        else {
-          // this load section to help mapping if we ran out of saved columns when doing Load Mapping
-          $js .= "swapOptions($formName, 'mapper[$i]', 0, 3, 'hs_mapper_" . $i . "_');\n";
-
-          if ($hasHeaders) {
-            $defaults["mapper[$i]"] = array($this->defaultFromHeader($columnHeader, $headerPatterns));
-          }
-          else {
-            $defaults["mapper[$i]"] = array($this->defaultFromData($dataPatterns, $i));
-          }
-        }
-        //end of load mapping
-      }
-      else {
-        $js .= "swapOptions($formName, 'mapper[$i]', 0, 3, 'hs_mapper_" . $i . "_');\n";
-        if ($hasHeaders) {
-          // Infer the default from the skipped headers if we have them
-          $defaults["mapper[$i]"] = array(
-            $this->defaultFromHeader($columnHeader,
-              $headerPatterns
-            ),
-            //                     $defaultLocationType->id
-            0,
-          );
-        }
-        else {
-          // Otherwise guess the default from the form of the data
-          $defaults["mapper[$i]"] = array(
-            $this->defaultFromData($dataPatterns, $i),
-            //                     $defaultLocationType->id
-            0,
-          );
-        }
-      }
-      $sel->setOptions([$sel1]);
-    }
-    $js .= "</script>\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) {
index 306fe2d755236bf756056be91e08ce8a535f4e98..ddf8bf452b0279955a59e894b80dce8adbe53e81 100644 (file)
@@ -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
index 99f8fd6372fb61807e94223add41d207bb3c2434..97147731300aad70f4954bbccbcc4cd9f51b3b6f 100644 (file)
@@ -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 = "<script type='text/javascript'>\n";
+    $formName = 'document.forms.' . $this->_name;
+
+    foreach ($this->getColumnHeaders() as $i => $columnHeader) {
+      $sel = &$this->addElement('hierselect', "mapper[$i]", ts('Mapper for Field %1', [1 => $i]), NULL);
+      $jsSet = FALSE;
+      if ($this->getSubmittedValue('savedMapping')) {
+        $fieldMapping = $fieldMappings[$i] ?? NULL;
+        if (isset($fieldMappings[$i])) {
+          if ($fieldMapping['name'] !== ts('do_not_import')) {
+            $js .= "{$formName}['mapper[$i][3]'].style.display = 'none';\n";
+            $defaults["mapper[$i]"] = [$fieldMapping['name']];
+            $jsSet = TRUE;
+          }
+          else {
+            $defaults["mapper[$i]"] = [];
+          }
+          if (!$jsSet) {
+            for ($k = 1; $k < 4; $k++) {
+              $js .= "{$formName}['mapper[$i][$k]'].style.display = 'none';\n";
+            }
+          }
+        }
+        else {
+          // this load section to help mapping if we ran out of saved columns when doing Load Mapping
+          $js .= "swapOptions($formName, 'mapper[$i]', 0, 3, 'hs_mapper_" . $i . "_');\n";
+
+          if ($hasHeaders) {
+            $defaults["mapper[$i]"] = [$this->defaultFromHeader($columnHeader, $headerPatterns)];
+          }
+          else {
+            $defaults["mapper[$i]"] = [$this->defaultFromData($dataPatterns, $i)];
+          }
+        }
+        //end of load mapping
+      }
+      else {
+        $js .= "swapOptions($formName, 'mapper[$i]', 0, 3, 'hs_mapper_" . $i . "_');\n";
+        if ($hasHeaders) {
+          // Infer the default from the skipped headers if we have them
+          $defaults["mapper[$i]"] = [
+            $this->defaultFromHeader($columnHeader,
+              $headerPatterns
+            ),
+            //                     $defaultLocationType->id
+            0,
+          ];
+        }
+        else {
+          // Otherwise guess the default from the form of the data
+          $defaults["mapper[$i]"] = [
+            $this->defaultFromData($dataPatterns, $i),
+            //                     $defaultLocationType->id
+            0,
+          ];
+        }
+      }
+      $sel->setOptions([$sel1]);
+    }
+    $js .= "</script>\n";
+    $this->assign('initHideBoxes', $js);
+    $this->setDefaults($defaults);
+    return [$sel, $headerPatterns];
+  }
+
 }
index cd81aa4585f96471974edacf10b71bd26c218b80..00b4a6fe3a0fa7e545cfbeb955fa4dedde858a00 100644 (file)
@@ -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.
index aa6b3d1bca212a32735f16dcd167855db339fffe..8564c9b70f2075dbe84c68484e7c26120d15acc5 100644 (file)
@@ -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"}