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 — fix-uploaders ( 5b8cb7...c8e752 )
by Pedro
15:13
created

BackpackCustomRule::getValidatorCustomAttributes()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 3
eloc 3
c 1
b 1
f 0
nc 2
nop 1
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 Backpack\Pro\Uploads\Validation\ValidGenericAjaxEndpoint;
0 ignored issues
show
Bug introduced by
The type Backpack\Pro\Uploads\Val...alidGenericAjaxEndpoint was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
7
use Closure;
8
use Illuminate\Contracts\Validation\DataAwareRule;
9
use Illuminate\Contracts\Validation\Rule;
10
use Illuminate\Contracts\Validation\ValidationRule;
11
use Illuminate\Contracts\Validation\ValidatorAwareRule;
12
use Illuminate\Http\UploadedFile;
13
use Illuminate\Support\Arr;
14
use Illuminate\Support\Facades\Validator;
15
use Illuminate\Support\Str;
16
17
abstract class BackpackCustomRule implements ValidationRule, DataAwareRule, ValidatorAwareRule
18
{
19
    use Support\HasFiles;
20
21
    /**
22
     * @var \Illuminate\Contracts\Validation\Validator
23
     */
24
    protected $validator;
25
26
    protected array $data;
27
28
    public array $fieldRules = [];
29
30
    public bool $implicit = true;
31
32
    public static function field(string|array|ValidationRule|Rule $rules = []): self
33
    {
34
        $instance = new static();
35
        $instance->fieldRules = self::getRulesAsArray($rules);
36
37
        if ($instance->validatesArrays()) {
38
            if (! in_array('array', $instance->getFieldRules())) {
39
                $instance->fieldRules[] = 'array';
40
            }
41
        }
42
43
        return $instance;
44
    }
45
46
    /**
47
     * Run the validation rule.
48
     *
49
     * @param  string  $attribute
50
     * @param  mixed  $value
51
     * @param  Closure(string): \Illuminate\Translation\PotentiallyTranslatedString  $fail
52
     * @return void
53
     */
54
    public function validate(string $attribute, mixed $value, Closure $fail): void
55
    {
56
        $value = $this->ensureValueIsValid($value);
57
58
        if ($value === false) {
59
            $fail('Invalid value for the attribute.')->translate();
60
61
            return;
62
        }
63
64
        $errors = $this->validateOnSubmit($attribute, $value);
65
        foreach ($errors as $error) {
66
            $fail($error)->translate();
67
        }
68
    }
69
70
    /**
71
     * Set the performing validator.
72
     *
73
     * @param  \Illuminate\Contracts\Validation\Validator  $validator
74
     * @return $this
75
     */
76
    public function setValidator($validator)
77
    {
78
        $this->validator = $validator;
79
80
        return $this;
81
    }
82
83
    /**
84
     * Set the data under validation.
85
     *
86
     * @param  array  $data
87
     * @return $this
88
     */
89
    public function setData($data)
90
    {
91
        $this->data = $data;
92
93
        return $this;
94
    }
95
96
    public function getFieldRules(): array
97
    {
98
        return tap($this->fieldRules, function ($rule) {
99
            if (is_a($rule, BackpackCustomRule::class, true)) {
100
                $rule = $rule->getFieldRules();
101
            }
102
103
            return $rule;
104
        });
105
    }
106
107
    protected static function getRulesAsArray($rules)
108
    {
109
        if (is_string($rules)) {
110
            $rules = explode('|', $rules);
111
        }
112
113
        if (! is_array($rules)) {
114
            $rules = [$rules];
115
        }
116
117
        return $rules;
118
    }
119
120
    protected function ensureValueIsValid($value)
121
    {
122
        if ($this->validatesArrays() && ! is_array($value)) {
123
            try {
124
                $value = json_decode($value, true) ?? [];
125
            } catch(\Exception $e) {
126
                return false;
127
            }
128
        }
129
130
        return $value;
131
    }
132
133
    private function validatesArrays(): bool
134
    {
135
        return is_a($this, ValidateArrayContract::class);
136
    }
137
138
    private function validateAndGetErrors(string $attribute, mixed $value, array $rules): array
139
    {
140
        $validator = Validator::make($value, [
141
            $attribute => $rules,
142
        ], $this->validator->customMessages, $this->getValidatorCustomAttributes($attribute));
0 ignored issues
show
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...
143
       
144
        return $validator->errors()->messages()[$attribute] ?? (! empty($validator->errors()->messages()) ? current($validator->errors()->messages()) : []);
145
    }
146
147
    private function getValidatorCustomAttributes(string $attribute): array
148
    {
149
        if(! is_a($this, ValidGenericAjaxEndpoint::class) && ! Str::contains($attribute, '.*.')) {
150
            return $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...
151
        }
152
        // generic fallback to `profile picture` from `profile.*.picture`
153
        return [$attribute => Str::replace('.*.', ' ', $attribute)];
154
    }
155
    protected function getValidationAttributeString(string $attribute)
156
    {
157
        return Str::substrCount($attribute, '.') > 1 ?
158
                Str::before($attribute, '.').'.*.'.Str::afterLast($attribute, '.') :
159
                $attribute;
160
    }
161
162
    protected function validateOnSubmit(string $attribute, mixed $value): array
163
    {
164
        return $this->validateRules($attribute, $value);
165
    }
166
167
    protected function validateFieldAndFile(string $attribute, null|array $data = null, array|null $customRules = null): array
168
    {
169
        $fieldErrors = $this->validateFieldRules($attribute, $data, $customRules);
170
171
        $fileErrors = $this->validateFileRules($attribute, $data);
172
173
        return array_merge($fieldErrors, $fileErrors);
174
    }
175
176
    /**
177
     * Implementation.
178
     */
179
    public function validateFieldRules(string $attribute, null|array|string|UploadedFile $data = null, array|null $customRules = null): array
180
    {
181
        $data = $data ?? $this->data;
182
        $validationRuleAttribute = $this->getValidationAttributeString($attribute);
183
        $data = $this->prepareValidatorData($data, $attribute);
184
185
        return $this->validateAndGetErrors($validationRuleAttribute, $data, $customRules ?? $this->getFieldRules());
186
    }
187
188
    protected function prepareValidatorData(array|string|UploadedFile $data, string $attribute): array
189
    {
190
        if ($this->validatesArrays() && is_array($data) && ! Str::contains($attribute, '.')) {
191
            return Arr::has($data, $attribute) ? $data : [$attribute => $data];
192
        }
193
194
        if (Str::contains($attribute, '.')) {
195
            $validData = [];
196
197
            Arr::set($validData, $attribute, ! is_array($data) ? $data : Arr::get($data, $attribute));
198
199
            return $validData;
200
        }
201
202
        return [$attribute => is_array($data) ? (Arr::get($data, $attribute) ?? $data) : $data];
203
    }
204
205
    protected function validateFileRules(string $attribute, mixed $data): array
206
    {
207
        $items = $this->prepareValidatorData($data ?? $this->data, $attribute);
208
        $items = is_array($items) ? $items : [$items];
0 ignored issues
show
introduced by
The condition is_array($items) is always true.
Loading history...
209
        $validationRuleAttribute = $this->getValidationAttributeString($attribute);
210
        
211
        $filesToValidate = Arr::get($items, $attribute);
212
        $filesToValidate = is_array($filesToValidate) ? array_filter($filesToValidate, function ($item) {
213
            return $item instanceof UploadedFile;
214
        }) : (is_a($filesToValidate, UploadedFile::class, true) ? [$filesToValidate] : []);
215
216
        Arr::set($items, $attribute, $filesToValidate);
217
218
        $errors = [];
219
220
        // validate each file individually
221
        foreach ($filesToValidate as $key => $file) {
222
            $fileToValidate = [];
223
            Arr::set($fileToValidate, $attribute, $file);
224
            $errors[] = $this->validateAndGetErrors($validationRuleAttribute, $fileToValidate, $this->getFileRules());
225
        }
226
227
        return array_unique(array_merge(...$errors));
228
    }
229
230
    public function validateRules(string $attribute, mixed $value): array
231
    {
232
        return $this->validateFieldAndFile($attribute, $value);
233
    }
234
}
235