1
0
قرینه از https://github.com/matomo-org/matomo.git synced 2025-08-22 06:57:53 +00:00
Files
matomo/plugins/Events/RecordBuilders/EventReports.php
2024-10-18 18:29:54 +02:00

218 خطوط
8.8 KiB
PHP

<?php
/**
* Matomo - free/libre analytics platform
*
* @link https://matomo.org
* @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Plugins\Events\RecordBuilders;
use Piwik\ArchiveProcessor;
use Piwik\ArchiveProcessor\Record;
use Piwik\ArchiveProcessor\RecordBuilder;
use Piwik\Config\GeneralConfig;
use Piwik\DataAccess\LogAggregator;
use Piwik\DataTable;
use Piwik\Metrics;
use Piwik\Plugins\Actions\ArchivingHelper;
use Piwik\Plugins\Events\Archiver;
use Piwik\RankingQuery;
use Piwik\Tracker\Action;
class EventReports extends RecordBuilder
{
public function __construct()
{
parent::__construct();
$this->columnToSortByBeforeTruncation = Metrics::INDEX_NB_VISITS;
$this->columnAggregationOps = [
Metrics::INDEX_EVENT_MIN_EVENT_VALUE => 'min',
Metrics::INDEX_EVENT_MAX_EVENT_VALUE => 'max',
];
}
public function getRecordMetadata(ArchiveProcessor $archiveProcessor): array
{
$idSite = $archiveProcessor->getParams()->getSite()->getId();
$maximumRowsInDataTable = GeneralConfig::getConfigValue('datatable_archiving_maximum_rows_events', $idSite);
$maximumRowsInSubDataTable = GeneralConfig::getConfigValue('datatable_archiving_maximum_rows_subtable_events', $idSite);
/** @var Record[] $records */
$records = [
Record::make(Record::TYPE_BLOB, Archiver::EVENTS_CATEGORY_ACTION_RECORD_NAME),
Record::make(Record::TYPE_BLOB, Archiver::EVENTS_CATEGORY_NAME_RECORD_NAME),
Record::make(Record::TYPE_BLOB, Archiver::EVENTS_ACTION_CATEGORY_RECORD_NAME),
Record::make(Record::TYPE_BLOB, Archiver::EVENTS_ACTION_NAME_RECORD_NAME),
Record::make(Record::TYPE_BLOB, Archiver::EVENTS_NAME_ACTION_RECORD_NAME),
Record::make(Record::TYPE_BLOB, Archiver::EVENTS_NAME_CATEGORY_RECORD_NAME),
];
foreach ($records as $record) {
$record->setMaxRowsInTable($maximumRowsInDataTable)
->setMaxRowsInSubtable($maximumRowsInSubDataTable)
->setBlobColumnAggregationOps($this->columnAggregationOps);
}
return $records;
}
protected function getRecordToDimensions()
{
return [
Archiver::EVENTS_CATEGORY_ACTION_RECORD_NAME => ["eventCategory", "eventAction"],
Archiver::EVENTS_CATEGORY_NAME_RECORD_NAME => ["eventCategory", "eventName"],
Archiver::EVENTS_ACTION_NAME_RECORD_NAME => ["eventAction", "eventName"],
Archiver::EVENTS_ACTION_CATEGORY_RECORD_NAME => ["eventAction", "eventCategory"],
Archiver::EVENTS_NAME_ACTION_RECORD_NAME => ["eventName", "eventAction"],
Archiver::EVENTS_NAME_CATEGORY_RECORD_NAME => ["eventName", "eventCategory"],
];
}
protected function aggregate(ArchiveProcessor $archiveProcessor): array
{
$logAggregator = $archiveProcessor->getLogAggregator();
$reports = [];
$select = "
log_action_event_category.name as eventCategory,
log_action_event_action.name as eventAction,
log_action_event_name.name as eventName,
count(distinct log_link_visit_action.idvisit) as `" . Metrics::INDEX_NB_VISITS . "`,
count(distinct log_link_visit_action.idvisitor) as `" . Metrics::INDEX_NB_UNIQ_VISITORS . "`,
count(*) as `" . Metrics::INDEX_EVENT_NB_HITS . "`,
sum(
case when " . Action::DB_COLUMN_CUSTOM_FLOAT . " is null
then 0
else " . Action::DB_COLUMN_CUSTOM_FLOAT . "
end
) as `" . Metrics::INDEX_EVENT_SUM_EVENT_VALUE . "`,
sum( case when " . Action::DB_COLUMN_CUSTOM_FLOAT . " is null then 0 else 1 end )
as `" . Metrics::INDEX_EVENT_NB_HITS_WITH_VALUE . "`,
min(" . Action::DB_COLUMN_CUSTOM_FLOAT . ") as `" . Metrics::INDEX_EVENT_MIN_EVENT_VALUE . "`,
max(" . Action::DB_COLUMN_CUSTOM_FLOAT . ") as `" . Metrics::INDEX_EVENT_MAX_EVENT_VALUE . "`
";
$from = [
"log_link_visit_action",
[
"table" => "log_action",
"tableAlias" => "log_action_event_category",
"joinOn" => "log_link_visit_action.idaction_event_category = log_action_event_category.idaction"
],
[
"table" => "log_action",
"tableAlias" => "log_action_event_action",
"joinOn" => "log_link_visit_action.idaction_event_action = log_action_event_action.idaction"
],
[
"table" => "log_action",
"tableAlias" => "log_action_event_name",
"joinOn" => "log_link_visit_action.idaction_name = log_action_event_name.idaction"
]
];
$where = $logAggregator->getWhereStatement('log_link_visit_action', 'server_time');
$where .= " AND log_link_visit_action.idaction_event_category IS NOT NULL";
$groupBy = "log_link_visit_action.idaction_event_category,
log_link_visit_action.idaction_event_action,
log_link_visit_action.idaction_name";
$orderBy = "`" . Metrics::INDEX_NB_VISITS . "` DESC, `eventName`";
$rankingQueryLimit = ArchivingHelper::getRankingQueryLimit();
$rankingQuery = null;
if ($rankingQueryLimit > 0) {
$rankingQuery = new RankingQuery($rankingQueryLimit);
$rankingQuery->addLabelColumn(['eventCategory', 'eventAction', 'eventName']);
$rankingQuery->addColumn([Metrics::INDEX_NB_UNIQ_VISITORS]);
$rankingQuery->addColumn([Metrics::INDEX_EVENT_NB_HITS, Metrics::INDEX_NB_VISITS, Metrics::INDEX_EVENT_NB_HITS_WITH_VALUE], 'sum');
$rankingQuery->addColumn(Metrics::INDEX_EVENT_SUM_EVENT_VALUE, 'sum');
$rankingQuery->addColumn(Metrics::INDEX_EVENT_MIN_EVENT_VALUE, 'min');
$rankingQuery->addColumn(Metrics::INDEX_EVENT_MAX_EVENT_VALUE, 'max');
}
$this->archiveDayQueryProcess($reports, $logAggregator, $select, $from, $where, $groupBy, $orderBy, $rankingQuery);
return $reports;
}
protected function archiveDayQueryProcess(
array &$reports,
LogAggregator $logAggregator,
string $select,
array $from,
string $where,
string $groupBy,
string $orderBy,
?RankingQuery $rankingQuery = null
): void {
// get query with segmentation
$query = $logAggregator->generateQuery($select, $from, $where, $groupBy, $orderBy);
// apply ranking query
if ($rankingQuery) {
$query['sql'] = $rankingQuery->generateRankingQuery($query['sql']);
}
// get result
$resultSet = $logAggregator->getDb()->query($query['sql'], $query['bind']);
if ($resultSet === false) {
return;
}
while ($row = $resultSet->fetch()) {
$this->aggregateEventRow($reports, $row);
}
}
protected function aggregateEventRow(array &$reports, array $row): void
{
foreach ($this->getRecordToDimensions() as $record => $dimensions) {
if (empty($reports[$record])) {
$reports[$record] = new DataTable();
}
/** @var DataTable $table */
$table = $reports[$record];
$mainDimension = $dimensions[0];
$mainLabel = $row[$mainDimension];
// Event name is optional
if (
$mainDimension == 'eventName'
&& empty($mainLabel)
) {
$mainLabel = Archiver::EVENT_NAME_NOT_SET;
}
$columns = [
Metrics::INDEX_NB_UNIQ_VISITORS => $row[Metrics::INDEX_NB_UNIQ_VISITORS] ?? 0,
Metrics::INDEX_NB_VISITS => $row[Metrics::INDEX_NB_VISITS] ?? 0,
Metrics::INDEX_EVENT_NB_HITS => $row[Metrics::INDEX_EVENT_NB_HITS] ?? 0,
Metrics::INDEX_EVENT_NB_HITS_WITH_VALUE => $row[Metrics::INDEX_EVENT_NB_HITS_WITH_VALUE] ?? 0,
Metrics::INDEX_EVENT_SUM_EVENT_VALUE => round($row[Metrics::INDEX_EVENT_SUM_EVENT_VALUE] ?? 0, 2),
Metrics::INDEX_EVENT_MIN_EVENT_VALUE => is_numeric($row[Metrics::INDEX_EVENT_MIN_EVENT_VALUE]) ? round($row[Metrics::INDEX_EVENT_MIN_EVENT_VALUE], 2) : null,
Metrics::INDEX_EVENT_MAX_EVENT_VALUE => is_numeric($row[Metrics::INDEX_EVENT_MAX_EVENT_VALUE]) ? round($row[Metrics::INDEX_EVENT_MAX_EVENT_VALUE], 2) : null,
];
$topLevelRow = $table->sumRowWithLabel($mainLabel, $columns, $this->columnAggregationOps);
$subDimension = $dimensions[1];
$subLabel = $row[$subDimension];
if (empty($subLabel)) {
continue;
}
$topLevelRow->sumRowWithLabelToSubtable($subLabel, $columns, $this->columnAggregationOps);
}
}
}