diff --git a/lib/pear/HTML/QuickForm.php b/lib/pear/HTML/QuickForm.php
index d74dd55ef43..0207066f889 100644
--- a/lib/pear/HTML/QuickForm.php
+++ b/lib/pear/HTML/QuickForm.php
@@ -21,6 +21,10 @@
require_once('PEAR.php');
require_once('HTML/Common.php');
+/**
+ * Static utility methods.
+ */
+require_once('HTML/QuickForm/utils.php');
$GLOBALS['HTML_QUICKFORM_ELEMENT_TYPES'] =
array(
@@ -834,9 +838,15 @@ class HTML_QuickForm extends HTML_Common {
} elseif (false !== ($pos = strpos($elementName, '['))) {
$base = substr($elementName, 0, $pos);
- $idx = "['" . str_replace(array(']', '['), array('', "']['"), substr($elementName, $pos + 1, -1)) . "']";
+ $keys = str_replace(
+ array('\\', '\'', ']', '['), array('\\\\', '\\\'', '', "']['"),
+ substr($elementName, $pos + 1, -1)
+ );
+ $idx = "['" . $keys . "']";
+ $keyArray = explode("']['", $keys);
+
if (isset($this->_submitValues[$base])) {
- $value = eval("return (isset(\$this->_submitValues['{$base}']{$idx})) ? \$this->_submitValues['{$base}']{$idx} : null;");
+ $value = HTML_QuickForm_utils::recursiveValue($this->_submitValues[$base], $keyArray, NULL);
}
if ((is_array($value) || null === $value) && isset($this->_submitFiles[$base])) {
diff --git a/lib/pear/HTML/QuickForm/element.php b/lib/pear/HTML/QuickForm/element.php
index 89597aa8a06..18332ea9997 100644
--- a/lib/pear/HTML/QuickForm/element.php
+++ b/lib/pear/HTML/QuickForm/element.php
@@ -20,6 +20,10 @@
// $Id$
require_once('HTML/Common.php');
+/**
+ * Static utility methods.
+ */
+require_once('HTML/QuickForm/utils.php');
/**
* Base class for form elements
@@ -351,8 +355,12 @@ class HTML_QuickForm_element extends HTML_Common
if (isset($values[$elementName])) {
return $values[$elementName];
} elseif (strpos($elementName, '[')) {
- $myVar = "['" . str_replace(array(']', '['), array('', "']['"), $elementName) . "']";
- return eval("return (isset(\$values$myVar)) ? \$values$myVar : null;");
+ $keys = str_replace(
+ array('\\', '\'', ']', '['), array('\\\\', '\\\'', '', "']['"),
+ $elementName
+ );
+ $arrayKeys = explode("']['", $keys);
+ return HTML_QuickForm_utils::recursiveValue($values, $arrayKeys);
} else {
return null;
}
@@ -483,10 +491,12 @@ class HTML_QuickForm_element extends HTML_Common
if (!strpos($name, '[')) {
return array($name => $value);
} else {
- $valueAry = array();
- $myIndex = "['" . str_replace(array(']', '['), array('', "']['"), $name) . "']";
- eval("\$valueAry$myIndex = \$value;");
- return $valueAry;
+ $keys = str_replace(
+ array('\\', '\'', ']', '['), array('\\\\', '\\\'', '', "']['"),
+ $name
+ );
+ $keysArray = explode("']['", $keys);
+ return HTML_QuickForm_utils::recursiveBuild($keysArray, $value);
}
}
}
diff --git a/lib/pear/HTML/QuickForm/hierselect.php b/lib/pear/HTML/QuickForm/hierselect.php
index 37622297d03..1bce43b6e7a 100644
--- a/lib/pear/HTML/QuickForm/hierselect.php
+++ b/lib/pear/HTML/QuickForm/hierselect.php
@@ -22,6 +22,10 @@
require_once('HTML/QuickForm/group.php');
require_once('HTML/QuickForm/select.php');
+/**
+ * Static utility methods.
+ */
+require_once 'HTML/QuickForm/utils.php';
/**
* Class to dynamically create two or more HTML Select elements
@@ -233,16 +237,19 @@ class HTML_QuickForm_hierselect extends HTML_QuickForm_group
*/
function _setOptions()
{
- $toLoad = '';
+ $arrayKeys = [];
foreach (array_keys($this->_elements) AS $key) {
- $array = eval("return isset(\$this->_options[{$key}]{$toLoad})? \$this->_options[{$key}]{$toLoad}: null;");
- if (is_array($array)) {
- $select =& $this->_elements[$key];
- $select->_options = array();
- $select->loadArray($array);
-
- $value = is_array($v = $select->getValue()) ? $v[0] : key($array);
- $toLoad .= '[\'' . str_replace(array('\\', '\''), array('\\\\', '\\\''), $value) . '\']';
+ if (isset($this->_options[$key])) {
+ if ((empty($arrayKeys)) || HTML_QuickForm_utils::recursiveIsset($this->_options[$key], $arrayKeys)) {
+ $array = empty($arrayKeys) ? $this->_options[$key] : HTML_QuickForm_utils::recursiveValue($this->_options[$key], $arrayKeys);
+ if (is_array($array)) {
+ $select =& $this->_elements[$key];
+ $select->_options = array();
+ $select->loadArray($array);
+ $value = is_array($v = $select->getValue()) ? $v[0] : key($array);
+ $arrayKeys[] = $value;
+ }
+ }
}
}
} // end func _setOptions
@@ -585,4 +592,4 @@ JAVASCRIPT;
// }}}
} // end class HTML_QuickForm_hierselect
-?>
\ No newline at end of file
+?>
diff --git a/lib/pear/HTML/QuickForm/utils.php b/lib/pear/HTML/QuickForm/utils.php
new file mode 100644
index 00000000000..00c6ba8e90e
--- /dev/null
+++ b/lib/pear/HTML/QuickForm/utils.php
@@ -0,0 +1,159 @@
+
+ * @copyright 2001-2018 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version CVS: $Id$
+ * @link http://pear.php.net/package/HTML_QuickForm
+ */
+
+/**
+ * Provides a collection of static methods for array manipulation.
+ *
+ * (courtesy of CiviCRM project (https://civicrm.org/)
+ *
+ * @category HTML
+ * @package HTML_QuickForm
+ * @author Chuck Burgess
+ * @version Release: @package_version@
+ * @since 3.2
+ */
+class HTML_QuickForm_utils
+{
+ /**
+ * Get a single value from an array-tree.
+ *
+ * @param array $values Ex: ['foo' => ['bar' => 123]].
+ * @param array $path Ex: ['foo', 'bar'].
+ * @param mixed $default
+ * @return mixed Ex 123.
+ *
+ * @access public
+ * @static
+ */
+ static function pathGet($values, $path, $default = NULL) {
+ foreach ($path as $key) {
+ if (!is_array($values) || !isset($values[$key])) {
+ return $default;
+ }
+ $values = $values[$key];
+ }
+ return $values;
+ }
+
+ /**
+ * Check if a key isset which may be several layers deep.
+ *
+ * This is a helper for when the calling function does not know how many layers deep
+ * the path array is so cannot easily check.
+ *
+ * @param array $values
+ * @param array $path
+ * @return bool
+ *
+ * @access public
+ * @static
+ */
+ static function pathIsset($values, $path) {
+ foreach ($path as $key) {
+ if (!is_array($values) || !isset($values[$key])) {
+ return FALSE;
+ }
+ $values = $values[$key];
+ }
+ return TRUE;
+ }
+
+ /**
+ * Set a single value in an array tree.
+ *
+ * @param array $values Ex: ['foo' => ['bar' => 123]].
+ * @param array $pathParts Ex: ['foo', 'bar'].
+ * @param mixed $value Ex: 456.
+ * @return void
+ *
+ * @access public
+ * @static
+ */
+ static function pathSet(&$values, $pathParts, $value) {
+ $r = &$values;
+ $last = array_pop($pathParts);
+ foreach ($pathParts as $part) {
+ if (!isset($r[$part])) {
+ $r[$part] = array();
+ }
+ $r = &$r[$part];
+ }
+ $r[$last] = $value;
+ }
+
+ /**
+ * Check if a key isset which may be several layers deep.
+ *
+ * This is a helper for when the calling function does not know how many layers deep the
+ * path array is so cannot easily check.
+ *
+ * @param array $array
+ * @param array $path
+ * @return bool
+ *
+ * @access public
+ * @static
+ */
+ static function recursiveIsset($array, $path) {
+ return self::pathIsset($array, $path);
+ }
+
+ /**
+ * Check if a key isset which may be several layers deep.
+ *
+ * This is a helper for when the calling function does not know how many layers deep the
+ * path array is so cannot easily check.
+ *
+ * @param array $array
+ * @param array $path An array of keys,
+ * e.g [0, 'bob', 8] where we want to check if $array[0]['bob'][8]
+ * @param mixed $default Value to return if not found.
+ * @return bool
+ *
+ * @access public
+ * @static
+ */
+ static function recursiveValue($array, $path, $default = NULL) {
+ return self::pathGet($array, $path, $default);
+ }
+
+ /**
+ * Append the value to the array using the key provided.
+ *
+ * e.g if value is 'llama' & path is [0, 'email', 'location'] result will be
+ * [0 => ['email' => ['location' => 'llama']]
+ *
+ * @param $path
+ * @param $value
+ * @param array $source
+ * @return array
+ *
+ * @access public
+ * @static
+ */
+ static function recursiveBuild($path, $value, $source = array()) {
+ self::pathSet($source, $path, $value);
+ return $source;
+ }
+}
+?>