Browse Source

[Form] fixed more cases where the delegating validator did not match the validator paths

Fabien Potencier 14 năm trước cách đây
mục cha
commit
03a05661f9

+ 11 - 4
src/Symfony/Component/Form/Extension/Validator/Validator/DelegatingValidator.php

@@ -183,9 +183,12 @@ class DelegatingValidator implements FormValidatorInterface
             $nestedNamePath = $namePath . '.' . $child->getName();
 
             if (strpos($path, '[') === 0) {
-                $nestedDataPath = $dataPath . $path;
+                $nestedDataPaths = array($dataPath . $path);
             } else {
-                $nestedDataPath = $dataPath . '.' . $path;
+                $nestedDataPaths = array($dataPath . '.' . $path);
+                if ($child->hasChildren()) {
+                    $nestedDataPaths[] = $dataPath . '[' . $path . ']';
+                }
             }
 
             if ($child->hasChildren()) {
@@ -195,10 +198,14 @@ class DelegatingValidator implements FormValidatorInterface
                     $this->buildDataPathMapping($child, $mapping, $dataPath, $nestedNamePath);
                 }
 
-                $this->buildDataPathMapping($child, $mapping, $nestedDataPath, $nestedNamePath);
+                foreach ($nestedDataPaths as $nestedDataPath) {
+                    $this->buildDataPathMapping($child, $mapping, $nestedDataPath, $nestedNamePath);
+                }
             }
 
-            $mapping['/^'.preg_quote($nestedDataPath, '/').'(?!\w)/'] = $child;
+            foreach ($nestedDataPaths as $nestedDataPath) {
+                $mapping['/^'.preg_quote($nestedDataPath, '/').'(?!\w)/'] = $child;
+            }
         }
     }
 

+ 22 - 0
tests/Symfony/Tests/Component/Form/Extension/Validator/Validator/DelegatingValidatorTest.php

@@ -369,6 +369,28 @@ class DelegatingValidatorTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals(array($this->getFormError()), $grandChild->getErrors());
     }
 
+    public function testDataErrorsOnGrandChild3()
+    {
+        $parent = $this->getForm();
+        $child = $this->getForm('address');
+        $grandChild = $this->getForm('street');
+
+        $parent->add($child);
+        $child->add($grandChild);
+
+        $this->delegate->expects($this->once())
+            ->method('validate')
+            ->will($this->returnValue(array(
+                $this->getConstraintViolation('data[address].street.constrainedProp')
+            )));
+
+        $this->validator->validate($parent);
+
+        $this->assertFalse($parent->hasErrors());
+        $this->assertFalse($child->hasErrors());
+        $this->assertEquals(array($this->getFormError()), $grandChild->getErrors());
+    }
+
     public function testDataErrorsOnParentIfNoChildFound()
     {
         $parent = $this->getForm();