diff --git a/plugins/DevicePlugins/API.php b/plugins/DevicePlugins/API.php index a325047a751..34c0f32d94f 100644 --- a/plugins/DevicePlugins/API.php +++ b/plugins/DevicePlugins/API.php @@ -46,56 +46,64 @@ public function getPlugin($idSite, $period, $date, $segment = false) $archive = Archive::build($idSite, $period, $date, $segment); $visitsSums = $archive->getDataTableFromNumeric('nb_visits'); - // check whether given tables are arrays if ($dataTable instanceof DataTable\Map) { - $dataTableMap = $dataTable->getDataTables(); - $browserVersionsArray = $browserVersions->getDataTables(); - $visitSumsArray = $visitsSums->getDataTables(); + $dataTable->multiFilter( + [ + $browserVersions instanceof DataTable\Map ? $browserVersions : null, + $visitsSums instanceof DataTable\Map ? $visitsSums : null, + ], + function (DataTable $pluginTable, ?DataTable $browserVersionsTable, ?DataTable $visitsTable): void { + $this->addVisitsPercentProcessedMetric($pluginTable, $browserVersionsTable, $visitsTable); + } + ); } else { - $dataTableMap = array($dataTable); - $browserVersionsArray = array($browserVersions); - $visitSumsArray = array($visitsSums); + $this->addVisitsPercentProcessedMetric( + $dataTable, + $browserVersions instanceof DataTable ? $browserVersions : null, + $visitsSums instanceof DataTable ? $visitsSums : null + ); } - // walk through the results and calculate the percentage - foreach ($dataTableMap as $key => $table) { - // Calculate percentage, but ignore IE users because plugin detection doesn't work on IE - $ieVisits = 0; + $dataTable->queueFilter('ColumnCallbackAddMetadata', ['label', 'logo', __NAMESPACE__ . '\getPluginsLogo']); + $dataTable->queueFilter('ColumnCallbackReplace', ['label', 'ucfirst']); + $dataTable->queueFilter('RangeCheck', ['nb_visits_percentage', 0, 1]); - $browserVersionsToExclude = array( - 'IE;10.0', - 'IE;9.0', - 'IE;8.0', - 'IE;7.0', - 'IE;6.0', - ); - foreach ($browserVersionsToExclude as $browserVersionToExclude) { - $ieStats = $browserVersionsArray[$key]->getRowFromLabel($browserVersionToExclude); - if ($ieStats !== false) { - $ieVisits += $ieStats->getColumn(Metrics::INDEX_NB_VISITS); - } - } + return $dataTable; + } - // get according visitsSum - $visits = $visitSumsArray[$key]; - if ($visits->getRowsCount() == 0) { - $visitsSumTotal = 0; - } else { - $visitsSumTotal = (float) $visits->getFirstRow()->getColumn('nb_visits'); - } + private function addVisitsPercentProcessedMetric( + DataTable $table, + ?DataTable $browserVersions, + ?DataTable $visits + ): void { + // Calculate percentage, but ignore IE users because plugin detection doesn't work on IE + $ieVisits = 0; - $visitsSum = $visitsSumTotal - $ieVisits; + $browserVersionsToExclude = [ + 'IE;10.0', + 'IE;9.0', + 'IE;8.0', + 'IE;7.0', + 'IE;6.0', + ]; + foreach ($browserVersionsToExclude as $browserVersionToExclude) { + $ieStats = $browserVersions ? $browserVersions->getRowFromLabel($browserVersionToExclude) : false; + if ($ieStats !== false) { + $ieVisits += $ieStats->getColumn(Metrics::INDEX_NB_VISITS); + } + } - $extraProcessedMetrics = $table->getMetadata(DataTable::EXTRA_PROCESSED_METRICS_METADATA_NAME); - $extraProcessedMetrics = is_array($extraProcessedMetrics) ? $extraProcessedMetrics : []; - $extraProcessedMetrics[] = new VisitsPercent($visitsSum); - $table->setMetadata(DataTable::EXTRA_PROCESSED_METRICS_METADATA_NAME, $extraProcessedMetrics); + if (!$visits || $visits->getRowsCount() == 0) { + $visitsSumTotal = 0; + } else { + $visitsSumTotal = (float)$visits->getFirstRow()->getColumn('nb_visits'); } - $dataTable->queueFilter('ColumnCallbackAddMetadata', array('label', 'logo', __NAMESPACE__ . '\getPluginsLogo')); - $dataTable->queueFilter('ColumnCallbackReplace', array('label', 'ucfirst')); - $dataTable->queueFilter('RangeCheck', array('nb_visits_percentage', 0, 1)); + $visitsSum = $visitsSumTotal - $ieVisits; - return $dataTable; + $extraProcessedMetrics = $table->getMetadata(DataTable::EXTRA_PROCESSED_METRICS_METADATA_NAME); + $extraProcessedMetrics = is_array($extraProcessedMetrics) ? $extraProcessedMetrics : []; + $extraProcessedMetrics[] = new VisitsPercent($visitsSum); + $table->setMetadata(DataTable::EXTRA_PROCESSED_METRICS_METADATA_NAME, $extraProcessedMetrics); } } diff --git a/plugins/DevicePlugins/tests/Integration/GetPluginApiTest.php b/plugins/DevicePlugins/tests/Integration/GetPluginApiTest.php new file mode 100644 index 00000000000..cb34368b449 --- /dev/null +++ b/plugins/DevicePlugins/tests/Integration/GetPluginApiTest.php @@ -0,0 +1,72 @@ +trackVisit(1, '2024-01-16 10:00:00'); + $this->trackVisit(1, '2024-01-17 10:00:00'); + $this->trackVisit(2, '2024-01-16 11:00:00'); + $this->trackVisit(2, '2024-01-17 11:00:00'); + } + + public function testGetPluginShouldSupportMultiSiteAndMultiPeriodRequests(): void + { + $result = API::getInstance()->getPlugin('1,2', 'day', '2024-01-16,2024-01-17'); + + self::assertInstanceOf(DataTable\Map::class, $result); + + $result->applyQueuedFilters(); + + foreach ($result->getDataTables() as $siteTable) { + self::assertInstanceOf(DataTable\Map::class, $siteTable); + + foreach ($siteTable->getDataTables() as $periodTable) { + self::assertInstanceOf(DataTable::class, $periodTable); + self::assertNotEmpty( + array_filter( + $periodTable->getMetadata(DataTable::EXTRA_PROCESSED_METRICS_METADATA_NAME) ?: [], + function ($metric) { + return $metric instanceof VisitsPercent; + } + ) + ); + self::assertGreaterThan(0, $periodTable->getRowsCount()); + } + } + } + + private function trackVisit(int $idSite, string $dateTime): void + { + $tracker = Fixture::getTracker($idSite, $dateTime, true, true); + $tracker->setIp(sprintf('10.0.0.%d', $idSite)); + $tracker->setPlugins(true, false, true, false, true); + $tracker->setUrl(sprintf('https://example.org/site-%d', $idSite)); + Fixture::checkResponse($tracker->doTrackPageView('Plugin Report Visit')); + } +}