Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
24 / 24
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
AuditRetentionCronJob
100.00% covered (success)
100.00%
23 / 23
100.00% covered (success)
100.00%
3 / 3
6
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 run
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
2
 resolveService
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2
3declare(strict_types=1);
4
5/** @license For full copyright and license information, please see the LICENSE.md file. */
6
7namespace App\Core\Audit\Infrastructure\Cron;
8
9defined('AMMONLY_APP') || exit('Direct script access is forbidden.');
10
11use App\Core\Audit\Application\Service\AuditRetentionService;
12use App\Core\Cron\CronTaskInterface;
13use App\Core\Database\MultiDbRouter;
14use App\Shared\Infrastructure\Config\InstallerConfigLoader;
15use PDO;
16
17/**
18 * Audit and Security Logs Retention Purge Cron Job.
19 *
20 * Implements CronTaskInterface to periodically prune expired audit entries according to retention settings.
21 *
22 * @package App\Core\Audit\Infrastructure\Cron
23 */
24final readonly class AuditRetentionCronJob implements CronTaskInterface
25{
26    /**
27     * AuditRetentionCronJob constructor.
28     *
29     * @param AuditRetentionService|PDO|null $source Audit retention service or PDO instance.
30     * @param string                         $prefix Database table prefix.
31     * @param int                            $auditDays Retention days for CRUD audit logs.
32     * @param int                            $securityDays Retention days for security alert logs.
33     */
34    public function __construct(
35        private AuditRetentionService|PDO|null $source = null,
36        private string                         $prefix = 'a_',
37        private int                            $auditDays = 180,
38        private int                            $securityDays = 365,
39    ) {
40    }
41
42    /** {@inheritdoc} */
43    public function run(): string
44    {
45        $service = $this->resolveService();
46        $results = $service->pruneExpiredLogs($this->auditDays, $this->securityDays);
47
48        $totalPruned = array_sum($results);
49        $summary = [];
50        foreach ($results as $table => $count) {
51            $summary[] = "{$table}{$count}";
52        }
53
54        return sprintf(
55            'AuditRetention: pruned %d total record(s) (Retention: audit=%dd, security=%dd). Details: %s',
56            $totalPruned,
57            $this->auditDays,
58            $this->securityDays,
59            implode(', ', $summary)
60        );
61    }
62
63    /**
64     * Resolves an AuditRetentionService instance.
65     */
66    private function resolveService(): AuditRetentionService
67    {
68        if ($this->source instanceof AuditRetentionService) {
69            return $this->source;
70        }
71
72        if ($this->source instanceof PDO) {
73            return new AuditRetentionService($this->source, $this->prefix);
74        }
75
76        $config = InstallerConfigLoader::load();
77        $dbParams = $config['db'] ?? [];
78        $router = new MultiDbRouter(['default' => $dbParams]);
79        $pdo = $router->getConnection('default');
80
81        return new AuditRetentionService($pdo, $this->prefix);
82    }
83}