You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2095 lines
78 KiB
2095 lines
78 KiB
<?php
|
|
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
|
|
|
/**
|
|
* Create, validate and process HTML forms
|
|
*
|
|
* PHP versions 4 and 5
|
|
*
|
|
* LICENSE: This source file is subject to version 3.01 of the PHP license
|
|
* that is available through the world-wide-web at the following URI:
|
|
* http://www.php.net/license/3_01.txt If you did not receive a copy of
|
|
* the PHP License and are unable to obtain it through the web, please
|
|
* send a note to license@php.net so we can mail you a copy immediately.
|
|
*
|
|
* @category HTML
|
|
* @package HTML_QuickForm
|
|
* @author Adam Daniel <adaniel1@eesus.jnj.com>
|
|
* @author Bertrand Mansion <bmansion@mamasam.com>
|
|
* @author Alexey Borzov <avb@php.net>
|
|
* @copyright 2001-2009 The PHP Group
|
|
* @license http://www.php.net/license/3_01.txt PHP License 3.01
|
|
* @version CVS: $Id: QuickForm.php,v 1.166 2009/04/04 21:34:02 avb Exp $
|
|
* @link http://pear.php.net/package/HTML_QuickForm
|
|
*/
|
|
|
|
/**
|
|
* PEAR and PEAR_Error classes, for error handling
|
|
*/
|
|
require_once 'PEAR.php';
|
|
/**
|
|
* Base class for all HTML classes
|
|
*/
|
|
require_once 'HTML/Common.php';
|
|
|
|
/**
|
|
* Element types known to HTML_QuickForm
|
|
* @see HTML_QuickForm::registerElementType(), HTML_QuickForm::getRegisteredTypes(),
|
|
* HTML_QuickForm::isTypeRegistered()
|
|
* @global array $GLOBALS['HTML_QUICKFORM_ELEMENT_TYPES']
|
|
*/
|
|
$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'),
|
|
'advanced_settings' => array('HTML/QuickForm/advanced_settings.php','HTML_QuickForm_advanced_settings'),
|
|
'label' => array('HTML/QuickForm/label.php','HTML_QuickForm_label'),
|
|
'email' => array('HTML/QuickForm/email.php','HTML_QuickForm_email')
|
|
);
|
|
|
|
/**
|
|
* Validation rules known to HTML_QuickForm
|
|
* @see HTML_QuickForm::registerRule(), HTML_QuickForm::getRegisteredRules(),
|
|
* HTML_QuickForm::isRuleRegistered()
|
|
* @global array $GLOBALS['_HTML_QuickForm_registered_rules']
|
|
*/
|
|
$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'),
|
|
'callback' => array('html_quickform_rule_callback', 'HTML/QuickForm/Rule/Callback.php'),
|
|
// Added by Chamilo team, 16-MAR-2010
|
|
//'compare' => array('html_quickform_rule_compare', 'HTML/QuickForm/Rule/Compare.php')
|
|
'compare' => array('html_quickform_rule_compare', 'HTML/QuickForm/Rule/Compare.php'),
|
|
'comparedate' => array('html_quickform_rule_comparedate', 'HTML/QuickForm/Rule/CompareDate.php'),
|
|
'errordate' => array('html_quickform_rule_date', 'HTML/QuickForm/Rule/Date.php'),
|
|
'captcha' => array('HTML_QuickForm_Rule_CAPTCHA', 'HTML/QuickForm/Rule/CAPTCHA.php')
|
|
//
|
|
);
|
|
|
|
// {{{ error codes
|
|
|
|
/**#@+
|
|
* Error codes for HTML_QuickForm
|
|
*
|
|
* Codes are mapped to textual messages by errorMessage() method, if you add a
|
|
* new code be sure to add a new message for it to errorMessage()
|
|
*
|
|
* @see HTML_QuickForm::errorMessage()
|
|
*/
|
|
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
|
|
*
|
|
* @category HTML
|
|
* @package HTML_QuickForm
|
|
* @author Adam Daniel <adaniel1@eesus.jnj.com>
|
|
* @author Bertrand Mansion <bmansion@mamasam.com>
|
|
* @author Alexey Borzov <avb@php.net>
|
|
* @version Release: 3.2.11
|
|
*/
|
|
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)
|
|
{
|
|
HTML_Common::HTML_Common($attributes);
|
|
$method = (strtoupper($method) == 'GET') ? 'get' : 'post';
|
|
// Modified by Chamilo team, 16-MAR-2010
|
|
//$action = ($action == '') ? $_SERVER['PHP_SELF'] : $action;
|
|
$action = ($action == '') ? api_get_self() : $action;
|
|
//
|
|
$target = empty($target) ? array() : array('target' => $target);
|
|
$form_id = $formName;
|
|
if (isset($attributes['id']) && !empty($attributes['id'])) {
|
|
$form_id = Security::remove_XSS($attributes['id']);
|
|
}
|
|
$attributes = array('action'=>$action, 'method'=>$method, 'name'=>$formName, 'id'=>$form_id) + $target;
|
|
$this->updateAttributes($attributes);
|
|
if (!$trackSubmit || isset($_REQUEST['_qf__' . $formName])) {
|
|
if (1 == get_magic_quotes_gpc()) {
|
|
$this->_submitValues = $this->_recursiveFilter('stripslashes', 'get' == $method? $_GET: $_POST);
|
|
foreach ($_FILES as $keyFirst => $valFirst) {
|
|
foreach ($valFirst as $keySecond => $valSecond) {
|
|
if ('name' == $keySecond) {
|
|
$this->_submitFiles[$keyFirst][$keySecond] = $this->_recursiveFilter('stripslashes', $valSecond);
|
|
} else {
|
|
$this->_submitFiles[$keyFirst][$keySecond] = $valSecond;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
$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.shorthandbytes
|
|
switch (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'];
|
|
}
|
|
}
|
|
|
|
$course_id = api_get_course_int_id();
|
|
//If I'm in a course replace the default max filesize with the course limits
|
|
if (!empty($course_id)) {
|
|
$free_course_quota = DocumentManager::get_course_quota() - DocumentManager::documents_total_space();
|
|
if (empty($this->_maxFileSize) || $free_course_quota <= $this->_maxFileSize) {
|
|
$this->_maxFileSize = intval($free_course_quota);
|
|
}
|
|
}
|
|
} // end constructor
|
|
|
|
// }}}
|
|
// {{{ 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
|
|
*/
|
|
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
|
|
*/
|
|
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
|
|
* @throws HTML_QuickForm_Error
|
|
*/
|
|
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 PEAR::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
|
|
* @throws HTML_QuickForm_Error
|
|
*/
|
|
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 PEAR::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 PEAR::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
|
|
* @throws HTML_QuickForm_Error
|
|
*/
|
|
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 PEAR::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 PEAR::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 HTML_QuickForm_Element
|
|
* @throws HTML_QuickForm_Error
|
|
*/
|
|
function &createElement($elementType) {
|
|
$args = func_get_args();
|
|
$element =& HTML_QuickForm::_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 HTML_QuickForm_Element
|
|
* @throws HTML_QuickForm_Error
|
|
*/
|
|
function &_loadElement($event, $type, $args)
|
|
{
|
|
$type = strtolower($type);
|
|
if (!HTML_QuickForm::isTypeRegistered($type)) {
|
|
$error = PEAR::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;
|
|
// Modified by Ivan Tcholakov, 16-MAR-2010. Suppressing a deprecation warning on PHP 5.3
|
|
//$elementObject =& new $className();
|
|
$elementObject = new $className();
|
|
|
|
for ($i = 0; $i < 5; $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 HTML_QuickForm_Element a reference to newly added 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));
|
|
if (PEAR::isError($elementObject)) {
|
|
return $elementObject;
|
|
}
|
|
}
|
|
$elementName = $elementObject->getName();
|
|
|
|
// Add the element if it is not an incompatible duplicate
|
|
if (!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 = PEAR::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 HTML_QuickForm_element Element to insert
|
|
* @param string Name of the element before which the new
|
|
* one is inserted
|
|
* @return HTML_QuickForm_element reference to inserted element
|
|
* @throws HTML_QuickForm_Error
|
|
*/
|
|
function &insertElementBefore(&$element, $nameAfter)
|
|
{
|
|
if (!empty($this->_duplicateIndex[$nameAfter])) {
|
|
$error = PEAR::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 = PEAR::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 duplicate
|
|
if (!empty($elementName) && isset($this->_elementIndex[$elementName])) {
|
|
if ($this->_elements[$this->_elementIndex[$elementName]]->getType() != $element->getType()) {
|
|
$error = PEAR::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 {
|
|
$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 order
|
|
ksort($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 $separator (optional)string to separate elements
|
|
* @param string $appendName (optional)specify whether the group name should be
|
|
* used in the form element name ex: group[element]
|
|
* @return HTML_QuickForm_group reference to a newly added group
|
|
* @since 2.8
|
|
* @access public
|
|
* @throws HTML_QuickForm_Error
|
|
*/
|
|
function &addGroup($elements, $name=null, $groupLabel='', $separator=null, $appendName = true)
|
|
{
|
|
static $anonGroups = 1;
|
|
|
|
if (0 == strlen($name)) {
|
|
$name = 'qf_group_' . $anonGroups++;
|
|
$appendName = false;
|
|
}
|
|
$group = & $this->addElement('group', $name, $groupLabel, $elements, $separator, $appendName);
|
|
return $group;
|
|
} // end func addGroup
|
|
|
|
// }}}
|
|
// {{{ &getElement()
|
|
|
|
/**
|
|
* Returns a reference to the element
|
|
*
|
|
* @param string $element Element name
|
|
* @since 2.0
|
|
* @access public
|
|
* @return HTML_QuickForm_element reference to element
|
|
* @throws HTML_QuickForm_Error
|
|
*/
|
|
function &getElement($element)
|
|
{
|
|
if (isset($this->_elementIndex[$element])) {
|
|
return $this->_elements[$this->_elementIndex[$element]];
|
|
} else {
|
|
$error = PEAR::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 = PEAR::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;
|
|
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 = str_replace(
|
|
array('\\', '\''), array('\\\\', '\\\''),
|
|
substr($elementName, 0, $pos)
|
|
);
|
|
$idx = "['" . str_replace(
|
|
array('\\', '\'', ']', '['), array('\\\\', '\\\'', '', "']['"),
|
|
substr($elementName, $pos + 1, -1)
|
|
) . "']";
|
|
if (isset($this->_submitValues[$base])) {
|
|
$value = eval("return (isset(\$this->_submitValues['{$base}']{$idx})) ? \$this->_submitValues['{$base}']{$idx} : 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 = false
|
|
if (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 such
|
|
if ($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 = 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 HTML_QuickForm_element a reference to the removed element
|
|
* @throws HTML_QuickForm_Error
|
|
*/
|
|
function &removeElement($elementName, $removeRules = true)
|
|
{
|
|
if (!isset($this->_elementIndex[$elementName])) {
|
|
$error = PEAR::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) {
|
|
$this->_required = array_diff($this->_required, array($elementName));
|
|
unset($this->_rules[$elementName], $this->_errors[$elementName]);
|
|
if ('group' == $el->getType()) {
|
|
foreach (array_keys($el->getElements()) as $key) {
|
|
unset($this->_rules[$el->getElementName($key)]);
|
|
}
|
|
}
|
|
}
|
|
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 PEAR::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 PEAR::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 PEAR::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();
|
|
}
|
|
if ($validation == 'client') {
|
|
$this->updateAttributes(array('onsubmit' => 'try { var myValidator = validate_' . $this->_attributes['id'] . '; } catch(e) { return true; } return myValidator(this);'));
|
|
}
|
|
$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 PEAR::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 PEAR::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 ('client' == $validation) {
|
|
$this->updateAttributes(array('onsubmit' => 'try { var myValidator = validate_' . $this->_attributes['id'] . '; } catch(e) { return true; } return myValidator(this);'));
|
|
}
|
|
}
|
|
}
|
|
if ($required > 0 && count($groupObj->getElements()) == $required) {
|
|
$this->_required[] = $group;
|
|
}
|
|
} elseif (is_string($arg1)) {
|
|
if (false === ($newName = $this->isRuleRegistered($type, true))) {
|
|
return PEAR::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 required
|
|
if ($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;
|
|
}
|
|
if ($validation == 'client') {
|
|
$this->updateAttributes(array('onsubmit' => 'try { var myValidator = validate_' . $this->_attributes['id'] . '; } catch(e) { return true; } return myValidator(this);'));
|
|
}
|
|
}
|
|
} // 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 PEAR::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
|
|
* @throws HTML_QuickForm_Error
|
|
*/
|
|
function applyFilter($element, $filter)
|
|
{
|
|
if (!is_callable($filter)) {
|
|
return PEAR::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 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 public
|
|
* @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)
|
|
{
|
|
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
|
|
*/
|
|
static 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 requested
|
|
include_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
|
|
* @throws HTML_QuickForm_Error
|
|
*/
|
|
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 it
|
|
if (!$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.
|
|
// See also bug #12014, we should only consider a file that has
|
|
// status UPLOAD_ERR_NO_FILE as not uploaded, in all other cases
|
|
// validation should be performed, so that e.g. 'maxfilesize' rule
|
|
// will display an error if status is UPLOAD_ERR_INI_SIZE
|
|
// or UPLOAD_ERR_FORM_SIZE
|
|
} elseif (is_array($submitValue)) {
|
|
if (false === ($pos = strpos($target, '['))) {
|
|
$isUpload = !empty($this->_submitFiles[$target]);
|
|
} else {
|
|
$base = str_replace(
|
|
array('\\', '\''), array('\\\\', '\\\''),
|
|
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']) || UPLOAD_ERR_NO_FILE == $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 now
|
|
foreach ($this->_formRules as $rule) {
|
|
if (true !== ($res = call_user_func($rule, $this->_submitValues, $this->_submitFiles))) {
|
|
if (is_array($res)) {
|
|
$this->_errors += $res;
|
|
} else {
|
|
return PEAR::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);
|
|
}
|
|
|
|
foreach (array_keys($this->_elements) as $key) {
|
|
$name = $this->_elements[$key]->getName();
|
|
if ($this->_freezeAll || isset($elementList[$name])) {
|
|
$this->_elements[$key]->freeze();
|
|
unset($elementList[$name]);
|
|
}
|
|
}
|
|
|
|
if (!empty($elementList)) {
|
|
return PEAR::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
|
|
* @return mixed Whatever value the $callback function returns
|
|
*/
|
|
function process($callback, $mergeFiles = true)
|
|
{
|
|
if (!is_callable($callback)) {
|
|
return PEAR::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';
|
|
// Modified by Ivan Tcholakov, 16-MAR-2010. Suppressing a deprecation warning on PHP 5.3
|
|
//$GLOBALS['_HTML_QuickForm_default_renderer'] =& new HTML_QuickForm_Renderer_Default();
|
|
$GLOBALS['_HTML_QuickForm_default_renderer'] = new HTML_QuickForm_Renderer_Default();
|
|
}
|
|
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 elements
|
|
if ($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 elements
|
|
if (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';
|
|
// Modified by Ivan Tcholakov, 16-MAR-2010. Suppressing a deprecation warning on PHP 5.3
|
|
//$renderer =& new HTML_QuickForm_Renderer_Array($collectHidden);
|
|
$renderer = new HTML_QuickForm_Renderer_Array($collectHidden);
|
|
//
|
|
$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
|
|
* @throws HTML_QuickForm_Error
|
|
*/
|
|
function exportValue($element)
|
|
{
|
|
if (!isset($this->_elementIndex[$element])) {
|
|
return PEAR::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() methods
|
|
foreach (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);
|
|
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 call
|
|
static $errorMessages;
|
|
|
|
// define the varies error messages
|
|
if (!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 code
|
|
if (HTML_QuickForm::isError($value)) {
|
|
$value = $value->getCode();
|
|
}
|
|
|
|
// return the textual error message corresponding to the code
|
|
return isset($errorMessages[$value]) ? $errorMessages[$value] : $errorMessages[QUICKFORM_ERROR];
|
|
} // end func errorMessage
|
|
|
|
// }}}
|
|
} // end class HTML_QuickForm
|
|
|
|
/**
|
|
* Class for errors thrown by HTML_QuickForm package
|
|
*
|
|
* @category HTML
|
|
* @package HTML_QuickForm
|
|
* @author Adam Daniel <adaniel1@eesus.jnj.com>
|
|
* @author Bertrand Mansion <bmansion@mamasam.com>
|
|
* @version Release: 3.2.11
|
|
*/
|
|
class 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
|
|
*/
|
|
function HTML_QuickForm_Error($code = QUICKFORM_ERROR, $mode = PEAR_ERROR_RETURN,
|
|
$level = E_USER_NOTICE, $debuginfo = null)
|
|
{
|
|
if (is_int($code)) {
|
|
$this->PEAR_Error(HTML_QuickForm::errorMessage($code), $code, $mode, $level, $debuginfo);
|
|
} else {
|
|
$this->PEAR_Error("Invalid error code: $code", QUICKFORM_ERROR, $mode, $level, $debuginfo);
|
|
}
|
|
}
|
|
// }}}
|
|
} // end class HTML_QuickForm_Error
|
|
?>
|
|
|