| <?php |
|
|
| |
| |
| |
| |
| |
| |
|
|
| 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); |
|
|
| |
| $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 { |
| |
| $query = $logAggregator->generateQuery($select, $from, $where, $groupBy, $orderBy); |
|
|
| |
| if ($rankingQuery) { |
| $query['sql'] = $rankingQuery->generateRankingQuery($query['sql']); |
| } |
|
|
| |
| $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(); |
| } |
|
|
| |
| $table = $reports[$record]; |
|
|
| $mainDimension = $dimensions[0]; |
| $mainLabel = $row[$mainDimension]; |
|
|
| |
| 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); |
| } |
| } |
| } |
|
|