ZF-11811: Prevent duplicate attributes on <link> tag when using Zend_View_Helper_HeadLink

Description

The createDataStylesheet method in the HeadLink helper creates duplicate element attributes when they're passed into the $extra variable.

For example:

$this->headLink()->appendStylesheet('/css/auth.less', 'all', null, array('rel' => 'stylesheet/less'));

Outputs:

When what is really wanted is:

Comments

Here's a patch.

--- /usr/share/php/libzend-framework-php/Zend/View/Helper/HeadLink.php 2011-08-08 09:52:13.000000000 -0400 +++ /var/www/interacbh/library/AyotteSoftware/View/Helper/HeadLink.php 2011-10-10 11:05:05.811625279 -0400 @@ -378,8 +378,8 @@ $extras = (array) $extras; }

  • $attributes = compact('rel', 'type', 'href', 'media', 'conditionalStylesheet', 'extras');
  • return $this->createData($attributes);
  • $attributes = compact('rel', 'type', 'href', 'media', 'conditionalStylesheet');
  •  return $this->createData(array_merge($attributes, $extras));
    

    }

    /** @@ -434,4 +434,4 @@ $attributes = compact('rel', 'href', 'type', 'title', 'extras'); return $this->createData($attributes); } -} +} \ No newline at end of file

Your fix modifies the return values of a public method (by removing the 'extras' key). Here is an alternate fix which maintains the same return signature while allowing keys in 'extras' to override the other keys:


Index: library/Zend/View/Helper/HeadLink.php
===================================================================
--- library/Zend/View/Helper/HeadLink.php       (revision 24537)
+++ library/Zend/View/Helper/HeadLink.php       (working copy)
@@ -379,7 +379,7 @@
         }

         $attributes = compact('rel', 'type', 'href', 'media', 'conditionalStylesheet', 'extras');
-        return $this->createData($attributes);
+        return $this->createData($this->_applyExtras($attributes));
     }

     /**
@@ -432,6 +432,24 @@
         $title = (string) $title;

         $attributes = compact('rel', 'href', 'type', 'title', 'extras');
-        return $this->createData($attributes);
+        return $this->createData($this->_applyExtras($attributes));
     }
+
+    /**
+     * Apply any overrides specified in the 'extras' array
+     * @param array $attributes
+     * @return array
+     */
+    protected function _applyExtras($attributes)
+    {
+        if (isset($attributes['extras'])) {
+            foreach ($attributes['extras'] as $eKey=>$eVal) {
+                if (isset($attributes[$eKey])) {
+                    $attributes[$eKey] = $eVal;
+                    unset($attributes['extras'][$eKey]);
+                }
+            }
+        }
+        return $attributes;
+    }
 }
Index: tests/Zend/View/Helper/HeadLinkTest.php
===================================================================
--- tests/Zend/View/Helper/HeadLinkTest.php     (revision 24537)
+++ tests/Zend/View/Helper/HeadLinkTest.php     (working copy)
@@ -467,6 +467,16 @@
         $this->helper->appendStylesheet(array('href' => '/bar/baz', 'id' => 'foo'));
         $this->assertContains('id="foo"', $this->helper->toString());
     }
+
+    /**
+     * @group ZF-11811
+     */
+    public function testHeadLinkAllowsOverrideOfRelAttribute()
+    {
+        $this->helper->appendStylesheet('/css/auth.less', 'all', null, array('rel' => 'stylesheet/less'));
+        $this->assertEquals(1, substr_count($this->helper->toString(), "rel=\""));
+        $this->assertContains('rel="stylesheet/less"', $this->helper->toString());
+    }
 }

 // Call Zend_View_Helper_HeadLinkTest::main() if this source file is executed directly.

All unit tests in the Zend_View_Helper suite pass for me after this addition. Could you please apply this patch and give it a try?

Fixed in trunk (1.12.0): r24814