ZF-9361: Zend_Form populate() and setDefaults() do not respect elementsBelongTo

Description

Zend_Form setDefaults is not aware of elementsBelongTo and therefor does not set the values for Elements which are appended to a SubForm which has set elementsBelongTo.

This patch fixes the issue, Unit Test included


Index: tests/Zend/Form/FormTest.php
===================================================================
--- tests/Zend/Form/FormTest.php    (Revision 21667)
+++ tests/Zend/Form/FormTest.php    (Arbeitskopie)
@@ -1473,7 +1473,26 @@
         $this->assertTrue($this->form->isValid($data));
     }
 
+    public function testPopulateWithElementsBelongTo()
+    {
+        $this->form->addSubForm(new Zend_Form_SubForm(), 'foo')
+                   ->foo->setElementsBelongTo('foo[foo]')
+                        ->addSubForm(new Zend_Form_SubForm(), 'foo')
+                        ->foo->setIsArray(false)
+                             ->addElement('text', 'foo');
 
+        $foo = array('foo' =>
+                     array('foo' =>
+                           array('foo' =>
+                                 array('foo' => 'foo Value'))));
+
+        $this->form->setView($this->getView())
+                   ->populate($foo);
+
+        $this->assertRegexp('/value=.foo Value./', $this->form->render());
+    }
+
+
     // Display groups
 
     public function testCanAddAndRetrieveSingleDisplayGroups()
Index: library/Zend/Form.php
===================================================================
--- library/Zend/Form.php   (Revision 21667)
+++ library/Zend/Form.php   (Arbeitskopie)
@@ -1226,13 +1226,16 @@
      */
     public function setDefaults(array $defaults)
     {
+        if ($this->isArray()) {
+            $defaults = $this->_dissolveArrayValue($defaults, $this->getElementsBelongTo());
+        }
         foreach ($this->getElements() as $name => $element) {
             if (array_key_exists($name, $defaults)) {
                 $this->setDefault($name, $defaults[$name]);
             }
         }
         foreach ($this->getSubForms() as $name => $form) {
-            if (array_key_exists($name, $defaults)) {
+            if (!$form->isArray() && array_key_exists($name, $defaults)) {
                 $form->setDefaults($defaults[$name]);
             } else {
                 $form->setDefaults($defaults);

Comments

Based on what i have learned about $form->isArray() in ZF-9348, this is a 100% correct fix. I have included check against !$form->isArray() as well as check against equal-Name-Chain.

Patch applied to trunk and 1.10 release branch