Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
41.03% covered (danger)
41.03%
16 / 39
33.33% covered (danger)
33.33%
2 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
SystemSettingsRepository
41.03% covered (danger)
41.03%
16 / 39
33.33% covered (danger)
33.33%
2 / 6
47.66
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 findAll
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
12
 findByKey
88.89% covered (warning)
88.89%
8 / 9
0.00% covered (danger)
0.00%
0 / 1
3.01
 update
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
12
 getValue
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLogLevelThreshold
85.71% covered (warning)
85.71%
6 / 7
0.00% covered (danger)
0.00%
0 / 1
2.01
1<?php
2
3declare(strict_types=1);
4
5namespace App\Domain\SystemSettings\Repository;
6
7use App\Domain\SystemSettings\Data\SystemSettingData;
8use PDO;
9use RuntimeException;
10
11/**
12 * Repository for system settings data access operations.
13 */
14final class SystemSettingsRepository
15{
16    public function __construct(
17        private readonly PDO $pdo,
18    ) {}
19
20    /**
21     * @return SystemSettingData[]
22     */
23    public function findAll(): array
24    {
25        $stmt = $this->pdo->query(
26            'SELECT
27                setting_id as "settingId",
28                setting_key as "settingKey",
29                setting_value as "settingValue",
30                description,
31                updated_by as "updatedBy",
32                created_at as "createdAt",
33                updated_at as "updatedAt"
34            FROM system_settings
35            ORDER BY setting_key',
36        );
37
38        if ($stmt === false) {
39            throw new RuntimeException('Failed to execute query');
40        }
41
42        $settings = [];
43        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
44            $settings[] = new SystemSettingData($row);
45        }
46
47        return $settings;
48    }
49
50    public function findByKey(string $key): ?SystemSettingData
51    {
52        $stmt = $this->pdo->prepare(
53            'SELECT
54                setting_id as "settingId",
55                setting_key as "settingKey",
56                setting_value as "settingValue",
57                description,
58                updated_by as "updatedBy",
59                created_at as "createdAt",
60                updated_at as "updatedAt"
61            FROM system_settings
62            WHERE setting_key = :key',
63        );
64
65        if ($stmt === false) {
66            throw new RuntimeException('Failed to prepare statement');
67        }
68        $stmt->execute(['key' => $key]);
69
70        $row = $stmt->fetch(PDO::FETCH_ASSOC);
71
72        return $row !== false ? new SystemSettingData($row) : null;
73    }
74
75    /**
76     * @param array<string, mixed> $value
77     * @param string $key
78     * @param ?int $updatedBy
79     */
80    public function update(string $key, array $value, ?int $updatedBy = null): bool
81    {
82        $stmt = $this->pdo->prepare(
83            'UPDATE system_settings
84            SET setting_value = :value,
85                updated_by = :updated_by,
86                updated_at = CURRENT_TIMESTAMP
87             WHERE setting_key = :key',
88        );
89
90        if ($stmt === false) {
91            throw new RuntimeException('Failed to prepare statement');
92        }
93
94        return $stmt->execute([
95            'key' => $key,
96            'value' => json_encode($value),
97            'updated_by' => $updatedBy,
98        ]) && $stmt->rowCount() > 0;
99    }
100
101    /**
102     * @param string $key
103     * @return array<string, mixed>|null
104     */
105    public function getValue(string $key): ?array
106    {
107        return $this->findByKey($key)?->settingValue;
108    }
109
110    /**
111     * @return array{value: int, level: string}
112     */
113    public function getLogLevelThreshold(): array
114    {
115        $value = $this->getValue('log_level_threshold');
116
117        if ($value === null) {
118            return ['value' => 500, 'level' => 'error'];
119        }
120
121        return [
122            'value' => (int)($value['value'] ?? 500),
123            'level' => (string)($value['level'] ?? 'error'),
124        ];
125    }
126}