AutorÃa | Ultima modificación | Ver Log |
<?php/* vim: set expandtab tabstop=4 shiftwidth=4: */// +----------------------------------------------------------------------+// | PHP version 4.0 |// +----------------------------------------------------------------------+// | Copyright (c) 1997-2003 The PHP Group |// +----------------------------------------------------------------------+// | This source file is subject to version 2.0 of the PHP license, |// | that is bundled with this package in the file LICENSE, and is |// | available at through the world-wide-web at |// | http://www.php.net/license/2_02.txt. |// | If you did not receive a copy of the PHP license and are unable to |// | obtain it through the world-wide-web, please send a note to |// | license@php.net so we can mail you a copy immediately. |// +----------------------------------------------------------------------+// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> |// | Bertrand Mansion <bmansion@mamasam.com> |// +----------------------------------------------------------------------+//// $Id$require_once('PEAR.php');require_once('HTML/Common.php');/*** Static utility methods.*/require_once('HTML/QuickForm/utils.php');$GLOBALS['HTML_QUICKFORM_ELEMENT_TYPES'] =array('group' =>array('HTML/QuickForm/group.php','HTML_QuickForm_group'),'hidden' =>array('HTML/QuickForm/hidden.php','HTML_QuickForm_hidden'),'reset' =>array('HTML/QuickForm/reset.php','HTML_QuickForm_reset'),'checkbox' =>array('HTML/QuickForm/checkbox.php','HTML_QuickForm_checkbox'),'file' =>array('HTML/QuickForm/file.php','HTML_QuickForm_file'),'image' =>array('HTML/QuickForm/image.php','HTML_QuickForm_image'),'password' =>array('HTML/QuickForm/password.php','HTML_QuickForm_password'),'radio' =>array('HTML/QuickForm/radio.php','HTML_QuickForm_radio'),'button' =>array('HTML/QuickForm/button.php','HTML_QuickForm_button'),'submit' =>array('HTML/QuickForm/submit.php','HTML_QuickForm_submit'),'select' =>array('HTML/QuickForm/select.php','HTML_QuickForm_select'),'hiddenselect' =>array('HTML/QuickForm/hiddenselect.php','HTML_QuickForm_hiddenselect'),'text' =>array('HTML/QuickForm/text.php','HTML_QuickForm_text'),'textarea' =>array('HTML/QuickForm/textarea.php','HTML_QuickForm_textarea'),'link' =>array('HTML/QuickForm/link.php','HTML_QuickForm_link'),'advcheckbox' =>array('HTML/QuickForm/advcheckbox.php','HTML_QuickForm_advcheckbox'),'date' =>array('HTML/QuickForm/date.php','HTML_QuickForm_date'),'static' =>array('HTML/QuickForm/static.php','HTML_QuickForm_static'),'header' =>array('HTML/QuickForm/header.php', 'HTML_QuickForm_header'),'html' =>array('HTML/QuickForm/html.php', 'HTML_QuickForm_html'),'hierselect' =>array('HTML/QuickForm/hierselect.php', 'HTML_QuickForm_hierselect'),'autocomplete' =>array('HTML/QuickForm/autocomplete.php', 'HTML_QuickForm_autocomplete'),'xbutton' =>array('HTML/QuickForm/xbutton.php','HTML_QuickForm_xbutton'));$GLOBALS['_HTML_QuickForm_registered_rules'] = array('required' => array('html_quickform_rule_required', 'HTML/QuickForm/Rule/Required.php'),'maxlength' => array('html_quickform_rule_range', 'HTML/QuickForm/Rule/Range.php'),'minlength' => array('html_quickform_rule_range', 'HTML/QuickForm/Rule/Range.php'),'rangelength' => array('html_quickform_rule_range', 'HTML/QuickForm/Rule/Range.php'),'email' => array('html_quickform_rule_email', 'HTML/QuickForm/Rule/Email.php'),'regex' => array('html_quickform_rule_regex', 'HTML/QuickForm/Rule/Regex.php'),'lettersonly' => array('html_quickform_rule_regex', 'HTML/QuickForm/Rule/Regex.php'),'alphanumeric' => array('html_quickform_rule_regex', 'HTML/QuickForm/Rule/Regex.php'),'numeric' => array('html_quickform_rule_regex', 'HTML/QuickForm/Rule/Regex.php'),'nopunctuation' => array('html_quickform_rule_regex', 'HTML/QuickForm/Rule/Regex.php'),'nonzero' => array('html_quickform_rule_regex', 'HTML/QuickForm/Rule/Regex.php'),'positiveint' => array('html_quickform_rule_regex', 'HTML/QuickForm/Rule/Regex.php'),'callback' => array('html_quickform_rule_callback', 'HTML/QuickForm/Rule/Callback.php'),'compare' => array('html_quickform_rule_compare', 'HTML/QuickForm/Rule/Compare.php'));// {{{ error codes/** Error codes for the QuickForm interface, which will be mapped to textual messages* in the QuickForm::errorMessage() function. If you are to add a new error code, be* sure to add the textual messages to the QuickForm::errorMessage() function as well*/define('QUICKFORM_OK', 1);define('QUICKFORM_ERROR', -1);define('QUICKFORM_INVALID_RULE', -2);define('QUICKFORM_NONEXIST_ELEMENT', -3);define('QUICKFORM_INVALID_FILTER', -4);define('QUICKFORM_UNREGISTERED_ELEMENT', -5);define('QUICKFORM_INVALID_ELEMENT_NAME', -6);define('QUICKFORM_INVALID_PROCESS', -7);define('QUICKFORM_DEPRECATED', -8);define('QUICKFORM_INVALID_DATASOURCE', -9);// }}}/*** Create, validate and process HTML forms** @author Adam Daniel <adaniel1@eesus.jnj.com>* @author Bertrand Mansion <bmansion@mamasam.com>* @version 2.0* @since PHP 4.0.3pl1*/class HTML_QuickForm extends HTML_Common {// {{{ properties/*** Array containing the form fields* @since 1.0* @var array* @access private*/var $_elements = array();/*** Array containing element name to index map* @since 1.1* @var array* @access private*/var $_elementIndex = array();/*** Array containing indexes of duplicate elements* @since 2.10* @var array* @access private*/var $_duplicateIndex = array();/*** Array containing required field IDs* @since 1.0* @var array* @access private*/var $_required = array();/*** Prefix message in javascript alert if error* @since 1.0* @var string* @access public*/var $_jsPrefix = 'Invalid information entered.';/*** Postfix message in javascript alert if error* @since 1.0* @var string* @access public*/var $_jsPostfix = 'Please correct these fields.';/*** Datasource object implementing the informal* datasource protocol* @since 3.3* @var object* @access private*/var $_datasource;/*** Array of default form values* @since 2.0* @var array* @access private*/var $_defaultValues = array();/*** Array of constant form values* @since 2.0* @var array* @access private*/var $_constantValues = array();/*** Array of submitted form values* @since 1.0* @var array* @access private*/var $_submitValues = array();/*** Array of submitted form files* @since 1.0* @var integer* @access public*/var $_submitFiles = array();/*** Value for maxfilesize hidden element if form contains file input* @since 1.0* @var integer* @access public*/var $_maxFileSize = 1048576; // 1 Mb = 1048576/*** Flag to know if all fields are frozen* @since 1.0* @var boolean* @access private*/var $_freezeAll = false;/*** Array containing the form rules* @since 1.0* @var array* @access private*/var $_rules = array();/*** Form rules, global variety* @var array* @access private*/var $_formRules = array();/*** Array containing the validation errors* @since 1.0* @var array* @access private*/var $_errors = array();/*** Note for required fields in the form* @var string* @since 1.0* @access private*/var $_requiredNote = '<span style="font-size:80%; color:#ff0000;">*</span><span style="font-size:80%;"> denotes required field</span>';/*** Whether the form was submitted* @var boolean* @access private*/var $_flagSubmitted = false;// }}}// {{{ constructor/*** Class constructor* @param string $formName Form's name.* @param string $method (optional)Form's method defaults to 'POST'* @param string $action (optional)Form's action* @param string $target (optional)Form's target defaults to '_self'* @param mixed $attributes (optional)Extra attributes for <form> tag* @param bool $trackSubmit (optional)Whether to track if the form was submitted by adding a special hidden field* @access public*/public function __construct($formName='', $method='post', $action='', $target='', $attributes=null, $trackSubmit = false){parent::__construct($attributes);$method = (strtoupper($method) == 'GET') ? 'get' : 'post';$action = ($action == '') ? $_SERVER['PHP_SELF'] : $action;$target = empty($target) ? array() : array('target' => $target);$attributes = array('action'=>$action, 'method'=>$method, 'name'=>$formName, 'id'=>$formName) + $target;$this->updateAttributes($attributes);if (!$trackSubmit || isset($_REQUEST['_qf__' . $formName])) {$this->_submitValues = 'get' == $method? $_GET: $_POST;$this->_submitFiles = $_FILES;$this->_flagSubmitted = count($this->_submitValues) > 0 || count($this->_submitFiles) > 0;}if ($trackSubmit) {unset($this->_submitValues['_qf__' . $formName]);$this->addElement('hidden', '_qf__' . $formName, null);}if (preg_match('/^([0-9]+)([a-zA-Z]*)$/', ini_get('upload_max_filesize'), $matches)) {// see http://www.php.net/manual/en/faq.using.php#faq.using.shorthandbytesswitch (strtoupper($matches['2'])) {case 'G':$this->_maxFileSize = $matches['1'] * 1073741824;break;case 'M':$this->_maxFileSize = $matches['1'] * 1048576;break;case 'K':$this->_maxFileSize = $matches['1'] * 1024;break;default:$this->_maxFileSize = $matches['1'];}}} // end constructor/*** Old syntax of class constructor. Deprecated in PHP7.** @deprecated since Moodle 3.1*/public function HTML_QuickForm($formName='', $method='post', $action='', $target='', $attributes=null, $trackSubmit = false) {debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER);self::__construct($formName, $method, $action, $target, $attributes, $trackSubmit);}// }}}// {{{ apiVersion()/*** Returns the current API version** @since 1.0* @access public* @return float*/function apiVersion(){return 3.2;} // end func apiVersion// }}}// {{{ registerElementType()/*** Registers a new element type** @param string $typeName Name of element type* @param string $include Include path for element type* @param string $className Element class name* @since 1.0* @access public* @return void*/static function registerElementType($typeName, $include, $className){$GLOBALS['HTML_QUICKFORM_ELEMENT_TYPES'][strtolower($typeName)] = array($include, $className);} // end func registerElementType// }}}// {{{ registerRule()/*** Registers a new validation rule** @param string $ruleName Name of validation rule* @param string $type Either: 'regex', 'function' or 'rule' for an HTML_QuickForm_Rule object* @param string $data1 Name of function, regular expression or HTML_QuickForm_Rule classname* @param string $data2 Object parent of above function or HTML_QuickForm_Rule file path* @since 1.0* @access public* @return void*/static function registerRule($ruleName, $type, $data1, $data2 = null){include_once('HTML/QuickForm/RuleRegistry.php');$registry =& HTML_QuickForm_RuleRegistry::singleton();$registry->registerRule($ruleName, $type, $data1, $data2);} // end func registerRule// }}}// {{{ elementExists()/*** Returns true if element is in the form** @param string $element form name of element to check* @since 1.0* @access public* @return boolean*/function elementExists($element=null){return isset($this->_elementIndex[$element]);} // end func elementExists// }}}// {{{ setDatasource()/*** Sets a datasource object for this form object** Datasource default and constant values will feed the QuickForm object if* the datasource implements defaultValues() and constantValues() methods.** @param object $datasource datasource object implementing the informal datasource protocol* @param mixed $defaultsFilter string or array of filter(s) to apply to default values* @param mixed $constantsFilter string or array of filter(s) to apply to constants values* @since 3.3* @access public* @return void*/function setDatasource(&$datasource, $defaultsFilter = null, $constantsFilter = null){if (is_object($datasource)) {$this->_datasource =& $datasource;if (is_callable(array($datasource, 'defaultValues'))) {$this->setDefaults($datasource->defaultValues($this), $defaultsFilter);}if (is_callable(array($datasource, 'constantValues'))) {$this->setConstants($datasource->constantValues($this), $constantsFilter);}} else {return self::raiseError(null, QUICKFORM_INVALID_DATASOURCE, null, E_USER_WARNING, "Datasource is not an object in QuickForm::setDatasource()", 'HTML_QuickForm_Error', true);}} // end func setDatasource// }}}// {{{ setDefaults()/*** Initializes default form values** @param array $defaultValues values used to fill the form* @param mixed $filter (optional) filter(s) to apply to all default values* @since 1.0* @access public* @return void*/function setDefaults($defaultValues = null, $filter = null){if (is_array($defaultValues)) {if (isset($filter)) {if (is_array($filter) && (2 != count($filter) || !is_callable($filter))) {foreach ($filter as $val) {if (!is_callable($val)) {return self::raiseError(null, QUICKFORM_INVALID_FILTER, null, E_USER_WARNING, "Callback function does not exist in QuickForm::setDefaults()", 'HTML_QuickForm_Error', true);} else {$defaultValues = $this->_recursiveFilter($val, $defaultValues);}}} elseif (!is_callable($filter)) {return self::raiseError(null, QUICKFORM_INVALID_FILTER, null, E_USER_WARNING, "Callback function does not exist in QuickForm::setDefaults()", 'HTML_QuickForm_Error', true);} else {$defaultValues = $this->_recursiveFilter($filter, $defaultValues);}}$this->_defaultValues = HTML_QuickForm::arrayMerge($this->_defaultValues, $defaultValues);foreach (array_keys($this->_elements) as $key) {$this->_elements[$key]->onQuickFormEvent('updateValue', null, $this);}}} // end func setDefaults// }}}// {{{ setConstants()/*** Initializes constant form values.* These values won't get overridden by POST or GET vars** @param array $constantValues values used to fill the form* @param mixed $filter (optional) filter(s) to apply to all default values** @since 2.0* @access public* @return void*/function setConstants($constantValues = null, $filter = null){if (is_array($constantValues)) {if (isset($filter)) {if (is_array($filter) && (2 != count($filter) || !is_callable($filter))) {foreach ($filter as $val) {if (!is_callable($val)) {return self::raiseError(null, QUICKFORM_INVALID_FILTER, null, E_USER_WARNING, "Callback function does not exist in QuickForm::setConstants()", 'HTML_QuickForm_Error', true);} else {$constantValues = $this->_recursiveFilter($val, $constantValues);}}} elseif (!is_callable($filter)) {return self::raiseError(null, QUICKFORM_INVALID_FILTER, null, E_USER_WARNING, "Callback function does not exist in QuickForm::setConstants()", 'HTML_QuickForm_Error', true);} else {$constantValues = $this->_recursiveFilter($filter, $constantValues);}}$this->_constantValues = HTML_QuickForm::arrayMerge($this->_constantValues, $constantValues);foreach (array_keys($this->_elements) as $key) {$this->_elements[$key]->onQuickFormEvent('updateValue', null, $this);}}} // end func setConstants// }}}// {{{ setMaxFileSize()/*** Sets the value of MAX_FILE_SIZE hidden element** @param int $bytes Size in bytes* @since 3.0* @access public* @return void*/function setMaxFileSize($bytes = 0){if ($bytes > 0) {$this->_maxFileSize = $bytes;}if (!$this->elementExists('MAX_FILE_SIZE')) {$this->addElement('hidden', 'MAX_FILE_SIZE', $this->_maxFileSize);} else {$el =& $this->getElement('MAX_FILE_SIZE');$el->updateAttributes(array('value' => $this->_maxFileSize));}} // end func setMaxFileSize// }}}// {{{ getMaxFileSize()/*** Returns the value of MAX_FILE_SIZE hidden element** @since 3.0* @access public* @return int max file size in bytes*/function getMaxFileSize(){return $this->_maxFileSize;} // end func getMaxFileSize// }}}// {{{ &createElement()/*** Creates a new form element of the given type.** This method accepts variable number of parameters, their* meaning and count depending on $elementType** @param string $elementType type of element to add (text, textarea, file...)* @since 1.0* @access public* @return object extended class of HTML_element* @throws HTML_QuickForm_Error*/function &createElement($elementType){if (!isset($this) || !($this instanceof HTML_QuickForm)) {// Several form elements in Moodle core before 3.2 were calling this method// statically suppressing PHP notices. This debugging message should notify// developers who copied such code and did not test their plugins on PHP 7.1.// Example of fixing group form elements can be found in commit// https://github.com/moodle/moodle/commit/721e2def56a48fab4f8d3ec7847af5cd03f5ec79debugging('Function createElement() can not be called statically, ' .'this will no longer work in PHP 7.1',DEBUG_DEVELOPER);}$args = func_get_args();$element = self::_loadElement('createElement', $elementType, array_slice($args, 1));return $element;} // end func createElement// }}}// {{{ _loadElement()/*** Returns a form element of the given type** @param string $event event to send to newly created element ('createElement' or 'addElement')* @param string $type element type* @param array $args arguments for event* @since 2.0* @access private* @return object a new element* @throws HTML_QuickForm_Error*/function &_loadElement($event, $type, $args){$type = strtolower($type);if (!self::isTypeRegistered($type)) {$error = self::raiseError(null, QUICKFORM_UNREGISTERED_ELEMENT, null, E_USER_WARNING, "Element '$type' does not exist in HTML_QuickForm::_loadElement()", 'HTML_QuickForm_Error', true);return $error;}$className = $GLOBALS['HTML_QUICKFORM_ELEMENT_TYPES'][$type][1];$includeFile = $GLOBALS['HTML_QUICKFORM_ELEMENT_TYPES'][$type][0];include_once($includeFile);$elementObject = new $className(); //Moodle: PHP 5.3 compatibilityfor ($i = 0; $i < 6; $i++) {if (!isset($args[$i])) {$args[$i] = null;}}$err = $elementObject->onQuickFormEvent($event, $args, $this);if ($err !== true) {return $err;}return $elementObject;} // end func _loadElement// }}}// {{{ addElement()/*** Adds an element into the form** If $element is a string representing element type, then this* method accepts variable number of parameters, their meaning* and count depending on $element** @param mixed $element element object or type of element to add (text, textarea, file...)* @since 1.0* @return object reference to element* @access public* @throws HTML_QuickForm_Error*/function &addElement($element){if (is_object($element) && is_subclass_of($element, 'html_quickform_element')) {$elementObject = &$element;$elementObject->onQuickFormEvent('updateValue', null, $this);} else {$args = func_get_args();$elementObject =& $this->_loadElement('addElement', $element, array_slice($args, 1));$pear = new PEAR();if ($pear->isError($elementObject)) {return $elementObject;}}$elementName = $elementObject->getName();// Add the element if it is not an incompatible duplicateif (!empty($elementName) && isset($this->_elementIndex[$elementName])) {if ($this->_elements[$this->_elementIndex[$elementName]]->getType() ==$elementObject->getType()) {$this->_elements[] =& $elementObject;$elKeys = array_keys($this->_elements);$this->_duplicateIndex[$elementName][] = end($elKeys);} else {$error = self::raiseError(null, QUICKFORM_INVALID_ELEMENT_NAME, null, E_USER_WARNING, "Element '$elementName' already exists in HTML_QuickForm::addElement()", 'HTML_QuickForm_Error', true);return $error;}} else {$this->_elements[] =& $elementObject;$elKeys = array_keys($this->_elements);$this->_elementIndex[$elementName] = end($elKeys);}if ($this->_freezeAll) {$elementObject->freeze();}return $elementObject;} // end func addElement// }}}// {{{ insertElementBefore()/*** Inserts a new element right before the other element** Warning: it is not possible to check whether the $element is already* added to the form, therefore if you want to move the existing form* element to a new position, you'll have to use removeElement():* $form->insertElementBefore($form->removeElement('foo', false), 'bar');** @access public* @since 3.2.4* @param object HTML_QuickForm_element Element to insert* @param string Name of the element before which the new one is inserted* @return object HTML_QuickForm_element reference to inserted element* @throws HTML_QuickForm_Error*/function &insertElementBefore(&$element, $nameAfter){if (!empty($this->_duplicateIndex[$nameAfter])) {$error = self::raiseError(null, QUICKFORM_INVALID_ELEMENT_NAME, null, E_USER_WARNING, 'Several elements named "' . $nameAfter . '" exist in HTML_QuickForm::insertElementBefore().', 'HTML_QuickForm_Error', true);return $error;} elseif (!$this->elementExists($nameAfter)) {$error = self::raiseError(null, QUICKFORM_NONEXIST_ELEMENT, null, E_USER_WARNING, "Element '$nameAfter' does not exist in HTML_QuickForm::insertElementBefore()", 'HTML_QuickForm_Error', true);return $error;}$elementName = $element->getName();$targetIdx = $this->_elementIndex[$nameAfter];$duplicate = false;// Like in addElement(), check that it's not an incompatible duplicateif (!empty($elementName) && isset($this->_elementIndex[$elementName])) {if ($this->_elements[$this->_elementIndex[$elementName]]->getType() != $element->getType()) {$error = self::raiseError(null, QUICKFORM_INVALID_ELEMENT_NAME, null, E_USER_WARNING, "Element '$elementName' already exists in HTML_QuickForm::insertElementBefore()", 'HTML_QuickForm_Error', true);return $error;}$duplicate = true;}// Move all the elements after added back one place, reindex _elementIndex and/or _duplicateIndex$elKeys = array_keys($this->_elements);for ($i = end($elKeys); $i >= $targetIdx; $i--) {if (isset($this->_elements[$i])) {$currentName = $this->_elements[$i]->getName();$this->_elements[$i + 1] =& $this->_elements[$i];if ($this->_elementIndex[$currentName] == $i) {$this->_elementIndex[$currentName] = $i + 1;} else {if (!empty($currentName)) {$dupIdx = array_search($i, $this->_duplicateIndex[$currentName]);$this->_duplicateIndex[$currentName][$dupIdx] = $i + 1;}}unset($this->_elements[$i]);}}// Put the element in place finally$this->_elements[$targetIdx] =& $element;if (!$duplicate) {$this->_elementIndex[$elementName] = $targetIdx;} else {$this->_duplicateIndex[$elementName][] = $targetIdx;}$element->onQuickFormEvent('updateValue', null, $this);if ($this->_freezeAll) {$element->freeze();}// If not done, the elements will appear in reverse orderksort($this->_elements);return $element;}// }}}// {{{ addGroup()/*** Adds an element group* @param array $elements array of elements composing the group* @param string $name (optional)group name* @param string $groupLabel (optional)group label* @param string|array $separator (optional) Use a string for one separator, or use an array to alternate the separators* @param bool $appendName (optional)specify whether the group name should be* used in the form element name ex: group[element]* @param mixed $attributes Either a typical HTML attribute string or an associative array* @return object reference to added group of elements* @since 2.8* @access public* @throws PEAR_Error*/function &addGroup($elements, $name = null, $groupLabel = '', $separator = null, $appendName = true, $attributes = null){static $anonGroups = 1;if (0 == strlen($name ?? '')) {$name = 'qf_group_' . $anonGroups++;$appendName = false;}$group =& $this->addElement('group', $name, $groupLabel, $elements, $separator, $appendName, $attributes);return $group;} // end func addGroup// }}}// {{{ &getElement()/*** Returns a reference to the element** @param string $element Element name* @since 2.0* @access public* @return object reference to element* @throws HTML_QuickForm_Error*/function &getElement($element){if (isset($this->_elementIndex[$element])) {return $this->_elements[$this->_elementIndex[$element]];} else {$error = self::raiseError(null, QUICKFORM_NONEXIST_ELEMENT, null, E_USER_WARNING, "Element '$element' does not exist in HTML_QuickForm::getElement()", 'HTML_QuickForm_Error', true);return $error;}} // end func getElement// }}}// {{{ &getElementValue()/*** Returns the element's raw value** This returns the value as submitted by the form (not filtered)* or set via setDefaults() or setConstants()** @param string $element Element name* @since 2.0* @access public* @return mixed element value* @throws HTML_QuickForm_Error*/function &getElementValue($element){if (!isset($this->_elementIndex[$element])) {$error = self::raiseError(null, QUICKFORM_NONEXIST_ELEMENT, null, E_USER_WARNING, "Element '$element' does not exist in HTML_QuickForm::getElementValue()", 'HTML_QuickForm_Error', true);return $error;}$value = $this->_elements[$this->_elementIndex[$element]]->getValue();if (isset($this->_duplicateIndex[$element])) {foreach ($this->_duplicateIndex[$element] as $index) {if (null !== ($v = $this->_elements[$index]->getValue())) {if (is_array($value)) {$value[] = $v;} else {$value = (null === $value)? $v: array($value, $v);}}}}return $value;} // end func getElementValue// }}}// {{{ getSubmitValue()/*** Returns the elements value after submit and filter** @param string Element name* @since 2.0* @access public* @return mixed submitted element value or null if not set*/function getSubmitValue($elementName){$value = null;$elementName = $elementName ?? '';if (isset($this->_submitValues[$elementName]) || isset($this->_submitFiles[$elementName])) {$value = isset($this->_submitValues[$elementName])? $this->_submitValues[$elementName]: array();if (is_array($value) && isset($this->_submitFiles[$elementName])) {foreach ($this->_submitFiles[$elementName] as $k => $v) {$value = HTML_QuickForm::arrayMerge($value, $this->_reindexFiles($this->_submitFiles[$elementName][$k], $k));}}} elseif ('file' == $this->getElementType($elementName)) {return $this->getElementValue($elementName);} elseif (false !== ($pos = strpos($elementName, '['))) {$base = substr($elementName, 0, $pos);$keys = str_replace(array('\\', '\'', ']', '['), array('\\\\', '\\\'', '', "']['"),substr($elementName, $pos + 1, -1));$idx = "['" . $keys . "']";$keyArray = explode("']['", $keys);if (isset($this->_submitValues[$base])) {$value = HTML_QuickForm_utils::recursiveValue($this->_submitValues[$base], $keyArray, NULL);}if ((is_array($value) || null === $value) && isset($this->_submitFiles[$base])) {$props = array('name', 'type', 'size', 'tmp_name', 'error');$code = "if (!isset(\$this->_submitFiles['{$base}']['name']{$idx})) {\n" ." return null;\n" ."} else {\n" ." \$v = array();\n";foreach ($props as $prop) {$code .= " \$v = HTML_QuickForm::arrayMerge(\$v, \$this->_reindexFiles(\$this->_submitFiles['{$base}']['{$prop}']{$idx}, '{$prop}'));\n";}$fileValue = eval($code . " return \$v;\n}\n");if (null !== $fileValue) {$value = null === $value? $fileValue: HTML_QuickForm::arrayMerge($value, $fileValue);}}}// This is only supposed to work for groups with appendName = falseif (null === $value && 'group' == $this->getElementType($elementName)) {$group =& $this->getElement($elementName);$elements =& $group->getElements();foreach (array_keys($elements) as $key) {$name = $group->getElementName($key);// prevent endless recursion in case of radios and suchif ($name != $elementName) {if (null !== ($v = $this->getSubmitValue($name))) {$value[$name] = $v;}}}}return $value;} // end func getSubmitValue// }}}// {{{ _reindexFiles()/*** A helper function to change the indexes in $_FILES array** @param mixed Some value from the $_FILES array* @param string The key from the $_FILES array that should be appended* @return array*/function _reindexFiles($value, $key){if (!is_array($value)) {return array($key => $value);} else {$ret = array();foreach ($value as $k => $v) {$ret[$k] = $this->_reindexFiles($v, $key);}return $ret;}}// }}}// {{{ getElementError()/*** Returns error corresponding to validated element** @param string $element Name of form element to check* @since 1.0* @access public* @return ?string error message corresponding to checked element*/function getElementError($element){if (isset($this->_errors[$element])) {return $this->_errors[$element];}} // end func getElementError// }}}// {{{ setElementError()/*** Set error message for a form element** @param string $element Name of form element to set error for* @param string $message Error message, if empty then removes the current error message* @since 1.0* @access public* @return void*/function setElementError($element, $message = null){if (!empty($message)) {$this->_errors[$element] = $message;} else {unset($this->_errors[$element]);}} // end func setElementError// }}}// {{{ getElementType()/*** Returns the type of the given element** @param string $element Name of form element* @since 1.1* @access public* @return string Type of the element, false if the element is not found*/function getElementType($element){if (isset($this->_elementIndex[$element])) {return $this->_elements[$this->_elementIndex[$element]]->getType();}return false;} // end func getElementType// }}}// {{{ updateElementAttr()/*** Updates Attributes for one or more elements** @param mixed $elements Array of element names/objects or string of elements to be updated* @param mixed $attrs Array or sting of html attributes* @since 2.10* @access public* @return void*/function updateElementAttr($elements, $attrs){if (is_string($elements)) {$elements = preg_split('/[ ]?,[ ]?/', $elements);}foreach (array_keys($elements) as $key) {if (is_object($elements[$key]) && is_a($elements[$key], 'HTML_QuickForm_element')) {$elements[$key]->updateAttributes($attrs);} elseif (isset($this->_elementIndex[$elements[$key]])) {$this->_elements[$this->_elementIndex[$elements[$key]]]->updateAttributes($attrs);if (isset($this->_duplicateIndex[$elements[$key]])) {foreach ($this->_duplicateIndex[$elements[$key]] as $index) {$this->_elements[$index]->updateAttributes($attrs);}}}}} // end func updateElementAttr// }}}// {{{ removeElement()/*** Removes an element** The method "unlinks" an element from the form, returning the reference* to the element object. If several elements named $elementName exist,* it removes the first one, leaving the others intact.** @param string $elementName The element name* @param boolean $removeRules True if rules for this element are to be removed too* @access public* @since 2.0* @return object HTML_QuickForm_element a reference to the removed element* @throws HTML_QuickForm_Error*/function &removeElement($elementName, $removeRules = true){if (!isset($this->_elementIndex[$elementName])) {$error = self::raiseError(null, QUICKFORM_NONEXIST_ELEMENT, null, E_USER_WARNING, "Element '$elementName' does not exist in HTML_QuickForm::removeElement()", 'HTML_QuickForm_Error', true);return $error;}$el =& $this->_elements[$this->_elementIndex[$elementName]];unset($this->_elements[$this->_elementIndex[$elementName]]);if (empty($this->_duplicateIndex[$elementName])) {unset($this->_elementIndex[$elementName]);} else {$this->_elementIndex[$elementName] = array_shift($this->_duplicateIndex[$elementName]);}if ($removeRules) {unset($this->_rules[$elementName], $this->_errors[$elementName]);}return $el;} // end func removeElement// }}}// {{{ addRule()/*** Adds a validation rule for the given field** If the element is in fact a group, it will be considered as a whole.* To validate grouped elements as separated entities,* use addGroupRule instead of addRule.** @param string $element Form element name* @param string $message Message to display for invalid data* @param string $type Rule type, use getRegisteredRules() to get types* @param string $format (optional)Required for extra rule data* @param string $validation (optional)Where to perform validation: "server", "client"* @param boolean $reset Client-side validation: reset the form element to its original value if there is an error?* @param boolean $force Force the rule to be applied, even if the target form element does not exist* @since 1.0* @access public* @throws HTML_QuickForm_Error*/function addRule($element, $message, $type, $format=null, $validation='server', $reset = false, $force = false){if (!$force) {if (!is_array($element) && !$this->elementExists($element)) {return self::raiseError(null, QUICKFORM_NONEXIST_ELEMENT, null, E_USER_WARNING, "Element '$element' does not exist in HTML_QuickForm::addRule()", 'HTML_QuickForm_Error', true);} elseif (is_array($element)) {foreach ($element as $el) {if (!$this->elementExists($el)) {return self::raiseError(null, QUICKFORM_NONEXIST_ELEMENT, null, E_USER_WARNING, "Element '$el' does not exist in HTML_QuickForm::addRule()", 'HTML_QuickForm_Error', true);}}}}if (false === ($newName = $this->isRuleRegistered($type, true))) {return self::raiseError(null, QUICKFORM_INVALID_RULE, null, E_USER_WARNING, "Rule '$type' is not registered in HTML_QuickForm::addRule()", 'HTML_QuickForm_Error', true);} elseif (is_string($newName)) {$type = $newName;}if (is_array($element)) {$dependent = $element;$element = array_shift($dependent);} else {$dependent = null;}if ($type == 'required' || $type == 'uploadedfile') {$this->_required[] = $element;}if (!isset($this->_rules[$element])) {$this->_rules[$element] = array();}$this->_rules[$element][] = array('type' => $type,'format' => $format,'message' => $message,'validation' => $validation,'reset' => $reset,'dependent' => $dependent);} // end func addRule// }}}// {{{ addGroupRule()/*** Adds a validation rule for the given group of elements** Only groups with a name can be assigned a validation rule* Use addGroupRule when you need to validate elements inside the group.* Use addRule if you need to validate the group as a whole. In this case,* the same rule will be applied to all elements in the group.* Use addRule if you need to validate the group against a function.** @param string $group Form group name* @param mixed $arg1 Array for multiple elements or error message string for one element* @param string $type (optional)Rule type use getRegisteredRules() to get types* @param string $format (optional)Required for extra rule data* @param int $howmany (optional)How many valid elements should be in the group* @param string $validation (optional)Where to perform validation: "server", "client"* @param bool $reset Client-side: whether to reset the element's value to its original state if validation failed.* @since 2.5* @access public* @throws HTML_QuickForm_Error*/function addGroupRule($group, $arg1, $type='', $format=null, $howmany=0, $validation = 'server', $reset = false){if (!$this->elementExists($group)) {return self::raiseError(null, QUICKFORM_NONEXIST_ELEMENT, null, E_USER_WARNING, "Group '$group' does not exist in HTML_QuickForm::addGroupRule()", 'HTML_QuickForm_Error', true);}$groupObj =& $this->getElement($group);if (is_array($arg1)) {$required = 0;foreach ($arg1 as $elementIndex => $rules) {$elementName = $groupObj->getElementName($elementIndex);foreach ($rules as $rule) {$format = (isset($rule[2])) ? $rule[2] : null;$validation = (isset($rule[3]) && 'client' == $rule[3])? 'client': 'server';$reset = isset($rule[4]) && $rule[4];$type = $rule[1];if (false === ($newName = $this->isRuleRegistered($type, true))) {return self::raiseError(null, QUICKFORM_INVALID_RULE, null, E_USER_WARNING, "Rule '$type' is not registered in HTML_QuickForm::addGroupRule()", 'HTML_QuickForm_Error', true);} elseif (is_string($newName)) {$type = $newName;}$this->_rules[$elementName][] = array('type' => $type,'format' => $format,'message' => $rule[0],'validation' => $validation,'reset' => $reset,'group' => $group);if ('required' == $type || 'uploadedfile' == $type) {$groupObj->_required[] = $elementName;$this->_required[] = $elementName;$required++;}}}if ($required > 0 && count($groupObj->getElements()) == $required) {$this->_required[] = $group;}} elseif (is_string($arg1)) {if (false === ($newName = $this->isRuleRegistered($type, true))) {return self::raiseError(null, QUICKFORM_INVALID_RULE, null, E_USER_WARNING, "Rule '$type' is not registered in HTML_QuickForm::addGroupRule()", 'HTML_QuickForm_Error', true);} elseif (is_string($newName)) {$type = $newName;}// addGroupRule() should also handle <select multiple>if (is_a($groupObj, 'html_quickform_group')) {// Radios need to be handled differently when requiredif ($type == 'required' && $groupObj->getGroupType() == 'radio') {$howmany = ($howmany == 0) ? 1 : $howmany;} else {$howmany = ($howmany == 0) ? count($groupObj->getElements()) : $howmany;}}$this->_rules[$group][] = array('type' => $type,'format' => $format,'message' => $arg1,'validation' => $validation,'howmany' => $howmany,'reset' => $reset);if ($type == 'required') {$this->_required[] = $group;}}} // end func addGroupRule// }}}// {{{ addFormRule()/*** Adds a global validation rule** This should be used when for a rule involving several fields or if* you want to use some completely custom validation for your form.* The rule function/method should return true in case of successful* validation and array('element name' => 'error') when there were errors.** @access public* @param mixed Callback, either function name or array(&$object, 'method')* @throws HTML_QuickForm_Error*/function addFormRule($rule){if (!is_callable($rule)) {return self::raiseError(null, QUICKFORM_INVALID_RULE, null, E_USER_WARNING, 'Callback function does not exist in HTML_QuickForm::addFormRule()', 'HTML_QuickForm_Error', true);}$this->_formRules[] = $rule;}// }}}// {{{ applyFilter()/*** Applies a data filter for the given field(s)** @param mixed $element Form element name or array of such names* @param mixed $filter Callback, either function name or array(&$object, 'method')* @since 2.0* @access public*/function applyFilter($element, $filter){if (!is_callable($filter)) {return self::raiseError(null, QUICKFORM_INVALID_FILTER, null, E_USER_WARNING, "Callback function does not exist in QuickForm::applyFilter()", 'HTML_QuickForm_Error', true);}if ($element == '__ALL__') {$this->_submitValues = $this->_recursiveFilter($filter, $this->_submitValues);} else {if (!is_array($element)) {$element = array($element);}foreach ($element as $elName) {$value = $this->getSubmitValue($elName);if (null !== $value) {if (false === strpos($elName, '[')) {$this->_submitValues[$elName] = $this->_recursiveFilter($filter, $value);} else {$idx = "['" . str_replace(array(']', '['), array('', "']['"), $elName) . "']";eval("\$this->_submitValues{$idx} = \$this->_recursiveFilter(\$filter, \$value);");}}}}} // end func applyFilter// }}}// {{{ _recursiveFilter()/*** Recursively apply a filter function** @param string $filter filter to apply* @param mixed $value submitted values* @since 2.0* @access private* @return mixed cleaned values*/function _recursiveFilter($filter, $value){if (is_array($value)) {$cleanValues = array();foreach ($value as $k => $v) {$cleanValues[$k] = $this->_recursiveFilter($filter, $v);}return $cleanValues;} else {return call_user_func($filter, $value);}} // end func _recursiveFilter// }}}// {{{ arrayMerge()/*** Merges two arrays** Merges two array like the PHP function array_merge but recursively.* The main difference is that existing keys will not be renumbered* if they are integers.** @access puplic* @param array $a original array* @param array $b array which will be merged into first one* @return array merged array*/static function arrayMerge($a, $b){if (is_null($a)) {$a = array();}if (is_null($b)) {$b = array();}foreach ($b as $k => $v) {if (is_array($v)) {if (isset($a[$k]) && !is_array($a[$k])) {$a[$k] = $v;} else {if (!isset($a[$k])) {$a[$k] = array();}$a[$k] = HTML_QuickForm::arrayMerge($a[$k], $v);}} else {$a[$k] = $v;}}return $a;} // end func arrayMerge// }}}// {{{ isTypeRegistered()/*** Returns whether or not the form element type is supported** @param string $type Form element type* @since 1.0* @access public* @return boolean*/function isTypeRegistered($type){return isset($GLOBALS['HTML_QUICKFORM_ELEMENT_TYPES'][strtolower($type)]);} // end func isTypeRegistered// }}}// {{{ getRegisteredTypes()/*** Returns an array of registered element types** @since 1.0* @access public* @return array*/function getRegisteredTypes(){return array_keys($GLOBALS['HTML_QUICKFORM_ELEMENT_TYPES']);} // end func getRegisteredTypes// }}}// {{{ isRuleRegistered()/*** Returns whether or not the given rule is supported** @param string $name Validation rule name* @param bool Whether to automatically register subclasses of HTML_QuickForm_Rule* @since 1.0* @access public* @return mixed true if previously registered, false if not, new rule name if auto-registering worked*/function isRuleRegistered($name, $autoRegister = false){if (is_scalar($name) && isset($GLOBALS['_HTML_QuickForm_registered_rules'][$name])) {return true;} elseif (!$autoRegister) {return false;}// automatically register the rule if requestedinclude_once 'HTML/QuickForm/RuleRegistry.php';$ruleName = false;if (is_object($name) && is_a($name, 'html_quickform_rule')) {$ruleName = !empty($name->name)? $name->name: strtolower(get_class($name));} elseif (is_string($name) && class_exists($name)) {$parent = strtolower($name);do {if ('html_quickform_rule' == strtolower($parent)) {$ruleName = strtolower($name);break;}} while ($parent = get_parent_class($parent));}if ($ruleName) {$registry =& HTML_QuickForm_RuleRegistry::singleton();$registry->registerRule($ruleName, null, $name);}return $ruleName;} // end func isRuleRegistered// }}}// {{{ getRegisteredRules()/*** Returns an array of registered validation rules** @since 1.0* @access public* @return array*/function getRegisteredRules(){return array_keys($GLOBALS['_HTML_QuickForm_registered_rules']);} // end func getRegisteredRules// }}}// {{{ isElementRequired()/*** Returns whether or not the form element is required** @param string $element Form element name* @since 1.0* @access public* @return boolean*/function isElementRequired($element){return in_array($element, $this->_required, true);} // end func isElementRequired// }}}// {{{ isElementFrozen()/*** Returns whether or not the form element is frozen** @param string $element Form element name* @since 1.0* @access public* @return boolean*/function isElementFrozen($element){if (isset($this->_elementIndex[$element])) {return $this->_elements[$this->_elementIndex[$element]]->isFrozen();}return false;} // end func isElementFrozen// }}}// {{{ setJsWarnings()/*** Sets JavaScript warning messages** @param string $pref Prefix warning* @param string $post Postfix warning* @since 1.1* @access public* @return void*/function setJsWarnings($pref, $post){$this->_jsPrefix = $pref;$this->_jsPostfix = $post;} // end func setJsWarnings// }}}// {{{ setRequiredNote()/*** Sets required-note** @param string $note Message indicating some elements are required* @since 1.1* @access public* @return void*/function setRequiredNote($note){$this->_requiredNote = $note;} // end func setRequiredNote// }}}// {{{ getRequiredNote()/*** Returns the required note** @since 2.0* @access public* @return string*/function getRequiredNote(){return $this->_requiredNote;} // end func getRequiredNote// }}}// {{{ validate()/*** Performs the server side validation* @access public* @since 1.0* @return boolean true if no error found*/function validate(){if (count($this->_rules) == 0 && count($this->_formRules) == 0 &&$this->isSubmitted()) {return (0 == count($this->_errors));} elseif (!$this->isSubmitted()) {return false;}include_once('HTML/QuickForm/RuleRegistry.php');$registry =& HTML_QuickForm_RuleRegistry::singleton();foreach ($this->_rules as $target => $rules) {$submitValue = $this->getSubmitValue($target);foreach ($rules as $rule) {if ((isset($rule['group']) && isset($this->_errors[$rule['group']])) ||isset($this->_errors[$target])) {continue 2;}// If element is not required and is empty, we shouldn't validate itif (!$this->isElementRequired($target)) {if (!isset($submitValue) || '' == $submitValue) {continue 2;// Fix for bug #3501: we shouldn't validate not uploaded files, either.// Unfortunately, we can't just use $element->isUploadedFile() since// the element in question can be buried in group. Thus this hack.} elseif (is_array($submitValue)) {if (false === ($pos = strpos($target, '['))) {$isUpload = !empty($this->_submitFiles[$target]);} else {$base = substr($target, 0, $pos);$idx = "['" . str_replace(array(']', '['), array('', "']['"), substr($target, $pos + 1, -1)) . "']";eval("\$isUpload = isset(\$this->_submitFiles['{$base}']['name']{$idx});");}if ($isUpload && (!isset($submitValue['error']) || 0 != $submitValue['error'])) {continue 2;}}}if (isset($rule['dependent']) && is_array($rule['dependent'])) {$values = array($submitValue);foreach ($rule['dependent'] as $elName) {$values[] = $this->getSubmitValue($elName);}$result = $registry->validate($rule['type'], $values, $rule['format'], true);} elseif (is_array($submitValue) && !isset($rule['howmany'])) {$result = $registry->validate($rule['type'], $submitValue, $rule['format'], true);} else {$result = $registry->validate($rule['type'], $submitValue, $rule['format'], false);}if (!$result || (!empty($rule['howmany']) && $rule['howmany'] > (int)$result)) {if (isset($rule['group'])) {$this->_errors[$rule['group']] = $rule['message'];} else {$this->_errors[$target] = $rule['message'];}}}}// process the global rules nowforeach ($this->_formRules as $rule) {if (true !== ($res = call_user_func($rule, $this->_submitValues, $this->_submitFiles))) {if (is_array($res)) {$this->_errors += $res;} else {return self::raiseError(null, QUICKFORM_ERROR, null, E_USER_WARNING, 'Form rule callback returned invalid value in HTML_QuickForm::validate()', 'HTML_QuickForm_Error', true);}}}return (0 == count($this->_errors));} // end func validate// }}}// {{{ freeze()/*** Displays elements without HTML input tags** @param mixed $elementList array or string of element(s) to be frozen* @since 1.0* @access public* @throws HTML_QuickForm_Error*/function freeze($elementList=null){if (!isset($elementList)) {$this->_freezeAll = true;$elementList = array();} else {if (!is_array($elementList)) {$elementList = preg_split('/[ ]*,[ ]*/', $elementList);}$elementList = array_flip($elementList);}$frozen = [];foreach (array_keys($this->_elements) as $key) {$name = $this->_elements[$key]->getName();if ($this->_freezeAll || isset($elementList[$name])) {$this->_elements[$key]->freeze();$frozen[$name] = true;}}if (count($elementList) != count($frozen)) {return self::raiseError(null, QUICKFORM_NONEXIST_ELEMENT, null, E_USER_WARNING, "Nonexistant element(s): '" . implode("', '", array_keys($elementList)) . "' in HTML_QuickForm::freeze()", 'HTML_QuickForm_Error', true);}return true;} // end func freeze// }}}// {{{ isFrozen()/*** Returns whether or not the whole form is frozen** @since 3.0* @access public* @return boolean*/function isFrozen(){return $this->_freezeAll;} // end func isFrozen// }}}// {{{ process()/*** Performs the form data processing** @param mixed $callback Callback, either function name or array(&$object, 'method')* @param bool $mergeFiles Whether uploaded files should be processed too* @since 1.0* @access public* @throws HTML_QuickForm_Error*/function process($callback, $mergeFiles = true){if (!is_callable($callback)) {return self::raiseError(null, QUICKFORM_INVALID_PROCESS, null, E_USER_WARNING, "Callback function does not exist in QuickForm::process()", 'HTML_QuickForm_Error', true);}$values = ($mergeFiles === true) ? HTML_QuickForm::arrayMerge($this->_submitValues, $this->_submitFiles) : $this->_submitValues;return call_user_func($callback, $values);} // end func process// }}}// {{{ accept()/*** Accepts a renderer** @param object An HTML_QuickForm_Renderer object* @since 3.0* @access public* @return void*/function accept(&$renderer){$renderer->startForm($this);foreach (array_keys($this->_elements) as $key) {$element =& $this->_elements[$key];$elementName = $element->getName();$required = ($this->isElementRequired($elementName) && !$element->isFrozen());$error = $this->getElementError($elementName);$element->accept($renderer, $required, $error);}$renderer->finishForm($this);} // end func accept// }}}// {{{ defaultRenderer()/*** Returns a reference to default renderer object** @access public* @since 3.0* @return object a default renderer object*/function &defaultRenderer(){if (!isset($GLOBALS['_HTML_QuickForm_default_renderer'])) {include_once('HTML/QuickForm/Renderer/Default.php');$GLOBALS['_HTML_QuickForm_default_renderer'] = new HTML_QuickForm_Renderer_Default(); //Moodle: PHP 5.3 compatibility}return $GLOBALS['_HTML_QuickForm_default_renderer'];} // end func defaultRenderer// }}}// {{{ toHtml ()/*** Returns an HTML version of the form** @param string $in_data (optional) Any extra data to insert right* before form is rendered. Useful when using templates.** @return string Html version of the form* @since 1.0* @access public*/function toHtml ($in_data = null){if (!is_null($in_data)) {$this->addElement('html', $in_data);}$renderer =& $this->defaultRenderer();$this->accept($renderer);return $renderer->toHtml();} // end func toHtml// }}}// {{{ getValidationScript()/*** Returns the client side validation script** @since 2.0* @access public* @return string Javascript to perform validation, empty string if no 'client' rules were added*/function getValidationScript(){if (empty($this->_rules) || empty($this->_attributes['onsubmit'])) {return '';}include_once('HTML/QuickForm/RuleRegistry.php');$registry =& HTML_QuickForm_RuleRegistry::singleton();$test = array();$js_escape = array("\r" => '\r',"\n" => '\n',"\t" => '\t',"'" => "\\'",'"' => '\"','\\' => '\\\\');foreach ($this->_rules as $elementName => $rules) {foreach ($rules as $rule) {if ('client' == $rule['validation']) {unset($element);$dependent = isset($rule['dependent']) && is_array($rule['dependent']);$rule['message'] = strtr($rule['message'], $js_escape);if (isset($rule['group'])) {$group =& $this->getElement($rule['group']);// No JavaScript validation for frozen elementsif ($group->isFrozen()) {continue 2;}$elements =& $group->getElements();foreach (array_keys($elements) as $key) {if ($elementName == $group->getElementName($key)) {$element =& $elements[$key];break;}}} elseif ($dependent) {$element = array();$element[] =& $this->getElement($elementName);foreach ($rule['dependent'] as $elName) {$element[] =& $this->getElement($elName);}} else {$element =& $this->getElement($elementName);}// No JavaScript validation for frozen elementsif (is_object($element) && $element->isFrozen()) {continue 2;} elseif (is_array($element)) {foreach (array_keys($element) as $key) {if ($element[$key]->isFrozen()) {continue 3;}}}$test[] = $registry->getValidationScript($element, $elementName, $rule);}}}if (count($test) > 0) {return"\n<script type=\"text/javascript\">\n" ."//<![CDATA[\n" ."function validate_" . $this->_attributes['id'] . "(frm) {\n" ." var value = '';\n" ." var errFlag = new Array();\n" ." var _qfGroups = {};\n" ." _qfMsg = '';\n\n" .join("\n", $test) ."\n if (_qfMsg != '') {\n" ." _qfMsg = '" . strtr($this->_jsPrefix, $js_escape) . "' + _qfMsg;\n" ." _qfMsg = _qfMsg + '\\n" . strtr($this->_jsPostfix, $js_escape) . "';\n" ." alert(_qfMsg);\n" ." return false;\n" ." }\n" ." return true;\n" ."}\n" ."//]]>\n" ."</script>";}return '';} // end func getValidationScript// }}}// {{{ getSubmitValues()/*** Returns the values submitted by the form** @since 2.0* @access public* @param bool Whether uploaded files should be returned too* @return array*/function getSubmitValues($mergeFiles = false){return $mergeFiles? HTML_QuickForm::arrayMerge($this->_submitValues, $this->_submitFiles): $this->_submitValues;} // end func getSubmitValues// }}}// {{{ toArray()/*** Returns the form's contents in an array.** The description of the array structure is in HTML_QuickForm_Renderer_Array docs** @since 2.0* @access public* @param bool Whether to collect hidden elements (passed to the Renderer's constructor)* @return array of form contents*/function toArray($collectHidden = false){include_once 'HTML/QuickForm/Renderer/Array.php';$renderer = new HTML_QuickForm_Renderer_Array($collectHidden); //Moodle: PHP 5.3 compatibility$this->accept($renderer);return $renderer->toArray();} // end func toArray// }}}// {{{ exportValue()/*** Returns a 'safe' element's value** This method first tries to find a cleaned-up submitted value,* it will return a value set by setValue()/setDefaults()/setConstants()* if submitted value does not exist for the given element.** @param string Name of an element* @access public* @return mixed*/function exportValue($element){if (!isset($this->_elementIndex[$element])) {return self::raiseError(null, QUICKFORM_NONEXIST_ELEMENT, null, E_USER_WARNING, "Element '$element' does not exist in HTML_QuickForm::getElementValue()", 'HTML_QuickForm_Error', true);}$value = $this->_elements[$this->_elementIndex[$element]]->exportValue($this->_submitValues, false);if (isset($this->_duplicateIndex[$element])) {foreach ($this->_duplicateIndex[$element] as $index) {if (null !== ($v = $this->_elements[$index]->exportValue($this->_submitValues, false))) {if (is_array($value)) {$value[] = $v;} else {$value = (null === $value)? $v: array($value, $v);}}}}return $value;}// }}}// {{{ exportValues()/*** Returns 'safe' elements' values** Unlike getSubmitValues(), this will return only the values* corresponding to the elements present in the form.** @param mixed Array/string of element names, whose values we want. If not set then return all elements.* @access public* @return array An assoc array of elements' values* @throws HTML_QuickForm_Error*/function exportValues($elementList = null){$values = array();if (null === $elementList) {// iterate over all elements, calling their exportValue() methodsforeach (array_keys($this->_elements) as $key) {$value = $this->_elements[$key]->exportValue($this->_submitValues, true);if (is_array($value)) {// This shit throws a bogus warning in PHP 4.3.x$values = HTML_QuickForm::arrayMerge($values, $value);}}} else {if (!is_array($elementList)) {$elementList = array_map('trim', explode(',', $elementList));}foreach ($elementList as $elementName) {$value = $this->exportValue($elementName);$pear = new PEAR();if ($pear->isError($value)) {return $value;}$values[$elementName] = $value;}}return $values;}// }}}// {{{ isSubmitted()/*** Tells whether the form was already submitted** This is useful since the _submitFiles and _submitValues arrays* may be completely empty after the trackSubmit value is removed.** @access public* @return bool*/function isSubmitted(){return $this->_flagSubmitted;}// }}}// {{{ isError()/*** Tell whether a result from a QuickForm method is an error (an instance of HTML_QuickForm_Error)** @access public* @param mixed result code* @return bool whether $value is an error*/static function isError($value){return (is_object($value) && is_a($value, 'html_quickform_error'));} // end func isError// }}}// {{{ errorMessage()/*** Return a textual error message for an QuickForm error code** @access public* @param int error code* @return string error message*/static function errorMessage($value){// make the variable static so that it only has to do the defining on the first callstatic $errorMessages;// define the varies error messagesif (!isset($errorMessages)) {$errorMessages = array(QUICKFORM_OK => 'no error',QUICKFORM_ERROR => 'unknown error',QUICKFORM_INVALID_RULE => 'the rule does not exist as a registered rule',QUICKFORM_NONEXIST_ELEMENT => 'nonexistent html element',QUICKFORM_INVALID_FILTER => 'invalid filter',QUICKFORM_UNREGISTERED_ELEMENT => 'unregistered element',QUICKFORM_INVALID_ELEMENT_NAME => 'element already exists',QUICKFORM_INVALID_PROCESS => 'process callback does not exist',QUICKFORM_DEPRECATED => 'method is deprecated',QUICKFORM_INVALID_DATASOURCE => 'datasource is not an object');}// If this is an error object, then grab the corresponding error codeif (HTML_QuickForm::isError($value)) {$value = $value->getCode();}// return the textual error message corresponding to the codereturn isset($errorMessages[$value]) ? $errorMessages[$value] : $errorMessages[QUICKFORM_ERROR];} // end func errorMessage// }}}} // end class HTML_QuickFormclass HTML_QuickForm_Error extends PEAR_Error {// {{{ properties/*** Prefix for all error messages* @var string*/var $error_message_prefix = 'QuickForm Error: ';// }}}// {{{ constructor/*** Creates a quickform error object, extending the PEAR_Error class** @param int $code the error code* @param int $mode the reaction to the error, either return, die or trigger/callback* @param int $level intensity of the error (PHP error code)* @param mixed $debuginfo any information that can inform user as to nature of the error*/public function __construct($code = QUICKFORM_ERROR, $mode = PEAR_ERROR_RETURN,$level = E_USER_NOTICE, $debuginfo = null){if (is_int($code)) {parent::__construct(HTML_QuickForm::errorMessage($code), $code, $mode, $level, $debuginfo);} else {parent::__construct("Invalid error code: $code", QUICKFORM_ERROR, $mode, $level, $debuginfo);}}/*** Old syntax of class constructor. Deprecated in PHP7.** @deprecated since Moodle 3.1*/public function HTML_QuickForm_Error($code = QUICKFORM_ERROR, $mode = PEAR_ERROR_RETURN,$level = E_USER_NOTICE, $debuginfo = null) {debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER);self::__construct($code, $mode, $level, $debuginfo);}// }}}} // end class HTML_QuickForm_Error?>