Issues

ZF-9409: Zend_Form::getFullyQualifiedName() does not respect elementsBelongTo

Description

This is an issue with equal named SubForms because they will get the same id rendered. But while fixing this i realized this is way too complicated.

I found a solution, however that is not consistent to how $element->getFullyQualifiedName() works.

This is done by adding setBelongsTo and getBelongsTo to Zend_Form, and setting that when calling _setElementsBelongTo on a Zend_Form with attached SubForms.

In method getFullyQualifiedName() it will then concat $belongsTo . $name . $elementsBelongTo


Index: tests/Zend/Form/FormTest.php
===================================================================
--- tests/Zend/Form/FormTest.php        (Revision 21732)
+++ tests/Zend/Form/FormTest.php        (Arbeitskopie)
@@ -1579,7 +1621,17 @@
         $this->assertSame($this->form->getValidValues($data['invalid']), $data['partial']);
     }
 
+    public function testGetFullyQualifiedNameWithElementsBelongTo()
+    {
+        $data = $this->_setup9350();
+
+        $this->form->setView($this->getView())->populate($data['valid']);
+        $html = $this->form->render();
+        preg_match_all('/id=.fieldset[^\"\']*/', $html, $match);
+        $this->assertEquals($match[0], array_unique($match[0]));
+    }
+
+
     // Display groups
 
     public function testCanAddAndRetrieveSingleDisplayGroups()
Index: library/Zend/Form.php
===================================================================
--- library/Zend/Form.php       (Revision 21732)
+++ library/Zend/Form.php       (Arbeitskopie)
@@ -860,6 +860,23 @@
         return $this->getAttrib('name');
     }
 
+    protected $_belongsTo = null;
+
+    public function setBelongsTo($notation)
+    {
+        $notation = $this->filterName($notation, true);
+        if ('' === $notation) {
+            $notation = null;
+        }
+        $this->_belongsTo = $notation;
+        return $this;
+    }
+
+    public function getBelongsTo()
+    {
+        return $this->_belongsTo;
+    }
+
     /**
      * Get fully qualified name
      *
@@ -869,7 +886,25 @@
      */
     public function getFullyQualifiedName()
     {
-        return $this->getName();
+        $name = $this->getName();
+
+        if ($this->isArray() &&
+            null !== ($elementsBelongTo = $this->getElementsBelongTo())) {
+                $name .= '/' . $elementsBelongTo;
+        }
+
+        if (null !== ($belongsTo = $this->getBelongsTo())) {
+            $name = $belongsTo . '/' . $name;
+        }
+
+        $path = explode('/', strtr($name, array('[' => '/', ']' => '')));
+
+        $name = array_shift($path);
+        
+        if (!empty($path)) {
+           $name .=  '[' . join($path, '][') . ']';
+        }
+        return $name;
     }
 
     /**
@@ -1452,9 +1494,14 @@
             foreach ($this->getElements() as $element) {
                 $element->setBelongsTo($array);
             }
+            foreach ($this->getSubForms() as $subform) {
+                $subform->setBelongsTo($array);
+            }
         } else {
             if (null !== ($element = $this->getElement($name))) {
                 $element->setBelongsTo($array);
+            } else if (null !== ($subform = $this->getSubForm($name))) {
+                $subform->setBelongsTo($array);
             }
         }
     }
@@ -1541,6 +1588,7 @@
         $this->_subForms[$name] = $form;
         $this->_order[$name]    = $order;
         $this->_orderUpdated    = true;
+        $this->_setElementsBelongTo($name);
         return $this;
     }

Comments

Matthew, what do you think about that, it will completely change the way fieldset id's for Forms and SubForms will be rendered, so i am really unsure about it.

And if we going to implement this, then we could append the fieldset to fullyName instead of prepending it, there was a Request in the Issue Tracker for that as well, to make it consistent with the label and element id's.