Completed
Push — master ( 14b1fe...69643f )
by Mark
04:01
created

Validator::notEmptyDate()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 3
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
4
 * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
5
 *
6
 * Licensed under The MIT License
7
 * For full copyright and license information, please see the LICENSE.txt
8
 * Redistributions of files must retain the above copyright notice.
9
 *
10
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
11
 * @link          https://cakephp.org CakePHP(tm) Project
12
 * @since         2.2.0
13
 * @license       https://opensource.org/licenses/mit-license.php MIT License
14
 */
15
namespace Cake\Validation;
16
17
use ArrayAccess;
18
use ArrayIterator;
19
use Countable;
20
use InvalidArgumentException;
21
use IteratorAggregate;
22
23
/**
24
 * Validator object encapsulates all methods related to data validations for a model
25
 * It also provides an API to dynamically change validation rules for each model field.
26
 *
27
 * Implements ArrayAccess to easily modify rules in the set
28
 *
29
 * @link https://book.cakephp.org/3.0/en/core-libraries/validation.html
30
 */
31
class Validator implements ArrayAccess, IteratorAggregate, Countable
32
{
33
    /**
34
     * Used to flag nested rules created with addNested() and addNestedMany()
35
     *
36
     * @var string
37
     */
38
    const NESTED = '_nested';
39
40
    /**
41
     * A flag for allowEmptyFor()
42
     *
43
     * When an empty string is given, it will be recognized as empty.
44
     *
45
     * @var int
46
     */
47
    const EMPTY_STRING = 1;
48
49
    /**
50
     * A flag for allowEmptyFor()
51
     *
52
     * When an empty array is given, it will be recognized as empty.
53
     *
54
     * @var int
55
     */
56
    const EMPTY_ARRAY = 2;
57
58
    /**
59
     * A flag for allowEmptyFor()
60
     *
61
     * When an array is given, if it has at least the `name`, `type`, `tmp_name` and `error` keys,
62
     * and the value of `error` is equal to `UPLOAD_ERR_NO_FILE`, the value will be recognized as
63
     * empty.
64
     *
65
     * @var int
66
     */
67
    const EMPTY_FILE = 4;
68
69
    /**
70
     * A flag for allowEmptyFor()
71
     *
72
     * When an array is given, if it contains the `year` key, and only empty strings
73
     * or null values, it will be recognized as empty.
74
     *
75
     * @var int
76
     */
77
    const EMPTY_DATE = 8;
78
79
    /**
80
     * A flag for allowEmptyFor()
81
     *
82
     * When an array is given, if it contains the `hour` key, and only empty strings
83
     * or null values, it will be recognized as empty.
84
     *
85
     * @var int
86
     */
87
    const EMPTY_TIME = 16;
88
89
    /**
90
     * A combination of the all EMPTY_* flags
91
     *
92
     * @var int
93
     */
94
    const EMPTY_ALL = self::EMPTY_STRING | self::EMPTY_ARRAY | self::EMPTY_FILE | self::EMPTY_DATE | self::EMPTY_TIME;
95
96
    /**
97
     * Holds the ValidationSet objects array
98
     *
99
     * @var array
100
     */
101
    protected $_fields = [];
102
103
    /**
104
     * An associative array of objects or classes containing methods
105
     * used for validation
106
     *
107
     * @var array
108
     */
109
    protected $_providers = [];
110
111
    /**
112
     * An associative array of objects or classes used as a default provider list
113
     *
114
     * @var array
115
     */
116
    protected static $_defaultProviders = [];
117
118
    /**
119
     * Contains the validation messages associated with checking the presence
120
     * for each corresponding field.
121
     *
122
     * @var array
123
     */
124
    protected $_presenceMessages = [];
125
126
    /**
127
     * Whether or not to use I18n functions for translating default error messages
128
     *
129
     * @var bool
130
     */
131
    protected $_useI18n = false;
132
133
    /**
134
     * Contains the validation messages associated with checking the emptiness
135
     * for each corresponding field.
136
     *
137
     * @var array
138
     */
139
    protected $_allowEmptyMessages = [];
140
141
    /**
142
     * Contains the flags which specify what is empty for each corresponding field.
143
     *
144
     * @var array
145
     */
146
    protected $_allowEmptyFlags = [];
147
148
    /**
149
     * Constructor
150
     *
151
     */
152
    public function __construct()
153
    {
154
        $this->_useI18n = function_exists('__d');
155
        $this->_providers = self::$_defaultProviders;
156
    }
157
158
    /**
159
     * Returns an array of fields that have failed validation. On the current model. This method will
160
     * actually run validation rules over data, not just return the messages.
161
     *
162
     * @param array $data The data to be checked for errors
163
     * @param bool $newRecord whether the data to be validated is new or to be updated.
164
     * @return array Array of invalid fields
165
     */
166
    public function errors(array $data, $newRecord = true)
167
    {
168
        $errors = [];
169
170
        foreach ($this->_fields as $name => $field) {
171
            $keyPresent = array_key_exists($name, $data);
172
173
            $providers = $this->_providers;
174
            $context = compact('data', 'newRecord', 'field', 'providers');
175
176
            if (!$keyPresent && !$this->_checkPresence($field, $context)) {
177
                $errors[$name]['_required'] = $this->getRequiredMessage($name);
178
                continue;
179
            }
180
            if (!$keyPresent) {
181
                continue;
182
            }
183
184
            $canBeEmpty = $this->_canBeEmpty($field, $context);
185
186
            $flags = static::EMPTY_ALL;
187
            if (isset($this->_allowEmptyFlags[$name])) {
188
                $flags = $this->_allowEmptyFlags[$name];
189
            }
190
191
            $isEmpty = $this->isEmpty($data[$name], $flags);
192
193
            if (!$canBeEmpty && $isEmpty) {
194
                $errors[$name]['_empty'] = $this->getNotEmptyMessage($name);
195
                continue;
196
            }
197
198
            if ($isEmpty) {
199
                continue;
200
            }
201
202
            $result = $this->_processRules($name, $field, $data, $newRecord);
203
            if ($result) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $result of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
204
                $errors[$name] = $result;
205
            }
206
        }
207
208
        return $errors;
209
    }
210
211
    /**
212
     * Returns a ValidationSet object containing all validation rules for a field, if
213
     * passed a ValidationSet as second argument, it will replace any other rule set defined
214
     * before
215
     *
216
     * @param string $name [optional] The fieldname to fetch.
217
     * @param \Cake\Validation\ValidationSet|null $set The set of rules for field
218
     * @return \Cake\Validation\ValidationSet
219
     */
220
    public function field($name, ValidationSet $set = null)
221
    {
222
        if (empty($this->_fields[$name])) {
223
            $set = $set ?: new ValidationSet();
224
            $this->_fields[$name] = $set;
225
        }
226
227
        return $this->_fields[$name];
228
    }
229
230
    /**
231
     * Check whether or not a validator contains any rules for the given field.
232
     *
233
     * @param string $name The field name to check.
234
     * @return bool
235
     */
236
    public function hasField($name)
237
    {
238
        return isset($this->_fields[$name]);
239
    }
240
241
    /**
242
     * Associates an object to a name so it can be used as a provider. Providers are
243
     * objects or class names that can contain methods used during validation of for
244
     * deciding whether a validation rule can be applied. All validation methods,
245
     * when called will receive the full list of providers stored in this validator.
246
     *
247
     * @param string $name The name under which the provider should be set.
248
     * @param object|string $object Provider object or class name.
249
     * @return $this
250
     */
251
    public function setProvider($name, $object)
252
    {
253
        $this->_providers[$name] = $object;
254
255
        return $this;
256
    }
257
258
    /**
259
     * Returns the provider stored under that name if it exists.
260
     *
261
     * @param string $name The name under which the provider should be set.
262
     * @return object|string|null
263
     * @throws \ReflectionException
264
     */
265
    public function getProvider($name)
266
    {
267
        if (isset($this->_providers[$name])) {
268
            return $this->_providers[$name];
269
        }
270
        if ($name !== 'default') {
271
            return null;
272
        }
273
274
        $this->_providers[$name] = new RulesProvider();
275
276
        return $this->_providers[$name];
277
    }
278
279
    /**
280
     * Returns the default provider stored under that name if it exists.
281
     *
282
     * @param string $name The name under which the provider should be retrieved.
283
     * @return object|string|null
284
     */
285
    public static function getDefaultProvider($name)
286
    {
287
        if (!isset(self::$_defaultProviders[$name])) {
288
            return null;
289
        }
290
291
        return self::$_defaultProviders[$name];
292
    }
293
294
    /**
295
     * Associates an object to a name so it can be used as a default provider.
296
     *
297
     * @param string $name The name under which the provider should be set.
298
     * @param object|string $object Provider object or class name.
299
     * @return void
300
     */
301
    public static function addDefaultProvider($name, $object)
302
    {
303
        self::$_defaultProviders[$name] = $object;
304
    }
305
306
    /**
307
     * Get the list of default providers.
308
     *
309
     * @return string[]
310
     */
311
    public static function getDefaultProviders()
312
    {
313
        return array_keys(self::$_defaultProviders);
314
    }
315
316
    /**
317
     * Associates an object to a name so it can be used as a provider. Providers are
318
     * objects or class names that can contain methods used during validation of for
319
     * deciding whether a validation rule can be applied. All validation methods,
320
     * when called will receive the full list of providers stored in this validator.
321
     *
322
     * If called with no arguments, it will return the provider stored under that name if
323
     * it exists, otherwise it returns this instance of chaining.
324
     *
325
     * @deprecated 3.4.0 Use setProvider()/getProvider() instead.
326
     * @param string $name The name under which the provider should be set.
327
     * @param null|object|string $object Provider object or class name.
328
     * @return $this|object|string|null
329
     */
330
    public function provider($name, $object = null)
331
    {
332
        deprecationWarning(
333
            'Validator::provider() is deprecated. ' .
334
            'Use Validator::setProvider()/getProvider() instead.'
335
        );
336
        if ($object !== null) {
337
            return $this->setProvider($name, $object);
338
        }
339
340
        return $this->getProvider($name);
341
    }
342
343
    /**
344
     * Get the list of providers in this validator.
345
     *
346
     * @return string[]
347
     */
348
    public function providers()
349
    {
350
        return array_keys($this->_providers);
351
    }
352
353
    /**
354
     * Returns whether a rule set is defined for a field or not
355
     *
356
     * @param string $field name of the field to check
357
     * @return bool
358
     */
359
    public function offsetExists($field)
360
    {
361
        return isset($this->_fields[$field]);
362
    }
363
364
    /**
365
     * Returns the rule set for a field
366
     *
367
     * @param string $field name of the field to check
368
     * @return \Cake\Validation\ValidationSet
369
     */
370
    public function offsetGet($field)
371
    {
372
        return $this->field($field);
373
    }
374
375
    /**
376
     * Sets the rule set for a field
377
     *
378
     * @param string $field name of the field to set
379
     * @param array|\Cake\Validation\ValidationSet $rules set of rules to apply to field
380
     * @return void
381
     */
382
    public function offsetSet($field, $rules)
383
    {
384
        if (!$rules instanceof ValidationSet) {
385
            $set = new ValidationSet();
386
            foreach ((array)$rules as $name => $rule) {
387
                $set->add($name, $rule);
388
            }
389
        }
390
        $this->_fields[$field] = $rules;
391
    }
392
393
    /**
394
     * Unsets the rule set for a field
395
     *
396
     * @param string $field name of the field to unset
397
     * @return void
398
     */
399
    public function offsetUnset($field)
400
    {
401
        unset($this->_fields[$field]);
402
    }
403
404
    /**
405
     * Returns an iterator for each of the fields to be validated
406
     *
407
     * @return \ArrayIterator
408
     */
409
    public function getIterator()
410
    {
411
        return new ArrayIterator($this->_fields);
412
    }
413
414
    /**
415
     * Returns the number of fields having validation rules
416
     *
417
     * @return int
418
     */
419
    public function count()
420
    {
421
        return count($this->_fields);
422
    }
423
424
    /**
425
     * Adds a new rule to a field's rule set. If second argument is an array
426
     * then rules list for the field will be replaced with second argument and
427
     * third argument will be ignored.
428
     *
429
     * ### Example:
430
     *
431
     * ```
432
     *      $validator
433
     *          ->add('title', 'required', ['rule' => 'notBlank'])
434
     *          ->add('user_id', 'valid', ['rule' => 'numeric', 'message' => 'Invalid User'])
435
     *
436
     *      $validator->add('password', [
437
     *          'size' => ['rule' => ['lengthBetween', 8, 20]],
438
     *          'hasSpecialCharacter' => ['rule' => 'validateSpecialchar', 'message' => 'not valid']
439
     *      ]);
440
     * ```
441
     *
442
     * @param string $field The name of the field from which the rule will be added
443
     * @param array|string $name The alias for a single rule or multiple rules array
444
     * @param array|\Cake\Validation\ValidationRule $rule the rule to add
445
     * @return $this
446
     */
447
    public function add($field, $name, $rule = [])
448
    {
449
        $validationSet = $this->field($field);
450
451
        if (!is_array($name)) {
452
            $rules = [$name => $rule];
453
        } else {
454
            $rules = $name;
455
        }
456
457
        foreach ($rules as $name => $rule) {
458
            if (is_array($rule)) {
459
                $rule += ['rule' => $name];
460
            }
461
            $validationSet->add($name, $rule);
462
        }
463
464
        return $this;
465
    }
466
467
    /**
468
     * Adds a nested validator.
469
     *
470
     * Nesting validators allows you to define validators for array
471
     * types. For example, nested validators are ideal when you want to validate a
472
     * sub-document, or complex array type.
473
     *
474
     * This method assumes that the sub-document has a 1:1 relationship with the parent.
475
     *
476
     * The providers of the parent validator will be synced into the nested validator, when
477
     * errors are checked. This ensures that any validation rule providers connected
478
     * in the parent will have the same values in the nested validator when rules are evaluated.
479
     *
480
     * @param string $field The root field for the nested validator.
481
     * @param \Cake\Validation\Validator $validator The nested validator.
482
     * @param string|null $message The error message when the rule fails.
483
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
484
     *   true when the validation rule should be applied.
485
     * @return $this
486
     */
487
    public function addNested($field, Validator $validator, $message = null, $when = null)
488
    {
489
        $extra = array_filter(['message' => $message, 'on' => $when]);
490
491
        $validationSet = $this->field($field);
492
        $validationSet->add(static::NESTED, $extra + ['rule' => function ($value, $context) use ($validator, $message) {
493
            if (!is_array($value)) {
494
                return false;
495
            }
496
            foreach ($this->providers() as $provider) {
497
                $validator->setProvider($provider, $this->getProvider($provider));
0 ignored issues
show
Bug introduced by
It seems like $this->getProvider($provider) targeting Cake\Validation\Validator::getProvider() can also be of type null; however, Cake\Validation\Validator::setProvider() does only seem to accept object|string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
498
            }
499
            $errors = $validator->errors($value, $context['newRecord']);
500
501
            $message = $message ? [static::NESTED => $message] : [];
0 ignored issues
show
Bug introduced by
Consider using a different name than the imported variable $message, 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...
502
503
            return empty($errors) ? true : $errors + $message;
504
        }]);
505
506
        return $this;
507
    }
508
509
    /**
510
     * Adds a nested validator.
511
     *
512
     * Nesting validators allows you to define validators for array
513
     * types. For example, nested validators are ideal when you want to validate many
514
     * similar sub-documents or complex array types.
515
     *
516
     * This method assumes that the sub-document has a 1:N relationship with the parent.
517
     *
518
     * The providers of the parent validator will be synced into the nested validator, when
519
     * errors are checked. This ensures that any validation rule providers connected
520
     * in the parent will have the same values in the nested validator when rules are evaluated.
521
     *
522
     * @param string $field The root field for the nested validator.
523
     * @param \Cake\Validation\Validator $validator The nested validator.
524
     * @param string|null $message The error message when the rule fails.
525
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
526
     *   true when the validation rule should be applied.
527
     * @return $this
528
     */
529
    public function addNestedMany($field, Validator $validator, $message = null, $when = null)
530
    {
531
        $extra = array_filter(['message' => $message, 'on' => $when]);
532
533
        $validationSet = $this->field($field);
534
        $validationSet->add(static::NESTED, $extra + ['rule' => function ($value, $context) use ($validator, $message) {
535
            if (!is_array($value)) {
536
                return false;
537
            }
538
            foreach ($this->providers() as $provider) {
539
                $validator->setProvider($provider, $this->getProvider($provider));
0 ignored issues
show
Bug introduced by
It seems like $this->getProvider($provider) targeting Cake\Validation\Validator::getProvider() can also be of type null; however, Cake\Validation\Validator::setProvider() does only seem to accept object|string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
540
            }
541
            $errors = [];
542
            foreach ($value as $i => $row) {
543
                if (!is_array($row)) {
544
                    return false;
545
                }
546
                $check = $validator->errors($row, $context['newRecord']);
547
                if (!empty($check)) {
548
                    $errors[$i] = $check;
549
                }
550
            }
551
552
            $message = $message ? [static::NESTED => $message] : [];
0 ignored issues
show
Bug introduced by
Consider using a different name than the imported variable $message, 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...
553
554
            return empty($errors) ? true : $errors + $message;
555
        }]);
556
557
        return $this;
558
    }
559
560
    /**
561
     * Removes a rule from the set by its name
562
     *
563
     * ### Example:
564
     *
565
     * ```
566
     *      $validator
567
     *          ->remove('title', 'required')
568
     *          ->remove('user_id')
569
     * ```
570
     *
571
     * @param string $field The name of the field from which the rule will be removed
572
     * @param string|null $rule the name of the rule to be removed
573
     * @return $this
574
     */
575
    public function remove($field, $rule = null)
576
    {
577
        if ($rule === null) {
578
            unset($this->_fields[$field]);
579
        } else {
580
            $this->field($field)->remove($rule);
581
        }
582
583
        return $this;
584
    }
585
586
    /**
587
     * Sets whether a field is required to be present in data array.
588
     * You can also pass array. Using an array will let you provide the following
589
     * keys:
590
     *
591
     * - `mode` individual mode for field
592
     * - `message` individual error message for field
593
     *
594
     * You can also set mode and message for all passed fields, the individual
595
     * setting takes precedence over group settings.
596
     *
597
     * @param string|array $field the name of the field or list of fields.
598
     * @param bool|string|callable $mode Valid values are true, false, 'create', 'update'.
599
     *   If a callable is passed then the field will be required only when the callback
600
     *   returns true.
601
     * @param string|null $message The message to show if the field presence validation fails.
602
     * @return $this
603
     */
604 View Code Duplication
    public function requirePresence($field, $mode = true, $message = null)
605
    {
606
        $defaults = [
607
            'mode' => $mode,
608
            'message' => $message
609
        ];
610
611
        if (!is_array($field)) {
612
            $field = $this->_convertValidatorToArray($field, $defaults);
613
        }
614
615
        foreach ($field as $fieldName => $setting) {
616
            $settings = $this->_convertValidatorToArray($fieldName, $defaults, $setting);
617
            $fieldName = current(array_keys($settings));
618
619
            $this->field($fieldName)->requirePresence($settings[$fieldName]['mode']);
620
            if ($settings[$fieldName]['message']) {
621
                $this->_presenceMessages[$fieldName] = $settings[$fieldName]['message'];
622
            }
623
        }
624
625
        return $this;
626
    }
627
628
    /**
629
     * Allows a field to be empty. You can also pass array.
630
     * Using an array will let you provide the following keys:
631
     *
632
     * - `when` individual when condition for field
633
     * - 'message' individual message for field
634
     *
635
     * You can also set when and message for all passed fields, the individual setting
636
     * takes precedence over group settings.
637
     *
638
     * This is the opposite of notEmpty() which requires a field to not be empty.
639
     * By using $mode equal to 'create' or 'update', you can allow fields to be empty
640
     * when records are first created, or when they are updated.
641
     *
642
     * ### Example:
643
     *
644
     * ```
645
     * // Email can be empty
646
     * $validator->allowEmpty('email');
647
     *
648
     * // Email can be empty on create
649
     * $validator->allowEmpty('email', 'create');
650
     *
651
     * // Email can be empty on update
652
     * $validator->allowEmpty('email', 'update');
653
     *
654
     * // Email and subject can be empty on update
655
     * $validator->allowEmpty(['email', 'subject'], 'update');
656
     *
657
     * // Email can be always empty, subject and content can be empty on update.
658
     * $validator->allowEmpty(
659
     *      [
660
     *          'email' => [
661
     *              'when' => true
662
     *          ],
663
     *          'content' => [
664
     *              'message' => 'Content cannot be empty'
665
     *          ],
666
     *          'subject'
667
     *      ],
668
     *      'update'
669
     * );
670
     * ```
671
     *
672
     * It is possible to conditionally allow emptiness on a field by passing a callback
673
     * as a second argument. The callback will receive the validation context array as
674
     * argument:
675
     *
676
     * ```
677
     * $validator->allowEmpty('email', function ($context) {
678
     *  return !$context['newRecord'] || $context['data']['role'] === 'admin';
679
     * });
680
     * ```
681
     *
682
     * This method will correctly detect empty file uploads and date/time/datetime fields.
683
     *
684
     * Because this and `notEmpty()` modify the same internal state, the last
685
     * method called will take precedence.
686
     *
687
     * @deprecated 3.7.0 Use allowEmptyString(), allowEmptyArray(), allowEmptyFile(),
688
     *   allowEmptyDate(), allowEmptyTime() or allowEmptyDateTime() instead.
689
     * @param string|array $field the name of the field or a list of fields
690
     * @param bool|string|callable $when Indicates when the field is allowed to be empty
691
     * Valid values are true (always), 'create', 'update'. If a callable is passed then
692
     * the field will allowed to be empty only when the callback returns true.
693
     * @param string|null $message The message to show if the field is not
694
     * @return $this
695
     */
696
    public function allowEmpty($field, $when = true, $message = null)
697
    {
698
        $defaults = [
699
            'when' => $when,
700
            'message' => $message,
701
        ];
702
        if (!is_array($field)) {
703
            $field = $this->_convertValidatorToArray($field, $defaults);
704
        }
705
706
        foreach ($field as $fieldName => $setting) {
707
            $settings = $this->_convertValidatorToArray($fieldName, $defaults, $setting);
708
            $fieldName = array_keys($settings)[0];
709
            $this->allowEmptyFor($fieldName, null, $settings[$fieldName]['when'], $settings[$fieldName]['message']);
710
        }
711
712
        return $this;
713
    }
714
715
    /**
716
     * Low-level method to indicate that a field can be empty.
717
     *
718
     * This method should generally not be used and instead you should
719
     * use:
720
     *
721
     * - `allowEmptyString()`
722
     * - `allowEmptyArray()`
723
     * - `allowEmptyFile()`
724
     * - `allowEmptyDate()`
725
     * - `allowEmptyDatetime()`
726
     * - `allowEmptyTime()`
727
     *
728
     * Should be used as their APIs are simpler to operate and read.
729
     *
730
     * You can also set flags, when and message for all passed fields, the individual
731
     * setting takes precedence over group settings.
732
     *
733
     * ### Example:
734
     *
735
     * ```
736
     * // Email can be empty
737
     * $validator->allowEmptyFor('email', Validator::EMPTY_STRING);
738
     *
739
     * // Email can be empty on create
740
     * $validator->allowEmptyFor('email', Validator::EMPTY_STRING, 'create');
741
     *
742
     * // Email can be empty on update
743
     * $validator->allowEmptyFor('email', Validator::EMPTY_STRING, 'update');
744
     * ```
745
     *
746
     * It is possible to conditionally allow emptiness on a field by passing a callback
747
     * as a second argument. The callback will receive the validation context array as
748
     * argument:
749
     *
750
     * ```
751
     * $validator->allowEmpty('email', Validator::EMPTY_STRING, function ($context) {
752
     *   return !$context['newRecord'] || $context['data']['role'] === 'admin';
753
     * });
754
     * ```
755
     *
756
     * If you want to allow other kind of empty data on a field, you need to pass other
757
     * flags:
758
     *
759
     * ```
760
     * $validator->allowEmptyFor('photo', Validator::EMPTY_FILE);
761
     * $validator->allowEmptyFor('published', Validator::EMPTY_STRING | Validator::EMPTY_DATE | Validator::EMPTY_TIME);
762
     * $validator->allowEmptyFor('items', Validator::EMPTY_STRING | Validator::EMPTY_ARRAY);
763
     * ```
764
     *
765
     * You can also use convenience wrappers of this method. The following calls are the
766
     * same as above:
767
     *
768
     * ```
769
     * $validator->allowEmptyFile('photo');
770
     * $validator->allowEmptyDateTime('published');
771
     * $validator->allowEmptyArray('items');
772
     * ```
773
     *
774
     * @param string $field The name of the field.
775
     * @param int|null $flags A bitmask of EMPTY_* flags which specify what is empty
776
     * @param bool|string|callable $when Indicates when the field is allowed to be empty
777
     * Valid values are true, false, 'create', 'update'. If a callable is passed then
778
     * the field will allowed to be empty only when the callback returns true.
779
     * @param string|null $message The message to show if the field is not
780
     * @since 3.7.0
781
     * @return $this
782
     */
783
    public function allowEmptyFor($field, $flags, $when = true, $message = null)
784
    {
785
        $this->field($field)->allowEmpty($when);
786
        if ($message) {
787
            $this->_allowEmptyMessages[$field] = $message;
788
        }
789
        if ($flags !== null) {
790
            $this->_allowEmptyFlags[$field] = $flags;
791
        }
792
793
        return $this;
794
    }
795
796
    /**
797
     * Compatibility shim for the allowEmpty* methods that enable
798
     * us to support both the `$when, $message` signature (deprecated)
799
     * and the `$message, $when` format which is preferred.
800
     *
801
     * A deprecation warning will be emitted when a deprecated form
802
     * is used.
803
     *
804
     * @param mixed $first The message or when to be sorted.
805
     * @param mixed $second The message or when to be sorted.
806
     * @param string $method The called method
807
     * @return array A list of [$message, $when]
808
     */
809
    protected function sortMessageAndWhen($first, $second, $method)
810
    {
811
        // Called with `$message, $when`. No order change necessary
812
        if ((
813
                in_array($second, [true, false, 'create', 'update'], true) ||
814
                is_callable($second)
815
            ) && (
816
                is_string($first) || $first === null
817
            ) && (
818
                $first !== 'create' && $first !== 'update'
819
            )
820
        ) {
821
            return [$first, $second];
822
        }
823
        deprecationWarning(
824
            "You are using a deprecated argument order for ${method}. " .
825
            "You should reverse the order of your `when` and `message` arguments " .
826
            "so that they are `message, when`."
827
        );
828
829
        // Called without the second argument.
830
        if (is_bool($second)) {
831
            $second = null;
832
        }
833
834
        // Called with `$when, $message`. Reverse the
835
        // order to match the expected return value.
836
        return [$second, $first];
837
    }
838
839
    /**
840
     * Allows a field to be an empty string.
841
     *
842
     * This method is equivalent to calling allowEmptyFor() with EMPTY_STRING flag.
843
     *
844
     * @param string $field The name of the field.
845
     * @param string|null $message The message to show if the field is not
846
     * @param bool|string|callable $when Indicates when the field is allowed to be empty
847
     * Valid values are true, false, 'create', 'update'. If a callable is passed then
848
     * the field will allowed to be empty only when the callback returns true.
849
     * @return $this
850
     * @since 3.7.0
851
     * @see \Cake\Validation\Validator::allowEmptyFor() For detail usage
852
     */
853
    public function allowEmptyString($field, $message = null, $when = true)
854
    {
855
        list($message, $when) = $this->sortMessageAndWhen($message, $when, __METHOD__);
856
857
        return $this->allowEmptyFor($field, self::EMPTY_STRING, $when, $message);
858
    }
859
860
    /**
861
     * Requires a field to be not be an empty string.
862
     *
863
     * Opposite to allowEmptyString()
864
     *
865
     * @param string $field The name of the field.
866
     * @param string|null $message The message to show if the field is empty.
867
     * @param bool|string|callable $when Indicates when the field is not allowed
868
     *   to be empty. Valid values are false (never), 'create', 'update'. If a
869
     *   callable is passed then the field will be required to be not empty when
870
     *   the callback returns true.
871
     * @return $this
872
     * @see \Cake\Validation\Validator::allowEmptyString()
873
     * @since 3.8.0
874
     */
875
    public function notEmptyString($field, $message = null, $when = false)
876
    {
877
        $when = $this->invertWhenClause($when);
878
879
        return $this->allowEmptyFor($field, self::EMPTY_STRING, $when, $message);
880
    }
881
882
    /**
883
     * Allows a field to be an empty array.
884
     *
885
     * This method is equivalent to calling allowEmptyFor() with EMPTY_STRING +
886
     * EMPTY_ARRAY flags.
887
     *
888
     * @param string $field The name of the field.
889
     * @param string|null $message The message to show if the field is not
890
     * @param bool|string|callable $when Indicates when the field is allowed to be empty
891
     * Valid values are true, false, 'create', 'update'. If a callable is passed then
892
     * the field will allowed to be empty only when the callback returns true.
893
     * @return $this
894
     * @since 3.7.0
895
     * @see \Cake\Validation\Validator::allowEmptyFor() for examples.
896
     */
897
    public function allowEmptyArray($field, $message = null, $when = true)
898
    {
899
        list($message, $when) = $this->sortMessageAndWhen($message, $when, __METHOD__);
900
901
        return $this->allowEmptyFor($field, self::EMPTY_STRING | self::EMPTY_ARRAY, $when, $message);
902
    }
903
904
    /**
905
     * Require a field to be a non-empty array
906
     *
907
     * Opposite to allowEmptyArray()
908
     *
909
     * @param string $field The name of the field.
910
     * @param string|null $message The message to show if the field is empty.
911
     * @param bool|string|callable $when Indicates when the field is not allowed
912
     *   to be empty. Valid values are false (never), 'create', 'update'. If a
913
     *   callable is passed then the field will be required to be not empty when
914
     *   the callback returns true.
915
     * @return $this
916
     * @see \Cake\Validation\Validator::allowEmptyArray()
917
     * @since 3.8.0
918
     */
919
    public function notEmptyArray($field, $message = null, $when = false)
920
    {
921
        $when = $this->invertWhenClause($when);
922
923
        return $this->allowEmptyFor($field, self::EMPTY_STRING | self::EMPTY_ARRAY, $when, $message);
924
    }
925
926
    /**
927
     * Allows a field to be an empty file.
928
     *
929
     * This method is equivalent to calling allowEmptyFor() with EMPTY_FILE flag.
930
     * File fields will not accept `''`, or `[]` as empty values. Only `null` and a file
931
     * upload with `error` equal to `UPLOAD_ERR_NO_FILE` will be treated as empty.
932
     *
933
     * @param string $field The name of the field.
934
     * @param string|null $message The message to show if the field is not
935
     * @param bool|string|callable $when Indicates when the field is allowed to be empty
936
     *   Valid values are true, 'create', 'update'. If a callable is passed then
937
     *   the field will allowed to be empty only when the callback returns true.
938
     * @return $this
939
     * @since 3.7.0
940
     * @see \Cake\Validation\Validator::allowEmptyFor() For detail usage
941
     */
942
    public function allowEmptyFile($field, $message = null, $when = true)
943
    {
944
        list($message, $when) = $this->sortMessageAndWhen($message, $when, __METHOD__);
945
946
        return $this->allowEmptyFor($field, self::EMPTY_FILE, $when, $message);
947
    }
948
949
    /**
950
     * Require a field to be a not-empty file.
951
     *
952
     * Opposite to allowEmptyFile()
953
     *
954
     * @param string $field The name of the field.
955
     * @param string|null $message The message to show if the field is empty.
956
     * @param bool|string|callable $when Indicates when the field is not allowed
957
     *   to be empty. Valid values are false (never), 'create', 'update'. If a
958
     *   callable is passed then the field will be required to be not empty when
959
     *   the callback returns true.
960
     * @return $this
961
     * @since 3.8.0
962
     * @see \Cake\Validation\Validator::allowEmptyFile()
963
     */
964
    public function notEmptyFile($field, $message = null, $when = false)
965
    {
966
        $when = $this->invertWhenClause($when);
967
968
        return $this->allowEmptyFor($field, self::EMPTY_FILE, $when, $message);
969
    }
970
971
    /**
972
     * Allows a field to be an empty date.
973
     *
974
     * Empty date values are `null`, `''`, `[]` and arrays where all values are `''`
975
     * and the `year` key is present.
976
     *
977
     * @param string $field The name of the field.
978
     * @param string|null $message The message to show if the field is not
979
     * @param bool|string|callable $when Indicates when the field is allowed to be empty
980
     * Valid values are true, false, 'create', 'update'. If a callable is passed then
981
     * the field will allowed to be empty only when the callback returns true.
982
     * @return $this
983
     * @since 3.7.0
984
     * @see \Cake\Validation\Validator::allowEmptyFor() for examples
985
     */
986
    public function allowEmptyDate($field, $message = null, $when = true)
987
    {
988
        list($message, $when) = $this->sortMessageAndWhen($message, $when, __METHOD__);
989
990
        return $this->allowEmptyFor($field, self::EMPTY_STRING | self::EMPTY_DATE, $when, $message);
991
    }
992
993
    /**
994
     * Require a non-empty date value
995
     *
996
     * @param string $field The name of the field.
997
     * @param string|null $message The message to show if the field is empty.
998
     * @param bool|string|callable $when Indicates when the field is not allowed
999
     *   to be empty. Valid values are false (never), 'create', 'update'. If a
1000
     *   callable is passed then the field will be required to be not empty when
1001
     *   the callback returns true.
1002
     * @return $this
1003
     * @since 3.8.0
1004
     * @see \Cake\Validation\Validator::allowEmptyDate() for examples
1005
     */
1006
    public function notEmptyDate($field, $message = null, $when = false)
1007
    {
1008
        $when = $this->invertWhenClause($when);
1009
1010
        return $this->allowEmptyFor($field, self::EMPTY_STRING | self::EMPTY_DATE, $when, $message);
1011
    }
1012
1013
    /**
1014
     * Allows a field to be an empty time.
1015
     *
1016
     * Empty date values are `null`, `''`, `[]` and arrays where all values are `''`
1017
     * and the `hour` key is present.
1018
     *
1019
     * This method is equivalent to calling allowEmptyFor() with EMPTY_STRING +
1020
     * EMPTY_TIME flags.
1021
     *
1022
     * @param string $field The name of the field.
1023
     * @param string|null $message The message to show if the field is not
1024
     * @param bool|string|callable $when Indicates when the field is allowed to be empty
1025
     * Valid values are true, false, 'create', 'update'. If a callable is passed then
1026
     * the field will allowed to be empty only when the callback returns true.
1027
     * @return $this
1028
     * @since 3.7.0
1029
     * @see \Cake\Validation\Validator::allowEmptyFor() for examples.
1030
     */
1031
    public function allowEmptyTime($field, $message = null, $when = true)
1032
    {
1033
        list($message, $when) = $this->sortMessageAndWhen($message, $when, __METHOD__);
1034
1035
        return $this->allowEmptyFor($field, self::EMPTY_STRING | self::EMPTY_TIME, $when, $message);
1036
    }
1037
1038
    /**
1039
     * Require a field to be a non-empty time.
1040
     *
1041
     * Opposite to allowEmptyTime()
1042
     *
1043
     * @param string $field The name of the field.
1044
     * @param string|null $message The message to show if the field is empty.
1045
     * @param bool|string|callable $when Indicates when the field is not allowed
1046
     *   to be empty. Valid values are false (never), 'create', 'update'. If a
1047
     *   callable is passed then the field will be required to be not empty when
1048
     *   the callback returns true.
1049
     * @return $this
1050
     * @since 3.8.0
1051
     * @see \Cake\Validation\Validator::allowEmptyTime()
1052
     */
1053
    public function notEmptyTime($field, $message = null, $when = false)
1054
    {
1055
        $when = $this->invertWhenClause($when);
1056
1057
        return $this->allowEmptyFor($field, self::EMPTY_STRING | self::EMPTY_TIME, $when, $message);
1058
    }
1059
1060
    /**
1061
     * Allows a field to be an empty date/time.
1062
     *
1063
     * Empty date values are `null`, `''`, `[]` and arrays where all values are `''`
1064
     * and the `year` and `hour` keys are present.
1065
     *
1066
     * This method is equivalent to calling allowEmptyFor() with EMPTY_STRING +
1067
     * EMPTY_DATE + EMPTY_TIME flags.
1068
     *
1069
     * @param string $field The name of the field.
1070
     * @param string|null $message The message to show if the field is not
1071
     * @param bool|string|callable $when Indicates when the field is allowed to be empty
1072
     *   Valid values are true, false, 'create', 'update'. If a callable is passed then
1073
     *   the field will allowed to be empty only when the callback returns false.
1074
     * @return $this
1075
     * @since 3.7.0
1076
     * @see \Cake\Validation\Validator::allowEmptyFor() for examples.
1077
     */
1078
    public function allowEmptyDateTime($field, $message = null, $when = true)
1079
    {
1080
        list($message, $when) = $this->sortMessageAndWhen($message, $when, __METHOD__);
1081
1082
        return $this->allowEmptyFor($field, self::EMPTY_STRING | self::EMPTY_DATE | self::EMPTY_TIME, $when, $message);
1083
    }
1084
1085
    /**
1086
     * Require a field to be a non empty date/time.
1087
     *
1088
     * Opposite to allowEmptyDateTime
1089
     *
1090
     * @param string $field The name of the field.
1091
     * @param string|null $message The message to show if the field is empty.
1092
     * @param bool|string|callable $when Indicates when the field is not allowed
1093
     *   to be empty. Valid values are false (never), 'create', 'update'. If a
1094
     *   callable is passed then the field will be required to be not empty when
1095
     *   the callback returns true.
1096
     * @return $this
1097
     * @since 3.8.0
1098
     * @see \Cake\Validation\Validator::allowEmptyDateTime()
1099
     */
1100
    public function notEmptyDateTime($field, $message = null, $when = true)
1101
    {
1102
        $when = $this->invertWhenClause($when);
1103
1104
        return $this->allowEmptyFor($field, self::EMPTY_STRING | self::EMPTY_DATE | self::EMPTY_TIME, $when, $message);
1105
    }
1106
1107
    /**
1108
     * Converts validator to fieldName => $settings array
1109
     *
1110
     * @param int|string $fieldName name of field
1111
     * @param array $defaults default settings
1112
     * @param string|array $settings settings from data
1113
     * @return array
1114
     */
1115
    protected function _convertValidatorToArray($fieldName, $defaults = [], $settings = [])
1116
    {
1117
        if (is_string($settings)) {
1118
            $fieldName = $settings;
1119
            $settings = [];
1120
        }
1121
        if (!is_array($settings)) {
1122
            throw new InvalidArgumentException(
1123
                sprintf('Invalid settings for "%s". Settings must be an array.', $fieldName)
1124
            );
1125
        }
1126
        $settings += $defaults;
1127
1128
        return [$fieldName => $settings];
1129
    }
1130
1131
    /**
1132
     * Sets a field to require a non-empty value. You can also pass array.
1133
     * Using an array will let you provide the following keys:
1134
     *
1135
     * - `when` individual when condition for field
1136
     * - `message` individual error message for field
1137
     *
1138
     * You can also set `when` and `message` for all passed fields, the individual setting
1139
     * takes precedence over group settings.
1140
     *
1141
     * This is the opposite of `allowEmpty()` which allows a field to be empty.
1142
     * By using $mode equal to 'create' or 'update', you can make fields required
1143
     * when records are first created, or when they are updated.
1144
     *
1145
     * ### Example:
1146
     *
1147
     * ```
1148
     * $message = 'This field cannot be empty';
1149
     *
1150
     * // Email cannot be empty
1151
     * $validator->notEmpty('email');
1152
     *
1153
     * // Email can be empty on update, but not create
1154
     * $validator->notEmpty('email', $message, 'create');
1155
     *
1156
     * // Email can be empty on create, but required on update.
1157
     * $validator->notEmpty('email', $message, 'update');
1158
     *
1159
     * // Email and title can be empty on create, but are required on update.
1160
     * $validator->notEmpty(['email', 'title'], $message, 'update');
1161
     *
1162
     * // Email can be empty on create, title must always be not empty
1163
     * $validator->notEmpty(
1164
     *      [
1165
     *          'email',
1166
     *          'title' => [
1167
     *              'when' => true,
1168
     *              'message' => 'Title cannot be empty'
1169
     *          ]
1170
     *      ],
1171
     *      $message,
1172
     *      'update'
1173
     * );
1174
     * ```
1175
     *
1176
     * It is possible to conditionally disallow emptiness on a field by passing a callback
1177
     * as the third argument. The callback will receive the validation context array as
1178
     * argument:
1179
     *
1180
     * ```
1181
     * $validator->notEmpty('email', 'Email is required', function ($context) {
1182
     *   return $context['newRecord'] && $context['data']['role'] !== 'admin';
1183
     * });
1184
     * ```
1185
     *
1186
     * Because this and `allowEmpty()` modify the same internal state, the last
1187
     * method called will take precedence.
1188
     *
1189
     * @deprecated 3.7.0 Use notEmptyString(), notEmptyArray(), notEmptyFile(),
1190
     *   notEmptyDate(), notEmptyTime() or notEmptyDateTime() instead.
1191
     * @param string|array $field the name of the field or list of fields
1192
     * @param string|null $message The message to show if the field is not
1193
     * @param bool|string|callable $when Indicates when the field is not allowed
1194
     *   to be empty. Valid values are true (always), 'create', 'update'. If a
1195
     *   callable is passed then the field will allowed to be empty only when
1196
     *   the callback returns false.
1197
     * @return $this
1198
     */
1199 View Code Duplication
    public function notEmpty($field, $message = null, $when = false)
1200
    {
1201
        $defaults = [
1202
            'when' => $when,
1203
            'message' => $message
1204
        ];
1205
1206
        if (!is_array($field)) {
1207
            $field = $this->_convertValidatorToArray($field, $defaults);
1208
        }
1209
1210
        foreach ($field as $fieldName => $setting) {
1211
            $settings = $this->_convertValidatorToArray($fieldName, $defaults, $setting);
1212
            $fieldName = current(array_keys($settings));
1213
1214
            $whenSetting = $this->invertWhenClause($settings[$fieldName]['when']);
1215
1216
            $this->field($fieldName)->allowEmpty($whenSetting);
1217
            if ($settings[$fieldName]['message']) {
1218
                $this->_allowEmptyMessages[$fieldName] = $settings[$fieldName]['message'];
1219
            }
1220
        }
1221
1222
        return $this;
1223
    }
1224
1225
    /**
1226
     * Invert a when clause for creating notEmpty rules
1227
     *
1228
     * @param bool|string|callable $when Indicates when the field is not allowed
1229
     *   to be empty. Valid values are true (always), 'create', 'update'. If a
1230
     *   callable is passed then the field will allowed to be empty only when
1231
     *   the callback returns false.
1232
     * @return bool|string|callable
1233
     */
1234
    protected function invertWhenClause($when)
1235
    {
1236
        if ($when === 'create' || $when === 'update') {
1237
            return $when === 'create' ? 'update' : 'create';
1238
        } elseif (is_callable($when)) {
1239
            return function ($context) use ($when) {
1240
                return !$when($context);
1241
            };
1242
        }
1243
1244
        return $when;
1245
    }
1246
1247
    /**
1248
     * Add a notBlank rule to a field.
1249
     *
1250
     * @param string $field The field you want to apply the rule to.
1251
     * @param string|null $message The error message when the rule fails.
1252
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1253
     *   true when the validation rule should be applied.
1254
     * @see \Cake\Validation\Validation::notBlank()
1255
     * @return $this
1256
     */
1257
    public function notBlank($field, $message = null, $when = null)
1258
    {
1259
        $extra = array_filter(['on' => $when, 'message' => $message]);
1260
1261
        return $this->add($field, 'notBlank', $extra + [
1262
            'rule' => 'notBlank',
1263
        ]);
1264
    }
1265
1266
    /**
1267
     * Add an alphanumeric rule to a field.
1268
     *
1269
     * @param string $field The field you want to apply the rule to.
1270
     * @param string|null $message The error message when the rule fails.
1271
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1272
     *   true when the validation rule should be applied.
1273
     * @see \Cake\Validation\Validation::alphaNumeric()
1274
     * @return $this
1275
     */
1276
    public function alphaNumeric($field, $message = null, $when = null)
1277
    {
1278
        $extra = array_filter(['on' => $when, 'message' => $message]);
1279
1280
        return $this->add($field, 'alphaNumeric', $extra + [
1281
            'rule' => 'alphaNumeric',
1282
        ]);
1283
    }
1284
1285
    /**
1286
     * Add an rule that ensures a string length is within a range.
1287
     *
1288
     * @param string $field The field you want to apply the rule to.
1289
     * @param array $range The inclusive minimum and maximum length you want permitted.
1290
     * @param string|null $message The error message when the rule fails.
1291
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1292
     *   true when the validation rule should be applied.
1293
     * @see \Cake\Validation\Validation::alphaNumeric()
1294
     * @return $this
1295
     */
1296 View Code Duplication
    public function lengthBetween($field, array $range, $message = null, $when = null)
1297
    {
1298
        if (count($range) !== 2) {
1299
            throw new InvalidArgumentException('The $range argument requires 2 numbers');
1300
        }
1301
        $extra = array_filter(['on' => $when, 'message' => $message]);
1302
1303
        return $this->add($field, 'lengthBetween', $extra + [
1304
            'rule' => ['lengthBetween', array_shift($range), array_shift($range)],
1305
        ]);
1306
    }
1307
1308
    /**
1309
     * Add a credit card rule to a field.
1310
     *
1311
     * @param string $field The field you want to apply the rule to.
1312
     * @param string $type The type of cards you want to allow. Defaults to 'all'.
1313
     *   You can also supply an array of accepted card types. e.g `['mastercard', 'visa', 'amex']`
1314
     * @param string|null $message The error message when the rule fails.
1315
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1316
     *   true when the validation rule should be applied.
1317
     * @see \Cake\Validation\Validation::creditCard()
1318
     * @return $this
1319
     */
1320 View Code Duplication
    public function creditCard($field, $type = 'all', $message = null, $when = null)
1321
    {
1322
        $extra = array_filter(['on' => $when, 'message' => $message]);
1323
1324
        return $this->add($field, 'creditCard', $extra + [
1325
            'rule' => ['creditCard', $type, true],
1326
        ]);
1327
    }
1328
1329
    /**
1330
     * Add a greater than comparison rule to a field.
1331
     *
1332
     * @param string $field The field you want to apply the rule to.
1333
     * @param int|float $value The value user data must be greater than.
1334
     * @param string|null $message The error message when the rule fails.
1335
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1336
     *   true when the validation rule should be applied.
1337
     * @see \Cake\Validation\Validation::comparison()
1338
     * @return $this
1339
     */
1340 View Code Duplication
    public function greaterThan($field, $value, $message = null, $when = null)
1341
    {
1342
        $extra = array_filter(['on' => $when, 'message' => $message]);
1343
1344
        return $this->add($field, 'greaterThan', $extra + [
1345
            'rule' => ['comparison', Validation::COMPARE_GREATER, $value]
1346
        ]);
1347
    }
1348
1349
    /**
1350
     * Add a greater than or equal to comparison rule to a field.
1351
     *
1352
     * @param string $field The field you want to apply the rule to.
1353
     * @param int|float $value The value user data must be greater than or equal to.
1354
     * @param string|null $message The error message when the rule fails.
1355
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1356
     *   true when the validation rule should be applied.
1357
     * @see \Cake\Validation\Validation::comparison()
1358
     * @return $this
1359
     */
1360 View Code Duplication
    public function greaterThanOrEqual($field, $value, $message = null, $when = null)
1361
    {
1362
        $extra = array_filter(['on' => $when, 'message' => $message]);
1363
1364
        return $this->add($field, 'greaterThanOrEqual', $extra + [
1365
            'rule' => ['comparison', Validation::COMPARE_GREATER_OR_EQUAL, $value]
1366
        ]);
1367
    }
1368
1369
    /**
1370
     * Add a less than comparison rule to a field.
1371
     *
1372
     * @param string $field The field you want to apply the rule to.
1373
     * @param int|float $value The value user data must be less than.
1374
     * @param string|null $message The error message when the rule fails.
1375
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1376
     *   true when the validation rule should be applied.
1377
     * @see \Cake\Validation\Validation::comparison()
1378
     * @return $this
1379
     */
1380 View Code Duplication
    public function lessThan($field, $value, $message = null, $when = null)
1381
    {
1382
        $extra = array_filter(['on' => $when, 'message' => $message]);
1383
1384
        return $this->add($field, 'lessThan', $extra + [
1385
            'rule' => ['comparison', Validation::COMPARE_LESS, $value]
1386
        ]);
1387
    }
1388
1389
    /**
1390
     * Add a less than or equal comparison rule to a field.
1391
     *
1392
     * @param string $field The field you want to apply the rule to.
1393
     * @param int|float $value The value user data must be less than or equal to.
1394
     * @param string|null $message The error message when the rule fails.
1395
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1396
     *   true when the validation rule should be applied.
1397
     * @see \Cake\Validation\Validation::comparison()
1398
     * @return $this
1399
     */
1400 View Code Duplication
    public function lessThanOrEqual($field, $value, $message = null, $when = null)
1401
    {
1402
        $extra = array_filter(['on' => $when, 'message' => $message]);
1403
1404
        return $this->add($field, 'lessThanOrEqual', $extra + [
1405
            'rule' => ['comparison', Validation::COMPARE_LESS_OR_EQUAL, $value]
1406
        ]);
1407
    }
1408
1409
    /**
1410
     * Add a equal to comparison rule to a field.
1411
     *
1412
     * @param string $field The field you want to apply the rule to.
1413
     * @param int|float $value The value user data must be equal to.
1414
     * @param string|null $message The error message when the rule fails.
1415
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1416
     *   true when the validation rule should be applied.
1417
     * @see \Cake\Validation\Validation::comparison()
1418
     * @return $this
1419
     */
1420 View Code Duplication
    public function equals($field, $value, $message = null, $when = null)
1421
    {
1422
        $extra = array_filter(['on' => $when, 'message' => $message]);
1423
1424
        return $this->add($field, 'equals', $extra + [
1425
            'rule' => ['comparison', Validation::COMPARE_EQUAL, $value]
1426
        ]);
1427
    }
1428
1429
    /**
1430
     * Add a not equal to comparison rule to a field.
1431
     *
1432
     * @param string $field The field you want to apply the rule to.
1433
     * @param int|float $value The value user data must be not be equal to.
1434
     * @param string|null $message The error message when the rule fails.
1435
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1436
     *   true when the validation rule should be applied.
1437
     * @see \Cake\Validation\Validation::comparison()
1438
     * @return $this
1439
     */
1440 View Code Duplication
    public function notEquals($field, $value, $message = null, $when = null)
1441
    {
1442
        $extra = array_filter(['on' => $when, 'message' => $message]);
1443
1444
        return $this->add($field, 'notEquals', $extra + [
1445
            'rule' => ['comparison', Validation::COMPARE_NOT_EQUAL, $value]
1446
        ]);
1447
    }
1448
1449
    /**
1450
     * Add a rule to compare two fields to each other.
1451
     *
1452
     * If both fields have the exact same value the rule will pass.
1453
     *
1454
     * @param string $field The field you want to apply the rule to.
1455
     * @param string $secondField The field you want to compare against.
1456
     * @param string|null $message The error message when the rule fails.
1457
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1458
     *   true when the validation rule should be applied.
1459
     * @see \Cake\Validation\Validation::compareFields()
1460
     * @return $this
1461
     */
1462 View Code Duplication
    public function sameAs($field, $secondField, $message = null, $when = null)
1463
    {
1464
        $extra = array_filter(['on' => $when, 'message' => $message]);
1465
1466
        return $this->add($field, 'sameAs', $extra + [
1467
            'rule' => ['compareFields', $secondField, Validation::COMPARE_SAME]
1468
        ]);
1469
    }
1470
1471
    /**
1472
     * Add a rule to compare that two fields have different values.
1473
     *
1474
     * @param string $field The field you want to apply the rule to.
1475
     * @param string $secondField The field you want to compare against.
1476
     * @param string|null $message The error message when the rule fails.
1477
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1478
     *   true when the validation rule should be applied.
1479
     * @see \Cake\Validation\Validation::compareFields()
1480
     * @return $this
1481
     * @since 3.6.0
1482
     */
1483 View Code Duplication
    public function notSameAs($field, $secondField, $message = null, $when = null)
1484
    {
1485
        $extra = array_filter(['on' => $when, 'message' => $message]);
1486
1487
        return $this->add($field, 'notSameAs', $extra + [
1488
            'rule' => ['compareFields', $secondField, Validation::COMPARE_NOT_SAME]
1489
        ]);
1490
    }
1491
1492
    /**
1493
     * Add a rule to compare one field is equal to another.
1494
     *
1495
     * @param string $field The field you want to apply the rule to.
1496
     * @param string $secondField The field you want to compare against.
1497
     * @param string|null $message The error message when the rule fails.
1498
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1499
     *   true when the validation rule should be applied.
1500
     * @see \Cake\Validation\Validation::compareFields()
1501
     * @return $this
1502
     * @since 3.6.0
1503
     */
1504 View Code Duplication
    public function equalToField($field, $secondField, $message = null, $when = null)
1505
    {
1506
        $extra = array_filter(['on' => $when, 'message' => $message]);
1507
1508
        return $this->add($field, 'equalToField', $extra + [
1509
            'rule' => ['compareFields', $secondField, Validation::COMPARE_EQUAL]
1510
        ]);
1511
    }
1512
1513
    /**
1514
     * Add a rule to compare one field is not equal to another.
1515
     *
1516
     * @param string $field The field you want to apply the rule to.
1517
     * @param string $secondField The field you want to compare against.
1518
     * @param string|null $message The error message when the rule fails.
1519
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1520
     *   true when the validation rule should be applied.
1521
     * @see \Cake\Validation\Validation::compareFields()
1522
     * @return $this
1523
     * @since 3.6.0
1524
     */
1525 View Code Duplication
    public function notEqualToField($field, $secondField, $message = null, $when = null)
1526
    {
1527
        $extra = array_filter(['on' => $when, 'message' => $message]);
1528
1529
        return $this->add($field, 'notEqualToField', $extra + [
1530
            'rule' => ['compareFields', $secondField, Validation::COMPARE_NOT_EQUAL]
1531
        ]);
1532
    }
1533
1534
    /**
1535
     * Add a rule to compare one field is greater than another.
1536
     *
1537
     * @param string $field The field you want to apply the rule to.
1538
     * @param string $secondField The field you want to compare against.
1539
     * @param string|null $message The error message when the rule fails.
1540
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1541
     *   true when the validation rule should be applied.
1542
     * @see \Cake\Validation\Validation::compareFields()
1543
     * @return $this
1544
     * @since 3.6.0
1545
     */
1546 View Code Duplication
    public function greaterThanField($field, $secondField, $message = null, $when = null)
1547
    {
1548
        $extra = array_filter(['on' => $when, 'message' => $message]);
1549
1550
        return $this->add($field, 'greaterThanField', $extra + [
1551
            'rule' => ['compareFields', $secondField, Validation::COMPARE_GREATER]
1552
        ]);
1553
    }
1554
1555
    /**
1556
     * Add a rule to compare one field is greater than or equal to another.
1557
     *
1558
     * @param string $field The field you want to apply the rule to.
1559
     * @param string $secondField The field you want to compare against.
1560
     * @param string|null $message The error message when the rule fails.
1561
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1562
     *   true when the validation rule should be applied.
1563
     * @see \Cake\Validation\Validation::compareFields()
1564
     * @return $this
1565
     * @since 3.6.0
1566
     */
1567 View Code Duplication
    public function greaterThanOrEqualToField($field, $secondField, $message = null, $when = null)
1568
    {
1569
        $extra = array_filter(['on' => $when, 'message' => $message]);
1570
1571
        return $this->add($field, 'greaterThanOrEqualToField', $extra + [
1572
            'rule' => ['compareFields', $secondField, Validation::COMPARE_GREATER_OR_EQUAL]
1573
        ]);
1574
    }
1575
1576
    /**
1577
     * Add a rule to compare one field is less than another.
1578
     *
1579
     * @param string $field The field you want to apply the rule to.
1580
     * @param string $secondField The field you want to compare against.
1581
     * @param string|null $message The error message when the rule fails.
1582
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1583
     *   true when the validation rule should be applied.
1584
     * @see \Cake\Validation\Validation::compareFields()
1585
     * @return $this
1586
     * @since 3.6.0
1587
     */
1588 View Code Duplication
    public function lessThanField($field, $secondField, $message = null, $when = null)
1589
    {
1590
        $extra = array_filter(['on' => $when, 'message' => $message]);
1591
1592
        return $this->add($field, 'lessThanField', $extra + [
1593
            'rule' => ['compareFields', $secondField, Validation::COMPARE_LESS]
1594
        ]);
1595
    }
1596
1597
    /**
1598
     * Add a rule to compare one field is less than or equal to another.
1599
     *
1600
     * @param string $field The field you want to apply the rule to.
1601
     * @param string $secondField The field you want to compare against.
1602
     * @param string|null $message The error message when the rule fails.
1603
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1604
     *   true when the validation rule should be applied.
1605
     * @see \Cake\Validation\Validation::compareFields()
1606
     * @return $this
1607
     * @since 3.6.0
1608
     */
1609 View Code Duplication
    public function lessThanOrEqualToField($field, $secondField, $message = null, $when = null)
1610
    {
1611
        $extra = array_filter(['on' => $when, 'message' => $message]);
1612
1613
        return $this->add($field, 'lessThanOrEqualToField', $extra + [
1614
            'rule' => ['compareFields', $secondField, Validation::COMPARE_LESS_OR_EQUAL]
1615
        ]);
1616
    }
1617
1618
    /**
1619
     * Add a rule to check if a field contains non alpha numeric characters.
1620
     *
1621
     * @param string $field The field you want to apply the rule to.
1622
     * @param int $limit The minimum number of non-alphanumeric fields required.
1623
     * @param string|null $message The error message when the rule fails.
1624
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1625
     *   true when the validation rule should be applied.
1626
     * @see \Cake\Validation\Validation::containsNonAlphaNumeric()
1627
     * @return $this
1628
     */
1629 View Code Duplication
    public function containsNonAlphaNumeric($field, $limit = 1, $message = null, $when = null)
1630
    {
1631
        $extra = array_filter(['on' => $when, 'message' => $message]);
1632
1633
        return $this->add($field, 'containsNonAlphaNumeric', $extra + [
1634
            'rule' => ['containsNonAlphaNumeric', $limit]
1635
        ]);
1636
    }
1637
1638
    /**
1639
     * Add a date format validation rule to a field.
1640
     *
1641
     * @param string $field The field you want to apply the rule to.
1642
     * @param array $formats A list of accepted date formats.
1643
     * @param string|null $message The error message when the rule fails.
1644
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1645
     *   true when the validation rule should be applied.
1646
     * @see \Cake\Validation\Validation::date()
1647
     * @return $this
1648
     */
1649 View Code Duplication
    public function date($field, $formats = ['ymd'], $message = null, $when = null)
1650
    {
1651
        $extra = array_filter(['on' => $when, 'message' => $message]);
1652
1653
        return $this->add($field, 'date', $extra + [
1654
            'rule' => ['date', $formats]
1655
        ]);
1656
    }
1657
1658
    /**
1659
     * Add a date time format validation rule to a field.
1660
     *
1661
     * @param string $field The field you want to apply the rule to.
1662
     * @param array $formats A list of accepted date formats.
1663
     * @param string|null $message The error message when the rule fails.
1664
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1665
     *   true when the validation rule should be applied.
1666
     * @see \Cake\Validation\Validation::datetime()
1667
     * @return $this
1668
     */
1669 View Code Duplication
    public function dateTime($field, $formats = ['ymd'], $message = null, $when = null)
1670
    {
1671
        $extra = array_filter(['on' => $when, 'message' => $message]);
1672
1673
        return $this->add($field, 'dateTime', $extra + [
1674
            'rule' => ['datetime', $formats]
1675
        ]);
1676
    }
1677
1678
    /**
1679
     * Add a time format validation rule to a field.
1680
     *
1681
     * @param string $field The field you want to apply the rule to.
1682
     * @param string|null $message The error message when the rule fails.
1683
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1684
     *   true when the validation rule should be applied.
1685
     * @see \Cake\Validation\Validation::time()
1686
     * @return $this
1687
     */
1688
    public function time($field, $message = null, $when = null)
1689
    {
1690
        $extra = array_filter(['on' => $when, 'message' => $message]);
1691
1692
        return $this->add($field, 'time', $extra + [
1693
            'rule' => 'time'
1694
        ]);
1695
    }
1696
1697
    /**
1698
     * Add a localized time, date or datetime format validation rule to a field.
1699
     *
1700
     * @param string $field The field you want to apply the rule to.
1701
     * @param string $type Parser type, one out of 'date', 'time', and 'datetime'
1702
     * @param string|null $message The error message when the rule fails.
1703
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1704
     *   true when the validation rule should be applied.
1705
     * @see \Cake\Validation\Validation::localizedTime()
1706
     * @return $this
1707
     */
1708 View Code Duplication
    public function localizedTime($field, $type = 'datetime', $message = null, $when = null)
1709
    {
1710
        $extra = array_filter(['on' => $when, 'message' => $message]);
1711
1712
        return $this->add($field, 'localizedTime', $extra + [
1713
            'rule' => ['localizedTime', $type]
1714
        ]);
1715
    }
1716
1717
    /**
1718
     * Add a boolean validation rule to a field.
1719
     *
1720
     * @param string $field The field you want to apply the rule to.
1721
     * @param string|null $message The error message when the rule fails.
1722
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1723
     *   true when the validation rule should be applied.
1724
     * @see \Cake\Validation\Validation::boolean()
1725
     * @return $this
1726
     */
1727
    public function boolean($field, $message = null, $when = null)
1728
    {
1729
        $extra = array_filter(['on' => $when, 'message' => $message]);
1730
1731
        return $this->add($field, 'boolean', $extra + [
1732
            'rule' => 'boolean'
1733
        ]);
1734
    }
1735
1736
    /**
1737
     * Add a decimal validation rule to a field.
1738
     *
1739
     * @param string $field The field you want to apply the rule to.
1740
     * @param int|null $places The number of decimal places to require.
1741
     * @param string|null $message The error message when the rule fails.
1742
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1743
     *   true when the validation rule should be applied.
1744
     * @see \Cake\Validation\Validation::decimal()
1745
     * @return $this
1746
     */
1747 View Code Duplication
    public function decimal($field, $places = null, $message = null, $when = null)
1748
    {
1749
        $extra = array_filter(['on' => $when, 'message' => $message]);
1750
1751
        return $this->add($field, 'decimal', $extra + [
1752
            'rule' => ['decimal', $places]
1753
        ]);
1754
    }
1755
1756
    /**
1757
     * Add an email validation rule to a field.
1758
     *
1759
     * @param string $field The field you want to apply the rule to.
1760
     * @param bool $checkMX Whether or not to check the MX records.
1761
     * @param string|null $message The error message when the rule fails.
1762
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1763
     *   true when the validation rule should be applied.
1764
     * @see \Cake\Validation\Validation::email()
1765
     * @return $this
1766
     */
1767 View Code Duplication
    public function email($field, $checkMX = false, $message = null, $when = null)
1768
    {
1769
        $extra = array_filter(['on' => $when, 'message' => $message]);
1770
1771
        return $this->add($field, 'email', $extra + [
1772
            'rule' => ['email', $checkMX]
1773
        ]);
1774
    }
1775
1776
    /**
1777
     * Add an IP validation rule to a field.
1778
     *
1779
     * This rule will accept both IPv4 and IPv6 addresses.
1780
     *
1781
     * @param string $field The field you want to apply the rule to.
1782
     * @param string|null $message The error message when the rule fails.
1783
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1784
     *   true when the validation rule should be applied.
1785
     * @see \Cake\Validation\Validation::ip()
1786
     * @return $this
1787
     */
1788
    public function ip($field, $message = null, $when = null)
1789
    {
1790
        $extra = array_filter(['on' => $when, 'message' => $message]);
1791
1792
        return $this->add($field, 'ip', $extra + [
1793
            'rule' => 'ip'
1794
        ]);
1795
    }
1796
1797
    /**
1798
     * Add an IPv4 validation rule to a field.
1799
     *
1800
     * @param string $field The field you want to apply the rule to.
1801
     * @param string|null $message The error message when the rule fails.
1802
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1803
     *   true when the validation rule should be applied.
1804
     * @see \Cake\Validation\Validation::ip()
1805
     * @return $this
1806
     */
1807
    public function ipv4($field, $message = null, $when = null)
1808
    {
1809
        $extra = array_filter(['on' => $when, 'message' => $message]);
1810
1811
        return $this->add($field, 'ipv4', $extra + [
1812
            'rule' => ['ip', 'ipv4']
1813
        ]);
1814
    }
1815
1816
    /**
1817
     * Add an IPv6 validation rule to a field.
1818
     *
1819
     * @param string $field The field you want to apply the rule to.
1820
     * @param string|null $message The error message when the rule fails.
1821
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1822
     *   true when the validation rule should be applied.
1823
     * @see \Cake\Validation\Validation::ip()
1824
     * @return $this
1825
     */
1826
    public function ipv6($field, $message = null, $when = null)
1827
    {
1828
        $extra = array_filter(['on' => $when, 'message' => $message]);
1829
1830
        return $this->add($field, 'ipv6', $extra + [
1831
            'rule' => ['ip', 'ipv6']
1832
        ]);
1833
    }
1834
1835
    /**
1836
     * Add a string length validation rule to a field.
1837
     *
1838
     * @param string $field The field you want to apply the rule to.
1839
     * @param int $min The minimum length required.
1840
     * @param string|null $message The error message when the rule fails.
1841
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1842
     *   true when the validation rule should be applied.
1843
     * @see \Cake\Validation\Validation::minLength()
1844
     * @return $this
1845
     */
1846
    public function minLength($field, $min, $message = null, $when = null)
1847
    {
1848
        $extra = array_filter(['on' => $when, 'message' => $message]);
1849
1850
        return $this->add($field, 'minLength', $extra + [
1851
            'rule' => ['minLength', $min]
1852
        ]);
1853
    }
1854
1855
    /**
1856
     * Add a string length validation rule to a field.
1857
     *
1858
     * @param string $field The field you want to apply the rule to.
1859
     * @param int $min The minimum length required.
1860
     * @param string|null $message The error message when the rule fails.
1861
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1862
     *   true when the validation rule should be applied.
1863
     * @see \Cake\Validation\Validation::minLengthBytes()
1864
     * @return $this
1865
     */
1866
    public function minLengthBytes($field, $min, $message = null, $when = null)
1867
    {
1868
        $extra = array_filter(['on' => $when, 'message' => $message]);
1869
1870
        return $this->add($field, 'minLengthBytes', $extra + [
1871
            'rule' => ['minLengthBytes', $min]
1872
        ]);
1873
    }
1874
1875
    /**
1876
     * Add a string length validation rule to a field.
1877
     *
1878
     * @param string $field The field you want to apply the rule to.
1879
     * @param int $max The maximum length allowed.
1880
     * @param string|null $message The error message when the rule fails.
1881
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1882
     *   true when the validation rule should be applied.
1883
     * @see \Cake\Validation\Validation::maxLength()
1884
     * @return $this
1885
     */
1886
    public function maxLength($field, $max, $message = null, $when = null)
1887
    {
1888
        $extra = array_filter(['on' => $when, 'message' => $message]);
1889
1890
        return $this->add($field, 'maxLength', $extra + [
1891
            'rule' => ['maxLength', $max]
1892
        ]);
1893
    }
1894
1895
    /**
1896
     * Add a string length validation rule to a field.
1897
     *
1898
     * @param string $field The field you want to apply the rule to.
1899
     * @param int $max The maximum length allowed.
1900
     * @param string|null $message The error message when the rule fails.
1901
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1902
     *   true when the validation rule should be applied.
1903
     * @see \Cake\Validation\Validation::maxLengthBytes()
1904
     * @return $this
1905
     */
1906
    public function maxLengthBytes($field, $max, $message = null, $when = null)
1907
    {
1908
        $extra = array_filter(['on' => $when, 'message' => $message]);
1909
1910
        return $this->add($field, 'maxLengthBytes', $extra + [
1911
            'rule' => ['maxLengthBytes', $max]
1912
        ]);
1913
    }
1914
1915
    /**
1916
     * Add a numeric value validation rule to a field.
1917
     *
1918
     * @param string $field The field you want to apply the rule to.
1919
     * @param string|null $message The error message when the rule fails.
1920
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1921
     *   true when the validation rule should be applied.
1922
     * @see \Cake\Validation\Validation::numeric()
1923
     * @return $this
1924
     */
1925
    public function numeric($field, $message = null, $when = null)
1926
    {
1927
        $extra = array_filter(['on' => $when, 'message' => $message]);
1928
1929
        return $this->add($field, 'numeric', $extra + [
1930
            'rule' => 'numeric'
1931
        ]);
1932
    }
1933
1934
    /**
1935
     * Add a natural number validation rule to a field.
1936
     *
1937
     * @param string $field The field you want to apply the rule to.
1938
     * @param string|null $message The error message when the rule fails.
1939
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1940
     *   true when the validation rule should be applied.
1941
     * @see \Cake\Validation\Validation::naturalNumber()
1942
     * @return $this
1943
     */
1944 View Code Duplication
    public function naturalNumber($field, $message = null, $when = null)
1945
    {
1946
        $extra = array_filter(['on' => $when, 'message' => $message]);
1947
1948
        return $this->add($field, 'naturalNumber', $extra + [
1949
            'rule' => ['naturalNumber', false]
1950
        ]);
1951
    }
1952
1953
    /**
1954
     * Add a validation rule to ensure a field is a non negative integer.
1955
     *
1956
     * @param string $field The field you want to apply the rule to.
1957
     * @param string|null $message The error message when the rule fails.
1958
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1959
     *   true when the validation rule should be applied.
1960
     * @see \Cake\Validation\Validation::naturalNumber()
1961
     * @return $this
1962
     */
1963 View Code Duplication
    public function nonNegativeInteger($field, $message = null, $when = null)
1964
    {
1965
        $extra = array_filter(['on' => $when, 'message' => $message]);
1966
1967
        return $this->add($field, 'nonNegativeInteger', $extra + [
1968
            'rule' => ['naturalNumber', true]
1969
        ]);
1970
    }
1971
1972
    /**
1973
     * Add a validation rule to ensure a field is within a numeric range
1974
     *
1975
     * @param string $field The field you want to apply the rule to.
1976
     * @param array $range The inclusive upper and lower bounds of the valid range.
1977
     * @param string|null $message The error message when the rule fails.
1978
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
1979
     *   true when the validation rule should be applied.
1980
     * @see \Cake\Validation\Validation::range()
1981
     * @return $this
1982
     */
1983 View Code Duplication
    public function range($field, array $range, $message = null, $when = null)
1984
    {
1985
        if (count($range) !== 2) {
1986
            throw new InvalidArgumentException('The $range argument requires 2 numbers');
1987
        }
1988
        $extra = array_filter(['on' => $when, 'message' => $message]);
1989
1990
        return $this->add($field, 'range', $extra + [
1991
            'rule' => ['range', array_shift($range), array_shift($range)]
1992
        ]);
1993
    }
1994
1995
    /**
1996
     * Add a validation rule to ensure a field is a URL.
1997
     *
1998
     * This validator does not require a protocol.
1999
     *
2000
     * @param string $field The field you want to apply the rule to.
2001
     * @param string|null $message The error message when the rule fails.
2002
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
2003
     *   true when the validation rule should be applied.
2004
     * @see \Cake\Validation\Validation::url()
2005
     * @return $this
2006
     */
2007 View Code Duplication
    public function url($field, $message = null, $when = null)
2008
    {
2009
        $extra = array_filter(['on' => $when, 'message' => $message]);
2010
2011
        return $this->add($field, 'url', $extra + [
2012
            'rule' => ['url', false]
2013
        ]);
2014
    }
2015
2016
    /**
2017
     * Add a validation rule to ensure a field is a URL.
2018
     *
2019
     * This validator requires the URL to have a protocol.
2020
     *
2021
     * @param string $field The field you want to apply the rule to.
2022
     * @param string|null $message The error message when the rule fails.
2023
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
2024
     *   true when the validation rule should be applied.
2025
     * @see \Cake\Validation\Validation::url()
2026
     * @return $this
2027
     */
2028 View Code Duplication
    public function urlWithProtocol($field, $message = null, $when = null)
2029
    {
2030
        $extra = array_filter(['on' => $when, 'message' => $message]);
2031
2032
        return $this->add($field, 'urlWithProtocol', $extra + [
2033
            'rule' => ['url', true]
2034
        ]);
2035
    }
2036
2037
    /**
2038
     * Add a validation rule to ensure the field value is within a whitelist.
2039
     *
2040
     * @param string $field The field you want to apply the rule to.
2041
     * @param array $list The list of valid options.
2042
     * @param string|null $message The error message when the rule fails.
2043
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
2044
     *   true when the validation rule should be applied.
2045
     * @see \Cake\Validation\Validation::inList()
2046
     * @return $this
2047
     */
2048
    public function inList($field, array $list, $message = null, $when = null)
2049
    {
2050
        $extra = array_filter(['on' => $when, 'message' => $message]);
2051
2052
        return $this->add($field, 'inList', $extra + [
2053
            'rule' => ['inList', $list]
2054
        ]);
2055
    }
2056
2057
    /**
2058
     * Add a validation rule to ensure the field is a UUID
2059
     *
2060
     * @param string $field The field you want to apply the rule to.
2061
     * @param string|null $message The error message when the rule fails.
2062
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
2063
     *   true when the validation rule should be applied.
2064
     * @see \Cake\Validation\Validation::uuid()
2065
     * @return $this
2066
     */
2067
    public function uuid($field, $message = null, $when = null)
2068
    {
2069
        $extra = array_filter(['on' => $when, 'message' => $message]);
2070
2071
        return $this->add($field, 'uuid', $extra + [
2072
            'rule' => 'uuid'
2073
        ]);
2074
    }
2075
2076
    /**
2077
     * Add a validation rule to ensure the field is an uploaded file
2078
     *
2079
     * For options see Cake\Validation\Validation::uploadedFile()
2080
     *
2081
     * @param string $field The field you want to apply the rule to.
2082
     * @param array $options An array of options.
2083
     * @param string|null $message The error message when the rule fails.
2084
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
2085
     *   true when the validation rule should be applied.
2086
     * @see \Cake\Validation\Validation::uploadedFile()
2087
     * @return $this
2088
     */
2089
    public function uploadedFile($field, array $options, $message = null, $when = null)
2090
    {
2091
        $extra = array_filter(['on' => $when, 'message' => $message]);
2092
2093
        return $this->add($field, 'uploadedFile', $extra + [
2094
            'rule' => ['uploadedFile', $options]
2095
        ]);
2096
    }
2097
2098
    /**
2099
     * Add a validation rule to ensure the field is a lat/long tuple.
2100
     *
2101
     * e.g. `<lat>, <lng>`
2102
     *
2103
     * @param string $field The field you want to apply the rule to.
2104
     * @param string|null $message The error message when the rule fails.
2105
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
2106
     *   true when the validation rule should be applied.
2107
     * @see \Cake\Validation\Validation::uuid()
2108
     * @return $this
2109
     */
2110
    public function latLong($field, $message = null, $when = null)
2111
    {
2112
        $extra = array_filter(['on' => $when, 'message' => $message]);
2113
2114
        return $this->add($field, 'latLong', $extra + [
2115
            'rule' => 'geoCoordinate'
2116
        ]);
2117
    }
2118
2119
    /**
2120
     * Add a validation rule to ensure the field is a latitude.
2121
     *
2122
     * @param string $field The field you want to apply the rule to.
2123
     * @param string|null $message The error message when the rule fails.
2124
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
2125
     *   true when the validation rule should be applied.
2126
     * @see \Cake\Validation\Validation::latitude()
2127
     * @return $this
2128
     */
2129
    public function latitude($field, $message = null, $when = null)
2130
    {
2131
        $extra = array_filter(['on' => $when, 'message' => $message]);
2132
2133
        return $this->add($field, 'latitude', $extra + [
2134
            'rule' => 'latitude'
2135
        ]);
2136
    }
2137
2138
    /**
2139
     * Add a validation rule to ensure the field is a longitude.
2140
     *
2141
     * @param string $field The field you want to apply the rule to.
2142
     * @param string|null $message The error message when the rule fails.
2143
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
2144
     *   true when the validation rule should be applied.
2145
     * @see \Cake\Validation\Validation::longitude()
2146
     * @return $this
2147
     */
2148
    public function longitude($field, $message = null, $when = null)
2149
    {
2150
        $extra = array_filter(['on' => $when, 'message' => $message]);
2151
2152
        return $this->add($field, 'longitude', $extra + [
2153
            'rule' => 'longitude'
2154
        ]);
2155
    }
2156
2157
    /**
2158
     * Add a validation rule to ensure a field contains only ascii bytes
2159
     *
2160
     * @param string $field The field you want to apply the rule to.
2161
     * @param string|null $message The error message when the rule fails.
2162
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
2163
     *   true when the validation rule should be applied.
2164
     * @see \Cake\Validation\Validation::ascii()
2165
     * @return $this
2166
     */
2167
    public function ascii($field, $message = null, $when = null)
2168
    {
2169
        $extra = array_filter(['on' => $when, 'message' => $message]);
2170
2171
        return $this->add($field, 'ascii', $extra + [
2172
            'rule' => 'ascii'
2173
        ]);
2174
    }
2175
2176
    /**
2177
     * Add a validation rule to ensure a field contains only BMP utf8 bytes
2178
     *
2179
     * @param string $field The field you want to apply the rule to.
2180
     * @param string|null $message The error message when the rule fails.
2181
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
2182
     *   true when the validation rule should be applied.
2183
     * @see \Cake\Validation\Validation::utf8()
2184
     * @return $this
2185
     */
2186 View Code Duplication
    public function utf8($field, $message = null, $when = null)
2187
    {
2188
        $extra = array_filter(['on' => $when, 'message' => $message]);
2189
2190
        return $this->add($field, 'utf8', $extra + [
2191
            'rule' => ['utf8', ['extended' => false]]
2192
        ]);
2193
    }
2194
2195
    /**
2196
     * Add a validation rule to ensure a field contains only utf8 bytes.
2197
     *
2198
     * This rule will accept 3 and 4 byte UTF8 sequences, which are necessary for emoji.
2199
     *
2200
     * @param string $field The field you want to apply the rule to.
2201
     * @param string|null $message The error message when the rule fails.
2202
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
2203
     *   true when the validation rule should be applied.
2204
     * @see \Cake\Validation\Validation::utf8()
2205
     * @return $this
2206
     */
2207 View Code Duplication
    public function utf8Extended($field, $message = null, $when = null)
2208
    {
2209
        $extra = array_filter(['on' => $when, 'message' => $message]);
2210
2211
        return $this->add($field, 'utf8Extended', $extra + [
2212
            'rule' => ['utf8', ['extended' => true]]
2213
        ]);
2214
    }
2215
2216
    /**
2217
     * Add a validation rule to ensure a field is an integer value.
2218
     *
2219
     * @param string $field The field you want to apply the rule to.
2220
     * @param string|null $message The error message when the rule fails.
2221
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
2222
     *   true when the validation rule should be applied.
2223
     * @see \Cake\Validation\Validation::isInteger()
2224
     * @return $this
2225
     */
2226
    public function integer($field, $message = null, $when = null)
2227
    {
2228
        $extra = array_filter(['on' => $when, 'message' => $message]);
2229
2230
        return $this->add($field, 'integer', $extra + [
2231
            'rule' => 'isInteger'
2232
        ]);
2233
    }
2234
2235
    /**
2236
     * Add a validation rule to ensure that a field contains an array.
2237
     *
2238
     * @param string $field The field you want to apply the rule to.
2239
     * @param string|null $message The error message when the rule fails.
2240
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
2241
     *   true when the validation rule should be applied.
2242
     * @see \Cake\Validation\Validation::isArray()
2243
     * @return $this
2244
     */
2245
    public function isArray($field, $message = null, $when = null)
2246
    {
2247
        $extra = array_filter(['on' => $when, 'message' => $message]);
2248
2249
        return $this->add($field, 'isArray', $extra + [
2250
                'rule' => 'isArray'
2251
            ]);
2252
    }
2253
2254
    /**
2255
     * Add a validation rule to ensure that a field contains a scalar.
2256
     *
2257
     * @param string $field The field you want to apply the rule to.
2258
     * @param string|null $message The error message when the rule fails.
2259
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
2260
     *   true when the validation rule should be applied.
2261
     * @see \Cake\Validation\Validation::isScalar()
2262
     * @return $this
2263
     */
2264
    public function scalar($field, $message = null, $when = null)
2265
    {
2266
        $extra = array_filter(['on' => $when, 'message' => $message]);
2267
2268
        return $this->add($field, 'scalar', $extra + [
2269
                'rule' => 'isScalar'
2270
            ]);
2271
    }
2272
2273
    /**
2274
     * Add a validation rule to ensure a field is a 6 digits hex color value.
2275
     *
2276
     * @param string $field The field you want to apply the rule to.
2277
     * @param string|null $message The error message when the rule fails.
2278
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
2279
     *   true when the validation rule should be applied.
2280
     * @see \Cake\Validation\Validation::hexColor()
2281
     * @return $this
2282
     */
2283
    public function hexColor($field, $message = null, $when = null)
2284
    {
2285
        $extra = array_filter(['on' => $when, 'message' => $message]);
2286
2287
        return $this->add($field, 'hexColor', $extra + [
2288
            'rule' => 'hexColor',
2289
        ]);
2290
    }
2291
2292
    /**
2293
     * Add a validation rule for a multiple select. Comparison is case sensitive by default.
2294
     *
2295
     * @param string $field The field you want to apply the rule to.
2296
     * @param array $options The options for the validator. Includes the options defined in
2297
     *   \Cake\Validation\Validation::multiple() and the `caseInsensitive` parameter.
2298
     * @param string|null $message The error message when the rule fails.
2299
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
2300
     *   true when the validation rule should be applied.
2301
     * @see \Cake\Validation\Validation::multiple()
2302
     * @return $this
2303
     */
2304
    public function multipleOptions($field, array $options = [], $message = null, $when = null)
2305
    {
2306
        $extra = array_filter(['on' => $when, 'message' => $message]);
2307
        $caseInsensitive = isset($options['caseInsensitive']) ? $options['caseInsensitive'] : false;
2308
        unset($options['caseInsensitive']);
2309
2310
        return $this->add($field, 'multipleOptions', $extra + [
2311
            'rule' => ['multiple', $options, $caseInsensitive]
2312
        ]);
2313
    }
2314
2315
    /**
2316
     * Add a validation rule to ensure that a field is an array containing at least
2317
     * the specified amount of elements
2318
     *
2319
     * @param string $field The field you want to apply the rule to.
2320
     * @param int $count The number of elements the array should at least have
2321
     * @param string|null $message The error message when the rule fails.
2322
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
2323
     *   true when the validation rule should be applied.
2324
     * @see \Cake\Validation\Validation::numElements()
2325
     * @return $this
2326
     */
2327 View Code Duplication
    public function hasAtLeast($field, $count, $message = null, $when = null)
2328
    {
2329
        $extra = array_filter(['on' => $when, 'message' => $message]);
2330
2331
        return $this->add($field, 'hasAtLeast', $extra + [
2332
            'rule' => function ($value) use ($count) {
2333
                if (is_array($value) && isset($value['_ids'])) {
2334
                    $value = $value['_ids'];
2335
                }
2336
2337
                return Validation::numElements($value, Validation::COMPARE_GREATER_OR_EQUAL, $count);
2338
            }
2339
        ]);
2340
    }
2341
2342
    /**
2343
     * Add a validation rule to ensure that a field is an array containing at most
2344
     * the specified amount of elements
2345
     *
2346
     * @param string $field The field you want to apply the rule to.
2347
     * @param int $count The number maximum amount of elements the field should have
2348
     * @param string|null $message The error message when the rule fails.
2349
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
2350
     *   true when the validation rule should be applied.
2351
     * @see \Cake\Validation\Validation::numElements()
2352
     * @return $this
2353
     */
2354 View Code Duplication
    public function hasAtMost($field, $count, $message = null, $when = null)
2355
    {
2356
        $extra = array_filter(['on' => $when, 'message' => $message]);
2357
2358
        return $this->add($field, 'hasAtMost', $extra + [
2359
            'rule' => function ($value) use ($count) {
2360
                if (is_array($value) && isset($value['_ids'])) {
2361
                    $value = $value['_ids'];
2362
                }
2363
2364
                return Validation::numElements($value, Validation::COMPARE_LESS_OR_EQUAL, $count);
2365
            }
2366
        ]);
2367
    }
2368
2369
    /**
2370
     * Returns whether or not a field can be left empty for a new or already existing
2371
     * record.
2372
     *
2373
     * @param string $field Field name.
2374
     * @param bool $newRecord whether the data to be validated is new or to be updated.
2375
     * @return bool
2376
     */
2377 View Code Duplication
    public function isEmptyAllowed($field, $newRecord)
2378
    {
2379
        $providers = $this->_providers;
2380
        $data = [];
2381
        $context = compact('data', 'newRecord', 'field', 'providers');
2382
2383
        return $this->_canBeEmpty($this->field($field), $context);
2384
    }
2385
2386
    /**
2387
     * Returns whether or not a field can be left out for a new or already existing
2388
     * record.
2389
     *
2390
     * @param string $field Field name.
2391
     * @param bool $newRecord Whether the data to be validated is new or to be updated.
2392
     * @return bool
2393
     */
2394 View Code Duplication
    public function isPresenceRequired($field, $newRecord)
2395
    {
2396
        $providers = $this->_providers;
2397
        $data = [];
2398
        $context = compact('data', 'newRecord', 'field', 'providers');
2399
2400
        return !$this->_checkPresence($this->field($field), $context);
2401
    }
2402
2403
    /**
2404
     * Returns whether or not a field matches against a regular expression.
2405
     *
2406
     * @param string $field Field name.
2407
     * @param string $regex Regular expression.
2408
     * @param string|null $message The error message when the rule fails.
2409
     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
2410
     *   true when the validation rule should be applied.
2411
     * @return $this
2412
     */
2413
    public function regex($field, $regex, $message = null, $when = null)
2414
    {
2415
        $extra = array_filter(['on' => $when, 'message' => $message]);
2416
2417
        return $this->add($field, 'regex', $extra + [
2418
            'rule' => ['custom', $regex]
2419
        ]);
2420
    }
2421
2422
    /**
2423
     * Gets the required message for a field
2424
     *
2425
     * @param string $field Field name
2426
     * @return string|null
2427
     */
2428
    public function getRequiredMessage($field)
2429
    {
2430
        if (!isset($this->_fields[$field])) {
2431
            return null;
2432
        }
2433
2434
        $defaultMessage = 'This field is required';
2435
        if ($this->_useI18n) {
2436
            $defaultMessage = __d('cake', 'This field is required');
2437
        }
2438
2439
        return isset($this->_presenceMessages[$field])
2440
            ? $this->_presenceMessages[$field]
2441
            : $defaultMessage;
2442
    }
2443
2444
    /**
2445
     * Gets the notEmpty message for a field
2446
     *
2447
     * @param string $field Field name
2448
     * @return string|null
2449
     */
2450
    public function getNotEmptyMessage($field)
2451
    {
2452
        if (!isset($this->_fields[$field])) {
2453
            return null;
2454
        }
2455
2456
        $defaultMessage = 'This field cannot be left empty';
2457
        if ($this->_useI18n) {
2458
            $defaultMessage = __d('cake', 'This field cannot be left empty');
2459
        }
2460
2461
        $notBlankMessage = null;
2462
        foreach ($this->_fields[$field] as $rule) {
2463
            if ($rule->get('rule') === 'notBlank' && $rule->get('message')) {
2464
                return $rule->get('message');
2465
            }
2466
        }
2467
2468
        return isset($this->_allowEmptyMessages[$field])
2469
            ? $this->_allowEmptyMessages[$field]
2470
            : $defaultMessage;
2471
    }
2472
2473
    /**
2474
     * Returns false if any validation for the passed rule set should be stopped
2475
     * due to the field missing in the data array
2476
     *
2477
     * @param \Cake\Validation\ValidationSet $field The set of rules for a field.
2478
     * @param array $context A key value list of data containing the validation context.
2479
     * @return bool
2480
     */
2481 View Code Duplication
    protected function _checkPresence($field, $context)
2482
    {
2483
        $required = $field->isPresenceRequired();
2484
2485
        if (!is_string($required) && is_callable($required)) {
2486
            return !$required($context);
2487
        }
2488
2489
        $newRecord = $context['newRecord'];
2490
        if (in_array($required, ['create', 'update'], true)) {
2491
            return (
2492
                ($required === 'create' && !$newRecord) ||
2493
                ($required === 'update' && $newRecord)
2494
            );
2495
        }
2496
2497
        return !$required;
2498
    }
2499
2500
    /**
2501
     * Returns whether the field can be left blank according to `allowEmpty`
2502
     *
2503
     * @param \Cake\Validation\ValidationSet $field the set of rules for a field
2504
     * @param array $context a key value list of data containing the validation context.
2505
     * @return bool
2506
     */
2507 View Code Duplication
    protected function _canBeEmpty($field, $context)
2508
    {
2509
        $allowed = $field->isEmptyAllowed();
0 ignored issues
show
Bug Compatibility introduced by
The expression $field->isEmptyAllowed(); of type boolean|callable adds the type string to the return on line 2523 which is incompatible with the return type documented by Cake\Validation\Validator::_canBeEmpty of type boolean.
Loading history...
2510
2511
        if (!is_string($allowed) && is_callable($allowed)) {
2512
            return $allowed($context);
2513
        }
2514
2515
        $newRecord = $context['newRecord'];
2516
        if (in_array($allowed, ['create', 'update'], true)) {
2517
            $allowed = (
2518
                ($allowed === 'create' && $newRecord) ||
2519
                ($allowed === 'update' && !$newRecord)
2520
            );
2521
        }
2522
2523
        return $allowed;
2524
    }
2525
2526
    /**
2527
     * Returns true if the field is empty in the passed data array
2528
     *
2529
     * @param mixed $data Value to check against.
2530
     * @return bool
2531
     * @deprecated 3.7.0 Use isEmpty() instead
2532
     */
2533
    protected function _fieldIsEmpty($data)
2534
    {
2535
        return $this->isEmpty($data, static::EMPTY_ALL);
2536
    }
2537
2538
    /**
2539
     * Returns true if the field is empty in the passed data array
2540
     *
2541
     * @param mixed $data Value to check against.
2542
     * @param int $flags A bitmask of EMPTY_* flags which specify what is empty
2543
     * @return bool
2544
     */
2545
    protected function isEmpty($data, $flags)
2546
    {
2547
        if ($data === null) {
2548
            return true;
2549
        }
2550
2551
        if ($data === '' && ($flags & self::EMPTY_STRING)) {
2552
            return true;
2553
        }
2554
2555
        $arrayTypes = self::EMPTY_ARRAY | self::EMPTY_DATE | self::EMPTY_TIME;
2556
        if ($data === [] && ($flags & $arrayTypes)) {
2557
            return true;
2558
        }
2559
2560
        if (is_array($data)) {
2561
            if (($flags & self::EMPTY_FILE)
2562
                && isset($data['name'], $data['type'], $data['tmp_name'], $data['error'])
2563
                && (int)$data['error'] === UPLOAD_ERR_NO_FILE
2564
            ) {
2565
                return true;
2566
            }
2567
2568
            $allFieldsAreEmpty = true;
2569
            foreach ($data as $field) {
2570
                if ($field !== null && $field !== '') {
2571
                    $allFieldsAreEmpty = false;
2572
                    break;
2573
                }
2574
            }
2575
2576
            if ($allFieldsAreEmpty) {
2577
                if (($flags & self::EMPTY_DATE) && isset($data['year'])) {
2578
                    return true;
2579
                }
2580
2581
                if (($flags & self::EMPTY_TIME) && isset($data['hour'])) {
2582
                    return true;
2583
                }
2584
            }
2585
        }
2586
2587
        return false;
2588
    }
2589
2590
    /**
2591
     * Iterates over each rule in the validation set and collects the errors resulting
2592
     * from executing them
2593
     *
2594
     * @param string $field The name of the field that is being processed
2595
     * @param \Cake\Validation\ValidationSet $rules the list of rules for a field
2596
     * @param array $data the full data passed to the validator
2597
     * @param bool $newRecord whether is it a new record or an existing one
2598
     * @return array
2599
     */
2600
    protected function _processRules($field, ValidationSet $rules, $data, $newRecord)
2601
    {
2602
        $errors = [];
2603
        // Loading default provider in case there is none
2604
        $this->getProvider('default');
2605
        $message = 'The provided value is invalid';
2606
2607
        if ($this->_useI18n) {
2608
            $message = __d('cake', 'The provided value is invalid');
2609
        }
2610
2611
        foreach ($rules as $name => $rule) {
2612
            $result = $rule->process($data[$field], $this->_providers, compact('newRecord', 'data', 'field'));
2613
            if ($result === true) {
2614
                continue;
2615
            }
2616
2617
            $errors[$name] = $message;
2618
            if (is_array($result) && $name === static::NESTED) {
2619
                $errors = $result;
2620
            }
2621
            if (is_string($result)) {
2622
                $errors[$name] = $result;
2623
            }
2624
2625
            if ($rule->isLast()) {
2626
                break;
2627
            }
2628
        }
2629
2630
        return $errors;
2631
    }
2632
2633
    /**
2634
     * Get the printable version of this object.
2635
     *
2636
     * @return array
2637
     */
2638
    public function __debugInfo()
2639
    {
2640
        $fields = [];
2641
        foreach ($this->_fields as $name => $fieldSet) {
2642
            $fields[$name] = [
2643
                'isPresenceRequired' => $fieldSet->isPresenceRequired(),
2644
                'isEmptyAllowed' => $fieldSet->isEmptyAllowed(),
2645
                'rules' => array_keys($fieldSet->rules()),
2646
            ];
2647
        }
2648
2649
        return [
2650
            '_presenceMessages' => $this->_presenceMessages,
2651
            '_allowEmptyMessages' => $this->_allowEmptyMessages,
2652
            '_allowEmptyFlags' => $this->_allowEmptyFlags,
2653
            '_useI18n' => $this->_useI18n,
2654
            '_providers' => array_keys($this->_providers),
2655
            '_fields' => $fields
2656
        ];
2657
    }
2658
}
2659