Skip to content

Commit

Permalink
CiviImport - Switch import_mappings to ImportTemplateField table
Browse files Browse the repository at this point in the history
  • Loading branch information
colemanw committed Jan 2, 2025
1 parent da397d7 commit eb99637
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 129 deletions.
2 changes: 1 addition & 1 deletion CRM/Contribute/Import/Parser/Contribution.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public static function getUserJobInfo(): array {
* @throws \CRM_Core_Exception
*/
protected function getFieldMappings(): array {
$mappedFields = $this->getUserJob()['metadata']['import_mappings'] ?? [];
$mappedFields = $this->getUserJob()['template_fields'] ?? [];
if (empty($mappedFields)) {
foreach ($this->getSubmittedValue('mapper') as $i => $mapperRow) {
$mappedField = $this->getMappingFieldFromMapperInput($mapperRow, 0, $i);
Expand Down
4 changes: 2 additions & 2 deletions CRM/Import/Form/MapField.php
Original file line number Diff line number Diff line change
Expand Up @@ -234,12 +234,12 @@ protected function getMappedField(array $fieldMapping, int $mappingID, int $colu
* @throws \CRM_Core_Exception
*/
protected function saveMappingField(int $mappingID, int $columnNumber, bool $isUpdate = FALSE): void {
if (!empty($this->userJob['metadata']['import_mappings'])) {
if (!empty($this->userJob['template_fields'])) {
// In this case Civi-Import has already saved the mapping to civicrm_user_job.metadata
// and the code here is just keeping civicrm_mapping_field in sync.
// Eventually we hope to phase out the use of the civicrm_mapping data &
// just use UserJob and Import Templates (UserJob records with 'is_template' = 1
$mappedFieldData = $this->userJob['metadata']['import_mappings'][$columnNumber];
$mappedFieldData = $this->userJob['template_fields'][$columnNumber];
$mappedField = array_intersect_key($mappedFieldData, array_fill_keys(['name', 'column_number', 'entity_data'], TRUE));
$mappedField['mapping_id'] = $mappingID;
}
Expand Down
67 changes: 4 additions & 63 deletions CRM/Import/Forms.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,13 @@
* This class helps the forms within the import flow access submitted & parsed values.
*/
class CRM_Import_Forms extends CRM_Core_Form {

use \Civi\UserJob\UserJobTrait;

/**
* @var int
*/
protected $templateID;

/**
* User job id.
*
* This is the primary key of the civicrm_user_job table which is used to
* track the import.
*
* @var int
*/
protected $userJobID;

/**
* Name of the import mapping (civicrm_mapping).
*
Expand Down Expand Up @@ -86,36 +76,6 @@ public function getEntity() {
return $this->controller->getEntity();
}

/**
* @return int|null
*/
public function getUserJobID(): ?int {
if (!$this->userJobID && $this->get('user_job_id')) {
$this->userJobID = $this->get('user_job_id');
}
return $this->userJobID;
}

/**
* Set user job ID.
*
* @param int $userJobID
*/
public function setUserJobID(int $userJobID): void {
$this->userJobID = $userJobID;
// This set allows other forms in the flow ot use $this->get('user_job_id').
$this->set('user_job_id', $userJobID);
}

/**
* User job details.
*
* This is the relevant row from civicrm_user_job.
*
* @var array
*/
protected $userJob;

/**
* @var \CRM_Import_Parser
*/
Expand All @@ -131,25 +91,6 @@ public function setUserJobID(int $userJobID): void {
*/
protected $isQuickFormMode = TRUE;

/**
* Get User Job.
*
* API call to retrieve the userJob row.
*
* @return array
*
* @throws \CRM_Core_Exception
*/
protected function getUserJob(): array {
if (!$this->userJob) {
$this->userJob = UserJob::get()
->addWhere('id', '=', $this->getUserJobID())
->execute()
->first();
}
return $this->userJob;
}

/**
* Get submitted values stored in the user job.
*
Expand Down Expand Up @@ -566,7 +507,7 @@ protected function isUpdateTemplateJob(): bool {
*/
protected function getColumnHeaders(): array {
$headers = $this->getDataSourceObject()->getColumnHeaders();
$mappedFields = $this->getUserJob()['metadata']['import_mappings'] ?? [];
$mappedFields = $this->getUserJob()['template_fields'] ?? [];
if (!empty($mappedFields) && count($mappedFields) > count($headers)) {
// The user has mapped one or more non-database fields, add those in.
$userMappedFields = array_diff_key($mappedFields, $headers);
Expand Down Expand Up @@ -608,7 +549,7 @@ protected function getDataRows($statuses = [], int $limit = 0): array {
$statuses = (array) $statuses;
$rows = $this->getDataSourceObject()->setLimit($limit)->setStatuses($statuses)->getRows();
$headers = $this->getColumnHeaders();
$mappings = $this->getUserJob()['metadata']['import_mappings'] ?? [];
$mappings = $this->getUserJob()['template_fields'] ?? [];
foreach ($rows as &$row) {
foreach ($headers as $index => $header) {
if (!$header) {
Expand Down Expand Up @@ -843,7 +784,7 @@ protected function getParser() {
protected function getMappedFieldLabels(): array {
$mapper = [];
$parser = $this->getParser();
$importMappings = $this->getUserJob()['metadata']['import_mappings'] ?? [];
$importMappings = $this->getUserJob()['template_fields'] ?? [];
if (empty($importMappings)) {
foreach ($this->getSubmittedValue('mapper') as $columnNumber => $mapping) {
$importMappings[] = $parser->getMappingFieldFromMapperInput((array) $mapping, 0, $columnNumber);
Expand Down
55 changes: 1 addition & 54 deletions CRM/Import/Parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
* supported.
*/
abstract class CRM_Import_Parser implements UserJobInterface {
use \Civi\UserJob\UserJobTrait;

/**
* Return codes
Expand All @@ -41,23 +42,6 @@ abstract class CRM_Import_Parser implements UserJobInterface {
*/
const DUPLICATE_SKIP = 1, DUPLICATE_UPDATE = 4, DUPLICATE_FILL = 8, DUPLICATE_NOCHECK = 16;

/**
* User job id.
*
* This is the primary key of the civicrm_user_job table which is used to
* track the import.
*
* @var int
*/
protected $userJobID;

/**
* The user job in use.
*
* @var array
*/
protected $userJob;

/**
* Potentially ambiguous options.
*
Expand All @@ -79,31 +63,13 @@ abstract class CRM_Import_Parser implements UserJobInterface {
*/
protected $siteDefaultCountry = NULL;

/**
* @return int|null
*/
public function getUserJobID(): ?int {
return $this->userJobID;
}

/**
* Ids of contacts created this iteration.
*
* @var array
*/
protected $createdContacts = [];

/**
* Set user job ID.
*
* @param int $userJobID
*
* @return self
*/
public function setUserJobID(int $userJobID): self {
$this->userJobID = $userJobID;
return $this;
}

/**
* Countries that the site is restricted to
Expand All @@ -120,25 +86,6 @@ public function getTrackingFields(): array {
return [];
}

/**
* Get User Job.
*
* API call to retrieve the userJob row.
*
* @return array
*
* @throws \CRM_Core_Exception
*/
protected function getUserJob(): array {
if (empty($this->userJob)) {
$this->userJob = UserJob::get()
->addWhere('id', '=', $this->getUserJobID())
->execute()
->first();
}
return $this->userJob;
}

/**
* Get the relevant datasource object.
*
Expand Down
85 changes: 85 additions & 0 deletions Civi/UserJob/UserJobTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php
/*
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC. All rights reserved. |
| |
| This work is published under the GNU AGPLv3 license with some |
| permitted exceptions and without any warranty. For full license |
| and copyright information, see https://civicrm.org/licensing |
+--------------------------------------------------------------------+
*/

namespace Civi\UserJob;

use Civi\Api4\ImportTemplateField;
use Civi\Api4\UserJob;

trait UserJobTrait {

/**
* User job id.
*
* This is the primary key of the civicrm_user_job table which is used to
* track the import.
*
* @var int
*/
protected $userJobID;

/**
* The user job in use.
*
* @var array
*/
protected $userJob;

/**
* @return int|null
*/
public function getUserJobID(): ?int {
if (!$this->userJobID && is_a($this, 'CRM_Core_Form') && $this->get('user_job_id')) {
$this->userJobID = $this->get('user_job_id');
}
return $this->userJobID;
}

/**
* Set user job ID.
*
* @param int $userJobID
*
* @return self
*/
public function setUserJobID(int $userJobID): self {
$this->userJobID = $userJobID;
// This allows other forms in the flow ot use $this->get('user_job_id').
if (is_a($this, 'CRM_Core_Form')) {
$this->set('user_job_id', $userJobID);
}
return $this;
}

/**
* Get User Job.
*
* API call to retrieve the userJob row.
*
* @return array
*
* @throws \CRM_Core_Exception
*/
protected function getUserJob(): array {
if (empty($this->userJob)) {
$this->userJob = UserJob::get()
->addWhere('id', '=', $this->getUserJobID())
->addChain('template_fields', ImportTemplateField::get()
->addWhere('user_job_id', '=', $this->getUserJobID())
->addOrderBy('column_number')
)
->execute()
->single();
}
return $this->userJob;
}

}
22 changes: 13 additions & 9 deletions ext/civiimport/ang/crmCiviimport.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@
// Declare a list of dependencies.
angular.module('crmCiviimport', CRM.angRequires('crmCiviimport'));

// The controller uses *injection*. This default injects a few things:
// $scope -- This is the set of variables shared between JS and HTML.
// crmApi, crmStatus, crmUiHelp -- These are services provided by civicrm-core.
// myContact -- The current contact, defined above in config().
angular.module('crmCiviimport').component('crmImportUi', {
templateUrl: '~/crmCiviimport/Import.html',
controller: function($scope, crmApi4, crmStatus, crmUiHelp) {
Expand Down Expand Up @@ -72,7 +68,7 @@

function buildImportMappings() {
$scope.data.importMappings = [];
var importMappings = $scope.userJob.metadata.import_mappings;
var importMappings = $scope.userJob.template_fields;
_.each($scope.data.columnHeaders, function (header, index) {
var fieldName = $scope.data.defaults['mapper[' + index + ']'][0];
if (Boolean(fieldName)) {
Expand Down Expand Up @@ -280,7 +276,7 @@
$scope.save = (function ($event) {
$event.preventDefault();
$scope.userJob.metadata.entity_configuration = {};
$scope.userJob.metadata.import_mappings = [];
$scope.userJob.template_fields = [];
_.each($scope.entitySelection, function (entity) {
$scope.userJob.metadata.entity_configuration[entity.id] = entity.selected;
});
Expand All @@ -294,15 +290,23 @@
entityConfig = {'soft_credit': $scope.userJob.metadata.entity_configuration[selectedEntity]};
}

$scope.userJob.metadata.import_mappings.push({
$scope.userJob.template_fields.push({
name: importRow.selectedField,
default_value: importRow.defaultValue,
// At this stage column_number is thrown away but we store it here to have it for when we change that.
column_number: index,
column_number: index + 1,
entity_data: entityConfig
});
});
crmApi4('UserJob', 'save', {records: [$scope.userJob]})
crmApi4('UserJob', 'save', {
records: [$scope.userJob],
chain: {
template_fields: ['ImportTemplateField', 'replace', {
where: [['user_job_id', '=', '$id']],
records: $scope.userJob.template_fields,
}],
},
})
.then(function(result) {
// Only post the form if the save succeeds.
document.getElementById("MapField").submit();
Expand Down

0 comments on commit eb99637

Please sign in to comment.