diff options
author | Matthieu Aubry <matt@piwik.org> | 2015-03-18 05:33:52 +0300 |
---|---|---|
committer | Matthieu Aubry <matt@piwik.org> | 2015-03-18 05:33:52 +0300 |
commit | c3bc0113fe3043b53ff6a96e766c2fc8dc0f1229 (patch) | |
tree | 923a51de4569ddec60bd3e22133b03b9d4c47cd9 /core/API | |
parent | 7e0d617359f0baf167d3f053f3e99a60e3c09a86 (diff) | |
parent | 76f7d00e92caed107b00b5e4c68218ea6ed78fcb (diff) |
Merge pull request #7465 from piwik/datatable_tweaks
Various performance improvements and bugfixes.
Diffstat (limited to 'core/API')
-rw-r--r-- | core/API/DataTableGenericFilter.php | 2 | ||||
-rw-r--r-- | core/API/DataTableManipulator/LabelFilter.php | 7 | ||||
-rw-r--r-- | core/API/DataTableManipulator/ReportTotalsCalculator.php | 117 | ||||
-rw-r--r-- | core/API/DataTablePostProcessor.php | 4 |
4 files changed, 73 insertions, 57 deletions
diff --git a/core/API/DataTableGenericFilter.php b/core/API/DataTableGenericFilter.php index ff49491642..1554703910 100644 --- a/core/API/DataTableGenericFilter.php +++ b/core/API/DataTableGenericFilter.php @@ -11,6 +11,7 @@ namespace Piwik\API; use Exception; use Piwik\Common; use Piwik\DataTable; +use Piwik\Plugin; use Piwik\Plugin\ProcessedMetric; use Piwik\Plugin\Report; @@ -120,6 +121,7 @@ class DataTableGenericFilter 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()); } } } diff --git a/core/API/DataTableManipulator/LabelFilter.php b/core/API/DataTableManipulator/LabelFilter.php index 0d4e11772a..c691398a40 100644 --- a/core/API/DataTableManipulator/LabelFilter.php +++ b/core/API/DataTableManipulator/LabelFilter.php @@ -64,6 +64,10 @@ class LabelFilter extends DataTableManipulator */ private function doFilterRecursiveDescend($labelParts, $dataTable) { + // we need to make sure to rebuild the index as some filters change the label column directly via + // $row->setColumn('label', '') which would not be noticed in the label index otherwise. + $dataTable->rebuildIndex(); + // search for the first part of the tree search $labelPart = array_shift($labelParts); @@ -102,6 +106,9 @@ class LabelFilter extends DataTableManipulator protected function manipulateSubtableRequest($request) { unset($request['label']); + unset($request['flat']); + $request['totals'] = 0; + $request['filter_sort_column'] = ''; // do not sort, we only want to find a matching column return $request; } diff --git a/core/API/DataTableManipulator/ReportTotalsCalculator.php b/core/API/DataTableManipulator/ReportTotalsCalculator.php index 4703c36c7d..2631b43d5a 100644 --- a/core/API/DataTableManipulator/ReportTotalsCalculator.php +++ b/core/API/DataTableManipulator/ReportTotalsCalculator.php @@ -23,6 +23,31 @@ use Piwik\Plugin\Report; class ReportTotalsCalculator extends DataTableManipulator { /** + * Array [readableMetric] => [summed value] + * @var array + */ + private $totals = array(); + + /** + * @var Report + */ + private $report; + + /** + * Constructor + * + * @param bool $apiModule + * @param bool $apiMethod + * @param array $request + * @param Report $report + */ + public function __construct($apiModule = false, $apiMethod = false, $request = array(), $report = null) + { + parent::__construct($apiModule, $apiMethod, $request); + $this->report = $report; + } + + /** * @param DataTable $table * @return \Piwik\DataTable|\Piwik\DataTable\Map */ @@ -53,66 +78,32 @@ class ReportTotalsCalculator extends DataTableManipulator */ protected function manipulateDataTable($dataTable) { - $report = $this->findCurrentReport(); - - if (!empty($report) && !$report->getDimension() && !$this->isReportAllMetricsReport($report)) { + if (!empty($this->report) && !$this->report->getDimension() && !$this->isAllMetricsReport()) { // we currently do not calculate the total value for reports having no dimension return $dataTable; } - // Array [readableMetric] => [summed value] - $totalValues = array(); - + $this->totals = array(); $firstLevelTable = $this->makeSureToWorkOnFirstLevelDataTable($dataTable); $metricsToCalculate = Metrics::getMetricIdsToProcessReportTotal(); - $realMetricNames = array(); + $metricNames = array(); foreach ($metricsToCalculate as $metricId) { - $metricName = Metrics::getReadableColumnName($metricId); - $realMetricName = $this->hasDataTableMetric($firstLevelTable, $metricId, $metricName); - if (!empty($realMetricName)) { - $realMetricNames[$metricName] = $realMetricName; - } + $metricNames[$metricId] = Metrics::getReadableColumnName($metricId);; } foreach ($firstLevelTable->getRows() as $row) { $columns = $row->getColumns(); - foreach ($realMetricNames as $metricName => $realMetricName) { - $totalValues = $this->sumColumnValueToTotal($columns, $metricName, $realMetricName, $totalValues); + foreach ($metricNames as $metricId => $metricName) { + $this->sumColumnValueToTotal($columns, $metricId, $metricName); } } - $dataTable->setMetadata('totals', $totalValues); + $dataTable->setMetadata('totals', $this->totals); return $dataTable; } - private function hasDataTableMetric(DataTable $dataTable, $metricId, $readableColumnName) - { - $firstRow = $dataTable->getFirstRow(); - - if (empty($firstRow)) { - return false; - } - - $columnAlternatives = array( - $metricId, - $readableColumnName, - // TODO: this and below is a hack to get report totals to work correctly w/ MultiSites.getAll. can be corrected - // when all metrics are described by Metadata classes & internal naming quirks are handled by core system. - 'Goal_' . $readableColumnName, - 'Actions_' . $readableColumnName - ); - - foreach ($columnAlternatives as $column) { - if ($firstRow->getColumn($column) !== false) { - return $column; - } - } - - return false; - } - private function makeSureToWorkOnFirstLevelDataTable($table) { if (!array_key_exists('idSubtable', $this->request)) { @@ -155,25 +146,40 @@ class ReportTotalsCalculator extends DataTableManipulator return $table; } - private function sumColumnValueToTotal($columns, $metricName, $realMetricId, $totalValues) + private function sumColumnValueToTotal($columns, $metricId, $metricName) { $value = false; - if (array_key_exists($realMetricId, $columns)) { - $value = $columns[$realMetricId]; - } - - if (false === $value) { + if (array_key_exists($metricId, $columns)) { + $value = $columns[$metricId]; + } + + if ($value === false) { + // we do not add $metricId to $possibleMetricNames for a small performance improvement since in most cases + // $metricId should be present in $columns so we avoid this foreach loop + $possibleMetricNames = array( + $metricName, + // TODO: this and below is a hack to get report totals to work correctly w/ MultiSites.getAll. can be corrected + // when all metrics are described by Metadata classes & internal naming quirks are handled by core system. + 'Goal_' . $metricName, + 'Actions_' . $metricName + ); + foreach ($possibleMetricNames as $possibleMetricName) { + if (array_key_exists($possibleMetricName, $columns)) { + $value = $columns[$possibleMetricName]; + break; + } + } - return $totalValues; + if ($value === false) { + return; + } } - if (array_key_exists($metricName, $totalValues)) { - $totalValues[$metricName] += $value; + if (array_key_exists($metricName, $this->totals)) { + $this->totals[$metricName] += $value; } else { - $totalValues[$metricName] = $value; + $this->totals[$metricName] = $value; } - - return $totalValues; } /** @@ -188,6 +194,7 @@ class ReportTotalsCalculator extends DataTableManipulator $request['expanded'] = 0; $request['filter_limit'] = -1; $request['filter_offset'] = 0; + $request['filter_sort_column'] = ''; $parametersToRemove = array('flat'); @@ -221,8 +228,8 @@ class ReportTotalsCalculator extends DataTableManipulator return null; } - private function isReportAllMetricsReport(Report $report) + private function isAllMetricsReport() { - return $report->getModule() == 'API' && $report->getAction() == 'get'; + return $this->report->getModule() == 'API' && $this->report->getAction() == 'get'; } } diff --git a/core/API/DataTablePostProcessor.php b/core/API/DataTablePostProcessor.php index 8d936e6779..24d8cf8b6c 100644 --- a/core/API/DataTablePostProcessor.php +++ b/core/API/DataTablePostProcessor.php @@ -191,8 +191,8 @@ class DataTablePostProcessor public function applyTotalsCalculator($dataTable) { if (1 == Common::getRequestVar('totals', '1', 'integer', $this->request)) { - $reportTotalsCalculator = new ReportTotalsCalculator($this->apiModule, $this->apiMethod, $this->request); - $dataTable = $reportTotalsCalculator->calculate($dataTable); + $calculator = new ReportTotalsCalculator($this->apiModule, $this->apiMethod, $this->request, $this->report); + $dataTable = $calculator->calculate($dataTable); } return $dataTable; } |