Skip to content

Commit

Permalink
Merge pull request #11900 from jeremyharris/nested-when
Browse files Browse the repository at this point in the history
Added 'message' and 'when' params to addNested and addNestedMany
  • Loading branch information
markstory committed Apr 3, 2018
2 parents 98ba1cf + ce0aad7 commit f5890bd
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 6 deletions.
26 changes: 20 additions & 6 deletions src/Validation/Validator.php
Expand Up @@ -421,12 +421,17 @@ public function add($field, $name, $rule = [])
*
* @param string $field The root field for the nested validator.
* @param \Cake\Validation\Validator $validator The nested validator.
* @param string|null $message The error message when the rule fails.
* @param string|callable|null $when Either 'create' or 'update' or a callable that returns
* true when the validation rule should be applied.
* @return $this
*/
public function addNested($field, Validator $validator)
public function addNested($field, Validator $validator, $message = null, $when = null)
{
$extra = array_filter(['message' => $message, 'on' => $when]);

$field = $this->field($field);
$field->add(static::NESTED, ['rule' => function ($value, $context) use ($validator) {
$field->add(static::NESTED, $extra + ['rule' => function ($value, $context) use ($validator, $message) {
if (!is_array($value)) {
return false;
}
Expand All @@ -435,7 +440,9 @@ public function addNested($field, Validator $validator)
}
$errors = $validator->errors($value, $context['newRecord']);

return empty($errors) ? true : $errors;
$message = $message ? [static::NESTED => $message] : [];

return empty($errors) ? true : $errors + $message;
}]);

return $this;
Expand All @@ -456,12 +463,17 @@ public function addNested($field, Validator $validator)
*
* @param string $field The root field for the nested validator.
* @param \Cake\Validation\Validator $validator The nested validator.
* @param string|null $message The error message when the rule fails.
* @param string|callable|null $when Either 'create' or 'update' or a callable that returns
* true when the validation rule should be applied.
* @return $this
*/
public function addNestedMany($field, Validator $validator)
public function addNestedMany($field, Validator $validator, $message = null, $when = null)
{
$extra = array_filter(['message' => $message, 'on' => $when]);

$field = $this->field($field);
$field->add(static::NESTED, ['rule' => function ($value, $context) use ($validator) {
$field->add(static::NESTED, $extra + ['rule' => function ($value, $context) use ($validator, $message) {
if (!is_array($value)) {
return false;
}
Expand All @@ -479,7 +491,9 @@ public function addNestedMany($field, Validator $validator)
}
}

return empty($errors) ? true : $errors;
$message = $message ? [static::NESTED => $message] : [];

return empty($errors) ? true : $errors + $message;
}]);

return $this;
Expand Down
65 changes: 65 additions & 0 deletions tests/TestCase/Validation/ValidatorTest.php
Expand Up @@ -93,6 +93,36 @@ public function testAddNestedSingleProviders()
$this->assertNotEmpty($result, 'Validation should fail');
}

/**
* Testing addNested with extra `$message` and `$when` params
*
* @return void
*/
public function testAddNestedWithExtra()
{
$inner = new Validator();
$inner->requirePresence('username');

$validator = new Validator();
$validator->addNested('user', $inner, 'errors found', 'create');

$this->assertCount(1, $validator->field('user'));

$rule = $validator->field('user')->rule(Validator::NESTED);
$this->assertSame('create', $rule->get('on'));

$errors = $validator->errors(['user' => 'string']);
$this->assertArrayHasKey('user', $errors);
$this->assertArrayHasKey(Validator::NESTED, $errors['user']);
$this->assertSame('errors found', $errors['user'][Validator::NESTED]);

$errors = $validator->errors(['user' => ['key' => 'value']]);
$this->assertArrayHasKey('user', $errors);
$this->assertArrayHasKey(Validator::NESTED, $errors['user']);

$this->assertEmpty($validator->errors(['user' => ['key' => 'value']], false));
}

/**
* Testing addNestedMany field rules
*
Expand Down Expand Up @@ -130,6 +160,41 @@ public function testAddNestedManyProviders()
$this->assertNotEmpty($result, 'Validation should fail');
}

/**
* Testing addNestedMany with extra `$message` and `$when` params
*
* @return void
*/
public function testAddNestedManyWithExtra()
{
$inner = new Validator();
$inner->requirePresence('body');

$validator = new Validator();
$validator->addNestedMany('comments', $inner, 'errors found', 'create');

$this->assertCount(1, $validator->field('comments'));

$rule = $validator->field('comments')->rule(Validator::NESTED);
$this->assertSame('create', $rule->get('on'));

$errors = $validator->errors(['comments' => 'string']);
$this->assertArrayHasKey('comments', $errors);
$this->assertArrayHasKey(Validator::NESTED, $errors['comments']);
$this->assertSame('errors found', $errors['comments'][Validator::NESTED]);

$errors = $validator->errors(['comments' => ['string']]);
$this->assertArrayHasKey('comments', $errors);
$this->assertArrayHasKey(Validator::NESTED, $errors['comments']);
$this->assertSame('errors found', $errors['comments'][Validator::NESTED]);

$errors = $validator->errors(['comments' => [['body' => null]]]);
$this->assertArrayHasKey('comments', $errors);
$this->assertArrayHasKey(Validator::NESTED, $errors['comments']);

$this->assertEmpty($validator->errors(['comments' => [['body' => null]]], false));
}

/**
* Tests that calling field will create a default validation set for it
*
Expand Down

0 comments on commit f5890bd

Please sign in to comment.