Skip to content

Commit

Permalink
Removing funcitons and code that were used to store state inside the
Browse files Browse the repository at this point in the history
validation subsystem, this showed to be very problematic in the past, so
making room for a different implementation
  • Loading branch information
lorenzo committed Nov 20, 2013
1 parent 13da71e commit 341ba6f
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 236 deletions.
2 changes: 1 addition & 1 deletion Cake/ORM/Table.php
Expand Up @@ -789,7 +789,7 @@ public function validator($name = 'default', $instance = null) {
return $this->_validators[$name] = $instance;
}

$validator = new Validator($this);
$validator = new Validator;
$validator = $this->{'validation' . ucfirst($name)}($validator);
return $this->_validators[$name] = $validator;
}
Expand Down
32 changes: 0 additions & 32 deletions Cake/ORM/Validation/ValidationRule.php
Expand Up @@ -26,20 +26,6 @@
*/
class ValidationRule {

/**
* Whether the field passed this validation rule
*
* @var mixed
*/
protected $_valid = true;

/**
* Holds whether the record being validated is being created or updated
*
* @var boolean
*/
protected $_isUpdate = false;

/**
* Validation method
*
Expand Down Expand Up @@ -162,24 +148,6 @@ protected function _getPropertiesArray() {
);
}

/**
* Sets the recordExists configuration value for this rule,
* ir refers to whether the model record it is validating exists
* exists in the collection or not (create or update operation)
*
* If called with no parameters it will return whether this rule
* is configured for update operations or not.
*
* @param boolean $exists Boolean to indicate if records exists
* @return boolean
*/
public function isUpdate($exists = null) {
if ($exists === null) {
return $this->_isUpdate;
}
return $this->_isUpdate = $exists;
}

/**
* Dispatches the validation rule to the given validator method
*
Expand Down
59 changes: 0 additions & 59 deletions Cake/ORM/Validation/ValidationSet.php
Expand Up @@ -47,13 +47,6 @@ class ValidationSet implements \ArrayAccess, \IteratorAggregate, \Countable {
*/
protected $_validationDomain = null;

/**
* Whether the validation is stopped
*
* @var boolean
*/
public $isStopped = false;

/**
* Holds the fieldname
*
Expand Down Expand Up @@ -82,13 +75,6 @@ class ValidationSet implements \ArrayAccess, \IteratorAggregate, \Countable {
*/
protected $_allowEmpty = false;

/**
* Holds whether the record being validated is to be created or updated
*
* @var boolean
*/
protected $_isUpdate = false;

/**
* Constructor
*
Expand All @@ -112,31 +98,6 @@ public function __construct($fieldName, $ruleSet) {
$this->ruleSet = $ruleSet;
}

/**
* Sets the list of methods to use for validation
*
* @param array $methods Methods list
* @return void
*/
public function setMethods($methods) {
$this->_methods = $methods;
}

/**
* Sets the I18n domain for validation messages.
*
* If no argument is passed the currently set domain will be returned.
*
* @param string $validationDomain The validation domain to be used.
* @return string
*/
public function validationDomain($validationDomain = null) {
if ($validationDomain === null) {
return $this->_validationDomain;
}
return $this->_validationDomain = $validationDomain;
}

/**
* Sets whether a field is required to be present in data array.
*
Expand Down Expand Up @@ -167,26 +128,6 @@ public function allowEmpty($allowEmpty = null) {
return $this->_allowEmpty = $allowEmpty;
}

/**
* Sets the isUpdate configuration value for this ruleset,
* it refers to whether the model record it is validating exists
* in the collection or not (create or update operation)
*
* If called with no parameters it will return whether this ruleset
* is configured for update operations or not.
*
* @return boolean
*/
public function isUpdate($isUpdate = null) {
if ($isUpdate === null) {
return $this->_isUpdate;
}
foreach ($this->getRules() as $rule) {
$rule->isUpdate($isUpdate);
}
return $this->_isUpdate = $isUpdate;
}

/**
* Runs all validation rules in this set and returns a list of
* validation errors
Expand Down
159 changes: 16 additions & 143 deletions Cake/ORM/Validator.php
Expand Up @@ -25,7 +25,7 @@
*
* Implements ArrayAccess to easily modify rules in the set
*
* @link http://book.cakephp.org/2.0/en/data-validation.html
* @link http://book.cakephp.org/2.0/en/data-validation.html
*/
class Validator implements \ArrayAccess, \IteratorAggregate, \Countable {

Expand All @@ -37,50 +37,18 @@ class Validator implements \ArrayAccess, \IteratorAggregate, \Countable {
protected $_fields = array();

/**
* Holds the reference to the table this Validator is attached to
* The translation domain to use when setting the error messages
*
* @var \Cake\ORM\Table
* @var string
*/
protected $_table = array();
protected $_validationDomain = 'default';

/**
* The validators $validate property, used for checking whether validation
* rules definition changed in the model and should be refreshed in this class
* List of errors found during validation
*
* @var array
*/
protected $_validate = array();

/**
* Holds the available custom callback methods, usually taken from model methods
* and behavior methods
*
* @var array
*/
protected $_methods = array();

/**
* Holds the available custom callback methods from the model
*
* @var array
*/
protected $_modelMethods = array();

/**
* Holds the list of behavior names that were attached when this object was created
*
* @var array
*/
protected $_behaviors = array();

/**
* Constructor
*
* @param \Cake\ORM\Table $table A reference to the table object this is bound to
*/
public function __construct(Table $table) {
$this->_table = $table;
}
protected $_errors = [];

/**
* Returns true if all fields pass validation.
Expand All @@ -91,9 +59,6 @@ public function __construct(Table $table) {
*/
public function validates($options = array()) {
$errors = $this->errors($options);
if (empty($errors) && $errors !== false) {
$errors = $this->_validateWithModels($options);
}
if (is_array($errors)) {
return count($errors) === 0;
}
Expand All @@ -106,77 +71,36 @@ public function validates($options = array()) {
*
* @param string $options An optional array of custom options to be made available in the beforeValidate callback
* @return array Array of invalid fields
* @see ModelValidator::validates()
* @see Validator::validates()
*/
public function errors($options = array()) {
if (!$this->_triggerBeforeValidate($options)) {
return false;
}
$model = $this->getModel();
$fieldList = $model->whitelist;
if (empty($fieldList) && !empty($options['fieldList'])) {
if (!empty($options['fieldList'][$model->alias]) && is_array($options['fieldList'][$model->alias])) {
$fieldList = $options['fieldList'][$model->alias];
} else {
$fieldList = $options['fieldList'];
}
}

$fieldList = $options['fieldList'];
$exists = $model->exists();
$methods = $this->getMethods();
$fields = $this->_validationList($fieldList);

foreach ($fields as $field) {
$field->setMethods($methods);
$field->validationDomain($model->validationDomain);
$data = isset($model->data[$model->alias]) ? $model->data[$model->alias] : array();
$errors = $field->validate($data, $exists);
foreach ($errors as $error) {
$this->invalidate($field->field, $error);
}
}

$model->getEventManager()->dispatch(new Event('Model.afterValidate', $model));
return $model->validationErrors;
return $this->_errors;
}

/**
* Marks a field as invalid, optionally setting a message explaining
* Marks a field as invalid in an entity, optionally setting a message explaining
* why the rule failed
*
* @param \Cake\ORM\Entity $entity The name of the field to invalidate
* @param string $field The name of the field to invalidate
* @param string $message Validation message explaining why the rule failed, defaults to true.
* @return void
*/
public function invalidate($field, $message = true) {
$this->getModel()->validationErrors[$field][] = $message;
}

/**
* Gets all possible custom methods from the Model and attached Behaviors
* to be used as validators
*
* @return array List of callables to be used as validation methods
*/
public function getMethods() {
$behaviors = $this->_model->Behaviors->enabled();
if (!empty($this->_methods) && $behaviors === $this->_behaviors) {
return $this->_methods;
}
$this->_behaviors = $behaviors;

if (empty($this->_modelMethods)) {
foreach (get_class_methods($this->_model) as $method) {
$this->_modelMethods[strtolower($method)] = array($this->_model, $method);
}
}

$methods = $this->_modelMethods;
foreach (array_keys($this->_model->Behaviors->methods()) as $method) {
$methods += array(strtolower($method) => array($this->_model, $method));
}

return $this->_methods = $methods;
public function invalidate($entity, $field, $message = true) {
}

/**
Expand All @@ -199,65 +123,14 @@ public function getField($name = null) {
/**
* Sets the I18n domain for validation messages. This method is chainable.
*
* @param string $validationDomain [optional] The validation domain to be used.
* @return ModelValidator
* @param string $validationDomain The validation domain to be used.
* @return Cake\Model\Validator
*/
public function setValidationDomain($validationDomain = null) {
if (empty($validationDomain)) {
$validationDomain = 'default';
}
$this->getModel()->validationDomain = $validationDomain;
public function setValidationDomain($validationDomain) {
$this->_validationDomain = $validationDomain;
return $this;
}

/**
* Gets the model related to this validator
*
* @return Model
*/
public function getModel() {
return $this->_model;
}

/**
* Processes the passed fieldList and returns the list of fields to be validated
*
* @param array $fieldList list of fields to be used for validation
* @return array List of validation rules to be applied
*/
protected function _validationList($fieldList = array()) {
if (empty($fieldList) || Hash::dimensions($fieldList) > 1) {
return $this->_fields;
}

$validateList = array();
$this->validationErrors = array();
foreach ((array)$fieldList as $f) {
if (!empty($this->_fields[$f])) {
$validateList[$f] = $this->_fields[$f];
}
}

return $validateList;
}

/**
* Propagates beforeValidate event
*
* @param array $options
* @return boolean
*/
protected function _triggerBeforeValidate($options = array()) {
$model = $this->getModel();
$event = new Event('Model.beforeValidate', $model, array($options));
list($event->break, $event->breakOn) = array(true, false);
$model->getEventManager()->dispatch($event);
if ($event->isStopped()) {
return false;
}
return true;
}

/**
* Returns whether a rule set is defined for a field or not
*
Expand Down
2 changes: 1 addition & 1 deletion Cake/Test/TestCase/ORM/TableTest.php
Expand Up @@ -1831,7 +1831,7 @@ public function functionTestValidationWithDefiner() {
*/
public function testValidatorSetter() {
$table = new Table;
$validator = new \Cake\ORM\Validator($table);
$validator = new \Cake\ORM\Validator;
$table->validator('other', $validator);
$this->assertSame($validator, $table->validator('other'));
}
Expand Down

0 comments on commit 341ba6f

Please sign in to comment.