ZF-4841: Zend_Form_Decorator_Label->setTag() produces invalid XHMTL

Issue Type: Bug Created: 2008-11-06T14:07:56.000+0000 Last Updated: 2009-11-19T10:22:45.000+0000 Status: Resolved Fix version(s): - 1.9.6 (24/Nov/09)

Reporter: Bryan C. Geraghty (archwisp) Assignee: Matthew Weier O'Phinney (matthew) Tags: - Zend_Form

Related issues: Attachments: - Label.patch



The tag "option" does not appear to be cleared properly when setTag is used and is rendered as an html property.

<pre class="highlight">
$start_date = new Zend_Form_Element_Text('start_date', array('label' => 'Start Date'));


<pre class="highlight">

Start Date

<pre class="highlight">
Index: Form/Decorator/Label.php
--- Form/Decorator/Label.php    (revision 12325)
+++ Form/Decorator/Label.php    (working copy)
@@ -289,6 +289,10 @@
         if (!empty($label)) {
+           if (!empty($tag) && isset($options['tag'])) {
+               unset($options['tag']);
+           }
             $options['class'] = $class;
             $label = $view->formLabel($element->getFullyQualifiedName(), trim($label), $options); 
         } else {


Posted by Michaƫl Perrin (sweedymick) on 2009-07-16T09:03:09.000+0000

I encounter this problem as well, and not only with the Label decorator. Setting a tag on an HtmlTag decorator instance will render some invalid HTML code, with the tag attribute being rendered.

This doesn't happen when no tag is defined (the default one is used instead) because the getTag() method of the decorator (called in the render() method) will try to get this attribute from the options, set it in the object property with the setTag() method, and then explicitly remove the "tag" attribute from the options using removeOption().

The patch I made is slightly different to yours, as the setTag() method now sets the provided tag in the options instead of the class property, and then it will be the getTag() option which will do the same job as it did. I did that to ensure that the default "dt" tag option is never used between the time the object is instantiated and the time it is rendered.

<pre class="highlight">
Index: Form/Decorator/Label.php
--- Form/Decorator/Label.php    (revision 13615)
+++ Form/Decorator/Label.php    (working copy)
@@ -101,7 +101,7 @@
         if (empty($tag)) {
             $this->_tag = null;
         } else {
-            $this->_tag = (string) $tag;
+            $this->setOption('tag', (string) $tag);
         return $this;
@@ -117,7 +117,7 @@
             $tag = $this->getOption('tag');
             if (null !== $tag) {
-                $this->setTag($tag);
+                $this->_tag = $tag;
             return $tag;

Posted by Steve Hollis (stevehollis) on 2009-11-19T10:00:20.000+0000

This issue has a root cause that is not addressed by either of the fixes above.

The getTag() method checks the options array for a tag option and correctly removes it if found. However, when there is an explicit call to setTag(), the tag option is not removed.

If the intention is to clear the tag, this causes a problem as the getTag() method will restore the original tag from the options array if it has been supplied.

If the intention is to change the tag, the 'tag' option is still passed to the HtmlTag decorator and rendered as an attribute.

Since, by default, the decorator is initialised by Zend_Form_Element with a tag option of 'dt', this affects the most common use case.

The fix is to remove the 'tag' option (if it exists) whenever setTag() is called. Patch for Label.php and LabelTest.php attached.

Index: Label.php

--- Label.php (revision 19044) +++ Label.php (working copy) @@ -103,6 +103,8 @@ } else { $this->_tag = (string) $tag; } + $this->removeOption('tag'); + return $this; }

Posted by Matthew Weier O'Phinney (matthew) on 2009-11-19T10:22:45.000+0000

Patch from Steve applied to trunk and 1.9 release branch.

Have you found an issue?

See the Overview section for more details.


© 2006-2018 by Zend, a Rogue Wave Company. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.