Merge pull request #23959 from totten/master-casexml-acttype
[civicrm-core.git] / CRM / Import / Forms.php
index e87bc5acb7478830c4b6d73cd0a1dc001563c9ad..c9636b25bcff91a516c528a8832d069f97661759 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.
@@ -131,7 +132,6 @@ class CRM_Import_Forms extends CRM_Core_Form {
    * @param string $fieldName
    *
    * @return mixed|null
-   * @throws \CRM_Core_Exception
    */
   public function getSubmittedValue(string $fieldName) {
     if ($fieldName === 'dataSource') {
@@ -300,8 +300,6 @@ class CRM_Import_Forms extends CRM_Core_Form {
    * This is called as a snippet in DataSourceConfig and
    * also from DataSource::buildForm to add the fields such
    * that quick form picks them up.
-   *
-   * @throws \CRM_Core_Exception
    */
   protected function getDataSourceFields(): array {
     $className = $this->getDataSourceClassName();
@@ -329,7 +327,6 @@ class CRM_Import_Forms extends CRM_Core_Form {
    * all forms.
    *
    * @return string[]
-   * @throws \CRM_Core_Exception
    */
   protected function getSubmittableFields(): array {
     $dataSourceFields = array_fill_keys($this->getDataSourceFields(), 'DataSource');
@@ -376,7 +373,7 @@ class CRM_Import_Forms extends CRM_Core_Form {
     $id = UserJob::create(FALSE)
       ->setValues([
         'created_id' => CRM_Core_Session::getLoggedInContactID(),
-        'type_id:name' => 'contact_import',
+        'job_type' => $this->getUserJobType(),
         'status_id:name' => 'draft',
         // This suggests the data could be cleaned up after this.
         'expires_date' => '+ 1 week',
@@ -459,6 +456,35 @@ class CRM_Import_Forms extends CRM_Core_Form {
     return $this->getDataSourceObject()->setLimit($limit)->setStatuses($statuses)->getRows();
   }
 
+  /**
+   * Get the datasource rows ready for csv output.
+   *
+   * @param array $statuses
+   * @param int $limit
+   *
+   * @return array
+   * @throws \API_Exception
+   * @throws \CRM_Core_Exception
+   */
+  protected function getOutputRows($statuses = [], int $limit = 0) {
+    $statuses = (array) $statuses;
+    $dataSource = $this->getDataSourceObject()->setLimit($limit)->setStatuses($statuses)->setStatuses($statuses);
+    $dataSource->setSelectFields(array_merge(['_id', '_status_message'], $dataSource->getDataFieldNames()));
+    return $dataSource->getRows();
+  }
+
+  /**
+   * Get the column headers for the output csv.
+   *
+   * @return array
+   */
+  protected function getOutputColumnsHeaders(): array {
+    $headers = $this->getColumnHeaders();
+    array_unshift($headers, ts('Reason'));
+    array_unshift($headers, ts('Line Number'));
+    return $headers;
+  }
+
   /**
    * Get the number of rows with the specified status.
    *
@@ -486,7 +512,7 @@ class CRM_Import_Forms extends CRM_Core_Form {
    */
   public static function outputCSV(): void {
     $userJobID = CRM_Utils_Request::retrieveValue('user_job_id', 'Integer', NULL, TRUE);
-    $status = CRM_Utils_Request::retrieveValue('status', 'String', NULL, TRUE);
+    $status = (int) CRM_Utils_Request::retrieveValue('status', 'String', NULL, TRUE);
     $saveFileName = CRM_Import_Parser::saveFileName($status);
 
     $form = new CRM_Import_Forms();
@@ -495,46 +521,15 @@ class CRM_Import_Forms extends CRM_Core_Form {
 
     $form->getUserJob();
     $writer = Writer::createFromFileObject(new SplTempFileObject());
-    $headers = $form->getColumnHeaders();
-    if ($headers) {
-      array_unshift($headers, ts('Reason'));
-      array_unshift($headers, ts('Line Number'));
-      $writer->insertOne($headers);
-    }
-    $writer->addFormatter(['CRM_Import_Forms', 'reorderOutput']);
-    // Note this might be more inefficient that iterating the result
+    $headers = $form->getOutputColumnsHeaders();
+    $writer->insertOne($headers);
+    // Note this might be more inefficient by iterating the result
     // set & doing insertOne - possibly something to explore later.
-    $writer->insertAll($form->getDataRows($status));
-
-    CRM_Utils_System::setHttpHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0');
-    CRM_Utils_System::setHttpHeader('Content-Description', 'File Transfer');
-    CRM_Utils_System::setHttpHeader('Content-Type', 'text/csv; charset=UTF-8');
+    $writer->insertAll($form->getOutputRows($status));
     $writer->output($saveFileName);
     CRM_Utils_System::civiExit();
   }
 
-  /**
-   * When outputting the row as a csv, more the last 2 rows to the start.
-   *
-   * This is because the id and status message fields are at the end. It may make sense
-   * to move them to the start later, when order code cleanup has happened...
-   *
-   * @param array $record
-   */
-  public static function reorderOutput(array $record): array {
-    $rowNumber = array_pop($record);
-    $message = array_pop($record);
-    // Also pop off the status - but we are not going to use this at this stage.
-    array_pop($record);
-    // Related entities
-    array_pop($record);
-    // Entity_id
-    array_pop($record);
-    array_unshift($record, $message);
-    array_unshift($record, $rowNumber);
-    return $record;
-  }
-
   /**
    * Get the url to download the relevant csv file.
    * @param string $status
@@ -549,6 +544,32 @@ class CRM_Import_Forms extends CRM_Core_Form {
     ]);
   }
 
+  /**
+   * Get the url to download the relevant csv file.
+   * @param string $status
+   *
+   * @return string
+   */
+
+  /**
+   *
+   * @return array
+   */
+  public function getTrackingSummary(): array {
+    $summary = [];
+    $fields = $this->getParser()->getTrackingFields();
+    $row = $this->getDataSourceObject()->setAggregateFields($fields)->getRow();
+    foreach ($fields as $fieldName => $field) {
+      $summary[] = [
+        'field_name' => $fieldName,
+        'description' => $field['description'],
+        'value' => $row[$fieldName],
+      ];
+    }
+
+    return $summary;
+  }
+
   /**
    * Get the fields available for import selection.
    *
@@ -567,6 +588,14 @@ class CRM_Import_Forms extends CRM_Core_Form {
    * @return \CRM_Contact_Import_Parser_Contact|\CRM_Contribute_Import_Parser_Contribution
    */
   protected function getParser() {
+    foreach (CRM_Core_BAO_UserJob::getTypes() as $jobType) {
+      if ($jobType['id'] === $this->getUserJob()['job_type']) {
+        $className = $jobType['class'];
+        $classObject = new $className();
+        $classObject->setUserJobID($this->getUserJobID());
+        return $classObject;
+      };
+    }
     return NULL;
   }
 
@@ -578,7 +607,6 @@ class CRM_Import_Forms extends CRM_Core_Form {
    *
    * @return array
    * @throws \API_Exception
-   * @throws \CRM_Core_Exception
    */
   protected function getMappedFieldLabels(): array {
     $mapper = [];
@@ -601,6 +629,7 @@ class CRM_Import_Forms extends CRM_Core_Form {
     $this->_columnNames = $this->getColumnHeaders();
     $this->_dataValues = array_values($this->getDataRows([], 2));
     $this->assign('columnNames', $this->getColumnHeaders());
+    $this->assign('showColumnNames', $this->getSubmittedValue('skipColumnHeader') || $this->getSubmittedValue('dataSource') !== 'CRM_Import_DataSource');
     $this->assign('highlightedFields', $this->getHighlightedFields());
     $this->assign('columnCount', $this->_columnCount);
     $this->assign('dataValues', $this->_dataValues);
@@ -638,4 +667,20 @@ class CRM_Import_Forms extends CRM_Core_Form {
     return $this->getParser()->getHeaderPatterns();
   }
 
+  /**
+   * Has the user chosen to update existing records.
+   * @return bool
+   */
+  protected function isUpdateExisting(): bool {
+    return ((int) $this->getSubmittedValue('onDuplicate')) === CRM_Import_Parser::DUPLICATE_UPDATE;
+  }
+
+  /**
+   * Has the user chosen to update existing records.
+   * @return bool
+   */
+  protected function isSkipExisting(): bool {
+    return ((int) $this->getSubmittedValue('onDuplicate')) === CRM_Import_Parser::DUPLICATE_SKIP;
+  }
+
 }