PEAR is archived and read-only

This mirror preserves historical PEAR package releases and metadata so existing references remain available.

Home » HTML » HTML_QuickForm » Bug #4432

hierselect doesn't work with special characters (/ & blank) in string array key

Details

Submitted2005-05-25 19:11 UTC
Fromchris-r at gmx dot de
Assignedavb
StatusClosed
PackageHTML_QuickForm
PHP Version4.2.2
OSLinux
Roadmaps(Not assigned)

Comments

[2005-05-25 19:11 UTC] chris-r at gmx dot de

Description:
------------
HierSelect worked fine for me until today when I coincidently entered a /(slash) and a space (blank) sign into one of the array fields. The Result was, that i still could select an entry in the first drop down, but the second dropdown menu didn't change. The second dropdown menu even didn't had any values inside, if one of the entries of the first dropdown were a special character like / (slash)

I also found out that other special characters like "&" also don't work. When I put a special character in the second array and I only have 2 arrays in total then it works as well.
For me it seems, that special characters in the first dropdown menu cause problems, but i don't know why.

As you can see in the sourcecode I use strings as array keys and not integers, because I need the string in the database query.

Would be nice if you could fix this, because I don't want to make my customer any regulations of what kind of signs the can use in their lists.

Thank you very much.
Christoph

Reproduce code:
---------------
http://www.artistnews.de/temp/hierselectproblemsource.txt

Expected result:
----------------
expected result should be that it works like if there were no special signs in the dropdown menus. when there are only words without space than it works.

[2005-05-28 15:15 UTC] pear at felixdd dot de

This patch for version 1.12 of hierselect.php will fix all issues concerning usage of nontrivial key values (containing characters javascript variables must not contain).

Also contains a better fix for "hierselect element name contains brackets"-fix of v1.13 (in CVS) - not only [] can now be used.

--- hierselect.php 11 Mar 2005 21:05:34 -0000 1.1.1.1
+++ hierselect.php 28 May 2005 15:12:38 -0000
@@ -237,7 +237,7 @@
$select->loadArray($array);

$value = is_array($v = $select->getValue()) ? $v[0] : key($array);
- $toLoad .= '[\''.$value.'\']';
+ $toLoad .= '[\''.str_replace('\\', '\\\\', $value).'\']';
}
}
}
@@ -289,8 +289,9 @@
*/
function _setJS()
{
- $this->_js = $js = '';
- $this->_jsArrayName = 'hs_' . $this->getName();
+ $js = '';
+ $this->_jsArrayName = 'hs_' . preg_replace('/\W/', '_', $this->getName());
+ $this->_js .= $this->_jsArrayName . " = new Array();\n";
for ($i = 1; $i < $this->_nbElements; $i++) {
$this->_setJSArray($this->_jsArrayName, $this->_options[$i], $js);
}
@@ -313,6 +314,7 @@
*/
function _setJSArray($grpName, $options, &$js, $optValue = '')
{
+ $optValue = str_replace(array('\\', '"'), array('\\\\', '\"'), $optValue);
if (is_array($options)) {
$js = '';
// For a hierselect containing 3 elements:
@@ -320,20 +322,20 @@
// and option 3 has been selected for the 2nd element,
// then the javascript array containing the values to load
// on the 3rd element will have the following name: grpName_1_3
- $name = ($optValue === '') ? $grpName : $grpName.'_'.$optValue;
+ $name = ($optValue === '') ? $grpName : $grpName.'["'.$optValue.'"]';
foreach($options AS $k => $v) {
$this->_setJSArray($name, $v, $js, $k);
}

// if $js !== '' add it to the JavaScript
- $this->_js .= ($js !== '') ? $name." = {\n".$js."\n}\n" : '';
+ $this->_js .= ($js !== '') ? $name." = new Array();\n".$name."[\"_\"] = {\n".$js."\n}\n" : '';
$js = '';
} else {
// $js empty means that we are adding the first element to the JavaScript.
if ($js != '') {
$js .= ",\n";
}
- $js .= '"'.$optValue.'":"'.$options.'"';
+ $js .= '"'.$optValue.'":"'.str_replace(array('\\', '"'), array('\\\\', '\"'), $options).'"';
}
}

@@ -374,13 +376,23 @@
." ctl = frm.form[grpName+'['+i+'][]'];\n"
." }\n"
." if (i <= eleIndex) {\n"
- ." n += \"_\"+ctl.value;\n"
+ ." n += '[\"' + ctl.value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g,'\\\\\"') + '\"]';\n"
." } else {\n"
." ctl.length = 0;\n"
." }\n"
." }\n\n"
- ." var t = eval(\"typeof(\"+arName + n +\")\");\n"
- ." if (t != 'undefined') {\n"
+ ." n += '[\"_\"]';\n"
+ ." var s = (arName + n).split('[');\n"
+ ." var t = true;\n"
+ ." for (var i = 0; i < s.length; i++) {\n"
+ ." if (i > 0)\n"
+ ." s[i] = '[' + s[i];\n"
+ ." if (eval('typeof(' + s.slice(0, i + 1).join('') + ')') == 'undefined') {\n"
+ ." t = false;\n"
+ ." break;\n"
+ ." }\n"
+ ." }\n"
+ ." if (t) {\n"
." var the_array = eval(arName+n);\n"
." var j = 0;\n"
." n = eleIndex + 1;\n"
@@ -393,7 +405,7 @@
." ctl.options[j++] = opt;\n"
." }\n"
." }\n"
- ." if (eleIndex+1 < nbElements) {\n"
+ ." if ((eleIndex + 1) < (nbElements - 1)) {\n"
." swapOptions(frm, grpName, eleIndex+1, nbElements, arName);\n"
." }\n"
."}\n";