CakePHP
  • Documentation
    • Book
    • API
    • Videos
    • Logos & Trademarks
  • Business Solutions
  • Swag
  • Road Trip
  • Team
  • Community
    • Community
    • Team
    • Issues (Github)
    • YouTube Channel
    • Get Involved
    • Bakery
    • Featured Resources
    • Newsletter
    • Certification
    • My CakePHP
    • CakeFest
    • Facebook
    • Twitter
    • Help & Support
    • Forum
    • Stack Overflow
    • IRC
    • Slack
    • Paid Support
CakePHP

C CakePHP 3.8 Red Velvet API

  • Overview
  • Tree
  • Deprecated
  • Version:
    • 3.8
      • 3.8
      • 3.7
      • 3.6
      • 3.5
      • 3.4
      • 3.3
      • 3.2
      • 3.1
      • 3.0
      • 2.10
      • 2.9
      • 2.8
      • 2.7
      • 2.6
      • 2.5
      • 2.4
      • 2.3
      • 2.2
      • 2.1
      • 2.0
      • 1.3
      • 1.2

Namespaces

  • Cake
    • Auth
      • Storage
    • Cache
      • Engine
    • Collection
      • Iterator
    • Command
    • Console
      • Exception
    • Controller
      • Component
      • Exception
    • Core
      • Configure
        • Engine
      • Exception
      • Retry
    • Database
      • Driver
      • Exception
      • Expression
      • Schema
      • Statement
      • Type
    • Datasource
      • Exception
    • Error
      • Middleware
    • Event
      • Decorator
    • Filesystem
    • Form
    • Http
      • Client
        • Adapter
        • Auth
      • Cookie
      • Exception
      • Middleware
      • Session
    • I18n
      • Formatter
      • Middleware
      • Parser
    • Log
      • Engine
    • Mailer
      • Exception
      • Transport
    • Network
      • Exception
    • ORM
      • Association
      • Behavior
        • Translate
      • Exception
      • Locator
      • Rule
    • Routing
      • Exception
      • Filter
      • Middleware
      • Route
    • Shell
      • Helper
      • Task
    • TestSuite
      • Fixture
      • Stub
    • Utility
      • Exception
    • Validation
    • View
      • Exception
      • Form
      • Helper
      • Widget
  • None

Classes

  • RulesProvider
  • Validation
  • ValidationRule
  • ValidationSet
  • Validator

Interfaces

  • ValidatableInterface
  • ValidatorAwareInterface

Traits

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

Generated using CakePHP API Docs