Skip to content

Commit

Permalink
Extract validator logic into a trait.
Browse files Browse the repository at this point in the history
Having these methods in a trait will let us not copy + paste code into
the elastic search plugin. It could also be useful for other datasource
plugins that need validation features.
  • Loading branch information
markstory committed Apr 18, 2015
1 parent c17c1ab commit a6a2eb3
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 79 deletions.
81 changes: 2 additions & 79 deletions src/ORM/Table.php
Expand Up @@ -37,7 +37,7 @@
use Cake\ORM\RulesChecker;
use Cake\ORM\Rule\IsUnique;
use Cake\Utility\Inflector;
use Cake\Validation\Validator;
use Cake\Validation\ValidatorAwareTrait;
use InvalidArgumentException;
use RuntimeException;

Expand Down Expand Up @@ -121,6 +121,7 @@ class Table implements RepositoryInterface, EventListenerInterface
{

use EventManagerTrait;
use ValidatorAwareTrait;

/**
* Name of default validation set.
Expand Down Expand Up @@ -200,13 +201,6 @@ class Table implements RepositoryInterface, EventListenerInterface
*/
protected $_registryAlias;

/**
* A list of validation objects indexed by name
*
* @var array
*/
protected $_validators = [];

/**
* The domain rules to be applied to entities saved by this table
*
Expand Down Expand Up @@ -1161,77 +1155,6 @@ public function updateAll($fields, $conditions)
return $statement->rowCount();
}

/**
* Returns the validation rules tagged with $name. It is possible to have
* multiple different named validation sets, this is useful when you need
* to use varying rules when saving from different routines in your system.
*
* There are two different ways of creating and naming validation sets: by
* creating a new method inside your own Table subclass, or by building
* the validator object yourself and storing it using this method.
*
* For example, if you wish to create a validation set called 'forSubscription',
* you will need to create a method in your Table subclass as follows:
*
* ```
* public function validationForSubscription($validator)
* {
* return $validator
* ->add('email', 'valid-email', ['rule' => 'email'])
* ->add('password', 'valid', ['rule' => 'notEmpty'])
* ->requirePresence('username');
* }
* ```
*
* Otherwise, you can build the object by yourself and store it in the Table object:
*
* ```
* $validator = new \Cake\Validation\Validator($table);
* $validator
* ->add('email', 'valid-email', ['rule' => 'email'])
* ->add('password', 'valid', ['rule' => 'notEmpty'])
* ->allowEmpty('bio');
* $table->validator('forSubscription', $validator);
* ```
*
* You can implement the method in `validationDefault` in your Table subclass
* should you wish to have a validation set that applies in cases where no other
* set is specified.
*
* @param string $name the name of the validation set to return
* @param \Cake\Validation\Validator|null $validator The validator instance to store,
* use null to get a validator.
* @return \Cake\Validation\Validator
*/
public function validator($name = self::DEFAULT_VALIDATOR, Validator $validator = null)
{
if ($validator === null && isset($this->_validators[$name])) {
return $this->_validators[$name];
}

if ($validator === null) {
$validator = new Validator();
$validator = $this->{'validation' . ucfirst($name)}($validator);
$this->dispatchEvent('Model.buildValidator', compact('validator', 'name'));
}

$validator->provider('table', $this);
return $this->_validators[$name] = $validator;
}

/**
* Returns the default validator object. Subclasses can override this function
* to add a default validation set to the validator object.
*
* @param \Cake\Validation\Validator $validator The validator that can be modified to
* add some rules to it.
* @return \Cake\Validation\Validator
*/
public function validationDefault(Validator $validator)
{
return $validator;
}

/**
* {@inheritDoc}
*/
Expand Down
108 changes: 108 additions & 0 deletions src/Validation/ValidatorAwareTrait.php
@@ -0,0 +1,108 @@
<?php
/**
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since 3.0.3
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Validation;

use Cake\Validation\Validator;

/**
* A trait that provides methods for building and
* interacting with Validators.
*
* This trait is useful when building ORM like features where
* the implementing class wants to build and customize a variety
* of validator instances.
*/
trait ValidatorAwareTrait
{
/**
* A list of validation objects indexed by name
*
* @var array
*/
protected $_validators = [];

/**
* Returns the validation rules tagged with $name. It is possible to have
* multiple different named validation sets, this is useful when you need
* to use varying rules when saving from different routines in your system.
*
* There are two different ways of creating and naming validation sets: by
* creating a new method inside your own Table subclass, or by building
* the validator object yourself and storing it using this method.
*
* For example, if you wish to create a validation set called 'forSubscription',
* you will need to create a method in your Table subclass as follows:
*
* ```
* public function validationForSubscription($validator)
* {
* return $validator
* ->add('email', 'valid-email', ['rule' => 'email'])
* ->add('password', 'valid', ['rule' => 'notEmpty'])
* ->requirePresence('username');
* }
* ```
*
* Otherwise, you can build the object by yourself and store it in the Table object:
*
* ```
* $validator = new \Cake\Validation\Validator($table);
* $validator
* ->add('email', 'valid-email', ['rule' => 'email'])
* ->add('password', 'valid', ['rule' => 'notEmpty'])
* ->allowEmpty('bio');
* $table->validator('forSubscription', $validator);
* ```
*
* You can implement the method in `validationDefault` in your Table subclass
* should you wish to have a validation set that applies in cases where no other
* set is specified.
*
* @param string $name the name of the validation set to return
* @param \Cake\Validation\Validator|null $validator The validator instance to store,
* use null to get a validator.
* @return \Cake\Validation\Validator
*/
public function validator($name = self::DEFAULT_VALIDATOR, Validator $validator = null)
{
if ($validator === null && isset($this->_validators[$name])) {
return $this->_validators[$name];
}

if ($validator === null) {
$validator = new Validator();
$validator = $this->{'validation' . ucfirst($name)}($validator);
if (method_exists($this, 'dispatchEvent')) {
$this->dispatchEvent('Model.buildValidator', compact('validator', 'name'));
}
}

$validator->provider('table', $this);
return $this->_validators[$name] = $validator;
}

/**
* Returns the default validator object. Subclasses can override this function
* to add a default validation set to the validator object.
*
* @param \Cake\Validation\Validator $validator The validator that can be modified to
* add some rules to it.
* @return \Cake\Validation\Validator
*/
public function validationDefault(Validator $validator)
{
return $validator;
}
}

0 comments on commit a6a2eb3

Please sign in to comment.