Completed
Push — master ( 5a38a9...eb02f9 )
by Renato
05:29
created

BaseValidator::getExtraConditions()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
eloc 6
c 0
b 0
f 0
nc 3
nop 1
dl 0
loc 12
ccs 0
cts 7
cp 0
crap 12
rs 9.4285
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 2
    protected function parserValidationRules($rules, $id = null)
172
    {
173
        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->where(function ($query) use ($id, $keyName) {
0 ignored issues
show
Documentation introduced by
function ($query) use($i...rWhereNull($keyName); } is of type object<Closure>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
221
                        $query->orWhere($keyName, '<>', $id);
222
                        $query->orWhereNull($keyName);
223
                    });
224
                }
225
226
                // Extra Conditions
227 1
                if (isset($p[4])) {
228
                    $extra = $this->getExtraConditions(array_slice($p, 4));
229
                    foreach ($extra as $key => $value) {
230
                        if (strtoupper($value) == 'NULL' || is_null($value)) {
231
                            $rule->whereNull($key);
232
                        } else {
233
                            $rule->where($key, $value);
234
                        }
235
                    }
236
                }
237
238 1
                $rules[$ruleIdx] = $rule;
239 2
            }
240 2
        });
241
242 2
        return $rules;
243
    }
244
245
    /**
246
     * Get the extra conditions for a unique / exists rule.
247
     *
248
     * @param  array  $segments
249
     * @return array
250
     */
251
    protected function getExtraConditions(array $segments)
252
    {
253
        $extra = [];
254
255
        $count = count($segments);
256
257
        for ($i = 0; $i < $count; $i += 2) {
258
            $extra[$segments[$i]] = isset($segments[$i + 1]) ? $segments[$i + 1] : null;
259
        }
260
261
        return $extra;
262
    }
263
264
    /**
265
     * Replace Values Rules
266
     *
267
     * @param string $rule
268
     *
269
     * @return string
270
     */
271 2
    protected function replaceValuesRules($rule)
272
    {
273 2
        $x = 0;
274 2
        while (preg_match('/\[([A-Za-z0-9_]+)\]/', $rule, $match)) {
275 2
            $x++;
276 2
            $field = $match[1];
277 2
            $value = 'NULL';
278 2
            if (array_key_exists($field, $this->data)) {
279
                $value = $this->getValue($field);
280
            }
281
282 2
            $rule = str_replace("[{$field}]", $value, $rule);
283 2
            if ($x>10) {
284
                break;
285
            }
286 2
        }
287
288 2
        return $rule;
289
    }
290
291
    /**
292
     * Get the value of a given attribute.
293
     *
294
     * @param string $attribute
295
     *
296
     * @return mixed
297
     */
298
    protected function getValue($attribute)
299
    {
300
        $value = array_get($this->data, $attribute);
301
302
        return is_null($value) ? 'NULL' : $value;
303
    }
304
}
305