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
Pull Request — main (#5478)
by Cristian
25:33 queued 14:59
created

BackpackCustomRule::validateOnSubmit()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 2
dl 0
loc 3
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\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 => Arr::get($data, $attribute)];
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];
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 = $this->validatesArrays() ? Arr::get($items, $attribute) : [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