Skip to content

Commit

Permalink
restructre command class
Browse files Browse the repository at this point in the history
  • Loading branch information
sgiehl committed Jan 31, 2025
1 parent 06003c2 commit 84528ee
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 92 deletions.
6 changes: 3 additions & 3 deletions core/DataAccess/Model.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}

Expand Down Expand Up @@ -208,7 +208,7 @@ public function updateArchiveAsInvalidated(
}
}

if (true === $doNotCreateInvalidations) {
if ($doNotCreateInvalidations) {
return count($idArchives);
}

Expand Down
211 changes: 122 additions & 89 deletions plugins/CoreAdminHome/Commands/InvalidateReportData.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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');
Expand Down Expand Up @@ -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
Expand All @@ -120,103 +142,115 @@ 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
) . " ]."
);
}
}
}

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

/**
Expand All @@ -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 = [];

Expand All @@ -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');

Expand All @@ -262,7 +296,7 @@ private function getSitesToInvalidateFor()
return $siteIds;
}

private function getPeriodTypesToInvalidateFor()
private function getPeriodTypesToInvalidateFor(): array
{
$periods = $this->getInput()->getOption('periods');
if (empty($periods)) {
Expand All @@ -289,7 +323,7 @@ private function getPeriodTypesToInvalidateFor()
/**
* @return Date[][]
*/
private function getDateRangesToInvalidateFor()
private function getDateRangesToInvalidateFor(): array
{
$dateRanges = $this->getInput()->getOption('dates');
if (empty($dateRanges)) {
Expand All @@ -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();
Expand Down Expand Up @@ -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) {
Expand All @@ -380,25 +413,25 @@ 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'];
}

if (
$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;
}

Expand Down

0 comments on commit 84528ee

Please sign in to comment.