Completed
Push — master ( d4e3f3...a970d6 )
by Mads
05:04
created

ApiRequest::transformValidationOutput()   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
/**
14
 * Class ApiRequest
15
 * @package Napp\Core\Api\Requests
16
 */
17
abstract class ApiRequest extends FormRequest
18
{
19
    /**
20
     * @return Validator
21
     * @throws \Napp\Core\Api\Exceptions\Exceptions\InvalidFieldException
22
     */
23 10
    protected function getValidatorInstance()
24
    {
25 10
        $this->replace($this->transformInput());
26 10
        $this->validateInputFields();
27
28 8
        return parent::getValidatorInstance();
29
    }
30
31
    /**
32
     * @param Validator $validator
33
     * @return void
34
     * @throws \Illuminate\Validation\ValidationException
35
     * @throws \Napp\Core\Api\Exceptions\Exceptions\ApiInternalCallValidationException
36
     * @throws \Napp\Core\Api\Exceptions\Exceptions\ValidationException
37
     */
38 8
    protected function failedValidation(Validator $validator)
39
    {
40 8
        if (false === $this->isApiInternalCall()) {
41 8
            $this->handleApiCallFailedValidation($validator);
42
        } else {
43
            $this->handleApiInternalCallFailedValidation($validator);
44
        }
45
    }
46
47
    /**
48
     * @return void
49
     * @throws InvalidFieldException
50
     */
51 10
    protected function validateInputFields(): void
52
    {
53 10
        $input = $this->input();
54 10
        $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

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