preventAjaxSubmit(); //special case for custom search, directly give option to download csv file $customSearchID = $this->get('customSearchID'); if ($customSearchID) { CRM_Export_BAO_Export::exportCustom($this->get('customSearchClass'), $this->get('formValues'), $this->get(CRM_Utils_Sort::SORT_ORDER) ); } $this->_selectAll = FALSE; $this->_exportMode = self::CONTACT_EXPORT; $this->_componentIds = []; $this->_componentClause = NULL; // FIXME: This should use a modified version of CRM_Contact_Form_Search::getModeValue but it doesn't have all the contexts // FIXME: Or better still, use CRM_Core_DAO_AllCoreTables::getBriefName($daoName) to get the $entityShortName $entityShortname = $this->getEntityShortName(); if (!in_array($entityShortname, ['Contact', 'Contribute', 'Member', 'Event', 'Pledge', 'Case', 'Grant', 'Activity'], TRUE)) { // This is never reached - the exception here is just to clarify that entityShortName MUST be one of the above // to save future refactorers & reviewers from asking that question. throw new CRM_Core_Exception('Unreachable code'); } $this->_exportMode = constant('CRM_Export_Form_Select::' . strtoupper($entityShortname) . '_EXPORT'); $this::$entityShortname = strtolower($entityShortname); $values = $this->getSearchFormValues(); $count = 0; $this->_matchingContacts = FALSE; if (CRM_Utils_Array::value('radio_ts', $values) == 'ts_sel') { foreach ($values as $key => $value) { if (strstr($key, 'mark_x')) { $count++; } if ($count > 2) { $this->_matchingContacts = TRUE; break; } } } $this->callPreProcessing(); // $component is used on CRM/Export/Form/Select.tpl to display extra information for contact export ($this->_exportMode == self::CONTACT_EXPORT) ? $component = FALSE : $component = TRUE; $this->assign('component', $component); $this->assign('isShowMergeOptions', $this->isShowContactMergeOptions()); if ($this->_componentTable) { $query = " SELECT count(*) FROM {$this->_componentTable} "; $totalSelectedRecords = CRM_Core_DAO::singleValueQuery($query); } else { $totalSelectedRecords = count($this->_componentIds); } $this->assign('totalSelectedRecords', $totalSelectedRecords); // all records actions = save a search if (($values['radio_ts'] == 'ts_all') || ($this->_task == CRM_Contact_Task::SAVE_SEARCH)) { $this->_selectAll = TRUE; $rowCount = $this->get('rowCount'); if ($rowCount > 2) { $this->_matchingContacts = TRUE; } $this->assign('totalSelectedRecords', $rowCount); } $this->assign('matchingContacts', $this->_matchingContacts); $this->set('componentIds', $this->_componentIds); $this->set('selectAll', $this->_selectAll); $this->set('exportMode', $this->_exportMode); $this->set('componentClause', $this->_componentClause); $this->set('componentTable', $this->getTableName()); } /** * Get the name of the table for the relevant entity. */ public function getTableName() { throw new CRM_Core_Exception('should be over-riden'); } /** * Build the form object. * * @return void */ public function buildQuickForm() { //export option $exportOptions = $exportOptionsJS = $mergeOptions = $mergeOptionsJS = $postalMailing = []; $exportOptions[self::EXPORT_ALL] = ts('Export PRIMARY fields'); $exportOptions[self::EXPORT_SELECTED] = ts('Select fields for export'); $mergeOptions[self::EXPORT_MERGE_DO_NOT_MERGE] = ts('Do not merge'); $mergeOptions[self::EXPORT_MERGE_SAME_ADDRESS] = ts('Merge All Contacts with the Same Address'); $mergeOptions[self::EXPORT_MERGE_HOUSEHOLD] = ts('Merge Household Members into their Households'); foreach (array_keys($exportOptions) as $key) { $exportOptionsJS[$key] = ['onClick' => 'showMappingOption( );']; } foreach (array_keys($mergeOptions) as $key) { $mergeOptionsJS[$key] = ['onclick' => 'showGreetingOptions( );']; } $this->addRadio('exportOption', ts('Export Type'), $exportOptions, [], '
', FALSE, $exportOptionsJS); $postalMailing[] = $this->createElement('advcheckbox', 'postal_mailing_export', NULL, NULL ); if ($this->_matchingContacts) { $this->_greetingOptions = self::getGreetingOptions(); foreach ($this->_greetingOptions as $key => $value) { $fieldLabel = ts('%1 (when merging contacts)', [1 => ucwords(str_replace('_', ' ', $key))]); $this->addElement('select', $key, $fieldLabel, $value, ['onchange' => "showOther(this);"] ); $this->addElement('text', "{$key}_other", ''); } } if ($this->_exportMode == self::CONTACT_EXPORT) { $this->addRadio('mergeOption', ts('Merge Options'), $mergeOptions, [], '
', FALSE, $mergeOptionsJS); $this->addGroup($postalMailing, 'postal_mailing_export', ts('Postal Mailing Export'), '
'); $this->addElement('select', 'additional_group', ts('Additional Group for Export'), ['' => ts('- select group -')] + CRM_Core_PseudoConstant::nestedGroup(), ['class' => 'crm-select2 huge'] ); } $this->buildMapping(); $this->setDefaults([ 'exportOption' => self::EXPORT_ALL, 'mergeOption' => self::EXPORT_MERGE_DO_NOT_MERGE, ]); $this->addButtons([ [ 'type' => 'next', 'name' => ts('Continue'), 'spacing' => '          ', 'isDefault' => TRUE, ], [ 'type' => 'cancel', 'name' => ts('Cancel'), ], ]); $this->addFormRule(['CRM_Export_Form_Select', 'formRule'], $this); } /** * Validation. * * @param array $params * (ref.) an assoc array of name/value pairs. * * @param $files * @param $self * * @return bool|array * mixed true or array of errors */ public static function formRule($params, $files, $self) { $errors = []; if (CRM_Utils_Array::value('mergeOption', $params) == self::EXPORT_MERGE_SAME_ADDRESS && $self->_matchingContacts ) { $greetings = [ 'postal_greeting' => 'postal_greeting_other', 'addressee' => 'addressee_other', ]; foreach ($greetings as $key => $value) { $otherOption = $params[$key] ?? NULL; if ((CRM_Utils_Array::value($otherOption, $self->_greetingOptions[$key]) == ts('Other')) && empty($params[$value])) { $label = ucwords(str_replace('_', ' ', $key)); $errors[$value] = ts('Please enter a value for %1 (when merging contacts), or select a pre-configured option from the list.', [1 => $label]); } } } return empty($errors) ? TRUE : $errors; } /** * Process the uploaded file. * * @throws \CRM_Core_Exception */ public function postProcess() { $params = $this->controller->exportValues($this->_name); $exportOption = $params['exportOption']; $mergeSameAddress = CRM_Utils_Array::value('mergeOption', $params) == self::EXPORT_MERGE_SAME_ADDRESS ? 1 : 0; $mergeSameHousehold = CRM_Utils_Array::value('mergeOption', $params) == self::EXPORT_MERGE_HOUSEHOLD ? 1 : 0; $this->set('mergeSameAddress', $mergeSameAddress); $this->set('mergeSameHousehold', $mergeSameHousehold); // instead of increasing the number of arguments to exportComponents function, we // will send $exportParams as another argument, which is an array and suppose to contain // all submitted options or any other argument $exportParams = $params; $mappingId = $params['mapping'] ?? NULL; if ($mappingId) { $this->set('mappingId', $mappingId); } else { $this->set('mappingId', NULL); } if ($exportOption == self::EXPORT_ALL) { CRM_Export_BAO_Export::exportComponents($this->_selectAll, $this->_componentIds, (array) $this->get('queryParams'), $this->get(CRM_Utils_Sort::SORT_ORDER), NULL, $this->get('returnProperties'), $this->_exportMode, $this->_componentClause, $this->_componentTable, $mergeSameAddress, $mergeSameHousehold, $exportParams, $this->get('queryOperator') ); } //reset map page $this->controller->resetPage('Map'); } /** * Return a descriptive name for the page, used in wizard header * * @return string */ public function getTitle() { return ts('Export Options'); } /** * Build mapping form element. */ public function buildMapping() { switch ($this->_exportMode) { case CRM_Export_Form_Select::CONTACT_EXPORT: $exportType = 'Export Contact'; break; case CRM_Export_Form_Select::CONTRIBUTE_EXPORT: $exportType = 'Export Contribution'; break; case CRM_Export_Form_Select::MEMBER_EXPORT: $exportType = 'Export Membership'; break; case CRM_Export_Form_Select::EVENT_EXPORT: $exportType = 'Export Participant'; break; case CRM_Export_Form_Select::PLEDGE_EXPORT: $exportType = 'Export Pledge'; break; case CRM_Export_Form_Select::CASE_EXPORT: $exportType = 'Export Case'; break; case CRM_Export_Form_Select::GRANT_EXPORT: $exportType = 'Export Grant'; break; case CRM_Export_Form_Select::ACTIVITY_EXPORT: $exportType = 'Export Activity'; break; } $this->set('mappingTypeId', CRM_Core_PseudoConstant::getKey('CRM_Core_BAO_Mapping', 'mapping_type_id', $exportType)); $mappings = CRM_Core_BAO_Mapping::getMappings($exportType, TRUE); if (!empty($mappings)) { $this->add('select2', 'mapping', ts('Use Saved Field Mapping'), $mappings, FALSE, ['placeholder' => ts('- select -')]); } } /** * @return array */ public static function getGreetingOptions() { $options = []; $greetings = [ 'postal_greeting' => 'postal_greeting_other', 'addressee' => 'addressee_other', ]; foreach ($greetings as $key => $value) { $params = []; $optionGroupId = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionGroup', $key, 'id', 'name'); CRM_Core_DAO::commonRetrieveAll('CRM_Core_DAO_OptionValue', 'option_group_id', $optionGroupId, $params, ['label', 'filter'] ); $greetingCount = 1; $options[$key] = ["$greetingCount" => ts('List of names')]; foreach ($params as $id => $field) { if (CRM_Utils_Array::value('filter', $field) == 4) { $options[$key][++$greetingCount] = $field['label']; } } $options[$key][++$greetingCount] = ts('Other'); } return $options; } /** * Get the query mode (eg. CRM_Contact_BAO_Query::MODE_CASE) * * @return int */ public function getQueryMode() { return (int) ($this->queryMode ?: $this->controller->get('component_mode')); } /** * Call the pre-processing function. */ protected function callPreProcessing(): void { throw new CRM_Core_Exception('This must be over-ridden'); } /** * Assign the title of the task to the tpl. */ protected function isShowContactMergeOptions() { throw new CRM_Core_Exception('This must be over-ridden'); } /** * Get the name of the component. * * @return array */ protected function getComponentName(): string { // CRM_Export_Controller_Standalone has this method if (method_exists($this->controller, 'getComponent')) { return $this->controller->getComponent(); } // For others, just guess based on the name of the controller $formName = CRM_Utils_System::getClassName($this->controller->getStateMachine()); $componentName = explode('_', $formName); return $componentName[1]; } /** * Get the DAO name for the given export. * * @return string */ protected function getDAOName(): string { switch ($this->getQueryMode()) { case CRM_Contact_BAO_Query::MODE_CONTRIBUTE: return 'Contribute'; case CRM_Contact_BAO_Query::MODE_MEMBER: return 'Membership'; case CRM_Contact_BAO_Query::MODE_EVENT: return 'Event'; case CRM_Contact_BAO_Query::MODE_PLEDGE: return 'Pledge'; case CRM_Contact_BAO_Query::MODE_CASE: return 'Case'; case CRM_Contact_BAO_Query::MODE_GRANT: return 'Grant'; case CRM_Contact_BAO_Query::MODE_ACTIVITY: return 'Activity'; default: return $this->controller->get('entity') ?? $this->getComponentName(); } } /** * Get the entity short name for a given export. * * @return string */ protected function getEntityShortName(): string { switch ($this->getQueryMode()) { case CRM_Contact_BAO_Query::MODE_CONTRIBUTE: return 'Contribute'; case CRM_Contact_BAO_Query::MODE_MEMBER: return 'Member'; case CRM_Contact_BAO_Query::MODE_EVENT: return 'Event'; case CRM_Contact_BAO_Query::MODE_PLEDGE: return 'Pledge'; case CRM_Contact_BAO_Query::MODE_CASE: return 'Case'; case CRM_Contact_BAO_Query::MODE_GRANT: return 'Grant'; case CRM_Contact_BAO_Query::MODE_ACTIVITY: return 'Activity'; default: return $this->getComponentName(); } } }