Browse Source

Merge pull request #11900 from jeremyharris/nested-when

Added 'message' and 'when' params to addNested and addNestedMany
Mark Story 8 years ago
parent
commit
f5890bd288
2 changed files with 85 additions and 6 deletions
  1. 20 6
      src/Validation/Validator.php
  2. 65 0
      tests/TestCase/Validation/ValidatorTest.php

+ 20 - 6
src/Validation/Validator.php

@@ -421,12 +421,17 @@ class Validator implements ArrayAccess, IteratorAggregate, Countable
      *
      * @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;
             }
@@ -435,7 +440,9 @@ class Validator implements ArrayAccess, IteratorAggregate, Countable
             }
             $errors = $validator->errors($value, $context['newRecord']);
 
-            return empty($errors) ? true : $errors;
+            $message = $message ? [static::NESTED => $message] : [];
+
+            return empty($errors) ? true : $errors + $message;
         }]);
 
         return $this;
@@ -456,12 +463,17 @@ class Validator implements ArrayAccess, IteratorAggregate, Countable
      *
      * @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;
             }
@@ -479,7 +491,9 @@ class Validator implements ArrayAccess, IteratorAggregate, Countable
                 }
             }
 
-            return empty($errors) ? true : $errors;
+            $message = $message ? [static::NESTED => $message] : [];
+
+            return empty($errors) ? true : $errors + $message;
         }]);
 
         return $this;

+ 65 - 0
tests/TestCase/Validation/ValidatorTest.php

@@ -94,6 +94,36 @@ class ValidatorTest extends TestCase
     }
 
     /**
+     * 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
      *
      * @return void
@@ -131,6 +161,41 @@ class ValidatorTest extends TestCase
     }
 
     /**
+     * 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
      *
      * @return void