2222use Piwik \Plugins \BotTracking \Archiver ;
2323use Piwik \Plugins \BotTracking \Dao \BotRequestsDao ;
2424use Piwik \Plugins \BotTracking \Metrics ;
25+ use Piwik \RankingQuery ;
2526use Piwik \Tracker \Action ;
2627use Piwik \Tracker \PageUrl ;
2728
@@ -40,13 +41,19 @@ class AIAssistantReports extends RecordBuilder
4041 'Devin ' => '' ,
4142 ];
4243
44+ /**
45+ * @var int
46+ */
47+ private $ rankingQueryLimit ;
48+
4349 public function __construct ()
4450 {
4551 parent ::__construct ();
4652
4753 $ this ->columnToSortByBeforeTruncation = Metrics::COLUMN_REQUESTS ;
4854 $ this ->maxRowsInTable = (int )GeneralConfig::getConfigValue ('datatable_archiving_maximum_rows_bots ' );
4955 $ this ->maxRowsInSubtable = (int )GeneralConfig::getConfigValue ('datatable_archiving_maximum_rows_subtable_bots ' );
56+ $ this ->rankingQueryLimit = $ this ->getRankingQueryLimit ();
5057 }
5158
5259 public function getRecordMetadata (ArchiveProcessor $ archiveProcessor ): array
@@ -137,27 +144,9 @@ private function queryAcquiredVisitsByAIAssistant(LogAggregator $logAggregator):
137144 */
138145 private function populateTableForActionType (array $ tables , int $ actionType , LogAggregator $ logAggregator , array $ visits ): void
139146 {
140- $ where = $ logAggregator ->getWhereStatement ('bot ' , 'server_time ' );
141- $ bindBase = $ logAggregator ->getGeneralQueryBindParams ();
142-
143- $ sql = sprintf (
144- "SELECT * FROM (SELECT bot.bot_name, log_action.name AS url, COUNT(*) AS requests
145- FROM %s AS bot
146- INNER JOIN %s AS log_action ON log_action.idaction = bot.idaction_url
147- WHERE log_action.name IS NOT NULL
148- AND log_action.name <> ''
149- AND log_action.type = %d
150- AND %s
151- GROUP BY bot.bot_name, url WITH ROLLUP) AS rollupQuery
152- ORDER BY bot_name, requests DESC, url " ,
153- BotRequestsDao::getPrefixedTableName (),
154- Common::prefixTable ('log_action ' ),
155- $ actionType ,
156- $ where
157- );
158-
159- $ resultSet = Db::query ($ sql , $ bindBase );
147+ $ resultSet = $ this ->queryBotRequests ($ logAggregator , $ actionType );
160148 $ actionRows = [];
149+ $ botTotals = [];
161150
162151 while ($ row = $ resultSet ->fetch ()) {
163152 /**
@@ -170,19 +159,28 @@ private function populateTableForActionType(array $tables, int $actionType, LogA
170159 continue ;
171160 }
172161
173- if (!is_null ($ url )) {
174- $ actionRows [] = $ row ;
162+ if (is_null ($ url )) {
175163 continue ;
176164 }
177165
178- $ metrics = [
179- Metrics::COLUMN_REQUESTS => $ row ['requests ' ],
180- Metrics::COLUMN_DOCUMENT_REQUESTS => $ actionType === Action::TYPE_DOWNLOAD ? $ row ['requests ' ] : 0 ,
181- Metrics::COLUMN_PAGE_REQUESTS => $ actionType === Action::TYPE_PAGE_URL ? $ row ['requests ' ] : 0 ,
182- Metrics::COLUMN_ACQUIRED_VISITS => $ visits [$ label ] ?? 0 ,
183- ];
166+ $ actionRows [] = $ row ;
167+
168+ if (!isset ($ botTotals [$ label ])) {
169+ $ botTotals [$ label ] = [
170+ Metrics::COLUMN_REQUESTS => 0 ,
171+ Metrics::COLUMN_DOCUMENT_REQUESTS => 0 ,
172+ Metrics::COLUMN_PAGE_REQUESTS => 0 ,
173+ Metrics::COLUMN_ACQUIRED_VISITS => 0 ,
174+ ];
175+ }
176+
177+ $ botTotals [$ label ][Metrics::COLUMN_REQUESTS ] += $ row ['requests ' ];
178+ $ botTotals [$ label ][Metrics::COLUMN_DOCUMENT_REQUESTS ] += $ actionType === Action::TYPE_DOWNLOAD ? $ row ['requests ' ] : 0 ;
179+ $ botTotals [$ label ][Metrics::COLUMN_PAGE_REQUESTS ] += $ actionType === Action::TYPE_PAGE_URL ? $ row ['requests ' ] : 0 ;
180+ $ botTotals [$ label ][Metrics::COLUMN_ACQUIRED_VISITS ] = max ($ botTotals [$ label ][Metrics::COLUMN_ACQUIRED_VISITS ], $ visits [$ label ] ?? 0 );
181+ }
184182
185- // we add all records to both tables, so we in the end have the total count of pages & documents in the main table
183+ foreach ( $ botTotals as $ label => $ metrics ) {
186184 $ tables [Archiver::AI_ASSISTANTS_PAGES_RECORD ]->sumRowWithLabel ($ label , $ metrics , [Metrics::COLUMN_ACQUIRED_VISITS => 'max ' ]);
187185 $ tables [Archiver::AI_ASSISTANTS_DOCUMENTS_RECORD ]->sumRowWithLabel ($ label , $ metrics , [Metrics::COLUMN_ACQUIRED_VISITS => 'max ' ]);
188186 }
@@ -202,6 +200,10 @@ private function populateTableForActionType(array $tables, int $actionType, LogA
202200 $ label = $ row ['bot_name ' ];
203201 $ url = $ row ['url ' ];
204202
203+ if ($ label === RankingQuery::LABEL_SUMMARY_ROW ) {
204+ continue ;
205+ }
206+
205207 $ tableRow = $ table ->getRowFromLabel ($ label );
206208
207209 if (empty ($ tableRow )) {
@@ -216,4 +218,48 @@ private function populateTableForActionType(array $tables, int $actionType, LogA
216218 ]);
217219 }
218220 }
221+
222+ private function queryBotRequests (LogAggregator $ logAggregator , int $ actionType )
223+ {
224+ $ where = $ logAggregator ->getWhereStatement ('bot ' , 'server_time ' );
225+ $ where .= ' AND log_action.name IS NOT NULL
226+ AND log_action.name <> \'\'
227+ AND log_action.type = ' . $ actionType ;
228+
229+ $ sql = sprintf (
230+ "SELECT bot.bot_name, log_action.name AS url, COUNT(*) AS requests
231+ FROM %s AS bot
232+ INNER JOIN %s AS log_action ON log_action.idaction = bot.idaction_url
233+ WHERE %s
234+ GROUP BY bot.bot_name, url
235+ ORDER BY bot.bot_name, requests DESC, url " ,
236+ BotRequestsDao::getPrefixedTableName (),
237+ Common::prefixTable ('log_action ' ),
238+ $ where
239+ );
240+
241+ if ($ this ->rankingQueryLimit > 0 ) {
242+ $ rankingQuery = new RankingQuery ($ this ->rankingQueryLimit );
243+ $ rankingQuery ->addLabelColumn (['bot_name ' , 'url ' ]);
244+ $ rankingQuery ->addColumn ('requests ' , 'sum ' );
245+ $ sql = $ rankingQuery ->generateRankingQuery ($ sql );
246+ }
247+
248+ return Db::query ($ sql , $ logAggregator ->getGeneralQueryBindParams ());
249+ }
250+
251+ private function getRankingQueryLimit (): int
252+ {
253+ $ maxRowsInTable = (int )$ this ->maxRowsInTable ;
254+ $ maxRowsInSubtable = (int )$ this ->maxRowsInSubtable ;
255+
256+ $ configLimit = (int )GeneralConfig::getConfigValue ('archiving_ranking_query_row_limit ' );
257+ $ configLimit = max ($ configLimit , 10 * $ maxRowsInTable );
258+
259+ if ($ configLimit === 0 ) {
260+ return 0 ;
261+ }
262+
263+ return max ($ configLimit , $ maxRowsInTable , $ maxRowsInSubtable );
264+ }
219265}
0 commit comments