Validator::requirePresence()   A
last analyzed

Complexity

Conditions 4
Paths 6

Size

Total Lines 23

Duplication

Lines 23
Ratio 100 %

Importance

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