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
19 * This class gets the name of the file to upload.
21 class CRM_Contact_Import_Form_MapField
extends CRM_Import_Form_MapField
{
23 use CRM_Contact_Import_MetadataTrait
;
26 * An array of all contact fields with
27 * formatted custom field names.
31 protected $_formattedFieldNames;
40 protected $_dedupeFields;
42 protected static $customFields;
45 * Attempt to match header labels with our mapper fields.
47 * FIXME: This is essentially the same function as parent::defaultFromHeader
49 * @param string $columnName name of column header
53 public function defaultFromColumnName($columnName) {
55 if (!preg_match('/^[a-z0-9 ]$/i', $columnName)) {
56 if ($columnKey = array_search($columnName, $this->getFieldTitles())) {
57 $this->_fieldUsed
[$columnKey] = TRUE;
62 foreach ($this->getHeaderPatterns() as $key => $re) {
63 // Skip empty key/patterns
64 if (!$key ||
!$re ||
strlen("$re") < 5) {
68 if (preg_match($re, $columnName)) {
69 $this->_fieldUsed
[$key] = TRUE;
77 * Set variables up before form is built.
79 * @throws \API_Exception
80 * @throws \CRM_Core_Exception
81 * @throws \Civi\API\Exception\UnauthorizedException
83 public function preProcess() {
84 $this->_mapperFields
= $this->get('fields');
85 $this->_importTableName
= $this->get('importTableName');
86 $this->_onDuplicate
= $this->get('onDuplicate');
87 $this->_contactSubType
= $this->get('contactSubType');
88 $highlightedFields = [];
89 $highlightedFields[] = 'email';
90 $highlightedFields[] = 'external_identifier';
91 //format custom field names, CRM-2676
92 $contactType = $this->getContactType();
93 switch ($this->get('contactType')) {
94 case CRM_Import_Parser
::CONTACT_INDIVIDUAL
:
95 $highlightedFields[] = 'first_name';
96 $highlightedFields[] = 'last_name';
99 case CRM_Import_Parser
::CONTACT_HOUSEHOLD
:
100 $highlightedFields[] = 'household_name';
103 case CRM_Import_Parser
::CONTACT_ORGANIZATION
:
104 $highlightedFields[] = 'organization_name';
107 $this->_contactType
= $contactType;
108 if ($this->_onDuplicate
== CRM_Import_Parser
::DUPLICATE_SKIP
) {
109 unset($this->_mapperFields
['id']);
112 $highlightedFields[] = 'id';
115 if ($this->_onDuplicate
!= CRM_Import_Parser
::DUPLICATE_NOCHECK
) {
116 //Mark Dedupe Rule Fields as required, since it's used in matching contact
117 foreach (CRM_Contact_BAO_ContactType
::basicTypes() as $cType) {
119 'contact_type' => $cType,
120 'used' => 'Unsupervised',
122 $this->_dedupeFields
[$cType] = CRM_Dedupe_BAO_DedupeRule
::dedupeRuleFields($ruleParams);
125 //Modify mapper fields title if fields are present in dedupe rule
126 if (is_array($this->_dedupeFields
[$contactType])) {
127 foreach ($this->_dedupeFields
[$contactType] as $val) {
128 if ($valTitle = CRM_Utils_Array
::value($val, $this->_mapperFields
)) {
129 $this->_mapperFields
[$val] = $valTitle . ' (match to contact)';
134 // retrieve and highlight required custom fields
135 $formattedFieldNames = $this->formatCustomFieldName($this->_mapperFields
);
136 self
::$customFields = CRM_Core_BAO_CustomField
::getFields($this->_contactType
);
137 foreach (self
::$customFields as $key => $attr) {
138 if (!empty($attr['is_required'])) {
139 $highlightedFields[] = "custom_$key";
142 $this->assign('highlightedFields', $highlightedFields);
143 $this->_formattedFieldNames
[$contactType] = $this->_mapperFields
= array_merge($this->_mapperFields
, $formattedFieldNames);
145 $columnNames = $this->getColumnHeaders();
146 $this->assign('showColNames', !empty($columnNames));
148 $this->_columnCount
= $this->getNumberOfColumns();
149 $this->_columnNames
= $columnNames;
150 $this->assign('columnNames', $this->getColumnHeaders());
151 //$this->_columnCount = $this->get( 'columnCount' );
152 $this->assign('columnCount', $this->_columnCount
);
153 $this->_dataValues
= array_values($this->getDataRows(2));
154 $this->assign('dataValues', $this->_dataValues
);
158 * Build the form object.
160 * @throws \CiviCRM_API3_Exception
162 public function buildQuickForm() {
163 $savedMappingID = (int) $this->get('savedMapping');
164 $this->buildSavedMappingFields($savedMappingID);
166 $this->addFormRule(['CRM_Contact_Import_Form_MapField', 'formRule']);
168 //-------- end of saved mapping stuff ---------
171 $mapperKeys = array_keys($this->_mapperFields
);
172 $hasColumnNames = !empty($this->_columnNames
);
173 $hasLocationTypes = $this->get('fieldTypes');
175 $this->_location_types
= ['Primary' => ts('Primary')] + CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Address', 'location_type_id');
176 $defaultLocationType = CRM_Core_BAO_LocationType
::getDefault();
178 // Pass default location to js
179 if ($defaultLocationType) {
180 $this->assign('defaultLocationType', $defaultLocationType->id
);
181 $this->assign('defaultLocationTypeLabel', $this->_location_types
[$defaultLocationType->id
]);
184 /* Initialize all field usages to false */
185 foreach ($mapperKeys as $key) {
186 $this->_fieldUsed
[$key] = FALSE;
189 $sel1 = $this->_mapperFields
;
192 $phoneTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Phone', 'phone_type_id');
193 $imProviders = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id');
194 $websiteTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Website', 'website_type_id');
196 foreach ($this->_location_types
as $key => $value) {
197 $sel3['phone'][$key] = &$phoneTypes;
198 $sel3['phone_ext'][$key] = &$phoneTypes;
199 //build array for IM service provider type for contact
200 $sel3['im'][$key] = &$imProviders;
205 // store and cache all relationship types
206 $contactRelation = new CRM_Contact_DAO_RelationshipType();
207 $contactRelation->find();
208 while ($contactRelation->fetch()) {
209 $contactRelationCache[$contactRelation->id
] = [];
210 $contactRelationCache[$contactRelation->id
]['contact_type_a'] = $contactRelation->contact_type_a
;
211 $contactRelationCache[$contactRelation->id
]['contact_sub_type_a'] = $contactRelation->contact_sub_type_a
;
212 $contactRelationCache[$contactRelation->id
]['contact_type_b'] = $contactRelation->contact_type_b
;
213 $contactRelationCache[$contactRelation->id
]['contact_sub_type_b'] = $contactRelation->contact_sub_type_b
;
215 $highlightedFields = $highlightedRelFields = [];
217 $highlightedFields['email'] = 'All';
218 $highlightedFields['external_identifier'] = 'All';
219 $highlightedFields['first_name'] = 'Individual';
220 $highlightedFields['last_name'] = 'Individual';
221 $highlightedFields['household_name'] = 'Household';
222 $highlightedFields['organization_name'] = 'Organization';
224 foreach ($mapperKeys as $key) {
225 // check if there is a _a_b or _b_a in the key
226 if (strpos($key, '_a_b') ||
strpos($key, '_b_a')) {
227 [$id, $first, $second] = explode('_', $key);
230 $id = $first = $second = NULL;
232 if (($first === 'a' && $second === 'b') ||
($first === 'b' && $second === 'a')) {
233 $cType = $contactRelationCache[$id]["contact_type_{$second}"];
235 //CRM-5125 for contact subtype specific relationshiptypes
237 if (!empty($contactRelationCache[$id]["contact_sub_type_{$second}"])) {
238 $cSubType = $contactRelationCache[$id]["contact_sub_type_{$second}"];
245 $relatedFields = CRM_Contact_BAO_Contact
::importableFields($cType);
246 unset($relatedFields['']);
248 foreach ($relatedFields as $name => $field) {
249 $values[$name] = $field['title'];
250 if (isset($hasLocationTypes[$name])) {
251 $sel3[$key][$name] = $this->_location_types
;
253 elseif ($name === 'url') {
254 $sel3[$key][$name] = $websiteTypes;
261 //fix to append custom group name to field name, CRM-2676
262 if (empty($this->_formattedFieldNames
[$cType]) ||
$cType == $this->_contactType
) {
263 $this->_formattedFieldNames
[$cType] = $this->formatCustomFieldName($values);
266 $this->_formattedFieldNames
[$cType] = array_merge($values, $this->_formattedFieldNames
[$cType]);
268 //Modified the Relationship fields if the fields are
269 //present in dedupe rule
270 if ($this->_onDuplicate
!= CRM_Import_Parser
::DUPLICATE_NOCHECK
&& !empty($this->_dedupeFields
[$cType]) &&
271 is_array($this->_dedupeFields
[$cType])
273 static $cTypeArray = [];
274 if ($cType != $this->_contactType
&& !in_array($cType, $cTypeArray)) {
275 foreach ($this->_dedupeFields
[$cType] as $val) {
276 if ($valTitle = CRM_Utils_Array
::value($val, $this->_formattedFieldNames
[$cType])) {
277 $this->_formattedFieldNames
[$cType][$val] = $valTitle . ' (match to contact)';
280 $cTypeArray[] = $cType;
284 foreach ($highlightedFields as $k => $v) {
285 if ($v == $cType ||
$v === 'All') {
286 $highlightedRelFields[$key][] = $k;
289 $this->assign('highlightedRelFields', $highlightedRelFields);
290 $sel2[$key] = $this->_formattedFieldNames
[$cType];
292 if (!empty($cSubType)) {
293 //custom fields for sub type
294 $subTypeFields = CRM_Core_BAO_CustomField
::getFieldsForImport($cSubType);
296 if (!empty($subTypeFields)) {
298 foreach ($subTypeFields as $customSubTypeField => $details) {
299 $subType[$customSubTypeField] = $details['title'];
300 $sel2[$key] = array_merge($sel2[$key], $this->formatCustomFieldName($subType));
305 foreach ($this->_location_types
as $k => $value) {
306 $sel4[$key]['phone'][$k] = &$phoneTypes;
307 $sel4[$key]['phone_ext'][$k] = &$phoneTypes;
308 //build array of IM service provider for related contact
309 $sel4[$key]['im'][$k] = &$imProviders;
314 if (!empty($hasLocationTypes[$key])) {
315 $options = $this->_location_types
;
317 elseif ($key === 'url') {
318 $options = $websiteTypes;
320 $sel2[$key] = $options;
324 $js = "<script type='text/javascript'>\n";
325 $formName = 'document.forms.' . $this->_name
;
326 //used to warn for mismatch column count or mismatch mapping
327 CRM_Core_Session
::singleton()->setStatus(NULL);
328 $processor = new CRM_Import_ImportProcessor();
329 $processor->setMappingID($savedMappingID);
330 $processor->setFormName($formName);
331 $processor->setMetadata($this->getContactImportMetadata());
332 $processor->setContactTypeByConstant($this->get('contactType'));
333 $processor->setContactSubType($this->get('contactSubType'));
335 for ($i = 0; $i < $this->_columnCount
; $i++
) {
336 $sel = &$this->addElement('hierselect', "mapper[$i]", ts('Mapper for Field %1', [1 => $i]), NULL);
338 if ($this->get('savedMapping') && $processor->getFieldName($i)) {
339 $defaults["mapper[$i]"] = $processor->getSavedQuickformDefaultsForColumn($i);
340 $js .= $processor->getQuickFormJSForField($i);
343 $js .= "swapOptions($formName, 'mapper[$i]', 0, 3, 'hs_mapper_0_');\n";
344 if ($hasColumnNames) {
345 // do array search first to see if has mapped key
346 $columnKey = array_search($this->_columnNames
[$i], $this->getFieldTitles());
347 if (isset($this->_fieldUsed
[$columnKey])) {
348 $defaults["mapper[$i]"] = $columnKey;
349 $this->_fieldUsed
[$key] = TRUE;
352 // Infer the default from the column names if we have them
353 $defaults["mapper[$i]"] = [
354 $this->defaultFromColumnName($this->_columnNames
[$i]),
360 // Otherwise guess the default from the form of the data
361 $defaults["mapper[$i]"] = [
362 $this->defaultFromData($this->getDataPatterns(), $i),
363 // $defaultLocationType->id
368 $sel->setOptions([$sel1, $sel2, $sel3, $sel4]);
371 $js .= "</script>\n";
372 $this->assign('initHideBoxes', $js);
374 //set warning if mismatch in more than
375 if (isset($mappingName) &&
376 ($this->_columnCount
!= count($mappingName))
378 CRM_Core_Session
::singleton()->setStatus(ts('The data columns in this import file appear to be different from the saved mapping. Please verify that you have selected the correct saved mapping before continuing.'));
381 $this->setDefaults($defaults);
386 'name' => ts('Previous'),
390 'name' => ts('Continue'),
391 'spacing' => ' ',
396 'name' => ts('Cancel'),
402 * Global validation rules for the form.
404 * @param array $fields
405 * Posted values of the form.
408 * list of errors to be posted back to the form
410 public static function formRule($fields) {
412 if (!empty($fields['saveMapping'])) {
413 $nameField = $fields['saveMappingName'] ??
NULL;
414 if (empty($nameField)) {
415 $errors['saveMappingName'] = ts('Name is required to save Import Mapping');
418 $mappingTypeId = CRM_Core_PseudoConstant
::getKey('CRM_Core_BAO_Mapping', 'mapping_type_id', 'Import Contact');
419 if (CRM_Core_BAO_Mapping
::checkMapping($nameField, $mappingTypeId)) {
420 $errors['saveMappingName'] = ts('Duplicate Import Mapping Name');
424 $template = CRM_Core_Smarty
::singleton();
425 if (!empty($fields['saveMapping'])) {
426 $template->assign('isCheked', TRUE);
429 if (!empty($errors)) {
431 $assignError = new CRM_Core_Page();
432 $assignError->assign('mappingDetailsError', $_flag);
441 * Process the mapped fields and map it into the uploaded file.
443 public function postProcess() {
444 $params = $this->controller
->exportValues('MapField');
446 //reload the mapfield if load mapping is pressed
447 if (!empty($params['savedMapping'])) {
448 $this->set('savedMapping', $params['savedMapping']);
449 $this->controller
->resetPage($this->_name
);
452 $mapperKeys = $this->controller
->exportValue($this->_name
, 'mapper');
454 $parser = $this->submit($params, $mapperKeys);
456 // add all the necessary variables to the form
461 * Format custom field name.
463 * Combine group and field name to avoid conflict.
465 * @param array $fields
469 public function formatCustomFieldName($fields) {
470 //CRM-2676, replacing the conflict for same custom field name from different custom group.
471 $fieldIds = $formattedFieldNames = [];
472 foreach ($fields as $key => $value) {
473 if ($customFieldId = CRM_Core_BAO_CustomField
::getKeyID($key)) {
474 $fieldIds[] = $customFieldId;
478 if (!empty($fieldIds) && is_array($fieldIds)) {
479 $groupTitles = CRM_Core_BAO_CustomGroup
::getGroupTitles($fieldIds);
481 if (!empty($groupTitles)) {
482 foreach ($groupTitles as $fId => $values) {
483 $key = "custom_{$fId}";
484 $groupTitle = $values['groupTitle'];
485 $formattedFieldNames[$key] = $fields[$key] . ' :: ' . $groupTitle;
490 return $formattedFieldNames;
494 * Main submit function.
496 * Extracted to add testing & start refactoring.
501 * @return \CRM_Contact_Import_Parser_Contact
502 * @throws \CiviCRM_API3_Exception
504 public function submit($params, $mapperKeys) {
505 $mapper = $mapperKeysMain = $locations = [];
506 $parserParameters = CRM_Contact_Import_Parser_Contact
::getParameterForParser($this->_columnCount
);
508 $phoneTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Phone', 'phone_type_id');
509 $imProviders = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id');
510 $websiteTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Website', 'website_type_id');
511 $locationTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Address', 'location_type_id');
512 $locationTypes['Primary'] = ts('Primary');
514 for ($i = 0; $i < $this->_columnCount
; $i++
) {
516 $fldName = $mapperKeys[$i][0] ??
NULL;
517 $selOne = $mapperKeys[$i][1] ??
NULL;
518 $selTwo = $mapperKeys[$i][2] ??
NULL;
519 $selThree = $mapperKeys[$i][3] ??
NULL;
520 $mapper[$i] = $this->_mapperFields
[$mapperKeys[$i][0]];
521 $mapperKeysMain[$i] = $fldName;
523 //need to differentiate non location elements.
524 if ($selOne && (is_numeric($selOne) ||
$selOne === 'Primary')) {
525 if ($fldName === 'url') {
526 $parserParameters['mapperWebsiteType'][$i] = $websiteTypes[$selOne];
529 $locations[$i] = $locationTypes[$selOne];
530 $parserParameters['mapperLocType'][$i] = $selOne;
531 if ($selTwo && is_numeric($selTwo)) {
532 if ($fldName === 'phone' ||
$fldName === 'phone_ext') {
533 $parserParameters['mapperPhoneType'][$i] = $phoneTypes[$selTwo];
535 elseif ($fldName === 'im') {
536 $parserParameters['mapperImProvider'][$i] = $imProviders[$selTwo];
542 //relationship contact mapper info.
543 [$id, $first, $second] = CRM_Utils_System
::explode('_', $fldName, 3);
544 if (($first === 'a' && $second === 'b') ||
545 ($first === 'b' && $second === 'a')
547 $parserParameters['mapperRelated'][$i] = $this->_mapperFields
[$fldName];
549 if ($selOne === 'url') {
550 $parserParameters['relatedContactWebsiteType'][$i] = $websiteTypes[$selTwo];
553 $parserParameters['relatedContactLocType'][$i] = $locationTypes[$selTwo] ??
NULL;
555 if ($selOne === 'phone' ||
$selOne === 'phone_ext') {
556 $parserParameters['relatedContactPhoneType'][$i] = $phoneTypes[$selThree];
558 elseif ($selOne === 'im') {
559 $parserParameters['relatedContactImProvider'][$i] = $imProviders[$selThree];
564 //get the related contact type.
565 $relationType = new CRM_Contact_DAO_RelationshipType();
566 $relationType->id
= $id;
567 $relationType->find(TRUE);
568 $parserParameters['relatedContactType'][$i] = $relationType->{"contact_type_$second"};
569 $parserParameters['relatedContactDetails'][$i] = $this->_formattedFieldNames
[$parserParameters['relatedContactType'][$i]][$selOne];
574 $this->set('columnNames', $this->_columnNames
);
575 $this->set('websites', $parserParameters['mapperWebsiteType']);
576 $this->set('locations', $locations);
577 $this->set('phones', $parserParameters['mapperPhoneType']);
578 $this->set('ims', $parserParameters['mapperImProvider']);
579 $this->set('related', $parserParameters['mapperRelated']);
580 $this->set('relatedContactType', $parserParameters['relatedContactType']);
581 $this->set('relatedContactDetails', $parserParameters['relatedContactDetails']);
582 $this->set('relatedContactLocType', $parserParameters['relatedContactLocType']);
583 $this->set('relatedContactPhoneType', $parserParameters['relatedContactPhoneType']);
584 $this->set('relatedContactImProvider', $parserParameters['relatedContactImProvider']);
585 $this->set('relatedContactWebsiteType', $parserParameters['relatedContactWebsiteType']);
586 $this->set('mapper', $mapper);
588 // store mapping Id to display it in the preview page
589 $this->set('loadMappingId', CRM_Utils_Array
::value('mappingId', $params));
591 //Updating Mapping Records
592 if (!empty($params['updateMapping'])) {
594 $mappingFields = new CRM_Core_DAO_MappingField();
595 $mappingFields->mapping_id
= $params['mappingId'];
596 $mappingFields->find();
598 $mappingFieldsId = [];
599 while ($mappingFields->fetch()) {
600 if ($mappingFields->id
) {
601 $mappingFieldsId[$mappingFields->column_number
] = $mappingFields->id
;
605 for ($i = 0; $i < $this->_columnCount
; $i++
) {
606 $updateMappingFields = new CRM_Core_DAO_MappingField();
607 $updateMappingFields->id
= $mappingFieldsId[$i] ??
NULL;
608 $updateMappingFields->mapping_id
= $params['mappingId'];
609 $updateMappingFields->column_number
= $i;
611 $mapperKeyParts = explode('_', $mapperKeys[$i][0], 3);
612 $id = $mapperKeyParts[0] ??
NULL;
613 $first = $mapperKeyParts[1] ??
NULL;
614 $second = $mapperKeyParts[2] ??
NULL;
615 if (($first == 'a' && $second == 'b') ||
($first == 'b' && $second == 'a')) {
616 $updateMappingFields->relationship_type_id
= $id;
617 $updateMappingFields->relationship_direction
= "{$first}_{$second}";
618 $updateMappingFields->name
= ucwords(str_replace("_", " ", $mapperKeys[$i][1]));
619 // get phoneType id and provider id separately
620 // before updating mappingFields of phone and IM for related contact, CRM-3140
621 if (CRM_Utils_Array
::value('1', $mapperKeys[$i]) == 'url') {
622 $updateMappingFields->website_type_id
= $mapperKeys[$i][2] ??
NULL;
625 if (CRM_Utils_Array
::value('1', $mapperKeys[$i]) == 'phone') {
626 $updateMappingFields->phone_type_id
= $mapperKeys[$i][3] ??
NULL;
628 elseif (CRM_Utils_Array
::value('1', $mapperKeys[$i]) == 'im') {
629 $updateMappingFields->im_provider_id
= $mapperKeys[$i][3] ??
NULL;
631 $updateMappingFields->location_type_id
= isset($mapperKeys[$i][2]) && is_numeric($mapperKeys[$i][2]) ?
$mapperKeys[$i][2] : NULL;
635 $updateMappingFields->name
= $mapper[$i];
636 $updateMappingFields->relationship_type_id
= 'NULL';
637 $updateMappingFields->relationship_type_direction
= 'NULL';
638 // to store phoneType id and provider id separately
639 // before updating mappingFields for phone and IM, CRM-3140
640 if (CRM_Utils_Array
::value('0', $mapperKeys[$i]) == 'url') {
641 $updateMappingFields->website_type_id
= $mapperKeys[$i][1] ??
NULL;
644 if (($mapperKeys[$i][0] ??
NULL) === 'phone' ||
($mapperKeys[$i][0] ??
NULL) === 'phone_ext') {
645 $updateMappingFields->phone_type_id
= $mapperKeys[$i][2] ??
NULL;
647 elseif (CRM_Utils_Array
::value('0', $mapperKeys[$i]) == 'im') {
648 $updateMappingFields->im_provider_id
= $mapperKeys[$i][2] ??
NULL;
650 $locationTypeID = $parserParameters['mapperLocType'][$i];
651 // location_type_id is NULL for non-location fields, and for Primary location.
652 $updateMappingFields->location_type_id
= is_numeric($locationTypeID) ?
$locationTypeID : 'null';
655 $updateMappingFields->save();
659 //Saving Mapping Details and Records
660 if (!empty($params['saveMapping'])) {
662 'name' => $params['saveMappingName'],
663 'description' => $params['saveMappingDesc'],
664 'mapping_type_id' => 'Import Contact',
667 $saveMapping = civicrm_api3('Mapping', 'create', $mappingParams);
670 foreach (array_keys($this->getColumnHeaders()) as $i) {
671 $mappingID = $this->saveMappingField($mapperKeys, $saveMapping, $this->getContactType(), $i, $mapper, $parserParameters);
673 $this->set('savedMapping', $mappingID);
676 $parser = new CRM_Contact_Import_Parser_Contact($mapperKeysMain, $parserParameters['mapperLocType'], $parserParameters['mapperPhoneType'],
677 $parserParameters['mapperImProvider'], $parserParameters['mapperRelated'], $parserParameters['relatedContactType'],
678 $parserParameters['relatedContactDetails'], $parserParameters['relatedContactLocType'],
679 $parserParameters['relatedContactPhoneType'], $parserParameters['relatedContactImProvider'],
680 $parserParameters['mapperWebsiteType'], $parserParameters['relatedContactWebsiteType']
682 $parser->setUserJobID($this->getUserJobID());
684 $parser->run($this->_importTableName
,
686 CRM_Import_Parser
::MODE_PREVIEW
,
687 $this->get('contactType'),
692 CRM_Contact_Import_Parser_Contact
::DEFAULT_TIMEOUT
,
693 $this->get('contactSubType'),
694 $this->getSubmittedValue('dedupe_rule_id')
701 * @param array $saveMapping
702 * @param string $cType
704 * @param array $mapper
705 * @param array $parserParameters
709 protected function saveMappingField($mapperKeys, array $saveMapping, string $cType, int $i, array $mapper, array $parserParameters): int {
710 $saveMappingFields = new CRM_Core_DAO_MappingField();
711 $saveMappingFields->mapping_id
= $saveMapping['id'];
712 $saveMappingFields->contact_type
= $cType;
713 $saveMappingFields->column_number
= $i;
715 $mapperKeyParts = explode('_', $mapperKeys[$i][0], 3);
716 $id = $mapperKeyParts[0] ??
NULL;
717 $first = $mapperKeyParts[1] ??
NULL;
718 $second = $mapperKeyParts[2] ??
NULL;
719 if (($first == 'a' && $second == 'b') ||
($first == 'b' && $second == 'a')) {
720 $saveMappingFields->name
= ucwords(str_replace("_", " ", $mapperKeys[$i][1]));
721 $saveMappingFields->relationship_type_id
= $id;
722 $saveMappingFields->relationship_direction
= "{$first}_{$second}";
723 // to get phoneType id and provider id separately
724 // before saving mappingFields of phone and IM for related contact, CRM-3140
725 if (CRM_Utils_Array
::value('1', $mapperKeys[$i]) == 'url') {
726 $saveMappingFields->website_type_id
= $mapperKeys[$i][2] ??
NULL;
729 if (CRM_Utils_Array
::value('1', $mapperKeys[$i]) == 'phone') {
730 $saveMappingFields->phone_type_id
= $mapperKeys[$i][3] ??
NULL;
732 elseif (CRM_Utils_Array
::value('1', $mapperKeys[$i]) == 'im') {
733 $saveMappingFields->im_provider_id
= $mapperKeys[$i][3] ??
NULL;
735 $saveMappingFields->location_type_id
= (isset($mapperKeys[$i][2]) && $mapperKeys[$i][2] !== 'Primary') ?
$mapperKeys[$i][2] : NULL;
739 $saveMappingFields->name
= $mapper[$i];
740 $locationTypeID = $parserParameters['mapperLocType'][$i];
741 // to get phoneType id and provider id separately
742 // before saving mappingFields of phone and IM, CRM-3140
743 if (CRM_Utils_Array
::value('0', $mapperKeys[$i]) == 'url') {
744 $saveMappingFields->website_type_id
= $mapperKeys[$i][1] ??
NULL;
747 if (($mapperKeys[$i][0] ??
NULL) === 'phone' ||
($mapperKeys[$i][0] ??
NULL) === 'phone_ext') {
748 $saveMappingFields->phone_type_id
= $mapperKeys[$i][2] ??
NULL;
750 elseif (CRM_Utils_Array
::value('0', $mapperKeys[$i]) == 'im') {
751 $saveMappingFields->im_provider_id
= $mapperKeys[$i][2] ??
NULL;
753 $saveMappingFields->location_type_id
= is_numeric($locationTypeID) ?
$locationTypeID : NULL;
755 $saveMappingFields->relationship_type_id
= NULL;
757 $saveMappingFields->save();
758 return $saveMappingFields->mapping_id
;