Skip to content

Commit e4fdbda

Browse files
mowens3claude
andcommitted
Fix PHPStan level 9 type errors
- Add proper type checks for mixed PDO fetch results - Use is_string/is_int/is_numeric guards before casting - Add is_array checks before array operations - Properly extract and validate row data from PDO results Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent b96c2e9 commit e4fdbda

File tree

2 files changed

+35
-11
lines changed

2 files changed

+35
-11
lines changed

src/ApiKey/ApiKeyManager.php

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,12 @@ public function validate(string $apiKey): ?ApiKey
104104
}
105105

106106
$record = $this->storage->get($keyId);
107-
if (!is_array($record) || empty($record['hash'])) {
107+
if (!is_array($record)) {
108+
return null;
109+
}
110+
111+
$hash = $record['hash'] ?? null;
112+
if (!is_string($hash) || $hash === '') {
108113
return null;
109114
}
110115

@@ -114,7 +119,7 @@ public function validate(string $apiKey): ?ApiKey
114119
return null;
115120
}
116121

117-
$expected = (string) $record['hash'];
122+
$expected = $hash;
118123
$actual = $this->hashSecret($secret);
119124

120125
if (!hash_equals($expected, $actual)) {
@@ -133,13 +138,19 @@ public function validate(string $apiKey): ?ApiKey
133138
*/
134139
private function recordToApiKey(string $keyId, array $record): ApiKey
135140
{
141+
$label = $record['label'] ?? '';
142+
$scopes = $record['scopes'] ?? [];
143+
$created = $record['created'] ?? 0;
144+
$lastUsed = $record['last_used'] ?? null;
145+
$expires = $record['expires'] ?? null;
146+
136147
return new ApiKey(
137148
keyId: $keyId,
138-
label: (string) ($record['label'] ?? ''),
139-
scopes: array_values(array_filter($record['scopes'] ?? [])),
140-
created: (int) ($record['created'] ?? 0),
141-
lastUsed: isset($record['last_used']) ? (int) $record['last_used'] : null,
142-
expires: isset($record['expires']) ? (int) $record['expires'] : null,
149+
label: is_string($label) ? $label : '',
150+
scopes: is_array($scopes) ? array_values(array_filter($scopes, 'is_string')) : [],
151+
created: is_int($created) ? $created : (is_numeric($created) ? (int) $created : 0),
152+
lastUsed: is_int($lastUsed) ? $lastUsed : (is_numeric($lastUsed) ? (int) $lastUsed : null),
153+
expires: is_int($expires) ? $expires : (is_numeric($expires) ? (int) $expires : null),
143154
);
144155
}
145156

src/ApiKey/Storage/PdoStorage.php

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,17 @@ public function getAll(): array
3232

3333
$keys = [];
3434
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
35-
$data = json_decode($row['data'], true);
35+
if (!is_array($row)) {
36+
continue;
37+
}
38+
$keyId = $row['key_id'] ?? null;
39+
$rawData = $row['data'] ?? null;
40+
if (!is_string($keyId) || !is_string($rawData)) {
41+
continue;
42+
}
43+
$data = json_decode($rawData, true);
3644
if (is_array($data)) {
37-
$keys[$row['key_id']] = $data;
45+
$keys[$keyId] = $data;
3846
}
3947
}
4048

@@ -73,11 +81,16 @@ public function get(string $keyId): ?array
7381
$stmt->execute(['key_id' => $keyId]);
7482

7583
$row = $stmt->fetch(PDO::FETCH_ASSOC);
76-
if (!$row) {
84+
if (!is_array($row)) {
85+
return null;
86+
}
87+
88+
$rawData = $row['data'] ?? null;
89+
if (!is_string($rawData)) {
7790
return null;
7891
}
7992

80-
$data = json_decode($row['data'], true);
93+
$data = json_decode($rawData, true);
8194
return is_array($data) ? $data : null;
8295
}
8396

0 commit comments

Comments
 (0)