Issues

ZF-7048: Zend_View_Helper_FormRadio creates invalid labels and id's

Description

There's a problem when passing an array to Zend_View_Helper_FormRadio that contains positive and negative values,

This array for example


    $opties = array('1'     => 'Some option',
                    '-1'    => 'Another option');

Will generate 2 radio buttons with the id "myname-1". Duplicate id's are not allowed and it also disables you from choosing the desired option. When you choose 'Another option' by clicking the label the radio button for 'Some option' will be selected.

Comments

Component assigned

Although we can't quite match on the full list of valid characters since PHP's regular expressions can't match Unicode character ranges, creating and using this filter instead of the Alnum filter should work for all cases when only 7-bit characters are used in IDs (which should be pretty much always):


<?php

/**
 * @see Zend_Filter_Interface
 */
require_once 'Zend/Filter/Interface.php';

class Zend_Filter_XmlName implements Zend_Filter_Interface
{
    /**
     * Defined by Zend_Filter_Interface
     *
     * Returns the string $value, removing all characters not valid in an XML
     * name as defined by http://www.w3.org/TR/REC-xml/#id.
     *
     * Note that this currently only allows 7-bit-safe characters since
     * preg_replace does not support pattern matching on unicode character
     * ranges.
     *
     * @param  string $value
     * @return string
     */
    public function filter($value)
    {
        $value = preg_replace('/[^A-Za-z0-9:_.-]/', '', (string) $value);
        return substr($value, strspn($value, '0123456789.-'));
    }
}

Patch against 1.8.4PL1:


Index: Zend/View/Helper/FormRadio.php
===================================================================
--- Zend/View/Helper/FormRadio.php      (revision 16719)
+++ Zend/View/Helper/FormRadio.php      (working copy)
@@ -129,8 +129,8 @@
         }

         // add radio buttons to the list.
-        require_once 'Zend/Filter/Alnum.php';
-        $filter = new Zend_Filter_Alnum();
+        require_once 'Zend/Filter/XmlName.php';
+        $filter = new Zend_Filter_XmlName();
         foreach ($options as $opt_value => $opt_label) {

             // Should the label be escaped?
@@ -153,7 +153,7 @@
             }

             // generate ID
-            $optId = $id . '-' . $filter->filter($opt_value);
+            $optId = $filter->filter($id . '-' . $opt_value);

             // Wrap the radios in labels
             $radio = '

There are probably other cases where this new filter should be used as well but I am not going to go looking for them right now. :)

Fixed in 1.11.8 Hell yeah!