Completed
Push — master ( eab647...b4731b )
by Mads
23:22 queued 20:45
created

ApiRequest::handleApiCallFailedValidation()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 1
dl 0
loc 7
ccs 5
cts 5
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Napp\Core\Api\Requests;
4
5
use Illuminate\Contracts\Validation\Validator;
6
use Illuminate\Foundation\Http\FormRequest;
7
use Napp\Core\Api\Exceptions\Exceptions\ApiInternalCallValidationException;
8
use Napp\Core\Api\Exceptions\Exceptions\InvalidFieldException;
9
use Napp\Core\Api\Exceptions\Exceptions\ValidationException;
10
use Napp\Core\Api\Transformers\ApiTransformer;
11
use Napp\Core\Api\Transformers\TransformerInterface;
12
13
abstract class ApiRequest extends FormRequest
14
{
15
    /**
16
     * @return Validator
17
     */
18 6
    protected function getValidatorInstance()
19
    {
20 6
        $this->replace($this->transformInput());
21 6
        $this->validateInputFields();
22
23 4
        return parent::getValidatorInstance();
24
    }
25
26
    /**
27
     * @param Validator $validator
28
     * @return void
29
     * @throws ValidationException
30
     */
31 4
    protected function failedValidation(Validator $validator)
32
    {
33 4
        if (false === $this->isApiInternalCall()) {
34 4
            $this->handleApiCallFailedValidation($validator);
35
        } else {
36
            $this->handleApiInternalCallFailedValidation($validator);
37
        }
38
    }
39
40
    /**
41
     * @return void
42
     * @throws InvalidFieldException
43
     */
44 6
    protected function validateInputFields()
45
    {
46 6
        $input = $this->input();
47 6
        $rules = $this->rules();
0 ignored issues
show
Bug introduced by
The method rules() does not exist on Napp\Core\Api\Requests\ApiRequest. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

47
        /** @scrutinizer ignore-call */ 
48
        $rules = $this->rules();
Loading history...
48 6
        if (false === empty(array_diff_key($input, $rules))) {
49 2
            $exception = new InvalidFieldException;
50 2
            $exception->statusMessage = $exception->statusMessage . ': ' . implode(',', array_keys(array_diff_key($input, $rules)));
51
52 2
            throw $exception;
53
        }
54 4
    }
55
56
    /**
57
     * @return array
58
     */
59 6
    protected function transformInput(): array
60
    {
61
        /**
62
         * Remove input fields like _method, _token, etc.
63
         */
64
        $input = array_filter($this->input(), function ($key) {
65 2
            return !starts_with($key, '_');
66 6
        }, ARRAY_FILTER_USE_KEY);
67
68 6
        return $this->getTransformer()->transformInput($input);
69
    }
70
71
    /**
72
     * @return TransformerInterface
73
     */
74
    protected function getTransformer(): TransformerInterface
75
    {
76
        return app(ApiTransformer::class);
77
    }
78
79
    /**
80
     * @see AppServiceProvider
81
     * @return bool
82
     */
83 4
    protected function isApiInternalCall(): bool
84
    {
85 4
        $request = request();
86 4
        if (true === $request->hasMacro('isApiInternalCall')) {
87 4
            return $request->isApiInternalCall();
88
        }
89
90
        return false;
91
    }
92
93
    /**
94
     * @param Validator $validator
95
     * @return void
96
     * @throws ValidationException
97
     * @throws \Illuminate\Validation\ValidationException
98
     */
99 4
    protected function handleApiCallFailedValidation(Validator $validator)
100
    {
101 4
        $message = $validator->messages()->first();
102 4
        $exception = new ValidationException();
103 4
        $exception->statusMessage = $exception->statusMessage . ': ' . $message;
104
105 4
        throw $exception;
106
    }
107
108
    /**
109
     * @param Validator $validator
110
     * @return void
111
     * @throws ApiInternalCallValidationException
112
     */
113
    protected function handleApiInternalCallFailedValidation(Validator $validator)
114
    {
115
        $input = $this->getTransformer()->transformOutput($this->except($this->dontFlash));
116
        $errors = collect($this->getTransformer()->transformOutput($validator->getMessageBag()->toArray()))
117
            ->reject(function ($error) {
118
                return false === is_array($error);
119
            })
120
            ->toArray();
121
122
        throw new ApiInternalCallValidationException($input, $errors);
123
    }
124
125
    /**
126
     * @param array $input
127
     * @param string $key
128
     * @return bool
129
     */
130
    protected function isValueSet(array $input, string $key): bool
131
    {
132
        return (true === isset($input[$key]) && false === empty($input[$key]));
133
    }
134
}
135