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