Merge pull request #23419 from chrisgaraffa/contactheader-regions
[civicrm-core.git] / CRM / Import / DataSource.php
index 91759365489307cba449a7f39cf9eb87d0e486d4..df8ea13d12664a4d455b908c5f0b0b06040814ef 100644 (file)
@@ -67,6 +67,30 @@ abstract class CRM_Import_DataSource {
    */
   private $statuses = [];
 
+  /**
+   * Fields to select.
+   *
+   * @var array
+   */
+  private $selectFields;
+
+  /**
+   * @return array|null
+   */
+  public function getSelectFields(): ?array {
+    return $this->selectFields;
+  }
+
+  /**
+   * @param array $selectFields
+   *
+   * @return CRM_Import_DataSource
+   */
+  public function setSelectFields(array $selectFields): CRM_Import_DataSource {
+    $this->selectFields = $selectFields;
+    return $this;
+  }
+
   /**
    * Current row.
    *
@@ -435,21 +459,59 @@ abstract class CRM_Import_DataSource {
    *   could be cases where it still clashes but time didn't tell in this case)
    * 2) the show fields query used to get the column names excluded the
    *   administrative fields, relying on this convention.
-   * 3) we have the capitalisation on _statusMsg - @todo change to _status_message
+   * 3) we have the capitalisation on _statusMsg - @param string $tableName
    *
-   * @param string $tableName
+   * @throws \API_Exception
+   * @todo change to _status_message
    */
   protected function addTrackingFieldsToTable(string $tableName): void {
     CRM_Core_DAO::executeQuery("
      ALTER TABLE $tableName
        ADD COLUMN _entity_id INT,
-       ADD COLUMN _related_entity_ids LONGTEXT,
+       " . $this->getAdditionalTrackingFields() . "
        ADD COLUMN _status VARCHAR(32) DEFAULT 'NEW' NOT NULL,
        ADD COLUMN _status_message TEXT,
-       ADD COLUMN _id INT PRIMARY KEY NOT NULL AUTO_INCREMENT"
+       ADD COLUMN _id INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
+       ADD INDEX(_id),
+       ADD INDEX(_status)
+       "
     );
   }
 
+  /**
+   * Get any additional import specific tracking fields.
+   *
+   * @throws \API_Exception
+   */
+  private function getAdditionalTrackingFields(): string {
+    $sql = '';
+    $fields = $this->getParser()->getTrackingFields();
+    foreach ($fields as $fieldName => $spec) {
+      $sql .= 'ADD COLUMN  _' . $fieldName . ' ' . $spec . ',';
+    }
+    return $sql;
+  }
+
+  /**
+   * Get the import parser.
+   *
+   * @return CRM_Import_Parser
+   *
+   * @throws \API_Exception
+   */
+  private function getParser() {
+    $parserClass = '';
+    foreach (CRM_Core_BAO_UserJob::getTypes() as $type) {
+      if ($this->getUserJob()['type_id'] === $type['id']) {
+        $parserClass = $type['class'];
+      }
+    }
+    /* @var \CRM_Import_Parser */
+    $parser = new $parserClass();
+    $parser->setUserJobID($this->getUserJobID());
+    return $parser;
+  }
+
   /**
    * Has the import job completed.
    *
@@ -471,22 +533,24 @@ abstract class CRM_Import_DataSource {
    * @param string $message
    * @param int|null $entityID
    *   Optional created entity ID
-   * @param array $relatedEntityIDs
+   * @param array $additionalFields
    *   Optional array e.g ['related_contact' => 4]
    *
    * @throws \API_Exception
    * @throws \CRM_Core_Exception
    */
-  public function updateStatus(int $id, string $status, string $message, ? int $entityID = NULL, array $relatedEntityIDs = []): void {
+  public function updateStatus(int $id, string $status, string $message, ? int $entityID = NULL, array $additionalFields = []): void {
     $sql = 'UPDATE ' . $this->getTableName() . ' SET _status = %1, _status_message = %2 ';
     $params = [1 => [$status, 'String'], 2 => [$message, 'String']];
     if ($entityID) {
       $sql .= ', _entity_id = %3';
       $params[3] = [$entityID, 'Integer'];
     }
-    if ($relatedEntityIDs) {
-      $sql .= ', _related_entities = %4';
-      $params[4] = [json_encode($relatedEntityIDs), 'String'];
+    $nextParam = 4;
+    foreach ($additionalFields as $fieldName => $value) {
+      $sql .= ', _' . $fieldName . ' = %' . $nextParam;
+      $params[$nextParam] = is_numeric($value) ? [$value, 'Int'] : [json_encode($value), 'String'];
+      $nextParam++;
     }
     CRM_Core_DAO::executeQuery($sql . ' WHERE _id = ' . $id, $params);
   }
@@ -497,13 +561,20 @@ abstract class CRM_Import_DataSource {
    * @throws \CRM_Core_Exception
    */
   private function instantiateQueryObject(): void {
-    $query = 'SELECT * FROM ' . $this->getTableName() . ' ' . $this->getStatusClause();
+    $query = 'SELECT ' . $this->getSelectClause() . ' FROM ' . $this->getTableName() . ' ' . $this->getStatusClause();
     if ($this->limit) {
       $query .= ' LIMIT ' . $this->limit . ($this->offset ? (' OFFSET ' . $this->offset) : NULL);
     }
     $this->queryResultObject = CRM_Core_DAO::executeQuery($query);
   }
 
+  /**
+   * @return string
+   */
+  private function getSelectClause(): string {
+    return $this->getSelectFields() ? implode(', ', $this->getSelectFields()) : '*';
+  }
+
   /**
    * Get the mapping of constants to database status codes.
    *
@@ -511,11 +582,15 @@ abstract class CRM_Import_DataSource {
    */
   protected function getStatusMapping(): array {
     return [
-      CRM_Import_Parser::VALID => ['imported', 'new'],
-      CRM_Import_Parser::ERROR => ['error', 'invalid'],
+      CRM_Import_Parser::VALID => ['imported', 'new', 'soft_credit_imported', 'pledge_payment_imported'],
+      CRM_Import_Parser::ERROR => ['error', 'invalid', 'soft_credit_error', 'pledge_payment_error'],
       CRM_Import_Parser::DUPLICATE => ['duplicate'],
       CRM_Import_Parser::NO_MATCH => ['invalid_no_match'],
       CRM_Import_Parser::UNPARSED_ADDRESS_WARNING => ['warning_unparsed_address'],
+      CRM_Contribute_Import_Parser_Contribution::SOFT_CREDIT_ERROR => ['soft_credit_error'],
+      CRM_Contribute_Import_Parser_Contribution::SOFT_CREDIT => ['soft_credit_imported'],
+      CRM_Contribute_Import_Parser_Contribution::PLEDGE_PAYMENT => ['pledge_payment_imported'],
+      CRM_Contribute_Import_Parser_Contribution::PLEDGE_PAYMENT_ERROR => ['pledge_payment_error'],
       'new' => ['new'],
     ];
   }