request = $request; $this->report = $report; } /** * Filters the given data table * * @param DataTable $table */ public function filter($table) { $this->applyGenericFilters($table); } /** * Makes sure a set of filters are not run. * * @param string[] $filterNames The name of each filter to disable. */ public function disableFilters($filterNames) { $this->disabledFilters = array_unique(array_merge($this->disabledFilters, $filterNames)); } /** * Returns an array containing the information of the generic Filter * to be applied automatically to the data resulting from the API calls. * * Order to apply the filters: * 1 - Filter that remove filtered rows * 2 - Filter that sort the remaining rows * 3 - Filter that keep only a subset of the results * 4 - Presentation filters * * @return array See the code for spec */ public static function getGenericFiltersInformation() { return array( array('Pattern', array( 'filter_column' => array('string', 'label'), 'filter_pattern' => array('string') )), array('PatternRecursive', array( 'filter_column_recursive' => array('string', 'label'), 'filter_pattern_recursive' => array('string'), )), array('ExcludeLowPopulation', array( 'filter_excludelowpop' => array('string'), 'filter_excludelowpop_value' => array('float', '0'), )), array('Sort', array( 'filter_sort_column' => array('string'), 'filter_sort_order' => array('string', 'desc'), $naturalSort = true, $recursiveSort = true, 'filter_sort_column_secondary' => true )), array('Truncate', array( 'filter_truncate' => array('integer'), )), array('Limit', array( 'filter_offset' => array('integer', '0'), 'filter_limit' => array('integer'), 'keep_summary_row' => array('integer', '0'), )) ); } private function getGenericFiltersHavingDefaultValues() { $filters = self::getGenericFiltersInformation(); if ($this->report && $this->report->getDefaultSortColumn()) { foreach ($filters as $index => $filter) { if ($filter[0] === 'Sort') { $filters[$index][1]['filter_sort_column'] = array('string', $this->report->getDefaultSortColumn()); $filters[$index][1]['filter_sort_order'] = array('string', $this->report->getDefaultSortOrder()); $callback = $this->report->getSecondarySortColumnCallback(); if (is_callable($callback)) { $filters[$index][1]['filter_sort_column_secondary'] = $callback; } } } } return $filters; } /** * Apply generic filters to the DataTable object resulting from the API Call. * Disable this feature by setting the parameter disable_generic_filters to 1 in the API call request. * * @param DataTable $datatable * @return bool */ protected function applyGenericFilters($datatable) { if ($datatable instanceof DataTable\Map) { $tables = $datatable->getDataTables(); foreach ($tables as $table) { $this->applyGenericFilters($table); } return; } $tableDisabledFilters = $datatable->getMetadata(DataTable::GENERIC_FILTERS_TO_DISABLE_METADATA_NAME) ?: []; $genericFilters = $this->getGenericFiltersHavingDefaultValues(); $filterApplied = false; foreach ($genericFilters as $filterMeta) { $filterName = $filterMeta[0]; $filterParams = $filterMeta[1]; $filterParameters = array(); $exceptionRaised = false; if (in_array($filterName, $this->disabledFilters) || in_array($filterName, $tableDisabledFilters) ) { continue; } foreach ($filterParams as $name => $info) { if (!is_array($info)) { // hard coded value that cannot be changed via API, see eg $naturalSort = true in 'Sort' $filterParameters[] = $info; } else { // parameter type to cast to $type = $info[0]; // default value if specified, when the parameter doesn't have a value $defaultValue = null; if (isset($info[1])) { $defaultValue = $info[1]; } try { $value = Common::getRequestVar($name, $defaultValue, $type, $this->request); settype($value, $type); $filterParameters[] = $value; } catch (Exception $e) { $exceptionRaised = true; break; } } } if (!$exceptionRaised) { $datatable->filter($filterName, $filterParameters); $filterApplied = true; } } return $filterApplied; } public function areProcessedMetricsNeededFor($metrics) { $columnQueryParameters = array( 'filter_column', 'filter_column_recursive', 'filter_excludelowpop', 'filter_sort_column' ); foreach ($columnQueryParameters as $queryParamName) { $queryParamValue = Common::getRequestVar($queryParamName, false, $type = null, $this->request); if (!empty($queryParamValue) && $this->containsProcessedMetric($metrics, $queryParamValue) ) { return true; } } return false; } /** * @param ProcessedMetric[] $metrics * @param string $name * @return bool */ private function containsProcessedMetric($metrics, $name) { foreach ($metrics as $metric) { if ($metric instanceof ProcessedMetric && $metric->getName() == $name ) { return true; } } return false; } }