Completed
Push — master ( f2d7cc...c90f48 )
by Robert
04:06
created

ResponseModel::setReturnStackTrace()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 5
ccs 3
cts 3
cp 1
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
crap 1
1
<?php
2
3
namespace MediaMonks\RestApiBundle\Model;
4
5
use MediaMonks\RestApiBundle\Exception\AbstractValidationException;
6
use MediaMonks\RestApiBundle\Exception\ExceptionInterface;
7
use MediaMonks\RestApiBundle\Response\Error;
8
use MediaMonks\RestApiBundle\Response\PaginatedResponseInterface;
9
use MediaMonks\RestApiBundle\Util\StringUtil;
10
use Symfony\Component\HttpFoundation\RedirectResponse;
11
use Symfony\Component\HttpFoundation\Response;
12
use Symfony\Component\HttpKernel\Exception\HttpException;
13
14
class ResponseModel
15
{
16
    const EXCEPTION_GENERAL = 'Exception';
17
    const EXCEPTION_HTTP = 'HttpException';
18
19
    /**
20
     * @var int
21
     */
22
    protected $statusCode = Response::HTTP_OK;
23
24
    /**
25
     * @var bool
26
     */
27
    protected $returnStatusCode = false;
28
29
    /**
30
     * @var bool
31
     */
32
    protected $returnStackTrace = false;
33
34
    /**
35
     * @var mixed
36
     */
37
    protected $data;
38
39
    /**
40
     * @var Response
41
     */
42
    protected $response;
43
44
    /**
45
     * @var \Exception
46
     */
47
    protected $exception;
48
49
    /**
50
     * @var PaginatedResponseInterface
51
     */
52
    protected $pagination;
53
54
    /**
55
     * @return boolean
56
     */
57 14
    public function isReturnStackTrace()
58
    {
59 14
        return $this->returnStackTrace;
60
    }
61
62
    /**
63
     * @param boolean $returnStackTrace
64
     * @return $this
65
     */
66 21
    public function setReturnStackTrace($returnStackTrace)
67
    {
68 21
        $this->returnStackTrace = $returnStackTrace;
69 21
        return $this;
70
    }
71
72
    /**
73
     * @return int
74
     */
75 32
    public function getStatusCode()
76
    {
77 32
        if (isset($this->response)) {
78 6
            return $this->response->getStatusCode();
79
        }
80 26
        if (isset($this->exception)) {
81 13
            return $this->getExceptionStatusCode();
82
        }
83 13
        if ($this->isEmpty()) {
84 2
            return Response::HTTP_NO_CONTENT;
85
        }
86
87 11
        return $this->statusCode;
88
    }
89
90
    /**
91
     * @return int
92
     */
93 13
    protected function getExceptionStatusCode()
94
    {
95 13
        if ($this->exception instanceof HttpException) {
96 4
            return $this->exception->getStatusCode();
97
        }
98 9
        if ($this->exception instanceof AbstractValidationException) {
99 4
            return Response::HTTP_BAD_REQUEST;
100
        }
101 5
        if ($this->isValidHttpStatusCode($this->exception->getCode())) {
102 2
            return $this->exception->getCode();
103
        }
104
105 3
        return Response::HTTP_INTERNAL_SERVER_ERROR;
106
    }
107
108
    /**
109
     * @param int $code
110
     * @return bool
111
     */
112 5
    protected function isValidHttpStatusCode($code)
113
    {
114 5
        return array_key_exists($code, Response::$statusTexts) && $code >= Response::HTTP_BAD_REQUEST;
115
    }
116
117
    /**
118
     * @param int $statusCode
119
     * @return $this
120
     */
121 9
    public function setStatusCode($statusCode)
122
    {
123 9
        $this->statusCode = $statusCode;
124
125 9
        return $this;
126
    }
127
128
    /**
129
     * @return bool
130
     */
131 28
    public function getReturnStatusCode()
132
    {
133 28
        return $this->returnStatusCode;
134
    }
135
136
    /**
137
     * @param bool $returnStatusCode
138
     * @return $this
139
     */
140 2
    public function setReturnStatusCode($returnStatusCode)
141
    {
142 2
        $this->returnStatusCode = $returnStatusCode;
143
144 2
        return $this;
145
    }
146
147
    /**
148
     * @return mixed
149
     */
150 10
    public function getData()
151
    {
152 10
        return $this->data;
153
    }
154
155
    /**
156
     * @param mixed $data
157
     * @return $this
158
     */
159 24
    public function setData($data)
160
    {
161 24
        $this->data = $data;
162
163 24
        return $this;
164
    }
165
166
    /**
167
     * @return \Exception
168
     */
169 11
    public function getException()
170
    {
171 11
        return $this->exception;
172
    }
173
174
    /**
175
     * @param \Exception $exception
176
     * @return $this
177
     */
178 17
    public function setException(\Exception $exception)
179
    {
180 17
        $this->exception = $exception;
181
182 17
        return $this;
183
    }
184
185
    /**
186
     * @return array
187
     */
188 11
    public function getPagination()
189
    {
190 11
        return $this->pagination;
191
    }
192
193
    /**
194
     * @param PaginatedResponseInterface $pagination
195
     * @return $this
196
     */
197 4
    public function setPagination(PaginatedResponseInterface $pagination)
198
    {
199 4
        $this->pagination = $pagination;
200 4
        $this->setData($pagination->getData());
201
202 4
        return $this;
203
    }
204
205
    /**
206
     * @return Response
207
     */
208 11
    public function getResponse()
209
    {
210 11
        return $this->response;
211
    }
212
213
    /**
214
     * @param Response $response
215
     * @return ResponseModel
216
     */
217 7
    public function setResponse(Response $response)
218
    {
219 7
        $this->response = $response;
220 7
        $this->setStatusCode($response->getStatusCode());
221 7
        $this->setData($response->getContent());
222
223 7
        return $this;
224
    }
225
226
    /**
227
     * @return array
228
     */
229 27
    public function toArray()
230
    {
231 27
        $return = [];
232 27
        if ($this->getReturnStatusCode()) {
233 1
            $return['statusCode'] = $this->getStatusCode();
234 1
        }
235 27
        if (isset($this->exception)) {
236 14
            $return['error'] = $this->exceptionToArray();
237 27
        } elseif (isset($this->response) && $this->response instanceof RedirectResponse) {
238 2
            $return['location'] = $this->response->headers->get('Location');
239 2
        } else {
240 11
            $return += $this->dataToArray();
241
        }
242 27
        return $return;
243
    }
244
245
    /**
246
     * @return array
247
     */
248 11
    protected function dataToArray()
249
    {
250 11
        $return = [];
251 11
        if (isset($this->data)) {
252 10
            $return['data'] = $this->data;
253 10
            if (isset($this->pagination)) {
254 3
                $return['pagination'] = $this->pagination->toArray();
255 3
            }
256 10
        }
257 11
        return $return;
258
    }
259
260
    /**
261
     * @return array
262
     */
263 14
    protected function exceptionToArray()
264
    {
265 14
        if ($this->exception instanceof ExceptionInterface) {
266 4
            $error = $this->exception->toArray();
267 4
        }
268 10
        elseif ($this->exception instanceof HttpException) {
269 4
            $error = $this->httpExceptionToArray();
270 4
        }
271
        else {
272 6
            $error = $this->generalExceptionToArray();
273
        }
274 14
        if($this->isReturnStackTrace()) {
275 10
            $error['stack_trace'] = $this->getExceptionStackTrace();
276 10
        }
277 14
        return $error;
278
    }
279
280
    /**
281
     * @return string
282
     */
283 10
    protected function getExceptionStackTrace()
284
    {
285 10
        $traces = [];
286 10
        foreach($this->exception->getTrace() as $trace) {
287 10
            $trace['args'] = json_decode(json_encode($trace['args']), true);
288 10
            $traces[] = $trace;
289 10
        }
290 10
        return $traces;
291
    }
292
293
    /**
294
     * @return array
295
     */
296 4
    protected function httpExceptionToArray()
297
    {
298
        return [
299 4
            'code'    => $this->getExceptionErrorCode(Error::CODE_HTTP, self::EXCEPTION_HTTP),
300 4
            'message' => $this->exception->getMessage()
301 4
        ];
302
    }
303
304
    /**
305
     * @return array
306
     */
307 6
    protected function generalExceptionToArray()
308
    {
309
        return [
310 6
            'code'    => trim($this->getExceptionErrorCode(Error::CODE_GENERAL, self::EXCEPTION_GENERAL), '.'),
311 6
            'message' => $this->exception->getMessage()
312 6
        ];
313
    }
314
315
    /**
316
     * @param string $errorCode
317
     * @param string $trim
318
     * @return string
319
     */
320 10
    protected function getExceptionErrorCode($errorCode, $trim = null)
321
    {
322 10
        return sprintf($errorCode, StringUtil::classToSnakeCase($this->exception, $trim));
323
    }
324
325
    /**
326
     * @return bool
327
     */
328 19
    public function isEmpty()
329
    {
330
        return (
331 19
            !isset($this->exception)
332 19
            && is_null($this->data)
333 19
            && !isset($this->pagination)
334 19
            && $this->isEmptyResponse()
335 19
        );
336
    }
337
338
    /**
339
     * @return bool
340
     */
341 2
    protected function isEmptyResponse()
342
    {
343 2
        return !isset($this->response) || $this->response->isEmpty();
344
    }
345
346
    // @codeCoverageIgnoreStart
347
    /**
348
     * This is called when an exception is thrown during the response transformation
349
     *
350
     * @return string
351
     */
352
    public function __toString()
353
    {
354
        $data                  = $this->toArray();
355
        $data['error']['code'] = Error::CODE_REST_API_BUNDLE;
356
357
        return json_encode($data);
358
    }
359
    // @codeCoverageIgnoreEnd
360
}
361