INFRA-132 - CRM/Case - Convert single-line @param to multi-line
[civicrm-core.git] / CRM / Contact / Import / Form / Preview.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
39de6fd5 4 | CiviCRM version 4.6 |
6a488035 5 +--------------------------------------------------------------------+
06b69b18 6 | Copyright CiviCRM LLC (c) 2004-2014 |
6a488035
TO
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
06b69b18 31 * @copyright CiviCRM LLC (c) 2004-2014
6a488035
TO
32 * $Id$
33 *
34 */
35
36/**
37 * This class previews the uploaded file and returns summary
38 * statistics
39 */
f532671f 40class CRM_Contact_Import_Form_Preview extends CRM_Import_Form_Preview {
6a488035
TO
41
42 /**
100fef9d 43 * Set variables up before form is built
6a488035
TO
44 *
45 * @return void
6a488035
TO
46 */
47 public function preProcess() {
48 //get the data from the session
49 $dataValues = $this->get('dataValues');
50 $mapper = $this->get('mapper');
51 $invalidRowCount = $this->get('invalidRowCount');
52 $conflictRowCount = $this->get('conflictRowCount');
53 $mismatchCount = $this->get('unMatchCount');
54 $columnNames = $this->get('columnNames');
55
56 //assign column names
57 $this->assign('columnNames', $columnNames);
58
59 //get the mapping name displayed if the mappingId is set
60 $mappingId = $this->get('loadMappingId');
61 if ($mappingId) {
62 $mapDAO = new CRM_Core_DAO_Mapping();
63 $mapDAO->id = $mappingId;
64 $mapDAO->find(TRUE);
65 $this->assign('loadedMapping', $mappingId);
66 $this->assign('savedName', $mapDAO->name);
67 }
68
69 $this->assign('rowDisplayCount', 2);
70
24431f7b 71 $groups = CRM_Core_PseudoConstant::nestedGroup();
6a488035
TO
72 $this->set('groups', $groups);
73
cd43c5e3 74 $tag = CRM_Core_PseudoConstant::get('CRM_Core_DAO_EntityTag', 'tag_id', array('onlyActive' => FALSE));
6a488035
TO
75 if ($tag) {
76 $this->set('tag', $tag);
77 }
78
79 if ($invalidRowCount) {
a05662ef 80 $urlParams = 'type=' . CRM_Import_Parser::ERROR . '&parser=CRM_Contact_Import_Parser';
6a488035
TO
81 $this->set('downloadErrorRecordsUrl', CRM_Utils_System::url('civicrm/export', $urlParams));
82 }
83
84 if ($conflictRowCount) {
a05662ef 85 $urlParams = 'type=' . CRM_Import_Parser::CONFLICT . '&parser=CRM_Contact_Import_Parser';
6a488035
TO
86 $this->set('downloadConflictRecordsUrl', CRM_Utils_System::url('civicrm/export', $urlParams));
87 }
88
89 if ($mismatchCount) {
a05662ef 90 $urlParams = 'type=' . CRM_Import_Parser::NO_MATCH . '&parser=CRM_Contact_Import_Parser';
6a488035
TO
91 $this->set('downloadMismatchRecordsUrl', CRM_Utils_System::url('civicrm/export', $urlParams));
92 }
93
94 $properties = array(
95 'mapper', 'locations', 'phones', 'ims',
96 'dataValues', 'columnCount',
97 'totalRowCount', 'validRowCount',
98 'invalidRowCount', 'conflictRowCount',
99 'downloadErrorRecordsUrl',
100 'downloadConflictRecordsUrl',
101 'downloadMismatchRecordsUrl',
102 'related', 'relatedContactDetails', 'relatedContactLocType',
103 'relatedContactPhoneType', 'relatedContactImProvider', 'websites',
104 'relatedContactWebsiteType',
105 );
106
107 foreach ($properties as $property) {
108 $this->assign($property, $this->get($property));
109 }
110
111 $statusID = $this->get('statusID');
112 if (!$statusID) {
113 $statusID = md5(uniqid(rand(), TRUE));
114 $this->set('statusID', $statusID);
115 }
116 $statusUrl = CRM_Utils_System::url('civicrm/ajax/status', "id={$statusID}", FALSE, NULL, FALSE);
117 $this->assign('statusUrl', $statusUrl);
118
119 $showColNames = TRUE;
120 if ('CRM_Import_DataSource_CSV' == $this->get('dataSource') &&
121 !$this->get('skipColumnHeader')
122 ) {
123 $showColNames = FALSE;
124 }
125 $this->assign('showColNames', $showColNames);
126 }
127
128 /**
c490a46a 129 * Build the form object
6a488035 130 *
355ba699 131 * @return void
6a488035
TO
132 */
133 public function buildQuickForm() {
134 $this->addElement('text', 'newGroupName', ts('Name for new group'));
135 $this->addElement('text', 'newGroupDesc', ts('Description of new group'));
136
137 $groups = $this->get('groups');
138
139 if (!empty($groups)) {
24431f7b 140 $this->addElement('select', 'groups', ts('Add imported records to existing group(s)'), $groups, array('multiple' => "multiple", 'class' => 'crm-select2'));
6a488035
TO
141 }
142
143 //display new tag
144 $this->addElement('text', 'newTagName', ts('Tag'));
145 $this->addElement('text', 'newTagDesc', ts('Description'));
146
147 $tag = $this->get('tag');
148 if (!empty($tag)) {
149 foreach ($tag as $tagID => $tagName) {
150 $this->addElement('checkbox', "tag[$tagID]", NULL, $tagName);
151 }
152 }
153
154 $path = "_qf_MapField_display=true";
155 $qfKey = CRM_Utils_Request::retrieve('qfKey', 'String', $form);
156 if (CRM_Utils_Rule::qfKey($qfKey)) {
157 $path .= "&qfKey=$qfKey";
158 }
159
160 $previousURL = CRM_Utils_System::url('civicrm/import/contact', $path, FALSE, NULL, FALSE);
161 $cancelURL = CRM_Utils_System::url('civicrm/import/contact', 'reset=1');
162
163 $buttons = array(
164 array(
165 'type' => 'back',
166 'name' => ts('<< Previous'),
167 'js' => array('onclick' => "location.href='{$previousURL}'; return false;"),
168 ),
169 array(
170 'type' => 'next',
171 'name' => ts('Import Now >>'),
172 'spacing' => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',
173 'isDefault' => TRUE,
174 'js' => array('onclick' => "return verify( );"),
175 ),
176 array(
177 'type' => 'cancel',
178 'name' => ts('Cancel'),
179 'js' => array('onclick' => "location.href='{$cancelURL}'; return false;"),
180 ),
181 );
182
183 $this->addButtons($buttons);
184
719a6fec 185 $this->addFormRule(array('CRM_Contact_Import_Form_Preview', 'formRule'), $this);
6a488035
TO
186 }
187
188 /**
100fef9d 189 * Global validation rules for the form
6a488035
TO
190 *
191 * @param array $fields posted values of the form
192 *
da6b46f4
EM
193 * @param $files
194 * @param $self
195 *
6a488035
TO
196 * @return array list of errors to be posted back to the form
197 * @static
6a488035 198 */
00be9182 199 public static function formRule($fields, $files, $self) {
6a488035
TO
200 $errors = array();
201 $invalidTagName = $invalidGroupName = FALSE;
202
a7488080 203 if (!empty($fields['newTagName'])) {
6a488035
TO
204 if (!CRM_Utils_Rule::objectExists(trim($fields['newTagName']),
205 array('CRM_Core_DAO_Tag')
206 )) {
207 $errors['newTagName'] = ts('Tag \'%1\' already exists.',
208 array(1 => $fields['newTagName'])
209 );
210 $invalidTagName = TRUE;
211 }
212 }
213
a7488080 214 if (!empty($fields['newGroupName'])) {
6a488035
TO
215 $title = trim($fields['newGroupName']);
216 $name = CRM_Utils_String::titleToVar($title);
217 $query = 'select count(*) from civicrm_group where name like %1 OR title like %2';
0e6e8724
DL
218 $grpCnt = CRM_Core_DAO::singleValueQuery(
219 $query,
220 array(
221 1 => array($name, 'String'),
6a488035 222 2 => array($title, 'String'),
0e6e8724
DL
223 )
224 );
6a488035
TO
225 if ($grpCnt) {
226 $invalidGroupName = TRUE;
227 $errors['newGroupName'] = ts('Group \'%1\' already exists.', array(1 => $fields['newGroupName']));
228 }
229 }
230
231 $self->assign('invalidTagName', $invalidTagName);
232 $self->assign('invalidGroupName', $invalidGroupName);
233
234 return empty($errors) ? TRUE : $errors;
235 }
236
6a488035
TO
237 /**
238 * Process the mapped fields and map it into the uploaded file
239 * preview the file and extract some summary statistics
240 *
241 * @return void
6a488035
TO
242 */
243 public function postProcess() {
244
245 $importJobParams = array(
246 'doGeocodeAddress' => $this->controller->exportValue('DataSource', 'doGeocodeAddress'),
247 'invalidRowCount' => $this->get('invalidRowCount'),
248 'conflictRowCount' => $this->get('conflictRowCount'),
249 'onDuplicate' => $this->get('onDuplicate'),
250 'dedupe' => $this->get('dedupe'),
251 'newGroupName' => $this->controller->exportValue($this->_name, 'newGroupName'),
252 'newGroupDesc' => $this->controller->exportValue($this->_name, 'newGroupDesc'),
253 'groups' => $this->controller->exportValue($this->_name, 'groups'),
254 'allGroups' => $this->get('groups'),
255 'newTagName' => $this->controller->exportValue($this->_name, 'newTagName'),
256 'newTagDesc' => $this->controller->exportValue($this->_name, 'newTagDesc'),
257 'tag' => $this->controller->exportValue($this->_name, 'tag'),
258 'allTags' => $this->get('tag'),
259 'mapper' => $this->controller->exportValue('MapField', 'mapper'),
260 'mapFields' => $this->get('fields'),
261 'contactType' => $this->get('contactType'),
262 'contactSubType' => $this->get('contactSubType'),
263 'primaryKeyName' => $this->get('primaryKeyName'),
264 'statusFieldName' => $this->get('statusFieldName'),
265 'statusID' => $this->get('statusID'),
266 'totalRowCount' => $this->get('totalRowCount'),
267 );
268
269 $tableName = $this->get('importTableName');
719a6fec 270 $importJob = new CRM_Contact_Import_ImportJob($tableName);
6a488035
TO
271 $importJob->setJobParams($importJobParams);
272
273 // If ACL applies to the current user, update cache before running the import.
274 if (!CRM_Core_Permission::check('view all contacts')) {
275 $session = CRM_Core_Session::singleton();
276 $userID = $session->get('userID');
277 CRM_ACL_BAO_Cache::updateEntry($userID);
278 }
279
280 // run the import
281 $importJob->runImport($this);
282
283 // update cache after we done with runImport
284 if (!CRM_Core_Permission::check('view all contacts')) {
285 CRM_ACL_BAO_Cache::updateEntry($userID);
286 }
287
288 // clear all caches
289 CRM_Contact_BAO_Contact_Utils::clearContactCaches();
290
291 // add all the necessary variables to the form
292 $importJob->setFormVariables($this);
293
294 // check if there is any error occured
295 $errorStack = CRM_Core_Error::singleton();
296 $errors = $errorStack->getErrors();
297 $errorMessage = array();
298
299 if (is_array($errors)) {
300 foreach ($errors as $key => $value) {
301 $errorMessage[] = $value['message'];
302 }
303
304 // there is no fileName since this is a sql import
305 // so fudge it
306 $config = CRM_Core_Config::singleton();
307 $errorFile = $config->uploadDir . "sqlImport.error.log";
308 if ($fd = fopen($errorFile, 'w')) {
309 fwrite($fd, implode('\n', $errorMessage));
310 }
311 fclose($fd);
312
313 $this->set('errorFile', $errorFile);
314
a05662ef 315 $urlParams = 'type=' . CRM_Import_Parser::ERROR . '&parser=CRM_Contact_Import_Parser';
6a488035
TO
316 $this->set('downloadErrorRecordsUrl', CRM_Utils_System::url('civicrm/export', $urlParams));
317
a05662ef 318 $urlParams = 'type=' . CRM_Import_Parser::CONFLICT . '&parser=CRM_Contact_Import_Parser';
6a488035
TO
319 $this->set('downloadConflictRecordsUrl', CRM_Utils_System::url('civicrm/export', $urlParams));
320
a05662ef 321 $urlParams = 'type=' . CRM_Import_Parser::NO_MATCH . '&parser=CRM_Contact_Import_Parser';
6a488035
TO
322 $this->set('downloadMismatchRecordsUrl', CRM_Utils_System::url('civicrm/export', $urlParams));
323 }
324
325 //hack to clean db
326 //if job complete drop table.
327 $importJob->isComplete(TRUE);
328 }
329
330 /**
331 * Process the mapped fields and map it into the uploaded file
332 * preview the file and extract some summary statistics
333 *
334 * @return void
6a488035
TO
335 */
336 public function postProcessOld() {
337
338 $doGeocodeAddress = $this->controller->exportValue('DataSource', 'doGeocodeAddress');
339 $invalidRowCount = $this->get('invalidRowCount');
340 $conflictRowCount = $this->get('conflictRowCount');
341 $onDuplicate = $this->get('onDuplicate');
342 $newGroupName = $this->controller->exportValue($this->_name, 'newGroupName');
343 $newGroupDesc = $this->controller->exportValue($this->_name, 'newGroupDesc');
344 $groups = $this->controller->exportValue($this->_name, 'groups');
345 $allGroups = $this->get('groups');
346 $newTagName = $this->controller->exportValue($this->_name, 'newTagName');
347 $newTagDesc = $this->controller->exportValue($this->_name, 'newTagDesc');
348 $tag = $this->controller->exportValue($this->_name, 'tag');
349 $allTags = $this->get('tag');
350
351 $mapper = $this->controller->exportValue('MapField', 'mapper');
352
353 $mapperKeys = array();
354 $mapperLocTypes = array();
355 $mapperPhoneTypes = array();
356 $mapperRelated = array();
357 $mapperRelatedContactType = array();
358 $mapperRelatedContactDetails = array();
359 $mapperRelatedContactLocType = array();
360 $mapperRelatedContactPhoneType = array();
361
362 foreach ($mapper as $key => $value) {
363 $mapperKeys[$key] = $mapper[$key][0];
364 if (is_numeric($mapper[$key][1])) {
365 $mapperLocTypes[$key] = $mapper[$key][1];
366 }
367 else {
368 $mapperLocTypes[$key] = NULL;
369 }
370
371 if (CRM_Utils_Array::value($key, $mapperKeys) == 'phone') {
372 $mapperPhoneTypes[$key] = $mapper[$key][2];
373 }
374 else {
375 $mapperPhoneTypes[$key] = NULL;
376 }
377
378 list($id, $first, $second) = explode('_', $mapper[$key][0]);
379 if (($first == 'a' && $second == 'b') || ($first == 'b' && $second == 'a')) {
380 $relationType = new CRM_Contact_DAO_RelationshipType();
381 $relationType->id = $id;
382 $relationType->find(TRUE);
0e6e8724
DL
383 $fieldName = "contact_type_$second";
384 $mapperRelatedContactType[$key] = $relationType->$fieldName;
6a488035
TO
385 $mapperRelated[$key] = $mapper[$key][0];
386 $mapperRelatedContactDetails[$key] = $mapper[$key][1];
387 $mapperRelatedContactLocType[$key] = $mapper[$key][2];
388 $mapperRelatedContactPhoneType[$key] = $mapper[$key][3];
389 }
390 else {
391 $mapperRelated[$key] = NULL;
392 $mapperRelatedContactType[$key] = NULL;
393 $mapperRelatedContactDetails[$key] = NULL;
394 $mapperRelatedContactLocType[$key] = NULL;
395 $mapperRelatedContactPhoneType[$key] = NULL;
396 }
397 }
398
719a6fec 399 $parser = new CRM_Contact_Import_Parser_Contact($mapperKeys, $mapperLocTypes,
6a488035
TO
400 $mapperPhoneTypes, $mapperRelated, $mapperRelatedContactType,
401 $mapperRelatedContactDetails, $mapperRelatedContactLocType,
402 $mapperRelatedContactPhoneType
403 );
404
405 $mapFields = $this->get('fields');
406
b2b0530a 407 $locationTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Address', 'location_type_id');
b4f964d9 408 $phoneTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Phone', 'phone_type_id');
6a488035
TO
409
410 foreach ($mapper as $key => $value) {
411 $header = array();
412 list($id, $first, $second) = explode('_', $mapper[$key][0]);
413 if (($first == 'a' && $second == 'b') || ($first == 'b' && $second == 'a')) {
414 $relationType = new CRM_Contact_DAO_RelationshipType();
415 $relationType->id = $id;
416 $relationType->find(TRUE);
417
418 $header[] = $relationType->name_a_b;
419 $header[] = ucwords(str_replace("_", " ", $mapper[$key][1]));
420
421 if (isset($mapper[$key][2])) {
422 $header[] = $locationTypes[$mapper[$key][2]];
423 }
424 if (isset($mapper[$key][3])) {
425 $header[] = $phoneTypes[$mapper[$key][3]];
426 }
427 }
428 else {
429 if (isset($mapFields[$mapper[$key][0]])) {
430 $header[] = $mapFields[$mapper[$key][0]];
431 if (isset($mapper[$key][1])) {
432 $header[] = $locationTypes[$mapper[$key][1]];
433 }
434 if (isset($mapper[$key][2])) {
435 $header[] = $phoneTypes[$mapper[$key][2]];
436 }
437 }
438 }
439 $mapperFields[] = implode(' - ', $header);
440 }
441
442 $tableName = $this->get('importTableName');
443 //print "Running parser on table: $tableName<br/>";
444 $parser->run($tableName, $mapperFields,
a05662ef 445 CRM_Import_Parser::MODE_IMPORT,
6a488035
TO
446 $this->get('contactType'),
447 $this->get('primaryKeyName'),
448 $this->get('statusFieldName'),
449 $onDuplicate,
450 $this->get('statusID'),
451 $this->get('totalRowCount'),
452 $doGeocodeAddress,
719a6fec 453 CRM_Contact_Import_Parser::DEFAULT_TIMEOUT,
6a488035
TO
454 $this->get('contactSubType'),
455 $this->get('dedupe')
456 );
457
458 // add the new contacts to selected groups
459 $contactIds = &$parser->getImportedContacts();
460
461 // add the new related contacts to selected groups
462 $relatedContactIds = &$parser->getRelatedImportedContacts();
463
464 $this->set('relatedCount', count($relatedContactIds));
465 $newGroupId = NULL;
466
467 //changed below if-statement "if ($newGroup) {" to "if ($newGroupName) {"
468 if ($newGroupName) {
469 /* Create a new group */
470
471 $gParams = array(
472 'name' => $newGroupName,
473 'title' => $newGroupName,
474 'description' => $newGroupDesc,
475 'is_active' => TRUE,
476 );
477 $group = CRM_Contact_BAO_Group::create($gParams);
478 $groups[] = $newGroupId = $group->id;
479 }
480
481 if (is_array($groups)) {
482 $groupAdditions = array();
483 foreach ($groups as $groupId) {
484 $addCount = CRM_Contact_BAO_GroupContact::addContactsToGroup($contactIds, $groupId);
485 if (!empty($relatedContactIds)) {
486 $addRelCount = CRM_Contact_BAO_GroupContact::addContactsToGroup($relatedContactIds, $groupId);
487 }
488 $totalCount = $addCount[1] + $addRelCount[1];
489 if ($groupId == $newGroupId) {
490 $name = $newGroupName;
491 $new = TRUE;
492 }
493 else {
494 $name = $allGroups[$groupId];
495 $new = FALSE;
496 }
497 $groupAdditions[] = array(
498 'url' => CRM_Utils_System::url('civicrm/group/search',
499 'reset=1&force=1&context=smog&gid=' . $groupId
500 ),
501 'name' => $name,
502 'added' => $totalCount,
503 'notAdded' => $addCount[2] + $addRelCount[2],
504 'new' => $new,
505 );
506 }
507 $this->set('groupAdditions', $groupAdditions);
508 }
509
510 $newTagId = NULL;
511 if ($newTagName) {
512 /* Create a new Tag */
513
514 $tagParams = array(
515 'name' => $newTagName,
516 'title' => $newTagName,
517 'description' => $newTagDesc,
518 'is_active' => TRUE,
519 );
520 $id = array();
521 $addedTag = CRM_Core_BAO_Tag::add($tagParams, $id);
522 $tag[$addedTag->id] = 1;
523 }
524 //add Tag to Import
525
526 if (is_array($tag)) {
527
528 $tagAdditions = array();
529 foreach ($tag as $tagId => $val) {
530 $addTagCount = CRM_Core_BAO_EntityTag::addContactsToTag($contactIds, $tagId);
531 if (!empty($relatedContactIds)) {
532 $addRelTagCount = CRM_Core_BAO_EntityTag::addContactsToTag($relatedContactIds, $tagId);
533 }
534 $totalTagCount = $addTagCount[1] + $addRelTagCount[1];
535 if ($tagId == $addedTag->id) {
536 $tagName = $newTagName;
537 $new = TRUE;
538 }
539 else {
540 $tagName = $allTags[$tagId];
541 $new = FALSE;
542 }
543 $tagAdditions[] = array(
544 'url' => CRM_Utils_System::url('civicrm/contact/search',
545 'reset=1&force=1&context=smog&id=' . $tagId
546 ),
547 'name' => $tagName,
548 'added' => $totalTagCount,
549 'notAdded' => $addTagCount[2] + $addRelTagCount[2],
550 'new' => $new,
551 );
552 }
553 $this->set('tagAdditions', $tagAdditions);
554 }
555
556 // add all the necessary variables to the form
a05662ef 557 $parser->set($this, CRM_Import_Parser::MODE_IMPORT);
6a488035
TO
558
559 // check if there is any error occured
560
561 $errorStack = CRM_Core_Error::singleton();
562 $errors = $errorStack->getErrors();
563 $errorMessage = array();
564
565 if (is_array($errors)) {
566 foreach ($errors as $key => $value) {
567 $errorMessage[] = $value['message'];
568 }
569
570 // there is no fileName since this is a sql import
571 // so fudge it
572 $config = CRM_Core_Config::singleton();
573 $errorFile = $config->uploadDir . "sqlImport.error.log";
574 if ($fd = fopen($errorFile, 'w')) {
575 fwrite($fd, implode('\n', $errorMessage));
576 }
577 fclose($fd);
578
579 $this->set('errorFile', $errorFile);
580
a05662ef 581 $urlParams = 'type=' . CRM_Import_Parser::ERROR . '&parser=CRM_Contact_Import_Parser';
6a488035
TO
582 $this->set('downloadErrorRecordsUrl', CRM_Utils_System::url('civicrm/export', $urlparams));
583
a05662ef 584 $urlParams = 'type=' . CRM_Import_Parser::CONFLICT . '&parser=CRM_Contact_Import_Parser';
6a488035
TO
585 $this->set('downloadConflictRecordsUrl', CRM_Utils_System::url('civicrm/export', $urlParams));
586
a05662ef 587 $urlParams = 'type=' . CRM_Import_Parser::NO_MATCH . '&parser=CRM_Contact_Import_Parser';
6a488035
TO
588 $this->set('downloadMismatchRecordsUrl', CRM_Utils_System::url('civicrm/export', $urlParams));
589 }
590 }
591}