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

BaseValidator::parserValidationRules()   C

Complexity

Conditions 20
Paths 1

Size

Total Lines 73
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 31
CRAP Score 41.9488

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 20
eloc 40
c 2
b 0
f 0
nc 1
nop 2
dl 0
loc 73
ccs 31
cts 50
cp 0.62
crap 41.9488
rs 5.3752

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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