3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
15 * @copyright CiviCRM LLC https://civicrm.org/licensing
19 * This class gets the name of the file to upload
21 class CRM_Export_Form_Select
extends CRM_Core_Form_Task
{
24 * Various Contact types.
29 EXPORT_MERGE_DO_NOT_MERGE
= 0,
30 EXPORT_MERGE_SAME_ADDRESS
= 1,
31 EXPORT_MERGE_HOUSEHOLD
= 2;
38 CONTRIBUTE_EXPORT
= 2,
47 * Current export mode.
53 public $_componentTable;
56 * Use the form name to create the tpl file name.
60 public function getTemplateFileName() {
61 return 'CRM/Export/Form/Select.tpl';
65 * Build all the data structures needed to build the form.
71 public function preProcess() {
72 $this->preventAjaxSubmit();
74 //special case for custom search, directly give option to download csv file
75 $customSearchID = $this->get('customSearchID');
76 if ($customSearchID) {
77 CRM_Export_BAO_Export
::exportCustom($this->get('customSearchClass'),
78 $this->get('formValues'),
79 $this->get(CRM_Utils_Sort
::SORT_ORDER
)
83 $this->_selectAll
= FALSE;
84 $this->_exportMode
= self
::CONTACT_EXPORT
;
85 $this->_componentIds
= [];
86 $this->_componentClause
= NULL;
88 // FIXME: This should use a modified version of CRM_Contact_Form_Search::getModeValue but it doesn't have all the contexts
89 // FIXME: Or better still, use CRM_Core_DAO_AllCoreTables::getBriefName($daoName) to get the $entityShortName
90 $entityShortname = $this->getEntityShortName();
92 if (!in_array($entityShortname, ['Contact', 'Contribute', 'Member', 'Event', 'Pledge', 'Case', 'Grant', 'Activity'], TRUE)) {
93 // This is never reached - the exception here is just to clarify that entityShortName MUST be one of the above
94 // to save future refactorers & reviewers from asking that question.
95 throw new CRM_Core_Exception('Unreachable code');
97 $this->_exportMode
= constant('CRM_Export_Form_Select::' . strtoupper($entityShortname) . '_EXPORT');
99 $this::$entityShortname = strtolower($entityShortname);
100 $values = $this->getSearchFormValues();
103 $this->_matchingContacts
= FALSE;
104 if (CRM_Utils_Array
::value('radio_ts', $values) == 'ts_sel') {
105 foreach ($values as $key => $value) {
106 if (strstr($key, 'mark_x')) {
110 $this->_matchingContacts
= TRUE;
116 $this->callPreProcessing();
118 // $component is used on CRM/Export/Form/Select.tpl to display extra information for contact export
119 ($this->_exportMode
== self
::CONTACT_EXPORT
) ?
$component = FALSE : $component = TRUE;
120 $this->assign('component', $component);
122 $this->assign('isShowMergeOptions', $this->isShowContactMergeOptions());
124 if ($this->_componentTable
) {
127 FROM {$this->_componentTable}
129 $totalSelectedRecords = CRM_Core_DAO
::singleValueQuery($query);
132 $totalSelectedRecords = count($this->_componentIds
);
134 $this->assign('totalSelectedRecords', $totalSelectedRecords);
136 // all records actions = save a search
137 if (($values['radio_ts'] == 'ts_all') ||
($this->_task
== CRM_Contact_Task
::SAVE_SEARCH
)) {
138 $this->_selectAll
= TRUE;
139 $rowCount = $this->get('rowCount');
141 $this->_matchingContacts
= TRUE;
143 $this->assign('totalSelectedRecords', $rowCount);
146 $this->assign('matchingContacts', $this->_matchingContacts
);
147 $this->set('componentIds', $this->_componentIds
);
148 $this->set('selectAll', $this->_selectAll
);
149 $this->set('exportMode', $this->_exportMode
);
150 $this->set('componentClause', $this->_componentClause
);
151 $this->set('componentTable', $this->getTableName());
155 * Get the name of the table for the relevant entity.
157 public function getTableName() {
158 throw new CRM_Core_Exception('should be over-riden');
162 * Build the form object.
166 public function buildQuickForm() {
168 $exportOptions = $exportOptionsJS = $mergeOptions = $mergeOptionsJS = $postalMailing = [];
169 $exportOptions[self
::EXPORT_ALL
] = ts('Export PRIMARY fields');
170 $exportOptions[self
::EXPORT_SELECTED
] = ts('Select fields for export');
171 $mergeOptions[self
::EXPORT_MERGE_DO_NOT_MERGE
] = ts('Do not merge');
172 $mergeOptions[self
::EXPORT_MERGE_SAME_ADDRESS
] = ts('Merge All Contacts with the Same Address');
173 $mergeOptions[self
::EXPORT_MERGE_HOUSEHOLD
] = ts('Merge Household Members into their Households');
174 foreach (array_keys($exportOptions) as $key) {
175 $exportOptionsJS[$key] = ['onClick' => 'showMappingOption( );'];
177 foreach (array_keys($mergeOptions) as $key) {
178 $mergeOptionsJS[$key] = ['onclick' => 'showGreetingOptions( );'];
180 $this->addRadio('exportOption', ts('Export Type'), $exportOptions, [], '<br/>', FALSE, $exportOptionsJS);
181 $postalMailing[] = $this->createElement('advcheckbox',
182 'postal_mailing_export',
187 if ($this->_matchingContacts
) {
188 $this->_greetingOptions
= self
::getGreetingOptions();
190 foreach ($this->_greetingOptions
as $key => $value) {
191 $fieldLabel = ts('%1 (when merging contacts)', [1 => ucwords(str_replace('_', ' ', $key))]);
192 $this->addElement('select', $key, $fieldLabel,
193 $value, ['onchange' => "showOther(this);"]
195 $this->addElement('text', "{$key}_other", '');
199 if ($this->_exportMode
== self
::CONTACT_EXPORT
) {
200 $this->addRadio('mergeOption', ts('Merge Options'), $mergeOptions, [], '<br/>', FALSE, $mergeOptionsJS);
201 $this->addGroup($postalMailing, 'postal_mailing_export', ts('Postal Mailing Export'), '<br/>');
203 $this->addElement('select', 'additional_group', ts('Additional Group for Export'),
204 ['' => ts('- select group -')] + CRM_Core_PseudoConstant
::nestedGroup(),
205 ['class' => 'crm-select2 huge']
209 $this->buildMapping();
212 'exportOption' => self
::EXPORT_ALL
,
213 'mergeOption' => self
::EXPORT_MERGE_DO_NOT_MERGE
,
219 'name' => ts('Continue'),
220 'spacing' => ' ',
225 'name' => ts('Cancel'),
229 $this->addFormRule(['CRM_Export_Form_Select', 'formRule'], $this);
235 * @param array $params
236 * (ref.) an assoc array of name/value pairs.
242 * mixed true or array of errors
244 public static function formRule($params, $files, $self) {
247 if (CRM_Utils_Array
::value('mergeOption', $params) == self
::EXPORT_MERGE_SAME_ADDRESS
&&
248 $self->_matchingContacts
251 'postal_greeting' => 'postal_greeting_other',
252 'addressee' => 'addressee_other',
255 foreach ($greetings as $key => $value) {
256 $otherOption = $params[$key] ??
NULL;
258 if ((CRM_Utils_Array
::value($otherOption, $self->_greetingOptions
[$key]) == ts('Other')) && empty($params[$value])) {
260 $label = ucwords(str_replace('_', ' ', $key));
261 $errors[$value] = ts('Please enter a value for %1 (when merging contacts), or select a pre-configured option from the list.', [1 => $label]);
266 return empty($errors) ?
TRUE : $errors;
270 * Process the uploaded file.
272 * @throws \CRM_Core_Exception
274 public function postProcess() {
275 $params = $this->controller
->exportValues($this->_name
);
276 $exportOption = $params['exportOption'];
277 $mergeSameAddress = CRM_Utils_Array
::value('mergeOption', $params) == self
::EXPORT_MERGE_SAME_ADDRESS ?
1 : 0;
278 $mergeSameHousehold = CRM_Utils_Array
::value('mergeOption', $params) == self
::EXPORT_MERGE_HOUSEHOLD ?
1 : 0;
280 $this->set('mergeSameAddress', $mergeSameAddress);
281 $this->set('mergeSameHousehold', $mergeSameHousehold);
283 // instead of increasing the number of arguments to exportComponents function, we
284 // will send $exportParams as another argument, which is an array and suppose to contain
285 // all submitted options or any other argument
286 $exportParams = $params;
288 $mappingId = $params['mapping'] ??
NULL;
290 $this->set('mappingId', $mappingId);
293 $this->set('mappingId', NULL);
296 if ($exportOption == self
::EXPORT_ALL
) {
297 CRM_Export_BAO_Export
::exportComponents($this->_selectAll
,
298 $this->_componentIds
,
299 (array) $this->get('queryParams'),
300 $this->get(CRM_Utils_Sort
::SORT_ORDER
),
302 $this->get('returnProperties'),
304 $this->_componentClause
,
305 $this->_componentTable
,
309 $this->get('queryOperator')
314 $this->controller
->resetPage('Map');
318 * Return a descriptive name for the page, used in wizard header
322 public function getTitle() {
323 return ts('Export Options');
327 * Build mapping form element.
329 public function buildMapping() {
330 switch ($this->_exportMode
) {
331 case CRM_Export_Form_Select
::CONTACT_EXPORT
:
332 $exportType = 'Export Contact';
335 case CRM_Export_Form_Select
::CONTRIBUTE_EXPORT
:
336 $exportType = 'Export Contribution';
339 case CRM_Export_Form_Select
::MEMBER_EXPORT
:
340 $exportType = 'Export Membership';
343 case CRM_Export_Form_Select
::EVENT_EXPORT
:
344 $exportType = 'Export Participant';
347 case CRM_Export_Form_Select
::PLEDGE_EXPORT
:
348 $exportType = 'Export Pledge';
351 case CRM_Export_Form_Select
::CASE_EXPORT
:
352 $exportType = 'Export Case';
355 case CRM_Export_Form_Select
::GRANT_EXPORT
:
356 $exportType = 'Export Grant';
359 case CRM_Export_Form_Select
::ACTIVITY_EXPORT
:
360 $exportType = 'Export Activity';
364 $this->set('mappingTypeId', CRM_Core_PseudoConstant
::getKey('CRM_Core_BAO_Mapping', 'mapping_type_id', $exportType));
366 $mappings = CRM_Core_BAO_Mapping
::getMappings($exportType, TRUE);
367 if (!empty($mappings)) {
368 $this->add('select2', 'mapping', ts('Use Saved Field Mapping'), $mappings, FALSE, ['placeholder' => ts('- select -')]);
375 public static function getGreetingOptions() {
378 'postal_greeting' => 'postal_greeting_other',
379 'addressee' => 'addressee_other',
382 foreach ($greetings as $key => $value) {
384 $optionGroupId = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_OptionGroup', $key, 'id', 'name');
386 CRM_Core_DAO
::commonRetrieveAll('CRM_Core_DAO_OptionValue', 'option_group_id', $optionGroupId,
387 $params, ['label', 'filter']
391 $options[$key] = ["$greetingCount" => ts('List of names')];
393 foreach ($params as $id => $field) {
394 if (CRM_Utils_Array
::value('filter', $field) == 4) {
395 $options[$key][++
$greetingCount] = $field['label'];
399 $options[$key][++
$greetingCount] = ts('Other');
406 * Get the query mode (eg. CRM_Contact_BAO_Query::MODE_CASE)
410 public function getQueryMode() {
411 return (int) ($this->queryMode ?
: $this->controller
->get('component_mode'));
415 * Call the pre-processing function.
417 protected function callPreProcessing(): void
{
418 throw new CRM_Core_Exception('This must be over-ridden');
422 * Assign the title of the task to the tpl.
424 protected function isShowContactMergeOptions() {
425 throw new CRM_Core_Exception('This must be over-ridden');
429 * Get the name of the component.
433 protected function getComponentName(): string {
434 // CRM_Export_Controller_Standalone has this method
435 if (method_exists($this->controller
, 'getComponent')) {
436 return $this->controller
->getComponent();
438 // For others, just guess based on the name of the controller
439 $formName = CRM_Utils_System
::getClassName($this->controller
->getStateMachine());
440 $componentName = explode('_', $formName);
441 return $componentName[1];
445 * Get the DAO name for the given export.
449 protected function getDAOName(): string {
450 switch ($this->getQueryMode()) {
451 case CRM_Contact_BAO_Query
::MODE_CONTRIBUTE
:
454 case CRM_Contact_BAO_Query
::MODE_MEMBER
:
457 case CRM_Contact_BAO_Query
::MODE_EVENT
:
460 case CRM_Contact_BAO_Query
::MODE_PLEDGE
:
463 case CRM_Contact_BAO_Query
::MODE_CASE
:
466 case CRM_Contact_BAO_Query
::MODE_GRANT
:
469 case CRM_Contact_BAO_Query
::MODE_ACTIVITY
:
473 return $this->controller
->get('entity') ??
$this->getComponentName();
478 * Get the entity short name for a given export.
482 protected function getEntityShortName(): string {
483 switch ($this->getQueryMode()) {
484 case CRM_Contact_BAO_Query
::MODE_CONTRIBUTE
:
487 case CRM_Contact_BAO_Query
::MODE_MEMBER
:
490 case CRM_Contact_BAO_Query
::MODE_EVENT
:
493 case CRM_Contact_BAO_Query
::MODE_PLEDGE
:
496 case CRM_Contact_BAO_Query
::MODE_CASE
:
499 case CRM_Contact_BAO_Query
::MODE_GRANT
:
502 case CRM_Contact_BAO_Query
::MODE_ACTIVITY
:
506 return $this->getComponentName();