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 — upload-validation ( 131a8f...ac355e )
by Pedro
11:51
created

ValidArray::__call()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 2
eloc 5
c 1
b 0
f 1
nc 2
nop 2
dl 0
loc 10
rs 10
1
<?php
2
3
namespace Backpack\CRUD\app\Library\Validation\Rules;
4
5
use Backpack\CRUD\app\Library\CrudPanel\CrudPanelFacade;
6
use Closure;
7
use Illuminate\Contracts\Validation\DataAwareRule;
8
use Illuminate\Contracts\Validation\ValidationRule;
0 ignored issues
show
Bug introduced by
The type Illuminate\Contracts\Validation\ValidationRule 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...
9
use Illuminate\Contracts\Validation\ValidatorAwareRule;
10
use Illuminate\Database\Eloquent\Model;
11
use Illuminate\Support\Facades\Validator;
12
use Illuminate\Validation\Rules\File;
13
use Illuminate\Support\Str;
14
15
class ValidArray implements ValidationRule, DataAwareRule, ValidatorAwareRule
16
{
17
    /**
18
     * @var \Illuminate\Contracts\Validation\Validator
19
     */
20
    protected $validator;
21
22
    protected array $data;
23
24
    public array $arrayRules = [];
25
26
    public array $itemRules = [];
27
28
    public array $namedItemRules = [];
29
30
    public ?Model $entry;
31
32
    public static function make(): self
33
    {
34
        $instance = new static();
35
        $entry = CrudPanelFacade::getCurrentEntry();
0 ignored issues
show
Bug introduced by
The method getCurrentEntry() does not exist on Backpack\CRUD\app\Librar...udPanel\CrudPanelFacade. Since you implemented __callStatic, 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

35
        /** @scrutinizer ignore-call */ 
36
        $entry = CrudPanelFacade::getCurrentEntry();
Loading history...
36
        $instance->entry = $entry !== false ? $entry : null;
37
38
        return $instance;
39
    }
40
41
    /**
42
     * Run the validation rule.
43
     *
44
     * @param  string  $attribute
45
     * @param  mixed  $value
46
     * @param  Closure(string): \Illuminate\Translation\PotentiallyTranslatedString  $fail
47
     * @return void
48
     */
49
    public function validate(string $attribute, mixed $value, Closure $fail): void
50
    {
51
        if (! is_array($value)) {
52
            try {
53
                $value = json_decode($value, true);
54
            } catch (\Exception $e) {
55
                $fail('Unable to determine the value type.');
56
57
                return;
58
            }
59
        }
60
        
61
        $this->validateArrayData($attribute, $fail, $value);
62
        $this->validateItemsAsArray($attribute, $value, $fail);
63
    }
64
65
    /**
66
     * Set the performing validator.
67
     *
68
     * @param  \Illuminate\Contracts\Validation\Validator  $validator
69
     * @return $this
70
     */
71
    public function setValidator($validator)
72
    {
73
        $this->validator = $validator;
74
75
        return $this;
76
    }
77
78
    /**
79
     * Set the data under validation.
80
     *
81
     * @param  array  $data
82
     * @return $this
83
     */
84
    public function setData($data)
85
    {
86
        $this->data = $data;
87
88
        return $this;
89
    }
90
91
    /**
92
     * Set the rules that apply to the "array" aka the field, if it's required, min, max etc.
93
     */
94
    public function arrayRules(string|array|File $rules): self
95
    {
96
        if (is_string($rules)) {
0 ignored issues
show
introduced by
The condition is_string($rules) is always false.
Loading history...
97
            $rules = explode('|', $rules);
98
        }
99
100
        if (! in_array('array', $rules)) {
101
            $rules[] = 'array';
102
        }
103
104
        $this->arrayRules = $rules;
105
106
        return $this;
107
    }
108
109
    /**
110
     * Set the rules that apply to the items beeing sent in array.
111
     */
112
    public function itemRules(string|array|File $rules): self
113
    {
114
        if (is_string($rules)) {
0 ignored issues
show
introduced by
The condition is_string($rules) is always false.
Loading history...
115
            $rules = explode('|', $rules);
116
        }
117
118
        if (! is_array($rules)) {
0 ignored issues
show
introduced by
The condition is_array($rules) is always true.
Loading history...
119
            $rules = [$rules];
120
        }
121
122
        $this->itemRules = $rules;
123
124
        return $this;
125
    }
126
127
    /**
128
     * Performs the validation on the array of items, item by item, using the item validation array.
129
     *
130
     * @param  string  $attribute
131
     * @param  array  $files
132
     * @param  Closure  $fail
133
     * @return void
134
     */
135
    protected function validateItems($attribute, $items, $fail)
136
    {
137
        foreach ($items as $item) {
138
            $validator = Validator::make([$attribute => $item], [
139
                $attribute => $this->itemRules,
140
            ], $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...
141
142
            if ($validator->fails()) {
143
                foreach ($validator->errors()->messages()[$attribute] as $message) {
144
                    $fail($message)->translate();
145
                }
146
            }
147
        }
148
    }
149
150
    /**
151
     * Performs the validation on the array of items, using the item validation array.
152
     *
153
     * @param  string  $attribute
154
     * @param  array  $files
155
     * @param  Closure  $fail
156
     * @return void
157
     */
158
    protected function validateItemsAsArray($attribute, $items, $fail)
159
    {
160
        if (! empty($this->namedItemRules)) {
161
            $this->validateNamedItemRules($attribute, $items, $fail);
0 ignored issues
show
Bug introduced by
$attribute of type string is incompatible with the type Backpack\CRUD\app\Library\Validation\Rules\stromg expected by parameter $attribute of Backpack\CRUD\app\Librar...alidateNamedItemRules(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

161
            $this->validateNamedItemRules(/** @scrutinizer ignore-type */ $attribute, $items, $fail);
Loading history...
162
        }
163
164
        $validator = Validator::make([$attribute => $items], [
165
            $attribute.'.*' => $this->itemRules,
166
        ], $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...
167
168
        if ($validator->fails()) {
169
            foreach ($validator->errors()->messages()[$attribute] as $message) {
170
                $fail($message)->translate();
171
            }
172
        }
173
    }
174
175
    /**
176
     * Validate the given data or the array of data from the validator againts the array rules.
177
     *
178
     * @param  string  $attribute
179
     * @param  Closure  $fail
180
     * @param  null|array  $data
181
     * @param  null|array  $rules
182
     * @return void
183
     */
184
    protected function validateArrayData($attribute, $fail, $data = null, $rules = null)
185
    {
186
        $data = $data ?? $this->data;
187
        $rules = $rules ?? $this->arrayRules;
188
       
189
        $validator = Validator::make($data, [
190
            $attribute => $rules,
191
        ], $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...
192
193
        if ($validator->fails()) {
194
            foreach ($validator->errors()->messages()[$attribute] as $message) {
195
                $fail($message)->translate();
196
            }
197
        }
198
    }
199
200
    /**
201
     * When developer provides named rules for the items, for example: 'repeatable' => [ValidArray::make()->ruleName('required')]
202
     *
203
     * @param stromg $attribute
0 ignored issues
show
Bug introduced by
The type Backpack\CRUD\app\Library\Validation\Rules\stromg 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...
204
     * @param array $items
205
     * @param Closure $fail
206
     * @return void
207
     */
208
    private function validateNamedItemRules($attribute, $items, $fail)
209
    {
210
        $this->namedItemRules = array_combine(array_map(function($ruleKey) use ($attribute) {
211
            return $attribute.'.*.'.$ruleKey;
212
        }, array_keys($this->namedItemRules)), $this->namedItemRules);
213
        
214
        array_walk($this->namedItemRules, function(&$value, $key) {
215
            if(is_array($value)) {
216
                $rules = [];
217
                foreach($value as $rule) {
218
                    if (is_a($rule, get_class($this), true)) {
219
                        $validArrayRules =  $rule->itemRules;
220
                        if(is_array($validArrayRules)) {
221
                            $rules = array_merge($rules, $validArrayRules);
222
                            continue;
223
                        }
224
                        $rules[] = $validArrayRules;
225
                        continue;
226
                    }
227
                    $rules[] = $rule;
228
                }
229
                $value = $rules;
230
            }
231
        });
232
233
        $this->validateArrayData($attribute, $fail, $items, $this->namedItemRules);
234
    }
235
236
    public function __call($method, $arguments)
237
    {
238
        // if method starts with `rule` eg: ruleName, extract the input name and add it to the array of rules
239
        if(Str::startsWith($method, 'rule')) {
240
            $argument = Str::snake(Str::replaceFirst('rule', '', $method));
241
            $this->namedItemRules[$argument] = $arguments[0];
242
            return $this;
243
        }
244
245
        return $this->{$method}(...$arguments);
246
    }
247
}
248