PayloadDecodingMiddleware::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 0
nc 1
nop 2
dl 0
loc 4
ccs 1
cts 1
cp 1
crap 1
rs 10
c 1
b 0
f 0
1
<?php
2
3
/**
4
 * It's free open-source software released under the MIT License.
5
 *
6
 * @author Anatoly Nekhay <[email protected]>
7
 * @copyright Copyright (c) 2018, Anatoly Nekhay
8
 * @license https://github.com/sunrise-php/http-router/blob/master/LICENSE
9
 * @link https://github.com/sunrise-php/http-router
10
 */
11
12
declare(strict_types=1);
13
14
namespace Sunrise\Http\Router\Middleware;
15
16
use Psr\Http\Message\ResponseInterface;
17
use Psr\Http\Message\ServerRequestInterface;
18
use Psr\Http\Server\MiddlewareInterface;
19
use Psr\Http\Server\RequestHandlerInterface;
20
use Sunrise\Coder\CodecManagerInterface;
21
use Sunrise\Coder\Exception\CodecException;
22
use Sunrise\Http\Router\Dictionary\HeaderName;
23
use Sunrise\Http\Router\Exception\HttpExceptionFactory;
24
use Sunrise\Http\Router\ServerRequest;
25
use Sunrise\Http\Router\StringableMediaType;
26
27
use function array_map;
28
29
/**
30
 * @since 3.0.0
31
 */
32
final class PayloadDecodingMiddleware implements MiddlewareInterface
33
{
34
    /**
35
     * @param array<array-key, mixed> $codecContext
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<array-key, mixed> at position 2 could not be parsed: Unknown type name 'array-key' at position 2 in array<array-key, mixed>.
Loading history...
36
     */
37 9
    public function __construct(
38
        private readonly CodecManagerInterface $codecManager,
39
        private readonly array $codecContext = [],
40
    ) {
41 9
    }
42
43
    /**
44
     * @inheritDoc
45
     */
46 9
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
47
    {
48 9
        $serverRequest = ServerRequest::create($request);
49
50 9
        $serverConsumedMediaTypes = $serverRequest->getRoute()->getConsumedMediaTypes();
51 9
        if ($serverConsumedMediaTypes === []) {
52
            // The server expects nothing from the client, just keep going...
53 1
            return $handler->handle($request);
54
        }
55
56 8
        $clientProducedMediaType = $serverRequest->getClientProducedMediaType();
57 8
        if ($clientProducedMediaType === null) {
58 1
            throw HttpExceptionFactory::missingMediaType();
59
        }
60
61 7
        if (!$serverRequest->serverConsumesMediaType($clientProducedMediaType)) {
62 1
            throw HttpExceptionFactory::unsupportedMediaType()
63 1
                ->addHeaderField(HeaderName::ACCEPT, ...array_map(
64 1
                    StringableMediaType::create(...),
65 1
                    $serverConsumedMediaTypes,
66 1
                ));
67
        }
68
69 6
        if (!$this->codecManager->supportsMediaType($clientProducedMediaType)) {
70 1
            return $handler->handle($request);
71
        }
72
73
        try {
74
            /** @var array<array-key, mixed>|object|null $parsedBody */
75 5
            $parsedBody = $this->codecManager->decode(
76 5
                $clientProducedMediaType,
77 5
                (string) $request->getBody(),
78 5
                $this->codecContext,
79 5
            );
80 1
        } catch (CodecException $e) {
81 1
            throw HttpExceptionFactory::invalidBody(previous: $e);
82
        }
83
84 4
        return $handler->handle($request->withParsedBody($parsedBody));
85
    }
86
}
87