Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/lib/pear/HTML/QuickForm.php
Go to the documentation of this file.
00001 <?php
00002 /* vim: set expandtab tabstop=4 shiftwidth=4: */
00003 // +----------------------------------------------------------------------+
00004 // | PHP version 4.0                                                      |
00005 // +----------------------------------------------------------------------+
00006 // | Copyright (c) 1997-2003 The PHP Group                                |
00007 // +----------------------------------------------------------------------+
00008 // | This source file is subject to version 2.0 of the PHP license,       |
00009 // | that is bundled with this package in the file LICENSE, and is        |
00010 // | available at through the world-wide-web at                           |
00011 // | http://www.php.net/license/2_02.txt.                                 |
00012 // | If you did not receive a copy of the PHP license and are unable to   |
00013 // | obtain it through the world-wide-web, please send a note to          |
00014 // | license@php.net so we can mail you a copy immediately.               |
00015 // +----------------------------------------------------------------------+
00016 // | Authors: Adam Daniel <adaniel1@eesus.jnj.com>                        |
00017 // |          Bertrand Mansion <bmansion@mamasam.com>                     |
00018 // +----------------------------------------------------------------------+
00019 //
00020 // $Id: QuickForm.php,v 1.8 2011/08/03 16:55:29 moodlerobot Exp $
00021 
00022 require_once('PEAR.php');
00023 require_once('HTML/Common.php');
00024 
00025 $GLOBALS['HTML_QUICKFORM_ELEMENT_TYPES'] =
00026         array(
00027             'group'         =>array('HTML/QuickForm/group.php','HTML_QuickForm_group'),
00028             'hidden'        =>array('HTML/QuickForm/hidden.php','HTML_QuickForm_hidden'),
00029             'reset'         =>array('HTML/QuickForm/reset.php','HTML_QuickForm_reset'),
00030             'checkbox'      =>array('HTML/QuickForm/checkbox.php','HTML_QuickForm_checkbox'),
00031             'file'          =>array('HTML/QuickForm/file.php','HTML_QuickForm_file'),
00032             'image'         =>array('HTML/QuickForm/image.php','HTML_QuickForm_image'),
00033             'password'      =>array('HTML/QuickForm/password.php','HTML_QuickForm_password'),
00034             'radio'         =>array('HTML/QuickForm/radio.php','HTML_QuickForm_radio'),
00035             'button'        =>array('HTML/QuickForm/button.php','HTML_QuickForm_button'),
00036             'submit'        =>array('HTML/QuickForm/submit.php','HTML_QuickForm_submit'),
00037             'select'        =>array('HTML/QuickForm/select.php','HTML_QuickForm_select'),
00038             'hiddenselect'  =>array('HTML/QuickForm/hiddenselect.php','HTML_QuickForm_hiddenselect'),
00039             'text'          =>array('HTML/QuickForm/text.php','HTML_QuickForm_text'),
00040             'textarea'      =>array('HTML/QuickForm/textarea.php','HTML_QuickForm_textarea'),
00041             'link'          =>array('HTML/QuickForm/link.php','HTML_QuickForm_link'),
00042             'advcheckbox'   =>array('HTML/QuickForm/advcheckbox.php','HTML_QuickForm_advcheckbox'),
00043             'date'          =>array('HTML/QuickForm/date.php','HTML_QuickForm_date'),
00044             'static'        =>array('HTML/QuickForm/static.php','HTML_QuickForm_static'),
00045             'header'        =>array('HTML/QuickForm/header.php', 'HTML_QuickForm_header'),
00046             'html'          =>array('HTML/QuickForm/html.php', 'HTML_QuickForm_html'),
00047             'hierselect'    =>array('HTML/QuickForm/hierselect.php', 'HTML_QuickForm_hierselect'),
00048             'autocomplete'  =>array('HTML/QuickForm/autocomplete.php', 'HTML_QuickForm_autocomplete'),
00049             'xbutton'       =>array('HTML/QuickForm/xbutton.php','HTML_QuickForm_xbutton')
00050         );
00051 
00052 $GLOBALS['_HTML_QuickForm_registered_rules'] = array(
00053     'required'      => array('html_quickform_rule_required', 'HTML/QuickForm/Rule/Required.php'),
00054     'maxlength'     => array('html_quickform_rule_range',    'HTML/QuickForm/Rule/Range.php'),
00055     'minlength'     => array('html_quickform_rule_range',    'HTML/QuickForm/Rule/Range.php'),
00056     'rangelength'   => array('html_quickform_rule_range',    'HTML/QuickForm/Rule/Range.php'),
00057     'email'         => array('html_quickform_rule_email',    'HTML/QuickForm/Rule/Email.php'),
00058     'regex'         => array('html_quickform_rule_regex',    'HTML/QuickForm/Rule/Regex.php'),
00059     'lettersonly'   => array('html_quickform_rule_regex',    'HTML/QuickForm/Rule/Regex.php'),
00060     'alphanumeric'  => array('html_quickform_rule_regex',    'HTML/QuickForm/Rule/Regex.php'),
00061     'numeric'       => array('html_quickform_rule_regex',    'HTML/QuickForm/Rule/Regex.php'),
00062     'nopunctuation' => array('html_quickform_rule_regex',    'HTML/QuickForm/Rule/Regex.php'),
00063     'nonzero'       => array('html_quickform_rule_regex',    'HTML/QuickForm/Rule/Regex.php'),
00064     'callback'      => array('html_quickform_rule_callback', 'HTML/QuickForm/Rule/Callback.php'),
00065     'compare'       => array('html_quickform_rule_compare',  'HTML/QuickForm/Rule/Compare.php')
00066 );
00067 
00068 // {{{ error codes
00069 
00070 /*
00071  * Error codes for the QuickForm interface, which will be mapped to textual messages
00072  * in the QuickForm::errorMessage() function.  If you are to add a new error code, be
00073  * sure to add the textual messages to the QuickForm::errorMessage() function as well
00074  */
00075 
00076 define('QUICKFORM_OK',                      1);
00077 define('QUICKFORM_ERROR',                  -1);
00078 define('QUICKFORM_INVALID_RULE',           -2);
00079 define('QUICKFORM_NONEXIST_ELEMENT',       -3);
00080 define('QUICKFORM_INVALID_FILTER',         -4);
00081 define('QUICKFORM_UNREGISTERED_ELEMENT',   -5);
00082 define('QUICKFORM_INVALID_ELEMENT_NAME',   -6);
00083 define('QUICKFORM_INVALID_PROCESS',        -7);
00084 define('QUICKFORM_DEPRECATED',             -8);
00085 define('QUICKFORM_INVALID_DATASOURCE',     -9);
00086 
00087 // }}}
00088 
00097 class HTML_QuickForm extends HTML_Common {
00098     // {{{ properties
00099 
00106     var $_elements = array();
00107 
00114     var $_elementIndex = array();
00115 
00122     var $_duplicateIndex = array();
00123 
00130     var $_required = array();
00131 
00138     var $_jsPrefix = 'Invalid information entered.';
00139 
00146     var $_jsPostfix = 'Please correct these fields.';
00147 
00155     var $_datasource;
00156 
00163     var $_defaultValues = array();
00164 
00171     var $_constantValues = array();
00172 
00179     var $_submitValues = array();
00180 
00187     var $_submitFiles = array();
00188 
00195     var $_maxFileSize = 1048576; // 1 Mb = 1048576
00196 
00203     var $_freezeAll = false;
00204 
00211     var $_rules = array();
00212 
00218     var $_formRules = array();
00219 
00226     var $_errors = array();
00227 
00234     var $_requiredNote = '<span style="font-size:80%; color:#ff0000;">*</span><span style="font-size:80%;"> denotes required field</span>';
00235 
00241     var $_flagSubmitted = false;
00242 
00243     // }}}
00244     // {{{ constructor
00245 
00256     function HTML_QuickForm($formName='', $method='post', $action='', $target='', $attributes=null, $trackSubmit = false)
00257     {
00258         HTML_Common::HTML_Common($attributes);
00259         $method = (strtoupper($method) == 'GET') ? 'get' : 'post';
00260         $action = ($action == '') ? $_SERVER['PHP_SELF'] : $action;
00261         $target = empty($target) ? array() : array('target' => $target);
00262         $attributes = array('action'=>$action, 'method'=>$method, 'name'=>$formName, 'id'=>$formName) + $target;
00263         $this->updateAttributes($attributes);
00264         if (!$trackSubmit || isset($_REQUEST['_qf__' . $formName])) {
00265             if (1 == get_magic_quotes_gpc()) {
00266                 $this->_submitValues = ('get' == $method? $_GET: $_POST); // we already eliminated magic quotes in moodle setup.php
00267                 foreach ($_FILES as $keyFirst => $valFirst) {
00268                     foreach ($valFirst as $keySecond => $valSecond) {
00269                         if ('name' == $keySecond) {
00270                             $this->_submitFiles[$keyFirst][$keySecond] = $valSecond; // we already eliminated magic quotes in moodle setup.php
00271                         } else {
00272                             $this->_submitFiles[$keyFirst][$keySecond] = $valSecond;
00273                         }
00274                     }
00275                 }
00276             } else {
00277                 $this->_submitValues = 'get' == $method? $_GET: $_POST;
00278                 $this->_submitFiles  = $_FILES;
00279             }
00280             $this->_flagSubmitted = count($this->_submitValues) > 0 || count($this->_submitFiles) > 0;
00281         }
00282         if ($trackSubmit) {
00283             unset($this->_submitValues['_qf__' . $formName]);
00284             $this->addElement('hidden', '_qf__' . $formName, null);
00285         }
00286         if (preg_match('/^([0-9]+)([a-zA-Z]*)$/', ini_get('upload_max_filesize'), $matches)) {
00287             // see http://www.php.net/manual/en/faq.using.php#faq.using.shorthandbytes
00288             switch (strtoupper($matches['2'])) {
00289                 case 'G':
00290                     $this->_maxFileSize = $matches['1'] * 1073741824;
00291                     break;
00292                 case 'M':
00293                     $this->_maxFileSize = $matches['1'] * 1048576;
00294                     break;
00295                 case 'K':
00296                     $this->_maxFileSize = $matches['1'] * 1024;
00297                     break;
00298                 default:
00299                     $this->_maxFileSize = $matches['1'];
00300             }
00301         }
00302     } // end constructor
00303 
00304     // }}}
00305     // {{{ apiVersion()
00306 
00314     function apiVersion()
00315     {
00316         return 3.2;
00317     } // end func apiVersion
00318 
00319     // }}}
00320     // {{{ registerElementType()
00321 
00332     function registerElementType($typeName, $include, $className)
00333     {
00334         $GLOBALS['HTML_QUICKFORM_ELEMENT_TYPES'][strtolower($typeName)] = array($include, $className);
00335     } // end func registerElementType
00336 
00337     // }}}
00338     // {{{ registerRule()
00339 
00351     function registerRule($ruleName, $type, $data1, $data2 = null)
00352     {
00353         include_once('HTML/QuickForm/RuleRegistry.php');
00354         $registry =& HTML_QuickForm_RuleRegistry::singleton();
00355         $registry->registerRule($ruleName, $type, $data1, $data2);
00356     } // end func registerRule
00357 
00358     // }}}
00359     // {{{ elementExists()
00360 
00369     function elementExists($element=null)
00370     {
00371         return isset($this->_elementIndex[$element]);
00372     } // end func elementExists
00373 
00374     // }}}
00375     // {{{ setDatasource()
00376 
00390     function setDatasource(&$datasource, $defaultsFilter = null, $constantsFilter = null)
00391     {
00392         if (is_object($datasource)) {
00393             $this->_datasource =& $datasource;
00394             if (is_callable(array($datasource, 'defaultValues'))) {
00395                 $this->setDefaults($datasource->defaultValues($this), $defaultsFilter);
00396             }
00397             if (is_callable(array($datasource, 'constantValues'))) {
00398                 $this->setConstants($datasource->constantValues($this), $constantsFilter);
00399             }
00400         } else {
00401             return PEAR::raiseError(null, QUICKFORM_INVALID_DATASOURCE, null, E_USER_WARNING, "Datasource is not an object in QuickForm::setDatasource()", 'HTML_QuickForm_Error', true);
00402         }
00403     } // end func setDatasource
00404 
00405     // }}}
00406     // {{{ setDefaults()
00407 
00417     function setDefaults($defaultValues = null, $filter = null)
00418     {
00419         if (is_array($defaultValues)) {
00420             if (isset($filter)) {
00421                 if (is_array($filter) && (2 != count($filter) || !is_callable($filter))) {
00422                     foreach ($filter as $val) {
00423                         if (!is_callable($val)) {
00424                             return PEAR::raiseError(null, QUICKFORM_INVALID_FILTER, null, E_USER_WARNING, "Callback function does not exist in QuickForm::setDefaults()", 'HTML_QuickForm_Error', true);
00425                         } else {
00426                             $defaultValues = $this->_recursiveFilter($val, $defaultValues);
00427                         }
00428                     }
00429                 } elseif (!is_callable($filter)) {
00430                     return PEAR::raiseError(null, QUICKFORM_INVALID_FILTER, null, E_USER_WARNING, "Callback function does not exist in QuickForm::setDefaults()", 'HTML_QuickForm_Error', true);
00431                 } else {
00432                     $defaultValues = $this->_recursiveFilter($filter, $defaultValues);
00433                 }
00434             }
00435             $this->_defaultValues = HTML_QuickForm::arrayMerge($this->_defaultValues, $defaultValues);
00436             foreach (array_keys($this->_elements) as $key) {
00437                 $this->_elements[$key]->onQuickFormEvent('updateValue', null, $this);
00438             }
00439         }
00440     } // end func setDefaults
00441 
00442     // }}}
00443     // {{{ setConstants()
00444 
00456     function setConstants($constantValues = null, $filter = null)
00457     {
00458         if (is_array($constantValues)) {
00459             if (isset($filter)) {
00460                 if (is_array($filter) && (2 != count($filter) || !is_callable($filter))) {
00461                     foreach ($filter as $val) {
00462                         if (!is_callable($val)) {
00463                             return PEAR::raiseError(null, QUICKFORM_INVALID_FILTER, null, E_USER_WARNING, "Callback function does not exist in QuickForm::setConstants()", 'HTML_QuickForm_Error', true);
00464                         } else {
00465                             $constantValues = $this->_recursiveFilter($val, $constantValues);
00466                         }
00467                     }
00468                 } elseif (!is_callable($filter)) {
00469                     return PEAR::raiseError(null, QUICKFORM_INVALID_FILTER, null, E_USER_WARNING, "Callback function does not exist in QuickForm::setConstants()", 'HTML_QuickForm_Error', true);
00470                 } else {
00471                     $constantValues = $this->_recursiveFilter($filter, $constantValues);
00472                 }
00473             }
00474             $this->_constantValues = HTML_QuickForm::arrayMerge($this->_constantValues, $constantValues);
00475             foreach (array_keys($this->_elements) as $key) {
00476                 $this->_elements[$key]->onQuickFormEvent('updateValue', null, $this);
00477             }
00478         }
00479     } // end func setConstants
00480 
00481     // }}}
00482     // {{{ setMaxFileSize()
00483 
00492     function setMaxFileSize($bytes = 0)
00493     {
00494         if ($bytes > 0) {
00495             $this->_maxFileSize = $bytes;
00496         }
00497         if (!$this->elementExists('MAX_FILE_SIZE')) {
00498             $this->addElement('hidden', 'MAX_FILE_SIZE', $this->_maxFileSize);
00499         } else {
00500             $el =& $this->getElement('MAX_FILE_SIZE');
00501             $el->updateAttributes(array('value' => $this->_maxFileSize));
00502         }
00503     } // end func setMaxFileSize
00504 
00505     // }}}
00506     // {{{ getMaxFileSize()
00507 
00515     function getMaxFileSize()
00516     {
00517         return $this->_maxFileSize;
00518     } // end func getMaxFileSize
00519 
00520     // }}}
00521     // {{{ &createElement()
00522 
00535     function &createElement($elementType)
00536     {
00537         $args    =  func_get_args();
00538         $element =& HTML_QuickForm::_loadElement('createElement', $elementType, array_slice($args, 1));
00539         return $element;
00540     } // end func createElement
00541 
00542     // }}}
00543     // {{{ _loadElement()
00544 
00556     function &_loadElement($event, $type, $args)
00557     {
00558         $type = strtolower($type);
00559         if (!HTML_QuickForm::isTypeRegistered($type)) {
00560             $error = PEAR::raiseError(null, QUICKFORM_UNREGISTERED_ELEMENT, null, E_USER_WARNING, "Element '$type' does not exist in HTML_QuickForm::_loadElement()", 'HTML_QuickForm_Error', true);
00561             return $error;
00562         }
00563         $className = $GLOBALS['HTML_QUICKFORM_ELEMENT_TYPES'][$type][1];
00564         $includeFile = $GLOBALS['HTML_QUICKFORM_ELEMENT_TYPES'][$type][0];
00565         include_once($includeFile);
00566         $elementObject = new $className(); //Moodle: PHP 5.3 compatibility
00567         for ($i = 0; $i < 5; $i++) {
00568             if (!isset($args[$i])) {
00569                 $args[$i] = null;
00570             }
00571         }
00572         $err = $elementObject->onQuickFormEvent($event, $args, $this);
00573         if ($err !== true) {
00574             return $err;
00575         }
00576         return $elementObject;
00577     } // end func _loadElement
00578 
00579     // }}}
00580     // {{{ addElement()
00581 
00595     function &addElement($element)
00596     {
00597         if (is_object($element) && is_subclass_of($element, 'html_quickform_element')) {
00598            $elementObject = &$element;
00599            $elementObject->onQuickFormEvent('updateValue', null, $this);
00600         } else {
00601             $args = func_get_args();
00602             $elementObject =& $this->_loadElement('addElement', $element, array_slice($args, 1));
00603             if (PEAR::isError($elementObject)) {
00604                 return $elementObject;
00605             }
00606         }
00607         $elementName = $elementObject->getName();
00608 
00609         // Add the element if it is not an incompatible duplicate
00610         if (!empty($elementName) && isset($this->_elementIndex[$elementName])) {
00611             if ($this->_elements[$this->_elementIndex[$elementName]]->getType() ==
00612                 $elementObject->getType()) {
00613                 $this->_elements[] =& $elementObject;
00614                 $elKeys = array_keys($this->_elements);
00615                 $this->_duplicateIndex[$elementName][] = end($elKeys);
00616             } else {
00617                 $error = PEAR::raiseError(null, QUICKFORM_INVALID_ELEMENT_NAME, null, E_USER_WARNING, "Element '$elementName' already exists in HTML_QuickForm::addElement()", 'HTML_QuickForm_Error', true);
00618                 return $error;
00619             }
00620         } else {
00621             $this->_elements[] =& $elementObject;
00622             $elKeys = array_keys($this->_elements);
00623             $this->_elementIndex[$elementName] = end($elKeys);
00624         }
00625         if ($this->_freezeAll) {
00626             $elementObject->freeze();
00627         }
00628 
00629         return $elementObject;
00630     } // end func addElement
00631 
00632     // }}}
00633     // {{{ insertElementBefore()
00634 
00650     function &insertElementBefore(&$element, $nameAfter)
00651     {
00652         if (!empty($this->_duplicateIndex[$nameAfter])) {
00653             $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);
00654             return $error;
00655         } elseif (!$this->elementExists($nameAfter)) {
00656             $error = PEAR::raiseError(null, QUICKFORM_NONEXIST_ELEMENT, null, E_USER_WARNING, "Element '$nameAfter' does not exist in HTML_QuickForm::insertElementBefore()", 'HTML_QuickForm_Error', true);
00657             return $error;
00658         }
00659         $elementName = $element->getName();
00660         $targetIdx   = $this->_elementIndex[$nameAfter];
00661         $duplicate   = false;
00662         // Like in addElement(), check that it's not an incompatible duplicate
00663         if (!empty($elementName) && isset($this->_elementIndex[$elementName])) {
00664             if ($this->_elements[$this->_elementIndex[$elementName]]->getType() != $element->getType()) {
00665                 $error = PEAR::raiseError(null, QUICKFORM_INVALID_ELEMENT_NAME, null, E_USER_WARNING, "Element '$elementName' already exists in HTML_QuickForm::insertElementBefore()", 'HTML_QuickForm_Error', true);
00666                 return $error;
00667             }
00668             $duplicate = true;
00669         }
00670         // Move all the elements after added back one place, reindex _elementIndex and/or _duplicateIndex
00671         $elKeys = array_keys($this->_elements);
00672         for ($i = end($elKeys); $i >= $targetIdx; $i--) {
00673             if (isset($this->_elements[$i])) {
00674                 $currentName = $this->_elements[$i]->getName();
00675                 $this->_elements[$i + 1] =& $this->_elements[$i];
00676                 if ($this->_elementIndex[$currentName] == $i) {
00677                     $this->_elementIndex[$currentName] = $i + 1;
00678                 } else {
00679                     $dupIdx = array_search($i, $this->_duplicateIndex[$currentName]);
00680                     $this->_duplicateIndex[$currentName][$dupIdx] = $i + 1;
00681                 }
00682                 unset($this->_elements[$i]);
00683             }
00684         }
00685         // Put the element in place finally
00686         $this->_elements[$targetIdx] =& $element;
00687         if (!$duplicate) {
00688             $this->_elementIndex[$elementName] = $targetIdx;
00689         } else {
00690             $this->_duplicateIndex[$elementName][] = $targetIdx;
00691         }
00692         $element->onQuickFormEvent('updateValue', null, $this);
00693         if ($this->_freezeAll) {
00694             $element->freeze();
00695         }
00696         // If not done, the elements will appear in reverse order
00697         ksort($this->_elements);
00698         return $element;
00699     }
00700 
00701     // }}}
00702     // {{{ addGroup()
00703 
00717     function &addGroup($elements, $name=null, $groupLabel='', $separator=null, $appendName = true)
00718     {
00719         static $anonGroups = 1;
00720 
00721         if (0 == strlen($name)) {
00722             $name       = 'qf_group_' . $anonGroups++;
00723             $appendName = false;
00724         }
00725         $group =& $this->addElement('group', $name, $groupLabel, $elements, $separator, $appendName);
00726         return $group;
00727     } // end func addGroup
00728 
00729     // }}}
00730     // {{{ &getElement()
00731 
00741     function &getElement($element)
00742     {
00743         if (isset($this->_elementIndex[$element])) {
00744             return $this->_elements[$this->_elementIndex[$element]];
00745         } else {
00746             $error = PEAR::raiseError(null, QUICKFORM_NONEXIST_ELEMENT, null, E_USER_WARNING, "Element '$element' does not exist in HTML_QuickForm::getElement()", 'HTML_QuickForm_Error', true);
00747             return $error;
00748         }
00749     } // end func getElement
00750 
00751     // }}}
00752     // {{{ &getElementValue()
00753 
00766     function &getElementValue($element)
00767     {
00768         if (!isset($this->_elementIndex[$element])) {
00769             $error = PEAR::raiseError(null, QUICKFORM_NONEXIST_ELEMENT, null, E_USER_WARNING, "Element '$element' does not exist in HTML_QuickForm::getElementValue()", 'HTML_QuickForm_Error', true);
00770             return $error;
00771         }
00772         $value = $this->_elements[$this->_elementIndex[$element]]->getValue();
00773         if (isset($this->_duplicateIndex[$element])) {
00774             foreach ($this->_duplicateIndex[$element] as $index) {
00775                 if (null !== ($v = $this->_elements[$index]->getValue())) {
00776                     if (is_array($value)) {
00777                         $value[] = $v;
00778                     } else {
00779                         $value = (null === $value)? $v: array($value, $v);
00780                     }
00781                 }
00782             }
00783         }
00784         return $value;
00785     } // end func getElementValue
00786 
00787     // }}}
00788     // {{{ getSubmitValue()
00789 
00798     function getSubmitValue($elementName)
00799     {
00800         $value = null;
00801         if (isset($this->_submitValues[$elementName]) || isset($this->_submitFiles[$elementName])) {
00802             $value = isset($this->_submitValues[$elementName])? $this->_submitValues[$elementName]: array();
00803             if (is_array($value) && isset($this->_submitFiles[$elementName])) {
00804                 foreach ($this->_submitFiles[$elementName] as $k => $v) {
00805                     $value = HTML_QuickForm::arrayMerge($value, $this->_reindexFiles($this->_submitFiles[$elementName][$k], $k));
00806                 }
00807             }
00808 
00809         } elseif ('file' == $this->getElementType($elementName)) {
00810             return $this->getElementValue($elementName);
00811 
00812         } elseif (false !== ($pos = strpos($elementName, '['))) {
00813             $base = substr($elementName, 0, $pos);
00814             $idx  = "['" . str_replace(array(']', '['), array('', "']['"), substr($elementName, $pos + 1, -1)) . "']";
00815             if (isset($this->_submitValues[$base])) {
00816                 $value = eval("return (isset(\$this->_submitValues['{$base}']{$idx})) ? \$this->_submitValues['{$base}']{$idx} : null;");
00817             }
00818 
00819             if ((is_array($value) || null === $value) && isset($this->_submitFiles[$base])) {
00820                 $props = array('name', 'type', 'size', 'tmp_name', 'error');
00821                 $code  = "if (!isset(\$this->_submitFiles['{$base}']['name']{$idx})) {\n" .
00822                          "    return null;\n" .
00823                          "} else {\n" .
00824                          "    \$v = array();\n";
00825                 foreach ($props as $prop) {
00826                     $code .= "    \$v = HTML_QuickForm::arrayMerge(\$v, \$this->_reindexFiles(\$this->_submitFiles['{$base}']['{$prop}']{$idx}, '{$prop}'));\n";
00827                 }
00828                 $fileValue = eval($code . "    return \$v;\n}\n");
00829                 if (null !== $fileValue) {
00830                     $value = null === $value? $fileValue: HTML_QuickForm::arrayMerge($value, $fileValue);
00831                 }
00832             }
00833         }
00834 
00835         // This is only supposed to work for groups with appendName = false
00836         if (null === $value && 'group' == $this->getElementType($elementName)) {
00837             $group    =& $this->getElement($elementName);
00838             $elements =& $group->getElements();
00839             foreach (array_keys($elements) as $key) {
00840                 $name = $group->getElementName($key);
00841                 // prevent endless recursion in case of radios and such
00842                 if ($name != $elementName) {
00843                     if (null !== ($v = $this->getSubmitValue($name))) {
00844                         $value[$name] = $v;
00845                     }
00846                 }
00847             }
00848         }
00849         return $value;
00850     } // end func getSubmitValue
00851 
00852     // }}}
00853     // {{{ _reindexFiles()
00854 
00862     function _reindexFiles($value, $key)
00863     {
00864         if (!is_array($value)) {
00865             return array($key => $value);
00866         } else {
00867             $ret = array();
00868             foreach ($value as $k => $v) {
00869                 $ret[$k] = $this->_reindexFiles($v, $key);
00870             }
00871             return $ret;
00872         }
00873     }
00874 
00875     // }}}
00876     // {{{ getElementError()
00877 
00886     function getElementError($element)
00887     {
00888         if (isset($this->_errors[$element])) {
00889             return $this->_errors[$element];
00890         }
00891     } // end func getElementError
00892 
00893     // }}}
00894     // {{{ setElementError()
00895 
00905     function setElementError($element, $message = null)
00906     {
00907         if (!empty($message)) {
00908             $this->_errors[$element] = $message;
00909         } else {
00910             unset($this->_errors[$element]);
00911         }
00912     } // end func setElementError
00913 
00914      // }}}
00915      // {{{ getElementType()
00916 
00925      function getElementType($element)
00926      {
00927          if (isset($this->_elementIndex[$element])) {
00928              return $this->_elements[$this->_elementIndex[$element]]->getType();
00929          }
00930          return false;
00931      } // end func getElementType
00932 
00933      // }}}
00934      // {{{ updateElementAttr()
00935 
00945     function updateElementAttr($elements, $attrs)
00946     {
00947         if (is_string($elements)) {
00948             $elements = preg_split('/[ ]?,[ ]?/', $elements);
00949         }
00950         foreach (array_keys($elements) as $key) {
00951             if (is_object($elements[$key]) && is_a($elements[$key], 'HTML_QuickForm_element')) {
00952                 $elements[$key]->updateAttributes($attrs);
00953             } elseif (isset($this->_elementIndex[$elements[$key]])) {
00954                 $this->_elements[$this->_elementIndex[$elements[$key]]]->updateAttributes($attrs);
00955                 if (isset($this->_duplicateIndex[$elements[$key]])) {
00956                     foreach ($this->_duplicateIndex[$elements[$key]] as $index) {
00957                         $this->_elements[$index]->updateAttributes($attrs);
00958                     }
00959                 }
00960             }
00961         }
00962     } // end func updateElementAttr
00963 
00964     // }}}
00965     // {{{ removeElement()
00966 
00981     function &removeElement($elementName, $removeRules = true)
00982     {
00983         if (!isset($this->_elementIndex[$elementName])) {
00984             $error = PEAR::raiseError(null, QUICKFORM_NONEXIST_ELEMENT, null, E_USER_WARNING, "Element '$elementName' does not exist in HTML_QuickForm::removeElement()", 'HTML_QuickForm_Error', true);
00985             return $error;
00986         }
00987         $el =& $this->_elements[$this->_elementIndex[$elementName]];
00988         unset($this->_elements[$this->_elementIndex[$elementName]]);
00989         if (empty($this->_duplicateIndex[$elementName])) {
00990             unset($this->_elementIndex[$elementName]);
00991         } else {
00992             $this->_elementIndex[$elementName] = array_shift($this->_duplicateIndex[$elementName]);
00993         }
00994         if ($removeRules) {
00995             unset($this->_rules[$elementName], $this->_errors[$elementName]);
00996         }
00997         return $el;
00998     } // end func removeElement
00999 
01000     // }}}
01001     // {{{ addRule()
01002 
01021     function addRule($element, $message, $type, $format=null, $validation='server', $reset = false, $force = false)
01022     {
01023         if (!$force) {
01024             if (!is_array($element) && !$this->elementExists($element)) {
01025                 return PEAR::raiseError(null, QUICKFORM_NONEXIST_ELEMENT, null, E_USER_WARNING, "Element '$element' does not exist in HTML_QuickForm::addRule()", 'HTML_QuickForm_Error', true);
01026             } elseif (is_array($element)) {
01027                 foreach ($element as $el) {
01028                     if (!$this->elementExists($el)) {
01029                         return PEAR::raiseError(null, QUICKFORM_NONEXIST_ELEMENT, null, E_USER_WARNING, "Element '$el' does not exist in HTML_QuickForm::addRule()", 'HTML_QuickForm_Error', true);
01030                     }
01031                 }
01032             }
01033         }
01034         if (false === ($newName = $this->isRuleRegistered($type, true))) {
01035             return PEAR::raiseError(null, QUICKFORM_INVALID_RULE, null, E_USER_WARNING, "Rule '$type' is not registered in HTML_QuickForm::addRule()", 'HTML_QuickForm_Error', true);
01036         } elseif (is_string($newName)) {
01037             $type = $newName;
01038         }
01039         if (is_array($element)) {
01040             $dependent = $element;
01041             $element   = array_shift($dependent);
01042         } else {
01043             $dependent = null;
01044         }
01045         if ($type == 'required' || $type == 'uploadedfile') {
01046             $this->_required[] = $element;
01047         }
01048         if (!isset($this->_rules[$element])) {
01049             $this->_rules[$element] = array();
01050         }
01051         if ($validation == 'client') {
01052             $this->updateAttributes(array('onsubmit' => 'try { var myValidator = validate_' . $this->_attributes['id'] . '; } catch(e) { return true; } return myValidator(this);'));
01053         }
01054         $this->_rules[$element][] = array(
01055             'type'        => $type,
01056             'format'      => $format,
01057             'message'     => $message,
01058             'validation'  => $validation,
01059             'reset'       => $reset,
01060             'dependent'   => $dependent
01061         );
01062     } // end func addRule
01063 
01064     // }}}
01065     // {{{ addGroupRule()
01066 
01087     function addGroupRule($group, $arg1, $type='', $format=null, $howmany=0, $validation = 'server', $reset = false)
01088     {
01089         if (!$this->elementExists($group)) {
01090             return PEAR::raiseError(null, QUICKFORM_NONEXIST_ELEMENT, null, E_USER_WARNING, "Group '$group' does not exist in HTML_QuickForm::addGroupRule()", 'HTML_QuickForm_Error', true);
01091         }
01092 
01093         $groupObj =& $this->getElement($group);
01094         if (is_array($arg1)) {
01095             $required = 0;
01096             foreach ($arg1 as $elementIndex => $rules) {
01097                 $elementName = $groupObj->getElementName($elementIndex);
01098                 foreach ($rules as $rule) {
01099                     $format = (isset($rule[2])) ? $rule[2] : null;
01100                     $validation = (isset($rule[3]) && 'client' == $rule[3])? 'client': 'server';
01101                     $reset = isset($rule[4]) && $rule[4];
01102                     $type = $rule[1];
01103                     if (false === ($newName = $this->isRuleRegistered($type, true))) {
01104                         return PEAR::raiseError(null, QUICKFORM_INVALID_RULE, null, E_USER_WARNING, "Rule '$type' is not registered in HTML_QuickForm::addGroupRule()", 'HTML_QuickForm_Error', true);
01105                     } elseif (is_string($newName)) {
01106                         $type = $newName;
01107                     }
01108 
01109                     $this->_rules[$elementName][] = array(
01110                                                         'type'        => $type,
01111                                                         'format'      => $format,
01112                                                         'message'     => $rule[0],
01113                                                         'validation'  => $validation,
01114                                                         'reset'       => $reset,
01115                                                         'group'       => $group);
01116 
01117                     if ('required' == $type || 'uploadedfile' == $type) {
01118                         $groupObj->_required[] = $elementName;
01119                         $this->_required[] = $elementName;
01120                         $required++;
01121                     }
01122                     if ('client' == $validation) {
01123                         $this->updateAttributes(array('onsubmit' => 'try { var myValidator = validate_' . $this->_attributes['id'] . '; } catch(e) { return true; } return myValidator(this);'));
01124                     }
01125                 }
01126             }
01127             if ($required > 0 && count($groupObj->getElements()) == $required) {
01128                 $this->_required[] = $group;
01129             }
01130         } elseif (is_string($arg1)) {
01131             if (false === ($newName = $this->isRuleRegistered($type, true))) {
01132                 return PEAR::raiseError(null, QUICKFORM_INVALID_RULE, null, E_USER_WARNING, "Rule '$type' is not registered in HTML_QuickForm::addGroupRule()", 'HTML_QuickForm_Error', true);
01133             } elseif (is_string($newName)) {
01134                 $type = $newName;
01135             }
01136 
01137             // addGroupRule() should also handle <select multiple>
01138             if (is_a($groupObj, 'html_quickform_group')) {
01139                 // Radios need to be handled differently when required
01140                 if ($type == 'required' && $groupObj->getGroupType() == 'radio') {
01141                     $howmany = ($howmany == 0) ? 1 : $howmany;
01142                 } else {
01143                     $howmany = ($howmany == 0) ? count($groupObj->getElements()) : $howmany;
01144                 }
01145             }
01146 
01147             $this->_rules[$group][] = array('type'       => $type,
01148                                             'format'     => $format,
01149                                             'message'    => $arg1,
01150                                             'validation' => $validation,
01151                                             'howmany'    => $howmany,
01152                                             'reset'      => $reset);
01153             if ($type == 'required') {
01154                 $this->_required[] = $group;
01155             }
01156             if ($validation == 'client') {
01157                 $this->updateAttributes(array('onsubmit' => 'try { var myValidator = validate_' . $this->_attributes['id'] . '; } catch(e) { return true; } return myValidator(this);'));
01158             }
01159         }
01160     } // end func addGroupRule
01161 
01162     // }}}
01163     // {{{ addFormRule()
01164 
01177     function addFormRule($rule)
01178     {
01179         if (!is_callable($rule)) {
01180             return PEAR::raiseError(null, QUICKFORM_INVALID_RULE, null, E_USER_WARNING, 'Callback function does not exist in HTML_QuickForm::addFormRule()', 'HTML_QuickForm_Error', true);
01181         }
01182         $this->_formRules[] = $rule;
01183     }
01184 
01185     // }}}
01186     // {{{ applyFilter()
01187 
01196     function applyFilter($element, $filter)
01197     {
01198         if (!is_callable($filter)) {
01199             return PEAR::raiseError(null, QUICKFORM_INVALID_FILTER, null, E_USER_WARNING, "Callback function does not exist in QuickForm::applyFilter()", 'HTML_QuickForm_Error', true);
01200         }
01201         if ($element == '__ALL__') {
01202             $this->_submitValues = $this->_recursiveFilter($filter, $this->_submitValues);
01203         } else {
01204             if (!is_array($element)) {
01205                 $element = array($element);
01206             }
01207             foreach ($element as $elName) {
01208                 $value = $this->getSubmitValue($elName);
01209                 if (null !== $value) {
01210                     if (false === strpos($elName, '[')) {
01211                         $this->_submitValues[$elName] = $this->_recursiveFilter($filter, $value);
01212                     } else {
01213                         $idx  = "['" . str_replace(array(']', '['), array('', "']['"), $elName) . "']";
01214                         eval("\$this->_submitValues{$idx} = \$this->_recursiveFilter(\$filter, \$value);");
01215                     }
01216                 }
01217             }
01218         }
01219     } // end func applyFilter
01220 
01221     // }}}
01222     // {{{ _recursiveFilter()
01223 
01233     function _recursiveFilter($filter, $value)
01234     {
01235         if (is_array($value)) {
01236             $cleanValues = array();
01237             foreach ($value as $k => $v) {
01238                 $cleanValues[$k] = $this->_recursiveFilter($filter, $v);
01239             }
01240             return $cleanValues;
01241         } else {
01242             return call_user_func($filter, $value);
01243         }
01244     } // end func _recursiveFilter
01245 
01246     // }}}
01247     // {{{ arrayMerge()
01248 
01261     function arrayMerge($a, $b)
01262     {
01263         foreach ($b as $k => $v) {
01264             if (is_array($v)) {
01265                 if (isset($a[$k]) && !is_array($a[$k])) {
01266                     $a[$k] = $v;
01267                 } else {
01268                     if (!isset($a[$k])) {
01269                         $a[$k] = array();
01270                     }
01271                     $a[$k] = HTML_QuickForm::arrayMerge($a[$k], $v);
01272                 }
01273             } else {
01274                 $a[$k] = $v;
01275             }
01276         }
01277         return $a;
01278     } // end func arrayMerge
01279 
01280     // }}}
01281     // {{{ isTypeRegistered()
01282 
01291     function isTypeRegistered($type)
01292     {
01293         return isset($GLOBALS['HTML_QUICKFORM_ELEMENT_TYPES'][strtolower($type)]);
01294     } // end func isTypeRegistered
01295 
01296     // }}}
01297     // {{{ getRegisteredTypes()
01298 
01306     function getRegisteredTypes()
01307     {
01308         return array_keys($GLOBALS['HTML_QUICKFORM_ELEMENT_TYPES']);
01309     } // end func getRegisteredTypes
01310 
01311     // }}}
01312     // {{{ isRuleRegistered()
01313 
01323     function isRuleRegistered($name, $autoRegister = false)
01324     {
01325         if (is_scalar($name) && isset($GLOBALS['_HTML_QuickForm_registered_rules'][$name])) {
01326             return true;
01327         } elseif (!$autoRegister) {
01328             return false;
01329         }
01330         // automatically register the rule if requested
01331         include_once 'HTML/QuickForm/RuleRegistry.php';
01332         $ruleName = false;
01333         if (is_object($name) && is_a($name, 'html_quickform_rule')) {
01334             $ruleName = !empty($name->name)? $name->name: strtolower(get_class($name));
01335         } elseif (is_string($name) && class_exists($name)) {
01336             $parent = strtolower($name);
01337             do {
01338                 if ('html_quickform_rule' == strtolower($parent)) {
01339                     $ruleName = strtolower($name);
01340                     break;
01341                 }
01342             } while ($parent = get_parent_class($parent));
01343         }
01344         if ($ruleName) {
01345             $registry =& HTML_QuickForm_RuleRegistry::singleton();
01346             $registry->registerRule($ruleName, null, $name);
01347         }
01348         return $ruleName;
01349     } // end func isRuleRegistered
01350 
01351     // }}}
01352     // {{{ getRegisteredRules()
01353 
01361     function getRegisteredRules()
01362     {
01363         return array_keys($GLOBALS['_HTML_QuickForm_registered_rules']);
01364     } // end func getRegisteredRules
01365 
01366     // }}}
01367     // {{{ isElementRequired()
01368 
01377     function isElementRequired($element)
01378     {
01379         return in_array($element, $this->_required, true);
01380     } // end func isElementRequired
01381 
01382     // }}}
01383     // {{{ isElementFrozen()
01384 
01393     function isElementFrozen($element)
01394     {
01395          if (isset($this->_elementIndex[$element])) {
01396              return $this->_elements[$this->_elementIndex[$element]]->isFrozen();
01397          }
01398          return false;
01399     } // end func isElementFrozen
01400 
01401     // }}}
01402     // {{{ setJsWarnings()
01403 
01413     function setJsWarnings($pref, $post)
01414     {
01415         $this->_jsPrefix = $pref;
01416         $this->_jsPostfix = $post;
01417     } // end func setJsWarnings
01418 
01419     // }}}
01420     // {{{ setRequiredNote()
01421 
01430     function setRequiredNote($note)
01431     {
01432         $this->_requiredNote = $note;
01433     } // end func setRequiredNote
01434 
01435     // }}}
01436     // {{{ getRequiredNote()
01437 
01445     function getRequiredNote()
01446     {
01447         return $this->_requiredNote;
01448     } // end func getRequiredNote
01449 
01450     // }}}
01451     // {{{ validate()
01452 
01459     function validate()
01460     {
01461         if (count($this->_rules) == 0 && count($this->_formRules) == 0 &&
01462             $this->isSubmitted()) {
01463             return (0 == count($this->_errors));
01464         } elseif (!$this->isSubmitted()) {
01465             return false;
01466         }
01467 
01468         include_once('HTML/QuickForm/RuleRegistry.php');
01469         $registry =& HTML_QuickForm_RuleRegistry::singleton();
01470 
01471         foreach ($this->_rules as $target => $rules) {
01472             $submitValue = $this->getSubmitValue($target);
01473 
01474             foreach ($rules as $rule) {
01475                 if ((isset($rule['group']) && isset($this->_errors[$rule['group']])) ||
01476                      isset($this->_errors[$target])) {
01477                     continue 2;
01478                 }
01479                 // If element is not required and is empty, we shouldn't validate it
01480                 if (!$this->isElementRequired($target)) {
01481                     if (!isset($submitValue) || '' == $submitValue) {
01482                         continue 2;
01483                     // Fix for bug #3501: we shouldn't validate not uploaded files, either.
01484                     // Unfortunately, we can't just use $element->isUploadedFile() since
01485                     // the element in question can be buried in group. Thus this hack.
01486                     } elseif (is_array($submitValue)) {
01487                         if (false === ($pos = strpos($target, '['))) {
01488                             $isUpload = !empty($this->_submitFiles[$target]);
01489                         } else {
01490                             $base = substr($target, 0, $pos);
01491                             $idx  = "['" . str_replace(array(']', '['), array('', "']['"), substr($target, $pos + 1, -1)) . "']";
01492                             eval("\$isUpload = isset(\$this->_submitFiles['{$base}']['name']{$idx});");
01493                         }
01494                         if ($isUpload && (!isset($submitValue['error']) || 0 != $submitValue['error'])) {
01495                             continue 2;
01496                         }
01497                     }
01498                 }
01499                 if (isset($rule['dependent']) && is_array($rule['dependent'])) {
01500                     $values = array($submitValue);
01501                     foreach ($rule['dependent'] as $elName) {
01502                         $values[] = $this->getSubmitValue($elName);
01503                     }
01504                     $result = $registry->validate($rule['type'], $values, $rule['format'], true);
01505                 } elseif (is_array($submitValue) && !isset($rule['howmany'])) {
01506                     $result = $registry->validate($rule['type'], $submitValue, $rule['format'], true);
01507                 } else {
01508                     $result = $registry->validate($rule['type'], $submitValue, $rule['format'], false);
01509                 }
01510 
01511                 if (!$result || (!empty($rule['howmany']) && $rule['howmany'] > (int)$result)) {
01512                     if (isset($rule['group'])) {
01513                         $this->_errors[$rule['group']] = $rule['message'];
01514                     } else {
01515                         $this->_errors[$target] = $rule['message'];
01516                     }
01517                 }
01518             }
01519         }
01520 
01521         // process the global rules now
01522         foreach ($this->_formRules as $rule) {
01523             if (true !== ($res = call_user_func($rule, $this->_submitValues, $this->_submitFiles))) {
01524                 if (is_array($res)) {
01525                     $this->_errors += $res;
01526                 } else {
01527                     return PEAR::raiseError(null, QUICKFORM_ERROR, null, E_USER_WARNING, 'Form rule callback returned invalid value in HTML_QuickForm::validate()', 'HTML_QuickForm_Error', true);
01528                 }
01529             }
01530         }
01531 
01532         return (0 == count($this->_errors));
01533     } // end func validate
01534 
01535     // }}}
01536     // {{{ freeze()
01537 
01546     function freeze($elementList=null)
01547     {
01548         if (!isset($elementList)) {
01549             $this->_freezeAll = true;
01550             $elementList = array();
01551         } else {
01552             if (!is_array($elementList)) {
01553                 $elementList = preg_split('/[ ]*,[ ]*/', $elementList);
01554             }
01555             $elementList = array_flip($elementList);
01556         }
01557 
01558         foreach (array_keys($this->_elements) as $key) {
01559             $name = $this->_elements[$key]->getName();
01560             if ($this->_freezeAll || isset($elementList[$name])) {
01561                 $this->_elements[$key]->freeze();
01562                 unset($elementList[$name]);
01563             }
01564         }
01565 
01566         if (!empty($elementList)) {
01567             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);
01568         }
01569         return true;
01570     } // end func freeze
01571 
01572     // }}}
01573     // {{{ isFrozen()
01574 
01582     function isFrozen()
01583     {
01584          return $this->_freezeAll;
01585     } // end func isFrozen
01586 
01587     // }}}
01588     // {{{ process()
01589 
01599     function process($callback, $mergeFiles = true)
01600     {
01601         if (!is_callable($callback)) {
01602             return PEAR::raiseError(null, QUICKFORM_INVALID_PROCESS, null, E_USER_WARNING, "Callback function does not exist in QuickForm::process()", 'HTML_QuickForm_Error', true);
01603         }
01604         $values = ($mergeFiles === true) ? HTML_QuickForm::arrayMerge($this->_submitValues, $this->_submitFiles) : $this->_submitValues;
01605         return call_user_func($callback, $values);
01606     } // end func process
01607 
01608     // }}}
01609     // {{{ accept()
01610 
01619     function accept(&$renderer)
01620     {
01621         $renderer->startForm($this);
01622         foreach (array_keys($this->_elements) as $key) {
01623             $element =& $this->_elements[$key];
01624             $elementName = $element->getName();
01625             $required    = ($this->isElementRequired($elementName) && !$element->isFrozen());
01626             $error       = $this->getElementError($elementName);
01627             $element->accept($renderer, $required, $error);
01628         }
01629         $renderer->finishForm($this);
01630     } // end func accept
01631 
01632     // }}}
01633     // {{{ defaultRenderer()
01634 
01642     function &defaultRenderer()
01643     {
01644         if (!isset($GLOBALS['_HTML_QuickForm_default_renderer'])) {
01645             include_once('HTML/QuickForm/Renderer/Default.php');
01646             $GLOBALS['_HTML_QuickForm_default_renderer'] = new HTML_QuickForm_Renderer_Default(); //Moodle: PHP 5.3 compatibility
01647         }
01648         return $GLOBALS['_HTML_QuickForm_default_renderer'];
01649     } // end func defaultRenderer
01650 
01651     // }}}
01652     // {{{ toHtml ()
01653 
01664     function toHtml ($in_data = null)
01665     {
01666         if (!is_null($in_data)) {
01667             $this->addElement('html', $in_data);
01668         }
01669         $renderer =& $this->defaultRenderer();
01670         $this->accept($renderer);
01671         return $renderer->toHtml();
01672     } // end func toHtml
01673 
01674     // }}}
01675     // {{{ getValidationScript()
01676 
01684     function getValidationScript()
01685     {
01686         if (empty($this->_rules) || empty($this->_attributes['onsubmit'])) {
01687             return '';
01688         }
01689 
01690         include_once('HTML/QuickForm/RuleRegistry.php');
01691         $registry =& HTML_QuickForm_RuleRegistry::singleton();
01692         $test = array();
01693         $js_escape = array(
01694             "\r"    => '\r',
01695             "\n"    => '\n',
01696             "\t"    => '\t',
01697             "'"     => "\\'",
01698             '"'     => '\"',
01699             '\\'    => '\\\\'
01700         );
01701 
01702         foreach ($this->_rules as $elementName => $rules) {
01703             foreach ($rules as $rule) {
01704                 if ('client' == $rule['validation']) {
01705                     unset($element);
01706 
01707                     $dependent  = isset($rule['dependent']) && is_array($rule['dependent']);
01708                     $rule['message'] = strtr($rule['message'], $js_escape);
01709 
01710                     if (isset($rule['group'])) {
01711                         $group    =& $this->getElement($rule['group']);
01712                         // No JavaScript validation for frozen elements
01713                         if ($group->isFrozen()) {
01714                             continue 2;
01715                         }
01716                         $elements =& $group->getElements();
01717                         foreach (array_keys($elements) as $key) {
01718                             if ($elementName == $group->getElementName($key)) {
01719                                 $element =& $elements[$key];
01720                                 break;
01721                             }
01722                         }
01723                     } elseif ($dependent) {
01724                         $element   =  array();
01725                         $element[] =& $this->getElement($elementName);
01726                         foreach ($rule['dependent'] as $elName) {
01727                             $element[] =& $this->getElement($elName);
01728                         }
01729                     } else {
01730                         $element =& $this->getElement($elementName);
01731                     }
01732                     // No JavaScript validation for frozen elements
01733                     if (is_object($element) && $element->isFrozen()) {
01734                         continue 2;
01735                     } elseif (is_array($element)) {
01736                         foreach (array_keys($element) as $key) {
01737                             if ($element[$key]->isFrozen()) {
01738                                 continue 3;
01739                             }
01740                         }
01741                     }
01742 
01743                     $test[] = $registry->getValidationScript($element, $elementName, $rule);
01744                 }
01745             }
01746         }
01747         if (count($test) > 0) {
01748             return
01749                 "\n<script type=\"text/javascript\">\n" .
01750                 "//<![CDATA[\n" .
01751                 "function validate_" . $this->_attributes['id'] . "(frm) {\n" .
01752                 "  var value = '';\n" .
01753                 "  var errFlag = new Array();\n" .
01754                 "  var _qfGroups = {};\n" .
01755                 "  _qfMsg = '';\n\n" .
01756                 join("\n", $test) .
01757                 "\n  if (_qfMsg != '') {\n" .
01758                 "    _qfMsg = '" . strtr($this->_jsPrefix, $js_escape) . "' + _qfMsg;\n" .
01759                 "    _qfMsg = _qfMsg + '\\n" . strtr($this->_jsPostfix, $js_escape) . "';\n" .
01760                 "    alert(_qfMsg);\n" .
01761                 "    return false;\n" .
01762                 "  }\n" .
01763                 "  return true;\n" .
01764                 "}\n" .
01765                 "//]]>\n" .
01766                 "</script>";
01767         }
01768         return '';
01769     } // end func getValidationScript
01770 
01771     // }}}
01772     // {{{ getSubmitValues()
01773 
01782     function getSubmitValues($mergeFiles = false)
01783     {
01784         return $mergeFiles? HTML_QuickForm::arrayMerge($this->_submitValues, $this->_submitFiles): $this->_submitValues;
01785     } // end func getSubmitValues
01786 
01787     // }}}
01788     // {{{ toArray()
01789 
01800     function toArray($collectHidden = false)
01801     {
01802         include_once 'HTML/QuickForm/Renderer/Array.php';
01803         $renderer = new HTML_QuickForm_Renderer_Array($collectHidden); //Moodle: PHP 5.3 compatibility
01804         $this->accept($renderer);
01805         return $renderer->toArray();
01806      } // end func toArray
01807 
01808     // }}}
01809     // {{{ exportValue()
01810 
01822     function exportValue($element)
01823     {
01824         if (!isset($this->_elementIndex[$element])) {
01825             return PEAR::raiseError(null, QUICKFORM_NONEXIST_ELEMENT, null, E_USER_WARNING, "Element '$element' does not exist in HTML_QuickForm::getElementValue()", 'HTML_QuickForm_Error', true);
01826         }
01827         $value = $this->_elements[$this->_elementIndex[$element]]->exportValue($this->_submitValues, false);
01828         if (isset($this->_duplicateIndex[$element])) {
01829             foreach ($this->_duplicateIndex[$element] as $index) {
01830                 if (null !== ($v = $this->_elements[$index]->exportValue($this->_submitValues, false))) {
01831                     if (is_array($value)) {
01832                         $value[] = $v;
01833                     } else {
01834                         $value = (null === $value)? $v: array($value, $v);
01835                     }
01836                 }
01837             }
01838         }
01839         return $value;
01840     }
01841 
01842     // }}}
01843     // {{{ exportValues()
01844 
01856     function exportValues($elementList = null)
01857     {
01858         $values = array();
01859         if (null === $elementList) {
01860             // iterate over all elements, calling their exportValue() methods
01861             foreach (array_keys($this->_elements) as $key) {
01862                 $value = $this->_elements[$key]->exportValue($this->_submitValues, true);
01863                 if (is_array($value)) {
01864                     // This shit throws a bogus warning in PHP 4.3.x
01865                     $values = HTML_QuickForm::arrayMerge($values, $value);
01866                 }
01867             }
01868         } else {
01869             if (!is_array($elementList)) {
01870                 $elementList = array_map('trim', explode(',', $elementList));
01871             }
01872             foreach ($elementList as $elementName) {
01873                 $value = $this->exportValue($elementName);
01874                 if (PEAR::isError($value)) {
01875                     return $value;
01876                 }
01877                 $values[$elementName] = $value;
01878             }
01879         }
01880         return $values;
01881     }
01882 
01883     // }}}
01884     // {{{ isSubmitted()
01885 
01895     function isSubmitted()
01896     {
01897         return $this->_flagSubmitted;
01898     }
01899 
01900 
01901     // }}}
01902     // {{{ isError()
01903 
01911     function isError($value)
01912     {
01913         return (is_object($value) && is_a($value, 'html_quickform_error'));
01914     } // end func isError
01915 
01916     // }}}
01917     // {{{ errorMessage()
01918 
01926     function errorMessage($value)
01927     {
01928         // make the variable static so that it only has to do the defining on the first call
01929         static $errorMessages;
01930 
01931         // define the varies error messages
01932         if (!isset($errorMessages)) {
01933             $errorMessages = array(
01934                 QUICKFORM_OK                    => 'no error',
01935                 QUICKFORM_ERROR                 => 'unknown error',
01936                 QUICKFORM_INVALID_RULE          => 'the rule does not exist as a registered rule',
01937                 QUICKFORM_NONEXIST_ELEMENT      => 'nonexistent html element',
01938                 QUICKFORM_INVALID_FILTER        => 'invalid filter',
01939                 QUICKFORM_UNREGISTERED_ELEMENT  => 'unregistered element',
01940                 QUICKFORM_INVALID_ELEMENT_NAME  => 'element already exists',
01941                 QUICKFORM_INVALID_PROCESS       => 'process callback does not exist',
01942                 QUICKFORM_DEPRECATED            => 'method is deprecated',
01943                 QUICKFORM_INVALID_DATASOURCE    => 'datasource is not an object'
01944             );
01945         }
01946 
01947         // If this is an error object, then grab the corresponding error code
01948         if (HTML_QuickForm::isError($value)) {
01949             $value = $value->getCode();
01950         }
01951 
01952         // return the textual error message corresponding to the code
01953         return isset($errorMessages[$value]) ? $errorMessages[$value] : $errorMessages[QUICKFORM_ERROR];
01954     } // end func errorMessage
01955 
01956     // }}}
01957 } // end class HTML_QuickForm
01958 
01959 class HTML_QuickForm_Error extends PEAR_Error {
01960 
01961     // {{{ properties
01962 
01967     var $error_message_prefix = 'QuickForm Error: ';
01968 
01969     // }}}
01970     // {{{ constructor
01971 
01980     function HTML_QuickForm_Error($code = QUICKFORM_ERROR, $mode = PEAR_ERROR_RETURN,
01981                          $level = E_USER_NOTICE, $debuginfo = null)
01982     {
01983         if (is_int($code)) {
01984             $this->PEAR_Error(HTML_QuickForm::errorMessage($code), $code, $mode, $level, $debuginfo);
01985         } else {
01986             $this->PEAR_Error("Invalid error code: $code", QUICKFORM_ERROR, $mode, $level, $debuginfo);
01987         }
01988     }
01989 
01990     // }}}
01991 } // end class HTML_QuickForm_Error
01992 ?>
 All Data Structures Namespaces Files Functions Variables Enumerations