RestException   A
last analyzed

Complexity

Total Complexity 29

Size/Duplication

Total Lines 316
Duplicated Lines 0 %

Test Coverage

Coverage 96.47%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 68
c 1
b 0
f 0
dl 0
loc 316
ccs 82
cts 85
cp 0.9647
rs 10
wmc 29

22 Methods

Rating   Name   Duplication   Size   Complexity  
A errorValidation() 0 3 1
A unknownAttribute() 0 4 1
A unknownRelation() 0 4 1
A createUnprocessable() 0 3 1
A missingData() 0 4 1
A createForbidden() 0 3 1
A invalidInclude() 0 4 1
A missingAdder() 0 13 2
A createFromConstraintViolationList() 0 10 2
A notJsonApiResource() 0 11 2
A missingDataMembers() 0 5 1
A missingSetter() 0 13 2
A missingGetter() 0 13 2
A missingRemover() 0 13 2
A errors() 0 3 1
A create() 0 6 1
A __construct() 0 6 1
A createNotFound() 0 4 1
A createFromException() 0 6 2
A createFilterError() 0 4 1
A error() 0 5 1
A missingRootData() 0 4 1
1
<?php namespace Pz\Doctrine\Rest\Exceptions;
2
3
use Doctrine\Common\Util\ClassUtils;
4
use Pz\Doctrine\Rest\Contracts\JsonApiResource;
5
use Symfony\Component\HttpFoundation\Response;
6
use Symfony\Component\Validator\ConstraintViolation;
7
use Symfony\Component\Validator\ConstraintViolationInterface;
8
use Symfony\Component\Validator\ConstraintViolationListInterface;
9
10
class RestException extends \Exception
11
{
12
    /**
13
     * @var array
14
     */
15
    protected $errors = [];
16
17
    /**
18
     * @param \Exception $exception
19
     * @param bool       $debug
20
     *
21
     * @return $this
22
     */
23 1
    public static function createFromException(\Exception $exception, $debug = false)
24
    {
25 1
        $extra = $debug ? ['trace' => $exception->getTrace()] : [];
26
27 1
        return static::create(Response::HTTP_INTERNAL_SERVER_ERROR, 'Internal Server Error', $exception)
28 1
            ->error('internal-error', [], $exception->getMessage(), $extra);
29
    }
30
31
    /**
32
     * @param ConstraintViolationListInterface $errors
33
     *
34
     * @return RestException
35
     */
36 1
    public static function createFromConstraintViolationList(ConstraintViolationListInterface $errors)
37
    {
38 1
        $exception = static::createUnprocessable('Input validation errors.');
39
40
        /** @var ConstraintViolationInterface $error */
41 1
        foreach ($errors as $error) {
42 1
            $exception->errorValidation($error->getPropertyPath(), $error->getMessage());
43
        }
44
45 1
        return $exception;
46
    }
47
48
    /**
49
     * @param string $message
50
     *
51
     * @return RestException
52
     */
53 1
    public static function createForbidden($message = 'Forbidden.')
54
    {
55 1
        return static::create(Response::HTTP_FORBIDDEN, $message);
56
    }
57
58
    /**
59
     * @param string $message
60
     *
61
     * @return RestException
62
     */
63 7
    public static function createUnprocessable($message = '')
64
    {
65 7
        return static::create(Response::HTTP_UNPROCESSABLE_ENTITY, $message);
66
    }
67
68
    /**
69
     * @param int|array $id
70
     * @param string    $resourceKey
71
     * @param string    $message
72
     *
73
     * @return $this
74
     */
75 3
    public static function createNotFound($id, $resourceKey, $message = '')
76
    {
77 3
        return static::create(Response::HTTP_NOT_FOUND, 'Entity not found.')
78 3
            ->error('entity-not-found', ['type' => $resourceKey, 'id' => $id], $message);
79
    }
80
81
    /**
82
     * @param array $source
83
     * @param       $message
84
     *
85
     * @return $this
86
     */
87 1
    public static function createFilterError(array $source, $message)
88
    {
89 1
        return static::create(Response::HTTP_BAD_REQUEST, 'Wrong filter input.')
90 1
            ->error('filter-input', $source, $message);
91
    }
92
93
    /**
94
     * @return static
95
     */
96 1
    public static function missingRootData()
97
    {
98 1
        return static::create(Response::HTTP_UNPROCESSABLE_ENTITY)
99 1
            ->error('missing-root-data', ['pointer' => ''], "Missing `data` member at document top level.");
100
    }
101
102
    /**
103
     * @param string $pointer
104
     *
105
     * @return $this
106
     */
107 1
    public static function missingData($pointer)
108
    {
109 1
        return static::create(Response::HTTP_UNPROCESSABLE_ENTITY)
110 1
            ->error('missing-data', ['pointer' => $pointer], "Missing `data` member at pointer level.");
111
    }
112
113
    /**
114
     * @param string $pointer
115
     *
116
     * @return $this
117
     */
118 1
    public static function missingDataMembers($pointer)
119
    {
120 1
        return static::create(Response::HTTP_UNPROCESSABLE_ENTITY)
121 1
            ->error('missing-data-members', ['pointer' => $pointer],
122 1
                'Missing or not array `data.attributes` or `data.relationships` at pointer level.'
123
            );
124
    }
125
126
    /**
127
     * @param string $pointer
128
     *
129
     * @return $this
130
     */
131 1
    public static function unknownAttribute($pointer)
132
    {
133 1
        return static::create(Response::HTTP_UNPROCESSABLE_ENTITY)
134 1
            ->error('unknown-attribute', ['pointer' => $pointer], 'Unknown attribute.');
135
    }
136
137
    /**
138
     * @param string $pointer
139
     *
140
     * @return static
141
     */
142 1
    public static function unknownRelation($pointer)
143
    {
144 1
        return static::create(Response::HTTP_UNPROCESSABLE_ENTITY)
145 1
            ->error('unknown-relation', ['pointer' => $pointer], 'Unknown relation.');
146
    }
147
148
    /**
149
     * @return static
150
     */
151
    public static function invalidInclude()
152
    {
153
        return static::create(Response::HTTP_UNPROCESSABLE_ENTITY)
154
            ->error('invalid-include', ['pointer' => 'include'], 'Invalid `include` param.');
155
    }
156
157
    /**
158
     * @param mixed $entity
159
     *
160
     * @return $this
161
     */
162 1
    public static function notJsonApiResource($entity)
163
    {
164 1
        $source = [];
165 1
        $message = 'Got not JsonApiResource entity.';
166
167 1
        if (is_object($entity)) {
168 1
            $source['class'] = get_class($entity);
169
        }
170
171 1
        return static::create(Response::HTTP_UNPROCESSABLE_ENTITY, $message)
172 1
            ->error('invalid-entity', $source, $message);
173
    }
174
175
    /**
176
     * @param object $entity
177
     * @param string $field
178
     * @param string $getter
179
     *
180
     * @return static
181
     */
182 1
    public static function missingGetter($entity, $field, $getter)
183
    {
184
        $source = [
185 1
            'entity' => ClassUtils::getClass($entity),
186 1
            'getter' => $getter
187
        ];
188
189 1
        if ($entity instanceof JsonApiResource) {
190 1
            $source['pointer'] = $entity->getResourceKey().'.'.$field;
191
        }
192
193 1
        return static::createUnprocessable()
194 1
            ->error('missing-getter', $source, 'Missing field getter.');
195
    }
196
197
    /**
198
     * @param object $entity
199
     * @param string $field
200
     * @param string $setter
201
     *
202
     * @return static
203
     */
204 2
    public static function missingSetter($entity, $field, $setter)
205
    {
206
        $source = [
207 2
            'entity' => ClassUtils::getClass($entity),
208 2
            'setter' => $setter
209
        ];
210
211 2
        if ($entity instanceof JsonApiResource) {
212 2
            $source['pointer'] = $entity->getResourceKey().'.'.$field;
213
        }
214
215 2
        return static::createUnprocessable('Setter not found for entity')
216 2
            ->error('missing-setter', $source, 'Missing field setter.');
217
    }
218
219
    /**
220
     * @param object $entity
221
     * @param string $field
222
     * @param string $adder
223
     *
224
     * @return RestException
225
     */
226 1
    public static function missingAdder($entity, $field, $adder)
227
    {
228
        $source = [
229 1
            'entity' => ClassUtils::getClass($entity),
230 1
            'adder' => $adder
231
        ];
232
233 1
        if ($entity instanceof JsonApiResource) {
234 1
            $source['pointer'] = $entity->getResourceKey().'.'.$field;
235
        }
236
237 1
        return static::createUnprocessable('Missing remover method.')
238 1
            ->error('missing-adder', $source, 'Missing collection adder.');
239
    }
240
241
    /**
242
     * @param object $entity
243
     * @param string $field
244
     * @param string $remover
245
     *
246
     * @return static
247
     */
248 1
    public static function missingRemover($entity, $field, $remover)
249
    {
250
        $source = [
251 1
            'entity' => ClassUtils::getClass($entity),
252 1
            'remover' => $remover
253
        ];
254
255 1
        if ($entity instanceof JsonApiResource) {
256 1
            $source['pointer'] = $entity->getResourceKey().'.'.$field;
257
        }
258
259 1
        return static::createUnprocessable('Missing remover method.')
260 1
            ->error('missing-remover', $source, 'Missing collection remover.');
261
    }
262
263
    /**
264
     * @param int             $httpStatus
265
     * @param string          $message
266
     * @param \Exception|null $previous
267
     *
268
     * @return static
269
     */
270 15
    static public function create(
271
        $httpStatus = Response::HTTP_INTERNAL_SERVER_ERROR,
272
        $message = '',
273
        \Exception $previous = null
274
    ) {
275 15
        return new static($httpStatus, $message, $previous);
276
    }
277
278
    /**
279
     * RestException constructor.
280
     *
281
     * @param int             $httpStatus
282
     * @param string          $message
283
     * @param \Exception|null $previous
284
     */
285 15
    public function __construct(
286
        $httpStatus = Response::HTTP_INTERNAL_SERVER_ERROR,
287
        $message = '',
288
        \Exception  $previous = null
289
    ) {
290 15
        parent::__construct($message, $httpStatus, $previous);
291 15
    }
292
293
    /**
294
     * @param string $pointer
295
     * @param string $detail
296
     * @param array  $extra
297
     *
298
     * @return RestException
299
     */
300 1
    public function errorValidation($pointer, $detail, array $extra = [])
301
    {
302 1
        return $this->error('validation', ['pointer' => $pointer], $detail, $extra);
303
    }
304
305
    /**
306
     * @param string $applicationCode
307
     * @param array  $source
308
     * @param string $detail
309
     * @param array  $extra
310
     *
311
     * @return $this
312
     */
313 14
    public function error($applicationCode, $source, $detail, array $extra = [])
314
    {
315 14
        $this->errors[] = array_merge(['code' => $applicationCode, 'source' => $source, 'detail' => $detail] + $extra);
316
317 14
        return $this;
318
    }
319
320
    /**
321
     * @return array
322
     */
323 13
    public function errors()
324
    {
325 13
        return $this->errors;
326
    }
327
}
328