ZF-7552: Same type decorators are lost when getting and setting back decorators

Description

When using multiple decorators of the same type (a specific name is given to each of them, as described in the documentation), getting decorators and setting them back on the object make all except one of them disappear. It occurs for Zend_Form, Zend_Form_DisplayGroup and Zend_Form_Element instances.

An example with a form element :


$element = new Zend_Form_Element_Text('foo');
$element->addDecorator(array('TdTag' => 'HtmlTag'), array('tag' => 'td'));
$element->addDecorator(array('TrTag' => 'HtmlTag'), array('tag' => 'tr'));

var_export($element->getDecorators());

$element->setDecorators($element->getDecorators()); // This should do nothing
var_export($element->getDecorators());

The first var_export will show the following HtmlTag decorators : * HtmlTag : the default one which renders the element surrounded with "td" * TrTag * TdTag

At the second var_export, only the TrTag (the last HtmlTag decorator) remains among the HtmlTag decorators (and furthermore, it has lost its name, getting a mere 'Zend_Form_Decorator_HtmlTag' name).

This is due to the fact that keys of the array provided to the addDecorators method are not used.

Proposed patch :


Index: Zend/Form.php
===================================================================
--- Zend/Form.php   (revision 17501)
+++ Zend/Form.php   (working copy)
@@ -2394,11 +2394,11 @@
      */
     public function addDecorators(array $decorators)
     {
-        foreach ($decorators as $decoratorInfo) {
+        foreach ($decorators as $decoratorName => $decoratorInfo) {
             if (is_string($decoratorInfo)) {
                 $this->addDecorator($decoratorInfo);
             } elseif ($decoratorInfo instanceof Zend_Form_Decorator_Interface) {
-                $this->addDecorator($decoratorInfo);
+                $this->addDecorator(array($decoratorName => $decoratorInfo));
             } elseif (is_array($decoratorInfo)) {
                 $argc    = count($decoratorInfo);
                 $options = array();
Index: Zend/Form/Element.php
===================================================================
--- Zend/Form/Element.php   (revision 17501)
+++ Zend/Form/Element.php   (working copy)
@@ -1761,11 +1763,11 @@
      */
     public function addDecorators(array $decorators)
     {
-        foreach ($decorators as $decoratorInfo) {
+        foreach ($decorators as $decoratorName => $decoratorInfo) {
             if (is_string($decoratorInfo)) {
                 $this->addDecorator($decoratorInfo);
             } elseif ($decoratorInfo instanceof Zend_Form_Decorator_Interface) {
-                $this->addDecorator($decoratorInfo);
+                $this->addDecorator(array($decoratorName => $decoratorInfo));
             } elseif (is_array($decoratorInfo)) {
                 $argc    = count($decoratorInfo);
                 $options = array();
Index: Zend/Form/DisplayGroup.php
===================================================================
--- Zend/Form/DisplayGroup.php  (revision 17501)
+++ Zend/Form/DisplayGroup.php  (working copy)
@@ -702,11 +702,11 @@
      */
     public function addDecorators(array $decorators)
     {
-        foreach ($decorators as $decoratorInfo) {
+        foreach ($decorators as $decoratorName => $decoratorInfo) {
             if (is_string($decoratorInfo)) {
                 $this->addDecorator($decoratorInfo);
             } elseif ($decoratorInfo instanceof Zend_Form_Decorator_Interface) {
-                $this->addDecorator($decoratorInfo);
+                $this->addDecorator(array($decoratorName => $decoratorInfo));
             } elseif (is_array($decoratorInfo)) {
                 $argc    = count($decoratorInfo);
                 $options = array();

Comments

Duplicates ZF-5197

I've added a patch file with Michaël's proposed fix. I modified it a little so it won't throw any unwantend exceptions. It works for me but I haven't fully tested it yet.

I confirm the issue too. The provided patch works well although I have not tested it thoroughly as well.

@Hendri Have you had a chance to fully test it yet?

Assigning to alab -- Christian, when you look at this one, if you resolve it, see if it also closes ZF-5197.

Fixed in r22464 and merged into 1.10 release branch