From 47f375b67ca2feb120f02e1475a5f49e028120ac Mon Sep 17 00:00:00 2001 From: Jaap Jansma <jaap.jansma@civicoop.org> Date: Wed, 26 Apr 2023 13:08:57 +0200 Subject: [PATCH] Added functionality to have a hard limit on a selection --- CHANGELOG.md | 1 + CRM/Contact/DataProcessorContactSearch.php | 11 ++ .../Selector/DataProcessorContactSearch.php | 1 + .../Form/Output/AbstractUIOutputForm.php | 117 ++++++++++++++++++ .../AbstractOutputExport.php | 15 ++- CRM/DataprocessorSearch/ActivitySearch.php | 10 ++ CRM/DataprocessorSearch/CaseSearch.php | 10 ++ .../ContributionSearch.php | 10 ++ .../Form/AbstractSearch.php | 77 ++++++------ CRM/DataprocessorSearch/MembershipSearch.php | 10 ++ CRM/DataprocessorSearch/ParticipantSearch.php | 10 ++ CRM/DataprocessorSearch/Search.php | 10 ++ .../DataProcessorContactSearch.tpl | 22 +++- .../Form/Output/UIOutput/CriteriaForm.tpl | 17 ++- .../OutputConfiguration/ActivitySearch.tpl | 21 ++++ .../Form/OutputConfiguration/CaseSearch.tpl | 21 ++++ .../ContributionSearch.tpl | 21 ++++ .../OutputConfiguration/MembershipSearch.tpl | 21 ++++ .../OutputConfiguration/ParticipantSearch.tpl | 21 ++++ .../Form/OutputConfiguration/Search.tpl | 21 ++++ 20 files changed, 402 insertions(+), 45 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed1a360e..0f7d2683 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ * Added field output handler: Arthmetic Operations. * Added field output handler for date range segments based on months. * Fixed issue with permission to view contact. Also works now without a user record +* Added functionality to have a hard limit on a selection # Version 1.66 diff --git a/CRM/Contact/DataProcessorContactSearch.php b/CRM/Contact/DataProcessorContactSearch.php index 4bd7c327..36906804 100644 --- a/CRM/Contact/DataProcessorContactSearch.php +++ b/CRM/Contact/DataProcessorContactSearch.php @@ -60,6 +60,9 @@ class CRM_Contact_DataProcessorContactSearch implements UIFormOutputInterface { $form->add('checkbox', 'expanded_search', E::ts('Expand criteria form initially?')); + $form->add('checkbox', 'enable_hard_limit', E::ts('Enable Hard Limit?')); + $form->add('text', 'default_hard_limit', E::ts('Default Hard Limit'), array('class' => 'huge'), false); + $form->addYesNo('link_to_view_contact', E::ts('Add link to view contact?')); // navigation field @@ -106,6 +109,12 @@ class CRM_Contact_DataProcessorContactSearch implements UIFormOutputInterface { else { $defaults['link_to_view_contact'] = TRUE; } + if (isset($output['configuration']['enable_hard_limit'])) { + $defaults['enable_hard_limit'] = $output['configuration']['enable_hard_limit']; + } + if (isset($output['configuration']['default_hard_limit'])) { + $defaults['default_hard_limit'] = $output['configuration']['default_hard_limit']; + } } } if (!isset($defaults['permission'])) { @@ -144,6 +153,8 @@ class CRM_Contact_DataProcessorContactSearch implements UIFormOutputInterface { $configuration['help_text'] = $submittedValues['help_text']; $configuration['expanded_search'] = isset($submittedValues['expanded_search']) ? $submittedValues['expanded_search'] : false; $configuration['link_to_view_contact'] = $submittedValues['link_to_view_contact']; + $configuration['enable_hard_limit'] = isset($submittedValues['enable_hard_limit']) ? $submittedValues['enable_hard_limit'] : false; + $configuration['default_hard_limit'] = $submittedValues['default_hard_limit']; return $configuration; } diff --git a/CRM/Contact/Selector/DataProcessorContactSearch.php b/CRM/Contact/Selector/DataProcessorContactSearch.php index 52a2a33e..86240431 100644 --- a/CRM/Contact/Selector/DataProcessorContactSearch.php +++ b/CRM/Contact/Selector/DataProcessorContactSearch.php @@ -44,6 +44,7 @@ class CRM_Contact_Selector_DataProcessorContactSearch { } $this->dataProcessorClass->getDataFlow()->addSort($sortField['name'], $sortDirection); } + CRM_Dataprocessor_Form_Output_AbstractUIOutputForm::applyLimit($this->dataProcessorClass, $formValues); } /** diff --git a/CRM/Dataprocessor/Form/Output/AbstractUIOutputForm.php b/CRM/Dataprocessor/Form/Output/AbstractUIOutputForm.php index fd3885eb..88ab305d 100644 --- a/CRM/Dataprocessor/Form/Output/AbstractUIOutputForm.php +++ b/CRM/Dataprocessor/Form/Output/AbstractUIOutputForm.php @@ -4,6 +4,7 @@ * @license AGPL-3.0 */ +use Civi\DataProcessor\DataFlow\InvalidFlowException; use Civi\DataProcessor\FilterHandler\AbstractFilterHandler; use Civi\DataProcessor\Output\UIOutputInterface; use Civi\DataProcessor\ProcessorType\AbstractProcessorType; @@ -199,6 +200,122 @@ abstract class CRM_Dataprocessor_Form_Output_AbstractUIOutputForm extends CRM_Co return $errors; } + /** + * Returns whether hard limit is enabled. + * + * @return bool + */ + protected function isHardLimitEnabled(): bool { + if (isset($this->dataProcessorOutput['configuration']) && isset($this->dataProcessorOutput['configuration']['enable_hard_limit']) && $this->dataProcessorOutput['configuration']['enable_hard_limit']) { + return true; + } + return false; + } + + /** + * Returns the default hard limit + * + * @return string + */ + protected function getDefaultHardLimit(): string { + if (isset($this->dataProcessorOutput['configuration']) && isset($this->dataProcessorOutput['configuration']['default_hard_limit'])) { + return $this->dataProcessorOutput['configuration']['default_hard_limit']; + } + return ''; + } + + /** + * Returns the default row limit. + * + * @return int + */ + protected static function getDefaultLimit(): int { + return CRM_Utils_Pager::ROWCOUNT; + } + + /** + * Returns the count of the current data processor. + * Taking into account a hard limit (if set). + * + * @param \Civi\DataProcessor\ProcessorType\AbstractProcessorType $dataProcessor + * @param array|NULL $submittedValues + * + * @return int + */ + public static function getCount(AbstractProcessorType $dataProcessor, array $submittedValues = null): int { + $count = 0; + try { + $count = $dataProcessor->getDataFlow()->recordCount(); + $hardLimit = static::getHardLimit($submittedValues); + if ($hardLimit && $count > $hardLimit) { + $count = $hardLimit; + } + } catch (InvalidFlowException $e) { + } + return $count; + } + + /** + * Apply the offset and limit + * + * @param \Civi\DataProcessor\ProcessorType\AbstractProcessorType $dataProcessor + * @param array|null $submittedValues + * + * @return void + */ + public static function applyLimit(AbstractProcessorType $dataProcessor, array $submittedValues = null) { + $hardLimit = static::getHardLimit($submittedValues); + $limit = static::getDefaultLimit(); + if (isset($submittedValues['crmRowCount']) && $submittedValues['crmRowCount']) { + $limit = $submittedValues['crmRowCount']; + } + $pageId = isset($submittedValues['crmPID']) ?? 1; + $offset = static::getOffset($pageId, $limit, $hardLimit); + if ($hardLimit && $limit > $hardLimit) { + $limit = $hardLimit; + } + try { + $dataProcessor->getDataFlow()->setOffset($offset); + $dataProcessor->getDataFlow()->setLimit($limit); + } catch (InvalidFlowException $e) { + } + } + + /** + * Returns the hard limit values + * + * @param array|null $submittedValues + * @return int|null + */ + protected static function getHardLimit(array $submittedValues=null):? int { + if (isset($submittedValues['hard_limit']) && is_numeric($submittedValues['hard_limit'])) { + return (int) $submittedValues['hard_limit']; + } + return null; + } + + /** + * Returns the offset for this page + * + * @param int $pageId + * @param int $limit + * @param int|NULL $hardLimit + * + * @return int + */ + public static function getOffset(int $pageId, int $limit, int $hardLimit = null): int { + if ($pageId) { + $offset = ($pageId - 1) * $limit; + } else { + $offset = 0; + } + if ($hardLimit && $offset > $hardLimit) { + $pageId = $hardLimit / $limit; + $offset = ($pageId -1) * $limit; + } + return $offset; + } + /** * Apply the filters to the database processor */ diff --git a/CRM/DataprocessorOutputExport/AbstractOutputExport.php b/CRM/DataprocessorOutputExport/AbstractOutputExport.php index 7bd700f0..b735d256 100644 --- a/CRM/DataprocessorOutputExport/AbstractOutputExport.php +++ b/CRM/DataprocessorOutputExport/AbstractOutputExport.php @@ -205,15 +205,22 @@ abstract class CRM_DataprocessorOutputExport_AbstractOutputExport implements Exp public function downloadExport(AbstractProcessorType $dataProcessorClass, $dataProcessor, $outputBAO, $formValues, $sortFieldName = null, $sortDirection = 'ASC', $idField=null, $selectedIds=array()) { try { static::addSelectedIdsFilterToDataProcessor($dataProcessorClass, $idField, $selectedIds); - if ($dataProcessorClass->getDataFlow()->recordCount() > $this->getMaxDirectDownload()) { + $count = CRM_Dataprocessor_Form_Output_AbstractUIOutputForm::getCount($dataProcessorClass, $formValues); + if ($count > $this->getMaxDirectDownload()) { $this->startBatchJob($dataProcessorClass, $dataProcessor, $outputBAO, $formValues, $sortFieldName, $sortDirection, $idField, $selectedIds); } else { + $dataProcessorClass->getDataFlow()->setOffset(0); + $dataProcessorClass->getDataFlow()->setLimit($count); $this->doDirectDownload($dataProcessorClass, $dataProcessor, $outputBAO, $sortFieldName, $sortDirection, $idField, $selectedIds, $formValues); } } catch (InvalidFlowException $e) { } } + public static function getHardLimit(array $formValues):? int { + return 2; + } + /** * Get the download name of the export file. * @@ -304,11 +311,7 @@ abstract class CRM_DataprocessorOutputExport_AbstractOutputExport implements Exp //now add this task to the queue $queue->createItem($task); - $count = 0; - try { - $count = $dataProcessorClass->getDataFlow()->recordCount(); - } catch (InvalidFlowException $e) { - } + $count = CRM_Dataprocessor_Form_Output_AbstractUIOutputForm::getCount($dataProcessorClass, $formValues); $recordsPerJob = $this->getJobSize(); for($i=0; $i < $count; $i = $i + $recordsPerJob) { $title = E::ts('Exporting records %1/%2', array( diff --git a/CRM/DataprocessorSearch/ActivitySearch.php b/CRM/DataprocessorSearch/ActivitySearch.php index f03a4858..4bee8bd0 100644 --- a/CRM/DataprocessorSearch/ActivitySearch.php +++ b/CRM/DataprocessorSearch/ActivitySearch.php @@ -59,6 +59,8 @@ class CRM_DataprocessorSearch_ActivitySearch implements UIFormOutputInterface { $form->add('wysiwyg', 'help_text', E::ts('Help text for this search'), array('rows' => 6, 'cols' => 80)); $form->add('text', 'no_result_text', E::ts('No result text'), array('class' => 'huge'), false); $form->add('checkbox', 'expanded_search', E::ts('Expand criteria form initially')); + $form->add('checkbox', 'enable_hard_limit', E::ts('Enable Hard Limit?')); + $form->add('text', 'default_hard_limit', E::ts('Default Hard Limit'), array('class' => 'huge'), false); // navigation field $navigationOptions = $navigation->getNavigationOptions(); @@ -97,6 +99,12 @@ class CRM_DataprocessorSearch_ActivitySearch implements UIFormOutputInterface { if (isset($output['configuration']['expanded_search'])) { $defaults['expanded_search'] = $output['configuration']['expanded_search']; } + if (isset($output['configuration']['enable_hard_limit'])) { + $defaults['enable_hard_limit'] = $output['configuration']['enable_hard_limit']; + } + if (isset($output['configuration']['default_hard_limit'])) { + $defaults['default_hard_limit'] = $output['configuration']['default_hard_limit']; + } } } if (!isset($defaults['permission'])) { @@ -133,6 +141,8 @@ class CRM_DataprocessorSearch_ActivitySearch implements UIFormOutputInterface { $configuration['hidden_fields'] = $submittedValues['hidden_fields']; $configuration['help_text'] = $submittedValues['help_text']; $configuration['expanded_search'] = isset($submittedValues['expanded_search']) ? $submittedValues['expanded_search'] : false; + $configuration['enable_hard_limit'] = isset($submittedValues['enable_hard_limit']) ? $submittedValues['enable_hard_limit'] : false; + $configuration['default_hard_limit'] = $submittedValues['default_hard_limit']; return $configuration; } diff --git a/CRM/DataprocessorSearch/CaseSearch.php b/CRM/DataprocessorSearch/CaseSearch.php index 26fb5190..ecbb892d 100644 --- a/CRM/DataprocessorSearch/CaseSearch.php +++ b/CRM/DataprocessorSearch/CaseSearch.php @@ -65,6 +65,8 @@ class CRM_DataprocessorSearch_CaseSearch implements UIFormOutputInterface { $form->add('text', 'no_result_text', E::ts('No result text'), array('class' => 'huge'), false); $form->add('checkbox', 'expanded_search', E::ts('Expand criteria form initially')); $form->add('checkbox', 'show_manage_case', E::ts('Show manage case column')); + $form->add('checkbox', 'enable_hard_limit', E::ts('Enable Hard Limit?')); + $form->add('text', 'default_hard_limit', E::ts('Default Hard Limit'), array('class' => 'huge'), false); // navigation field $navigationOptions = $navigation->getNavigationOptions(); @@ -109,6 +111,12 @@ class CRM_DataprocessorSearch_CaseSearch implements UIFormOutputInterface { if (isset($output['configuration']['show_manage_case'])) { $defaults['show_manage_case'] = $output['configuration']['show_manage_case']; } + if (isset($output['configuration']['enable_hard_limit'])) { + $defaults['enable_hard_limit'] = $output['configuration']['enable_hard_limit']; + } + if (isset($output['configuration']['default_hard_limit'])) { + $defaults['default_hard_limit'] = $output['configuration']['default_hard_limit']; + } } } if (!isset($defaults['permission'])) { @@ -147,6 +155,8 @@ class CRM_DataprocessorSearch_CaseSearch implements UIFormOutputInterface { $configuration['help_text'] = $submittedValues['help_text']; $configuration['expanded_search'] = isset($submittedValues['expanded_search']) ? $submittedValues['expanded_search'] : false; $configuration['show_manage_case'] = isset($submittedValues['show_manage_case']) ? $submittedValues['show_manage_case'] : false; + $configuration['enable_hard_limit'] = isset($submittedValues['enable_hard_limit']) ? $submittedValues['enable_hard_limit'] : false; + $configuration['default_hard_limit'] = $submittedValues['default_hard_limit']; return $configuration; } diff --git a/CRM/DataprocessorSearch/ContributionSearch.php b/CRM/DataprocessorSearch/ContributionSearch.php index c77a785d..aa054ba9 100644 --- a/CRM/DataprocessorSearch/ContributionSearch.php +++ b/CRM/DataprocessorSearch/ContributionSearch.php @@ -59,6 +59,8 @@ class CRM_DataprocessorSearch_ContributionSearch implements UIFormOutputInterfac $form->add('wysiwyg', 'help_text', E::ts('Help text for this search'), array('rows' => 6, 'cols' => 80)); $form->add('text', 'no_result_text', E::ts('No result text'), array('class' => 'huge'), false); $form->add('checkbox', 'expanded_search', E::ts('Expand criteria form initially')); + $form->add('checkbox', 'enable_hard_limit', E::ts('Enable Hard Limit?')); + $form->add('text', 'default_hard_limit', E::ts('Default Hard Limit'), array('class' => 'huge'), false); // navigation field $navigationOptions = $navigation->getNavigationOptions(); @@ -97,6 +99,12 @@ class CRM_DataprocessorSearch_ContributionSearch implements UIFormOutputInterfac if (isset($output['configuration']['expanded_search'])) { $defaults['expanded_search'] = $output['configuration']['expanded_search']; } + if (isset($output['configuration']['enable_hard_limit'])) { + $defaults['enable_hard_limit'] = $output['configuration']['enable_hard_limit']; + } + if (isset($output['configuration']['default_hard_limit'])) { + $defaults['default_hard_limit'] = $output['configuration']['default_hard_limit']; + } } } if (!isset($defaults['permission'])) { @@ -133,6 +141,8 @@ class CRM_DataprocessorSearch_ContributionSearch implements UIFormOutputInterfac $configuration['no_result_text'] = $submittedValues['no_result_text']; $configuration['help_text'] = $submittedValues['help_text']; $configuration['expanded_search'] = isset($submittedValues['expanded_search']) ? $submittedValues['expanded_search'] : false; + $configuration['enable_hard_limit'] = isset($submittedValues['enable_hard_limit']) ? $submittedValues['enable_hard_limit'] : false; + $configuration['default_hard_limit'] = $submittedValues['default_hard_limit']; return $configuration; } diff --git a/CRM/DataprocessorSearch/Form/AbstractSearch.php b/CRM/DataprocessorSearch/Form/AbstractSearch.php index 78de8b18..3408e08f 100644 --- a/CRM/DataprocessorSearch/Form/AbstractSearch.php +++ b/CRM/DataprocessorSearch/Form/AbstractSearch.php @@ -118,6 +118,18 @@ abstract class CRM_DataprocessorSearch_Form_AbstractSearch extends CRM_Dataproce return false; } + /** + * Returns the key for the (prevnext) cache + * @return string + */ + protected function getCacheKey(): string { + $qfKeyParam = CRM_Utils_Array::value('qfKey', $this->_formValues); + if (empty($qfKeyParam) && $this->controller->_key) { + $qfKeyParam = $this->controller->_key; + } + return "civicrm search " . $qfKeyParam; + } + /** * Returns whether the ID field is Visible * @@ -219,6 +231,10 @@ abstract class CRM_DataprocessorSearch_Form_AbstractSearch extends CRM_Dataproce $this->_formValues = $this->controller->exportValues($this->_name); } + if ($this->isHardLimitEnabled() && !isset($this->_formValues['hard_limit'])) { + $this->_formValues['hard_limit'] = $this->getDefaultHardLimit(); + } + $this->_searchButtonName = $this->getButtonName('refresh'); $this->_actionButtonName = $this->getButtonName('next', 'action'); $this->_done = FALSE; @@ -240,9 +256,8 @@ abstract class CRM_DataprocessorSearch_Form_AbstractSearch extends CRM_Dataproce $this->sort->initSortID($this->_formValues[CRM_Utils_Sort::SORT_ID]); } $this->assign_by_ref('sort', $this->sort); - $limit = CRM_Utils_Request::retrieveValue('crmRowCount', 'Positive', $this->getDefaultLimit()); $pageId = CRM_Utils_Request::retrieveValue('crmPID', 'Positive', 1); - $this->buildRows($pageId, $limit); + $this->buildRows($pageId); $this->addExportOutputs(); } @@ -265,22 +280,12 @@ abstract class CRM_DataprocessorSearch_Form_AbstractSearch extends CRM_Dataproce return false; } - /** - * Returns the default row limit. - * - * @return int - */ - protected function getDefaultLimit(): int { - return CRM_Utils_Pager::ROWCOUNT; - } - /** * Retrieve the records from the data processor * * @param $pageId - * @param $limit */ - protected function buildRows($pageId, $limit) { + protected function buildRows($pageId) { $rows = []; $ids = array(); $prevnextData = array(); @@ -288,12 +293,8 @@ abstract class CRM_DataprocessorSearch_Form_AbstractSearch extends CRM_Dataproce $id_field = $this->getIdFieldName(); $this->assign('id_field', $id_field); - - $offset = ($pageId - 1) * $limit; try { - $this->dataProcessorClass->getDataFlow()->setLimit($limit); - $this->dataProcessorClass->getDataFlow()->setOffset($offset); - self::applyFilters($this->dataProcessorClass, $this->_formValues); + static::applyFilters($this->dataProcessorClass, $this->_formValues); // Set the sort if ($this->sort->getCurrentSortID() > 1) { @@ -310,11 +311,12 @@ abstract class CRM_DataprocessorSearch_Form_AbstractSearch extends CRM_Dataproce } elseif ($id_field) { $this->dataProcessorClass->getDataFlow()->addSort($id_field, 'ASC'); } + static::applyLimit($this->dataProcessorClass, $this->_formValues); $this->alterDataProcessor($this->dataProcessorClass); $this->dataProcessorClass->postInitialize(); $pagerParams = $this->getPagerParams(); - $pagerParams['total'] = $this->dataProcessorClass->getDataFlow()->recordCount(); + $pagerParams['total'] = static::getCount($this->dataProcessorClass, $this->_formValues); $pagerParams['pageID'] = $pageId; $this->pager = new CRM_Utils_Pager($pagerParams); $this->assign('pager', $this->pager); @@ -354,7 +356,7 @@ abstract class CRM_DataprocessorSearch_Form_AbstractSearch extends CRM_Dataproce $prevnextData[] = array( 'entity_id1' => $row['id'], 'entity_table' => $this->getEntityTable(), - 'data' => json_encode($record), + 'data' => '', // json_encode($record), ); } $ids[] = $row['id']; @@ -381,8 +383,7 @@ abstract class CRM_DataprocessorSearch_Form_AbstractSearch extends CRM_Dataproce } if ($this->usePrevNextCache()) { - $cacheKey = "civicrm search {$this->controller->_key}"; - CRM_DataprocessorSearch_Utils_PrevNextCache::fillWithArray($cacheKey, $prevnextData); + CRM_DataprocessorSearch_Utils_PrevNextCache::fillWithArray($this->getCacheKey(), $prevnextData); } else { $this->retrieveEntityIds(); } @@ -437,7 +438,7 @@ abstract class CRM_DataprocessorSearch_Form_AbstractSearch extends CRM_Dataproce $params['total'] = 0; $params['status'] =E::ts('%%StatusMessage%%'); $params['csvString'] = NULL; - $params['rowCount'] = $this->getDefaultLimit(); + $params['rowCount'] = static::getDefaultLimit(); $params['buttonTop'] = 'PagerTopButton'; $params['buttonBottom'] = 'PagerBottomButton'; return $params; @@ -493,6 +494,12 @@ abstract class CRM_DataprocessorSearch_Form_AbstractSearch extends CRM_Dataproce $this->assign_by_ref('selectedIds', $selectedIds); $this->add('hidden', 'context'); $this->add('hidden', CRM_Utils_Sort::SORT_ID); + + $this->assign('hard_limit_enabled', $this->isHardLimitEnabled()); + if ($this->isHardLimitEnabled()) { + $this->add('text', 'hard_limit', E::ts('Hard Limit')); + $this->setDefaults(['hard_limit' => $this->getDefaultHardLimit()]); + } } public function setDefaultValues(): array { @@ -526,8 +533,7 @@ abstract class CRM_DataprocessorSearch_Form_AbstractSearch extends CRM_Dataproce ($this->_force && !$crmPID) ) { //reset the cache table for new search - $cacheKey = "civicrm search {$this->controller->_key}"; - CRM_DataprocessorSearch_Utils_PrevNextCache::deleteItem(NULL, $cacheKey); + CRM_DataprocessorSearch_Utils_PrevNextCache::deleteItem(NULL, $this->getCacheKey()); } if (!empty($_POST)) { @@ -581,19 +587,12 @@ abstract class CRM_DataprocessorSearch_Form_AbstractSearch extends CRM_Dataproce return $this->entityIDs; } $this->entityIDs = []; - $qfKeyParam = CRM_Utils_Array::value('qfKey', $this->_formValues); - if (empty($qfKeyParam) && $this->controller->_key) { - $qfKeyParam = $this->controller->_key; - } // We use ajax to handle selections only if the search results component_mode is set to "contacts" if ($this->usePrevNextCache()) { $this->addClass('crm-ajax-selection-form'); - if ($qfKeyParam) { - $qfKeyParam = "civicrm search $qfKeyParam"; - $selectedIdsArr = CRM_DataprocessorSearch_Utils_PrevNextCache::getSelection($qfKeyParam); - if (isset($selectedIdsArr[$qfKeyParam]) && is_array($selectedIdsArr[$qfKeyParam])) { - $this->entityIDs = array_keys($selectedIdsArr[$qfKeyParam]); - } + $selectedIdsArr = CRM_DataprocessorSearch_Utils_PrevNextCache::getSelection($this->getCacheKey()); + if (isset($selectedIdsArr[$this->getCacheKey()]) && is_array($selectedIdsArr[$this->getCacheKey()])) { + $this->entityIDs = array_keys($selectedIdsArr[$this->getCacheKey()]); } } else { if (isset($this->_formValues['radio_ts']) && $this->_formValues['radio_ts'] == 'ts_sel') { @@ -604,7 +603,11 @@ abstract class CRM_DataprocessorSearch_Form_AbstractSearch extends CRM_Dataproce } } elseif (!$skipSelectAll && (!isset($this->_formValues['radio_ts']) || $this->_formValues['radio_ts'] == 'ts_all')) { try { - $this->dataProcessorClass->getDataFlow()->setLimit(FALSE); + $limit = FALSE; + if ($this->getHardLimit()) { + $limit = $this->getHardLimit(); + } + $this->dataProcessorClass->getDataFlow()->setLimit($limit); $this->dataProcessorClass->getDataFlow()->setOffset(0); $id_field = $this->getIdFieldName(); while ($record = $this->dataProcessorClass->getDataFlow() @@ -630,7 +633,7 @@ abstract class CRM_DataprocessorSearch_Form_AbstractSearch extends CRM_Dataproce // We use ajax to handle selections only if the search results component_mode is set to "contacts" if ($this->allRecordsSelected()) { try { - return $this->dataProcessorClass->getDataFlow()->recordCount(); + return static::getCount($this->dataProcessorClass, $this->_formValues); } catch (InvalidFlowException $e) { // Do nothing } diff --git a/CRM/DataprocessorSearch/MembershipSearch.php b/CRM/DataprocessorSearch/MembershipSearch.php index 4b63d1a0..c48766b0 100644 --- a/CRM/DataprocessorSearch/MembershipSearch.php +++ b/CRM/DataprocessorSearch/MembershipSearch.php @@ -59,6 +59,8 @@ class CRM_DataprocessorSearch_MembershipSearch implements UIFormOutputInterface $form->add('wysiwyg', 'help_text', E::ts('Help text for this search'), array('rows' => 6, 'cols' => 80)); $form->add('text', 'no_result_text', E::ts('No result text'), array('class' => 'huge'), false); $form->add('checkbox', 'expanded_search', E::ts('Expand criteria form initially')); + $form->add('checkbox', 'enable_hard_limit', E::ts('Enable Hard Limit?')); + $form->add('text', 'default_hard_limit', E::ts('Default Hard Limit'), array('class' => 'huge'), false); // navigation field $navigationOptions = $navigation->getNavigationOptions(); @@ -97,6 +99,12 @@ class CRM_DataprocessorSearch_MembershipSearch implements UIFormOutputInterface if (isset($output['configuration']['expanded_search'])) { $defaults['expanded_search'] = $output['configuration']['expanded_search']; } + if (isset($output['configuration']['enable_hard_limit'])) { + $defaults['enable_hard_limit'] = $output['configuration']['enable_hard_limit']; + } + if (isset($output['configuration']['default_hard_limit'])) { + $defaults['default_hard_limit'] = $output['configuration']['default_hard_limit']; + } } } if (!isset($defaults['permission'])) { @@ -133,6 +141,8 @@ class CRM_DataprocessorSearch_MembershipSearch implements UIFormOutputInterface $configuration['hidden_fields'] = $submittedValues['hidden_fields']; $configuration['help_text'] = $submittedValues['help_text']; $configuration['expanded_search'] = isset($submittedValues['expanded_search']) ? $submittedValues['expanded_search'] : false; + $configuration['enable_hard_limit'] = isset($submittedValues['enable_hard_limit']) ? $submittedValues['enable_hard_limit'] : false; + $configuration['default_hard_limit'] = $submittedValues['default_hard_limit']; return $configuration; } diff --git a/CRM/DataprocessorSearch/ParticipantSearch.php b/CRM/DataprocessorSearch/ParticipantSearch.php index 4bfdcef9..628e29a1 100644 --- a/CRM/DataprocessorSearch/ParticipantSearch.php +++ b/CRM/DataprocessorSearch/ParticipantSearch.php @@ -59,6 +59,8 @@ class CRM_DataprocessorSearch_ParticipantSearch implements UIFormOutputInterface $form->add('wysiwyg', 'help_text', E::ts('Help text for this search'), array('rows' => 6, 'cols' => 80)); $form->add('text', 'no_result_text', E::ts('No result text'), array('class' => 'huge'), false); $form->add('checkbox', 'expanded_search', E::ts('Expand criteria form initially')); + $form->add('checkbox', 'enable_hard_limit', E::ts('Enable Hard Limit?')); + $form->add('text', 'default_hard_limit', E::ts('Default Hard Limit'), array('class' => 'huge'), false); // navigation field $navigationOptions = $navigation->getNavigationOptions(); @@ -97,6 +99,12 @@ class CRM_DataprocessorSearch_ParticipantSearch implements UIFormOutputInterface if (isset($output['configuration']['expanded_search'])) { $defaults['expanded_search'] = $output['configuration']['expanded_search']; } + if (isset($output['configuration']['enable_hard_limit'])) { + $defaults['enable_hard_limit'] = $output['configuration']['enable_hard_limit']; + } + if (isset($output['configuration']['default_hard_limit'])) { + $defaults['default_hard_limit'] = $output['configuration']['default_hard_limit']; + } } } if (!isset($defaults['permission'])) { @@ -133,6 +141,8 @@ class CRM_DataprocessorSearch_ParticipantSearch implements UIFormOutputInterface $configuration['hidden_fields'] = $submittedValues['hidden_fields']; $configuration['help_text'] = $submittedValues['help_text']; $configuration['expanded_search'] = isset($submittedValues['expanded_search']) ? $submittedValues['expanded_search'] : false; + $configuration['enable_hard_limit'] = isset($submittedValues['enable_hard_limit']) ? $submittedValues['enable_hard_limit'] : false; + $configuration['default_hard_limit'] = $submittedValues['default_hard_limit']; return $configuration; } diff --git a/CRM/DataprocessorSearch/Search.php b/CRM/DataprocessorSearch/Search.php index 27f39f9b..f2e8f267 100644 --- a/CRM/DataprocessorSearch/Search.php +++ b/CRM/DataprocessorSearch/Search.php @@ -62,6 +62,8 @@ class CRM_DataprocessorSearch_Search implements UIFormOutputInterface { $form->add('checkbox', 'expanded_search', E::ts('Expand criteria form initially')); $form->add('checkbox', 'expose_aggregate', E::ts('Expose aggregate options')); $form->add('checkbox', 'expose_hidden_fields', E::ts('Expose hidden field options')); + $form->add('checkbox', 'enable_hard_limit', E::ts('Enable Hard Limit?')); + $form->add('text', 'default_hard_limit', E::ts('Default Hard Limit'), array('class' => 'huge'), false); // navigation field $navigationOptions = $navigation->getNavigationOptions(); @@ -106,6 +108,12 @@ class CRM_DataprocessorSearch_Search implements UIFormOutputInterface { if (isset($output['configuration']['expose_hidden_fields'])) { $defaults['expose_hidden_fields'] = $output['configuration']['expose_hidden_fields']; } + if (isset($output['configuration']['enable_hard_limit'])) { + $defaults['enable_hard_limit'] = $output['configuration']['enable_hard_limit']; + } + if (isset($output['configuration']['default_hard_limit'])) { + $defaults['default_hard_limit'] = $output['configuration']['default_hard_limit']; + } } } if (!isset($defaults['permission'])) { @@ -143,6 +151,8 @@ class CRM_DataprocessorSearch_Search implements UIFormOutputInterface { $configuration['expanded_search'] = isset($submittedValues['expanded_search']) ? $submittedValues['expanded_search'] : false; $configuration['expose_aggregate'] = isset($submittedValues['expose_aggregate']) ? $submittedValues['expose_aggregate'] : false; $configuration['expose_hidden_fields'] = isset($submittedValues['expose_hidden_fields']) ? $submittedValues['expose_hidden_fields'] : false; + $configuration['enable_hard_limit'] = isset($submittedValues['enable_hard_limit']) ? $submittedValues['enable_hard_limit'] : false; + $configuration['default_hard_limit'] = $submittedValues['default_hard_limit']; return $configuration; } diff --git a/templates/CRM/Contact/Form/OutputConfiguration/DataProcessorContactSearch.tpl b/templates/CRM/Contact/Form/OutputConfiguration/DataProcessorContactSearch.tpl index 45c0c497..0ef5ba2a 100644 --- a/templates/CRM/Contact/Form/OutputConfiguration/DataProcessorContactSearch.tpl +++ b/templates/CRM/Contact/Form/OutputConfiguration/DataProcessorContactSearch.tpl @@ -54,5 +54,25 @@ <div class="content">{$form.no_result_text.html}</div> <div class="clear"></div> </div> - + <div class="crm-section"> + <div class="label">{$form.enable_hard_limit.label}</div> + <div class="content">{$form.enable_hard_limit.html}</div> + <div class="clear"></div> + </div> + <div class="crm-section" id="section_default_hard_limit"> + <div class="label">{$form.default_hard_limit.label}</div> + <div class="content">{$form.default_hard_limit.html}</div> + <div class="clear"></div> + </div> {/crmScope} +{literal} +<script type="text/javascript"> + cj("#enable_hard_limit").click(function() { + if (this.checked) { + cj('#section_default_hard_limit').show(); + } else { + cj('#section_default_hard_limit').hide(); + } + }).click(); +</script> +{/literal} diff --git a/templates/CRM/Dataprocessor/Form/Output/UIOutput/CriteriaForm.tpl b/templates/CRM/Dataprocessor/Form/Output/UIOutput/CriteriaForm.tpl index 7c8776a3..d7c9ab6e 100644 --- a/templates/CRM/Dataprocessor/Form/Output/UIOutput/CriteriaForm.tpl +++ b/templates/CRM/Dataprocessor/Form/Output/UIOutput/CriteriaForm.tpl @@ -1,5 +1,5 @@ {crmScope extensionKey='dataprocessor'} -{if $has_exposed_filters} +{if $has_exposed_filters || $hard_limit_enabled} <div class="crm-form-block crm-search-form-block"> <div id="searchForm" class="form-item"> <div class="crm-accordion-wrapper crm-advanced_search_form-accordion {if (!empty($dataprocessor_rows))}collapsed{/if}"> @@ -8,6 +8,7 @@ </div> <!-- /.crm-accordion-header --> <div class="crm-accordion-body"> + {if $has_exposed_filters} {foreach from=$filters item=filterCollection} {if $filterCollection.title} <div class="crm-accordion-wrapper {$filterCollection.class}"> @@ -38,6 +39,20 @@ </div> {/if} {/foreach} + {/if} + {if $hard_limit_enabled} + <div class="crm-accordion-wrapper"> + <div class="crm-accordion-header">{ts}Limit results to a maximum number of records.{/ts}</div> + <div class="crm-accordion-body"> + <table> + <tr> + <td class="label">{$form.hard_limit.label}</td> + <td>{$form.hard_limit.html}</td> + </tr> + </table> + </div> + </div> + {/if} <div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location="botton"}</div> </div> </div> diff --git a/templates/CRM/DataprocessorSearch/Form/OutputConfiguration/ActivitySearch.tpl b/templates/CRM/DataprocessorSearch/Form/OutputConfiguration/ActivitySearch.tpl index 75a77ac7..48889342 100644 --- a/templates/CRM/DataprocessorSearch/Form/OutputConfiguration/ActivitySearch.tpl +++ b/templates/CRM/DataprocessorSearch/Form/OutputConfiguration/ActivitySearch.tpl @@ -49,4 +49,25 @@ <div class="content">{$form.no_result_text.html}</div> <div class="clear"></div> </div> + <div class="crm-section"> + <div class="label">{$form.enable_hard_limit.label}</div> + <div class="content">{$form.enable_hard_limit.html}</div> + <div class="clear"></div> + </div> + <div class="crm-section" id="section_default_hard_limit"> + <div class="label">{$form.default_hard_limit.label}</div> + <div class="content">{$form.default_hard_limit.html}</div> + <div class="clear"></div> + </div> {/crmScope} +{literal} + <script type="text/javascript"> + cj("#enable_hard_limit").click(function() { + if (this.checked) { + cj('#section_default_hard_limit').show(); + } else { + cj('#section_default_hard_limit').hide(); + } + }).click(); + </script> +{/literal} diff --git a/templates/CRM/DataprocessorSearch/Form/OutputConfiguration/CaseSearch.tpl b/templates/CRM/DataprocessorSearch/Form/OutputConfiguration/CaseSearch.tpl index d97b2625..54d1df4c 100644 --- a/templates/CRM/DataprocessorSearch/Form/OutputConfiguration/CaseSearch.tpl +++ b/templates/CRM/DataprocessorSearch/Form/OutputConfiguration/CaseSearch.tpl @@ -59,4 +59,25 @@ <div class="content">{$form.no_result_text.html}</div> <div class="clear"></div> </div> + <div class="crm-section"> + <div class="label">{$form.enable_hard_limit.label}</div> + <div class="content">{$form.enable_hard_limit.html}</div> + <div class="clear"></div> + </div> + <div class="crm-section" id="section_default_hard_limit"> + <div class="label">{$form.default_hard_limit.label}</div> + <div class="content">{$form.default_hard_limit.html}</div> + <div class="clear"></div> + </div> {/crmScope} +{literal} + <script type="text/javascript"> + cj("#enable_hard_limit").click(function() { + if (this.checked) { + cj('#section_default_hard_limit').show(); + } else { + cj('#section_default_hard_limit').hide(); + } + }).click(); + </script> +{/literal} diff --git a/templates/CRM/DataprocessorSearch/Form/OutputConfiguration/ContributionSearch.tpl b/templates/CRM/DataprocessorSearch/Form/OutputConfiguration/ContributionSearch.tpl index 400045fb..0fbc2323 100644 --- a/templates/CRM/DataprocessorSearch/Form/OutputConfiguration/ContributionSearch.tpl +++ b/templates/CRM/DataprocessorSearch/Form/OutputConfiguration/ContributionSearch.tpl @@ -49,4 +49,25 @@ <div class="content">{$form.no_result_text.html}</div> <div class="clear"></div> </div> + <div class="crm-section"> + <div class="label">{$form.enable_hard_limit.label}</div> + <div class="content">{$form.enable_hard_limit.html}</div> + <div class="clear"></div> + </div> + <div class="crm-section" id="section_default_hard_limit"> + <div class="label">{$form.default_hard_limit.label}</div> + <div class="content">{$form.default_hard_limit.html}</div> + <div class="clear"></div> + </div> {/crmScope} +{literal} + <script type="text/javascript"> + cj("#enable_hard_limit").click(function() { + if (this.checked) { + cj('#section_default_hard_limit').show(); + } else { + cj('#section_default_hard_limit').hide(); + } + }).click(); + </script> +{/literal} diff --git a/templates/CRM/DataprocessorSearch/Form/OutputConfiguration/MembershipSearch.tpl b/templates/CRM/DataprocessorSearch/Form/OutputConfiguration/MembershipSearch.tpl index c3603719..f3122a3f 100644 --- a/templates/CRM/DataprocessorSearch/Form/OutputConfiguration/MembershipSearch.tpl +++ b/templates/CRM/DataprocessorSearch/Form/OutputConfiguration/MembershipSearch.tpl @@ -49,4 +49,25 @@ <div class="content">{$form.no_result_text.html}</div> <div class="clear"></div> </div> + <div class="crm-section"> + <div class="label">{$form.enable_hard_limit.label}</div> + <div class="content">{$form.enable_hard_limit.html}</div> + <div class="clear"></div> + </div> + <div class="crm-section" id="section_default_hard_limit"> + <div class="label">{$form.default_hard_limit.label}</div> + <div class="content">{$form.default_hard_limit.html}</div> + <div class="clear"></div> + </div> {/crmScope} +{literal} + <script type="text/javascript"> + cj("#enable_hard_limit").click(function() { + if (this.checked) { + cj('#section_default_hard_limit').show(); + } else { + cj('#section_default_hard_limit').hide(); + } + }).click(); + </script> +{/literal} diff --git a/templates/CRM/DataprocessorSearch/Form/OutputConfiguration/ParticipantSearch.tpl b/templates/CRM/DataprocessorSearch/Form/OutputConfiguration/ParticipantSearch.tpl index b6b741c2..cdc792c2 100644 --- a/templates/CRM/DataprocessorSearch/Form/OutputConfiguration/ParticipantSearch.tpl +++ b/templates/CRM/DataprocessorSearch/Form/OutputConfiguration/ParticipantSearch.tpl @@ -49,4 +49,25 @@ <div class="content">{$form.no_result_text.html}</div> <div class="clear"></div> </div> + <div class="crm-section"> + <div class="label">{$form.enable_hard_limit.label}</div> + <div class="content">{$form.enable_hard_limit.html}</div> + <div class="clear"></div> + </div> + <div class="crm-section" id="section_default_hard_limit"> + <div class="label">{$form.default_hard_limit.label}</div> + <div class="content">{$form.default_hard_limit.html}</div> + <div class="clear"></div> + </div> {/crmScope} +{literal} + <script type="text/javascript"> + cj("#enable_hard_limit").click(function() { + if (this.checked) { + cj('#section_default_hard_limit').show(); + } else { + cj('#section_default_hard_limit').hide(); + } + }).click(); + </script> +{/literal} diff --git a/templates/CRM/DataprocessorSearch/Form/OutputConfiguration/Search.tpl b/templates/CRM/DataprocessorSearch/Form/OutputConfiguration/Search.tpl index 519e7f27..653944b5 100644 --- a/templates/CRM/DataprocessorSearch/Form/OutputConfiguration/Search.tpl +++ b/templates/CRM/DataprocessorSearch/Form/OutputConfiguration/Search.tpl @@ -59,4 +59,25 @@ <div class="content">{$form.no_result_text.html}</div> <div class="clear"></div> </div> + <div class="crm-section"> + <div class="label">{$form.enable_hard_limit.label}</div> + <div class="content">{$form.enable_hard_limit.html}</div> + <div class="clear"></div> + </div> + <div class="crm-section" id="section_default_hard_limit"> + <div class="label">{$form.default_hard_limit.label}</div> + <div class="content">{$form.default_hard_limit.html}</div> + <div class="clear"></div> + </div> {/crmScope} +{literal} + <script type="text/javascript"> + cj("#enable_hard_limit").click(function() { + if (this.checked) { + cj('#section_default_hard_limit').show(); + } else { + cj('#section_default_hard_limit').hide(); + } + }).click(); + </script> +{/literal} -- GitLab