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

ApiRequest   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 133
Duplicated Lines 0 %

Test Coverage

Coverage 75.56%

Importance

Changes 0
Metric Value
eloc 36
dl 0
loc 133
ccs 34
cts 45
cp 0.7556
rs 10
c 0
b 0
f 0
wmc 14

10 Methods

Rating   Name   Duplication   Size   Complexity  
A transformInput() 0 10 1
A isApiInternalCall() 0 8 2
A getTransformer() 0 3 1
A failedValidation() 0 6 2
A validateInputFields() 0 9 2
A getValidatorInstance() 0 6 1
A handleApiInternalCallFailedValidation() 0 6 1
A isValueSet() 0 3 2
A transformValidationOutput() 0 7 1
A handleApiCallFailedValidation() 0 8 1
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
}