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

Test Failed
Pull Request — main (#5478)
by Pedro
27:49 queued 12:44
created

BackpackCustomRule::getFieldRules()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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