From 93c5d842a87788e854d88a0fef4bfca5b1e0dd0d Mon Sep 17 00:00:00 2001 From: Eileen McNaughton Date: Sat, 11 Mar 2023 16:06:23 +1300 Subject: [PATCH] Import data source Re-use already uploaded data, optionally on 'back' Without this patch a user who uses the 'back' button must re-upload the csv / sql they just uploaded.... --- CRM/Import/DataSource/CSV.php | 2 +- CRM/Import/Form/DataSource.php | 49 ++++++++++++++----- CRM/Import/Forms.php | 20 +++++--- .../Event/Subscriber/ImportSubscriber.php | 4 +- templates/CRM/Import/Form/DataSource.tpl | 16 ++++++ 5 files changed, 71 insertions(+), 20 deletions(-) diff --git a/CRM/Import/DataSource/CSV.php b/CRM/Import/DataSource/CSV.php index b1f5edf7f5..a71aef20de 100644 --- a/CRM/Import/DataSource/CSV.php +++ b/CRM/Import/DataSource/CSV.php @@ -23,7 +23,7 @@ class CRM_Import_DataSource_CSV extends CRM_Import_DataSource { * * @var string[] */ - protected $submittableFields = ['skipColumnHeader', 'uploadField', 'fieldSeparator']; + protected $submittableFields = ['skipColumnHeader', 'uploadFile', 'fieldSeparator']; /** * Provides information about the data source. diff --git a/CRM/Import/Form/DataSource.php b/CRM/Import/Form/DataSource.php index bf43361ccc..87f9b933ce 100644 --- a/CRM/Import/Form/DataSource.php +++ b/CRM/Import/Form/DataSource.php @@ -64,6 +64,13 @@ abstract class CRM_Import_Form_DataSource extends CRM_Import_Forms { $this->assign('urlPath', 'civicrm/import/datasource'); $this->assign('urlPathVar', 'snippet=4&user_job_id=' . $this->get('user_job_id')); + if ($this->isImportDataUploaded()) { + $this->add('checkbox', 'use_existing_upload', ts('Use data already uploaded'), NULL, FALSE, [ + 'onChange' => " + CRM.$('.crm-import-datasource-form-block-dataSource').toggle(); + CRM.$('#data-source-form-block').toggle()", + ]); + } $this->add('select', 'dataSource', ts('Data Source'), $this->getDataSources(), TRUE, ['onchange' => 'buildDataSourceFormBlock(this.value);'] @@ -78,9 +85,16 @@ abstract class CRM_Import_Form_DataSource extends CRM_Import_Forms { //build date formats CRM_Core_Form_Date::buildAllowedDateFormats($this); - - $this->buildDataSourceFields(); - + // When we call buildDataSourceFields we add them to the form both for purposes of + // initial display, but also so they are available during `postProcess`. Hence + // we need to add them to the form when first displaying it, or when a csv has been + // uploaded or csv described but NOT when the existing file is used. We have + // to check `_POST` for this because we want them to be not-added BEFORE validation + // as `buildDataSourceFields` also adds rules, which will run before `use_existing_upload` + // is treated as submitted. + if (empty($_POST['use_existing_upload'])) { + $this->buildDataSourceFields(); + } $this->addButtons([ [ 'type' => 'upload', @@ -169,15 +183,28 @@ abstract class CRM_Import_Form_DataSource extends CRM_Import_Forms { * @throws \CRM_Core_Exception */ protected function processDatasource(): void { - if (!$this->getUserJobID()) { - $this->createUserJob(); - } - else { - $this->flushDataSource(); - $this->updateUserJobMetadata('submitted_values', $this->getSubmittedValues()); - } try { - $this->instantiateDataSource(); + if (!$this->getUserJobID()) { + $this->createUserJob(); + $this->instantiateDataSource(); + } + else { + $submittedValues = $this->getSubmittedValues(); + $fieldsToCopyOver = array_keys(array_diff_key($submittedValues, $this->submittableFields)); + if ($submittedValues['use_existing_upload']) { + // Use the already saved value. + $fieldsToCopyOver[] = 'dataSource'; + foreach ($fieldsToCopyOver as $field) { + $submittedValues[$field] = $this->getUserJobSubmittedValues()[$field]; + } + $this->updateUserJobMetadata('submitted_values', $submittedValues); + } + else { + $this->flushDataSource(); + $this->updateUserJobMetadata('submitted_values', $submittedValues); + $this->instantiateDataSource(); + } + } } catch (CRM_Core_Exception $e) { CRM_Core_Error::statusBounce($e->getUserMessage()); diff --git a/CRM/Import/Forms.php b/CRM/Import/Forms.php index 4c024ba234..7b7ccac34c 100644 --- a/CRM/Import/Forms.php +++ b/CRM/Import/Forms.php @@ -113,17 +113,12 @@ class CRM_Import_Forms extends CRM_Core_Form { * @var string[] */ protected $submittableFields = [ - // Skip column header is actually a field that would be added from the - // datasource - but currently only in contact, it is always there for - // other imports, ditto uploadFile. - 'skipColumnHeader' => 'DataSource', - 'fieldSeparator' => 'DataSource', - 'uploadFile' => 'DataSource', 'contactType' => 'DataSource', 'contactSubType' => 'DataSource', 'dateFormats' => 'DataSource', 'savedMapping' => 'DataSource', 'dataSource' => 'DataSource', + 'use_existing_upload' => 'DataSource', 'dedupe_rule_id' => 'DataSource', 'onDuplicate' => 'DataSource', 'disableUSPS' => 'DataSource', @@ -285,6 +280,19 @@ class CRM_Import_Forms extends CRM_Core_Form { $oldDataSourceObject = new $oldDataSource($this->getUserJobID()); $newParams = $this->getSubmittedValue('dataSource') === $oldDataSource ? $this->getSubmittedValues() : []; $oldDataSourceObject->purge($newParams); + $this->updateUserJobMetadata('DataSource', []); + } + + /** + * Is the data already uploaded. + * + * This would be true on the DataSource screen when using the back button + * and ideally we can re-use that data rather than make them upload anew. + * + * @throws \CRM_Core_Exception + */ + protected function isImportDataUploaded(): bool { + return $this->getUserJobID() && !empty($this->getUserJob()['metadata']['DataSource']['table_name']); } /** diff --git a/ext/civiimport/Civi/Api4/Event/Subscriber/ImportSubscriber.php b/ext/civiimport/Civi/Api4/Event/Subscriber/ImportSubscriber.php index 2ad00eeba2..9ae91301b3 100644 --- a/ext/civiimport/Civi/Api4/Event/Subscriber/ImportSubscriber.php +++ b/ext/civiimport/Civi/Api4/Event/Subscriber/ImportSubscriber.php @@ -126,9 +126,9 @@ class ImportSubscriber extends AutoService implements EventSubscriberInterface { if (!is_array($metadata)) { return NULL; } - return $metadata['DataSource']['table_name'] ?: NULL; + return $metadata['DataSource']['table_name'] ?? NULL; } - return $event->params['metadata']['DataSource']['table_name'] ?: NULL; + return $event->params['metadata']['DataSource']['table_name'] ?? NULL; } /** diff --git a/templates/CRM/Import/Form/DataSource.tpl b/templates/CRM/Import/Form/DataSource.tpl index 9a2b4686ca..d62f2e7f99 100644 --- a/templates/CRM/Import/Form/DataSource.tpl +++ b/templates/CRM/Import/Form/DataSource.tpl @@ -27,6 +27,16 @@

{ts}Choose Data Source{/ts}

+ {if array_key_exists('use_existing_upload', $form)} + + + + {* If the there is already an uploaded file then check the box when the form loads. This will + cause it be checked regardless of whether they checked it last time (we assume they want + to re-use) and also triggers the hide script for the dataSource field *} + {literal}{/literal} + + {/if} @@ -191,5 +201,11 @@ } {/literal} + {if array_key_exists('use_existing_upload', $form)} + {* If the there is already an uploaded file then check the box when the form loads. This will + cause it be checked regardless of whether they checked it last time (we assume they want + to re-use) and also triggers the hide script for the dataSource field *} + {literal}{/literal} + {/if} -- 2.25.1
{$form.use_existing_upload.label}{$form.use_existing_upload.html}
{$form.dataSource.label} {$form.dataSource.html} {help id='data-source-selection'}