From 84528ee5f294131a2172a43d567a4d790184d594 Mon Sep 17 00:00:00 2001 From: sgiehl Date: Fri, 31 Jan 2025 14:03:22 +0100 Subject: [PATCH] restructre command class --- core/DataAccess/Model.php | 6 +- .../Commands/InvalidateReportData.php | 211 ++++++++++-------- 2 files changed, 125 insertions(+), 92 deletions(-) diff --git a/core/DataAccess/Model.php b/core/DataAccess/Model.php index 8b10fc14f40..82b940b1a3a 100644 --- a/core/DataAccess/Model.php +++ b/core/DataAccess/Model.php @@ -173,9 +173,9 @@ public function updateArchiveAsInvalidated( } } else { if (null === $segment) { - $nameCondition = "name LIKE '$doneFlag%.$plugin'"; // invalidate all segments + $nameCondition = "name LIKE '$doneFlag%.$plugin'"; // invalidate all segments for specific plugin } else { - $nameCondition = "name = '$doneFlag.$plugin'"; // invalidate specific segment only + $nameCondition = "name = '$doneFlag.$plugin'"; // invalidate specific segment for specific plugin only } } @@ -208,7 +208,7 @@ public function updateArchiveAsInvalidated( } } - if (true === $doNotCreateInvalidations) { + if ($doNotCreateInvalidations) { return count($idArchives); } diff --git a/plugins/CoreAdminHome/Commands/InvalidateReportData.php b/plugins/CoreAdminHome/Commands/InvalidateReportData.php index 5fbeea65846..9f65c247186 100644 --- a/plugins/CoreAdminHome/Commands/InvalidateReportData.php +++ b/plugins/CoreAdminHome/Commands/InvalidateReportData.php @@ -10,6 +10,7 @@ namespace Piwik\Plugins\CoreAdminHome\Commands; use Exception; +use Piwik\Archive\ArchiveInvalidator; use Piwik\ArchiveProcessor\Rules; use Piwik\Container\StaticContainer; use Piwik\Date; @@ -36,6 +37,24 @@ class InvalidateReportData extends ConsoleCommand */ private $allSegments = null; + /** + * @var LoggerInterface + */ + private $logger; + + /** + * @var ArchiveInvalidator + */ + private $invalidator; + + public function __construct() + { + parent::__construct(); + + $this->logger = StaticContainer::get(LoggerInterface::class); + $this->invalidator = StaticContainer::get(ArchiveInvalidator::class); + } + protected function configure() { $this->setName('core:invalidate-report-data'); @@ -95,23 +114,26 @@ protected function configure() protected function doExecute(): int { - $input = $this->getInput(); - $output = $this->getOutput(); - - $invalidator = StaticContainer::get('Piwik\Archive\ArchiveInvalidator'); - - $cascade = $input->getOption('cascade'); - $dryRun = $input->getOption('dry-run'); - $plugin = $input->getOption('plugin'); - $ignoreLogDeletionLimit = $input->getOption('ignore-log-deletion-limit'); - $sites = $this->getSitesToInvalidateFor(); $periodTypes = $this->getPeriodTypesToInvalidateFor(); $dateRanges = $this->getDateRangesToInvalidateFor(); $segments = $this->getSegmentsToInvalidateFor($sites); - $logger = StaticContainer::get(LoggerInterface::class); + $this->logUnavailableSegmentsInfo($segments, $sites); + + foreach ($periodTypes as $periodType) { + if ($periodType === 'range') { + $this->invalidateRangePeriods($dateRanges, $segments, $sites); + } else { + $this->invalidateNonRangePeriods($periodType, $dateRanges, $segments, $sites); + } + } + + return self::SUCCESS; + } + private function logUnavailableSegmentsInfo(array $segments, array $sites): void + { // check availability of provided segments for all sites foreach ($segments as $segmentStr) { // determine sites where current segment is available for @@ -120,14 +142,14 @@ protected function doExecute(): int if (empty($sitesToProcess)) { // segment not available for any site - $logger->info("Segment [$segmentStr] not available for any site, skipping it..."); + $this->logger->info("Segment [$segmentStr] not available for any site, skipping it..."); continue; } $sitesDiff = array_diff($sites, $sitesToProcess); if (count($sitesDiff)) { - $logger->info( + $this->logger->info( "Segment [$segmentStr] not available for all sites, skipping this segment for sites [ " . implode( ', ', $sitesDiff @@ -135,88 +157,100 @@ protected function doExecute(): int ); } } + } + private function invalidateNonRangePeriods( + string $periodType, + array $dateRangesToInvalidate, + array $segments, + array $sites + ): void { + $ignoreLogDeletionLimit = $this->getInput()->getOption('ignore-log-deletion-limit'); + $cascade = $this->getInput()->getOption('cascade'); + $dryRun = $this->getInput()->getOption('dry-run'); + $plugin = $this->getInput()->getOption('plugin'); + + foreach ($dateRangesToInvalidate as $dateRange) { + foreach ($segments as $segmentStr) { + // determine sites where current segment is available for + $sitesToProcess = $this->getSitesForSegment($segmentStr, $sites); + $segment = new Segment($segmentStr, $sitesToProcess); + + if (empty($sitesToProcess)) { + continue; + } - foreach ($periodTypes as $periodType) { - if ($periodType === 'range') { - continue; // special handling for range below - } - foreach ($dateRanges as $dateRange) { - foreach ($segments as $segmentStr) { - // determine sites where current segment is available for - $sitesToProcess = $this->getSitesForSegment($segmentStr, $sites); - $segment = new Segment($segmentStr, $sitesToProcess); - - if (empty($sitesToProcess)) { - continue; - } - - $logger->info("Invalidating $periodType periods in $dateRange for site = [ " - . implode(', ', $sitesToProcess) . " ], segment = [ $segmentStr ]..."); + $this->logger->info("Invalidating $periodType periods in $dateRange for site = [ " + . implode(', ', $sitesToProcess) . " ], segment = [ $segmentStr ]..."); - $dates = $this->getPeriodDates($periodType, $dateRange); + $dates = $this->getPeriodDates($periodType, $dateRange); - if ($dryRun) { - $message = "[Dry-run] invalidating archives for site = [ " . implode(', ', $sitesToProcess) - . " ], dates = [ " . implode(', ', $dates) . " ], period = [ $periodType ], segment = [ " - . "$segmentStr ], cascade = [ " . (int)$cascade . " ]"; - if (!empty($plugin)) { - $message .= ", plugin = [ $plugin ]"; - } - $logger->info($message); - } else { - $invalidationResult = $invalidator->markArchivesAsInvalidated( - $sitesToProcess, - $dates, - $periodType, - $segment, - $cascade, - false, - $plugin, - $ignoreLogDeletionLimit - ); - - if ($output->getVerbosity() > $output::VERBOSITY_NORMAL) { - foreach ($invalidationResult->makeOutputLogs() as $outputLog) { - $logger->info($outputLog); - } + if ($dryRun) { + $message = "[Dry-run] invalidating archives for site = [ " . implode(', ', $sitesToProcess) + . " ], dates = [ " . implode(', ', $dates) . " ], period = [ $periodType ], segment = [ " + . "$segmentStr ], cascade = [ " . (int)$cascade . " ]"; + if (!empty($plugin)) { + $message .= ", plugin = [ $plugin ]"; + } + $this->logger->info($message); + } else { + $invalidationResult = $this->invalidator->markArchivesAsInvalidated( + $sitesToProcess, + $dates, + $periodType, + $segment, + $cascade, + false, + $plugin, + $ignoreLogDeletionLimit + ); + + if ($this->getOutput()->getVerbosity() > $this->getOutput()::VERBOSITY_NORMAL) { + foreach ($invalidationResult->makeOutputLogs() as $outputLog) { + $this->logger->info($outputLog); } } } } } + } - $periods = trim($input->getOption('periods')); + private function invalidateRangePeriods( + array $dateRangesToInvalidate, + array $segments, + array $sites + ): void { + $dryRun = $this->getInput()->getOption('dry-run'); + $plugin = $this->getInput()->getOption('plugin'); + $periods = trim($this->getInput()->getOption('periods')); $isUsingAllOption = $periods === self::ALL_OPTION_VALUE; - if ($isUsingAllOption || in_array('range', $periodTypes)) { - $rangeDates = array(); - foreach ($dateRanges as $dateRange) { - if ( - $isUsingAllOption - && !Period::isMultiplePeriod($dateRange, 'day') - ) { - continue; // not a range, nothing to do... only when "all" option is used - } + $rangeDates = []; - $rangeDates[] = $this->getPeriodDates('range', $dateRange); + foreach ($dateRangesToInvalidate as $dateRange) { + if ( + $isUsingAllOption + && !Period::isMultiplePeriod($dateRange, 'day') + ) { + continue; // not a range, nothing to do... only when "all" option is used } - if (!empty($rangeDates)) { - foreach ($segments as $segmentStr) { - $sitesToProcess = $this->getSitesForSegment($segmentStr, $sites); - $segment = new Segment($segmentStr, $sitesToProcess); - - if ($dryRun) { - $dateRangeStr = implode(';', $dateRanges); - $logger->info("Invalidating range periods overlapping $dateRangeStr for " - . "site = [ " . implode(', ', $sitesToProcess) . " ], segment = [ $segmentStr ]..."); - } else { - $invalidator->markArchivesOverlappingRangeAsInvalidated($sitesToProcess, $rangeDates, $segment, $plugin); - } + + $rangeDates[] = $this->getPeriodDates('range', $dateRange); + } + + if (!empty($rangeDates)) { + foreach ($segments as $segmentStr) { + $sitesToProcess = $this->getSitesForSegment($segmentStr, $sites); + $segment = new Segment($segmentStr, $sitesToProcess); + + if ($dryRun) { + $dateRangeStr = implode(';', $dateRangesToInvalidate); + $this->logger->info("Invalidating range periods overlapping $dateRangeStr for " + . "site = [ " . implode(', ', $sitesToProcess) . " ], segment = [ $segmentStr ]..."); + } else { + $this->invalidator->markArchivesOverlappingRangeAsInvalidated($sitesToProcess, $rangeDates, $segment, $plugin); } } } - - return self::SUCCESS; } /** @@ -227,7 +261,7 @@ protected function doExecute(): int * @return array * @throws \Exception */ - private function getSitesForSegment(string $segmentStr, array $idSites) + private function getSitesForSegment(string $segmentStr, array $idSites): array { $sitesToProcess = []; @@ -243,7 +277,7 @@ private function getSitesForSegment(string $segmentStr, array $idSites) return $sitesToProcess; } - private function getSitesToInvalidateFor() + private function getSitesToInvalidateFor(): array { $sites = $this->getInput()->getOption('sites'); @@ -262,7 +296,7 @@ private function getSitesToInvalidateFor() return $siteIds; } - private function getPeriodTypesToInvalidateFor() + private function getPeriodTypesToInvalidateFor(): array { $periods = $this->getInput()->getOption('periods'); if (empty($periods)) { @@ -289,7 +323,7 @@ private function getPeriodTypesToInvalidateFor() /** * @return Date[][] */ - private function getDateRangesToInvalidateFor() + private function getDateRangesToInvalidateFor(): array { $dateRanges = $this->getInput()->getOption('dates'); if (empty($dateRanges)) { @@ -311,7 +345,7 @@ private function getPeriodDates($periodType, $dateRange) throw new \InvalidArgumentException("Invalid date or date range specifier '$dateRange'", $code = 0, $ex); } - $result = array(); + $result = []; if ($periodType === 'range') { $result[] = $period->getDateStart(); $result[] = $period->getDateEnd(); @@ -368,7 +402,6 @@ private function getSegmentsToInvalidateFor(array $idSites): array */ private function findSegment(string $segmentOptionValue, array $idSites) { - $logger = StaticContainer::get(LoggerInterface::class); $allSegments = $this->getAllSegments($idSites); foreach ($allSegments as $segment) { @@ -380,12 +413,12 @@ private function findSegment(string $segmentOptionValue, array $idSites) } if ($segmentOptionValue == $segment['idsegment']) { - $logger->debug("Matching '$segmentOptionValue' by idsegment with segment {segment}.", ['segment' => json_encode($segment)]); + $this->logger->debug("Matching '$segmentOptionValue' by idsegment with segment {segment}.", ['segment' => json_encode($segment)]); return $segment['definition']; } if (strtolower($segmentOptionValue) == strtolower($segment['name'])) { - $logger->debug("Matching '$segmentOptionValue' by name with segment {segment}.", ['segment' => json_encode($segment)]); + $this->logger->debug("Matching '$segmentOptionValue' by name with segment {segment}.", ['segment' => json_encode($segment)]); return $segment['definition']; } @@ -393,12 +426,12 @@ private function findSegment(string $segmentOptionValue, array $idSites) $segment['definition'] == $segmentOptionValue || $segment['definition'] == urldecode($segmentOptionValue) ) { - $logger->debug("Matching '{value}' by definition with segment {segment}.", ['value' => $segmentOptionValue, 'segment' => json_encode($segment)]); + $this->logger->debug("Matching '{value}' by definition with segment {segment}.", ['value' => $segmentOptionValue, 'segment' => json_encode($segment)]); return $segment['definition']; } } - $logger->warning("'$segmentOptionValue' did not match any stored segment, but invalidating it anyway."); + $this->logger->warning("'$segmentOptionValue' did not match any stored segment, but invalidating it anyway."); return $segmentOptionValue; }