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 public function preProcess() {
80 $dataSource = $this->get('dataSource');
81 $skipColumnHeader = $this->get('skipColumnHeader');
82 $this->_mapperFields
= $this->get('fields');
83 $this->_importTableName
= $this->get('importTableName');
84 $this->_onDuplicate
= $this->get('onDuplicate');
85 $this->_contactSubType
= $this->get('contactSubType');
86 $highlightedFields = [];
87 $highlightedFields[] = 'email';
88 $highlightedFields[] = 'external_identifier';
89 //format custom field names, CRM-2676
90 switch ($this->get('contactType')) {
91 case CRM_Import_Parser
::CONTACT_INDIVIDUAL
:
92 $contactType = 'Individual';
93 $highlightedFields[] = 'first_name';
94 $highlightedFields[] = 'last_name';
97 case CRM_Import_Parser
::CONTACT_HOUSEHOLD
:
98 $contactType = 'Household';
99 $highlightedFields[] = 'household_name';
102 case CRM_Import_Parser
::CONTACT_ORGANIZATION
:
103 $contactType = '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 (['Individual', 'Household', 'Organization'] as $cType) {
119 'contact_type' => $cType,
120 'used' => 'Unsupervised',
122 $this->_dedupeFields
[$cType] = CRM_Dedupe_BAO_Rule
::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);
146 //get original col headers from csv if present.
147 if ($dataSource == 'CRM_Import_DataSource_CSV' && $skipColumnHeader) {
148 $columnNames = $this->get('originalColHeader');
151 // get the field names from the temp. DB table
152 $dao = new CRM_Core_DAO();
153 $db = $dao->getDatabaseConnection();
155 $columnsQuery = "SHOW FIELDS FROM $this->_importTableName
156 WHERE Field NOT LIKE '\_%'";
157 $columnsResult = $db->query($columnsQuery);
158 while ($row = $columnsResult->fetchRow(DB_FETCHMODE_ASSOC
)) {
159 $columnNames[] = $row['Field'];
163 $showColNames = TRUE;
164 if ($dataSource === 'CRM_Import_DataSource_CSV' && !$skipColumnHeader) {
165 $showColNames = FALSE;
167 $this->assign('showColNames', $showColNames);
169 $this->_columnCount
= count($columnNames);
170 $this->_columnNames
= $columnNames;
171 $this->assign('columnNames', $columnNames);
172 //$this->_columnCount = $this->get( 'columnCount' );
173 $this->assign('columnCount', $this->_columnCount
);
174 $this->_dataValues
= $this->get('dataValues');
175 $this->assign('dataValues', $this->_dataValues
);
176 $this->assign('rowDisplayCount', 2);
180 * Build the form object.
182 * @throws \CiviCRM_API3_Exception
184 public function buildQuickForm() {
185 $savedMappingID = (int) $this->get('savedMapping');
186 $this->buildSavedMappingFields($savedMappingID);
188 $this->addFormRule(['CRM_Contact_Import_Form_MapField', 'formRule']);
190 //-------- end of saved mapping stuff ---------
193 $mapperKeys = array_keys($this->_mapperFields
);
194 $hasColumnNames = !empty($this->_columnNames
);
195 $hasLocationTypes = $this->get('fieldTypes');
197 $this->_location_types
= ['Primary' => ts('Primary')] + CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Address', 'location_type_id');
198 $defaultLocationType = CRM_Core_BAO_LocationType
::getDefault();
200 // Pass default location to js
201 if ($defaultLocationType) {
202 $this->assign('defaultLocationType', $defaultLocationType->id
);
203 $this->assign('defaultLocationTypeLabel', $this->_location_types
[$defaultLocationType->id
]);
206 /* Initialize all field usages to false */
207 foreach ($mapperKeys as $key) {
208 $this->_fieldUsed
[$key] = FALSE;
211 $sel1 = $this->_mapperFields
;
214 $phoneTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Phone', 'phone_type_id');
215 $imProviders = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id');
216 $websiteTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Website', 'website_type_id');
218 foreach ($this->_location_types
as $key => $value) {
219 $sel3['phone'][$key] = &$phoneTypes;
220 //build array for IM service provider type for contact
221 $sel3['im'][$key] = &$imProviders;
226 // store and cache all relationship types
227 $contactRelation = new CRM_Contact_DAO_RelationshipType();
228 $contactRelation->find();
229 while ($contactRelation->fetch()) {
230 $contactRelationCache[$contactRelation->id
] = [];
231 $contactRelationCache[$contactRelation->id
]['contact_type_a'] = $contactRelation->contact_type_a
;
232 $contactRelationCache[$contactRelation->id
]['contact_sub_type_a'] = $contactRelation->contact_sub_type_a
;
233 $contactRelationCache[$contactRelation->id
]['contact_type_b'] = $contactRelation->contact_type_b
;
234 $contactRelationCache[$contactRelation->id
]['contact_sub_type_b'] = $contactRelation->contact_sub_type_b
;
236 $highlightedFields = $highlightedRelFields = [];
238 $highlightedFields['email'] = 'All';
239 $highlightedFields['external_identifier'] = 'All';
240 $highlightedFields['first_name'] = 'Individual';
241 $highlightedFields['last_name'] = 'Individual';
242 $highlightedFields['household_name'] = 'Household';
243 $highlightedFields['organization_name'] = 'Organization';
245 foreach ($mapperKeys as $key) {
246 // check if there is a _a_b or _b_a in the key
247 if (strpos($key, '_a_b') ||
strpos($key, '_b_a')) {
248 list($id, $first, $second) = explode('_', $key);
251 $id = $first = $second = NULL;
253 if (($first === 'a' && $second === 'b') ||
($first === 'b' && $second === 'a')) {
254 $cType = $contactRelationCache[$id]["contact_type_{$second}"];
256 //CRM-5125 for contact subtype specific relationshiptypes
258 if (!empty($contactRelationCache[$id]["contact_sub_type_{$second}"])) {
259 $cSubType = $contactRelationCache[$id]["contact_sub_type_{$second}"];
266 $relatedFields = CRM_Contact_BAO_Contact
::importableFields($cType);
267 unset($relatedFields['']);
269 foreach ($relatedFields as $name => $field) {
270 $values[$name] = $field['title'];
271 if (isset($hasLocationTypes[$name])) {
272 $sel3[$key][$name] = $this->_location_types
;
274 elseif ($name === 'url') {
275 $sel3[$key][$name] = $websiteTypes;
282 //fix to append custom group name to field name, CRM-2676
283 if (empty($this->_formattedFieldNames
[$cType]) ||
$cType == $this->_contactType
) {
284 $this->_formattedFieldNames
[$cType] = $this->formatCustomFieldName($values);
287 $this->_formattedFieldNames
[$cType] = array_merge($values, $this->_formattedFieldNames
[$cType]);
289 //Modified the Relationship fields if the fields are
290 //present in dedupe rule
291 if ($this->_onDuplicate
!= CRM_Import_Parser
::DUPLICATE_NOCHECK
&& !empty($this->_dedupeFields
[$cType]) &&
292 is_array($this->_dedupeFields
[$cType])
294 static $cTypeArray = [];
295 if ($cType != $this->_contactType
&& !in_array($cType, $cTypeArray)) {
296 foreach ($this->_dedupeFields
[$cType] as $val) {
297 if ($valTitle = CRM_Utils_Array
::value($val, $this->_formattedFieldNames
[$cType])) {
298 $this->_formattedFieldNames
[$cType][$val] = $valTitle . ' (match to contact)';
301 $cTypeArray[] = $cType;
305 foreach ($highlightedFields as $k => $v) {
306 if ($v == $cType ||
$v === 'All') {
307 $highlightedRelFields[$key][] = $k;
310 $this->assign('highlightedRelFields', $highlightedRelFields);
311 $sel2[$key] = $this->_formattedFieldNames
[$cType];
313 if (!empty($cSubType)) {
314 //custom fields for sub type
315 $subTypeFields = CRM_Core_BAO_CustomField
::getFieldsForImport($cSubType);
317 if (!empty($subTypeFields)) {
319 foreach ($subTypeFields as $customSubTypeField => $details) {
320 $subType[$customSubTypeField] = $details['title'];
321 $sel2[$key] = array_merge($sel2[$key], $this->formatCustomFieldName($subType));
326 foreach ($this->_location_types
as $k => $value) {
327 $sel4[$key]['phone'][$k] = &$phoneTypes;
328 //build array of IM service provider for related contact
329 $sel4[$key]['im'][$k] = &$imProviders;
334 if (!empty($hasLocationTypes[$key])) {
335 $options = $this->_location_types
;
337 elseif ($key === 'url') {
338 $options = $websiteTypes;
340 $sel2[$key] = $options;
344 $js = "<script type='text/javascript'>\n";
345 $formName = 'document.forms.' . $this->_name
;
346 //used to warn for mismatch column count or mismatch mapping
347 CRM_Core_Session
::singleton()->setStatus(NULL);
348 $processor = new CRM_Import_ImportProcessor();
349 $processor->setMappingID($savedMappingID);
350 $processor->setFormName($formName);
351 $processor->setMetadata($this->getContactImportMetadata());
352 $processor->setContactTypeByConstant($this->get('contactType'));
353 $processor->setContactSubType($this->get('contactSubType'));
355 for ($i = 0; $i < $this->_columnCount
; $i++
) {
356 $sel = &$this->addElement('hierselect', "mapper[$i]", ts('Mapper for Field %1', [1 => $i]), NULL);
358 if ($this->get('savedMapping') && $processor->getFieldName($i)) {
359 $defaults["mapper[$i]"] = $processor->getSavedQuickformDefaultsForColumn($i);
360 $js .= $processor->getQuickFormJSForField($i);
363 $js .= "swapOptions($formName, 'mapper[$i]', 0, 3, 'hs_mapper_0_');\n";
364 if ($hasColumnNames) {
365 // do array search first to see if has mapped key
366 $columnKey = array_search($this->_columnNames
[$i], $this->getFieldTitles());
367 if (isset($this->_fieldUsed
[$columnKey])) {
368 $defaults["mapper[$i]"] = $columnKey;
369 $this->_fieldUsed
[$key] = TRUE;
372 // Infer the default from the column names if we have them
373 $defaults["mapper[$i]"] = [
374 $this->defaultFromColumnName($this->_columnNames
[$i]),
380 // Otherwise guess the default from the form of the data
381 $defaults["mapper[$i]"] = [
382 $this->defaultFromData($this->getDataPatterns(), $i),
383 // $defaultLocationType->id
388 $sel->setOptions([$sel1, $sel2, $sel3, $sel4]);
391 $js .= "</script>\n";
392 $this->assign('initHideBoxes', $js);
394 //set warning if mismatch in more than
395 if (isset($mappingName) &&
396 ($this->_columnCount
!= count($mappingName))
398 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.'));
401 $this->setDefaults($defaults);
406 'name' => ts('Previous'),
410 'name' => ts('Continue'),
411 'spacing' => ' ',
416 'name' => ts('Cancel'),
422 * Global validation rules for the form.
424 * @param array $fields
425 * Posted values of the form.
428 * list of errors to be posted back to the form
430 public static function formRule($fields) {
432 if (!empty($fields['saveMapping'])) {
433 $nameField = $fields['saveMappingName'] ??
NULL;
434 if (empty($nameField)) {
435 $errors['saveMappingName'] = ts('Name is required to save Import Mapping');
438 $mappingTypeId = CRM_Core_PseudoConstant
::getKey('CRM_Core_BAO_Mapping', 'mapping_type_id', 'Import Contact');
439 if (CRM_Core_BAO_Mapping
::checkMapping($nameField, $mappingTypeId)) {
440 $errors['saveMappingName'] = ts('Duplicate Import Mapping Name');
444 $template = CRM_Core_Smarty
::singleton();
445 if (!empty($fields['saveMapping'])) {
446 $template->assign('isCheked', TRUE);
449 if (!empty($errors)) {
451 $assignError = new CRM_Core_Page();
452 $assignError->assign('mappingDetailsError', $_flag);
461 * Process the mapped fields and map it into the uploaded file.
463 public function postProcess() {
464 $params = $this->controller
->exportValues('MapField');
466 //reload the mapfield if load mapping is pressed
467 if (!empty($params['savedMapping'])) {
468 $this->set('savedMapping', $params['savedMapping']);
469 $this->controller
->resetPage($this->_name
);
472 $mapperKeys = $this->controller
->exportValue($this->_name
, 'mapper');
474 $parser = $this->submit($params, $mapperKeys);
476 // add all the necessary variables to the form
481 * Format custom field name.
483 * Combine group and field name to avoid conflict.
485 * @param array $fields
489 public function formatCustomFieldName($fields) {
490 //CRM-2676, replacing the conflict for same custom field name from different custom group.
491 $fieldIds = $formattedFieldNames = [];
492 foreach ($fields as $key => $value) {
493 if ($customFieldId = CRM_Core_BAO_CustomField
::getKeyID($key)) {
494 $fieldIds[] = $customFieldId;
498 if (!empty($fieldIds) && is_array($fieldIds)) {
499 $groupTitles = CRM_Core_BAO_CustomGroup
::getGroupTitles($fieldIds);
501 if (!empty($groupTitles)) {
502 foreach ($groupTitles as $fId => $values) {
503 $key = "custom_{$fId}";
504 $groupTitle = $values['groupTitle'];
505 $formattedFieldNames[$key] = $fields[$key] . ' :: ' . $groupTitle;
510 return $formattedFieldNames;
514 * Main submit function.
516 * Extracted to add testing & start refactoring.
521 * @return \CRM_Contact_Import_Parser_Contact
522 * @throws \CiviCRM_API3_Exception
524 public function submit($params, $mapperKeys) {
525 $mapper = $mapperKeysMain = $locations = [];
526 $parserParameters = CRM_Contact_Import_Parser_Contact
::getParameterForParser($this->_columnCount
);
528 $phoneTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Phone', 'phone_type_id');
529 $imProviders = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id');
530 $websiteTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Website', 'website_type_id');
531 $locationTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Address', 'location_type_id');
532 $locationTypes['Primary'] = ts('Primary');
534 for ($i = 0; $i < $this->_columnCount
; $i++
) {
536 $fldName = $mapperKeys[$i][0] ??
NULL;
537 $selOne = $mapperKeys[$i][1] ??
NULL;
538 $selTwo = $mapperKeys[$i][2] ??
NULL;
539 $selThree = $mapperKeys[$i][3] ??
NULL;
540 $mapper[$i] = $this->_mapperFields
[$mapperKeys[$i][0]];
541 $mapperKeysMain[$i] = $fldName;
543 //need to differentiate non location elements.
544 if ($selOne && (is_numeric($selOne) ||
$selOne === 'Primary')) {
545 if ($fldName === 'url') {
546 $parserParameters['mapperWebsiteType'][$i] = $websiteTypes[$selOne];
549 $locations[$i] = $locationTypes[$selOne];
550 $parserParameters['mapperLocType'][$i] = $selOne;
551 if ($selTwo && is_numeric($selTwo)) {
552 if ($fldName === 'phone') {
553 $parserParameters['mapperPhoneType'][$i] = $phoneTypes[$selTwo];
555 elseif ($fldName === 'im') {
556 $parserParameters['mapperImProvider'][$i] = $imProviders[$selTwo];
562 //relationship contact mapper info.
563 list($id, $first, $second) = CRM_Utils_System
::explode('_', $fldName, 3);
564 if (($first === 'a' && $second === 'b') ||
565 ($first === 'b' && $second === 'a')
567 $parserParameters['mapperRelated'][$i] = $this->_mapperFields
[$fldName];
569 if ($selOne === 'url') {
570 $parserParameters['relatedContactWebsiteType'][$i] = $websiteTypes[$selTwo];
573 $parserParameters['relatedContactLocType'][$i] = $locationTypes[$selTwo] ??
NULL;
575 if ($selOne === 'phone') {
576 $parserParameters['relatedContactPhoneType'][$i] = $phoneTypes[$selThree];
578 elseif ($selOne === 'im') {
579 $parserParameters['relatedContactImProvider'][$i] = $imProviders[$selThree];
584 //get the related contact type.
585 $relationType = new CRM_Contact_DAO_RelationshipType();
586 $relationType->id
= $id;
587 $relationType->find(TRUE);
588 $parserParameters['relatedContactType'][$i] = $relationType->{"contact_type_$second"};
589 $parserParameters['relatedContactDetails'][$i] = $this->_formattedFieldNames
[$parserParameters['relatedContactType'][$i]][$selOne];
594 $this->set('columnNames', $this->_columnNames
);
595 $this->set('websites', $parserParameters['mapperWebsiteType']);
596 $this->set('locations', $locations);
597 $this->set('phones', $parserParameters['mapperPhoneType']);
598 $this->set('ims', $parserParameters['mapperImProvider']);
599 $this->set('related', $parserParameters['mapperRelated']);
600 $this->set('relatedContactType', $parserParameters['relatedContactType']);
601 $this->set('relatedContactDetails', $parserParameters['relatedContactDetails']);
602 $this->set('relatedContactLocType', $parserParameters['relatedContactLocType']);
603 $this->set('relatedContactPhoneType', $parserParameters['relatedContactPhoneType']);
604 $this->set('relatedContactImProvider', $parserParameters['relatedContactImProvider']);
605 $this->set('relatedContactWebsiteType', $parserParameters['relatedContactWebsiteType']);
606 $this->set('mapper', $mapper);
608 // store mapping Id to display it in the preview page
609 $this->set('loadMappingId', CRM_Utils_Array
::value('mappingId', $params));
611 //Updating Mapping Records
612 if (!empty($params['updateMapping'])) {
614 $mappingFields = new CRM_Core_DAO_MappingField();
615 $mappingFields->mapping_id
= $params['mappingId'];
616 $mappingFields->find();
618 $mappingFieldsId = [];
619 while ($mappingFields->fetch()) {
620 if ($mappingFields->id
) {
621 $mappingFieldsId[$mappingFields->column_number
] = $mappingFields->id
;
625 for ($i = 0; $i < $this->_columnCount
; $i++
) {
626 $updateMappingFields = new CRM_Core_DAO_MappingField();
627 $updateMappingFields->id
= $mappingFieldsId[$i] ??
NULL;
628 $updateMappingFields->mapping_id
= $params['mappingId'];
629 $updateMappingFields->column_number
= $i;
631 $mapperKeyParts = explode('_', $mapperKeys[$i][0], 3);
632 $id = $mapperKeyParts[0] ??
NULL;
633 $first = $mapperKeyParts[1] ??
NULL;
634 $second = $mapperKeyParts[2] ??
NULL;
635 if (($first == 'a' && $second == 'b') ||
($first == 'b' && $second == 'a')) {
636 $updateMappingFields->relationship_type_id
= $id;
637 $updateMappingFields->relationship_direction
= "{$first}_{$second}";
638 $updateMappingFields->name
= ucwords(str_replace("_", " ", $mapperKeys[$i][1]));
639 // get phoneType id and provider id separately
640 // before updating mappingFields of phone and IM for related contact, CRM-3140
641 if (CRM_Utils_Array
::value('1', $mapperKeys[$i]) == 'url') {
642 $updateMappingFields->website_type_id
= $mapperKeys[$i][2] ??
NULL;
645 if (CRM_Utils_Array
::value('1', $mapperKeys[$i]) == 'phone') {
646 $updateMappingFields->phone_type_id
= $mapperKeys[$i][3] ??
NULL;
648 elseif (CRM_Utils_Array
::value('1', $mapperKeys[$i]) == 'im') {
649 $updateMappingFields->im_provider_id
= $mapperKeys[$i][3] ??
NULL;
651 $updateMappingFields->location_type_id
= isset($mapperKeys[$i][2]) && is_numeric($mapperKeys[$i][2]) ?
$mapperKeys[$i][2] : NULL;
655 $updateMappingFields->name
= $mapper[$i];
656 $updateMappingFields->relationship_type_id
= 'NULL';
657 $updateMappingFields->relationship_type_direction
= 'NULL';
658 // to store phoneType id and provider id separately
659 // before updating mappingFields for phone and IM, CRM-3140
660 if (CRM_Utils_Array
::value('0', $mapperKeys[$i]) == 'url') {
661 $updateMappingFields->website_type_id
= $mapperKeys[$i][1] ??
NULL;
664 if (CRM_Utils_Array
::value('0', $mapperKeys[$i]) == 'phone') {
665 $updateMappingFields->phone_type_id
= $mapperKeys[$i][2] ??
NULL;
667 elseif (CRM_Utils_Array
::value('0', $mapperKeys[$i]) == 'im') {
668 $updateMappingFields->im_provider_id
= $mapperKeys[$i][2] ??
NULL;
670 $locationTypeID = $parserParameters['mapperLocType'][$i];
671 // location_type_id is NULL for non-location fields, and for Primary location.
672 $updateMappingFields->location_type_id
= is_numeric($locationTypeID) ?
$locationTypeID : 'null';
675 $updateMappingFields->save();
679 //Saving Mapping Details and Records
680 if (!empty($params['saveMapping'])) {
682 'name' => $params['saveMappingName'],
683 'description' => $params['saveMappingDesc'],
684 'mapping_type_id' => 'Import Contact',
687 $saveMapping = civicrm_api3('Mapping', 'create', $mappingParams);
689 $contactType = $this->get('contactType');
690 switch ($contactType) {
691 case CRM_Import_Parser
::CONTACT_INDIVIDUAL
:
692 $cType = 'Individual';
695 case CRM_Import_Parser
::CONTACT_HOUSEHOLD
:
696 $cType = 'Household';
699 case CRM_Import_Parser
::CONTACT_ORGANIZATION
:
700 $cType = 'Organization';
704 for ($i = 0; $i < $this->_columnCount
; $i++
) {
705 $mappingID = $this->saveMappingField($mapperKeys, $saveMapping, $cType, $i, $mapper, $parserParameters);
707 $this->set('savedMapping', $mappingID);
710 $parser = new CRM_Contact_Import_Parser_Contact($mapperKeysMain, $parserParameters['mapperLocType'], $parserParameters['mapperPhoneType'],
711 $parserParameters['mapperImProvider'], $parserParameters['mapperRelated'], $parserParameters['relatedContactType'],
712 $parserParameters['relatedContactDetails'], $parserParameters['relatedContactLocType'],
713 $parserParameters['relatedContactPhoneType'], $parserParameters['relatedContactImProvider'],
714 $parserParameters['mapperWebsiteType'], $parserParameters['relatedContactWebsiteType']
717 $primaryKeyName = $this->get('primaryKeyName');
718 $statusFieldName = $this->get('statusFieldName');
719 $parser->run($this->_importTableName
,
721 CRM_Import_Parser
::MODE_PREVIEW
,
722 $this->get('contactType'),
727 CRM_Contact_Import_Parser
::DEFAULT_TIMEOUT
,
728 $this->get('contactSubType'),
736 * @param array $saveMapping
737 * @param string $cType
739 * @param array $mapper
740 * @param array $parserParameters
744 protected function saveMappingField($mapperKeys, array $saveMapping, string $cType, int $i, array $mapper, array $parserParameters): int {
745 $saveMappingFields = new CRM_Core_DAO_MappingField();
746 $saveMappingFields->mapping_id
= $saveMapping['id'];
747 $saveMappingFields->contact_type
= $cType;
748 $saveMappingFields->column_number
= $i;
750 $mapperKeyParts = explode('_', $mapperKeys[$i][0], 3);
751 $id = $mapperKeyParts[0] ??
NULL;
752 $first = $mapperKeyParts[1] ??
NULL;
753 $second = $mapperKeyParts[2] ??
NULL;
754 if (($first == 'a' && $second == 'b') ||
($first == 'b' && $second == 'a')) {
755 $saveMappingFields->name
= ucwords(str_replace("_", " ", $mapperKeys[$i][1]));
756 $saveMappingFields->relationship_type_id
= $id;
757 $saveMappingFields->relationship_direction
= "{$first}_{$second}";
758 // to get phoneType id and provider id separately
759 // before saving mappingFields of phone and IM for related contact, CRM-3140
760 if (CRM_Utils_Array
::value('1', $mapperKeys[$i]) == 'url') {
761 $saveMappingFields->website_type_id
= $mapperKeys[$i][2] ??
NULL;
764 if (CRM_Utils_Array
::value('1', $mapperKeys[$i]) == 'phone') {
765 $saveMappingFields->phone_type_id
= $mapperKeys[$i][3] ??
NULL;
767 elseif (CRM_Utils_Array
::value('1', $mapperKeys[$i]) == 'im') {
768 $saveMappingFields->im_provider_id
= $mapperKeys[$i][3] ??
NULL;
770 $saveMappingFields->location_type_id
= (isset($mapperKeys[$i][2]) && $mapperKeys[$i][2] !== 'Primary') ?
$mapperKeys[$i][2] : NULL;
774 $saveMappingFields->name
= $mapper[$i];
775 $locationTypeID = $parserParameters['mapperLocType'][$i];
776 // to get phoneType id and provider id separately
777 // before saving mappingFields of phone and IM, CRM-3140
778 if (CRM_Utils_Array
::value('0', $mapperKeys[$i]) == 'url') {
779 $saveMappingFields->website_type_id
= $mapperKeys[$i][1] ??
NULL;
782 if (CRM_Utils_Array
::value('0', $mapperKeys[$i]) == 'phone') {
783 $saveMappingFields->phone_type_id
= $mapperKeys[$i][2] ??
NULL;
785 elseif (CRM_Utils_Array
::value('0', $mapperKeys[$i]) == 'im') {
786 $saveMappingFields->im_provider_id
= $mapperKeys[$i][2] ??
NULL;
788 $saveMappingFields->location_type_id
= is_numeric($locationTypeID) ?
$locationTypeID : NULL;
790 $saveMappingFields->relationship_type_id
= NULL;
792 $saveMappingFields->save();
793 return $saveMappingFields->mapping_id
;