Skip to content

Commit 5a78472

Browse files
authored
feat: add support php8.4 (#7)
1 parent 178092e commit 5a78472

File tree

10 files changed

+66
-41
lines changed

10 files changed

+66
-41
lines changed

.github/workflows/unit-tests.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ on:
88

99
jobs:
1010
unit-tests:
11-
name: Run Unit Tests
11+
name: PHP ${{ matrix.php }}
1212
runs-on: ubuntu-latest
1313

1414
strategy:
1515
fail-fast: true
1616
matrix:
17-
php: [8.2]
17+
php: [8.2, 8.3, 8.4]
1818
dependency-version: [prefer-stable]
1919

2020
steps:
@@ -27,7 +27,7 @@ jobs:
2727
uses: shivammathur/setup-php@v2
2828
with:
2929
php-version: ${{ matrix.php }}
30-
extensions: dom, mbstring, zip
30+
extensions: dom, mbstring, zip, sodium
3131
coverage: pcov
3232

3333
# Determine the Composer cache directory

composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@
5252
"laravel/pint": "^1.13.7",
5353
"orchestra/testbench": "^9.0",
5454
"pestphp/pest": "^2.28.1",
55-
"phpstan/phpstan": "1.10.56",
56-
"rector/rector": "0.19.5"
55+
"phpstan/phpstan": "^2.1",
56+
"rector/rector": "^2.0"
5757
},
5858
"scripts": {
5959
"refactor": "rector",

phpstan.neon.dist

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,3 @@ parameters:
44
- src
55

66
reportUnmatchedIgnoredErrors: true
7-
checkGenericClassInNonGenericObjectType: false

rector.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
use Rector\Config\RectorConfig;
66
use Rector\Php82\Rector\Class_\ReadOnlyClassRector;
7-
use Rector\Privatization\Rector\Class_\FinalizeClassesWithoutChildrenRector;
87
use Rector\Privatization\Rector\ClassMethod\PrivatizeFinalClassMethodRector;
98
use Rector\Privatization\Rector\MethodCall\PrivatizeLocalGetterToPropertyRector;
109
use Rector\Privatization\Rector\Property\PrivatizeFinalClassPropertyRector;
@@ -24,7 +23,6 @@
2423

2524
$rectorConfig->skip(
2625
[
27-
FinalizeClassesWithoutChildrenRector::class,
2826
PrivatizeLocalGetterToPropertyRector::class,
2927
ReadOnlyClassRector::class,
3028
]

src/Attributes/AbstractAttributes.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,22 @@
44

55
use Illuminate\Contracts\Support\Arrayable;
66

7+
/**
8+
* @template TKey of array-key
9+
* @template TValue
10+
*
11+
* @implements Arrayable<TKey, TValue>
12+
*/
713
abstract class AbstractAttributes implements Arrayable
814
{
9-
/** @return array<string, mixed> */
15+
/**
16+
* @return array<TKey, TValue>
17+
*/
1018
abstract protected function getAttributes(): array;
1119

20+
/**
21+
* @return array<TKey, TValue>
22+
*/
1223
public function toArray(): array
1324
{
1425
return $this->getAttributes();

src/Attributes/IdempotencyAttributes.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
use Illuminate\Http\Request;
99
use Illuminate\Http\Response;
1010

11+
/**
12+
* @extends AbstractAttributes<string, array<string, mixed>>
13+
*/
1114
class IdempotencyAttributes extends AbstractAttributes
1215
{
1316
private IdempotentRequest $request;

src/Config/IdempotencyConfig.php

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,15 @@
44

55
final class IdempotencyConfig
66
{
7-
// Idempotency config keys
8-
public const ENABLED_KEY = 'enabled';
9-
public const IDEMPOTENCY_HEADER_KEY = 'idempotency_header';
10-
public const RELAYED_HEADER_KEY = 'idempotency_relayed_header';
11-
public const ENFORCED_VERBS_KEY = 'enforced_verbs';
12-
public const DUPLICATE_HANDLING_KEY = 'duplicate_handling';
13-
public const MAX_LOCK_WAIT_TIME_KEY = 'max_lock_wait_time';
14-
public const USER_ID_RESOLVER_KEY = 'user_id_resolver';
15-
public const UNAUTHENTICATED_USER_ID_KEY = 'unauthenticated_user_id';
16-
17-
// Cache config keys
18-
public const CACHE_TTL_KEY = 'cache.ttl';
19-
public const CACHE_STORE_KEY = 'cache.store';
20-
217
// Default values
228
private const DEFAULT_MAX_LOCK_WAIT_TIME = 10; // 10 seconds
239
private const DEFAULT_CACHE_TTL = 86400; // 24 hours
2410
public const DEFAULT_CACHE_STORE = 'default';
11+
public const DEFAULT_IDEMPOTENCY_HEADER = 'Idempotency-Key';
12+
public const DEFAULT_RELAYED_HEADER = 'Idempotency-Relayed';
13+
public const DEFAULT_ENFORCED_VERBS = ['POST', 'PUT', 'PATCH', 'DELETE'];
14+
public const DEFAULT_DUPLICATE_HANDLING = 'exception';
15+
public const DEFAULT_UNAUTHENTICATED_USER_ID = 'guest';
2516

2617
/**
2718
* @param array<string> $enforcedVerbs
@@ -40,22 +31,32 @@ private function __construct(
4031
private readonly string $cacheStore
4132
) {}
4233

43-
// @phpstan-ignore-next-line
34+
/**
35+
* @param array{
36+
* enabled?: bool,
37+
* idempotency_header?: string,
38+
* idempotency_relayed_header?: string,
39+
* enforced_verbs?: string[],
40+
* duplicate_handling?: string,
41+
* max_lock_wait_time?: int,
42+
* user_id_resolver?: class-string|null,
43+
* unauthenticated_user_id?: string,
44+
* cache?: array{ttl?: int, store?: string}
45+
* } $attributes
46+
*/
4447
public static function createFromArray(array $attributes): self
4548
{
46-
$get = static fn (string $key, int|bool|string|array|null $default = null) => $attributes[$key] ?? $default;
47-
4849
return new self(
49-
$get(self::ENABLED_KEY, false),
50-
$get(self::IDEMPOTENCY_HEADER_KEY),
51-
$get(self::RELAYED_HEADER_KEY),
52-
$get(self::ENFORCED_VERBS_KEY),
53-
$get(self::DUPLICATE_HANDLING_KEY),
54-
$get(self::MAX_LOCK_WAIT_TIME_KEY, self::DEFAULT_MAX_LOCK_WAIT_TIME),
55-
$get(self::USER_ID_RESOLVER_KEY, null),
56-
$get(self::UNAUTHENTICATED_USER_ID_KEY),
57-
$get(self::CACHE_TTL_KEY, self::DEFAULT_CACHE_TTL),
58-
$get(self::CACHE_STORE_KEY, self::DEFAULT_CACHE_STORE)
50+
enabled: $attributes['enabled'] ?? false,
51+
idempotencyHeader: $attributes['idempotency_header'] ?? self::DEFAULT_IDEMPOTENCY_HEADER,
52+
relayedHeader: $attributes['idempotency_relayed_header'] ?? self::DEFAULT_RELAYED_HEADER,
53+
enforcedVerbs: $attributes['enforced_verbs'] ?? self::DEFAULT_ENFORCED_VERBS,
54+
duplicateHandling: $attributes['duplicate_handling'] ?? self::DEFAULT_DUPLICATE_HANDLING,
55+
maxLockWaitTime: $attributes['max_lock_wait_time'] ?? self::DEFAULT_MAX_LOCK_WAIT_TIME,
56+
userIdResolver: $attributes['user_id_resolver'] ?? null,
57+
unauthenticatedUserId: $attributes['unauthenticated_user_id'] ?? self::DEFAULT_UNAUTHENTICATED_USER_ID,
58+
cacheTtl: $attributes['cache']['ttl'] ?? self::DEFAULT_CACHE_TTL,
59+
cacheStore: $attributes['cache']['store'] ?? self::DEFAULT_CACHE_STORE,
5960
);
6061
}
6162

@@ -117,7 +118,7 @@ public function getUnauthenticatedUserId(): string
117118

118119
public function getCacheTtl(int $default = self::DEFAULT_CACHE_TTL): int
119120
{
120-
return $this->cacheTtl ?? $default;
121+
return $this->cacheTtl > 0 ? $this->cacheTtl : $default;
121122
}
122123

123124
public function getCacheStore(): string

src/Entities/IdempotentRequest.php

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
final class IdempotentRequest
99
{
1010
/**
11-
* @param array<string, list<string|null>> $body
11+
* @param array<string|int, list<string|null>|mixed> $body
1212
* @param array<string, list<string|null>> $headers
1313
*/
1414
public function __construct(
@@ -19,7 +19,12 @@ public function __construct(
1919
) {}
2020

2121
/**
22-
* @param array{body: array<string, list<string|null>>, headers: array<string, list<string|null>>, path: string, checksum: Checksum} $attributes
22+
* @param array{
23+
* body: array<string|int, list<string|null>|mixed>,
24+
* headers: array<string, list<string|null>>,
25+
* path: string,
26+
* checksum: Checksum
27+
* } $attributes
2328
*/
2429
public static function createFromArray(array $attributes): self
2530
{
@@ -45,7 +50,7 @@ public static function createFromRequest(Request $request): self
4550
}
4651

4752
/**
48-
* @return array<string, list<string|null>>
53+
* @return array<string|int, list<string|null>|mixed>
4954
*/
5055
public function getBody(): array
5156
{
@@ -76,7 +81,12 @@ public function getChecksum(): Checksum
7681
}
7782

7883
/**
79-
* @return array{body: array<string, list<string|null>>, headers: array<string, list<string|null>>, path: string, checksum: Checksum}
84+
* @return array{
85+
* body: array<string|int,
86+
* list<string|null>|mixed>,
87+
* headers: array<string, list<string|null>>,
88+
* path: string, checksum: Checksum
89+
* }
8090
*/
8191
public function toArray(): array
8292
{

src/Middleware/IdempotencyMiddleware.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,13 @@ public function __construct(
3232
public function handle(Request $request, Closure $next): Response|JsonResponse
3333
{
3434
if ($this->config->isNotEnabled() && $this->isEnforcedVerb($request) === false) {
35+
// @phpstan-ignore-next-line
3536
return $next($request);
3637
}
3738

3839
$idempotencyKey = $this->getIdempotencyKey($request);
3940
if (! $idempotencyKey) {
41+
// @phpstan-ignore-next-line
4042
return $next($request);
4143
}
4244

src/Providers/IdempotencyServiceProvider.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ function (Application $app): IdempotencyConfig {
7777
$configRepository = $app->make(ConfigRepository::class);
7878
$config = (array) $configRepository->get('idempotency', []);
7979

80+
// @phpstan-ignore-next-line
8081
return IdempotencyConfig::createFromArray($config);
8182
}
8283
);

0 commit comments

Comments
 (0)