Skip to content

Commit 2fc8af9

Browse files
committed
up
1 parent c91f51f commit 2fc8af9

6 files changed

Lines changed: 77 additions & 13 deletions

File tree

src/Auth/Authenticator.php

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class Authenticator
2424
/**
2525
* Authentication configuration
2626
*
27-
* @var array
27+
* @var array<string,mixed>
2828
*/
2929
public array $config;
3030

@@ -38,7 +38,7 @@ class Authenticator
3838
/**
3939
* Currently authenticated user data
4040
*
41-
* @var array|null
41+
* @var array{ id?: int|string, username?: string, email?: string, role?: string }|null
4242
*/
4343
private ?array $currentUser = null;
4444

@@ -144,6 +144,11 @@ public function requireAuth(): void
144144
/**
145145
* Create a JWT token with custom payload
146146
*/
147+
/**
148+
* Create a JWT token with custom payload
149+
*
150+
* @param array<string,mixed> $payload
151+
*/
147152
public function createJwt(array $payload, int $expireSeconds = 3600): string
148153
{
149154
$now = time();
@@ -173,18 +178,21 @@ public function validateJwt(string $jwt): bool
173178

174179
/**
175180
* Get HTTP request headers
181+
*
182+
* @return array<string,string>
176183
*/
177184
private function getHeaders(): array
178185
{
179186
if (function_exists('getallheaders')) {
180-
return getallheaders();
187+
$all = getallheaders();
188+
return is_array($all) ? $all : [];
181189
}
182190
// Fallback
183191
$headers = [];
184192
foreach ($_SERVER as $name => $value) {
185193
if (str_starts_with($name, 'HTTP_')) {
186194
$header = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))));
187-
$headers[$header] = $value;
195+
$headers[$header] = (string)$value;
188196
}
189197
}
190198
return $headers;

src/Cache/CacheManager.php

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,14 @@ class CacheManager
3636
/**
3737
* Cache configuration
3838
*
39-
* @var array
39+
* @var array<string,mixed>
4040
*/
4141
private array $config;
4242

4343
/**
4444
* Cache statistics for current request
4545
*
46-
* @var array
46+
* @var array{hits:int,misses:int,writes:int,invalidations:int}
4747
*/
4848
private array $stats = [
4949
'hits' => 0,
@@ -58,7 +58,7 @@ class CacheManager
5858
* Creates appropriate cache driver based on configuration.
5959
* Falls back to file cache if configured driver is unavailable.
6060
*
61-
* @param array $config Cache configuration from config/cache.php
61+
* @param array<string,mixed> $config Cache configuration from config/cache.php
6262
*
6363
* @example
6464
* $cache = new CacheManager([
@@ -180,6 +180,9 @@ public function shouldCache(string $table): bool
180180
* ]);
181181
* // Returns: "api:table:users:params:a3f5c8d9e2..."
182182
*/
183+
/**
184+
* @param array<string,mixed> $params
185+
*/
183186
public function generateKey(string $table, array $params): string
184187
{
185188
// Sort params for consistent keys
@@ -189,7 +192,7 @@ public function generateKey(string $table, array $params): string
189192
$baseKey = sprintf(
190193
'api:table:%s:params:%s',
191194
$table,
192-
md5(json_encode($params))
195+
md5((string) json_encode($params))
193196
);
194197

195198
// Add user variation if configured
@@ -396,6 +399,9 @@ public function has(string $key): bool
396399
* // ...
397400
* // ]
398401
*/
402+
/**
403+
* @return array<string,mixed>
404+
*/
399405
public function getStats(): array
400406
{
401407
$driverStats = $this->driver->getStats();
@@ -434,7 +440,7 @@ private function getHitRatio(): float
434440
private function getApiKeyFromRequest(): ?string
435441
{
436442
// Check header
437-
$headers = function_exists('getallheaders') ? getallheaders() : [];
443+
$headers = function_exists('getallheaders') ? (getallheaders() ?: []) : [];
438444
$apiKey = $headers['X-API-Key'] ?? $headers['X-Api-Key'] ?? null;
439445

440446
// Check query parameter

src/Config/ApiConfig.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,33 @@
3131
*/
3232
class ApiConfig
3333
{
34+
/** @var bool */
3435
private bool $authEnabled;
36+
/** @var string */
3537
private string $authMethod;
38+
/** @var list<string> */
3639
private array $apiKeys;
40+
/** @var string */
3741
private string $apiKeyRole;
42+
/** @var array<string,string> */
3843
private array $basicUsers;
44+
/** @var bool */
3945
private bool $useDatabaseAuth;
46+
/** @var string */
4047
private string $jwtSecret;
48+
/** @var int */
4149
private int $jwtExpiration;
50+
/** @var string */
4251
private string $jwtAlgorithm;
52+
/** @var array<string,array{tables:list<string>,actions:list<string>}> */
4353
private array $roles;
54+
/** @var array<string,string> */
4455
private array $userRoles;
56+
/** @var array{enabled:bool,requests_per_minute:int,requests_per_hour:int,requests_per_day:int} */
4557
private array $rateLimitConfig;
58+
/** @var array{enabled:bool,log_requests:bool,log_responses:bool,log_errors:bool} */
4659
private array $loggingConfig;
60+
/** @var array{enabled:bool} */
4761
private array $monitoringConfig;
4862

4963
/**
@@ -169,6 +183,9 @@ public function getAuthMethod(): string
169183
/**
170184
* Get valid API keys
171185
*/
186+
/**
187+
* @return list<string>
188+
*/
172189
public function getApiKeys(): array
173190
{
174191
return $this->apiKeys;
@@ -185,6 +202,9 @@ public function getApiKeyRole(): string
185202
/**
186203
* Get basic auth users
187204
*/
205+
/**
206+
* @return array<string,string>
207+
*/
188208
public function getBasicUsers(): array
189209
{
190210
return $this->basicUsers;
@@ -225,6 +245,9 @@ public function getJwtAlgorithm(): string
225245
/**
226246
* Get all roles configuration
227247
*/
248+
/**
249+
* @return array<string,array{tables:list<string>,actions:list<string>}>
250+
*/
228251
public function getRoles(): array
229252
{
230253
return $this->roles;
@@ -233,6 +256,9 @@ public function getRoles(): array
233256
/**
234257
* Get user role mappings
235258
*/
259+
/**
260+
* @return array<string,string>
261+
*/
236262
public function getUserRoles(): array
237263
{
238264
return $this->userRoles;
@@ -249,6 +275,9 @@ public function getUserRole(string $username): ?string
249275
/**
250276
* Get rate limit configuration
251277
*/
278+
/**
279+
* @return array{enabled:bool,requests_per_minute:int,requests_per_hour:int,requests_per_day:int}
280+
*/
252281
public function getRateLimitConfig(): array
253282
{
254283
return $this->rateLimitConfig;
@@ -257,6 +286,9 @@ public function getRateLimitConfig(): array
257286
/**
258287
* Get logging configuration
259288
*/
289+
/**
290+
* @return array{enabled:bool,log_requests:bool,log_responses:bool,log_errors:bool}
291+
*/
260292
public function getLoggingConfig(): array
261293
{
262294
return $this->loggingConfig;
@@ -265,6 +297,9 @@ public function getLoggingConfig(): array
265297
/**
266298
* Get monitoring configuration
267299
*/
300+
/**
301+
* @return array{enabled:bool}
302+
*/
268303
public function getMonitoringConfig(): array
269304
{
270305
return $this->monitoringConfig;
@@ -281,6 +316,9 @@ public function isMonitoringEnabled(): bool
281316
/**
282317
* Convert to array (for backward compatibility)
283318
*/
319+
/**
320+
* @return array<string,mixed>
321+
*/
284322
public function toArray(): array
285323
{
286324
return [

src/Database/Dialect/DialectInterface.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,18 @@ interface DialectInterface
1414
/** Quote an identifier (table/column) safely for the dialect. */
1515
public function quoteIdent(string $ident): string;
1616

17-
/** Return list of tables in the current database/schema. */
17+
/**
18+
* Return list of tables in the current database/schema.
19+
*
20+
* @return array<int,string>
21+
*/
1822
public function listTables(PDO $pdo): array;
1923

20-
/** Return list of columns (associative arrays) for a given table. */
24+
/**
25+
* Return list of columns (associative arrays) for a given table.
26+
*
27+
* @return array<int,array<string,mixed>>
28+
*/
2129
public function listColumns(PDO $pdo, string $table): array;
2230

2331
/** Return the primary key column name for a given table, or null if not found. */

src/Http/ErrorResponder.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ public function __construct(
2323
* Handle an exception: log, record metrics, and send JSON error response.
2424
* Returns the payload and status for callers that also need to log response.
2525
*
26-
* @return array{0: array, 1: int}
26+
* @param array<string,mixed> $context
27+
* @return array{0: array{error: string}, 1: int}
2728
*/
2829
public function fromException(Throwable $e, array $context = [], int $status = 500): array
2930
{

src/Http/Middleware/RateLimitMiddleware.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ public function __construct(
2727
* Perform rate limit check and respond if exceeded.
2828
* Returns false if request should terminate (429 already sent),
2929
* otherwise true and ensures headers are emitted.
30+
*
31+
* @param string $identifier
32+
* @return bool
3033
*/
3134
public function checkAndRespond(string $identifier): bool
3235
{
@@ -53,7 +56,7 @@ public function checkAndRespond(string $identifier): bool
5356

5457
// Add rate limit headers for allowed requests
5558
foreach ($this->rateLimiter->getHeaders($identifier) as $name => $value) {
56-
header($name . ': ' . $value);
59+
header((string)$name . ': ' . (string)$value);
5760
}
5861
return true;
5962
}

0 commit comments

Comments
 (0)