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); } } }