Navigation Menu

Skip to content

Commit

Permalink
Fix multi-model validators with deep & atomic.
Browse files Browse the repository at this point in the history
Apply patch from 'Christian Buffin' to fix validateMany() and
validateAssociated() when atomic=false & deep=true are used in
conjunction. Using Hash to flatten the nested set of validation results
yields the correct results.

Fixes #3352
  • Loading branch information
markstory committed Nov 29, 2012
1 parent 966c69c commit f250592
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 2 deletions.
4 changes: 2 additions & 2 deletions lib/Cake/Model/ModelValidator.php
Expand Up @@ -156,7 +156,7 @@ public function validateAssociated(&$data, $options = array()) {
$data[$association] = $model->{$association}->data[$model->{$association}->alias];
}
if (is_array($validates)) {
if (in_array(false, $validates, true)) {
if (in_array(false, Hash::flatten($validates), true)) {
$validates = false;
} else {
$validates = true;
Expand Down Expand Up @@ -220,7 +220,7 @@ public function validateMany(&$data, $options = array()) {
$validates = $model->set($record) && $model->validates($options);
$data[$key] = $model->data;
}
if ($validates === false || (is_array($validates) && in_array(false, $validates, true))) {
if ($validates === false || (is_array($validates) && in_array(false, Hash::flatten($validates), true))) {
$validationErrors[$key] = $model->validationErrors;
$validates = false;
} else {
Expand Down
120 changes: 120 additions & 0 deletions lib/Cake/Test/Case/Model/ModelValidationTest.php
Expand Up @@ -2227,4 +2227,124 @@ public function testCustomMethodWithEmptyValue() {
$this->assertFalse($model->validates());
}

/**
* Test validateAssociated with atomic=false & deep=true
*
* @return void
*/
public function testValidateAssociatedAtomicFalseDeepTrueWithErrors() {
$this->loadFixtures('Comment', 'Article', 'User', 'Attachment');
$Attachment = ClassRegistry::init('Attachment');
$Attachment->Comment->validator()->add('comment', array(
array('rule' => 'notEmpty')
));
$Attachment->Comment->User->bindModel(array(
'hasMany' => array(
'Article',
'Comment'
)),
false
);

$data = array(
'Attachment' => array(
'attachment' => 'text',
'Comment' => array(
'comment' => '',
'published' => 'N',
'User' => array(
'user' => 'Foo',
'password' => 'mypassword',
'Comment' => array(
array(
'comment' => ''
)
)
)
)
)
);
$result = $Attachment->validateAssociated($data, array('atomic' => false, 'deep' => true));

$result = $Attachment->validationErrors;
$expected = array(
'Comment' => array(
'comment' => array(
0 => 'This field cannot be left blank',
),
'User' => array(
'Comment' => array(
0 => array(
'comment' => array(
0 => 'This field cannot be left blank',
),
),
),
),
),
);
$this->assertEquals($result, $expected);
}

/**
* Test validateMany with atomic=false & deep=true
*
* @return void
*/
public function testValidateManyAtomicFalseDeepTrueWithErrors() {
$this->loadFixtures('Comment', 'Article', 'User');
$Article = ClassRegistry::init('Article');
$Article->Comment->validator()->add('comment', array(
array('rule' => 'notEmpty')
));

$data = array(
array(
'Article' => array(
'user_id' => 1,
'title' => 'Foo',
'body' => 'text',
'published' => 'N'
),
'Comment' => array(
array(
'user_id' => 1,
'comment' => 'Baz',
'published' => 'N',
)
),
),
array(
'Article' => array(
'user_id' => 1,
'title' => 'Bar',
'body' => 'text',
'published' => 'N'
),
'Comment' => array(
array(
'user_id' => 1,
'comment' => '',
'published' => 'N',
)
),
),
);
$Article->validateMany($data, array('atomic' => false, 'deep' => true));

$result = $Article->validationErrors;
$expected = array(
1 => array(
'Comment' => array(
0 => array(
'comment' => array(
0 => 'This field cannot be left blank',
),
),
),
),
);
$this->assertEquals($result, $expected);
}

}

0 comments on commit f250592

Please sign in to comment.