Skip to content

Commit

Permalink
in API.getProcessedReport, add report metadata for extra processed me…
Browse files Browse the repository at this point in the history
…trics added via DataTable metadata
  • Loading branch information
diosmosis committed Sep 19, 2024
1 parent 54a0fcd commit 0c76eb1
Show file tree
Hide file tree
Showing 10 changed files with 288 additions and 28 deletions.
46 changes: 29 additions & 17 deletions core/Plugin/Report.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@
use Piwik\Plugin\Dimension\ActionDimension;
use Piwik\Plugin\Dimension\ConversionDimension;
use Piwik\Plugin\Dimension\VisitDimension;
use Piwik\Plugins\CoreHome\Columns\Metrics\BounceRate;
use Piwik\Plugins\CoreHome\Columns\Metrics\ActionsPerVisit;
use Piwik\Plugins\CoreHome\Columns\Metrics\AverageTimeOnSite;
use Piwik\Plugins\CoreHome\Columns\Metrics\ConversionRate;
use Piwik\Plugins\CoreVisualizations\Visualizations\HtmlTable;
use Piwik\ViewDataTable\Factory as ViewDataTableFactory;
use Exception;
Expand Down Expand Up @@ -370,15 +366,26 @@ public function render()
}

/**
*
* Processing a uniqueId for each report, can be used by UIs as a key to match a given report
*
* @return string
*/
public function getId()
{
$params = $this->getParameters();
return self::buildId($this->getModule(), $this->getAction(), $this->getParameters());
}

$paramsKey = $this->getModule() . '.' . $this->getAction();
/**
* TODO
*
* @param string $module
* @param string $action
* @param array|null $params
* @return string
*/
public static function buildId(string $module, string $action, ?array $params = null): string
{
$paramsKey = $module . '.' . $action;

if (!empty($params)) {
foreach ($params as $key => $value) {
Expand Down Expand Up @@ -436,7 +443,7 @@ public function getRecursiveLabelSeparator()
*/
public function getMetrics()
{
return $this->getMetricTranslations($this->metrics);
return self::getMetricTranslations($this->metrics);
}

/**
Expand Down Expand Up @@ -494,7 +501,7 @@ public function getProcessedMetrics()
return $this->processedMetrics;
}

return $this->getMetricTranslations($this->processedMetrics);
return self::getMetricTranslations($this->processedMetrics);
}

/**
Expand Down Expand Up @@ -795,7 +802,10 @@ protected function buildReportMetadata()
$report['metrics'] = $this->getMetrics();
$report['metricsDocumentation'] = $this->getMetricsDocumentation();

$processedMetricMetadata = $this->getProcessedMetricsMetadata();
$processedMetricMetadata = self::getProcessedMetricsMetadata(
$this->processedMetrics ?: [],
$this->getProcessedMetrics() ?: null
);
$report['processedMetrics'] = $processedMetricMetadata['names'];
$report['processedMetricFormulas'] = $processedMetricMetadata['formulas'];
$report['temporaryMetricAggregationTypes'] = $processedMetricMetadata['temporaryMetricAggregationTypes'];
Expand Down Expand Up @@ -927,7 +937,8 @@ public function getParameters()
}

/**
* Get the translated name of the category the report belongs to.
* Get the ID of the category the report belongs to.
* The ID should also be a valid translation key.
* @return string|null
* @ignore
*/
Expand All @@ -937,8 +948,9 @@ public function getCategoryId()
}

/**
* Get the translated name of the subcategory the report belongs to.
* Get the ID of the subcategory the report belongs to.
* @return string|null
* The ID should also be a valid translation key.
* @ignore
*/
public function getSubcategoryId()
Expand Down Expand Up @@ -1094,7 +1106,7 @@ public function fetchSubtable($idSubtable, $paramOverride = array())
return Request::processRequest($module . '.' . $action, $paramOverride);
}

private function getMetricTranslations($metricsToTranslate)
private static function getMetricTranslations($metricsToTranslate)
{
$translations = Metrics::getDefaultMetricTranslations();
$metrics = array();
Expand Down Expand Up @@ -1341,20 +1353,20 @@ private function isScopeSameOrSubsetOf(?string $scope, string $supersetScope): b
return false;
}

private function getProcessedMetricsMetadata(): array
public static function getProcessedMetricsMetadata(?array $processedMetrics, ?array $processedMetricTranslations = null): array
{
$metadata = [
'names' => $this->getProcessedMetrics() ?: [],
'names' => $processedMetricTranslations ?: self::getMetricTranslations($processedMetrics ?: []),
'formulas' => [],
'temporaryMetricAggregationTypes' => [],
'temporaryMetricSemanticTypes' => [],
];

if (empty($this->processedMetrics)) {
if (empty($processedMetrics)) {
return $metadata;
}

foreach ($this->processedMetrics as $processedMetric) {
foreach ($processedMetrics as $processedMetric) {
if (!($processedMetric instanceof ProcessedMetric)) {
continue;
}
Expand Down
47 changes: 45 additions & 2 deletions plugins/API/ProcessedReport.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,20 @@
use Piwik\Common;
use Piwik\Container\StaticContainer;
use Piwik\DataTable;
use Piwik\DataTable\DataTableInterface;
use Piwik\DataTable\Filter\AddColumnsProcessedMetricsGoal;
use Piwik\DataTable\Map;
use Piwik\DataTable\Row;
use Piwik\DataTable\Simple;
use Piwik\Date;
use Piwik\Metrics;
use Piwik\Metrics\Formatter;
use Piwik\Period;
use Piwik\Piwik;
use Piwik\Plugin\ProcessedMetric;
use Piwik\Plugin\Report;
use Piwik\Plugin\ReportsProvider;
use Piwik\Plugins\Goals\Columns\Metrics\GoalSpecificProcessedMetric;
use Piwik\Site;
use Piwik\Timer;
use Piwik\Url;
Expand Down Expand Up @@ -179,9 +184,10 @@ public function translateMetric($metric, $idSite, $apiMethodUniqueId)
* @param bool|Date $date
* @param bool $hideMetricsDoc
* @param bool $showSubtableReports
* @param array $dataTables TODO
* @return array
*/
public function getReportMetadata($idSite, $period = false, $date = false, $hideMetricsDoc = false, $showSubtableReports = false)
public function getReportMetadata($idSite, $period = false, $date = false, $hideMetricsDoc = false, $showSubtableReports = false, ?array $dataTables = null)
{
Piwik::checkUserHasViewAccess($idSite);

Expand All @@ -200,7 +206,8 @@ public function getReportMetadata($idSite, $period = false, $date = false, $hide
$availableReports = array();

foreach ($this->reportsProvider->getAllReports() as $report) {
$report->configureReportMetadata($availableReports, $parameters);
$dataTable = $dataTables[$report->getId()] ?? null;
$report->configureReportMetadata($availableReports, $parameters, $dataTable);
}

foreach ($availableReports as &$availableReport) {
Expand Down Expand Up @@ -432,6 +439,8 @@ public function getProcessedReport(

list($newReport, $columns, $rowsMetadata, $totals) = $this->handleTableReport($idSite, $dataTable, $reportMetadata, $showRawMetrics, $formatMetrics);

$this->handleExtraProcessedMetricsMetadata($dataTable, $reportMetadata);

if (function_exists('mb_substr')) {
foreach ($columns as &$name) {
if (substr($name, 0, 1) === mb_substr($name, 0, 1)) {
Expand Down Expand Up @@ -946,4 +955,38 @@ private function getIdGoalToUseForActionsReports($idGoal, string $requestMethod)
}
return $idGoal;
}

private function handleExtraProcessedMetricsMetadata(DataTableInterface $reportData, array &$reportMetadata): void
{
$dataTable = $this->getFirstDataTable($reportData);
if (empty($dataTable)) {
return;
}

$extraProcessedMetrics = $dataTable->getMetadata(DataTable::EXTRA_PROCESSED_METRICS_METADATA_NAME);
if (empty($extraProcessedMetrics)) {
return;
}

$extraProcessedMetrics = array_filter($extraProcessedMetrics, function ($processedMetric) {
return $processedMetric instanceof ProcessedMetric
&& !($processedMetric instanceof GoalSpecificProcessedMetric);
});

$extraMetadata = Report::getProcessedMetricsMetadata($extraProcessedMetrics);

$reportMetadata['processedMetrics'] = array_merge($reportMetadata['processedMetrics'] ?? [], $extraMetadata['names']);
$reportMetadata['processedMetricFormulas'] = array_merge($reportMetadata['processedMetricFormulas'] ?? [], $extraMetadata['formulas']);
$reportMetadata['temporaryMetricAggregationTypes'] = array_merge($reportMetadata['temporaryMetricAggregationTypes'] ?? [], $extraMetadata['temporaryMetricAggregationTypes']);
$reportMetadata['temporaryMetricSemanticTypes'] = array_merge($reportMetadata['temporaryMetricSemanticTypes'] ?? [], $extraMetadata['temporaryMetricSemanticTypes']);
}

private function getFirstDataTable(DataTableInterface $reportData)
{
$table = $reportData;
while ($table instanceof Map) {
$table = $table->getFirstRow();
}
return $table;
}
}
5 changes: 0 additions & 5 deletions plugins/Actions/Reports/GetPageTitlesFollowingSiteSearch.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,6 @@ public function getMetrics()
);
}

public function getProcessedMetrics()
{
return array();
}

protected function getMetricsDocumentation()
{
return array(
Expand Down
15 changes: 15 additions & 0 deletions tests/PHPUnit/System/ApiGetReportMetadataTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,21 @@ public function getApiForTesting()
],
],

[
'API.getProcessedReport',
[
'idSite' => $idSite,
'date' => $dateTime,
'apiModule' => 'UserCountry',
'apiAction' => 'getCountry',
'testSuffix' => '_withExtraProcessedMetrics',
'otherRequestParameters' => [
'filter_update_columns_when_show_all_goals' => '1',
'idGoal' => '0',
],
],
],

// Test w/ showRawMetrics=true
[
'API.getProcessedReport',
Expand Down
1 change: 1 addition & 0 deletions tests/PHPUnit/System/ApiGetReportMetadataYearTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public function getApiForTesting()
'date' => self::$fixture->dateTime,
'periods' => 'year',
'language' => 'fr');
return [array('API.getProcessedReport', $params)];
return array(
array('API.getProcessedReport', $params),
array('LanguagesManager.getAvailableLanguageNames', $params),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,14 @@
<avg_time_on_site>Avg. Time on Website</avg_time_on_site>
<bounce_rate>Bounce Rate</bounce_rate>
<revenue_per_visit>Revenue per Visit</revenue_per_visit>
<conversion_rate>Conversion Rate</conversion_rate>
</processedMetrics>
<processedMetricFormulas>
<revenue_per_visit>$revenue / ($nb_visits != 0 ? $nb_visits : $nb_conversions)</revenue_per_visit>
<conversion_rate>$nb_visits_converted / $nb_visits</conversion_rate>
<nb_actions_per_visit>$nb_actions / $nb_visits</nb_actions_per_visit>
<avg_time_on_site>$sum_visit_length / $nb_visits</avg_time_on_site>
<bounce_rate>$bounce_count / $nb_visits</bounce_rate>
</processedMetricFormulas>
<metricTypes>
<nb_visits>number</nb_visits>
Expand Down Expand Up @@ -72,6 +77,14 @@
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=UserCountry&amp;apiAction=getCountry&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=UserCountry&amp;apiAction=getCountry&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
<uniqueId>UserCountry_getCountry</uniqueId>
<temporaryMetricAggregationTypes>
<sum_visit_length>sum</sum_visit_length>
<bounce_count>sum</bounce_count>
</temporaryMetricAggregationTypes>
<temporaryMetricSemanticTypes>
<sum_visit_length>number</sum_visit_length>
<bounce_count>number</bounce_count>
</temporaryMetricSemanticTypes>
</metadata>
<columns>
<label>Country</label>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1713,8 +1713,6 @@
</metricTypesGoal>
<metricAggregationTypesGoal>
<nb_conversions>sum</nb_conversions>
<nb_conversions_attrib />
<revenue_attrib />
</metricAggregationTypesGoal>
<processedMetricsGoal>
<revenue_per_visit>Ecommerce order Revenue per Visit</revenue_per_visit>
Expand Down Expand Up @@ -2128,8 +2126,6 @@
</metricTypesGoal>
<metricAggregationTypesGoal>
<nb_conversions>sum</nb_conversions>
<nb_conversions_attrib />
<revenue_attrib />
</metricAggregationTypesGoal>
<processedMetricsGoal>
<revenue_per_visit>Ecommerce order Revenue per Visit</revenue_per_visit>
Expand Down Expand Up @@ -2207,6 +2203,12 @@
<nb_hits_following_search>The number of times this Page was visited after a visitor did a search on your website, and clicked on this page in the search results.</nb_hits_following_search>
<nb_hits>The number of times this page was visited.</nb_hits>
</metricsDocumentation>
<processedMetrics>
<avg_time_on_page>Avg. time on page</avg_time_on_page>
<bounce_rate>Bounce Rate</bounce_rate>
<exit_rate>Exit rate</exit_rate>
<avg_time_generation>Avg. generation time</avg_time_generation>
</processedMetrics>
<processedMetricFormulas>
<avg_time_on_page>$sum_time_spent / $nb_hits</avg_time_on_page>
<bounce_rate>$entry_bounce_count / $entry_nb_visits</bounce_rate>
Expand Down Expand Up @@ -2297,6 +2299,12 @@
<nb_hits_following_search>The number of times this Page was visited after a visitor did a search on your website, and clicked on this page in the search results.</nb_hits_following_search>
<nb_hits>The number of times this page was visited.</nb_hits>
</metricsDocumentation>
<processedMetrics>
<avg_time_on_page>Avg. time on page</avg_time_on_page>
<bounce_rate>Bounce Rate</bounce_rate>
<exit_rate>Exit rate</exit_rate>
<avg_time_generation>Avg. generation time</avg_time_generation>
</processedMetrics>
<processedMetricFormulas>
<avg_time_on_page>$sum_time_spent / $nb_hits</avg_time_on_page>
<bounce_rate>$entry_bounce_count / $entry_nb_visits</bounce_rate>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,14 @@
<avg_time_on_site>Avg. Time on Website</avg_time_on_site>
<bounce_rate>Bounce Rate</bounce_rate>
<revenue_per_visit>Revenue per Visit</revenue_per_visit>
<conversion_rate>Conversion Rate</conversion_rate>
</processedMetrics>
<processedMetricFormulas>
<revenue_per_visit>$revenue / ($nb_visits != 0 ? $nb_visits : $nb_conversions)</revenue_per_visit>
<conversion_rate>$nb_visits_converted / $nb_visits</conversion_rate>
<nb_actions_per_visit>$nb_actions / $nb_visits</nb_actions_per_visit>
<avg_time_on_site>$sum_visit_length / $nb_visits</avg_time_on_site>
<bounce_rate>$bounce_count / $nb_visits</bounce_rate>
</processedMetricFormulas>
<metricTypes>
<nb_visits>number</nb_visits>
Expand Down Expand Up @@ -72,6 +77,14 @@
<imageGraphUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=UserCountry&amp;apiAction=getCountry&amp;period=day&amp;date=2009-01-04</imageGraphUrl>
<imageGraphEvolutionUrl>index.php?module=API&amp;method=ImageGraph.get&amp;idSite=1&amp;apiModule=UserCountry&amp;apiAction=getCountry&amp;period=day&amp;date=2008-12-06,2009-01-04</imageGraphEvolutionUrl>
<uniqueId>UserCountry_getCountry</uniqueId>
<temporaryMetricAggregationTypes>
<sum_visit_length>sum</sum_visit_length>
<bounce_count>sum</bounce_count>
</temporaryMetricAggregationTypes>
<temporaryMetricSemanticTypes>
<sum_visit_length>number</sum_visit_length>
<bounce_count>number</bounce_count>
</temporaryMetricSemanticTypes>
</metadata>
<columns>
<label>Country</label>
Expand Down
Loading

0 comments on commit 0c76eb1

Please sign in to comment.