EncodableResponseResolver::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
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
c 1
b 0
f 0
nc 1
nop 4
dl 0
loc 7
ccs 1
cts 1
cp 1
crap 1
rs 10
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\ResponseResolver;
15
16
use Fig\Http\Message\StatusCodeInterface;
17
use Psr\Http\Message\ResponseFactoryInterface;
18
use Psr\Http\Message\ResponseInterface;
19
use Psr\Http\Message\ServerRequestInterface;
20
use ReflectionAttribute;
21
use ReflectionMethod;
22
use RuntimeException;
23
use Sunrise\Coder\CodecManagerInterface;
24
use Sunrise\Coder\Exception\CodecException;
25
use Sunrise\Coder\MediaTypeInterface;
26
use Sunrise\Http\Router\Annotation\EncodableResponse;
27
use Sunrise\Http\Router\Dictionary\HeaderName;
28
use Sunrise\Http\Router\ResponseResolverChain;
29
use Sunrise\Http\Router\ResponseResolverInterface;
30
use Sunrise\Http\Router\ServerRequest;
31
32
use function sprintf;
33
34
/**
35
 * @since 3.0.0
36
 */
37
final class EncodableResponseResolver implements ResponseResolverInterface
38
{
39 9
    public function __construct(
40
        private readonly ResponseFactoryInterface $responseFactory,
41
        private readonly CodecManagerInterface $codecManager,
42
        private readonly MediaTypeInterface $defaultMediaType,
43
        /** @var array<array-key, mixed> */
44
        private readonly array $codecContext = [],
45
    ) {
46 9
    }
47
48
    /**
49
     * @inheritDoc
50
     *
51
     * @throws RuntimeException
52
     */
53 8
    public function resolveResponse(
54
        mixed $response,
55
        ReflectionMethod $responder,
56
        ServerRequestInterface $request,
57
    ): ?ResponseInterface {
58
        /** @var list<ReflectionAttribute<EncodableResponse>> $annotations */
59 8
        $annotations = $responder->getAttributes(EncodableResponse::class);
60 8
        if ($annotations === []) {
0 ignored issues
show
introduced by
The condition $annotations === array() is always false.
Loading history...
61 1
            return null;
62
        }
63
64 7
        $serverRequest = ServerRequest::create($request);
65 7
        $serverProducedMediaTypes = $serverRequest->getRoute()->getProducedMediaTypes();
66 7
        $clientPreferredMediaType = $serverRequest->getClientPreferredMediaType(...$serverProducedMediaTypes);
67
68 7
        $processParams = $annotations[0]->newInstance();
69 7
        $codecMediaType = $clientPreferredMediaType ?? $processParams->defaultMediaType ?? $this->defaultMediaType;
70 7
        $codecContext = $processParams->codecContext + $this->codecContext;
71
72
        try {
73 7
            $encodedResponse = $this->codecManager->encode($codecMediaType, $response, $codecContext);
74 1
        } catch (CodecException $e) {
75 1
            throw new RuntimeException(sprintf(
76 1
                'The responder "%s" returned a response that could not be encoded due to: %s',
77 1
                ResponseResolverChain::stringifyResponder($responder),
78 1
                $e->getMessage(),
79 1
            ), previous: $e);
80
        }
81
82 6
        $responseContentType = $codecMediaType->getIdentifier();
83 6
        $responseContentType .= '; charset=UTF-8'; // It should be a text data type...
84
85 6
        $resolvedResponse = $this->responseFactory
86 6
            ->createResponse(StatusCodeInterface::STATUS_OK)
87 6
            ->withHeader(HeaderName::CONTENT_TYPE, $responseContentType);
88
89 6
        $resolvedResponse->getBody()->write($encodedResponse);
90
91 6
        return $resolvedResponse;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $resolvedResponse returns the type Psr\Http\Message\MessageInterface which includes types incompatible with the type-hinted return Psr\Http\Message\ResponseInterface|null.
Loading history...
92
    }
93
94 1
    public function getWeight(): int
95
    {
96 1
        return 10;
97
    }
98
}
99