Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
92.86% covered (success)
92.86%
13 / 14
75.00% covered (warning)
75.00%
3 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
ReadsJsonPayload
92.86% covered (success)
92.86%
13 / 14
75.00% covered (warning)
75.00%
3 / 4
8.02
0.00% covered (danger)
0.00%
0 / 1
 decodeJsonBody
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 stringField
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 boolField
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
2.06
 intField
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3declare(strict_types=1);
4
5namespace App\Shared\Infrastructure\Http;
6
7use InvalidArgumentException;
8use Symfony\Component\HttpFoundation\Request;
9
10/**
11 * Small helpers for controllers that accept a JSON request body. Field readers
12 * are forgiving on type (missing/non-scalar string fields collapse to '') and
13 * push validation down to the domain; an unparseable body or a non-integer
14 * where an int is required throws InvalidArgumentException, which controllers
15 * already map to 400.
16 */
17trait ReadsJsonPayload
18{
19    /**
20     * @return array<array-key, mixed>
21     */
22    private function decodeJsonBody(Request $request): array
23    {
24        $payload = json_decode($request->getContent(), true);
25
26        if (!is_array($payload)) {
27            throw new InvalidArgumentException('Invalid JSON body.');
28        }
29
30        return $payload;
31    }
32
33    /**
34     * @param array<array-key, mixed> $payload
35     */
36    private function stringField(array $payload, string $key): string
37    {
38        $value = $payload[$key] ?? '';
39
40        return is_scalar($value) ? (string) $value : '';
41    }
42
43    /**
44     * @param array<array-key, mixed> $payload
45     */
46    private function boolField(array $payload, string $key): bool
47    {
48        $value = $payload[$key] ?? null;
49
50        if (!is_bool($value)) {
51            throw new InvalidArgumentException(sprintf('Field <%s> must be a boolean.', $key));
52        }
53
54        return $value;
55    }
56
57    /**
58     * @param array<array-key, mixed> $payload
59     */
60    private function intField(array $payload, string $key): int
61    {
62        $value = $payload[$key] ?? null;
63
64        if (!is_int($value)) {
65            throw new InvalidArgumentException(sprintf('Field <%s> must be an integer (amount in minor units).', $key));
66        }
67
68        return $value;
69    }
70}