Skip to content

Commit

Permalink
Refactored getMethods, got rid of validationErrors property in ModelV…
Browse files Browse the repository at this point in the history
…alidator, made validateAssociated and many tests

pass
  • Loading branch information
lorenzo committed Apr 29, 2012
1 parent b83f936 commit c31f87b
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 145 deletions.
70 changes: 32 additions & 38 deletions lib/Cake/Model/ModelValidator.php
Expand Up @@ -90,7 +90,6 @@ public function __construct(Model $Model) {
* @return boolean True if there are no errors
*/
public function validates($options = array()) {
$this->validationErrors = array();
$errors = $this->invalidFields($options);
if (empty($errors) && $errors !== false) {
$errors = $this->_validateWithModels($options);
Expand All @@ -117,12 +116,12 @@ public function validates($options = array()) {
* depending on whether each record validated successfully.
*/
public function validateAssociated($data, $options = array()) {
$options = array_merge(array('atomic' => true, 'deep' => false), $options);
$model = $this->getModel();

$this->validationErrors = $model->validationErrors = $return = array();
if (!($model->create($data) && $this->validates($options))) {
$this->validationErrors = array($model->alias => $this->validationErrors);
$options = array_merge(array('atomic' => true, 'deep' => false), $options);
$model->validationErrors = $validationErrors = $return = array();
if (!($model->create($data) && $model->validates($options))) {
$validationErrors[$model->alias] = $model->validationErrors;
$return[$model->alias] = false;
} else {
$return[$model->alias] = true;
Expand All @@ -133,9 +132,9 @@ public function validateAssociated($data, $options = array()) {
if (isset($associations[$association])) {
if (in_array($associations[$association], array('belongsTo', 'hasOne'))) {
if ($options['deep']) {
$validates = $model->{$association}->validator()->validateAssociated($values, $options);
$validates = $model->{$association}->validateAssociated($values, $options);
} else {
$validates = $model->{$association}->create($values) !== null && $model->{$association}->validator()->validates($options);
$validates = $model->{$association}->create($values) !== null && $model->{$association}->validates($options);
}
if (is_array($validates)) {
if (in_array(false, $validates, true)) {
Expand All @@ -146,23 +145,23 @@ public function validateAssociated($data, $options = array()) {
}
$return[$association] = $validates;
} elseif ($associations[$association] === 'hasMany') {
$validates = $model->{$association}->validator()->validateMany($values, $options);
$validates = $model->{$association}->validateMany($values, $options);
$return[$association] = $validates;
}
if (!$validates || (is_array($validates) && in_array(false, $validates, true))) {
$this->validationErrors[$association] = $model->{$association}->validator()->validationErrors;
$validationErrors[$association] = $model->{$association}->validationErrors;
}
}
}

if (isset($this->validationErrors[$model->alias])) {
$this->validationErrors = $this->validationErrors[$model->alias];
$model->validationErrors = $validationErrors;
if (isset($validationErrors[$model->alias])) {
$model->validationErrors = $validationErrors[$model->alias];
}
$model->validationErrors = $this->validationErrors;
if (!$options['atomic']) {
return $return;
}
if ($return[$model->alias] === false || !empty($this->validationErrors)) {
if ($return[$model->alias] === false || !empty($model->validationErrors)) {
return false;
}
return true;
Expand All @@ -185,29 +184,28 @@ public function validateAssociated($data, $options = array()) {
* depending on whether each record validated successfully.
*/
public function validateMany($data, $options = array()) {
$options = array_merge(array('atomic' => true, 'deep' => false), $options);
$model = $this->getModel();

$this->validationErrors = $validationErrors = $model->validationErrors = $return = array();
$options = array_merge(array('atomic' => true, 'deep' => false), $options);
$model->validationErrors = $validationErrors = $return = array();
foreach ($data as $key => $record) {
if ($options['deep']) {
$validates = $this->validateAssociated($record, $options);
$validates = $model->validateAssociated($record, $options);
} else {
$validates = $model->create($record) && $this->validates($options);
$validates = $model->create($record) && $model->validates($options);
}
if ($validates === false || (is_array($validates) && in_array(false, $validates, true))) {
$validationErrors[$key] = $this->validationErrors;
$validationErrors[$key] = $model->validationErrors;
$validates = false;
} else {
$validates = true;
}
$return[$key] = $validates;
}
$this->validationErrors = $model->validationErrors = $validationErrors;
$model->validationErrors = $validationErrors;
if (!$options['atomic']) {
return $return;
}
if (empty($this->validationErrors)) {
if (empty($model->validationErrors)) {
return true;
}
return false;
Expand All @@ -228,21 +226,22 @@ public function invalidFields($options = array()) {
$this->setOptions($options);

if (!$this->_parseRules()) {
return $model->validationErrors = $this->validationErrors;
return $model->validationErrors;
}

$exists = $model->exists();
$methods = $this->getMethods();
foreach ($this->_fields as $field) {
$field->setMethods($methods);
$field->setValidationDomain($model->validationDomain);
$errors = $field->validate($model->data, $exists);
$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);
}
}

return $model->validationErrors = $this->validationErrors;
return $model->validationErrors;
}

/**
Expand All @@ -258,35 +257,30 @@ public function invalidate($field, $value = true) {
if (!is_array($this->validationErrors)) {
$this->validationErrors = array();
}
$this->validationErrors[$field][] = $this->getModel()->validationErrors[$field][] = $value;
$this->getModel()->validationErrors[$field][] = $value;
}

/**
* Gets all possible custom methods from the Model, Behaviors and the Validator.
* If $type is null (default) gets all methods. If $type is one of 'model', 'behaviors' or 'validator',
* gets the corresponding methods.
*
* @param string $type [optional] The methods type to get. Defaults to null
* @return array The requested methods
*/
public function getMethods($type = null) {
public function getMethods() {
if (!empty($this->_methods)) {
if ($type !== null && !empty($this->_methods[$type])) {
return $this->_methods[$type];
}
return $this->_methods;
}

$this->_methods['model'] = array_map('strtolower', get_class_methods($this->_model));
$this->_methods['behaviors'] = array_keys($this->_model->Behaviors->methods());
$this->_methods['validator'] = get_class_methods($this);
$methods = array();
foreach (get_class_methods($this->_model) as $method); {
$methods[strtolower($method)] = array($this->_model, $method);
}

if ($type !== null && !empty($this->_methods[$type])) {
return $this->_methods[$type];
foreach (array_keys($this->_model->Behaviors->methods()) as $mthod) {
$methods += array(strtolower($method) => array($this->_model, $method));
}
unset($type);

return $this->_methods;
return $this->_methods = $methods;
}

/**
Expand Down
17 changes: 6 additions & 11 deletions lib/Cake/Model/Validator/CakeRule.php
Expand Up @@ -261,21 +261,16 @@ public function dispatchValidation(&$data, &$methods) {

$validator = $this->getPropertiesArray();
$rule = strtolower($this->_rule);

if (in_array(strtolower($this->_rule), $methods['model'])) {
$this->_ruleParams[] = array_merge($validator, $this->_passedOptions);
$this->_ruleParams[0] = array($this->getField()->field => $this->_ruleParams[0]);
$this->_valid = $Model->dispatchMethod($this->_rule, $this->_ruleParams);
} elseif (in_array($this->_rule, $methods['behaviors']) || in_array(strtolower($this->_rule), $methods['behaviors'])) {
if (isset($methods[$rule])) {
$this->_ruleParams[] = array_merge($validator, $this->_passedOptions);
$this->_ruleParams[0] = array($this->getField()->field => $this->_ruleParams[0]);
$this->_valid = $Model->Behaviors->dispatchMethod($Model, $this->_rule, $this->_ruleParams);
} elseif (method_exists('Validation', $this->_rule)) {
$this->_ruleParams[0] = array($this->_field => $this->_ruleParams[0]);
$this->_valid = call_user_func_array($methods[$rule], $this->_ruleParams);
} elseif (class_exists('Validation') && method_exists('Validation', $this->_rule)) {
$this->_valid = call_user_func_array(array('Validation', $this->_rule), $this->_ruleParams);
} elseif (!is_array($validator['rule'])) {
$this->_valid = preg_match($this->_rule, $this->data[$this->getField()->field]);
$this->_valid = preg_match($this->_rule, $data[$this->_field]);
} elseif (Configure::read('debug') > 0) {
trigger_error(__d('cake_dev', 'Could not find validation handler %s for %s', $this->_rule, $this->_field->field), E_USER_WARNING);
trigger_error(__d('cake_dev', 'Could not find validation handler %s for %s', $this->_rule, $this->_field), E_USER_WARNING);
return false;
}

Expand Down
85 changes: 3 additions & 82 deletions lib/Cake/Test/Case/Model/ModelValidationTest.php
Expand Up @@ -1767,36 +1767,6 @@ public function testValidateMany() {
$this->assertEquals($expected, $TestModel->validationErrors);
}

/**
* testGetData method
*
* @return void
*/
public function testGetData() {
$this->loadFixtures('Article', 'Comment');
$TestModel = new Article();
$data = array(
'Article' => array(
'id' =>1, 'title' => 'first title'
),
'Comment' => array(
array('id' => 1, 'article_id' => 1, 'title' => 'first comment'),
array('id' => 2, 'article_id' => 1, 'title' => 'second comment')
)
);
$Validator = new ModelValidator($TestModel);
$TestModel->set($data);
$result = $Validator->getData(null, true);
$this->assertEquals($data, $result);

$Validator->data = array();
$result = $Validator->getData();
$this->assertEquals($data['Article'], $result);

$result = $Validator->getData('title');
$this->assertEquals($data['Article']['title'], $result);
}

/**
* testGetMethods method
*
Expand All @@ -1814,51 +1784,6 @@ public function testGetMethods() {
$this->assertEquals($expected, $result['model']);
}

/**
* testGetFields method
*
* @return void
*/
public function testGetFields() {
$this->loadFixtures('Article', 'Comment');
$TestModel = new Article();
$Validator = $TestModel->validator();

$result = $Validator->getFields();
$this->assertSame(array(), $result);

$Validator->setFields();
$result = $Validator->getFields();
$this->assertEquals(array('user_id', 'title','body'), array_keys($result));

$result = $Validator->getFields('title');
$this->assertInstanceOf('CakeField', $result);
}

/**
* testSetFields method
*
* @return void
*/
public function testSetFields() {
$this->loadFixtures('Article', 'Comment');
$TestModel = new Article();
$TestModel->whitelist = array('title', 'body');
$Validator = $TestModel->validator();

$result = $Validator->setFields();
$this->assertTrue($result);

$result = $Validator->getFields();
$this->assertEquals(array('title','body'), array_keys($result));

$result = $Validator->getFields('user_id');
$this->assertFalse($result);

$result = $Validator->getFields('body');
$this->assertEquals(array('notEmpty'), $result->ruleSet);
}

/**
* testSetOptions method
*
Expand Down Expand Up @@ -1912,15 +1837,11 @@ public function testSetValidationDomain() {
$TestModel = new Article();
$Validator = $TestModel->validator();

$result = $Validator->setValidationDomain();
$this->assertEquals('default', $result->validationDomain);

$TestModel->validationDomain = 'validation_messages';
$result = $Validator->setValidationDomain();
$this->assertEquals('validation_messages', $result->validationDomain);
$result = $Validator->setValidationDomain('default');
$this->assertEquals('default', $TestModel->validationDomain);

$result = $Validator->setValidationDomain('other');
$this->assertEquals('other', $result->validationDomain);
$this->assertEquals('other', $TestModel->validationDomain);
}

/**
Expand Down
15 changes: 1 addition & 14 deletions lib/Cake/Test/Case/Model/Validator/CakeFieldTest.php
Expand Up @@ -32,24 +32,11 @@ class CakeFieldTest extends BaseModelTest {
* @return void
*/
public function setUp() {
$this->skipIf(true);
parent::setUp();
$this->Article = new Article();
$this->Article->set(array('title' => '', 'body' => 'no title'));
$this->Validator = new ModelValidator($this->Article);
$this->Validator->getData();
}

/**
* testConstruct method
*
* @return void
*/
public function testConstruct() {
$Field = new CakeField($this->Validator, 'title', 'notEmpty');

$this->assertEquals(array('title' => '', 'body' => 'no title'), $Field->data);
$this->assertEquals('title', $Field->field);
$this->assertEquals(array('notEmpty'), $Field->ruleSet);
}

/**
Expand Down

0 comments on commit c31f87b

Please sign in to comment.