Update copyright date for 2020
[civicrm-core.git] / CRM / Export / Form / Select.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
fee14197 4 | CiviCRM version 5 |
6a488035 5 +--------------------------------------------------------------------+
f299f7db 6 | Copyright CiviCRM LLC (c) 2004-2020 |
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 +--------------------------------------------------------------------+
d25dd0ee 26 */
6a488035
TO
27
28/**
29 *
30 * @package CRM
f299f7db 31 * @copyright CiviCRM LLC (c) 2004-2020
6a488035
TO
32 * $Id$
33 *
34 */
35
36/**
37 * This class gets the name of the file to upload
38 */
31aaf096 39class CRM_Export_Form_Select extends CRM_Core_Form_Task {
6a488035
TO
40
41 /**
fe482240 42 * Various Contact types.
6a488035 43 */
7da04cde 44 const
0e6e8724
DL
45 EXPORT_ALL = 1,
46 EXPORT_SELECTED = 2,
47 EXPORT_MERGE_DO_NOT_MERGE = 0,
48 EXPORT_MERGE_SAME_ADDRESS = 1,
49 EXPORT_MERGE_HOUSEHOLD = 2;
6a488035
TO
50
51 /**
fe482240 52 * Export modes.
6a488035 53 */
7da04cde 54 const
0e6e8724
DL
55 CONTACT_EXPORT = 1,
56 CONTRIBUTE_EXPORT = 2,
57 MEMBER_EXPORT = 3,
58 EVENT_EXPORT = 4,
59 PLEDGE_EXPORT = 5,
60 CASE_EXPORT = 6,
61 GRANT_EXPORT = 7,
62 ACTIVITY_EXPORT = 8;
6a488035
TO
63
64 /**
fe482240 65 * Current export mode.
6a488035
TO
66 *
67 * @var int
68 */
69 public $_exportMode;
70
71 public $_componentTable;
72
73 /**
fe482240 74 * Build all the data structures needed to build the form.
6a488035
TO
75 *
76 * @param
77 *
78 * @return void
6a488035 79 */
00be9182 80 public function preProcess() {
df4c8e9c
CW
81 $this->preventAjaxSubmit();
82
6a488035 83 //special case for custom search, directly give option to download csv file
7b845814 84 $customSearchID = $this->get('customSearchID');
85 if ($customSearchID) {
86 CRM_Export_BAO_Export::exportCustom($this->get('customSearchClass'),
87 $this->get('formValues'),
88 $this->get(CRM_Utils_Sort::SORT_ORDER)
89 );
90 }
6a488035
TO
91
92 $this->_selectAll = FALSE;
93 $this->_exportMode = self::CONTACT_EXPORT;
be2fb01f 94 $this->_componentIds = [];
6a488035
TO
95 $this->_componentClause = NULL;
96
3b4adc92 97 // we need to determine component export
be2fb01f 98 $components = ['Contact', 'Contribute', 'Member', 'Event', 'Pledge', 'Case', 'Grant', 'Activity'];
3b4adc92 99
3b4adc92 100 // FIXME: This should use a modified version of CRM_Contact_Form_Search::getModeValue but it doesn't have all the contexts
ae70f47e 101 // FIXME: Or better still, use CRM_Core_DAO_AllCoreTables::getBriefName($daoName) to get the $entityShortName
a0174743 102 switch ($this->getQueryMode()) {
3b4adc92
MW
103 case CRM_Contact_BAO_Query::MODE_CONTRIBUTE:
104 $entityShortname = 'Contribute';
a0174743 105 $entityDAOName = $entityShortname;
3b4adc92
MW
106 break;
107
108 case CRM_Contact_BAO_Query::MODE_MEMBER:
109 $entityShortname = 'Member';
110 $entityDAOName = 'Membership';
111 break;
112
113 case CRM_Contact_BAO_Query::MODE_EVENT:
114 $entityShortname = 'Event';
a0174743 115 $entityDAOName = $entityShortname;
3b4adc92
MW
116 break;
117
118 case CRM_Contact_BAO_Query::MODE_PLEDGE:
119 $entityShortname = 'Pledge';
a0174743 120 $entityDAOName = $entityShortname;
3b4adc92
MW
121 break;
122
123 case CRM_Contact_BAO_Query::MODE_CASE:
124 $entityShortname = 'Case';
a0174743 125 $entityDAOName = $entityShortname;
3b4adc92
MW
126 break;
127
128 case CRM_Contact_BAO_Query::MODE_GRANT:
129 $entityShortname = 'Grant';
a0174743 130 $entityDAOName = $entityShortname;
3b4adc92
MW
131 break;
132
133 case CRM_Contact_BAO_Query::MODE_ACTIVITY:
134 $entityShortname = 'Activity';
a0174743 135 $entityDAOName = $entityShortname;
3b4adc92
MW
136 break;
137
138 default:
a0174743
MW
139 // FIXME: Code cleanup, we may not need to do this $componentName code here.
140 $formName = CRM_Utils_System::getClassName($this->controller->getStateMachine());
141 $componentName = explode('_', $formName);
142 if ($formName == 'CRM_Export_StateMachine_Standalone') {
be2fb01f 143 $componentName = ['CRM', $this->controller->get('entity')];
a0174743 144 }
7b966967
SL
145 // Contact
146 $entityShortname = $componentName[1];
a0174743 147 $entityDAOName = $entityShortname;
3b4adc92
MW
148 break;
149 }
150
151 if (in_array($entityShortname, $components)) {
152 $this->_exportMode = constant('CRM_Export_Form_Select::' . strtoupper($entityShortname) . '_EXPORT');
153 $formTaskClassName = "CRM_{$entityShortname}_Form_Task";
154 $taskClassName = "CRM_{$entityShortname}_Task";
155 if (isset($formTaskClassName::$entityShortname)) {
156 $this::$entityShortname = $formTaskClassName::$entityShortname;
157 if (isset($formTaskClassName::$tableName)) {
158 $this::$tableName = $formTaskClassName::$tableName;
159 }
160 }
161 else {
162 $this::$entityShortname = $entityShortname;
163 $this::$tableName = CRM_Core_DAO_AllCoreTables::getTableForClass(CRM_Core_DAO_AllCoreTables::getFullName($entityDAOName));
164 }
165 }
166
6a488035 167 // get the submitted values based on search
7b845814 168 if ($this->_action == CRM_Core_Action::ADVANCED) {
6a488035
TO
169 $values = $this->controller->exportValues('Advanced');
170 }
171 elseif ($this->_action == CRM_Core_Action::PROFILE) {
172 $values = $this->controller->exportValues('Builder');
173 }
174 elseif ($this->_action == CRM_Core_Action::COPY) {
175 $values = $this->controller->exportValues('Custom');
176 }
177 else {
ca524188 178 if (in_array($entityShortname, $components) && $entityShortname !== 'Contact') {
6a488035
TO
179 $values = $this->controller->exportValues('Search');
180 }
181 else {
182 $values = $this->controller->exportValues('Basic');
183 }
184 }
185
186 $count = 0;
187 $this->_matchingContacts = FALSE;
188 if (CRM_Utils_Array::value('radio_ts', $values) == 'ts_sel') {
189 foreach ($values as $key => $value) {
190 if (strstr($key, 'mark_x')) {
191 $count++;
192 }
193 if ($count > 2) {
194 $this->_matchingContacts = TRUE;
195 break;
196 }
197 }
198 }
199
a0174743 200 $formTaskClassName::preProcessCommon($this);
6886d6f2 201
3b4adc92
MW
202 // $component is used on CRM/Export/Form/Select.tpl to display extra information for contact export
203 ($this->_exportMode == self::CONTACT_EXPORT) ? $component = FALSE : $component = TRUE;
204 $this->assign('component', $component);
6a488035 205
3b4adc92
MW
206 // Set the task title
207 $componentTasks = $taskClassName::taskTitles();
6a488035 208 $this->_task = $values['task'];
3b4adc92
MW
209 $taskName = $componentTasks[$this->_task];
210 $this->assign('taskName', $taskName);
6a488035
TO
211
212 if ($this->_componentTable) {
213 $query = "
214SELECT count(*)
215FROM {$this->_componentTable}
216";
217 $totalSelectedRecords = CRM_Core_DAO::singleValueQuery($query);
218 }
219 else {
220 $totalSelectedRecords = count($this->_componentIds);
221 }
222 $this->assign('totalSelectedRecords', $totalSelectedRecords);
3b4adc92 223
6a488035
TO
224 // all records actions = save a search
225 if (($values['radio_ts'] == 'ts_all') || ($this->_task == CRM_Contact_Task::SAVE_SEARCH)) {
226 $this->_selectAll = TRUE;
227 $rowCount = $this->get('rowCount');
228 if ($rowCount > 2) {
229 $this->_matchingContacts = TRUE;
230 }
231 $this->assign('totalSelectedRecords', $rowCount);
232 }
233
234 $this->assign('matchingContacts', $this->_matchingContacts);
235 $this->set('componentIds', $this->_componentIds);
236 $this->set('selectAll', $this->_selectAll);
237 $this->set('exportMode', $this->_exportMode);
238 $this->set('componentClause', $this->_componentClause);
239 $this->set('componentTable', $this->_componentTable);
240 }
241
242 /**
fe482240 243 * Build the form object.
6a488035
TO
244 *
245 * @return void
6a488035
TO
246 */
247 public function buildQuickForm() {
248 //export option
be2fb01f 249 $exportOptions = $mergeOptions = $postalMailing = [];
6a488035
TO
250 $exportOptions[] = $this->createElement('radio',
251 NULL, NULL,
7b845814 252 ts('Export PRIMARY fields'),
6a488035 253 self::EXPORT_ALL,
be2fb01f 254 ['onClick' => 'showMappingOption( );']
6a488035
TO
255 );
256 $exportOptions[] = $this->createElement('radio',
257 NULL, NULL,
258 ts('Select fields for export'),
259 self::EXPORT_SELECTED,
be2fb01f 260 ['onClick' => 'showMappingOption( );']
6a488035
TO
261 );
262
263 $mergeOptions[] = $this->createElement('radio',
264 NULL, NULL,
265 ts('Do not merge'),
266 self::EXPORT_MERGE_DO_NOT_MERGE,
be2fb01f 267 ['onclick' => 'showGreetingOptions( );']
6a488035
TO
268 );
269 $mergeOptions[] = $this->createElement('radio',
270 NULL, NULL,
271 ts('Merge All Contacts with the Same Address'),
272 self::EXPORT_MERGE_SAME_ADDRESS,
be2fb01f 273 ['onclick' => 'showGreetingOptions( );']
6a488035
TO
274 );
275 $mergeOptions[] = $this->createElement('radio',
276 NULL, NULL,
277 ts('Merge Household Members into their Households'),
278 self::EXPORT_MERGE_HOUSEHOLD,
be2fb01f 279 ['onclick' => 'showGreetingOptions( );']
6a488035
TO
280 );
281
282 $postalMailing[] = $this->createElement('advcheckbox',
283 'postal_mailing_export',
284 NULL,
285 NULL
286 );
287
288 $this->addGroup($exportOptions, 'exportOption', ts('Export Type'), '<br/>');
289
290 if ($this->_matchingContacts) {
291 $this->_greetingOptions = self::getGreetingOptions();
292
293 foreach ($this->_greetingOptions as $key => $value) {
ee769c00 294 $fieldLabel = ts('%1 (when merging contacts)', [1 => ucwords(str_replace('_', ' ', $key))]);
6a488035 295 $this->addElement('select', $key, $fieldLabel,
be2fb01f 296 $value, ['onchange' => "showOther(this);"]
6a488035
TO
297 );
298 $this->addElement('text', "{$key}_other", '');
299 }
300 }
301
302 if ($this->_exportMode == self::CONTACT_EXPORT) {
303 $this->addGroup($mergeOptions, 'mergeOption', ts('Merge Options'), '<br/>');
304 $this->addGroup($postalMailing, 'postal_mailing_export', ts('Postal Mailing Export'), '<br/>');
305
306 $this->addElement('select', 'additional_group', ts('Additional Group for Export'),
be2fb01f
CW
307 ['' => ts('- select group -')] + CRM_Core_PseudoConstant::nestedGroup(),
308 ['class' => 'crm-select2 huge']
6a488035
TO
309 );
310 }
311
312 $this->buildMapping();
313
be2fb01f 314 $this->setDefaults([
6a488035 315 'exportOption' => self::EXPORT_ALL,
353ffa53 316 'mergeOption' => self::EXPORT_MERGE_DO_NOT_MERGE,
be2fb01f 317 ]);
6a488035 318
be2fb01f 319 $this->addButtons([
7b966967
SL
320 [
321 'type' => 'next',
322 'name' => ts('Continue'),
323 'spacing' => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',
324 'isDefault' => TRUE,
325 ],
326 [
327 'type' => 'cancel',
328 'name' => ts('Cancel'),
329 ],
330 ]);
6a488035 331
be2fb01f 332 $this->addFormRule(['CRM_Export_Form_Select', 'formRule'], $this);
6a488035
TO
333 }
334
335 /**
fe482240 336 * Validation.
6a488035 337 *
b9add4b3
TO
338 * @param array $params
339 * (ref.) an assoc array of name/value pairs.
6a488035 340 *
fd31fa4c
EM
341 * @param $files
342 * @param $self
343 *
72b3a70c
CW
344 * @return bool|array
345 * mixed true or array of errors
6a488035 346 */
a0174743 347 public static function formRule($params, $files, $self) {
be2fb01f 348 $errors = [];
6a488035
TO
349
350 if (CRM_Utils_Array::value('mergeOption', $params) == self::EXPORT_MERGE_SAME_ADDRESS &&
351 $self->_matchingContacts
352 ) {
be2fb01f 353 $greetings = [
6a488035
TO
354 'postal_greeting' => 'postal_greeting_other',
355 'addressee' => 'addressee_other',
be2fb01f 356 ];
6a488035
TO
357
358 foreach ($greetings as $key => $value) {
359 $otherOption = CRM_Utils_Array::value($key, $params);
360
8cc574cf 361 if ((CRM_Utils_Array::value($otherOption, $self->_greetingOptions[$key]) == ts('Other')) && empty($params[$value])) {
6a488035
TO
362
363 $label = ucwords(str_replace('_', ' ', $key));
ee769c00 364 $errors[$value] = ts('Please enter a value for %1 (when merging contacts), or select a pre-configured option from the list.', [1 => $label]);
6a488035
TO
365 }
366 }
367 }
368
369 return empty($errors) ? TRUE : $errors;
370 }
371
372 /**
fe482240 373 * Process the uploaded file.
6a488035 374 *
a0174743 375 * @throws \CRM_Core_Exception
6a488035
TO
376 */
377 public function postProcess() {
353ffa53
TO
378 $params = $this->controller->exportValues($this->_name);
379 $exportOption = $params['exportOption'];
380 $mergeSameAddress = CRM_Utils_Array::value('mergeOption', $params) == self::EXPORT_MERGE_SAME_ADDRESS ? 1 : 0;
6a488035
TO
381 $mergeSameHousehold = CRM_Utils_Array::value('mergeOption', $params) == self::EXPORT_MERGE_HOUSEHOLD ? 1 : 0;
382
383 $this->set('mergeSameAddress', $mergeSameAddress);
384 $this->set('mergeSameHousehold', $mergeSameHousehold);
385
386 // instead of increasing the number of arguments to exportComponents function, we
387 // will send $exportParams as another argument, which is an array and suppose to contain
388 // all submitted options or any other argument
389 $exportParams = $params;
390
6a488035
TO
391 $mappingId = CRM_Utils_Array::value('mapping', $params);
392 if ($mappingId) {
393 $this->set('mappingId', $mappingId);
394 }
395 else {
396 $this->set('mappingId', NULL);
397 }
398
6a488035 399 if ($exportOption == self::EXPORT_ALL) {
7b845814 400 CRM_Export_BAO_Export::exportComponents($this->_selectAll,
401 $this->_componentIds,
402 (array) $this->get('queryParams'),
403 $this->get(CRM_Utils_Sort::SORT_ORDER),
404 NULL,
405 $this->get('returnProperties'),
406 $this->_exportMode,
407 $this->_componentClause,
408 $this->_componentTable,
409 $mergeSameAddress,
410 $mergeSameHousehold,
411 $exportParams,
412 $this->get('queryOperator')
413 );
6a488035
TO
414 }
415
416 //reset map page
417 $this->controller->resetPage('Map');
418 }
419
420 /**
421 * Return a descriptive name for the page, used in wizard header
422 *
423 * @return string
6a488035
TO
424 */
425 public function getTitle() {
653f9ec1 426 return ts('Export Options');
6a488035
TO
427 }
428
429 /**
fe482240 430 * Build mapping form element.
6a488035 431 */
00be9182 432 public function buildMapping() {
6a488035
TO
433 switch ($this->_exportMode) {
434 case CRM_Export_Form_Select::CONTACT_EXPORT:
435 $exportType = 'Export Contact';
436 break;
437
438 case CRM_Export_Form_Select::CONTRIBUTE_EXPORT:
439 $exportType = 'Export Contribution';
440 break;
441
442 case CRM_Export_Form_Select::MEMBER_EXPORT:
443 $exportType = 'Export Membership';
444 break;
445
446 case CRM_Export_Form_Select::EVENT_EXPORT:
447 $exportType = 'Export Participant';
448 break;
449
450 case CRM_Export_Form_Select::PLEDGE_EXPORT:
451 $exportType = 'Export Pledge';
452 break;
453
454 case CRM_Export_Form_Select::CASE_EXPORT:
455 $exportType = 'Export Case';
456 break;
457
458 case CRM_Export_Form_Select::GRANT_EXPORT:
459 $exportType = 'Export Grant';
460 break;
461
462 case CRM_Export_Form_Select::ACTIVITY_EXPORT:
463 $exportType = 'Export Activity';
464 break;
465 }
466
95f52e3b 467 $this->set('mappingTypeId', CRM_Core_PseudoConstant::getKey('CRM_Core_BAO_Mapping', 'mapping_type_id', $exportType));
6a488035 468
4f55a797 469 $mappings = CRM_Core_BAO_Mapping::getMappings($exportType, TRUE);
6a488035 470 if (!empty($mappings)) {
4f55a797 471 $this->add('select2', 'mapping', ts('Use Saved Field Mapping'), $mappings, FALSE, ['placeholder' => ts('- select -')]);
6a488035
TO
472 }
473 }
474
e0ef6999
EM
475 /**
476 * @return array
477 */
00be9182 478 public static function getGreetingOptions() {
be2fb01f
CW
479 $options = [];
480 $greetings = [
6a488035
TO
481 'postal_greeting' => 'postal_greeting_other',
482 'addressee' => 'addressee_other',
be2fb01f 483 ];
6a488035
TO
484
485 foreach ($greetings as $key => $value) {
be2fb01f 486 $params = [];
6a488035
TO
487 $optionGroupId = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionGroup', $key, 'id', 'name');
488
489 CRM_Core_DAO::commonRetrieveAll('CRM_Core_DAO_OptionValue', 'option_group_id', $optionGroupId,
be2fb01f 490 $params, ['label', 'filter']
6a488035
TO
491 );
492
493 $greetingCount = 1;
be2fb01f 494 $options[$key] = ["$greetingCount" => ts('List of names')];
6a488035
TO
495
496 foreach ($params as $id => $field) {
497 if (CRM_Utils_Array::value('filter', $field) == 4) {
498 $options[$key][++$greetingCount] = $field['label'];
499 }
500 }
501
502 $options[$key][++$greetingCount] = ts('Other');
503 }
504
505 return $options;
506 }
96025800 507
a0174743
MW
508 /**
509 * Get the query mode (eg. CRM_Core_BAO_Query::MODE_CASE)
510 *
511 * @return int
512 */
513 public function getQueryMode() {
d5fd18f6 514 return (int) ($this->queryMode ?: $this->controller->get('component_mode'));
a0174743
MW
515 }
516
6a488035 517}