ValidatorAwareTrait.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (http://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. (http://cakefoundation.org)
  11. * @link http://cakephp.org CakePHP(tm) Project
  12. * @since 3.0.3
  13. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Validation;
  16. use Cake\Event\EventDispatcherInterface;
  17. use RuntimeException;
  18. /**
  19. * A trait that provides methods for building and
  20. * interacting with Validators.
  21. *
  22. * This trait is useful when building ORM like features where
  23. * the implementing class wants to build and customize a variety
  24. * of validator instances.
  25. *
  26. * This trait expects that classes including it define two constants:
  27. *
  28. * - `DEFAULT_VALIDATOR` - The default validator name.
  29. * - `VALIDATOR_PROVIDER_NAME ` - The provider name the including class is assigned
  30. * in validators.
  31. *
  32. * If the including class also implements events the `Model.buildValidator` event
  33. * will be triggered when validators are created.
  34. */
  35. trait ValidatorAwareTrait
  36. {
  37. /**
  38. * Validator class.
  39. *
  40. * @var string
  41. */
  42. protected $_validatorClass = '\Cake\Validation\Validator';
  43. /**
  44. * A list of validation objects indexed by name
  45. *
  46. * @var array
  47. */
  48. protected $_validators = [];
  49. /**
  50. * Returns the validation rules tagged with $name. It is possible to have
  51. * multiple different named validation sets, this is useful when you need
  52. * to use varying rules when saving from different routines in your system.
  53. *
  54. * There are two different ways of creating and naming validation sets: by
  55. * creating a new method inside your own Table subclass, or by building
  56. * the validator object yourself and storing it using this method.
  57. *
  58. * For example, if you wish to create a validation set called 'forSubscription',
  59. * you will need to create a method in your Table subclass as follows:
  60. *
  61. * ```
  62. * public function validationForSubscription($validator)
  63. * {
  64. * return $validator
  65. * ->add('email', 'valid-email', ['rule' => 'email'])
  66. * ->add('password', 'valid', ['rule' => 'notBlank'])
  67. * ->requirePresence('username');
  68. * }
  69. * ```
  70. *
  71. * Otherwise, you can build the object by yourself and store it in the Table object:
  72. *
  73. * ```
  74. * $validator = new \Cake\Validation\Validator($table);
  75. * $validator
  76. * ->add('email', 'valid-email', ['rule' => 'email'])
  77. * ->add('password', 'valid', ['rule' => 'notBlank'])
  78. * ->allowEmpty('bio');
  79. * $table->validator('forSubscription', $validator);
  80. * ```
  81. *
  82. * You can implement the method in `validationDefault` in your Table subclass
  83. * should you wish to have a validation set that applies in cases where no other
  84. * set is specified.
  85. *
  86. * @param string|null $name the name of the validation set to return
  87. * @param \Cake\Validation\Validator|null $validator The validator instance to store,
  88. * use null to get a validator.
  89. * @return \Cake\Validation\Validator
  90. * @throws \RuntimeException
  91. */
  92. public function validator($name = null, Validator $validator = null)
  93. {
  94. if ($name === null) {
  95. $name = self::DEFAULT_VALIDATOR;
  96. }
  97. if ($validator === null && isset($this->_validators[$name])) {
  98. return $this->_validators[$name];
  99. }
  100. if ($validator === null) {
  101. $validator = new $this->_validatorClass;
  102. $validator = $this->{'validation' . ucfirst($name)}($validator);
  103. if ($this instanceof EventDispatcherInterface) {
  104. $this->dispatchEvent('Model.buildValidator', compact('validator', 'name'));
  105. }
  106. if (!$validator instanceof Validator) {
  107. throw new RuntimeException(sprintf('The %s::%s() validation method must return an instance of %s.', __CLASS__, 'validation' . ucfirst($name), Validator::class));
  108. }
  109. }
  110. $validator->provider(self::VALIDATOR_PROVIDER_NAME, $this);
  111. return $this->_validators[$name] = $validator;
  112. }
  113. /**
  114. * Returns the default validator object. Subclasses can override this function
  115. * to add a default validation set to the validator object.
  116. *
  117. * @param \Cake\Validation\Validator $validator The validator that can be modified to
  118. * add some rules to it.
  119. * @return \Cake\Validation\Validator
  120. */
  121. public function validationDefault(Validator $validator)
  122. {
  123. return $validator;
  124. }
  125. }