update Piwik to version 2.16 (fixes #91)

This commit is contained in:
oliver 2016-04-10 18:55:57 +02:00
commit d885a4baa9
5833 changed files with 418860 additions and 226988 deletions

View file

@ -1,6 +1,6 @@
<?php
/**
* Piwik - Open source web analytics
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
@ -22,64 +22,64 @@ use Piwik\ViewDataTable\RequestConfig as VizRequest;
/**
* The base class of all report visualizations.
*
*
* ViewDataTable instances load analytics data via Piwik's Reporting API and then output some
* type of visualization of that data.
*
*
* Visualizations can be in any format. HTML-based visualizations should extend
* {@link Visualization}. Visualizations that use other formats, such as visualizations
* that output an image, should extend ViewDataTable directly.
*
* ### Creating ViewDataTables
*
*
* ViewDataTable instances are not created via the new operator, instead the {@link Piwik\ViewDataTable\Factory}
* class is used.
*
*
* The specific subclass to create is determined, first, by the **viewDataTable** query paramater.
* If this parameter is not set, then the default visualization type for the report being
* displayed is used.
*
* ### Configuring ViewDataTables
*
*
* **Display properties**
*
*
* ViewDataTable output can be customized by setting one of many available display
* properties. Display properties are stored as fields in {@link Piwik\ViewDataTable\Config} objects.
* ViewDataTables store a {@link Piwik\ViewDataTable\Config} object in the {@link $config} field.
*
*
* Display properties can be set at any time before rendering.
*
*
* **Request properties**
*
*
* Request properties are similar to display properties in the way they are set. They are,
* however, not used to customize ViewDataTable instances, but in the request to Piwik's
* API when loading analytics data.
*
*
* Request properties are set by setting the fields of a {@link Piwik\ViewDataTable\RequestConfig} object stored in
* the {@link $requestConfig} field. They can be set at any time before rendering.
* Setting them after data is loaded will have no effect.
*
*
* **Customizing how reports are displayed**
*
*
* Each individual report should be rendered in its own controller method. There are two
* ways to render a report within its controller method. You can either:
*
*
* 1. manually create and configure a ViewDataTable instance
* 2. invoke {@link Piwik\Plugin\Controller::renderReport} and configure the ViewDataTable instance
* in the {@hook ViewDataTable.configure} event.
*
*
* ViewDataTable instances are configured by setting and modifying display properties and request
* properties.
*
*
* ### Creating new visualizations
*
*
* New visualizations can be created by extending the ViewDataTable class or one of its
* descendants. To learn more [read our guide on creating new visualizations](/guides/visualizing-report-data#creating-new-visualizations).
*
*
* ### Examples
*
*
* **Manually configuring a ViewDataTable**
*
*
* // a controller method that displays a single report
* public function myReport()
* {
@ -89,18 +89,18 @@ use Piwik\ViewDataTable\RequestConfig as VizRequest;
* // ...
* return $view->render();
* }
*
*
* **Using {@link Piwik\Plugin\Controller::renderReport}**
*
*
* First, a controller method that displays a single report:
*
*
* public function myReport()
* {
* return $this->renderReport(__FUNCTION__);`
* }
*
*
* Then the event handler for the {@hook ViewDataTable.configure} event:
*
*
* public function configureViewDataTable(ViewDataTable $view)
* {
* switch ($view->requestConfig->apiMethodToRequestDataTable) {
@ -111,32 +111,32 @@ use Piwik\ViewDataTable\RequestConfig as VizRequest;
* break;
* }
* }
*
*
* **Using custom configuration objects in a new visualization**
*
*
* class MyVisualizationConfig extends Piwik\ViewDataTable\Config
* {
* public $my_new_property = true;
* }
*
*
* class MyVisualizationRequestConfig extends Piwik\ViewDataTable\RequestConfig
* {
* public $my_new_property = false;
* }
*
*
* class MyVisualization extends Piwik\Plugin\ViewDataTable
* {
* public static function getDefaultConfig()
* {
* return new MyVisualizationConfig();
* }
*
*
* public static function getDefaultRequestConfig()
* {
* return new MyVisualizationRequestConfig();
* }
* }
*
*
*
* @api
*/
@ -153,14 +153,14 @@ abstract class ViewDataTable implements ViewInterface
/**
* Contains display properties for this visualization.
*
*
* @var \Piwik\ViewDataTable\Config
*/
public $config;
/**
* Contains request properties for this visualization.
*
*
* @var \Piwik\ViewDataTable\RequestConfig
*/
public $requestConfig;
@ -175,7 +175,7 @@ abstract class ViewDataTable implements ViewInterface
* Posts the {@hook ViewDataTable.configure} event which plugins can use to configure the
* way reports are displayed.
*/
public function __construct($controllerAction, $apiMethodToRequestDataTable)
public function __construct($controllerAction, $apiMethodToRequestDataTable, $overrideParams = array())
{
list($controllerName, $controllerAction) = explode('.', $controllerAction);
@ -191,13 +191,53 @@ abstract class ViewDataTable implements ViewInterface
$this->requestConfig->apiMethodToRequestDataTable = $apiMethodToRequestDataTable;
$report = Report::factory($this->requestConfig->getApiModuleToRequest(), $this->requestConfig->getApiMethodToRequest());
if (!empty($report)) {
/** @var Report $report */
$subtable = $report->getActionToLoadSubTables();
if (!empty($subtable)) {
$this->config->subtable_controller_action = $subtable;
}
$this->config->show_goals = $report->hasGoalMetrics();
$relatedReports = $report->getRelatedReports();
if (!empty($relatedReports)) {
foreach ($relatedReports as $relatedReport) {
$widgetTitle = $relatedReport->getWidgetTitle();
if ($widgetTitle && Common::getRequestVar('widget', 0, 'int')) {
$relatedReportName = $widgetTitle;
} else {
$relatedReportName = $relatedReport->getName();
}
$this->config->addRelatedReport($relatedReport->getModule() . '.' . $relatedReport->getAction(),
$relatedReportName);
}
}
$metrics = $report->getMetrics();
if (!empty($metrics)) {
$this->config->addTranslations($metrics);
}
$processedMetrics = $report->getProcessedMetrics();
if (!empty($processedMetrics)) {
$this->config->addTranslations($processedMetrics);
}
$report->configureView($this);
}
/**
* Triggered during {@link ViewDataTable} construction. Subscribers should customize
* the view based on the report that is being displayed.
*
*
* Plugins that define their own reports must subscribe to this event in order to
* specify how the Piwik UI should display the report.
*
*
* **Example**
*
* // event handler
@ -210,7 +250,7 @@ abstract class ViewDataTable implements ViewInterface
* break;
* }
* }
*
*
* @param ViewDataTable $view The instance to configure.
*/
Piwik::postEvent('ViewDataTable.configure', array($this));
@ -229,16 +269,17 @@ abstract class ViewDataTable implements ViewInterface
$this->requestConfig->filter_excludelowpop_value = $function();
}
$this->overrideViewPropertiesWithParams($overrideParams);
$this->overrideViewPropertiesWithQueryParams();
}
protected function assignRelatedReportsTitle()
{
if(!empty($this->config->related_reports_title)) {
if (!empty($this->config->related_reports_title)) {
// title already assigned by a plugin
return;
}
if(count($this->config->related_reports) == 1) {
if (count($this->config->related_reports) == 1) {
$this->config->related_reports_title = Piwik::translate('General_RelatedReport') . ':';
} else {
$this->config->related_reports_title = Piwik::translate('General_RelatedReports') . ':';
@ -247,12 +288,12 @@ abstract class ViewDataTable implements ViewInterface
/**
* Returns the default config instance.
*
*
* Visualizations that define their own display properties should override this method and
* return an instance of their new {@link Piwik\ViewDataTable\Config} descendant.
*
* See the last example {@link ViewDataTable here} for more information.
*
*
* @return \Piwik\ViewDataTable\Config
*/
public static function getDefaultConfig()
@ -262,12 +303,12 @@ abstract class ViewDataTable implements ViewInterface
/**
* Returns the default request config instance.
*
*
* Visualizations that define their own request properties should override this method and
* return an instance of their new {@link Piwik\ViewDataTable\RequestConfig} descendant.
*
* See the last example {@link ViewDataTable here} for more information.
*
*
* @return \Piwik\ViewDataTable\RequestConfig
*/
public static function getDefaultRequestConfig()
@ -275,7 +316,7 @@ abstract class ViewDataTable implements ViewInterface
return new VizRequest();
}
protected function loadDataTableFromAPI($fixedRequestParams = array())
protected function loadDataTableFromAPI()
{
if (!is_null($this->dataTable)) {
// data table is already there
@ -283,14 +324,14 @@ abstract class ViewDataTable implements ViewInterface
return $this->dataTable;
}
$this->dataTable = $this->request->loadDataTableFromAPI($fixedRequestParams);
$this->dataTable = $this->request->loadDataTableFromAPI();
return $this->dataTable;
}
/**
* Returns the viewDataTable ID for this DataTable visualization.
*
*
* Derived classes should not override this method. They should instead declare a const ID field
* with the viewDataTable ID.
*
@ -306,13 +347,13 @@ abstract class ViewDataTable implements ViewInterface
throw new \Exception($message);
}
return $id;
return $id;
}
/**
* Returns `true` if this instance's or any of its ancestors' viewDataTable IDs equals the supplied ID,
* `false` if otherwise.
*
*
* Can be used to test whether a ViewDataTable object is an instance of a certain visualization or not,
* without having to know where that visualization is.
*
@ -399,7 +440,7 @@ abstract class ViewDataTable implements ViewInterface
if (property_exists($this->requestConfig, $name)) {
$this->requestConfig->$name = $this->getPropertyFromQueryParam($name, $this->requestConfig->$name);
} elseif (property_exists($this->config, $name)) {
$this->config->$name = $this->getPropertyFromQueryParam($name, $this->config->$name);
$this->config->$name = $this->getPropertyFromQueryParam($name, $this->config->$name);
}
}
@ -443,7 +484,7 @@ abstract class ViewDataTable implements ViewInterface
/**
* Returns `true` if this visualization can display some type of data or not.
*
*
* New visualization classes should override this method if they can only visualize certain
* types of data. The evolution graph visualization, for example, can only visualize
* sets of DataTables. If the API method used results in a single DataTable, the evolution
@ -456,4 +497,63 @@ abstract class ViewDataTable implements ViewInterface
{
return $view->config->show_all_views_icons;
}
private function overrideViewPropertiesWithParams($overrideParams)
{
if (empty($overrideParams)) {
return;
}
foreach ($overrideParams as $key => $value) {
if (property_exists($this->requestConfig, $key)) {
$this->requestConfig->$key = $value;
} elseif (property_exists($this->config, $key)) {
$this->config->$key = $value;
} elseif ($key != 'enable_filter_excludelowpop') {
$this->config->custom_parameters[$key] = $value;
}
}
}
/**
* Display a meaningful error message when any invalid parameter is being set.
*
* @param $overrideParams
* @throws
*/
public function throwWhenSettingNonOverridableParameter($overrideParams)
{
$nonOverridableParams = $this->getNonOverridableParams($overrideParams);
if(count($nonOverridableParams) > 0) {
throw new \Exception(sprintf(
"Setting parameters %s is not allowed. Please report this bug to the Piwik team.",
implode(" and ", $nonOverridableParams)
));
}
}
/**
* @param $overrideParams
* @return array
*/
public function getNonOverridableParams($overrideParams)
{
$paramsCannotBeOverridden = array();
foreach ($overrideParams as $paramName => $paramValue) {
if (property_exists($this->requestConfig, $paramName)) {
$allowedParams = $this->requestConfig->overridableProperties;
} elseif (property_exists($this->config, $paramName)) {
$allowedParams = $this->config->overridableProperties;
} else {
// setting Config.custom_parameters is always allowed
continue;
}
if (!in_array($paramName, $allowedParams)) {
$paramsCannotBeOverridden[] = $paramName;
}
}
return $paramsCannotBeOverridden;
}
}