Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions config/global.ini.php
Original file line number Diff line number Diff line change
Expand Up @@ -1154,6 +1154,10 @@
delete_reports_keep_range_reports = 0
delete_reports_keep_segment_reports = 0

[ArchivingMetrics]
; retention_days - delete archiving metrics older than this many days. Set to 0 to disable cleanup.
retention_days = 180

[mail]
defaultHostnameIfEmpty = defaultHostnameIfEmpty.example.org ; default Email @hostname, if current host can't be read from system variables
transport = ; smtp (using the configuration below) or empty (using built-in mail() function)
Expand Down
58 changes: 58 additions & 0 deletions plugins/ArchivingMetrics/Tasks.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

/**
* Matomo - free/libre analytics platform
*
* @link https://matomo.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/

declare(strict_types=1);

namespace Piwik\Plugins\ArchivingMetrics;

use Piwik\Common;
use Piwik\Config;
use Piwik\Date;
use Piwik\Db;

class Tasks extends \Piwik\Plugin\Tasks
{
public const DEFAULT_RETENTION_DAYS = 180;

public function schedule()
{
$this->weekly('purgeOldMetrics');
$this->monthly('purgeMetricsForDeletedSites');
}

/**
* To test execute the following command:
* `./console core:run-scheduled-tasks --force "Piwik\Plugins\ArchivingMetrics\Tasks.purgeOldMetrics"`
*/
public function purgeOldMetrics()
{
$retentionDays = $this->getRetentionDays();
if ($retentionDays <= 0) {
return;
}

$cutoff = Date::now()->subDay($retentionDays)->getDatetime();
$table = Common::prefixTable('archiving_metrics');
Db::query("DELETE FROM {$table} WHERE ts_started < ?", [$cutoff]);
}

public function purgeMetricsForDeletedSites()
{
$siteTable = Common::prefixTable('site');
$table = Common::prefixTable('archiving_metrics');
Db::query("DELETE a FROM {$table} a LEFT JOIN {$siteTable} s ON a.idsite = s.idsite WHERE s.idsite IS NULL");
}

private function getRetentionDays(): int
{
$config = Config::getInstance();
$retentionDays = $config->ArchivingMetrics['retention_days'] ?? self::DEFAULT_RETENTION_DAYS;
return max(0, (int) $retentionDays);
}
}
92 changes: 92 additions & 0 deletions plugins/ArchivingMetrics/tests/Integration/TasksTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?php

/**
* Matomo - free/libre analytics platform
*
* @link https://matomo.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/

declare(strict_types=1);

namespace Piwik\Plugins\ArchivingMetrics\tests\Integration;

use Piwik\Common;
use Piwik\Config;
use Piwik\Date;
use Piwik\Db;
use Piwik\Plugins\ArchivingMetrics\Tasks;
use Piwik\Tests\Framework\Fixture;
use Piwik\Tests\Framework\TestCase\IntegrationTestCase;

/**
* @group ArchivingMetrics
* @group ArchivingMetrics_Tasks
* @group Plugins
*/
class TasksTest extends IntegrationTestCase
{
public function testPurgeOldMetricsDeletesRowsOlderThanRetention(): void
{
$config = Config::getInstance();
$config->ArchivingMetrics = ['retention_days' => 30];

$this->insertRow(Date::now()->subDay(31)->getDatetime());
$this->insertRow(Date::now()->subDay(5)->getDatetime());

$task = new Tasks();
$task->purgeOldMetrics();

$count = (int) Db::fetchOne('SELECT COUNT(*) FROM ' . Common::prefixTable('archiving_metrics'));
$this->assertSame(1, $count);
}

public function testPurgeOldMetricsDisabledKeepsRows(): void
{
$config = Config::getInstance();
$config->ArchivingMetrics = ['retention_days' => 0];

$this->insertRow(Date::now()->subDay(400)->getDatetime());

$task = new Tasks();
$task->purgeOldMetrics();

$count = (int) Db::fetchOne('SELECT COUNT(*) FROM ' . Common::prefixTable('archiving_metrics'));
$this->assertSame(1, $count);
}

public function testPurgeMetricsForDeletedSitesRemovesOrphanedRows(): void
{
$idSite = Fixture::createWebsite('2024-01-01 00:00:00');

$this->insertRow(Date::now()->subDay(5)->getDatetime(), $idSite);
$this->insertRow(Date::now()->subDay(5)->getDatetime(), 9999);

$task = new Tasks();
$task->purgeMetricsForDeletedSites();

$count = (int) Db::fetchOne('SELECT COUNT(*) FROM ' . Common::prefixTable('archiving_metrics'));
$this->assertSame(1, $count);
}

private function insertRow(string $tsStarted, int $idSite = 1): void
{
$table = Common::prefixTable('archiving_metrics');
Db::query(
"INSERT INTO {$table} (idarchive, idsite, archive_name, date1, date2, period, ts_started, ts_finished, total_time, total_time_exclusive)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
[
1,
$idSite,
'done',
'2025-01-01',
'2025-01-01',
1,
$tsStarted,
$tsStarted,
123,
100,
]
);
}
}
Loading