Merge pull request #23723 from mattwire/ufmatchsearchkit
[civicrm-core.git] / CRM / Import / DataSource / SQL.php
index c1cbb61e1e4db6033223584f7b7c45fa064552af..78b20839f9be3f4bb87f7a2799c143d1076af521 100644 (file)
  */
 class CRM_Import_DataSource_SQL extends CRM_Import_DataSource {
 
+  /**
+   * Form fields declared for this datasource.
+   *
+   * @var string[]
+   */
+  protected $submittableFields = ['sqlQuery'];
+
   /**
    * Provides information about the data source.
    *
    * @return array
    *   collection of info about this data source
    */
-  public function getInfo() {
+  public function getInfo(): array {
     return [
       'title' => ts('SQL Query'),
       'permissions' => ['import SQL datasource'],
     ];
   }
 
-  /**
-   * Set variables up before form is built.
-   *
-   * @param CRM_Core_Form $form
-   */
-  public function preProcess(&$form) {
-  }
-
   /**
    * This is function is called by the form object to get the DataSource's
    * form snippet. It should add all fields necesarry to get the data
@@ -64,32 +63,54 @@ class CRM_Import_DataSource_SQL extends CRM_Import_DataSource {
     $errors = [];
 
     // Makeshift query validation (case-insensitive regex matching on word boundaries)
-    $forbidden = ['ALTER', 'CREATE', 'DELETE', 'DESCRIBE', 'DROP', 'SHOW', 'UPDATE', 'information_schema'];
+    $forbidden = ['ALTER', 'CREATE', 'DELETE', 'DESCRIBE', 'DROP', 'SHOW', 'UPDATE', 'REPLACE', 'information_schema'];
     foreach ($forbidden as $pattern) {
       if (preg_match("/\\b$pattern\\b/i", $fields['sqlQuery'])) {
         $errors['sqlQuery'] = ts('The query contains the forbidden %1 command.', [1 => $pattern]);
       }
     }
 
-    return $errors ? $errors : TRUE;
+    return $errors ?: TRUE;
   }
 
   /**
-   * Process the form submission.
-   *
-   * @param array $params
-   * @param string $db
-   * @param \CRM_Core_Form $form
+   * Initialize the datasource, based on the submitted values stored in the user job.
    *
+   * @throws \API_Exception
    * @throws \CRM_Core_Exception
    */
-  public function postProcess(&$params, &$db, &$form) {
-    $importJob = new CRM_Contact_Import_ImportJob(
-      CRM_Utils_Array::value('import_table_name', $params),
-      $params['sqlQuery'], TRUE
-    );
+  public function initialize(): void {
+    $table = CRM_Utils_SQL_TempTable::build()->setDurable();
+    $tableName = $table->getName();
+    $table->createWithQuery($this->getSubmittedValue('sqlQuery'));
+
+    // Get the names of the fields to be imported. Any fields starting with an
+    // underscore are considered to be internal to the import process)
+    $columnsResult = CRM_Core_DAO::executeQuery(
+      'SHOW FIELDS FROM ' . $tableName . "
+      WHERE Field NOT LIKE '\_%'");
+
+    $columnNames = [];
+    while ($columnsResult->fetch()) {
+      if (strpos($columnsResult->Field, ' ') !== FALSE) {
+        // Remove spaces as the Database object does this
+        // $keys = str_replace(array(".", " "), "_", array_keys($array));
+        // https://lab.civicrm.org/dev/core/-/issues/1337
+        $usableColumnName = str_replace(' ', '_', $columnsResult->Field);
+        CRM_Core_DAO::executeQuery('ALTER TABLE ' . $tableName . ' CHANGE `' . $columnsResult->Field . '` ' . $usableColumnName . ' ' . $columnsResult->Type);
+        $columnNames[] = $usableColumnName;
+      }
+      else {
+        $columnNames[] = $columnsResult->Field;
+      }
+    }
 
-    $form->set('importTableName', $importJob->getTableName());
+    $this->addTrackingFieldsToTable($tableName);
+    $this->updateUserJobMetadata('DataSource', [
+      'table_name' => $tableName,
+      'column_headers' => $columnNames,
+      'number_of_columns' => count($columnNames),
+    ]);
   }
 
 }