Scrutinizer GitHub App not installed

We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.

Install GitHub App

Passed
Push — add-method-to-get-ajax-uploade... ( 4a3e5a...2230c6 )
by Pedro
14:58
created

BackpackCustomRule::prepareValidatorData()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 3
c 0
b 0
f 0
nc 3
nop 2
dl 0
loc 7
rs 10
1
<?php
2
3
namespace Backpack\CRUD\app\Library\Validation\Rules;
4
5
use Backpack\CRUD\app\Library\Validation\Rules\Support\ValidateArrayContract;
6
use Closure;
7
use Illuminate\Contracts\Validation\DataAwareRule;
8
use Illuminate\Contracts\Validation\Rule;
9
use Illuminate\Contracts\Validation\ValidationRule;
10
use Illuminate\Contracts\Validation\ValidatorAwareRule;
11
use Illuminate\Http\UploadedFile;
12
use Illuminate\Support\Facades\Validator;
13
use Illuminate\Support\Str;
14
use Illuminate\Support\Arr;
15
16
abstract class BackpackCustomRule implements ValidationRule, DataAwareRule, ValidatorAwareRule
17
{
18
    use Support\HasFiles;
19
20
    /**
21
     * @var \Illuminate\Contracts\Validation\Validator
22
     */
23
    protected $validator;
24
25
    protected array $data;
26
27
    public array $fieldRules = [];
28
29
    public bool $implicit = true;
30
31
    public static function field(string|array|ValidationRule|Rule $rules = []): self
32
    {
33
        $instance = new static();
34
        $instance->fieldRules = self::getRulesAsArray($rules);
35
36
        if($instance->validatesArrays()) {
37
            if (! in_array('array', $instance->getFieldRules())) {
38
                $instance->fieldRules[] = 'array';
39
            }
40
        }
41
        return $instance;
42
43
44
        $instance = new static();
0 ignored issues
show
Unused Code introduced by
$instance = new static() is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
45
        $instance->fieldRules = self::getRulesAsArray($rules);
46
47
        if (! in_array('array', $instance->getFieldRules())) {
48
            $instance->fieldRules[] = 'array';
49
        }
50
51
        return $instance;
52
    }
53
54
    /**
55
     * Run the validation rule.
56
     *
57
     * @param  string  $attribute
58
     * @param  mixed  $value
59
     * @param  Closure(string): \Illuminate\Translation\PotentiallyTranslatedString  $fail
60
     * @return void
61
     */
62
    public function validate(string $attribute, mixed $value, Closure $fail): void
63
    {
64
        $value = $this->ensureValueIsValid($value);
65
      
66
        if ($value === false) {
67
            $fail('Invalid value for the attribute.')->translate();
68
69
            return;
70
        }
71
72
        $errors = $this->validateOnSubmit($attribute, $value);
73
        foreach ($errors as $error) {
74
            $fail($error)->translate();
75
        }
76
    }
77
78
    /**
79
     * Set the performing validator.
80
     *
81
     * @param  \Illuminate\Contracts\Validation\Validator  $validator
82
     * @return $this
83
     */
84
    public function setValidator($validator)
85
    {
86
        $this->validator = $validator;
87
88
        return $this;
89
    }
90
91
    /**
92
     * Set the data under validation.
93
     *
94
     * @param  array  $data
95
     * @return $this
96
     */
97
    public function setData($data)
98
    {
99
        $this->data = $data;
100
101
        return $this;
102
    }
103
104
    public function getFieldRules(): array
105
    {
106
        return tap($this->fieldRules, function ($rule) {
107
            if (is_a($rule, BackpackCustomRule::class, true)) {
108
                $rule = $rule->getFieldRules();
109
            }
110
111
            return $rule;
112
        });
113
    }
114
115
    protected static function getRulesAsArray($rules)
116
    {
117
        if (is_string($rules)) {
118
            $rules = explode('|', $rules);
119
        }
120
121
        if (! is_array($rules)) {
122
            $rules = [$rules];
123
        }
124
125
        return $rules;
126
    }
127
128
    protected function ensureValueIsValid($value)
129
    {
130
        if($this->validatesArrays() && ! is_array($value)) {
131
            try {
132
                $value = json_decode($value, true) ?? [];
133
            } catch(\Exception $e) {
134
                return false;
135
            }
136
        }
137
138
        return $value;
139
    }
140
141
    private function validatesArrays(): bool
142
    {
143
        return is_a($this, ValidateArrayContract::class);
144
    }
145
146
    private function validateAndGetErrors(string $attribute, mixed $value, array $rules): array
147
    {
148
        $validator = Validator::make($value, [
149
            $attribute => $rules,
150
        ], $this->validator->customMessages, $this->validator->customAttributes);
0 ignored issues
show
Bug introduced by
Accessing customAttributes on the interface Illuminate\Contracts\Validation\Validator suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
Bug introduced by
Accessing customMessages on the interface Illuminate\Contracts\Validation\Validator suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
151
        return $validator->errors()->messages()[$attribute] ?? [];
152
    }
153
154
    protected function getValidationAttributeString(string $attribute)
155
    {
156
        return Str::substrCount($attribute, '.') > 1 ?
157
                Str::before($attribute, '.').'.*.'.Str::afterLast($attribute, '.') :
158
                $attribute;
159
    }
160
161
    protected function validateOnSubmit(string $attribute, mixed $value): array
162
    {
163
        return $this->validateRules($attribute, $value);
164
    }
165
166
    protected function validateFieldAndFile(string $attribute, null|array $data = null, array|null $customRules = null): array
167
    {
168
        $fieldErrors = $this->validateFieldRules($attribute, $data, $customRules);
169
        $fileErrors = $this->validateFileRules($attribute, $data);
170
171
        return array_merge($fieldErrors, $fileErrors);
172
    }
173
174
    /**
175
     * Implementation.
176
     */
177
    public function validateFieldRules(string $attribute, null|array|UploadedFile $data = null, array|null $customRules = null): array
178
    {
179
        $data = $data ?? $this->data;
180
        $validationRuleAttribute = $this->getValidationAttributeString($attribute);
181
       
182
        $data = $this->prepareValidatorData($data, $attribute);
183
       
184
        return $this->validateAndGetErrors($validationRuleAttribute, $data, $customRules ?? $this->getFieldRules());
185
    }
186
187
    protected function prepareValidatorData(array|UploadedFile $data, string $attribute): array
188
    {
189
190
        if($this->validatesArrays() && is_array($data)) {
191
            return Arr::has($data, $attribute) ? $data : [$attribute => Arr::get($data, $attribute)];
192
        }
193
        return [$attribute => $data];
194
    }
195
196
    protected function validateFileRules(string $attribute, mixed $data): array
197
    {
198
        $data = $data ?? $this->data;
199
        $items = is_array($data) && array_key_exists($attribute, $data) ? $data[$attribute] : $data;
200
        $items = is_array($items) ? $items : [$items];
201
        $errors = [];
202
        // we validate each file individually to avoid returning messages like: `field.0` is not a pdf.
203
        foreach ($items as $sentFiles) {
204
            if(!is_array($sentFiles)) {
205
                try {
206
                    if (is_file($sentFiles)) {
207
                        $errors[] = $this->validateAndGetErrors($attribute, [$attribute => $sentFiles], $this->getFileRules());
208
                    }
209
                    continue;
210
                }catch(\Exception) {
211
                    $errors[] = 'Unknown datatype, aborting upload process.';
212
                    break;
213
                }
214
            }
215
    
216
            if (is_multidimensional_array($sentFiles)) {
217
                foreach ($sentFiles as $key => $value) {
218
                    foreach ($value[$attribute] as $file) {
219
                        if (is_file($file)) {
220
                            $errors[] = $this->validateAndGetErrors($attribute, [$attribute => $file], $this->getFileRules());
221
                        }
222
                    }
223
                }
224
                continue;
225
            }
226
227
            foreach ($sentFiles as $key => $value) {
228
                if (is_file($value)) {
229
                    $errors[] = $this->validateAndGetErrors($attribute, [$attribute => $value], $this->getFileRules());
230
                }
231
            }            
232
        }
233
       
234
        return array_unique(array_merge(...$errors));
235
    }
236
237
    public function validateRules(string $attribute, mixed $value): array
238
    {
239
        return $this->validateFieldAndFile($attribute, $value);
240
    }
241
}
242