Skip to content

Commit

Permalink
Merge pull request #6243 from piwik/6078
Browse files Browse the repository at this point in the history
Adding new PivotByDimension DataTable filter that can pivot a report by (almost) any dimension. refs #6078
  • Loading branch information
Matthieu Aubry committed Sep 21, 2014
2 parents b82aca5 + 3d04d15 commit 2fc11ee
Show file tree
Hide file tree
Showing 63 changed files with 2,455 additions and 64 deletions.
11 changes: 11 additions & 0 deletions config/global.ini.php
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,17 @@
; If set to 0 it also disables the "sent plugin update emails" feature in general and the related setting in the UI.
enable_update_communication = 1

; This controls whether the pivotBy query parameter can be used with any dimension or just subtable
; dimensions. If set to 1, it will fetch a report with a segment for each row of the table being pivoted.
; At present, this is very inefficient, so it is disabled by default.
pivot_by_filter_enable_fetch_by_segment = 0

; This controls the default maximum number of columns to display in a pivot table. Since a pivot table displays
; a table's rows as columns, the number of columns can become very large, which will affect webpage layouts.
; Set to -1 to specify no limit. Note: The pivotByColumnLimit query parameter can be used to override this default
; on a per-request basis;
pivot_by_filter_default_column_limit = 10

[Tracker]
; Piwik uses first party cookies by default. If set to 1,
; the visit ID cookie will be set on the Piwik server domain as well
Expand Down
5 changes: 5 additions & 0 deletions core/API/DocumentationGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,11 @@ public function getExampleUrl($class, $methodName, $parametersToSet = array())
$aParameters['hideColumns'] = false;
$aParameters['showColumns'] = false;
$aParameters['filter_pattern_recursive'] = false;
$aParameters['pivotBy'] = false;
$aParameters['pivotByColumn'] = false;
$aParameters['pivotByColumnLimit'] = false;
$aParameters['disable_queued_filters'] = false;
$aParameters['disable_generic_filters'] = false;

$moduleName = Proxy::getInstance()->getModuleNameFromClassName($class);
$aParameters = array_merge(array('module' => 'API', 'method' => $moduleName . '.' . $methodName), $aParameters);
Expand Down
14 changes: 13 additions & 1 deletion core/API/ResponseBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Piwik\API\DataTableManipulator\ReportTotalsCalculator;
use Piwik\Common;
use Piwik\DataTable;
use Piwik\DataTable\Filter\PivotByDimension;
use Piwik\DataTable\Renderer;
use Piwik\DataTable\DataTableInterface;
use Piwik\DataTable\Filter\ColumnDelete;
Expand Down Expand Up @@ -157,10 +158,21 @@ private function formatExceptionMessage(Exception $exception)
return Renderer::formatValueXml($message);
}

protected function handleDataTable($datatable)
protected function handleDataTable(DataTableInterface $datatable)
{
$label = $this->getLabelFromRequest($this->request);

// handle pivot by dimension filter
$pivotBy = Common::getRequestVar('pivotBy', false, 'string', $this->request);
if (!empty($pivotBy)) {
$reportId = $this->apiModule . '.' . $this->apiMethod;
$pivotByColumn = Common::getRequestVar('pivotByColumn', false, 'string', $this->request);
$pivotByColumnLimit = Common::getRequestVar('pivotByColumnLimit', false, 'int', $this->request);

$datatable->filter('PivotByDimension', array($reportId, $pivotBy, $pivotByColumn, $pivotByColumnLimit,
PivotByDimension::isSegmentFetchingEnabledInConfig()));
}

// if requested, flatten nested tables
if (Common::getRequestVar('flat', '0', 'string', $this->request) == '1') {
$flattener = new Flattener($this->apiModule, $this->apiMethod, $this->request);
Expand Down
21 changes: 20 additions & 1 deletion core/Columns/Dimension.php
Original file line number Diff line number Diff line change
Expand Up @@ -195,10 +195,29 @@ public static function getAllDimensions()
* @return Dimension|null The created instance or null if there is no Dimension for
* $dimensionId or if the plugin that contains the Dimension is
* not loaded.
* @api
*/
public static function factory($dimensionId)
{
list($module, $dimension) = explode('.', $dimensionId);
return ComponentFactory::factory($module, $dimension, __CLASS__);
}
}

/**
* Returns the name of the plugin that contains this Dimension.
*
* @return string
* @throws Exception if the Dimension is not located within a Plugin module.
* @api
*/
public function getModule()
{
$id = $this->getId();
if (empty($id)) {
throw new Exception("Invalid dimension ID: '$id'.");
}

$parts = explode('.', $id);
return reset($parts);
}
}
12 changes: 10 additions & 2 deletions core/DataTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ public function applyQueuedFilters()
foreach ($this->queuedFilters as $filter) {
$this->filter($filter['className'], $filter['parameters']);
}
$this->queuedFilters = array();
$this->clearQueuedFilters();
}

/**
Expand Down Expand Up @@ -1634,6 +1634,14 @@ protected function aggregateRowFromSimpleTable($row)
$thisRow->sumRow($row, $copyMeta = true, $this->getMetadata(self::COLUMN_AGGREGATION_OPS_METADATA_NAME));
}

/**
* Unsets all queued filters.
*/
public function clearQueuedFilters()
{
$this->queuedFilters = array();
}

/**
* @return \ArrayIterator|Row[]
*/
Expand Down Expand Up @@ -1662,4 +1670,4 @@ public function offsetUnset($offset)
{
$this->deleteRow($offset);
}
}
}

0 comments on commit 2fc11ee

Please sign in to comment.