Lines 100.00% 34 / 34
Methods 100.00% 16 / 16
Classes 100.00% 1 / 1
Covered by tests of size
Name Lines Methods CRAP
 getId 100.00% 1 / 1 100.00% 1 / 1 1
 setId 100.00% 2 / 2 100.00% 1 / 1 1
 getTime 100.00% 1 / 1 100.00% 1 / 1 1
 setTime 100.00% 2 / 2 100.00% 1 / 1 1
 getUserId 100.00% 1 / 1 100.00% 1 / 1 1
 setUserId 100.00% 2 / 2 100.00% 1 / 1 1
 getText 100.00% 1 / 1 100.00% 1 / 1 1
 setText 100.00% 2 / 2 100.00% 1 / 1 1
 getIp 100.00% 1 / 1 100.00% 1 / 1 1
 setIp 100.00% 2 / 2 100.00% 1 / 1 1
 getHash 100.00% 1 / 1 100.00% 1 / 1 1
 setHash 100.00% 2 / 2 100.00% 1 / 1 1
 getPreviousHash 100.00% 1 / 1 100.00% 1 / 1 1
 setPreviousHash 100.00% 2 / 2 100.00% 1 / 1 1
 calculateHash 100.00% 8 / 8 100.00% 1 / 1 1
 verifyIntegrity 100.00% 5 / 5 100.00% 1 / 1 2
22class AdminLog
23{
24    private int $id = 0;
25
26    private int $time = 0;
27
28    private int $userId = 0;
29
30    private string $text = '';
31
32    private string $ip = '';
33
34    private ?string $hash = null;
35    private ?string $previousHash = null;
36
37    public function getId(): int
38    {
39        return $this->id;
40    }
41
42    public function setId(int $id): AdminLog
43    {
44        $this->id = $id;
45        return $this;
46    }
47
48    public function getTime(): int
49    {
50        return $this->time;
51    }
52
53    public function setTime(int $time): AdminLog
54    {
55        $this->time = $time;
56        return $this;
57    }
58
59    public function getUserId(): int
60    {
61        return $this->userId;
62    }
63
64    public function setUserId(int $userId): AdminLog
65    {
66        $this->userId = $userId;
67        return $this;
68    }
69
70    public function getText(): string
71    {
72        return $this->text;
73    }
74
75    public function setText(string $text): AdminLog
76    {
77        $this->text = $text;
78        return $this;
79    }
80
81    public function getIp(): string
82    {
83        return $this->ip;
84    }
85
86    public function setIp(string $ip): AdminLog
87    {
88        $this->ip = $ip;
89        return $this;
90    }
91
92    public function getHash(): ?string
93    {
94        return $this->hash;
95    }
96
97    public function setHash(?string $hash): AdminLog
98    {
99        $this->hash = $hash;
100        return $this;
101    }
102
103    public function getPreviousHash(): ?string
104    {
105        return $this->previousHash;
106    }
107
108    public function setPreviousHash(?string $previousHash): AdminLog
109    {
110        $this->previousHash = $previousHash;
111        return $this;
112    }
113
114    /**
115     * Calculates SHA-256 hash over all log data.
116     * Note: ID is not included because it's auto-generated after INSERT
117     * @return string 64-character hex hash
118     */
119    public function calculateHash(): string
120    {
121        $data = implode('|', [
122            (string) $this->time,
123            (string) $this->userId,
124            $this->ip,
125            $this->text,
126            $this->previousHash ?? '',
127        ]);
128
129        return hash('sha256', $data);
130    }
131
132    /**
133     * Verifies if the stored hash matches the calculated hash.
134     * @return bool True if the hash is valid, false if tampered
135     */
136    public function verifyIntegrity(): bool
137    {
138        $storedHash = $this->hash;
139        if ($storedHash === null) {
140            return false;
141        }
142
143        $calculatedHash = $this->calculateHash();
144
145        return hash_equals($storedHash, $calculatedHash);
146    }
147}