Validation_Core   D
last analyzed

Complexity

Total Complexity 113

Size/Duplication

Total Lines 714
Duplicated Lines 16.11 %

Coupling/Cohesion

Components 2
Dependencies 3

Importance

Changes 3
Bugs 2 Features 0
Metric Value
c 3
b 2
f 0
dl 115
loc 714
rs 4.4444
wmc 113
lcom 2
cbo 3

23 Methods

Rating   Name   Duplication   Size   Complexity  
A factory() 0 4 1
A __construct() 0 7 1
A __clone() 0 5 1
A copy() 0 8 1
A submitted() 0 8 2
A field_names() 0 15 1
A as_array() 0 4 1
C safe_array() 0 31 7
A allow_empty_rules() 0 10 1
D callback() 0 36 9
A pre_filter() 21 21 4
A post_filter() 21 21 3
B add_rules() 0 40 6
A add_callbacks() 21 21 3
F validate() 52 162 42
A add_error() 0 6 1
B message() 0 27 5
A errors() 0 19 4
B required() 0 13 6
A matches() 0 10 4
B length() 0 21 5
A depends_on() 0 10 4
A chars() 0 4 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Validation_Core often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Validation_Core, and based on these observations, apply Extract Interface, too.

1
<?php defined('SYSPATH') or die('No direct access allowed.');
2
/**
3
 * Validation library.
4
 *
5
 * $Id: Validation.php 4120 2009-03-25 19:22:31Z jheathco $
6
 *
7
 * @package    Validation
8
 * @author     Kohana Team
9
 * @copyright  (c) 2007-2008 Kohana Team
10
 * @license    http://kohanaphp.com/license.html
11
 */
12
class Validation_Core extends ArrayObject
13
{
14
15
    // Filters
16
    protected $pre_filters = array();
17
    protected $post_filters = array();
18
19
    // Rules and callbacks
20
    protected $rules = array();
21
    protected $callbacks = array();
22
23
    // Rules that are allowed to run on empty fields
24
    protected $empty_rules = array('required', 'matches');
25
26
    // Errors
27
    protected $errors = array();
28
    protected $messages = array();
29
30
    // Fields that are expected to be arrays
31
    protected $array_fields = array();
32
33
    // Checks if there is data to validate.
34
    protected $submitted;
35
36
    /**
37
     * Creates a new Validation instance.
38
     *
39
     * @param   array   array to use for validation
40
     * @return  object
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use Validation.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
41
     */
42
    public static function factory(array $array)
43
    {
44
        return new Validation($array);
45
    }
46
47
    /**
48
     * Sets the unique "any field" key and creates an ArrayObject from the
49
     * passed array.
50
     *
51
     * @param   array   array to validate
52
     * @return  void
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
53
     */
54
    public function __construct(array $array)
55
    {
56
        // The array is submitted if the array is not empty
57
        $this->submitted = ! empty($array);
58
59
        parent::__construct($array, ArrayObject::ARRAY_AS_PROPS | ArrayObject::STD_PROP_LIST);
60
    }
61
62
    /**
63
     * Magic clone method, clears errors and messages.
64
     *
65
     * @return  void
66
     */
67
    public function __clone()
68
    {
69
        $this->errors = array();
70
        $this->messages = array();
71
    }
72
73
    /**
74
     * Create a copy of the current validation rules and change the array.
75
     *
76
     * @chainable
77
     * @param   array  new array to validate
0 ignored issues
show
Documentation introduced by
Should the type for parameter $array not be array? Also, consider making the array more specific, something like array<String>, or String[].

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive. In addition it looks for parameters that have the generic type array and suggests a stricter type like array<String>.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
78
     * @return  Validation_Core
79
     */
80
    public function copy(array $array)
81
    {
82
        $copy = clone $this;
83
84
        $copy->exchangeArray($array);
85
86
        return $copy;
87
    }
88
89
    /**
90
     * Test if the data has been submitted.
91
     *
92
     * @return  boolean
93
     */
94
    public function submitted($value = null)
95
    {
96
        if (is_bool($value)) {
97
            $this->submitted = $value;
98
        }
99
100
        return $this->submitted;
101
    }
102
103
    /**
104
     * Returns an array of all the field names that have filters, rules, or callbacks.
105
     *
106
     * @return  array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<integer|string>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
107
     */
108
    public function field_names()
109
    {
110
        // All the fields that are being validated
111
        $fields = array_keys(array_merge(
112
            $this->pre_filters,
113
            $this->rules,
114
            $this->callbacks,
115
            $this->post_filters
116
        ));
117
118
        // Remove wildcard fields
119
        $fields = array_diff($fields, array('*'));
120
121
        return $fields;
122
    }
123
124
    /**
125
     * Returns the array values of the current object.
126
     *
127
     * @return  array
128
     */
129
    public function as_array()
130
    {
131
        return $this->getArrayCopy();
132
    }
133
134
    /**
135
     * Returns the ArrayObject values, removing all inputs without rules.
136
     * To choose specific inputs, list the field name as arguments.
137
     *
138
     * @param   boolean  return only fields with filters, rules, and callbacks
139
     * @return  array
140
     */
141
    public function safe_array()
142
    {
143
        // Load choices
144
        $choices = func_get_args();
145
        $choices = empty($choices) ? null : array_combine($choices, $choices);
146
147
        // Get field names
148
        $fields = $this->field_names();
149
150
        $safe = array();
151
        foreach ($fields as $field) {
152
            if ($choices === null or isset($choices[$field])) {
153
                if (isset($this[$field])) {
154
                    $value = $this[$field];
155
156
                    if (is_object($value)) {
157
                        // Convert the value back into an array
158
                        $value = $value->getArrayCopy();
159
                    }
160
                } else {
161
                    // Even if the field is not in this array, it must be set
162
                    $value = null;
163
                }
164
165
                // Add the field to the array
166
                $safe[$field] = $value;
167
            }
168
        }
169
170
        return $safe;
171
    }
172
173
    /**
174
     * Add additional rules that will forced, even for empty fields. All arguments
175
     * passed will be appended to the list.
176
     *
177
     * @chainable
178
     * @param   string   rule name
179
     * @return  Validation_Core
180
     */
181
    public function allow_empty_rules($rules)
0 ignored issues
show
Unused Code introduced by
The parameter $rules is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
182
    {
183
        // Any number of args are supported
184
        $rules = func_get_args();
185
186
        // Merge the allowed rules
187
        $this->empty_rules = array_merge($this->empty_rules, $rules);
188
189
        return $this;
190
    }
191
192
    /**
193
     * Converts a filter, rule, or callback into a fully-qualified callback array.
194
     *
195
     * @return  callable
196
     */
197
    protected function callback($callback)
198
    {
199
        if (is_string($callback)) {
200
            if (strpos($callback, '::') !== false) {
201
                $callback = explode('::', $callback);
202
            } elseif (function_exists($callback)) {
203
                // No need to check if the callback is a method
204
                $callback = $callback;
0 ignored issues
show
Bug introduced by
Why assign $callback to itself?

This checks looks for cases where a variable has been assigned to itself.

This assignement can be removed without consequences.

Loading history...
205
            } elseif (method_exists($this, $callback)) {
206
                // The callback exists in Validation
207
                $callback = array($this, $callback);
208
            } elseif (method_exists('valid', $callback)) {
209
                // The callback exists in valid::
210
                $callback = array('valid', $callback);
211
            }
212
        }
213
214
        if (! is_callable($callback, false)) {
215
            if (is_array($callback)) {
216
                if (is_object($callback[0])) {
217
                    // Object instance syntax
218
                    $name = get_class($callback[0]).'->'.$callback[1];
219
                } else {
220
                    // Static class syntax
221
                    $name = $callback[0].'::'.$callback[1];
222
                }
223
            } else {
224
                // Function syntax
225
                $name = $callback;
226
            }
227
228
            throw new Kohana_Exception('validation.not_callable', $name);
229
        }
230
231
        return $callback;
232
    }
233
234
    /**
235
     * Add a pre-filter to one or more inputs. Pre-filters are applied before
236
     * rules or callbacks are executed.
237
     *
238
     * @chainable
239
     * @param   callback  filter
240
     * @param   string    fields to apply filter to, use TRUE for all fields
241
     * @return  Validation_Core
242
     */
243 View Code Duplication
    public function pre_filter($filter, $field = true)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
244
    {
245
        if ($field === true or $field === '*') {
246
            // Use wildcard
247
            $fields = array('*');
248
        } else {
249
            // Add the filter to specific inputs
250
            $fields = func_get_args();
251
            $fields = array_slice($fields, 1);
252
        }
253
254
        // Convert to a proper callback
255
        $filter = $this->callback($filter);
256
257
        foreach ($fields as $field) {
258
            // Add the filter to specified field
259
            $this->pre_filters[$field][] = $filter;
260
        }
261
262
        return $this;
263
    }
264
265
    /**
266
     * Add a post-filter to one or more inputs. Post-filters are applied after
267
     * rules and callbacks have been executed.
268
     *
269
     * @chainable
270
     * @param   callback  filter
271
     * @param   string    fields to apply filter to, use TRUE for all fields
272
     * @return  Validation_Core
273
     */
274 View Code Duplication
    public function post_filter($filter, $field = true)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
275
    {
276
        if ($field === true) {
277
            // Use wildcard
278
            $fields = array('*');
279
        } else {
280
            // Add the filter to specific inputs
281
            $fields = func_get_args();
282
            $fields = array_slice($fields, 1);
283
        }
284
285
        // Convert to a proper callback
286
        $filter = $this->callback($filter);
287
288
        foreach ($fields as $field) {
289
            // Add the filter to specified field
290
            $this->post_filters[$field][] = $filter;
291
        }
292
293
        return $this;
294
    }
295
296
    /**
297
     * Add rules to a field. Validation rules may only return TRUE or FALSE and
298
     * can not manipulate the value of a field.
299
     *
300
     * @chainable
301
     * @param   string    field name
302
     * @param   callback  rules (one or more arguments)
303
     * @return  Validation_Core
304
     */
305
    public function add_rules($field, $rules)
0 ignored issues
show
Unused Code introduced by
The parameter $rules is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
306
    {
307
        // Get the rules
308
        $rules = func_get_args();
309
        $rules = array_slice($rules, 1);
310
311
        if ($field === true) {
312
            // Use wildcard
313
            $field = '*';
314
        }
315
316
        foreach ($rules as $rule) {
317
            // Arguments for rule
318
            $args = null;
319
320
            if (is_string($rule)) {
321
                if (preg_match('/^([^\[]++)\[(.+)\]$/', $rule, $matches)) {
322
                    // Split the rule into the function and args
323
                    $rule = $matches[1];
324
                    $args = preg_split('/(?<!\\\\),\s*/', $matches[2]);
325
326
                    // Replace escaped comma with comma
327
                    $args = str_replace('\,', ',', $args);
328
                }
329
            }
330
331
            if ($rule === 'is_array') {
332
                // This field is expected to be an array
333
                $this->array_fields[$field] = $field;
334
            }
335
336
            // Convert to a proper callback
337
            $rule = $this->callback($rule);
338
339
            // Add the rule, with args, to the field
340
            $this->rules[$field][] = array($rule, $args);
341
        }
342
343
        return $this;
344
    }
345
346
    /**
347
     * Add callbacks to a field. Callbacks must accept the Validation object
348
     * and the input name. Callback returns are not processed.
349
     *
350
     * @chainable
351
     * @param   string     field name
352
     * @param   callbacks  callbacks (unlimited number)
353
     * @return  Validation_Core
354
     */
355 View Code Duplication
    public function add_callbacks($field, $callbacks)
0 ignored issues
show
Unused Code introduced by
The parameter $callbacks is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
356
    {
357
        // Get all callbacks as an array
358
        $callbacks = func_get_args();
359
        $callbacks = array_slice($callbacks, 1);
360
361
        if ($field === true) {
362
            // Use wildcard
363
            $field = '*';
364
        }
365
366
        foreach ($callbacks as $callback) {
367
            // Convert to a proper callback
368
            $callback = $this->callback($callback);
369
370
            // Add the callback to specified field
371
            $this->callbacks[$field][] = $callback;
372
        }
373
374
        return $this;
375
    }
376
377
    /**
378
     * Validate by processing pre-filters, rules, callbacks, and post-filters.
379
     * All fields that have filters, rules, or callbacks will be initialized if
380
     * they are undefined. Validation will only be run if there is data already
381
     * in the array.
382
     *
383
     * @param   object  Validation object, used only for recursion
0 ignored issues
show
Documentation introduced by
Should the type for parameter $object not be Validation|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
384
     * @param   object  name of field for errors
385
     * @return  bool
386
     */
387
    public function validate($object = null, $field_name = null)
0 ignored issues
show
Unused Code introduced by
The parameter $field_name is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
388
    {
389
        if ($object === null) {
390
            // Use the current object
391
            $object = $this;
0 ignored issues
show
Unused Code introduced by
$object is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
392
        }
393
394
        // Get all field names
395
        $fields = $this->field_names();
396
397
        // Copy the array from the object, to optimize multiple sets
398
        $array = $this->getArrayCopy();
399
400
        foreach ($fields as $field) {
401
            if ($field === '*') {
402
                // Ignore wildcard
403
                continue;
404
            }
405
406
            if (! isset($array[$field])) {
407
                if (isset($this->array_fields[$field])) {
408
                    // This field must be an array
409
                    $array[$field] = array();
410
                } else {
411
                    $array[$field] = null;
412
                }
413
            }
414
        }
415
416
        // Swap the array back into the object
417
        $this->exchangeArray($array);
418
419
        // Get all defined field names
420
        $fields = array_keys($array);
421
422 View Code Duplication
        foreach ($this->pre_filters as $field => $callbacks) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
423
            foreach ($callbacks as $callback) {
424
                if ($field === '*') {
425
                    foreach ($fields as $f) {
426
                        $this[$f] = is_array($this[$f]) ? array_map($callback, $this[$f]) : call_user_func($callback, $this[$f]);
427
                    }
428
                } else {
429
                    $this[$field] = is_array($this[$field]) ? array_map($callback, $this[$field]) : call_user_func($callback, $this[$field]);
430
                }
431
            }
432
        }
433
434
        if ($this->submitted === false) {
435
            return false;
436
        }
437
438
        foreach ($this->rules as $field => $callbacks) {
439
            foreach ($callbacks as $callback) {
440
                // Separate the callback and arguments
441
                list($callback, $args) = $callback;
442
443
                // Function or method name of the rule
444
                $rule = is_array($callback) ? $callback[1] : $callback;
445
446
                if ($field === '*') {
447
                    foreach ($fields as $f) {
448
                        // Note that continue, instead of break, is used when
449
                        // applying rules using a wildcard, so that all fields
450
                        // will be validated.
451
452
                        if (isset($this->errors[$f])) {
453
                            // Prevent other rules from being evaluated if an error has occurred
454
                            continue;
455
                        }
456
457
                        if (empty($this[$f]) and ! in_array($rule, $this->empty_rules)) {
458
                            // This rule does not need to be processed on empty fields
459
                            continue;
460
                        }
461
462 View Code Duplication
                        if ($args === null) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
463
                            if (! call_user_func($callback, $this[$f])) {
464
                                $this->errors[$f] = $rule;
465
466
                                // Stop validating this field when an error is found
467
                                continue;
468
                            }
469
                        } else {
470
                            if (! call_user_func($callback, $this[$f], $args)) {
471
                                $this->errors[$f] = $rule;
472
473
                                // Stop validating this field when an error is found
474
                                continue;
475
                            }
476
                        }
477
                    }
478
                } else {
479
                    if (isset($this->errors[$field])) {
480
                        // Prevent other rules from being evaluated if an error has occurred
481
                        break;
482
                    }
483
484
                    if (! in_array($rule, $this->empty_rules) and ! $this->required($this[$field])) {
485
                        // This rule does not need to be processed on empty fields
486
                        continue;
487
                    }
488
489 View Code Duplication
                    if ($args === null) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
490
                        if (! call_user_func($callback, $this[$field])) {
491
                            $this->errors[$field] = $rule;
492
493
                            // Stop validating this field when an error is found
494
                            break;
495
                        }
496
                    } else {
497
                        if (! call_user_func($callback, $this[$field], $args)) {
498
                            $this->errors[$field] = $rule;
499
500
                            // Stop validating this field when an error is found
501
                            break;
502
                        }
503
                    }
504
                }
505
            }
506
        }
507
508
        foreach ($this->callbacks as $field => $callbacks) {
509
            foreach ($callbacks as $callback) {
510
                if ($field === '*') {
511
                    foreach ($fields as $f) {
512
                        // Note that continue, instead of break, is used when
513
                        // applying rules using a wildcard, so that all fields
514
                        // will be validated.
515
516
                        if (isset($this->errors[$f])) {
517
                            // Stop validating this field when an error is found
518
                            continue;
519
                        }
520
521
                        call_user_func($callback, $this, $f);
522
                    }
523
                } else {
524
                    if (isset($this->errors[$field])) {
525
                        // Stop validating this field when an error is found
526
                        break;
527
                    }
528
529
                    call_user_func($callback, $this, $field);
530
                }
531
            }
532
        }
533
534 View Code Duplication
        foreach ($this->post_filters as $field => $callbacks) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
535
            foreach ($callbacks as $callback) {
536
                if ($field === '*') {
537
                    foreach ($fields as $f) {
538
                        $this[$f] = is_array($this[$f]) ? array_map($callback, $this[$f]) : call_user_func($callback, $this[$f]);
539
                    }
540
                } else {
541
                    $this[$field] = is_array($this[$field]) ? array_map($callback, $this[$field]) : call_user_func($callback, $this[$field]);
542
                }
543
            }
544
        }
545
546
        // Return TRUE if there are no errors
547
        return $this->errors === array();
548
    }
549
550
    /**
551
     * Add an error to an input.
552
     *
553
     * @chainable
554
     * @param   string  input name
555
     * @param   string  unique error name
556
     * @return  Validation_Core
557
     */
558
    public function add_error($field, $name)
559
    {
560
        $this->errors[$field] = $name;
561
562
        return $this;
563
    }
564
565
    /**
566
     * Sets or returns the message for an input.
567
     *
568
     * @chainable
569
     * @param   string   input key
570
     * @param   string   message to set
571
     * @return  string|object
572
     */
573
    public function message($input = null, $message = null)
574
    {
575
        if ($message === null) {
576
            if ($input === null) {
577
                $messages = array();
578
                $keys     = array_keys($this->messages);
579
580
                foreach ($keys as $input) {
581
                    $messages[] = $this->message($input);
582
                }
583
584
                return implode("\n", $messages);
585
            }
586
587
            // Return nothing if no message exists
588
            if (empty($this->messages[$input])) {
589
                return '';
590
            }
591
592
            // Return the HTML message string
593
            return $this->messages[$input];
594
        } else {
595
            $this->messages[$input] = $message;
596
        }
597
598
        return $this;
599
    }
600
601
    /**
602
     * Return the errors array.
603
     *
604
     * @param   boolean  load errors from a lang file
605
     * @return  array
606
     */
607
    public function errors($file = null)
608
    {
609
        if ($file === null) {
610
            return $this->errors;
611
        } else {
612
            $errors = array();
613
            foreach ($this->errors as $input => $error) {
614
                // Key for this input error
615
                $key = "$file.$input.$error";
616
617
                if (($errors[$input] = Kohana::lang($key)) === $key) {
618
                    // Get the default error message
619
                    $errors[$input] = Kohana::lang("$file.$input.default");
620
                }
621
            }
622
623
            return $errors;
624
        }
625
    }
626
627
    /**
628
     * Rule: required. Generates an error if the field has an empty value.
629
     *
630
     * @param   mixed   input value
631
     * @return  bool
632
     */
633
    public function required($str)
634
    {
635
        if (is_object($str) and $str instanceof ArrayObject) {
636
            // Get the array from the ArrayObject
637
            $str = $str->getArrayCopy();
638
        }
639
640
        if (is_array($str)) {
641
            return ! empty($str);
642
        } else {
643
            return ! ($str === '' or $str === null or $str === false);
644
        }
645
    }
646
647
    /**
648
     * Rule: matches. Generates an error if the field does not match one or more
649
     * other fields.
650
     *
651
     * @param   mixed   input value
652
     * @param   array   input names to match against
653
     * @return  bool
654
     */
655
    public function matches($str, array $inputs)
656
    {
657
        foreach ($inputs as $key) {
658
            if ($str !== (isset($this[$key]) ? $this[$key] : null)) {
659
                return false;
660
            }
661
        }
662
663
        return true;
664
    }
665
666
    /**
667
     * Rule: length. Generates an error if the field is too long or too short.
668
     *
669
     * @param   mixed   input value
670
     * @param   array   minimum, maximum, or exact length to match
671
     * @return  bool
672
     */
673
    public function length($str, array $length)
674
    {
675
        if (! is_string($str)) {
676
            return false;
677
        }
678
679
        $size = utf8::strlen($str);
680
        $status = false;
681
682
        if (count($length) > 1) {
683
            list($min, $max) = $length;
684
685
            if ($size >= $min and $size <= $max) {
686
                $status = true;
687
            }
688
        } else {
689
            $status = ($size === (int) $length[0]);
690
        }
691
692
        return $status;
693
    }
694
695
    /**
696
     * Rule: depends_on. Generates an error if the field does not depend on one
697
     * or more other fields.
698
     *
699
     * @param   mixed   field name
700
     * @param   array   field names to check dependency
701
     * @return  bool
702
     */
703
    public function depends_on($field, array $fields)
0 ignored issues
show
Unused Code introduced by
The parameter $field is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
704
    {
705
        foreach ($fields as $depends_on) {
706
            if (! isset($this[$depends_on]) or $this[$depends_on] == null) {
707
                return false;
708
            }
709
        }
710
711
        return true;
712
    }
713
714
    /**
715
     * Rule: chars. Generates an error if the field contains characters outside of the list.
716
     *
717
     * @param   string  field value
718
     * @param   array   allowed characters
719
     * @return  bool
720
     */
721
    public function chars($value, array $chars)
722
    {
723
        return ! preg_match('![^'.implode('', $chars).']!u', $value);
724
    }
725
} // End Validation
726