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