Update calls to class constants CRM-11254
[civicrm-core.git] / CRM / Contribute / Import / Form / MapField.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.3 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2013 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
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. |
13 | |
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. |
18 | |
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 +--------------------------------------------------------------------+
26*/
27
28/**
29 *
30 * @package CRM
31 * @copyright CiviCRM LLC (c) 2004-2013
32 * $Id$
33 *
34 */
35
36/**
37 * This class gets the name of the file to upload
38 */
39class CRM_Contribute_Import_Form_MapField extends CRM_Core_Form {
40
41 /**
42 * cache of preview data values
43 *
44 * @var array
45 * @access protected
46 */
47 protected $_dataValues;
48
49 /**
50 * mapper fields
51 *
52 * @var array
53 * @access protected
54 */
55 protected $_mapperFields;
56
57 /**
58 * loaded mapping ID
59 *
60 * @var int
61 * @access protected
62 */
63 protected $_loadedMappingId;
64
65 /**
66 * number of columns in import file
67 *
68 * @var int
69 * @access protected
70 */
71 protected $_columnCount;
72
73 /**
74 * column headers, if we have them
75 *
76 * @var array
77 * @access protected
78 */
79 protected $_columnHeaders;
80
81 /**
82 * an array of booleans to keep track of whether a field has been used in
83 * form building already.
84 *
85 * @var array
86 * @access protected
87 */
88 protected $_fieldUsed;
89
90 /**
91 * Attempt to match header labels with our mapper fields
92 *
93 * @param header
94 * @param mapperFields
95 *
96 * @return string
97 * @access public
98 */
99 public function defaultFromHeader($header, &$patterns) {
100 foreach ($patterns as $key => $re) {
101 // Skip empty key/patterns
102 if (!$key || !$re || strlen("$re") < 5) {
103 continue;
104 }
105
106 // Scan through the headerPatterns defined in the schema for a match
107 if (preg_match($re, $header)) {
108 $this->_fieldUsed[$key] = TRUE;
109 return $key;
110 }
111 }
112 return '';
113 }
114
115 /**
116 * Guess at the field names given the data and patterns from the schema
117 *
118 * @param patterns
119 * @param index
120 *
121 * @return string
122 * @access public
123 */
124 public function defaultFromData(&$patterns, $index) {
125 $best = '';
126 $bestHits = 0;
127 $n = count($this->_dataValues);
128
129 foreach ($patterns as $key => $re) {
130 // Skip empty key/patterns
131 if (!$key || !$re || strlen("$re") < 5) {
132 continue;
133 }
134
135 /* Take a vote over the preview data set */
136
137 $hits = 0;
138 for ($i = 0; $i < $n; $i++) {
139 if (preg_match($re, $this->_dataValues[$i][$index])) {
140 $hits++;
141 }
142 }
143
144 if ($hits > $bestHits) {
145 $bestHits = $hits;
146 $best = $key;
147 }
148 }
149
150 if ($best != '') {
151 $this->_fieldUsed[$best] = TRUE;
152 }
153 return $best;
154 }
155
156 /**
157 * Function to set variables up before form is built
158 *
159 * @return void
160 * @access public
161 */
162 public function preProcess() {
163 $this->_mapperFields = $this->get('fields');
164 asort($this->_mapperFields);
165
166 $this->_columnCount = $this->get('columnCount');
167 $this->assign('columnCount', $this->_columnCount);
168 $this->_dataValues = $this->get('dataValues');
169 $this->assign('dataValues', $this->_dataValues);
170
171 $skipColumnHeader = $this->controller->exportValue('UploadFile', 'skipColumnHeader');
172 $this->_onDuplicate = $this->get('onDuplicate', isset($onDuplicate) ? $onDuplicate : "");
173
174 if ($skipColumnHeader) {
175 $this->assign('skipColumnHeader', $skipColumnHeader);
176 $this->assign('rowDisplayCount', 3);
177 /* if we had a column header to skip, stash it for later */
178
179 $this->_columnHeaders = $this->_dataValues[0];
180 }
181 else {
182 $this->assign('rowDisplayCount', 2);
183 }
184 $highlightedFields = array();
185 $highlightedFields[] = 'financial_type';
186 //CRM-2219 removing other required fields since for updation only
187 //invoice id or trxn id or contribution id is required.
a05662ef 188 if ($this->_onDuplicate == CRM_Import_Parser::DUPLICATE_UPDATE) {
6a488035
TO
189 $remove = array('contribution_contact_id', 'email', 'first_name', 'last_name', 'external_identifier');
190 foreach ($remove as $value) {
191 unset($this->_mapperFields[$value]);
192 }
193
194 //modify field title only for update mode. CRM-3245
195 foreach (array(
196 'contribution_id', 'invoice_id', 'trxn_id') as $key) {
197 $this->_mapperFields[$key] .= ' (match to contribution record)';
198 $highlightedFields[] = $key;
199 }
200 }
a05662ef 201 elseif ($this->_onDuplicate == CRM_Import_Parser::DUPLICATE_SKIP) {
6a488035
TO
202 unset($this->_mapperFields['contribution_id']);
203 $highlightedFieldsArray = array('contribution_contact_id', 'email', 'first_name', 'last_name', 'external_identifier', 'total_amount');
204 foreach ($highlightedFieldsArray as $name) {
205 $highlightedFields[] = $name;
206 }
207 }
208
209 // modify field title for contribution status
210 $this->_mapperFields['contribution_status_id'] = ts('Contribution Status');
211
212 $this->assign('highlightedFields', $highlightedFields);
213 }
214
215 /**
216 * Function to actually build the form
217 *
218 * @return void
219 * @access public
220 */
221 public function buildQuickForm() {
222 //to save the current mappings
223 if (!$this->get('savedMapping')) {
224 $saveDetailsName = ts('Save this field mapping');
225 $this->applyFilter('saveMappingName', 'trim');
226 $this->add('text', 'saveMappingName', ts('Name'));
227 $this->add('text', 'saveMappingDesc', ts('Description'));
228 }
229 else {
230 $savedMapping = $this->get('savedMapping');
231
232 list($mappingName, $mappingContactType, $mappingLocation, $mappingPhoneType, $mappingRelation) = CRM_Core_BAO_Mapping::getMappingFields($savedMapping);
233
234 $mappingName = $mappingName[1];
235 $mappingContactType = $mappingContactType[1];
236 $mappingLocation = CRM_Utils_Array::value('1', CRM_Utils_Array::value(1, $mappingLocation));
237 $mappingPhoneType = CRM_Utils_Array::value('1', CRM_Utils_Array::value(1, $mappingPhoneType));
238 $mappingRelation = CRM_Utils_Array::value('1', CRM_Utils_Array::value(1, $mappingRelation));
239
240 //mapping is to be loaded from database
241
242 $params = array('id' => $savedMapping);
243 $temp = array();
244 $mappingDetails = CRM_Core_BAO_Mapping::retrieve($params, $temp);
245
246 $this->assign('loadedMapping', $mappingDetails->name);
247 $this->set('loadedMapping', $savedMapping);
248
249 $getMappingName = new CRM_Core_DAO_Mapping();
250 $getMappingName->id = $savedMapping;
251 $getMappingName->mapping_type = 'Import Contributions';
252 $getMappingName->find();
253 while ($getMappingName->fetch()) {
254 $mapperName = $getMappingName->name;
255 }
256
257 $this->assign('savedName', $mapperName);
258
259 $this->add('hidden', 'mappingId', $savedMapping);
260
261 $this->addElement('checkbox', 'updateMapping', ts('Update this field mapping'), NULL);
262 $saveDetailsName = ts('Save as a new field mapping');
263 $this->add('text', 'saveMappingName', ts('Name'));
264 $this->add('text', 'saveMappingDesc', ts('Description'));
265 }
266
267 $this->addElement('checkbox', 'saveMapping', $saveDetailsName, NULL, array('onclick' => "showSaveDetails(this)"));
268
269 $this->addFormRule(array('CRM_Contribute_Import_Form_MapField', 'formRule'), $this);
270
271 //-------- end of saved mapping stuff ---------
272
273 $defaults = array();
274 $mapperKeys = array_keys($this->_mapperFields);
275 $hasHeaders = !empty($this->_columnHeaders);
276 $headerPatterns = $this->get('headerPatterns');
277 $dataPatterns = $this->get('dataPatterns');
278 $hasLocationTypes = $this->get('fieldTypes');
279
280
281 /* Initialize all field usages to false */
282
283 foreach ($mapperKeys as $key) {
284 $this->_fieldUsed[$key] = FALSE;
285 }
b2b0530a 286 $this->_location_types = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Address', 'location_type_id');
6a488035
TO
287 $sel1 = $this->_mapperFields;
288
289 if (!$this->get('onDuplicate')) {
290 unset($sel1['id']);
291 unset($sel1['contribution_id']);
292 }
293
294 // start of soft credit section
295 // get contact type for this import
296 $contactTypeId = $this->get('contactType');
297 $contactTypes = array(
a05662ef
CW
298 CRM_Import_Parser::CONTACT_INDIVIDUAL => 'Individual',
299 CRM_Import_Parser::CONTACT_HOUSEHOLD => 'Household',
300 CRM_Import_Parser::CONTACT_ORGANIZATION => 'Organization',
6a488035
TO
301 );
302
303 $contactType = $contactTypes[$contactTypeId];
304
305 // get imporatable fields for contact type
306 $contactFields = CRM_Contact_BAO_Contact::importableFields($contactType, NULL);
307
308 // get the Dedupe rule for this contact type and build soft credit array
309 $ruleParams = array(
310 'contact_type' => $contactType,
311 'used' => 'Unsupervised',
312 );
313 $fieldsArray = CRM_Dedupe_BAO_Rule::dedupeRuleFields($ruleParams);
314 $softCreditFields = array();
315 if (is_array($fieldsArray)) {
316 foreach ($fieldsArray as $value) {
317 //skip if there is no dupe rule
318 if ($value == 'none') {
319 continue;
320 }
321 $softCreditFields[$value] = $contactFields[trim($value)]['title'];
322 }
323 }
324
325 $softCreditFields['contact_id'] = ts('Contact ID');
326 $softCreditFields['external_identifier'] = ts('External Identifier');
327
328 $sel2['soft_credit'] = $softCreditFields;
329
330 // end of soft credit section
331
332 $js = "<script type='text/javascript'>\n";
333 $formName = 'document.forms.' . $this->_name;
334
335 //used to warn for mismatch column count or mismatch mapping
336 $warning = 0;
337
338 for ($i = 0; $i < $this->_columnCount; $i++) {
339 $sel = &$this->addElement('hierselect', "mapper[$i]", ts('Mapper for Field %1', array(1 => $i)), NULL);
340 $jsSet = FALSE;
341 if ($this->get('savedMapping')) {
342 if (isset($mappingName[$i])) {
343 if ($mappingName[$i] != ts('- do not import -')) {
344
345 $mappingHeader = array_keys($this->_mapperFields, $mappingName[$i]);
346 // reusing contact_type field array for soft credit
347 $softField = isset($mappingContactType[$i]) ? $mappingContactType[$i] : 0;
348
349 if (!$softField) {
350 $js .= "{$formName}['mapper[$i][1]'].style.display = 'none';\n";
351 }
352
353 $js .= "{$formName}['mapper[$i][2]'].style.display = 'none';\n";
354 $js .= "{$formName}['mapper[$i][3]'].style.display = 'none';\n";
355 $defaults["mapper[$i]"] = array(
356 $mappingHeader[0],
357 ($softField) ? $softField : "",
358 (isset($locationId)) ? $locationId : "",
359 (isset($phoneType)) ? $phoneType : "",
360 );
361 $jsSet = TRUE;
362 }
363 else {
364 $defaults["mapper[$i]"] = array();
365 }
366 if (!$jsSet) {
367 for ($k = 1; $k < 4; $k++) {
368 $js .= "{$formName}['mapper[$i][$k]'].style.display = 'none';\n";
369 }
370 }
371 }
372 else {
373 // this load section to help mapping if we ran out of saved columns when doing Load Mapping
374 $js .= "swapOptions($formName, 'mapper[$i]', 0, 3, 'hs_mapper_" . $i . "_');\n";
375
376 if ($hasHeaders) {
377 $defaults["mapper[$i]"] = array($this->defaultFromHeader($this->_columnHeaders[$i], $headerPatterns));
378 }
379 else {
380 $defaults["mapper[$i]"] = array($this->defaultFromData($dataPatterns, $i));
381 }
382 }
383 //end of load mapping
384 }
385 else {
386 $js .= "swapOptions($formName, 'mapper[$i]', 0, 3, 'hs_mapper_" . $i . "_');\n";
387 if ($hasHeaders) {
388 // Infer the default from the skipped headers if we have them
389 $defaults["mapper[$i]"] = array(
390 $this->defaultFromHeader(CRM_Utils_Array::value($i, $this->_columnHeaders),
391 $headerPatterns
392 ),
393 // $defaultLocationType->id
394 0,
395 );
396 }
397 else {
398 // Otherwise guess the default from the form of the data
399 $defaults["mapper[$i]"] = array(
400 $this->defaultFromData($dataPatterns, $i),
401 // $defaultLocationType->id
402 0,
403 );
404 }
405 }
406 $sel->setOptions(array($sel1, $sel2, (isset($sel3)) ? $sel3 : "", (isset($sel4)) ? $sel4 : ""));
407 }
408 $js .= "</script>\n";
409 $this->assign('initHideBoxes', $js);
410
411 //set warning if mismatch in more than
412 if (isset($mappingName)) {
413 if (($this->_columnCount != count($mappingName))) {
414 $warning++;
415 }
416 }
417 if ($warning != 0 && $this->get('savedMapping')) {
418 $session = CRM_Core_Session::singleton();
419 $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.'));
420 }
421 else {
422 $session = CRM_Core_Session::singleton();
423 $session->setStatus(NULL);
424 }
425
426 $this->setDefaults($defaults);
427
428 $this->addButtons(array(
429 array(
430 'type' => 'back',
431 'name' => ts('<< Previous'),
432 ),
433 array(
434 'type' => 'next',
435 'name' => ts('Continue >>'),
436 'spacing' => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',
437 'isDefault' => TRUE,
438 ),
439 array(
440 'type' => 'cancel',
441 'name' => ts('Cancel'),
442 ),
443 )
444 );
445 }
446
447 /**
448 * global validation rules for the form
449 *
450 * @param array $fields posted values of the form
451 *
452 * @return array list of errors to be posted back to the form
453 * @static
454 * @access public
455 */
456 static function formRule($fields, $files, $self) {
457 $errors = array();
458 $fieldMessage = NULL;
459
460 if (!array_key_exists('savedMapping', $fields)) {
461 $importKeys = array();
462 foreach ($fields['mapper'] as $mapperPart) {
463 $importKeys[] = $mapperPart[0];
464 }
465
466 $contactTypeId = $self->get('contactType');
467 $contactTypes = array(
a05662ef
CW
468 CRM_Import_Parser::CONTACT_INDIVIDUAL => 'Individual',
469 CRM_Import_Parser::CONTACT_HOUSEHOLD => 'Household',
470 CRM_Import_Parser::CONTACT_ORGANIZATION => 'Organization',
6a488035
TO
471 );
472 $params = array(
473 'used' => 'Unsupervised',
474 'contact_type' => $contactTypes[$contactTypeId],
475 );
476 list($ruleFields, $threshold) = CRM_Dedupe_BAO_RuleGroup::dedupeRuleFieldsWeight($params);
477 $weightSum = 0;
478 foreach ($importKeys as $key => $val) {
479 if (array_key_exists($val, $ruleFields)) {
480 $weightSum += $ruleFields[$val];
481 }
482 }
483 foreach ($ruleFields as $field => $weight) {
484 $fieldMessage .= ' ' . $field . '(weight ' . $weight . ')';
485 }
486
487 // FIXME: should use the schema titles, not redeclare them
488 $requiredFields = array(
489 'contribution_contact_id' => ts('Contact ID'),
490 'total_amount' => ts('Total Amount'),
491 'financial_type' => ts('Financial Type')
492 );
493
494 foreach ($requiredFields as $field => $title) {
495 if (!in_array($field, $importKeys)) {
496 if ($field == 'contribution_contact_id') {
497 if (!($weightSum >= $threshold || in_array('external_identifier', $importKeys)) &&
a05662ef 498 $self->_onDuplicate != CRM_Import_Parser::DUPLICATE_UPDATE
6a488035
TO
499 ) {
500 $errors['_qf_default'] .= ts('Missing required contact matching fields.') . " $fieldMessage " . ts('(Sum of all weights should be greater than or equal to threshold: %1).', array(
501 1 => $threshold)) . '<br />';
502 }
a05662ef 503 elseif ($self->_onDuplicate == CRM_Import_Parser::DUPLICATE_UPDATE &&
6a488035
TO
504 !(in_array('invoice_id', $importKeys) || in_array('trxn_id', $importKeys) ||
505 in_array('contribution_id', $importKeys)
506 )
507 ) {
508 $errors['_qf_default'] .= ts('Invoice ID or Transaction ID or Contribution ID are required to match to the existing contribution records in Update mode.') . '<br />';
509 }
510 }
511 else {
a05662ef 512 if ($self->_onDuplicate != CRM_Import_Parser::DUPLICATE_UPDATE) {
6a488035
TO
513 $errors['_qf_default'] .= ts('Missing required field: %1', array(
514 1 => $title)) . '<br />';
515 }
516 }
517 }
518 }
519
520 //at least one field should be mapped during update.
a05662ef 521 if ($self->_onDuplicate == CRM_Import_Parser::DUPLICATE_UPDATE) {
6a488035
TO
522 $atleastOne = FALSE;
523 foreach ($self->_mapperFields as $key => $field) {
524 if (in_array($key, $importKeys) &&
525 !in_array($key, array('doNotImport', 'contribution_id', 'invoice_id', 'trxn_id'))
526 ) {
527 $atleastOne = TRUE;
528 break;
529 }
530 }
531 if (!$atleastOne) {
532 $errors['_qf_default'] .= ts('At least one contribution field needs to be mapped for update during update mode.') . '<br />';
533 }
534 }
535 }
536
537 if (CRM_Utils_Array::value('saveMapping', $fields)) {
538 $nameField = CRM_Utils_Array::value('saveMappingName', $fields);
539 if (empty($nameField)) {
540 $errors['saveMappingName'] = ts('Name is required to save Import Mapping');
541 }
542 else {
543 $mappingTypeId = CRM_Core_OptionGroup::getValue('mapping_type', 'Import Contribution', 'name');
544 if (CRM_Core_BAO_Mapping::checkMapping($nameField, $mappingTypeId)) {
545 $errors['saveMappingName'] = ts('Duplicate Import Contribution Mapping Name');
546 }
547 }
548 }
549
550 if (!empty($errors)) {
551 if (!empty($errors['saveMappingName'])) {
552 $_flag = 1;
553 $assignError = new CRM_Core_Page();
554 $assignError->assign('mappingDetailsError', $_flag);
555 }
556 return $errors;
557 }
558
559 return TRUE;
560 }
561
562 /**
563 * Process the mapped fields and map it into the uploaded file
564 * preview the file and extract some summary statistics
565 *
566 * @return void
567 * @access public
568 */
569 public function postProcess() {
570 $params = $this->controller->exportValues('MapField');
571
572 //reload the mapfield if load mapping is pressed
573 if (!empty($params['savedMapping'])) {
574 $this->set('savedMapping', $params['savedMapping']);
575 $this->controller->resetPage($this->_name);
576 return;
577 }
578
579 $fileName = $this->controller->exportValue('UploadFile', 'uploadFile');
580 $skipColumnHeader = $this->controller->exportValue('UploadFile', 'skipColumnHeader');
581
582 $config = CRM_Core_Config::singleton();
583 $seperator = $config->fieldSeparator;
584
585 $mapper = $mapperKeys = $mapperKeysMain = $mapperSoftCredit = $softCreditFields = $mapperPhoneType = array();
586 $mapperKeys = $this->controller->exportValue($this->_name, 'mapper');
587
588 for ($i = 0; $i < $this->_columnCount; $i++) {
589 $mapper[$i] = $this->_mapperFields[$mapperKeys[$i][0]];
590 $mapperKeysMain[$i] = $mapperKeys[$i][0];
591
592 if (isset($mapperKeys[$i][0]) && $mapperKeys[$i][0] == 'soft_credit') {
593 $mapperSoftCredit[$i] = $mapperKeys[$i][1];
594 list($first, $second) = explode('_', $mapperSoftCredit[$i]);
595 $softCreditFields[$i] = ucwords($first . " " . $second);
596 }
597 else {
598 $mapperSoftCredit[$i] = $softCreditFields[$i] = NULL;
599 $softCreditFields[$i] = NULL;
600 }
601 }
602
603 $this->set('mapper', $mapper);
604 $this->set('softCreditFields', $softCreditFields);
605
606 // store mapping Id to display it in the preview page
607 $this->set('loadMappingId', CRM_Utils_Array::value('mappingId', $params));
608
609 //Updating Mapping Records
610 if (CRM_Utils_Array::value('updateMapping', $params)) {
611 $mappingFields = new CRM_Core_DAO_MappingField();
612 $mappingFields->mapping_id = $params['mappingId'];
613 $mappingFields->find();
614
615 $mappingFieldsId = array();
616 while ($mappingFields->fetch()) {
617 if ($mappingFields->id) {
618 $mappingFieldsId[$mappingFields->column_number] = $mappingFields->id;
619 }
620 }
621
622 for ($i = 0; $i < $this->_columnCount; $i++) {
623 $updateMappingFields = new CRM_Core_DAO_MappingField();
624 $updateMappingFields->id = $mappingFieldsId[$i];
625 $updateMappingFields->mapping_id = $params['mappingId'];
626 $updateMappingFields->column_number = $i;
627 $updateMappingFields->name = $mapper[$i];
628
629 //reuse contact_type field in db to store fields associated with soft credit
630 $updateMappingFields->contact_type = isset($mapperSoftCredit[$i]) ? $mapperSoftCredit[$i] : NULL;
631 $updateMappingFields->save();
632 }
633 }
634
635 //Saving Mapping Details and Records
636 if (CRM_Utils_Array::value('saveMapping', $params)) {
637 $mappingParams = array(
638 'name' => $params['saveMappingName'],
639 'description' => $params['saveMappingDesc'],
640 'mapping_type_id' => CRM_Core_OptionGroup::getValue('mapping_type',
641 'Import Contribution',
642 'name'
643 ),
644 );
645 $saveMapping = CRM_Core_BAO_Mapping::add($mappingParams);
646
647 for ($i = 0; $i < $this->_columnCount; $i++) {
648 $saveMappingFields = new CRM_Core_DAO_MappingField();
649 $saveMappingFields->mapping_id = $saveMapping->id;
650 $saveMappingFields->column_number = $i;
651 $saveMappingFields->name = $mapper[$i];
652
653 //reuse contact_type field in db to store fields associated with soft credit
654 $saveMappingFields->contact_type = isset($mapperSoftCredit[$i]) ? $mapperSoftCredit[$i] : NULL;
655 $saveMappingFields->save();
656 }
657 $this->set('savedMapping', $saveMappingFields->mapping_id);
658 }
659
660 $parser = new CRM_Contribute_Import_Parser_Contribution($mapperKeysMain, $mapperSoftCredit, $mapperPhoneType);
661 $parser->run($fileName, $seperator, $mapper, $skipColumnHeader,
a05662ef 662 CRM_Import_Parser::MODE_PREVIEW, $this->get('contactType')
6a488035
TO
663 );
664
665 // add all the necessary variables to the form
666 $parser->set($this);
667 }
668
669 /**
670 * Return a descriptive name for the page, used in wizard header
671 *
672 * @return string
673 * @access public
674 */
675 public function getTitle() {
676 return ts('Match Fields');
677 }
678}
679