3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
15 * @copyright CiviCRM LLC https://civicrm.org/licensing
17 class CRM_Import_DataSource_SQL
extends CRM_Import_DataSource
{
20 * Form fields declared for this datasource.
24 protected $submittableFields = ['sqlQuery'];
27 * Provides information about the data source.
30 * collection of info about this data source
32 public function getInfo(): array {
34 'title' => ts('SQL Query'),
35 'permissions' => ['import SQL datasource'],
40 * This is function is called by the form object to get the DataSource's
41 * form snippet. It should add all fields necesarry to get the data
42 * uploaded to the temporary table in the DB.
44 * @param CRM_Core_Form $form
47 * (operates directly on form argument)
49 public function buildQuickForm(&$form) {
50 $form->add('hidden', 'hidden_dataSource', 'CRM_Import_DataSource_SQL');
51 $form->add('textarea', 'sqlQuery', ts('Specify SQL Query'), ['rows' => 10, 'cols' => 45], TRUE);
52 $form->addFormRule(['CRM_Import_DataSource_SQL', 'formRule'], $form);
58 * @param CRM_Core_Form $form
62 public static function formRule($fields, $files, $form) {
65 // Makeshift query validation (case-insensitive regex matching on word boundaries)
66 $forbidden = ['ALTER', 'CREATE', 'DELETE', 'DESCRIBE', 'DROP', 'SHOW', 'UPDATE', 'REPLACE', 'information_schema'];
67 foreach ($forbidden as $pattern) {
68 if (preg_match("/\\b$pattern\\b/i", $fields['sqlQuery'])) {
69 $errors['sqlQuery'] = ts('The query contains the forbidden %1 command.', [1 => $pattern]);
73 return $errors ?
: TRUE;
77 * Initialize the datasource, based on the submitted values stored in the user job.
79 * @throws \API_Exception
80 * @throws \CRM_Core_Exception
82 public function initialize(): void
{
83 $table = CRM_Utils_SQL_TempTable
::build()->setDurable();
84 $tableName = $table->getName();
85 $table->createWithQuery($this->getSubmittedValue('sqlQuery'));
87 // Get the names of the fields to be imported. Any fields starting with an
88 // underscore are considered to be internal to the import process)
89 $columnsResult = CRM_Core_DAO
::executeQuery(
90 'SHOW FIELDS FROM ' . $tableName . "
91 WHERE Field NOT LIKE '\_%'");
94 while ($columnsResult->fetch()) {
95 $columnNames[] = $columnsResult->Field
;
98 $this->addTrackingFieldsToTable($tableName);
99 $this->updateUserJobMetadata('DataSource', [
100 'table_name' => $tableName,
101 'column_headers' => $columnNames,
102 'number_of_columns' => count($columnNames),