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
Posted by Christian Albrecht (alab) on 2010-04-02T08:06:46.000+0000
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.