3 +--------------------------------------------------------------------+
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2019 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
31 * @copyright CiviCRM LLC (c) 2004-2019
35 * This class gets the name of the file to upload.
37 class CRM_Contact_Import_Form_MapField
extends CRM_Import_Form_MapField
{
41 * An array of all contact fields with
42 * formatted custom field names.
46 protected $_formattedFieldNames;
55 protected $_dedupeFields;
57 protected static $customFields;
60 * Attempt to match header labels with our mapper fields.
62 * FIXME: This is essentially the same function as parent::defaultFromHeader
64 * @param string $columnName name of column header
65 * @param array $patterns pattern to match for the column
69 public function defaultFromColumnName($columnName, &$patterns) {
71 if (!preg_match('/^[a-z0-9 ]$/i', $columnName)) {
72 if ($columnKey = array_search($columnName, $this->_mapperFields
)) {
73 $this->_fieldUsed
[$columnKey] = TRUE;
78 foreach ($patterns as $key => $re) {
79 // Skip empty key/patterns
80 if (!$key ||
!$re ||
strlen("$re") < 5) {
84 if (preg_match($re, $columnName)) {
85 $this->_fieldUsed
[$key] = TRUE;
93 * Set variables up before form is built.
95 public function preProcess() {
96 $dataSource = $this->get('dataSource');
97 $skipColumnHeader = $this->get('skipColumnHeader');
98 $this->_mapperFields
= $this->get('fields');
99 $this->_importTableName
= $this->get('importTableName');
100 $this->_onDuplicate
= $this->get('onDuplicate');
101 $highlightedFields = array();
102 $highlightedFields[] = 'email';
103 $highlightedFields[] = 'external_identifier';
104 //format custom field names, CRM-2676
105 switch ($this->get('contactType')) {
106 case CRM_Import_Parser
::CONTACT_INDIVIDUAL
:
107 $contactType = 'Individual';
108 $highlightedFields[] = 'first_name';
109 $highlightedFields[] = 'last_name';
112 case CRM_Import_Parser
::CONTACT_HOUSEHOLD
:
113 $contactType = 'Household';
114 $highlightedFields[] = 'household_name';
117 case CRM_Import_Parser
::CONTACT_ORGANIZATION
:
118 $contactType = 'Organization';
119 $highlightedFields[] = 'organization_name';
122 $this->_contactType
= $contactType;
123 if ($this->_onDuplicate
== CRM_Import_Parser
::DUPLICATE_SKIP
) {
124 unset($this->_mapperFields
['id']);
127 $highlightedFields[] = 'id';
130 if ($this->_onDuplicate
!= CRM_Import_Parser
::DUPLICATE_NOCHECK
) {
131 //Mark Dedupe Rule Fields as required, since it's used in matching contact
138 'contact_type' => $cType,
139 'used' => 'Unsupervised',
141 $this->_dedupeFields
[$cType] = CRM_Dedupe_BAO_Rule
::dedupeRuleFields($ruleParams);
144 //Modify mapper fields title if fields are present in dedupe rule
145 if (is_array($this->_dedupeFields
[$contactType])) {
146 foreach ($this->_dedupeFields
[$contactType] as $val) {
147 if ($valTitle = CRM_Utils_Array
::value($val, $this->_mapperFields
)) {
148 $this->_mapperFields
[$val] = $valTitle . ' (match to contact)';
153 // retrieve and highlight required custom fields
154 $formattedFieldNames = $this->formatCustomFieldName($this->_mapperFields
);
155 self
::$customFields = CRM_Core_BAO_CustomField
::getFields($this->_contactType
);
156 foreach (self
::$customFields as $key => $attr) {
157 if (!empty($attr['is_required'])) {
158 $highlightedFields[] = "custom_$key";
161 $this->assign('highlightedFields', $highlightedFields);
162 $this->_formattedFieldNames
[$contactType] = $this->_mapperFields
= array_merge($this->_mapperFields
, $formattedFieldNames);
164 $columnNames = array();
165 //get original col headers from csv if present.
166 if ($dataSource == 'CRM_Import_DataSource_CSV' && $skipColumnHeader) {
167 $columnNames = $this->get('originalColHeader');
170 // get the field names from the temp. DB table
171 $dao = new CRM_Core_DAO();
172 $db = $dao->getDatabaseConnection();
174 $columnsQuery = "SHOW FIELDS FROM $this->_importTableName
175 WHERE Field NOT LIKE '\_%'";
176 $columnsResult = $db->query($columnsQuery);
177 while ($row = $columnsResult->fetchRow(DB_FETCHMODE_ASSOC
)) {
178 $columnNames[] = $row['Field'];
182 $showColNames = TRUE;
183 if ($dataSource == 'CRM_Import_DataSource_CSV' && !$skipColumnHeader) {
184 $showColNames = FALSE;
186 $this->assign('showColNames', $showColNames);
188 $this->_columnCount
= count($columnNames);
189 $this->_columnNames
= $columnNames;
190 $this->assign('columnNames', $columnNames);
191 //$this->_columnCount = $this->get( 'columnCount' );
192 $this->assign('columnCount', $this->_columnCount
);
193 $this->_dataValues
= $this->get('dataValues');
194 $this->assign('dataValues', $this->_dataValues
);
195 $this->assign('rowDisplayCount', 2);
199 * Build the form object.
201 public function buildQuickForm() {
202 //to save the current mappings
203 if (!$this->get('savedMapping')) {
204 $saveDetailsName = ts('Save this field mapping');
205 $this->applyFilter('saveMappingName', 'trim');
206 $this->add('text', 'saveMappingName', ts('Name'));
207 $this->add('text', 'saveMappingDesc', ts('Description'));
210 $savedMapping = $this->get('savedMapping');
212 list($mappingName, $mappingContactType, $mappingLocation, $mappingPhoneType, $mappingImProvider, $mappingRelation, $mappingOperator, $mappingValue, $mappingWebsiteType) = CRM_Core_BAO_Mapping
::getMappingFields($savedMapping, TRUE);
214 //get loaded Mapping Fields
215 $mappingName = CRM_Utils_Array
::value(1, $mappingName);
216 $mappingLocation = CRM_Utils_Array
::value(1, $mappingLocation);
217 $mappingPhoneType = CRM_Utils_Array
::value(1, $mappingPhoneType);
218 $mappingImProvider = CRM_Utils_Array
::value(1, $mappingImProvider);
219 $mappingRelation = CRM_Utils_Array
::value(1, $mappingRelation);
220 $mappingWebsiteType = CRM_Utils_Array
::value(1, $mappingWebsiteType);
222 $this->assign('loadedMapping', $savedMapping);
223 $this->set('loadedMapping', $savedMapping);
225 $params = array('id' => $savedMapping);
227 $mappingDetails = CRM_Core_BAO_Mapping
::retrieve($params, $temp);
229 $this->assign('savedName', $mappingDetails->name
);
231 $this->add('hidden', 'mappingId', $savedMapping);
233 $this->addElement('checkbox', 'updateMapping', ts('Update this field mapping'), NULL);
234 $saveDetailsName = ts('Save as a new field mapping');
235 $this->add('text', 'saveMappingName', ts('Name'));
236 $this->add('text', 'saveMappingDesc', ts('Description'));
239 $this->addElement('checkbox', 'saveMapping', $saveDetailsName, NULL, array('onclick' => "showSaveDetails(this)"));
241 $this->addFormRule(array('CRM_Contact_Import_Form_MapField', 'formRule'));
243 //-------- end of saved mapping stuff ---------
246 $mapperKeys = array_keys($this->_mapperFields
);
247 $hasColumnNames = !empty($this->_columnNames
);
248 $columnPatterns = $this->get('columnPatterns');
249 $dataPatterns = $this->get('dataPatterns');
250 $hasLocationTypes = $this->get('fieldTypes');
252 $this->_location_types
= array('Primary' => ts('Primary')) + CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Address', 'location_type_id');
253 $defaultLocationType = CRM_Core_BAO_LocationType
::getDefault();
255 // Pass default location to js
256 if ($defaultLocationType) {
257 $this->assign('defaultLocationType', $defaultLocationType->id
);
258 $this->assign('defaultLocationTypeLabel', $this->_location_types
[$defaultLocationType->id
]);
261 /* Initialize all field usages to false */
262 foreach ($mapperKeys as $key) {
263 $this->_fieldUsed
[$key] = FALSE;
266 $sel1 = $this->_mapperFields
;
269 $phoneTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Phone', 'phone_type_id');
270 $imProviders = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id');
271 $websiteTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Website', 'website_type_id');
273 foreach ($this->_location_types
as $key => $value) {
274 $sel3['phone'][$key] = &$phoneTypes;
275 //build array for IM service provider type for contact
276 $sel3['im'][$key] = &$imProviders;
281 // store and cache all relationship types
282 $contactRelation = new CRM_Contact_DAO_RelationshipType();
283 $contactRelation->find();
284 while ($contactRelation->fetch()) {
285 $contactRelationCache[$contactRelation->id
] = array();
286 $contactRelationCache[$contactRelation->id
]['contact_type_a'] = $contactRelation->contact_type_a
;
287 $contactRelationCache[$contactRelation->id
]['contact_sub_type_a'] = $contactRelation->contact_sub_type_a
;
288 $contactRelationCache[$contactRelation->id
]['contact_type_b'] = $contactRelation->contact_type_b
;
289 $contactRelationCache[$contactRelation->id
]['contact_sub_type_b'] = $contactRelation->contact_sub_type_b
;
291 $highlightedFields = $highlightedRelFields = array();
293 $highlightedFields['email'] = 'All';
294 $highlightedFields['external_identifier'] = 'All';
295 $highlightedFields['first_name'] = 'Individual';
296 $highlightedFields['last_name'] = 'Individual';
297 $highlightedFields['household_name'] = 'Household';
298 $highlightedFields['organization_name'] = 'Organization';
300 foreach ($mapperKeys as $key) {
301 // check if there is a _a_b or _b_a in the key
302 if (strpos($key, '_a_b') ||
strpos($key, '_b_a')) {
303 list($id, $first, $second) = explode('_', $key);
306 $id = $first = $second = NULL;
308 if (($first == 'a' && $second == 'b') ||
($first == 'b' && $second == 'a')) {
309 $cType = $contactRelationCache[$id]["contact_type_{$second}"];
311 //CRM-5125 for contact subtype specific relationshiptypes
313 if (!empty($contactRelationCache[$id]["contact_sub_type_{$second}"])) {
314 $cSubType = $contactRelationCache[$id]["contact_sub_type_{$second}"];
321 $relatedFields = CRM_Contact_BAO_Contact
::importableFields($cType);
322 unset($relatedFields['']);
324 foreach ($relatedFields as $name => $field) {
325 $values[$name] = $field['title'];
326 if (isset($hasLocationTypes[$name])) {
327 $sel3[$key][$name] = $this->_location_types
;
329 elseif ($name == 'url') {
330 $sel3[$key][$name] = $websiteTypes;
337 //fix to append custom group name to field name, CRM-2676
338 if (empty($this->_formattedFieldNames
[$cType]) ||
$cType == $this->_contactType
) {
339 $this->_formattedFieldNames
[$cType] = $this->formatCustomFieldName($values);
342 $this->_formattedFieldNames
[$cType] = array_merge($values, $this->_formattedFieldNames
[$cType]);
344 //Modified the Relationship fields if the fields are
345 //present in dedupe rule
346 if ($this->_onDuplicate
!= CRM_Import_Parser
::DUPLICATE_NOCHECK
&& !empty($this->_dedupeFields
[$cType]) &&
347 is_array($this->_dedupeFields
[$cType])
349 static $cTypeArray = array();
350 if ($cType != $this->_contactType
&& !in_array($cType, $cTypeArray)) {
351 foreach ($this->_dedupeFields
[$cType] as $val) {
352 if ($valTitle = CRM_Utils_Array
::value($val, $this->_formattedFieldNames
[$cType])) {
353 $this->_formattedFieldNames
[$cType][$val] = $valTitle . ' (match to contact)';
356 $cTypeArray[] = $cType;
360 foreach ($highlightedFields as $k => $v) {
361 if ($v == $cType ||
$v == 'All') {
362 $highlightedRelFields[$key][] = $k;
365 $this->assign('highlightedRelFields', $highlightedRelFields);
366 $sel2[$key] = $this->_formattedFieldNames
[$cType];
368 if (!empty($cSubType)) {
369 //custom fields for sub type
370 $subTypeFields = CRM_Core_BAO_CustomField
::getFieldsForImport($cSubType);
372 if (!empty($subTypeFields)) {
374 foreach ($subTypeFields as $customSubTypeField => $details) {
375 $subType[$customSubTypeField] = $details['title'];
376 $sel2[$key] = array_merge($sel2[$key], $this->formatCustomFieldName($subType));
381 foreach ($this->_location_types
as $k => $value) {
382 $sel4[$key]['phone'][$k] = &$phoneTypes;
383 //build array of IM service provider for related contact
384 $sel4[$key]['im'][$k] = &$imProviders;
389 if (!empty($hasLocationTypes[$key])) {
390 $options = $this->_location_types
;
392 elseif ($key == 'url') {
393 $options = $websiteTypes;
395 $sel2[$key] = $options;
399 $js = "<script type='text/javascript'>\n";
400 $formName = 'document.forms.' . $this->_name
;
401 //used to warn for mismatch column count or mismatch mapping
403 for ($i = 0; $i < $this->_columnCount
; $i++
) {
404 $sel = &$this->addElement('hierselect', "mapper[$i]", ts('Mapper for Field %1', array(1 => $i)), NULL);
406 if ($this->get('savedMapping')) {
407 if (isset($mappingName[$i])) {
408 if ($mappingName[$i] != ts('- do not import -')) {
410 if (isset($mappingRelation[$i])) {
411 // relationship mapping
412 switch ($this->get('contactType')) {
413 case CRM_Import_Parser
::CONTACT_INDIVIDUAL
:
414 $contactType = 'Individual';
417 case CRM_Import_Parser
::CONTACT_HOUSEHOLD
:
418 $contactType = 'Household';
421 case CRM_Import_Parser
::CONTACT_ORGANIZATION
:
422 $contactType = 'Organization';
425 $contactSubType = NULL;
426 if ($this->get('contactSubType')) {
427 $contactSubType = $this->get('contactSubType');
430 $relations = CRM_Contact_BAO_Relationship
::getContactRelationshipType(NULL, NULL, NULL, $contactType,
431 FALSE, 'label', TRUE, $contactSubType
434 foreach ($relations as $key => $var) {
435 if ($key == $mappingRelation[$i]) {
441 $contactDetails = strtolower(str_replace(" ", "_", $mappingName[$i]));
442 $websiteTypeId = isset($mappingWebsiteType[$i]) ?
$mappingWebsiteType[$i] : NULL;
443 $locationId = isset($mappingLocation[$i]) ?
$mappingLocation[$i] : 0;
444 $phoneType = isset($mappingPhoneType[$i]) ?
$mappingPhoneType[$i] : NULL;
445 //get provider id from saved mappings
446 $imProvider = isset($mappingImProvider[$i]) ?
$mappingImProvider[$i] : NULL;
448 if ($websiteTypeId) {
449 $defaults["mapper[$i]"] = array($relation, $contactDetails, $websiteTypeId);
450 if (!$websiteTypeId) {
451 $js .= "{$formName}['mapper[$i][2]'].style.display = 'none';\n";
455 // default for IM/phone when mapping with relation is true
457 if (isset($phoneType)) {
458 $typeId = $phoneType;
460 elseif (isset($imProvider)) {
461 $typeId = $imProvider;
463 $defaults["mapper[$i]"] = array($relation, $contactDetails, $locationId, $typeId);
465 $js .= "{$formName}['mapper[$i][2]'].style.display = 'none';\n";
468 // fix for edge cases, CRM-4954
469 if ($contactDetails == 'image_url') {
470 $contactDetails = str_replace('url', 'URL', $contactDetails);
473 if (!$contactDetails) {
474 $js .= "{$formName}['mapper[$i][1]'].style.display = 'none';\n";
477 if ((!$phoneType) && (!$imProvider)) {
478 $js .= "{$formName}['mapper[$i][3]'].style.display = 'none';\n";
480 //$js .= "{$formName}['mapper[$i][3]'].style.display = 'none';\n";
484 $mappingHeader = array_keys($this->_mapperFields
, $mappingName[$i]);
485 $websiteTypeId = isset($mappingWebsiteType[$i]) ?
$mappingWebsiteType[$i] : NULL;
486 $locationId = isset($mappingLocation[$i]) ?
$mappingLocation[$i] : 0;
487 $phoneType = isset($mappingPhoneType[$i]) ?
$mappingPhoneType[$i] : NULL;
488 // get IM service provider id
489 $imProvider = isset($mappingImProvider[$i]) ?
$mappingImProvider[$i] : NULL;
491 if ($websiteTypeId) {
492 if (!$websiteTypeId) {
493 $js .= "{$formName}['mapper[$i][1]'].style.display = 'none';\n";
495 $defaults["mapper[$i]"] = array($mappingHeader[0], $websiteTypeId);
499 $js .= "{$formName}['mapper[$i][1]'].style.display = 'none';\n";
501 //default for IM/phone without related contact
503 if (isset($phoneType)) {
504 $typeId = $phoneType;
506 elseif (isset($imProvider)) {
507 $typeId = $imProvider;
509 $defaults["mapper[$i]"] = array($mappingHeader[0], $locationId, $typeId);
512 if ((!$phoneType) && (!$imProvider)) {
513 $js .= "{$formName}['mapper[$i][2]'].style.display = 'none';\n";
516 $js .= "{$formName}['mapper[$i][3]'].style.display = 'none';\n";
522 $defaults["mapper[$i]"] = array();
525 for ($k = 1; $k < 4; $k++
) {
526 $js .= "{$formName}['mapper[$i][$k]'].style.display = 'none';\n";
531 // this load section to help mapping if we ran out of saved columns when doing Load Mapping
532 $js .= "swapOptions($formName, 'mapper[$i]', 0, 3, 'hs_mapper_0_');\n";
534 if ($hasColumnNames) {
535 $defaults["mapper[$i]"] = array($this->defaultFromColumnName($this->_columnNames
[$i], $columnPatterns));
538 $defaults["mapper[$i]"] = array($this->defaultFromData($dataPatterns, $i));
541 //end of load mapping
544 $js .= "swapOptions($formName, 'mapper[$i]', 0, 3, 'hs_mapper_0_');\n";
545 if ($hasColumnNames) {
546 // do array search first to see if has mapped key
548 $columnKey = array_search($this->_columnNames
[$i], $this->_mapperFields
);
549 if (isset($this->_fieldUsed
[$columnKey])) {
550 $defaults["mapper[$i]"] = $columnKey;
551 $this->_fieldUsed
[$key] = TRUE;
554 // Infer the default from the column names if we have them
555 $defaults["mapper[$i]"] = array(
556 $this->defaultFromColumnName($this->_columnNames
[$i],
564 // Otherwise guess the default from the form of the data
565 $defaults["mapper[$i]"] = array(
566 $this->defaultFromData($dataPatterns, $i),
567 // $defaultLocationType->id
572 $sel->setOptions(array($sel1, $sel2, $sel3, $sel4));
575 $js .= "</script>\n";
576 $this->assign('initHideBoxes', $js);
578 //set warning if mismatch in more than
579 if (isset($mappingName) &&
580 ($this->_columnCount
!= count($mappingName))
585 if ($warning != 0 && $this->get('savedMapping')) {
586 $session = CRM_Core_Session
::singleton();
587 $session->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.'));
590 $session = CRM_Core_Session
::singleton();
591 $session->setStatus(NULL);
594 $this->setDefaults($defaults);
596 $this->addButtons(array(
599 'name' => ts('Previous'),
603 'name' => ts('Continue'),
604 'spacing' => ' ',
609 'name' => ts('Cancel'),
616 * Global validation rules for the form.
618 * @param array $fields
619 * Posted values of the form.
622 * list of errors to be posted back to the form
624 public static function formRule($fields) {
626 if (!empty($fields['saveMapping'])) {
627 $nameField = CRM_Utils_Array
::value('saveMappingName', $fields);
628 if (empty($nameField)) {
629 $errors['saveMappingName'] = ts('Name is required to save Import Mapping');
632 $mappingTypeId = CRM_Core_PseudoConstant
::getKey('CRM_Core_BAO_Mapping', 'mapping_type_id', 'Import Contact');
633 if (CRM_Core_BAO_Mapping
::checkMapping($nameField, $mappingTypeId)) {
634 $errors['saveMappingName'] = ts('Duplicate Import Mapping Name');
638 $template = CRM_Core_Smarty
::singleton();
639 if (!empty($fields['saveMapping'])) {
640 $template->assign('isCheked', TRUE);
643 if (!empty($errors)) {
645 $assignError = new CRM_Core_Page();
646 $assignError->assign('mappingDetailsError', $_flag);
655 * Process the mapped fields and map it into the uploaded file.
657 public function postProcess() {
658 $params = $this->controller
->exportValues('MapField');
660 //reload the mapfield if load mapping is pressed
661 if (!empty($params['savedMapping'])) {
662 $this->set('savedMapping', $params['savedMapping']);
663 $this->controller
->resetPage($this->_name
);
666 $mapperKeys = $this->controller
->exportValue($this->_name
, 'mapper');
668 $parser = $this->submit($params, $mapperKeys);
670 // add all the necessary variables to the form
675 * Format custom field name.
677 * Combine group and field name to avoid conflict.
679 * @param array $fields
683 public function formatCustomFieldName(&$fields) {
684 //CRM-2676, replacing the conflict for same custom field name from different custom group.
685 $fieldIds = $formattedFieldNames = array();
686 foreach ($fields as $key => $value) {
687 if ($customFieldId = CRM_Core_BAO_CustomField
::getKeyID($key)) {
688 $fieldIds[] = $customFieldId;
692 if (!empty($fieldIds) && is_array($fieldIds)) {
693 $groupTitles = CRM_Core_BAO_CustomGroup
::getGroupTitles($fieldIds);
695 if (!empty($groupTitles)) {
696 foreach ($groupTitles as $fId => $values) {
697 $key = "custom_{$fId}";
698 $groupTitle = $values['groupTitle'];
699 $formattedFieldNames[$key] = $fields[$key] . ' :: ' . $groupTitle;
704 return $formattedFieldNames;
708 * Main submit function.
710 * Extracted to add testing & start refactoring.
715 * @return \CRM_Contact_Import_Parser_Contact
717 public function submit($params, $mapperKeys) {
718 $mapper = $mapperKeysMain = $locations = array();
719 $parserParameters = CRM_Contact_Import_Parser_Contact
::getParameterForParser($this->_columnCount
);
721 $phoneTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Phone', 'phone_type_id');
722 $imProviders = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id');
723 $websiteTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Website', 'website_type_id');
724 $locationTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Address', 'location_type_id');
725 $locationTypes['Primary'] = ts('Primary');
727 for ($i = 0; $i < $this->_columnCount
; $i++
) {
729 $fldName = CRM_Utils_Array
::value(0, $mapperKeys[$i]);
730 $selOne = CRM_Utils_Array
::value(1, $mapperKeys[$i]);
731 $selTwo = CRM_Utils_Array
::value(2, $mapperKeys[$i]);
732 $selThree = CRM_Utils_Array
::value(3, $mapperKeys[$i]);
733 $mapper[$i] = $this->_mapperFields
[$mapperKeys[$i][0]];
734 $mapperKeysMain[$i] = $fldName;
736 //need to differentiate non location elements.
737 if ($selOne && (is_numeric($selOne) ||
$selOne === 'Primary')) {
738 if ($fldName == 'url') {
739 $parserParameters['mapperWebsiteType'][$i] = $websiteTypes[$selOne];
742 $locations[$i] = $locationTypes[$selOne];
743 $parserParameters['mapperLocType'][$i] = $selOne;
744 if ($selTwo && is_numeric($selTwo)) {
745 if ($fldName == 'phone') {
746 $parserParameters['mapperPhoneType'][$i] = $phoneTypes[$selTwo];
748 elseif ($fldName == 'im') {
749 $parserParameters['mapperImProvider'][$i] = $imProviders[$selTwo];
755 //relationship contact mapper info.
756 list($id, $first, $second) = CRM_Utils_System
::explode('_', $fldName, 3);
757 if (($first == 'a' && $second == 'b') ||
758 ($first == 'b' && $second == 'a')
760 $parserParameters['mapperRelated'][$i] = $this->_mapperFields
[$fldName];
762 if ($selOne == 'url') {
763 $parserParameters['relatedContactWebsiteType'][$i] = $websiteTypes[$selTwo];
766 $parserParameters['relatedContactLocType'][$i] = CRM_Utils_Array
::value($selTwo, $locationTypes);
768 if ($selOne == 'phone') {
769 $parserParameters['relatedContactPhoneType'][$i] = $phoneTypes[$selThree];
771 elseif ($selOne == 'im') {
772 $parserParameters['relatedContactImProvider'][$i] = $imProviders[$selThree];
777 //get the related contact type.
778 $relationType = new CRM_Contact_DAO_RelationshipType();
779 $relationType->id
= $id;
780 $relationType->find(TRUE);
781 $parserParameters['relatedContactType'][$i] = $relationType->{"contact_type_$second"};
782 $parserParameters['relatedContactDetails'][$i] = $this->_formattedFieldNames
[$parserParameters['relatedContactType'][$i]][$selOne];
787 $this->set('columnNames', $this->_columnNames
);
788 $this->set('websites', $parserParameters['mapperWebsiteType']);
789 $this->set('locations', $locations);
790 $this->set('phones', $parserParameters['mapperPhoneType']);
791 $this->set('ims', $parserParameters['mapperImProvider']);
792 $this->set('related', $parserParameters['mapperRelated']);
793 $this->set('relatedContactType', $parserParameters['relatedContactType']);
794 $this->set('relatedContactDetails', $parserParameters['relatedContactDetails']);
795 $this->set('relatedContactLocType', $parserParameters['relatedContactLocType']);
796 $this->set('relatedContactPhoneType', $parserParameters['relatedContactPhoneType']);
797 $this->set('relatedContactImProvider', $parserParameters['relatedContactImProvider']);
798 $this->set('relatedContactWebsiteType', $parserParameters['relatedContactWebsiteType']);
799 $this->set('mapper', $mapper);
801 // store mapping Id to display it in the preview page
802 $this->set('loadMappingId', CRM_Utils_Array
::value('mappingId', $params));
804 //Updating Mapping Records
805 if (!empty($params['updateMapping'])) {
807 $mappingFields = new CRM_Core_DAO_MappingField();
808 $mappingFields->mapping_id
= $params['mappingId'];
809 $mappingFields->find();
811 $mappingFieldsId = array();
812 while ($mappingFields->fetch()) {
813 if ($mappingFields->id
) {
814 $mappingFieldsId[$mappingFields->column_number
] = $mappingFields->id
;
818 for ($i = 0; $i < $this->_columnCount
; $i++
) {
819 $updateMappingFields = new CRM_Core_DAO_MappingField();
820 $updateMappingFields->id
= CRM_Utils_Array
::value($i, $mappingFieldsId);
821 $updateMappingFields->mapping_id
= $params['mappingId'];
822 $updateMappingFields->column_number
= $i;
824 $mapperKeyParts = explode('_', $mapperKeys[$i][0], 3);
825 $id = isset($mapperKeyParts[0]) ?
$mapperKeyParts[0] : NULL;
826 $first = isset($mapperKeyParts[1]) ?
$mapperKeyParts[1] : NULL;
827 $second = isset($mapperKeyParts[2]) ?
$mapperKeyParts[2] : NULL;
828 if (($first == 'a' && $second == 'b') ||
($first == 'b' && $second == 'a')) {
829 $updateMappingFields->relationship_type_id
= $id;
830 $updateMappingFields->relationship_direction
= "{$first}_{$second}";
831 $updateMappingFields->name
= ucwords(str_replace("_", " ", $mapperKeys[$i][1]));
832 // get phoneType id and provider id separately
833 // before updating mappingFields of phone and IM for related contact, CRM-3140
834 if (CRM_Utils_Array
::value('1', $mapperKeys[$i]) == 'url') {
835 $updateMappingFields->website_type_id
= isset($mapperKeys[$i][2]) ?
$mapperKeys[$i][2] : NULL;
838 if (CRM_Utils_Array
::value('1', $mapperKeys[$i]) == 'phone') {
839 $updateMappingFields->phone_type_id
= isset($mapperKeys[$i][3]) ?
$mapperKeys[$i][3] : NULL;
841 elseif (CRM_Utils_Array
::value('1', $mapperKeys[$i]) == 'im') {
842 $updateMappingFields->im_provider_id
= isset($mapperKeys[$i][3]) ?
$mapperKeys[$i][3] : NULL;
844 $updateMappingFields->location_type_id
= isset($mapperKeys[$i][2]) ?
$mapperKeys[$i][2] : NULL;
848 $updateMappingFields->name
= $mapper[$i];
849 $updateMappingFields->relationship_type_id
= 'NULL';
850 $updateMappingFields->relationship_type_direction
= 'NULL';
851 // to store phoneType id and provider id separately
852 // before updating mappingFields for phone and IM, CRM-3140
853 if (CRM_Utils_Array
::value('0', $mapperKeys[$i]) == 'url') {
854 $updateMappingFields->website_type_id
= isset($mapperKeys[$i][1]) ?
$mapperKeys[$i][1] : NULL;
857 if (CRM_Utils_Array
::value('0', $mapperKeys[$i]) == 'phone') {
858 $updateMappingFields->phone_type_id
= isset($mapperKeys[$i][2]) ?
$mapperKeys[$i][2] : NULL;
860 elseif (CRM_Utils_Array
::value('0', $mapperKeys[$i]) == 'im') {
861 $updateMappingFields->im_provider_id
= isset($mapperKeys[$i][2]) ?
$mapperKeys[$i][2] : NULL;
863 $locationTypeID = $parserParameters['mapperLocType'][$i];
864 // location_type_id is NULL for non-location fields, and for Primary location.
865 $updateMappingFields->location_type_id
= is_numeric($locationTypeID) ?
$locationTypeID : 'null';
868 $updateMappingFields->save();
872 //Saving Mapping Details and Records
873 if (!empty($params['saveMapping'])) {
874 $mappingParams = array(
875 'name' => $params['saveMappingName'],
876 'description' => $params['saveMappingDesc'],
877 'mapping_type_id' => 'Import Contact',
880 $saveMapping = civicrm_api3('Mapping', 'create', $mappingParams);
882 $contactType = $this->get('contactType');
883 switch ($contactType) {
884 case CRM_Import_Parser
::CONTACT_INDIVIDUAL
:
885 $cType = 'Individual';
888 case CRM_Import_Parser
::CONTACT_HOUSEHOLD
:
889 $cType = 'Household';
892 case CRM_Import_Parser
::CONTACT_ORGANIZATION
:
893 $cType = 'Organization';
896 for ($i = 0; $i < $this->_columnCount
; $i++
) {
897 $saveMappingFields = new CRM_Core_DAO_MappingField();
898 $saveMappingFields->mapping_id
= $saveMapping['id'];
899 $saveMappingFields->contact_type
= $cType;
900 $saveMappingFields->column_number
= $i;
902 $mapperKeyParts = explode('_', $mapperKeys[$i][0], 3);
903 $id = isset($mapperKeyParts[0]) ?
$mapperKeyParts[0] : NULL;
904 $first = isset($mapperKeyParts[1]) ?
$mapperKeyParts[1] : NULL;
905 $second = isset($mapperKeyParts[2]) ?
$mapperKeyParts[2] : NULL;
906 if (($first == 'a' && $second == 'b') ||
($first == 'b' && $second == 'a')) {
907 $saveMappingFields->name
= ucwords(str_replace("_", " ", $mapperKeys[$i][1]));
908 $saveMappingFields->relationship_type_id
= $id;
909 $saveMappingFields->relationship_direction
= "{$first}_{$second}";
910 // to get phoneType id and provider id separately
911 // before saving mappingFields of phone and IM for related contact, CRM-3140
912 if (CRM_Utils_Array
::value('1', $mapperKeys[$i]) == 'url') {
913 $saveMappingFields->website_type_id
= isset($mapperKeys[$i][2]) ?
$mapperKeys[$i][2] : NULL;
916 if (CRM_Utils_Array
::value('1', $mapperKeys[$i]) == 'phone') {
917 $saveMappingFields->phone_type_id
= isset($mapperKeys[$i][3]) ?
$mapperKeys[$i][3] : NULL;
919 elseif (CRM_Utils_Array
::value('1', $mapperKeys[$i]) == 'im') {
920 $saveMappingFields->im_provider_id
= isset($mapperKeys[$i][3]) ?
$mapperKeys[$i][3] : NULL;
922 $saveMappingFields->location_type_id
= (isset($mapperKeys[$i][2]) && $mapperKeys[$i][2] !== 'Primary') ?
$mapperKeys[$i][2] : NULL;
926 $saveMappingFields->name
= $mapper[$i];
927 $locationTypeID = $parserParameters['mapperLocType'][$i];
928 // to get phoneType id and provider id separately
929 // before saving mappingFields of phone and IM, CRM-3140
930 if (CRM_Utils_Array
::value('0', $mapperKeys[$i]) == 'url') {
931 $saveMappingFields->website_type_id
= isset($mapperKeys[$i][1]) ?
$mapperKeys[$i][1] : NULL;
934 if (CRM_Utils_Array
::value('0', $mapperKeys[$i]) == 'phone') {
935 $saveMappingFields->phone_type_id
= isset($mapperKeys[$i][2]) ?
$mapperKeys[$i][2] : NULL;
937 elseif (CRM_Utils_Array
::value('0', $mapperKeys[$i]) == 'im') {
938 $saveMappingFields->im_provider_id
= isset($mapperKeys[$i][2]) ?
$mapperKeys[$i][2] : NULL;
940 $saveMappingFields->location_type_id
= is_numeric($locationTypeID) ?
$locationTypeID : NULL;
942 $saveMappingFields->relationship_type_id
= NULL;
944 $saveMappingFields->save();
946 $this->set('savedMapping', $saveMappingFields->mapping_id
);
949 $parser = new CRM_Contact_Import_Parser_Contact($mapperKeysMain, $parserParameters['mapperLocType'], $parserParameters['mapperPhoneType'],
950 $parserParameters['mapperImProvider'], $parserParameters['mapperRelated'], $parserParameters['relatedContactType'],
951 $parserParameters['relatedContactDetails'], $parserParameters['relatedContactLocType'],
952 $parserParameters['relatedContactPhoneType'], $parserParameters['relatedContactImProvider'],
953 $parserParameters['mapperWebsiteType'], $parserParameters['relatedContactWebsiteType']
956 $primaryKeyName = $this->get('primaryKeyName');
957 $statusFieldName = $this->get('statusFieldName');
958 $parser->run($this->_importTableName
,
960 CRM_Import_Parser
::MODE_PREVIEW
,
961 $this->get('contactType'),
966 CRM_Contact_Import_Parser
::DEFAULT_TIMEOUT
,
967 $this->get('contactSubType'),