BaseValidator::getExtraConditions()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 1
dl 0
loc 12
ccs 0
cts 7
cp 0
crap 12
rs 9.8666
c 0
b 0
f 0
1
<?php
2
namespace NwLaravel\Validation;
3
4
use Illuminate\Validation\Factory;
5
use Prettus\Validator\AbstractValidator;
6
use Illuminate\Validation\Rules\Unique;
7
use Illuminate\Validation\Rule;
8
9
/**
10
 * Class BaseValidator
11
 * @abstract
12
 */
13
abstract class BaseValidator extends AbstractValidator
14
{
15
    /**
16
     * Validator
17
     *
18
     * @var \Illuminate\Validation\Factory
19
     */
20
    protected $validator;
21
22
    /**
23
     * @var string
24
     */
25
    protected $keyName;
26
27
    /**
28
     * @var array
29
     */
30
    protected $messages = [];
31
32
    /**
33
     * @var array
34
     */
35
    protected $attributes = [];
36
37
    /**
38
     * Construct
39
     *
40
     * @param \Illuminate\Validation\Factory $validator
41
     */
42 2
    public function __construct(Factory $validator)
43
    {
44 2
        $this->validator = $validator;
45 2
        $this->rules = array_merge_recursive((array) $this->rules, $this->makeRules());
46 2
        $this->messages = array_merge_recursive((array) $this->messages, $this->makeMessages());
47 2
        $this->attributes = array_merge_recursive((array) $this->attributes, $this->makeAttributes());
48 2
    }
49
50
    /**
51
     * MakeRules
52
     *
53
     * @return array
54
     */
55 2
    protected function makeRules()
56
    {
57 2
        return [];
58
    }
59
60
    /**
61
     * Make Messages
62
     *
63
     * @return array
64
     */
65 2
    protected function makeMessages()
66
    {
67 2
        return [];
68
    }
69
70
    /**
71
     * Make Attributes
72
     *
73
     * @return array
74
     */
75 2
    protected function makeAttributes()
76
    {
77 2
        return [];
78
    }
79
80
    /**
81
     * Get Messages
82
     *
83
     * @return array
84
     */
85 2
    public function getMessages()
86
    {
87 2
        return $this->messages;
88
    }
89
90
    /**
91
     * Get Attributes
92
     *
93
     * @return array
94
     */
95 2
    public function getAttributes()
96
    {
97 2
        return $this->attributes;
98
    }
99
100
    /**
101
     * Get Validator
102
     *
103
     * @return \Illuminate\Validation\Factory
104
     */
105
    public function getValidator()
106
    {
107
        return $this->validator;
108
    }
109
110
    /**
111
     * Set Key Name
112
     *
113
     * @param string $keyName
114
     *
115
     * @return BaseValidator
116
     */
117
    public function setKeyName($keyName)
118
    {
119
        $this->keyName = $keyName;
120
    }
121
122
    /**
123
     * Get rule for validation by action ValidatorInterface::RULE_CREATE or ValidatorInterface::RULE_UPDATE
124
     *
125
     * Default rule: ValidatorInterface::RULE_CREATE
126
     *
127
     * @param string|null $action
128
     *
129
     * @return array
130
     */
131 2
    public function getRules($action = null)
132
    {
133 2
        $rules = [];
134
135 2
        if (isset($this->rules[$action])) {
136 2
            $rules = $this->rules[$action];
137 2
        }
138
139 2
        return $this->parserValidationRules($rules, $this->id);
140
    }
141
142
    /**
143
     * Pass the data and the rules to the validator
144
     *
145
     * @param string $action
146
     * @return bool
147
     */
148 2
    public function passes($action = null)
149
    {
150 2
        $rules      = $this->getRules($action);
151 2
        $messages   = $this->getMessages();
152 2
        $attributes = $this->getAttributes();
153 2
        $validator  = $this->validator->make($this->data, $rules, $messages, $attributes);
154
155 2
        if ($validator->fails()) {
156 1
            $this->errors = $validator->messages();
157 1
            return false;
158
        }
159
160 1
        return true;
161
    }
162
163
    /**
164
     * Parser Validation Rules
165
     *
166
     * @param array    $rules
167
     * @param int|null $id
168
     *
169
     * @return array
170
     */
171
    protected function parserValidationRules($rules, $id = null)
172
    {
173 2
        array_walk($rules, function (&$rules, $field) use ($id) {
174 2
            if (!is_array($rules)) {
175 2
                $rules = explode("|", $rules);
176 2
            }
177
178 2
            foreach ($rules as $ruleIdx => $rule) {
179 2
                $rule = $this->replaceValuesRules($rule);
180
181 2
                $itens = array_pad(explode(":", $rule), 2, null);
182 2
                $nameRule = isset($itens[0]) ? $itens[0] : null;
183 2
                $params = implode(":", array_splice($itens, 1));
184
185 2
                if ($nameRule != "unique") {
186 2
                    $rule = $nameRule;
187 2
                    if (!empty($params)) {
188 2
                        $rule .= ":".$params;
189 2
                    }
190 2
                    $rules[$ruleIdx] = $rule;
191 2
                    continue;
192
                }
193
194
                // Atualiza Rule Unique
195 1
                $p = array_map("trim", explode(",", $params));
196
197 1
                $table = $p[0];
198
199
                // set field name to rules key ($field) (laravel convention)
200 1
                if (isset($p[1]) && !empty($p[1])) {
201
                    $field = $p[1];
202
                }
203
204
                // set 3rd parameter to id given to getValidationRules()
205 1
                if (isset($p[2]) && !empty($p[2]) && strtoupper($p[2]) != 'NULL') {
206
                    $id = intval($p[2]);
0 ignored issues
show
Bug introduced by
Consider using a different name than the imported variable $id, or did you forget to import by reference?

It seems like you are assigning to a variable which was imported through a use statement which was not imported by reference.

For clarity, we suggest to use a different name or import by reference depending on whether you would like to have the change visibile in outer-scope.

Change not visible in outer-scope

$x = 1;
$callable = function() use ($x) {
    $x = 2; // Not visible in outer scope. If you would like this, how
            // about using a different variable name than $x?
};

$callable();
var_dump($x); // integer(1)

Change visible in outer-scope

$x = 1;
$callable = function() use (&$x) {
    $x = 2;
};

$callable();
var_dump($x); // integer(2)
Loading history...
207
                }
208
209 1
                if (isset($p[3]) && !empty($p[3])) {
210
                    $keyName = $p[3];
211
                } else {
212 1
                    $keyName = 'id';
213
                }
214
215 1
                if (! $rule instanceof Unique) {
216 1
                    $rule = Rule::unique($table, $field);
217 1
                }
218
219 1
                if (!empty($id) || $id == '0') {
220
                    $rule->ignore($id, $keyName);
221
                }
222
223
                // Extra Conditions
224 1
                if (isset($p[4])) {
225
                    $extra = $this->getExtraConditions(array_slice($p, 4));
226
                    foreach ($extra as $key => $value) {
227
                        if (strtoupper($value) == 'NULL' || is_null($value)) {
228
                            $rule->whereNull($key);
229
                        } else {
230
                            $rule->where($key, $value);
231
                        }
232
                    }
233
                }
234
235 1
                $rules[$ruleIdx] = $rule;
236 2
            }
237 2
        });
238
239 2
        return $rules;
240
    }
241
242
    /**
243
     * Get the extra conditions for a unique / exists rule.
244
     *
245
     * @param  array  $segments
246
     * @return array
247
     */
248
    protected function getExtraConditions(array $segments)
249
    {
250
        $extra = [];
251
252
        $count = count($segments);
253
254
        for ($i = 0; $i < $count; $i += 2) {
255
            $extra[$segments[$i]] = isset($segments[$i + 1]) ? $segments[$i + 1] : null;
256
        }
257
258
        return $extra;
259
    }
260
261
    /**
262
     * Replace Values Rules
263
     *
264
     * @param string $rule
265
     *
266
     * @return string
267
     */
268 2
    protected function replaceValuesRules($rule)
269
    {
270 2
        $x = 0;
271 2
        while (preg_match('/\[([A-Za-z0-9_]+)\]/', $rule, $match)) {
272 2
            $x++;
273 2
            $field = $match[1];
274 2
            $value = 'NULL';
275 2
            if (array_key_exists($field, $this->data)) {
276
                $value = $this->getValue($field);
277
            }
278
279 2
            $rule = str_replace("[{$field}]", $value, $rule);
280 2
            if ($x>10) {
281
                break;
282
            }
283 2
        }
284
285 2
        return $rule;
286
    }
287
288
    /**
289
     * Get the value of a given attribute.
290
     *
291
     * @param string $attribute
292
     *
293
     * @return mixed
294
     */
295
    protected function getValue($attribute)
296
    {
297
        $value = array_get($this->data, $attribute);
0 ignored issues
show
Deprecated Code introduced by
The function array_get() has been deprecated with message: Arr::get() should be used directly instead. Will be removed in Laravel 6.0.

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
298
299
        return is_null($value) ? 'NULL' : $value;
300
    }
301
}
302