Passed
Push — master ( 4a0c9c...b2edbe )
by Dominik
01:57
created

ResponseManager::createResponse()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 19
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 19
ccs 10
cts 10
cp 1
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 10
nc 3
nop 4
crap 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Chubbyphp\ApiHttp\Manager;
6
7
use Chubbyphp\ApiHttp\Error\Error;
8
use Chubbyphp\ApiHttp\Error\ErrorInterface;
9
use Chubbyphp\ApiHttp\Factory\ResponseFactoryInterface;
10
use Chubbyphp\Serialization\SerializerInterface;
11
use Chubbyphp\Serialization\TransformerInterface;
12
use Psr\Http\Message\ServerRequestInterface as Request;
13
use Psr\Http\Message\ResponseInterface as Response;
14
15
final class ResponseManager implements ResponseManagerInterface
16
{
17
    /**
18
     * @var RequestManagerInterface
19
     */
20
    private $requestManager;
21
22
    /**
23
     * @var ResponseFactoryInterface
24
     */
25
    private $responseFactory;
26
27
    /**
28
     * @var SerializerInterface
29
     */
30
    private $serializer;
31
32
    /**
33
     * @var TransformerInterface
34
     */
35
    private $transformer;
36
37
    /**
38
     * @param RequestManagerInterface  $requestManager
39
     * @param ResponseFactoryInterface $responseFactory
40
     * @param SerializerInterface      $serializer
41
     * @param TransformerInterface     $transformer
42
     */
43 10
    public function __construct(
44
        RequestManagerInterface $requestManager,
45
        ResponseFactoryInterface $responseFactory,
46
        SerializerInterface $serializer,
47
        TransformerInterface $transformer
48
    ) {
49 10
        $this->requestManager = $requestManager;
50 10
        $this->responseFactory = $responseFactory;
51 10
        $this->serializer = $serializer;
52 10
        $this->transformer = $transformer;
53 10
    }
54
55
    /**
56
     * @param Request     $request
57
     * @param int         $code
58
     * @param string      $accept
59
     * @param object|null $object
60
     *
61
     * @return Response
62
     */
63 3
    public function createResponse(Request $request, int $code, string $accept, $object = null): Response
64
    {
65 3
        $response = $this->responseFactory->createResponse($code);
66
67 3
        if (null === $object) {
68 2
            if (200 === $code) {
69 1
                return $response->withStatus(204);
70
            }
71
72 1
            return $response;
73
        }
74
75 1
        $body = $this->transformer->transform($this->serializer->serialize($request, $object), $accept);
76
77 1
        $response = $response->withStatus($code)->withHeader('Content-Type', $accept);
78 1
        $response->getBody()->write($body);
79
80 1
        return $response;
81
    }
82
83
    /**
84
     * @param Request        $request
85
     * @param int            $code
86
     * @param string         $accept
87
     * @param ErrorInterface $error
88
     *
89
     * @return Response
90
     */
91 6
    public function createResponseByError(Request $request, int $code, string $accept, ErrorInterface $error): Response
92
    {
93 6
        $response = $this->responseFactory->createResponse($code);
94
95 6
        $body = $this->transformer->transform($this->serializer->serialize($request, $error), $accept);
96
97 6
        $response = $response->withStatus($code)->withHeader('Content-Type', $accept);
98 6
        $response->getBody()->write($body);
99
100 6
        return $response;
101
    }
102
103
    /**
104
     * @param Request $request
105
     * @param string  $accept
106
     * @param string  $contentType
107
     *
108
     * @return Response
109
     */
110 1 View Code Duplication
    public function createBodyNotDeserializableResponse(Request $request, string $accept, string $contentType): Response
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
111
    {
112 1
        return $this->createResponseByError($request, 400, $accept, new Error(
113 1
            Error::SCOPE_BODY,
114 1
            'body_not_deserializable',
115 1
            'the given body is not deserializable with given content-type',
116 1
            'deserialize',
117
            [
118 1
                'contentType' => $contentType,
119 1
                'body' => (string) $request->getBody(),
120
            ]
121
        ));
122
    }
123
124
    /**
125
     * @param Request $request
126
     * @param string  $accept
127
     * @param string  $type
128
     * @param array   $arguments
129
     *
130
     * @return Response
131
     */
132 1 View Code Duplication
    public function createPermissionDeniedResponse(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
133
        Request $request,
134
        string $accept,
135
        string $type,
136
        array $arguments
137
    ): Response {
138 1
        return $this->createResponseByError($request, 403, $accept, new Error(
139 1
            Error::SCOPE_HEADER,
140 1
            'permission_denied',
141 1
            'the wished resource does not exist',
142 1
            $type,
143 1
            $arguments
144
        ));
145
    }
146
147
    /**
148
     * @param Request $request
149
     * @param string  $accept
150
     * @param string  $type
151
     * @param array   $arguments
152
     *
153
     * @return Response
154
     */
155 1 View Code Duplication
    public function createResourceNotFoundResponse(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
156
        Request $request,
157
        string $accept,
158
        string $type,
159
        array $arguments
160
    ): Response {
161 1
        return $this->createResponseByError($request, 404, $accept, new Error(
162 1
            Error::SCOPE_RESOURCE,
163 1
            'resource_not_found',
164 1
            'the wished resource does not exist',
165 1
            $type, $arguments
166
        ));
167
    }
168
169
    /**
170
     * @param Request $request
171
     *
172
     * @return Response
173
     */
174 1
    public function createAcceptNotSupportedResponse(Request $request): Response
175
    {
176 1
        $response = $this->responseFactory->createResponse(406);
177 1
        $response = $response->withHeader('X-Not-Acceptable', sprintf(
178 1
            'Accept "%s" is not supported, supported are %s',
179 1
            $request->getHeaderLine('Accept'),
180 1
            implode(', ', $this->requestManager->getSupportedAccepts())
181
        ));
182
183 1
        return $response;
184
    }
185
186
    /**
187
     * @param Request $request
188
     * @param string  $accept
189
     *
190
     * @return Response
191
     */
192 1 View Code Duplication
    public function createContentTypeNotSupportedResponse(Request $request, string $accept): Response
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
193
    {
194 1
        return $this->createResponseByError($request, 415, $accept, new Error(
195 1
            Error::SCOPE_HEADER,
196 1
            'contentype_not_supported',
197 1
            'the given content type is not supported',
198 1
            'content-type',
199
            [
200 1
                'contentType' => $request->getHeaderLine('Content-Type'),
201 1
                'supportedContentTypes' => $this->requestManager->getSupportedContentTypes(),
202
            ]
203
        ));
204
    }
205
206
    /**
207
     * @param Request $request
208
     * @param string  $accept
209
     * @param string  $scope
210
     * @param string  $type
211
     * @param array   $errors
212
     *
213
     * @return Response
214
     */
215 1
    public function createValidationErrorResponse(
216
        Request $request,
217
        string $accept,
218
        string $scope,
219
        string $type,
220
        array $errors
221
    ): Response {
222 1
        return $this->createResponseByError($request, 422, $accept, new Error(
223 1
            $scope,
224 1
            'validation_error',
225 1
            'there where validation errors while validating the object',
226 1
            $type,
227 1
            $errors
228
        ));
229
    }
230
}
231