Skip to content

Commit

Permalink
Sync providers from parent validator into children.
Browse files Browse the repository at this point in the history
Syncing providers allows for a more seamless use of nested validators,
as each nested validator can be assured that it will have the same
rule providers as the other rules.
  • Loading branch information
markstory committed May 12, 2015
1 parent 43e869b commit 35e525b
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 0 deletions.
24 changes: 24 additions & 0 deletions src/Validation/Validator.php
Expand Up @@ -199,6 +199,16 @@ public function provider($name, $object = null)
return $this;
}

/**
* Get the list of providers in this validator.
*
* @return array
*/
public function providers()
{
return array_keys($this->_providers);
}

/**
* Returns whether a rule set is defined for a field or not
*
Expand Down Expand Up @@ -319,6 +329,10 @@ public function add($field, $name, $rule = [])
*
* This method assumes that the sub-document has a 1:1 relationship with the parent.
*
* The providers of the parent validator will be synced into the nested validator, when
* errors are checked. This ensures that any validation rule providers connected
* in the parent will have the same values in the nested validator when rules are evaluated.
*
* @param string $field The root field for the nested validator.
* @param \Cake\Validation\Validator $validator The nested validator.
* @return $this
Expand All @@ -330,6 +344,9 @@ public function addNested($field, Validator $validator)
if (!is_array($value)) {
return false;
}
foreach ($this->providers() as $provider) {
$validator->provider($provider, $this->provider($provider));
}
$errors = $validator->errors($value);
return empty($errors) ? true : $errors;
}]);
Expand All @@ -345,6 +362,10 @@ public function addNested($field, Validator $validator)
*
* This method assumes that the sub-document has a 1:N relationship with the parent.
*
* The providers of the parent validator will be synced into the nested validator, when
* errors are checked. This ensures that any validation rule providers connected
* in the parent will have the same values in the nested validator when rules are evaluated.
*
* @param string $field The root field for the nested validator.
* @param \Cake\Validation\Validator $validator The nested validator.
* @return $this
Expand All @@ -356,6 +377,9 @@ public function addNestedMany($field, Validator $validator)
if (!is_array($value)) {
return false;
}
foreach ($this->providers() as $provider) {
$validator->provider($provider, $this->provider($provider));
}
$errors = [];
foreach ($value as $i => $row) {
if (!is_array($row)) {
Expand Down
42 changes: 42 additions & 0 deletions tests/TestCase/Validation/ValidatorTest.php
Expand Up @@ -61,6 +61,27 @@ public function testAddNestedSingle()
$this->assertCount(1, $validator->field('user'));
}

/**
* Testing addNested connects providers
*
* @return void
*/
public function testAddNestedSingleProviders()
{
$validator = new Validator();
$validator->provider('test', $this);

$inner = new Validator();
$inner->add('username', 'not-blank', ['rule' => function () use ($inner, $validator) {
$this->assertSame($validator->providers(), $inner->providers(), 'Providers should match');
return false;
}]);
$validator->addNested('user', $inner);

$result = $validator->errors(['user' => ['username' => 'example']]);
$this->assertNotEmpty($result, 'Validation should fail');
}

/**
* Testing addNestedMany field rules
*
Expand All @@ -76,6 +97,27 @@ public function testAddNestedMany()
$this->assertCount(1, $validator->field('comments'));
}

/**
* Testing addNestedMany connects providers
*
* @return void
*/
public function testAddNestedManyProviders()
{
$validator = new Validator();
$validator->provider('test', $this);

$inner = new Validator();
$inner->add('comment', 'not-blank', ['rule' => function () use ($inner, $validator) {
$this->assertSame($validator->providers(), $inner->providers(), 'Providers should match');
return false;
}]);
$validator->addNestedMany('comments', $inner);

$result = $validator->errors(['comments' => [['comment' => 'example']]]);
$this->assertNotEmpty($result, 'Validation should fail');
}

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

0 comments on commit 35e525b

Please sign in to comment.