update Piwik to version 2.16 (fixes #91)
This commit is contained in:
parent
296343bf3b
commit
d885a4baa9
5833 changed files with 418860 additions and 226988 deletions
|
|
@ -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
|
||||
|
|
@ -11,22 +11,24 @@ namespace Piwik\Plugins\API;
|
|||
use Exception;
|
||||
use Piwik\API\Request;
|
||||
use Piwik\Archive\DataTableFactory;
|
||||
use Piwik\CacheId;
|
||||
use Piwik\Cache as PiwikCache;
|
||||
use Piwik\Common;
|
||||
use Piwik\DataTable;
|
||||
use Piwik\DataTable\Row;
|
||||
use Piwik\DataTable\Simple;
|
||||
use Piwik\DataTable;
|
||||
use Piwik\Date;
|
||||
use Piwik\Metrics;
|
||||
use Piwik\MetricsFormatter;
|
||||
use Piwik\Metrics\Formatter;
|
||||
use Piwik\Period;
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Plugin\Report;
|
||||
use Piwik\Site;
|
||||
use Piwik\Timer;
|
||||
use Piwik\Url;
|
||||
|
||||
class ProcessedReport
|
||||
{
|
||||
|
||||
/**
|
||||
* Loads reports metadata, then return the requested one,
|
||||
* matching optional API parameters.
|
||||
|
|
@ -38,8 +40,10 @@ class ProcessedReport
|
|||
|
||||
foreach ($reportsMetadata as $report) {
|
||||
// See ArchiveProcessor/Aggregator.php - unique visitors are not processed for period != day
|
||||
// todo: should use SettingsPiwik::isUniqueVisitorsEnabled instead
|
||||
if (($period && $period != 'day') && !($apiModule == 'VisitsSummary' && $apiAction == 'get')) {
|
||||
unset($report['metrics']['nb_uniq_visitors']);
|
||||
unset($report['metrics']['nb_users']);
|
||||
}
|
||||
if ($report['module'] == $apiModule
|
||||
&& $report['action'] == $apiAction
|
||||
|
|
@ -148,31 +152,45 @@ class ProcessedReport
|
|||
Piwik::checkUserHasViewAccess($idSites);
|
||||
}
|
||||
|
||||
// as they cache key contains a lot of information there would be an even better cache result by caching parts of
|
||||
// this huge method separately but that makes it also more complicated. leaving it like this for now.
|
||||
$key = $this->buildReportMetadataCacheKey($idSites, $period, $date, $hideMetricsDoc, $showSubtableReports);
|
||||
$key = CacheId::pluginAware($key);
|
||||
$cache = PiwikCache::getTransientCache();
|
||||
|
||||
if ($cache->contains($key)) {
|
||||
return $cache->fetch($key);
|
||||
}
|
||||
|
||||
$parameters = array('idSites' => $idSites, 'period' => $period, 'date' => $date);
|
||||
|
||||
$availableReports = array();
|
||||
|
||||
foreach (Report::getAllReports() as $report) {
|
||||
$report->configureReportMetadata($availableReports, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggered when gathering metadata for all available reports.
|
||||
*
|
||||
*
|
||||
* Plugins that define new reports should use this event to make them available in via
|
||||
* the metadata API. By doing so, the report will become available in scheduled reports
|
||||
* as well as in the Piwik Mobile App. In fact, any third party app that uses the metadata
|
||||
* API will automatically have access to the new report.
|
||||
*
|
||||
*
|
||||
* @param string &$availableReports The list of available reports. Append to this list
|
||||
* to make a report available.
|
||||
*
|
||||
*
|
||||
* Every element of this array must contain the following
|
||||
* information:
|
||||
*
|
||||
*
|
||||
* - **category**: A translated string describing the report's category.
|
||||
* - **name**: The translated display title of the report.
|
||||
* - **module**: The plugin of the report.
|
||||
* - **action**: The API method that serves the report.
|
||||
*
|
||||
*
|
||||
* The following information is optional:
|
||||
*
|
||||
*
|
||||
* - **dimension**: The report's [dimension](/guides/all-about-analytics-data#dimensions) if any.
|
||||
* - **metrics**: An array mapping metric names with their display names.
|
||||
* - **metricsDocumentation**: An array mapping metric names with their
|
||||
|
|
@ -183,25 +201,31 @@ class ProcessedReport
|
|||
* metrics.
|
||||
* - **order**: The order of the report in the list of reports
|
||||
* with the same category.
|
||||
*
|
||||
*
|
||||
* @param array $parameters Contains the values of the sites and period we are
|
||||
* getting reports for. Some reports depend on this data.
|
||||
* For example, Goals reports depend on the site IDs being
|
||||
* requested. Contains the following information:
|
||||
*
|
||||
*
|
||||
* - **idSites**: The array of site IDs we are getting reports for.
|
||||
* - **period**: The period type, eg, `'day'`, `'week'`, `'month'`,
|
||||
* `'year'`, `'range'`.
|
||||
* - **date**: A string date within the period or a date range, eg,
|
||||
* `'2013-01-01'` or `'2012-01-01,2013-01-01'`.
|
||||
*
|
||||
*
|
||||
* TODO: put dimensions section in all about analytics data
|
||||
* @deprecated since 2.5.0 Use Report Classes instead.
|
||||
* @ignore
|
||||
*/
|
||||
Piwik::postEvent('API.getReportMetadata', array(&$availableReports, $parameters));
|
||||
|
||||
// TODO we can remove this one once we remove API.getReportMetadata event (except hideMetricsDoc)
|
||||
foreach ($availableReports as &$availableReport) {
|
||||
// can be removed once we remove hook API.getReportMetadata
|
||||
if (!isset($availableReport['metrics'])) {
|
||||
$availableReport['metrics'] = Metrics::getDefaultMetrics();
|
||||
}
|
||||
// can be removed once we remove hook API.getReportMetadata
|
||||
if (!isset($availableReport['processedMetrics'])) {
|
||||
$availableReport['processedMetrics'] = Metrics::getDefaultProcessedMetrics();
|
||||
}
|
||||
|
|
@ -211,24 +235,25 @@ class ProcessedReport
|
|||
unset($availableReport['metricsDocumentation']);
|
||||
} else if (!isset($availableReport['metricsDocumentation'])) {
|
||||
// set metric documentation to default if it's not set
|
||||
// can be removed once we remove hook API.getReportMetadata
|
||||
$availableReport['metricsDocumentation'] = Metrics::getDefaultMetricsDocumentation();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggered after all available reports are collected.
|
||||
*
|
||||
*
|
||||
* This event can be used to modify the report metadata of reports in other plugins. You
|
||||
* could, for example, add custom metrics to every report or remove reports from the list
|
||||
* of available reports.
|
||||
*
|
||||
*
|
||||
* @param array &$availableReports List of all report metadata. Read the {@hook API.getReportMetadata}
|
||||
* docs to see what this array contains.
|
||||
* @param array $parameters Contains the values of the sites and period we are
|
||||
* getting reports for. Some report depend on this data.
|
||||
* For example, Goals reports depend on the site IDs being
|
||||
* request. Contains the following information:
|
||||
*
|
||||
*
|
||||
* - **idSites**: The array of site IDs we are getting reports for.
|
||||
* - **period**: The period type, eg, `'day'`, `'week'`, `'month'`,
|
||||
* `'year'`, `'range'`.
|
||||
|
|
@ -238,16 +263,17 @@ class ProcessedReport
|
|||
Piwik::postEvent('API.getReportMetadata.end', array(&$availableReports, $parameters));
|
||||
|
||||
// Sort results to ensure consistent order
|
||||
usort($availableReports, array($this, 'sort'));
|
||||
|
||||
// Add the magic API.get report metadata aggregating all plugins API.get API calls automatically
|
||||
$this->addApiGetMetdata($availableReports);
|
||||
usort($availableReports, array('self', 'sortReports'));
|
||||
|
||||
$knownMetrics = array_merge(Metrics::getDefaultMetrics(), Metrics::getDefaultProcessedMetrics());
|
||||
$columnsToKeep = $this->getColumnsToKeep();
|
||||
$columnsToRemove = $this->getColumnsToRemove();
|
||||
|
||||
foreach ($availableReports as &$availableReport) {
|
||||
// Ensure all metrics have a translation
|
||||
$metrics = $availableReport['metrics'];
|
||||
$cleanedMetrics = array();
|
||||
// TODO we can remove this once we remove the getReportMetadata event, leaving it here for backwards compatibility
|
||||
foreach ($metrics as $metricId => $metricTranslation) {
|
||||
// When simply the column name was given, ie 'metric' => array( 'nb_visits' )
|
||||
// $metricTranslation is in this case nb_visits. We look for a known translation.
|
||||
|
|
@ -262,13 +288,13 @@ class ProcessedReport
|
|||
$availableReport['metrics'] = $cleanedMetrics;
|
||||
|
||||
// if hide/show columns specified, hide/show metrics & docs
|
||||
$availableReport['metrics'] = $this->hideShowMetrics($availableReport['metrics']);
|
||||
$availableReport['metrics'] = $this->hideShowMetricsWithParams($availableReport['metrics'], $columnsToRemove, $columnsToKeep);
|
||||
if (isset($availableReport['processedMetrics'])) {
|
||||
$availableReport['processedMetrics'] = $this->hideShowMetrics($availableReport['processedMetrics']);
|
||||
$availableReport['processedMetrics'] = $this->hideShowMetricsWithParams($availableReport['processedMetrics'], $columnsToRemove, $columnsToKeep);
|
||||
}
|
||||
if (isset($availableReport['metricsDocumentation'])) {
|
||||
$availableReport['metricsDocumentation'] =
|
||||
$this->hideShowMetrics($availableReport['metricsDocumentation']);
|
||||
$this->hideShowMetricsWithParams($availableReport['metricsDocumentation'], $columnsToRemove, $columnsToKeep);
|
||||
}
|
||||
|
||||
// Remove array elements that are false (to clean up API output)
|
||||
|
|
@ -278,6 +304,7 @@ class ProcessedReport
|
|||
}
|
||||
}
|
||||
// when there are per goal metrics, don't display conversion_rate since it can differ from per goal sum
|
||||
// TODO we should remove this once we remove the getReportMetadata event, leaving it here for backwards compatibility
|
||||
if (isset($availableReport['metricsGoal'])) {
|
||||
unset($availableReport['processedMetrics']['conversion_rate']);
|
||||
unset($availableReport['metricsGoal']['conversion_rate']);
|
||||
|
|
@ -306,93 +333,79 @@ class ProcessedReport
|
|||
}
|
||||
}
|
||||
|
||||
return array_values($availableReports); // make sure array has contiguous key values
|
||||
$actualReports = array_values($availableReports);
|
||||
$cache->save($key, $actualReports);
|
||||
|
||||
return $actualReports; // make sure array has contiguous key values
|
||||
}
|
||||
|
||||
/**
|
||||
* API metadata are sorted by category/name,
|
||||
* with a little tweak to replicate the standard Piwik category ordering
|
||||
*
|
||||
* @param string $a
|
||||
* @param string $b
|
||||
* @param array $a
|
||||
* @param array $b
|
||||
* @return int
|
||||
*/
|
||||
private function sort($a, $b)
|
||||
private static function sortReports($a, $b)
|
||||
{
|
||||
static $order = null;
|
||||
if (is_null($order)) {
|
||||
$order = array(
|
||||
Piwik::translate('General_MultiSitesSummary'),
|
||||
Piwik::translate('VisitsSummary_VisitsSummary'),
|
||||
Piwik::translate('Goals_Ecommerce'),
|
||||
Piwik::translate('General_Actions'),
|
||||
Piwik::translate('Events_Events'),
|
||||
Piwik::translate('Actions_SubmenuSitesearch'),
|
||||
Piwik::translate('Referrers_Referrers'),
|
||||
Piwik::translate('Goals_Goals'),
|
||||
Piwik::translate('General_Visitors'),
|
||||
Piwik::translate('DevicesDetection_DevicesDetection'),
|
||||
Piwik::translate('UserSettings_VisitorSettings'),
|
||||
);
|
||||
}
|
||||
return ($category = strcmp(array_search($a['category'], $order), array_search($b['category'], $order))) == 0
|
||||
? (@$a['order'] < @$b['order'] ? -1 : 1)
|
||||
: $category;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the metadata for the API.get report
|
||||
* In other plugins, this would hook on 'API.getReportMetadata'
|
||||
*/
|
||||
private function addApiGetMetdata(&$availableReports)
|
||||
{
|
||||
$metadata = array(
|
||||
'category' => Piwik::translate('General_API'),
|
||||
'name' => Piwik::translate('General_MainMetrics'),
|
||||
'module' => 'API',
|
||||
'action' => 'get',
|
||||
'metrics' => array(),
|
||||
'processedMetrics' => array(),
|
||||
'metricsDocumentation' => array(),
|
||||
'order' => 1
|
||||
);
|
||||
|
||||
$indexesToMerge = array('metrics', 'processedMetrics', 'metricsDocumentation');
|
||||
|
||||
foreach ($availableReports as $report) {
|
||||
if ($report['action'] == 'get') {
|
||||
foreach ($indexesToMerge as $index) {
|
||||
if (isset($report[$index])
|
||||
&& is_array($report[$index])
|
||||
) {
|
||||
$metadata[$index] = array_merge($metadata[$index], $report[$index]);
|
||||
}
|
||||
}
|
||||
$order = array();
|
||||
foreach (Report::$orderOfReports as $category) {
|
||||
$order[] = Piwik::translate($category);
|
||||
}
|
||||
}
|
||||
|
||||
$availableReports[] = $metadata;
|
||||
$posA = array_search($a['category'], $order);
|
||||
$posB = array_search($b['category'], $order);
|
||||
|
||||
if ($posA === false && $posB === false) {
|
||||
return strcmp($a['category'], $b['category']);
|
||||
} elseif ($posA === false) {
|
||||
return 1;
|
||||
} elseif ($posB === false) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
$category = strcmp($posA, $posB);
|
||||
|
||||
if ($category == 0) {
|
||||
return (@$a['order'] < @$b['order'] ? -1 : 1);
|
||||
}
|
||||
|
||||
return $category;
|
||||
}
|
||||
|
||||
public function getProcessedReport($idSite, $period, $date, $apiModule, $apiAction, $segment = false,
|
||||
$apiParameters = false, $idGoal = false, $language = false,
|
||||
$showTimer = true, $hideMetricsDoc = false, $idSubtable = false, $showRawMetrics = false)
|
||||
$showTimer = true, $hideMetricsDoc = false, $idSubtable = false, $showRawMetrics = false,
|
||||
$formatMetrics = null, $idDimension = false)
|
||||
{
|
||||
$timer = new Timer();
|
||||
if (empty($apiParameters)) {
|
||||
$apiParameters = array();
|
||||
}
|
||||
|
||||
if (!empty($idGoal)
|
||||
&& empty($apiParameters['idGoal'])
|
||||
) {
|
||||
$apiParameters['idGoal'] = $idGoal;
|
||||
}
|
||||
|
||||
if (!empty($idDimension)
|
||||
&& empty($apiParameters['idDimension'])
|
||||
) {
|
||||
$apiParameters['idDimension'] = (int) $idDimension;
|
||||
}
|
||||
|
||||
// Is this report found in the Metadata available reports?
|
||||
$reportMetadata = $this->getMetadata($idSite, $apiModule, $apiAction, $apiParameters, $language,
|
||||
$period, $date, $hideMetricsDoc, $showSubtableReports = true);
|
||||
if (empty($reportMetadata)) {
|
||||
throw new Exception("Requested report $apiModule.$apiAction for Website id=$idSite not found in the list of available reports. \n");
|
||||
}
|
||||
|
||||
$reportMetadata = reset($reportMetadata);
|
||||
|
||||
// Generate Api call URL passing custom parameters
|
||||
|
|
@ -406,8 +419,18 @@ class ProcessedReport
|
|||
'language' => $language,
|
||||
'idSubtable' => $idSubtable,
|
||||
));
|
||||
|
||||
if (!empty($segment)) $parameters['segment'] = $segment;
|
||||
|
||||
if (!empty($reportMetadata['processedMetrics'])
|
||||
&& !empty($reportMetadata['metrics']['nb_visits'])
|
||||
&& @$reportMetadata['category'] != Piwik::translate('Goals_Ecommerce')
|
||||
&& $apiModule !== 'MultiSites'
|
||||
) {
|
||||
$deleteRowsWithNoVisits = empty($reportMetadata['constantRowsCount']) ? '1' : '0';
|
||||
$parameters['filter_add_columns_when_show_all_columns'] = $deleteRowsWithNoVisits;
|
||||
}
|
||||
|
||||
$url = Url::getQueryStringFromParameters($parameters);
|
||||
$request = new Request($url);
|
||||
try {
|
||||
|
|
@ -417,13 +440,14 @@ class ProcessedReport
|
|||
throw new Exception("API returned an error: " . $e->getMessage() . " at " . basename($e->getFile()) . ":" . $e->getLine() . "\n");
|
||||
}
|
||||
|
||||
list($newReport, $columns, $rowsMetadata, $totals) = $this->handleTableReport($idSite, $dataTable, $reportMetadata, $showRawMetrics);
|
||||
foreach ($columns as $columnId => &$name) {
|
||||
list($newReport, $columns, $rowsMetadata, $totals) = $this->handleTableReport($idSite, $dataTable, $reportMetadata, $showRawMetrics, $formatMetrics);
|
||||
|
||||
foreach ($columns as &$name) {
|
||||
$name = ucfirst($name);
|
||||
}
|
||||
$website = new Site($idSite);
|
||||
|
||||
$period = Period::factory($period, $date);
|
||||
$period = Period\Factory::build($period, $date);
|
||||
$period = $period->getLocalizedLongString();
|
||||
|
||||
$return = array(
|
||||
|
|
@ -454,44 +478,44 @@ class ProcessedReport
|
|||
* @param \Piwik\DataTable\Map|\Piwik\DataTable\Simple $dataTable
|
||||
* @param array $reportMetadata
|
||||
* @param bool $showRawMetrics
|
||||
* @param bool|null $formatMetrics
|
||||
* @return array Simple|Set $newReport with human readable format & array $columns list of translated column names & Simple|Set $rowsMetadata
|
||||
*/
|
||||
private function handleTableReport($idSite, $dataTable, &$reportMetadata, $showRawMetrics = false)
|
||||
private function handleTableReport($idSite, $dataTable, &$reportMetadata, $showRawMetrics = false, $formatMetrics = null)
|
||||
{
|
||||
$hasDimension = isset($reportMetadata['dimension']);
|
||||
$columns = $reportMetadata['metrics'];
|
||||
$columns = @$reportMetadata['metrics'] ?: array();
|
||||
|
||||
if ($hasDimension) {
|
||||
$columns = array_merge(
|
||||
array('label' => $reportMetadata['dimension']),
|
||||
$columns
|
||||
);
|
||||
}
|
||||
|
||||
if (isset($reportMetadata['processedMetrics'])) {
|
||||
$processedMetricsAdded = Metrics::getDefaultProcessedMetrics();
|
||||
foreach ($processedMetricsAdded as $processedMetricId => $processedMetricTranslation) {
|
||||
// this processed metric can be displayed for this report
|
||||
if (isset($reportMetadata['processedMetrics'][$processedMetricId])) {
|
||||
$columns[$processedMetricId] = $processedMetricTranslation;
|
||||
}
|
||||
if (isset($reportMetadata['processedMetrics']) && is_array($reportMetadata['processedMetrics'])) {
|
||||
$processedMetricsAdded = Metrics::getDefaultProcessedMetrics();
|
||||
foreach ($reportMetadata['processedMetrics'] as $processedMetricId => $processedMetricTranslation) {
|
||||
// this processed metric can be displayed for this report
|
||||
|
||||
if ($processedMetricTranslation && $processedMetricId !== $processedMetricTranslation) {
|
||||
$columns[$processedMetricId] = $processedMetricTranslation;
|
||||
} elseif (isset($processedMetricsAdded[$processedMetricId])) {
|
||||
// for instance in case 'nb_visits' => 'nb_visits' we will translate it
|
||||
$columns[$processedMetricId] = $processedMetricsAdded[$processedMetricId];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Display the global Goal metrics
|
||||
if (isset($reportMetadata['metricsGoal'])) {
|
||||
$metricsGoalDisplay = array('revenue');
|
||||
// Add processed metrics to be displayed for this report
|
||||
foreach ($metricsGoalDisplay as $goalMetricId) {
|
||||
if (isset($reportMetadata['metricsGoal'][$goalMetricId])) {
|
||||
$columns[$goalMetricId] = $reportMetadata['metricsGoal'][$goalMetricId];
|
||||
}
|
||||
// Display the global Goal metrics
|
||||
if (isset($reportMetadata['metricsGoal'])) {
|
||||
$metricsGoalDisplay = array('revenue');
|
||||
// Add processed metrics to be displayed for this report
|
||||
foreach ($metricsGoalDisplay as $goalMetricId) {
|
||||
if (isset($reportMetadata['metricsGoal'][$goalMetricId])) {
|
||||
$columns[$goalMetricId] = $reportMetadata['metricsGoal'][$goalMetricId];
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($reportMetadata['processedMetrics'])) {
|
||||
// Add processed metrics
|
||||
$dataTable->filter('AddColumnsProcessedMetrics', array($deleteRowsWithNoVisit = false));
|
||||
}
|
||||
}
|
||||
|
||||
$columns = $this->hideShowMetrics($columns);
|
||||
|
|
@ -508,10 +532,10 @@ class ProcessedReport
|
|||
$rowsMetadata->setKeyName("prettyDate");
|
||||
|
||||
// Process each Simple entry
|
||||
foreach ($dataTable->getDataTables() as $label => $simpleDataTable) {
|
||||
foreach ($dataTable->getDataTables() as $simpleDataTable) {
|
||||
$this->removeEmptyColumns($columns, $reportMetadata, $simpleDataTable);
|
||||
|
||||
list($enhancedSimpleDataTable, $rowMetadata) = $this->handleSimpleDataTable($idSite, $simpleDataTable, $columns, $hasDimension, $showRawMetrics);
|
||||
list($enhancedSimpleDataTable, $rowMetadata) = $this->handleSimpleDataTable($idSite, $simpleDataTable, $columns, $hasDimension, $showRawMetrics, $formatMetrics);
|
||||
$enhancedSimpleDataTable->setAllTableMetadata($simpleDataTable->getAllTableMetadata());
|
||||
|
||||
$period = $simpleDataTable->getMetadata(DataTableFactory::TABLE_METADATA_PERIOD_INDEX)->getLocalizedLongString();
|
||||
|
|
@ -522,7 +546,7 @@ class ProcessedReport
|
|||
}
|
||||
} else {
|
||||
$this->removeEmptyColumns($columns, $reportMetadata, $dataTable);
|
||||
list($newReport, $rowsMetadata) = $this->handleSimpleDataTable($idSite, $dataTable, $columns, $hasDimension, $showRawMetrics);
|
||||
list($newReport, $rowsMetadata) = $this->handleSimpleDataTable($idSite, $dataTable, $columns, $hasDimension, $showRawMetrics, $formatMetrics);
|
||||
|
||||
$totals = $this->aggregateReportTotalValues($dataTable, $totals);
|
||||
}
|
||||
|
|
@ -547,14 +571,17 @@ class ProcessedReport
|
|||
return;
|
||||
}
|
||||
|
||||
$columns = $this->hideShowMetrics($columns, $emptyColumns);
|
||||
$columnsToRemove = $this->getColumnsToRemove();
|
||||
$columnsToKeep = $this->getColumnsToKeep();
|
||||
|
||||
$columns = $this->hideShowMetricsWithParams($columns, $columnsToRemove, $columnsToKeep, $emptyColumns);
|
||||
|
||||
if (isset($reportMetadata['metrics'])) {
|
||||
$reportMetadata['metrics'] = $this->hideShowMetrics($reportMetadata['metrics'], $emptyColumns);
|
||||
$reportMetadata['metrics'] = $this->hideShowMetricsWithParams($reportMetadata['metrics'], $columnsToRemove, $columnsToKeep, $emptyColumns);
|
||||
}
|
||||
|
||||
if (isset($reportMetadata['metricsDocumentation'])) {
|
||||
$reportMetadata['metricsDocumentation'] = $this->hideShowMetrics($reportMetadata['metricsDocumentation'], $emptyColumns);
|
||||
$reportMetadata['metricsDocumentation'] = $this->hideShowMetricsWithParams($reportMetadata['metricsDocumentation'], $columnsToRemove, $columnsToKeep, $emptyColumns);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -574,9 +601,21 @@ class ProcessedReport
|
|||
}
|
||||
|
||||
// remove columns if hideColumns query parameters exist
|
||||
$columnsToRemove = Common::getRequestVar('hideColumns', '');
|
||||
if ($columnsToRemove != '') {
|
||||
$columnsToRemove = explode(',', $columnsToRemove);
|
||||
$columnsToRemove = $this->getColumnsToRemove();
|
||||
|
||||
// remove columns if showColumns query parameters exist
|
||||
$columnsToKeep = $this->getColumnsToKeep();
|
||||
|
||||
return $this->hideShowMetricsWithParams($columns, $columnsToRemove, $columnsToKeep, $emptyColumns);
|
||||
}
|
||||
|
||||
private function hideShowMetricsWithParams($columns, $columnsToRemove, $columnsToKeep, $emptyColumns = array())
|
||||
{
|
||||
if (!is_array($columns)) {
|
||||
return $columns;
|
||||
}
|
||||
|
||||
if (null !== $columnsToRemove) {
|
||||
foreach ($columnsToRemove as $name) {
|
||||
// if a column to remove is in the column list, remove it
|
||||
if (isset($columns[$name])) {
|
||||
|
|
@ -585,12 +624,7 @@ class ProcessedReport
|
|||
}
|
||||
}
|
||||
|
||||
// remove columns if showColumns query parameters exist
|
||||
$columnsToKeep = Common::getRequestVar('showColumns', '');
|
||||
if ($columnsToKeep != '') {
|
||||
$columnsToKeep = explode(',', $columnsToKeep);
|
||||
$columnsToKeep[] = 'label';
|
||||
|
||||
if (null !== $columnsToKeep) {
|
||||
foreach ($columns as $name => $ignore) {
|
||||
// if the current column should not be kept, remove it
|
||||
$idx = array_search($name, $columnsToKeep);
|
||||
|
|
@ -626,10 +660,10 @@ class ProcessedReport
|
|||
* @param array $metadataColumns
|
||||
* @param boolean $hasDimension
|
||||
* @param bool $returnRawMetrics If set to true, the original metrics will be returned
|
||||
*
|
||||
* @param bool|null $formatMetrics
|
||||
* @return array DataTable $enhancedDataTable filtered metrics with human readable format & Simple $rowsMetadata
|
||||
*/
|
||||
private function handleSimpleDataTable($idSite, $simpleDataTable, $metadataColumns, $hasDimension, $returnRawMetrics = false)
|
||||
private function handleSimpleDataTable($idSite, $simpleDataTable, $metadataColumns, $hasDimension, $returnRawMetrics = false, $formatMetrics = null)
|
||||
{
|
||||
// new DataTable to store metadata
|
||||
$rowsMetadata = new DataTable();
|
||||
|
|
@ -641,28 +675,50 @@ class ProcessedReport
|
|||
$enhancedDataTable = new Simple();
|
||||
}
|
||||
|
||||
// add missing metrics
|
||||
foreach ($simpleDataTable->getRows() as $row) {
|
||||
$rowMetrics = $row->getColumns();
|
||||
foreach ($metadataColumns as $id => $name) {
|
||||
if (!isset($rowMetrics[$id])) {
|
||||
$row->addColumn($id, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
$formatter = new Formatter();
|
||||
|
||||
foreach ($simpleDataTable->getRows() as $row) {
|
||||
$rowMetrics = $row->getColumns();
|
||||
|
||||
// add missing metrics
|
||||
foreach ($metadataColumns as $id => $name) {
|
||||
if (!isset($rowMetrics[$id])) {
|
||||
$row->setColumn($id, 0);
|
||||
$rowMetrics[$id] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
$enhancedRow = new Row();
|
||||
$enhancedDataTable->addRow($enhancedRow);
|
||||
$rowMetrics = $row->getColumns();
|
||||
|
||||
foreach ($rowMetrics as $columnName => $columnValue) {
|
||||
// filter metrics according to metadata definition
|
||||
if (isset($metadataColumns[$columnName])) {
|
||||
// generate 'human readable' metric values
|
||||
$prettyValue = MetricsFormatter::getPrettyValue($idSite, $columnName, $columnValue, $htmlAllowed = false);
|
||||
|
||||
// if we handle MultiSites.getAll we do not always have the same idSite but different ones for
|
||||
// each site, see https://github.com/piwik/piwik/issues/5006
|
||||
$idSiteForRow = $idSite;
|
||||
$idSiteMetadata = $row->getMetadata('idsite');
|
||||
if ($idSiteMetadata && is_numeric($idSiteMetadata)) {
|
||||
$idSiteForRow = (int) $idSiteMetadata;
|
||||
}
|
||||
|
||||
// format metrics manually here to maintain API.getProcessedReport BC if format_metrics query parameter is
|
||||
// not supplied. TODO: should be removed for 3.0. should only rely on format_metrics query parameter.
|
||||
if ($formatMetrics === null
|
||||
|| $formatMetrics == 'bc'
|
||||
) {
|
||||
$prettyValue = self::getPrettyValue($formatter, $idSiteForRow, $columnName, $columnValue, $htmlAllowed = false);
|
||||
} else {
|
||||
$prettyValue = $columnValue;
|
||||
}
|
||||
$enhancedRow->addColumn($columnName, $prettyValue);
|
||||
} // For example the Maps Widget requires the raw metrics to do advanced datavis
|
||||
elseif ($returnRawMetrics) {
|
||||
else if ($returnRawMetrics) {
|
||||
if (!isset($columnValue)) {
|
||||
$columnValue = 0;
|
||||
}
|
||||
$enhancedRow->addColumn($columnName, $columnValue);
|
||||
}
|
||||
}
|
||||
|
|
@ -715,4 +771,108 @@ class ProcessedReport
|
|||
|
||||
return $totals;
|
||||
}
|
||||
}
|
||||
|
||||
private function getColumnsToRemove()
|
||||
{
|
||||
$columnsToRemove = Common::getRequestVar('hideColumns', '');
|
||||
|
||||
if ($columnsToRemove != '') {
|
||||
return explode(',', $columnsToRemove);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function getColumnsToKeep()
|
||||
{
|
||||
$columnsToKeep = Common::getRequestVar('showColumns', '');
|
||||
|
||||
if ($columnsToKeep != '') {
|
||||
$columnsToKeep = explode(',', $columnsToKeep);
|
||||
$columnsToKeep[] = 'label';
|
||||
|
||||
return $columnsToKeep;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function buildReportMetadataCacheKey($idSites, $period, $date, $hideMetricsDoc, $showSubtableReports)
|
||||
{
|
||||
if (isset($_GET) && isset($_POST) && is_array($_GET) && is_array($_POST)) {
|
||||
$request = $_GET + $_POST;
|
||||
} elseif (isset($_GET) && is_array($_GET)) {
|
||||
$request = $_GET;
|
||||
} elseif (isset($_POST) && is_array($_POST)) {
|
||||
$request = $_POST;
|
||||
} else {
|
||||
$request = array();
|
||||
}
|
||||
|
||||
$key = '';
|
||||
foreach ($request as $k => $v) {
|
||||
if (is_array($v)) {
|
||||
$key .= $k . $this->getImplodedArray($v) . ',';
|
||||
} else {
|
||||
$key .= $k . $v . ',';
|
||||
}
|
||||
}
|
||||
|
||||
$key .= implode(',', $idSites) . ($period === false ? 0 : $period) . ($date === false ? 0 : $date);
|
||||
$key .= (int)$hideMetricsDoc . (int)$showSubtableReports . Piwik::getCurrentUserLogin();
|
||||
return 'reportMetadata' . md5($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $v
|
||||
* @return string
|
||||
*/
|
||||
private function getImplodedArray($v)
|
||||
{
|
||||
return implode(', ', array_map(function ($entry) {
|
||||
if (is_array($entry)) {
|
||||
return implode(":", $entry);
|
||||
}
|
||||
return $entry;
|
||||
}, $v));
|
||||
}
|
||||
|
||||
/**
|
||||
* Prettifies a metric value based on the column name.
|
||||
*
|
||||
* @param int $idSite The ID of the site the metric is for (used if the column value is an amount of money).
|
||||
* @param string $columnName The metric name.
|
||||
* @param mixed $value The metric value.
|
||||
* @param bool $isHtml If true, replaces all spaces with `' '`.
|
||||
* @return string
|
||||
*/
|
||||
public static function getPrettyValue(Formatter $formatter, $idSite, $columnName, $value)
|
||||
{
|
||||
if (!is_numeric($value)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
// Display time in human readable
|
||||
if (strpos($columnName, 'time_generation') !== false) {
|
||||
return $formatter->getPrettyTimeFromSeconds($value, true);
|
||||
}
|
||||
if (strpos($columnName, 'time') !== false) {
|
||||
return $formatter->getPrettyTimeFromSeconds($value);
|
||||
}
|
||||
|
||||
// Add revenue symbol to revenues
|
||||
$isMoneyMetric = strpos($columnName, 'revenue') !== false || strpos($columnName, 'price') !== false;
|
||||
if ($isMoneyMetric && strpos($columnName, 'evolution') === false) {
|
||||
return $formatter->getPrettyMoney($value, $idSite);
|
||||
}
|
||||
|
||||
// Add % symbol to rates
|
||||
if (strpos($columnName, '_rate') !== false) {
|
||||
if (strpos($value, "%") === false) {
|
||||
return $value . "%";
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue