forked from vergnet/site-accueil-insa
601 lines
24 KiB
PHP
601 lines
24 KiB
PHP
<?php
|
|
/**
|
|
* Matomo - free/libre analytics platform
|
|
*
|
|
* @link https://matomo.org
|
|
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
|
*
|
|
*/
|
|
namespace Piwik\Plugins\MultiSites;
|
|
|
|
use Exception;
|
|
use Piwik\API\Request;
|
|
use Piwik\Archive;
|
|
use Piwik\Common;
|
|
use Piwik\Container\StaticContainer;
|
|
use Piwik\DataTable;
|
|
use Piwik\DataTable\Row;
|
|
use Piwik\Period;
|
|
use Piwik\Period\Range;
|
|
use Piwik\Piwik;
|
|
use Piwik\Plugins\Goals\Archiver;
|
|
use Piwik\Plugins\SitesManager\API as APISitesManager;
|
|
use Piwik\Scheduler\Scheduler;
|
|
use Piwik\SettingsPiwik;
|
|
use Piwik\Site;
|
|
|
|
/**
|
|
* The MultiSites API lets you request the key metrics (visits, page views, revenue) for all Websites in Matomo.
|
|
* @method static \Piwik\Plugins\MultiSites\API getInstance()
|
|
*/
|
|
class API extends \Piwik\Plugin\API
|
|
{
|
|
const METRIC_TRANSLATION_KEY = 'translation';
|
|
const METRIC_EVOLUTION_COL_NAME_KEY = 'evolution_column_name';
|
|
const METRIC_RECORD_NAME_KEY = 'record_name';
|
|
const METRIC_COL_NAME_KEY = 'metric_column_name';
|
|
const METRIC_IS_ECOMMERCE_KEY = 'is_ecommerce';
|
|
|
|
const NB_VISITS_METRIC = 'nb_visits';
|
|
const NB_ACTIONS_METRIC = 'nb_actions';
|
|
const NB_PAGEVIEWS_LABEL = 'nb_pageviews';
|
|
const NB_PAGEVIEWS_METRIC = 'Actions_nb_pageviews';
|
|
const GOAL_REVENUE_METRIC = 'revenue';
|
|
const GOAL_CONVERSION_METRIC = 'nb_conversions';
|
|
const ECOMMERCE_ORDERS_METRIC = 'orders';
|
|
const ECOMMERCE_REVENUE_METRIC = 'ecommerce_revenue';
|
|
|
|
private static $baseMetrics = array(
|
|
self::NB_VISITS_METRIC => array(
|
|
self::METRIC_TRANSLATION_KEY => 'General_ColumnNbVisits',
|
|
self::METRIC_EVOLUTION_COL_NAME_KEY => 'visits_evolution',
|
|
self::METRIC_RECORD_NAME_KEY => self::NB_VISITS_METRIC,
|
|
self::METRIC_COL_NAME_KEY => self::NB_VISITS_METRIC,
|
|
self::METRIC_IS_ECOMMERCE_KEY => false,
|
|
),
|
|
self::NB_ACTIONS_METRIC => array(
|
|
self::METRIC_TRANSLATION_KEY => 'General_ColumnNbActions',
|
|
self::METRIC_EVOLUTION_COL_NAME_KEY => 'actions_evolution',
|
|
self::METRIC_RECORD_NAME_KEY => self::NB_ACTIONS_METRIC,
|
|
self::METRIC_COL_NAME_KEY => self::NB_ACTIONS_METRIC,
|
|
self::METRIC_IS_ECOMMERCE_KEY => false,
|
|
)
|
|
);
|
|
|
|
/**
|
|
* Returns a report displaying the total visits, actions and revenue, as
|
|
* well as the evolution of these values, of all existing sites over a
|
|
* specified period of time.
|
|
*
|
|
* If the specified period is not a 'range', this function will calculate
|
|
* evolution metrics. Evolution metrics are metrics that display the
|
|
* percent increase/decrease of another metric since the last period.
|
|
*
|
|
* This function will merge the result of the archive query so each
|
|
* row in the result DataTable will correspond to the metrics of a single
|
|
* site. If a date range is specified, the result will be a
|
|
* DataTable\Map, but it will still be merged.
|
|
*
|
|
* @param string $period The period type to get data for.
|
|
* @param string $date The date(s) to get data for.
|
|
* @param bool|string $segment The segments to get data for.
|
|
* @param bool|string $_restrictSitesToLogin Hack used to enforce we restrict the returned data to the specified username
|
|
* Only used when a scheduled task is running
|
|
* @param bool|string $enhanced When true, return additional goal & ecommerce metrics
|
|
* @param bool|string $pattern If specified, only the website which names (or site ID) match the pattern will be returned using SitesManager.getPatternMatchSites
|
|
* @param array $showColumns If specified, only the requested columns will be fetched
|
|
* @return DataTable
|
|
*/
|
|
public function getAll($period, $date, $segment = false, $_restrictSitesToLogin = false, $enhanced = false, $pattern = false, $showColumns = array())
|
|
{
|
|
Piwik::checkUserHasSomeViewAccess();
|
|
|
|
$sites = $this->getSitesIdFromPattern($pattern, $_restrictSitesToLogin);
|
|
|
|
if (!empty($showColumns) && !is_array($showColumns)) {
|
|
$showColumns = explode(',', $showColumns);
|
|
}
|
|
|
|
if (empty($sites)) {
|
|
return new DataTable();
|
|
}
|
|
|
|
return $this->buildDataTable(
|
|
$sites,
|
|
$period,
|
|
$date,
|
|
$segment,
|
|
$_restrictSitesToLogin,
|
|
$enhanced,
|
|
$multipleWebsitesRequested = true,
|
|
$showColumns
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Fetches the list of sites which names match the string pattern
|
|
*
|
|
* @param string $pattern
|
|
* @param bool $_restrictSitesToLogin
|
|
* @return array|string
|
|
*/
|
|
private function getSitesIdFromPattern($pattern, $_restrictSitesToLogin)
|
|
{
|
|
// First clear cache
|
|
Site::clearCache();
|
|
|
|
if (empty($pattern)) {
|
|
|
|
/** @var Scheduler $scheduler */
|
|
$scheduler = StaticContainer::getContainer()->get('Piwik\Scheduler\Scheduler');
|
|
// Then, warm the cache with only the data we should have access to
|
|
if (Piwik::hasUserSuperUserAccess()
|
|
// Hack: when this API function is called as a Scheduled Task, Super User status is enforced.
|
|
// This means this function would return ALL websites in all cases.
|
|
// Instead, we make sure that only the right set of data is returned
|
|
&& !$scheduler->isRunningTask()
|
|
) {
|
|
APISitesManager::getInstance()->getAllSites();
|
|
} else {
|
|
APISitesManager::getInstance()->getSitesWithAtLeastViewAccess($limit = false, $_restrictSitesToLogin);
|
|
}
|
|
|
|
} else {
|
|
$sites = Request::processRequest('SitesManager.getPatternMatchSites',
|
|
array('pattern' => $pattern,
|
|
// added because caller could overwrite these
|
|
'limit' => SettingsPiwik::getWebsitesCountToDisplay(),
|
|
'showColumns' => '',
|
|
'hideColumns' => '',
|
|
'format' => 'original'));
|
|
|
|
if (!empty($sites)) {
|
|
Site::setSitesFromArray($sites);
|
|
}
|
|
}
|
|
|
|
// Both calls above have called Site::setSitesFromArray. We now get these sites:
|
|
$sitesToProblablyAdd = Site::getSites();
|
|
|
|
return $sitesToProblablyAdd;
|
|
}
|
|
|
|
/**
|
|
* Same as getAll but for a unique Matomo site
|
|
* @see \Piwik\Plugins\MultiSites\API::getAll()
|
|
*
|
|
* @param int $idSite Id of the Matomo site
|
|
* @param string $period The period type to get data for.
|
|
* @param string $date The date(s) to get data for.
|
|
* @param bool|string $segment The segments to get data for.
|
|
* @param bool|string $_restrictSitesToLogin Hack used to enforce we restrict the returned data to the specified username
|
|
* Only used when a scheduled task is running
|
|
* @param bool|string $enhanced When true, return additional goal & ecommerce metrics
|
|
* @return DataTable
|
|
*/
|
|
public function getOne($idSite, $period, $date, $segment = false, $_restrictSitesToLogin = false, $enhanced = false)
|
|
{
|
|
Piwik::checkUserHasViewAccess($idSite);
|
|
|
|
$sites = $this->getSiteFromId($idSite);
|
|
|
|
return $this->buildDataTable(
|
|
$sites,
|
|
$period,
|
|
$date,
|
|
$segment,
|
|
$_restrictSitesToLogin,
|
|
$enhanced,
|
|
$multipleWebsitesRequested = false,
|
|
$showColumns = array()
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @param null|string $period
|
|
* @param null|string $date
|
|
* @param false|string $segment
|
|
* @param string $pattern
|
|
* @param int $filter_limit
|
|
* @return array
|
|
* @throws Exception
|
|
*/
|
|
public function getAllWithGroups($period = null, $date = null, $segment = false, $pattern = '', $filter_limit = 0)
|
|
{
|
|
Piwik::checkUserHasSomeViewAccess();
|
|
|
|
if (Period::isMultiplePeriod($date, $period)) {
|
|
throw new Exception('Multiple periods are not supported');
|
|
}
|
|
|
|
$segment = $segment ?: false;
|
|
$request = $_GET + $_POST;
|
|
|
|
$dashboard = new Dashboard($period, $date, $segment);
|
|
|
|
if ($pattern !== '') {
|
|
$dashboard->search(strtolower($pattern));
|
|
}
|
|
|
|
$response = [
|
|
'numSites' => $dashboard->getNumSites(),
|
|
'totals' => $dashboard->getTotals(),
|
|
'lastDate' => $dashboard->getLastDate(),
|
|
'sites' => $dashboard->getSites($request, $filter_limit)
|
|
];
|
|
|
|
return $response;
|
|
}
|
|
|
|
private function getSiteFromId($idSite)
|
|
{
|
|
$idSite = (int) $idSite;
|
|
$sites = array(APISitesManager::getInstance()->getSiteFromId($idSite));
|
|
|
|
return $sites;
|
|
}
|
|
|
|
private function buildDataTable($sitesToProblablyAdd, $period, $date, $segment, $_restrictSitesToLogin, $enhanced, $multipleWebsitesRequested, $showColumns)
|
|
{
|
|
$idSites = array();
|
|
if (!empty($sitesToProblablyAdd)) {
|
|
foreach ($sitesToProblablyAdd as $site) {
|
|
$idSites[] = $site['idsite'];
|
|
}
|
|
}
|
|
|
|
// build the archive type used to query archive data
|
|
$archive = Archive::build(
|
|
$idSites,
|
|
$period,
|
|
$date,
|
|
$segment,
|
|
$_restrictSitesToLogin
|
|
);
|
|
|
|
// determine what data will be displayed
|
|
$fieldsToGet = array();
|
|
$columnNameRewrites = array();
|
|
$apiECommerceMetrics = array();
|
|
$apiMetrics = API::getApiMetrics($enhanced);
|
|
foreach ($apiMetrics as $metricName => $metricSettings) {
|
|
if (!empty($showColumns) && !in_array($metricName, $showColumns)) {
|
|
unset($apiMetrics[$metricName]);
|
|
continue;
|
|
}
|
|
$fieldsToGet[] = $metricSettings[self::METRIC_RECORD_NAME_KEY];
|
|
$columnNameRewrites[$metricSettings[self::METRIC_RECORD_NAME_KEY]] = $metricName;
|
|
|
|
if ($metricSettings[self::METRIC_IS_ECOMMERCE_KEY]) {
|
|
$apiECommerceMetrics[$metricName] = $metricSettings;
|
|
}
|
|
}
|
|
|
|
$dataTable = $archive->getDataTableFromNumericAndMergeChildren($fieldsToGet);
|
|
|
|
$this->populateLabel($dataTable);
|
|
$totalMetrics = $this->preformatApiMetricsForTotalsCalculation($apiMetrics);
|
|
$this->setMetricsTotalsMetadata($dataTable, $totalMetrics);
|
|
|
|
// if the period isn't a range & a lastN/previousN date isn't used, we get the same
|
|
// data for the last period to show the evolution of visits/actions/revenue
|
|
[$strLastDate, $lastPeriod] = Range::getLastDate($date, $period);
|
|
|
|
if ($strLastDate !== false) {
|
|
|
|
if ($lastPeriod !== false) {
|
|
// NOTE: no easy way to set last period date metadata when range of dates is requested.
|
|
// will be easier if DataTable\Map::metadata is removed, and metadata that is
|
|
// put there is put directly in DataTable::metadata.
|
|
$dataTable->setMetadata(self::getLastPeriodMetadataName('date'), $lastPeriod);
|
|
}
|
|
|
|
$pastArchive = Archive::build($idSites, $period, $strLastDate, $segment, $_restrictSitesToLogin);
|
|
$pastData = $pastArchive->getDataTableFromNumericAndMergeChildren($fieldsToGet);
|
|
|
|
$this->populateLabel($pastData); // labels are needed to calculate evolution
|
|
$this->calculateEvolutionPercentages($dataTable, $pastData, $apiMetrics);
|
|
$this->setPastTotalVisitsMetadata($dataTable, $pastData);
|
|
|
|
if ($dataTable instanceof DataTable) {
|
|
// needed for MultiSites\Dashboard
|
|
$dataTable->setMetadata('pastData', $pastData);
|
|
}
|
|
}
|
|
|
|
// move the site id to a metadata column
|
|
$dataTable->queueFilter('MetadataCallbackAddMetadata', array('idsite', 'group', function($idSite) {
|
|
if ($idSite == '-1') { // Others row might occur when `filter_truncate` API parameter is used
|
|
return '';
|
|
}
|
|
return Site::getGroupFor($idSite);
|
|
}, array()));
|
|
$dataTable->queueFilter('MetadataCallbackAddMetadata', array('idsite', 'main_url', function($idSite) {
|
|
if ($idSite == '-1') { // Others row might occur when `filter_truncate` API parameter is used
|
|
return '';
|
|
}
|
|
return Site::getMainUrlFor($idSite);
|
|
}, array()));
|
|
|
|
// set the label of each row to the site name
|
|
if ($multipleWebsitesRequested) {
|
|
$dataTable->queueFilter('ColumnCallbackReplace', array('label', function($idSite) {
|
|
if ($idSite == '-1') { // Others row might occur when `filter_truncate` API parameter is used
|
|
return Piwik::translate('General_Others');
|
|
}
|
|
return Site::getNameFor($idSite);
|
|
}));
|
|
} else {
|
|
$dataTable->queueFilter('ColumnDelete', array('label'));
|
|
}
|
|
|
|
// replace record names with user friendly metric names
|
|
$dataTable->queueFilter('ReplaceColumnNames', array($columnNameRewrites));
|
|
|
|
// filter rows without visits
|
|
// note: if only one website is queried and there are no visits, we can not remove the row otherwise
|
|
// ResponseBuilder throws 'Call to a member function getColumns() on a non-object'
|
|
if ($multipleWebsitesRequested
|
|
// We don't delete the 0 visits row, if "Enhanced" mode is on.
|
|
&& !$enhanced && (empty($showColumns) || in_array(self::NB_VISITS_METRIC, $showColumns))
|
|
) {
|
|
$dataTable->filter(
|
|
'ColumnCallbackDeleteRow',
|
|
array(
|
|
self::NB_VISITS_METRIC,
|
|
function ($value) {
|
|
return $value == 0;
|
|
}
|
|
)
|
|
);
|
|
}
|
|
|
|
// Remove <ts_archived> row metadata, it's already been used by any filters that needed it
|
|
$dataTable->queueFilter(function($dataTable) {
|
|
$dataTable->deleteRowsMetadata(DataTable::ARCHIVED_DATE_METADATA_NAME);
|
|
$dataTable->deleteColumn('_metadata');
|
|
});
|
|
|
|
if ($multipleWebsitesRequested && $dataTable->getRowsCount() === 1 && $dataTable instanceof DataTable\Simple) {
|
|
$simpleTable = $dataTable;
|
|
$dataTable = $simpleTable->getEmptyClone();
|
|
$dataTable->addRow($simpleTable->getFirstRow());
|
|
unset($simpleTable);
|
|
}
|
|
|
|
return $dataTable;
|
|
}
|
|
|
|
/**
|
|
* Performs a binary filter of two
|
|
* DataTables in order to correctly calculate evolution metrics.
|
|
*
|
|
* @param DataTable|DataTable\Map $currentData
|
|
* @param DataTable|DataTable\Map $pastData
|
|
* @param array $apiMetrics The array of string fields to calculate evolution
|
|
* metrics for.
|
|
* @throws Exception
|
|
*/
|
|
private function calculateEvolutionPercentages($currentData, $pastData, $apiMetrics)
|
|
{
|
|
if (get_class($currentData) != get_class($pastData)) { // sanity check for regressions
|
|
throw new Exception("Expected \$pastData to be of type " . get_class($currentData) . " - got "
|
|
. get_class($pastData) . ".");
|
|
}
|
|
|
|
if ($currentData instanceof DataTable\Map) {
|
|
$pastArray = $pastData->getDataTables();
|
|
foreach ($currentData->getDataTables() as $subTable) {
|
|
$this->calculateEvolutionPercentages($subTable, current($pastArray), $apiMetrics);
|
|
next($pastArray);
|
|
}
|
|
} else {
|
|
$extraProcessedMetrics = $currentData->getMetadata(DataTable::EXTRA_PROCESSED_METRICS_METADATA_NAME);
|
|
foreach ($apiMetrics as $metricSettings) {
|
|
$evolutionMetricClass = $this->isEcommerceEvolutionMetric($metricSettings)
|
|
? "Piwik\\Plugins\\MultiSites\\Columns\\Metrics\\EcommerceOnlyEvolutionMetric"
|
|
: "Piwik\\Plugins\\CoreHome\\Columns\\Metrics\\EvolutionMetric";
|
|
|
|
$extraProcessedMetrics = is_array($extraProcessedMetrics) ? $extraProcessedMetrics : [];
|
|
$extraProcessedMetrics[] = new $evolutionMetricClass(
|
|
$metricSettings[self::METRIC_RECORD_NAME_KEY],
|
|
$pastData,
|
|
$metricSettings[self::METRIC_EVOLUTION_COL_NAME_KEY],
|
|
$quotientPrecision = 1,
|
|
$currentData
|
|
);
|
|
}
|
|
$currentData->setMetadata(DataTable::EXTRA_PROCESSED_METRICS_METADATA_NAME, $extraProcessedMetrics);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
public static function getApiMetrics($enhanced)
|
|
{
|
|
$metrics = self::$baseMetrics;
|
|
|
|
if (Common::isActionsPluginEnabled()) {
|
|
$metrics[self::NB_PAGEVIEWS_LABEL] = array(
|
|
self::METRIC_TRANSLATION_KEY => 'General_ColumnPageviews',
|
|
self::METRIC_EVOLUTION_COL_NAME_KEY => 'pageviews_evolution',
|
|
self::METRIC_RECORD_NAME_KEY => self::NB_PAGEVIEWS_METRIC,
|
|
self::METRIC_COL_NAME_KEY => self::NB_PAGEVIEWS_LABEL,
|
|
self::METRIC_IS_ECOMMERCE_KEY => false,
|
|
);
|
|
}
|
|
|
|
if (Common::isGoalPluginEnabled()) {
|
|
// goal revenue metric
|
|
$metrics[self::GOAL_REVENUE_METRIC] = array(
|
|
self::METRIC_TRANSLATION_KEY => 'General_ColumnRevenue',
|
|
self::METRIC_EVOLUTION_COL_NAME_KEY => self::GOAL_REVENUE_METRIC . '_evolution',
|
|
self::METRIC_RECORD_NAME_KEY => Archiver::getRecordName(self::GOAL_REVENUE_METRIC),
|
|
self::METRIC_COL_NAME_KEY => self::GOAL_REVENUE_METRIC,
|
|
self::METRIC_IS_ECOMMERCE_KEY => false,
|
|
);
|
|
|
|
if ($enhanced) {
|
|
// number of goal conversions metric
|
|
$metrics[self::GOAL_CONVERSION_METRIC] = array(
|
|
self::METRIC_TRANSLATION_KEY => 'Goals_ColumnConversions',
|
|
self::METRIC_EVOLUTION_COL_NAME_KEY => self::GOAL_CONVERSION_METRIC . '_evolution',
|
|
self::METRIC_RECORD_NAME_KEY => Archiver::getRecordName(self::GOAL_CONVERSION_METRIC),
|
|
self::METRIC_COL_NAME_KEY => self::GOAL_CONVERSION_METRIC,
|
|
self::METRIC_IS_ECOMMERCE_KEY => false,
|
|
);
|
|
|
|
// number of orders
|
|
$metrics[self::ECOMMERCE_ORDERS_METRIC] = array(
|
|
self::METRIC_TRANSLATION_KEY => 'General_EcommerceOrders',
|
|
self::METRIC_EVOLUTION_COL_NAME_KEY => self::ECOMMERCE_ORDERS_METRIC . '_evolution',
|
|
self::METRIC_RECORD_NAME_KEY => Archiver::getRecordName(self::GOAL_CONVERSION_METRIC, 0),
|
|
self::METRIC_COL_NAME_KEY => self::ECOMMERCE_ORDERS_METRIC,
|
|
self::METRIC_IS_ECOMMERCE_KEY => true,
|
|
);
|
|
|
|
// eCommerce revenue
|
|
$metrics[self::ECOMMERCE_REVENUE_METRIC] = array(
|
|
self::METRIC_TRANSLATION_KEY => 'General_ProductRevenue',
|
|
self::METRIC_EVOLUTION_COL_NAME_KEY => self::ECOMMERCE_REVENUE_METRIC . '_evolution',
|
|
self::METRIC_RECORD_NAME_KEY => Archiver::getRecordName(self::GOAL_REVENUE_METRIC, 0),
|
|
self::METRIC_COL_NAME_KEY => self::ECOMMERCE_REVENUE_METRIC,
|
|
self::METRIC_IS_ECOMMERCE_KEY => true,
|
|
);
|
|
}
|
|
}
|
|
|
|
return $metrics;
|
|
}
|
|
|
|
private function preformatApiMetricsForTotalsCalculation($apiMetrics)
|
|
{
|
|
$metrics = array();
|
|
foreach ($apiMetrics as $label => $metricsInfo) {
|
|
$totalMetadataName = self::getTotalMetadataName($label);
|
|
$metrics[$totalMetadataName] = $metricsInfo[self::METRIC_RECORD_NAME_KEY];
|
|
}
|
|
|
|
return $metrics;
|
|
}
|
|
|
|
/**
|
|
* Sets the total visits, actions & revenue for a DataTable returned by
|
|
* $this->buildDataTable.
|
|
*
|
|
* @param DataTable $dataTable
|
|
* @param array $apiMetrics Metrics info.
|
|
* @return array Array of three values: total visits, total actions, total revenue
|
|
*/
|
|
private function setMetricsTotalsMetadata($dataTable, $apiMetrics)
|
|
{
|
|
if ($dataTable instanceof DataTable\Map) {
|
|
foreach ($dataTable->getDataTables() as $table) {
|
|
$this->setMetricsTotalsMetadata($table, $apiMetrics);
|
|
}
|
|
} else {
|
|
$totals = array();
|
|
foreach ($apiMetrics as $label => $recordName) {
|
|
$totals[$label] = 0;
|
|
}
|
|
|
|
$rows = $dataTable->getRows();
|
|
|
|
$rows = $this->filterRowsForTotalsCalculation($rows);
|
|
|
|
foreach ($rows as $row) {
|
|
foreach ($apiMetrics as $totalMetadataName => $recordName) {
|
|
$totals[$totalMetadataName] += $row->getColumn($recordName);
|
|
}
|
|
}
|
|
|
|
$dataTable->setMetadataValues($totals);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets the number of total visits in the pastTable on the dataTable as metadata.
|
|
*
|
|
* @param DataTable $dataTable
|
|
* @param DataTable $pastTable
|
|
*/
|
|
private function setPastTotalVisitsMetadata($dataTable, $pastTable)
|
|
{
|
|
if ($pastTable instanceof DataTable) {
|
|
$total = 0;
|
|
$metric = 'nb_visits';
|
|
|
|
$rows = $pastTable->getRows();
|
|
$rows = $this->filterRowsForTotalsCalculation($rows);
|
|
|
|
foreach ($rows as $row) {
|
|
$total += $row->getColumn($metric);
|
|
}
|
|
|
|
$dataTable->setMetadata(self::getTotalMetadataName($metric . '_lastdate'), $total);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param Row[] $rows
|
|
* @return mixed
|
|
*/
|
|
private function filterRowsForTotalsCalculation($rows)
|
|
{
|
|
/**
|
|
* Triggered to filter / restrict which rows should be included in the MultiSites (All Websites Dashboard)
|
|
* totals calculation
|
|
*
|
|
* **Example**
|
|
*
|
|
* public function filterMultiSitesRows(&$rows)
|
|
* {
|
|
* foreach ($rows as $index => $row) {
|
|
* if ($row->getColumn('label') === 5) {
|
|
* unset($rows[$index]); // remove idSite 5 from totals
|
|
* }
|
|
* }
|
|
* }
|
|
*
|
|
* @param Row[] &$rows An array containing rows, one row for each site. The label columns equals the idSite.
|
|
*/
|
|
Piwik::postEvent('MultiSites.filterRowsForTotalsCalculation', array(&$rows));
|
|
|
|
return $rows;
|
|
}
|
|
|
|
private static function getTotalMetadataName($name)
|
|
{
|
|
return 'total_' . $name;
|
|
}
|
|
|
|
private static function getLastPeriodMetadataName($name)
|
|
{
|
|
return 'last_period_' . $name;
|
|
}
|
|
|
|
private function populateLabel($dataTable)
|
|
{
|
|
$dataTable->filter(function (DataTable $table) {
|
|
foreach ($table->getRowsWithoutSummaryRow() as $row) {
|
|
$row->setColumn('label', $row->getMetadata('idsite'));
|
|
}
|
|
});
|
|
// make sure label column is always first column
|
|
$dataTable->queueFilter(function (DataTable $table) {
|
|
foreach ($table->getRowsWithoutSummaryRow() as $row) {
|
|
$row->setColumns(array_merge(array('label' => $row->getColumn('label')), $row->getColumns()));
|
|
}
|
|
});
|
|
}
|
|
|
|
private function isEcommerceEvolutionMetric($metricSettings)
|
|
{
|
|
return in_array($metricSettings[self::METRIC_EVOLUTION_COL_NAME_KEY], array(
|
|
self::GOAL_REVENUE_METRIC . '_evolution',
|
|
self::ECOMMERCE_ORDERS_METRIC . '_evolution',
|
|
self::ECOMMERCE_REVENUE_METRIC . '_evolution'
|
|
));
|
|
}
|
|
}
|