This is NOT YET PART OF THE MOODLE API it is here for experimental purposes.
--- /dev/null
+<?php
+$string['denotesreq']='$a denotes required field.';
+$string['requiredelement']='Required field.';
+$string['nonexistentformelements']='Trying to add help buttons to nonexistent form elements : $a';
+?>
\ No newline at end of file
--- /dev/null
+<?php
+require_once('HTML/QuickForm/checkbox.php');
+
+/**
+ * HTML class for a checkbox type element
+ *
+ * @author Jamie Pratt
+ * @access public
+ */
+class moodleform_checkbox extends HTML_QuickForm_checkbox{
+ /**
+ * html for help button, if empty then no help
+ *
+ * @var string
+ */
+ var $_helpbutton='';
+ /**
+ * set html for help button
+ *
+ * @access public
+ * @param array $help array of arguments to make a help button
+ */
+ function setHelpButton($helpbuttonargs){
+ if (!is_array($helpbuttonargs)){
+ $helpbuttonargs=array($helpbuttonargs);
+ }else{
+ $helpbuttonargs=$helpbuttonargs;
+ }
+ //we do this to to return html instead of printing it
+ //without having to specify it in every call to make a button.
+ $defaultargs=array('', '', 'moodle', true, false, '', true);
+ $helpbuttonargs=$helpbuttonargs + $defaultargs ;
+ $this->_helpbutton=call_user_func_array('helpbutton', $helpbuttonargs);
+ }
+ /**
+ * get html for help button
+ *
+ * @access public
+ * @return string html for help button
+ */
+ function getHelpButton(){
+ return $this->_helpbutton;
+ }
+}
+?>
\ No newline at end of file
--- /dev/null
+<?php
+global $CFG;
+require_once "$CFG->libdir/form/group.php";
+require_once "$CFG->libdir/formslib.php";
+
+/**
+ * Class for a group of elements used to input a date.
+ *
+ * Emulates moodle print_date_selector function
+ *
+ * @author Jamie Pratt <me@jamiep.org>
+ * @access public
+ */
+class moodleform_date_selector extends moodleform_group
+{
+ /**
+ * Control the fieldnames for form elements
+ *
+ * day => string day fieldname
+ * month => string month fieldname
+ * year => string year fieldname
+ * timezone => float/string timezone
+ * applydst => apply users daylight savings adjustment?
+ */
+ var $_options = array('startyear'=>1970, 'stopyear'=>2020,
+ 'timezone'=>99, 'applydst'=>true);
+
+ /**
+ * These complement separators, they are appended to the resultant HTML
+ * @access private
+ * @var array
+ */
+ var $_wrap = array('', '');
+
+ /**
+ * Class constructor
+ *
+ * @access public
+ * @param string Element's name
+ * @param mixed Label(s) for an element
+ * @param array Options to control the element's display
+ * @param mixed Either a typical HTML attribute string or an associative array
+ */
+ function moodleform_date_selector($elementName = null, $elementLabel = null, $options = array(), $attributes = null)
+ {
+ $this->HTML_QuickForm_element($elementName, $elementLabel, $attributes);
+ $this->_persistantFreeze = true;
+ $this->_appendName = true;
+ $this->_type = 'date_selector';
+ // set the options, do not bother setting bogus ones
+ if (is_array($options)) {
+ foreach ($options as $name => $value) {
+ if (isset($this->_options[$name])) {
+ if (is_array($value) && is_array($this->_options[$name])) {
+ $this->_options[$name] = @array_merge($this->_options[$name], $value);
+ } else {
+ $this->_options[$name] = $value;
+ }
+ }
+ }
+ }
+ }
+
+ // }}}
+ // {{{ _createElements()
+
+ function _createElements()
+ {
+ $this->_elements = array();
+ for ($i=1; $i<=31; $i++) {
+ $days[$i] = $i;
+ }
+ for ($i=1; $i<=12; $i++) {
+ $months[$i] = userdate(gmmktime(12,0,0,$i,1,2000), "%B");
+ }
+ for ($i=$this->_options['startyear']; $i<=$this->_options['stopyear']; $i++) {
+ $years[$i] = $i;
+ }
+ $this->_elements[] =& moodleform::createElement('select', 'day', null, $days, $this->getAttributes(), true);
+ $this->_elements[] =& moodleform::createElement('select','month', null, $months, $this->getAttributes(), true);
+ $this->_elements[] =& moodleform::createElement('select','year', null, $years, $this->getAttributes(), true);
+
+ }
+
+ // }}}
+ // {{{ setValue()
+
+ function setValue($value)
+ {
+ if (!($value)) {
+ $value = time();
+ }
+ if (!is_array($value)) {
+ $currentdate = usergetdate($value);
+ $value = array(
+ 'day' => $currentdate['mday'],
+ 'month' => $currentdate['mon'],
+ 'year' => $currentdate['year']);
+
+ }
+ parent::setValue($value);
+ }
+
+ // }}}
+ // {{{ toHtml()
+
+ function toHtml()
+ {
+ include_once('HTML/QuickForm/Renderer/Default.php');
+ $renderer =& new HTML_QuickForm_Renderer_Default();
+ $renderer->setElementTemplate('{element}');
+ parent::accept($renderer);
+ return $this->_wrap[0] . $renderer->toHtml() . $this->_wrap[1];
+ }
+
+ // }}}
+ // {{{ accept()
+
+ function accept(&$renderer, $required = false, $error = null)
+ {
+ $renderer->renderElement($this, $required, $error);
+ }
+
+ // }}}
+ // {{{ onQuickFormEvent()
+
+ function onQuickFormEvent($event, $arg, &$caller)
+ {
+ if ('updateValue' == $event) {
+ return HTML_QuickForm_element::onQuickFormEvent($event, $arg, $caller);
+ } else {
+ return parent::onQuickFormEvent($event, $arg, $caller);
+ }
+ }
+ /**
+ * Output a timestamp. Give it the name of the group.
+ *
+ * @param array $submitValues
+ * @param bool $assoc
+ * @return array
+ */
+ function exportValue(&$submitValues, $assoc = false)
+ {
+ $value = null;
+ $valuearray = $this->_elements[0]->exportValue($submitValues[$this->getName()], true);
+ $valuearray +=$this->_elements[1]->exportValue($submitValues[$this->getName()], true);
+ $valuearray +=$this->_elements[2]->exportValue($submitValues[$this->getName()], true);
+ $value[$this->getName()]=make_timestamp($valuearray['year'],
+ $valuearray['month'],
+ $valuearray['day'],
+ 0,0,0,
+ $this->_options['timezone'],
+ $this->_options['applydst']);
+ return $value;
+ }
+
+ // }}}
+}
+?>
\ No newline at end of file
--- /dev/null
+<?php
+require_once('HTML/QuickForm/file.php');
+
+/**
+ * HTML class for a form element to upload a file
+ *
+ * @author Jamie Pratt
+ * @access public
+ */
+class moodleform_file extends HTML_QuickForm_file{
+ /**
+ * html for help button, if empty then no help
+ *
+ * @var string
+ */
+ var $_helpbutton='';
+ /**
+ * set html for help button
+ *
+ * @access public
+ * @param array $help array of arguments to make a help button
+ */
+ function setHelpButton($helpbuttonargs){
+ if (!is_array($helpbuttonargs)){
+ $helpbuttonargs=array($helpbuttonargs);
+ }else{
+ $helpbuttonargs=$helpbuttonargs;
+ }
+ //we do this to to return html instead of printing it
+ //without having to specify it in every call to make a button.
+ $defaultargs=array('', '', 'moodle', true, false, '', true);
+ $helpbuttonargs=$helpbuttonargs + $defaultargs ;
+ $this->_helpbutton=call_user_func_array('helpbutton', $helpbuttonargs);
+ }
+ /**
+ * get html for help button
+ *
+ * @access public
+ * @return string html for help button
+ */
+ function getHelpButton(){
+ return $this->_helpbutton;
+ }
+}
+?>
\ No newline at end of file
--- /dev/null
+<?php
+require_once("HTML/QuickForm/group.php");
+
+/**
+ * HTML class for a form element group
+ *
+ * @author Adam Daniel <adaniel1@eesus.jnj.com>
+ * @author Bertrand Mansion <bmansion@mamasam.com>
+ * @version 1.0
+ * @since PHP4.04pl1
+ * @access public
+ */
+class moodleform_group extends HTML_QuickForm_group{
+ /**
+ * html for help button, if empty then no help
+ *
+ * @var string
+ */
+ var $_helpbutton='';
+ /**
+ * set html for help button
+ *
+ * @access public
+ * @param array $help array of arguments to make a help button
+ */
+ function setHelpButton($helpbuttonargs){
+ if (!is_array($helpbuttonargs)){
+ $helpbuttonargs=array($helpbuttonargs);
+ }else{
+ $helpbuttonargs=$helpbuttonargs;
+ }
+ //we do this to to return html instead of printing it
+ //without having to specify it in every call to make a button.
+ $defaultargs=array('', '', 'moodle', true, false, '', true);
+ $helpbuttonargs=$helpbuttonargs + $defaultargs ;
+ $this->_helpbutton=call_user_func_array('helpbutton', $helpbuttonargs);
+ }
+ /**
+ * get html for help button
+ *
+ * @access public
+ * @return string html for help button
+ */
+ function getHelpButton(){
+ return $this->_helpbutton;
+ }
+}
\ No newline at end of file
--- /dev/null
+<?php
+global $CFG;
+require_once("$CFG->libdir/form/textarea.php");
+
+/**
+ * HTML class for htmleditor type element
+ *
+ * @author Jamie Pratt
+ * @access public
+ */
+class moodleform_htmleditor extends moodleform_textarea{
+ var $_type = 'htmleditor';
+ var $_elementTemplateType='default';
+ var $_canUseHtmlEditor;
+ var $_options=array('course'=>0);
+ function moodleform_htmleditor($elementName=null, $elementLabel=null, $attributes=null){
+ $this->_canUseHtmlEditor=can_use_html_editor();
+ if ($this->_canUseHtmlEditor){
+ $this->_elementTemplateType='wide';
+ }else{
+ $this->_elementTemplateType='default';
+ }
+ parent::moodleform_textarea($elementName, $elementLabel, $attributes);
+ }
+ function getElementTemplateType(){
+ return $this->_elementTemplateType;
+ }
+ function toHtml(){
+ ob_start();
+ use_html_editor($this->getName());
+ $script=ob_get_clean();
+ if ($this->_flagFrozen) {
+ return $this->getFrozenHtml();
+ } else {
+ return $this->_getTabs() .
+ print_textarea($this->_canUseHtmlEditor,
+ $this->getAttribute('rows'),
+ $this->getAttribute('cols'),
+ $this->getAttribute('width'),
+ $this->getAttribute('height'),
+ $this->getName(),
+ preg_replace("/(\r\n|\n|\r)/", '
',$this->getValue()),
+ $this->_options['course'],
+ true).$script;
+ }
+ } //end func toHtml
+
+}
+?>
\ No newline at end of file
--- /dev/null
+<?php
+require_once('HTML/QuickForm/password.php');
+
+/**
+ * HTML class for a password type element
+ *
+ * @author Jamie Pratt
+ * @access public
+ */
+class moodleform_password extends HTML_QuickForm_password{
+ /**
+ * html for help button, if empty then no help
+ *
+ * @var string
+ */
+ var $_helpbutton='';
+ /**
+ * set html for help button
+ *
+ * @access public
+ * @param array $help array of arguments to make a help button
+ */
+ function setHelpButton($helpbuttonargs){
+ if (!is_array($helpbuttonargs)){
+ $helpbuttonargs=array($helpbuttonargs);
+ }else{
+ $helpbuttonargs=$helpbuttonargs;
+ }
+ //we do this to to return html instead of printing it
+ //without having to specify it in every call to make a button.
+ $defaultargs=array('', '', 'moodle', true, false, '', true);
+ $helpbuttonargs=$helpbuttonargs + $defaultargs ;
+ $this->_helpbutton=call_user_func_array('helpbutton', $helpbuttonargs);
+ }
+ /**
+ * get html for help button
+ *
+ * @access public
+ * @return string html for help button
+ */
+ function getHelpButton(){
+ return $this->_helpbutton;
+ }
+}
+?>
\ No newline at end of file
--- /dev/null
+<?php
+require_once('HTML/QuickForm/radio.php');
+
+/**
+ * HTML class for a radio type element
+ *
+ * @author Jamie Pratt
+ * @access public
+ */
+class moodleform_radio extends HTML_QuickForm_radio{
+ /**
+ * html for help button, if empty then no help
+ *
+ * @var string
+ */
+ var $_helpbutton='';
+ /**
+ * set html for help button
+ *
+ * @access public
+ * @param array $help array of arguments to make a help button
+ */
+ function setHelpButton($helpbuttonargs){
+ if (!is_array($helpbuttonargs)){
+ $helpbuttonargs=array($helpbuttonargs);
+ }else{
+ $helpbuttonargs=$helpbuttonargs;
+ }
+ //we do this to to return html instead of printing it
+ //without having to specify it in every call to make a button.
+ $defaultargs=array('', '', 'moodle', true, false, '', true);
+ $helpbuttonargs=$helpbuttonargs + $defaultargs ;
+ $this->_helpbutton=call_user_func_array('helpbutton', $helpbuttonargs);
+ }
+ /**
+ * get html for help button
+ *
+ * @access public
+ * @return string html for help button
+ */
+ function getHelpButton(){
+ return $this->_helpbutton;
+ }
+}
+?>
\ No newline at end of file
--- /dev/null
+<?php
+require_once('HTML/QuickForm/select.php');
+
+/**
+ * HTML class for a select type element
+ *
+ * @author Jamie Pratt
+ * @access public
+ */
+class moodleform_select extends HTML_QuickForm_select{
+ /**
+ * html for help button, if empty then no help
+ *
+ * @var string
+ */
+ var $_helpbutton='';
+ /**
+ * set html for help button
+ *
+ * @access public
+ * @param array $help array of arguments to make a help button
+ */
+ function setHelpButton($helpbuttonargs){
+ if (!is_array($helpbuttonargs)){
+ $helpbuttonargs=array($helpbuttonargs);
+ }else{
+ $helpbuttonargs=$helpbuttonargs;
+ }
+ //we do this to to return html instead of printing it
+ //without having to specify it in every call to make a button.
+ $defaultargs=array('', '', 'moodle', true, false, '', true);
+ $helpbuttonargs=$helpbuttonargs + $defaultargs ;
+ $this->_helpbutton=call_user_func_array('helpbutton', $helpbuttonargs);
+ }
+ /**
+ * get html for help button
+ *
+ * @access public
+ * @return string html for help button
+ */
+ function getHelpButton(){
+ return $this->_helpbutton;
+ }
+}
+?>
\ No newline at end of file
--- /dev/null
+<?php
+require_once("HTML/QuickForm/text.php");
+
+/**
+ * HTML class for a text type element
+ *
+ * @author Jamie Pratt
+ * @access public
+ */
+class moodleform_text extends HTML_QuickForm_text{
+ /**
+ * html for help button, if empty then no help
+ *
+ * @var string
+ */
+ var $_helpbutton='';
+ /**
+ * set html for help button
+ *
+ * @access public
+ * @param array $help array of arguments to make a help button
+ */
+ function setHelpButton($helpbuttonargs){
+ if (!is_array($helpbuttonargs)){
+ $helpbuttonargs=array($helpbuttonargs);
+ }else{
+ $helpbuttonargs=$helpbuttonargs;
+ }
+ //we do this to to return html instead of printing it
+ //without having to specify it in every call to make a button.
+ $defaultargs=array('', '', 'moodle', true, false, '', true);
+ $helpbuttonargs=$helpbuttonargs + $defaultargs ;
+ $this->_helpbutton=call_user_func_array('helpbutton', $helpbuttonargs);
+ }
+ /**
+ * get html for help button
+ *
+ * @access public
+ * @return string html for help button
+ */
+ function getHelpButton(){
+ return $this->_helpbutton;
+ }
+}
\ No newline at end of file
--- /dev/null
+<?php
+require_once('HTML/QuickForm/textarea.php');
+
+/**
+ * HTML class for a textarea type element
+ *
+ * @author Jamie Pratt
+ * @access public
+ */
+class moodleform_textarea extends HTML_QuickForm_textarea{
+ /**
+ * html for help button, if empty then no help
+ *
+ * @var string
+ */
+ var $_helpbutton='';
+ /**
+ * set html for help button
+ *
+ * @access public
+ * @param array $help array of arguments to make a help button
+ */
+ function setHelpButton($helpbuttonargs){
+ if (!is_array($helpbuttonargs)){
+ $helpbuttonargs=array($helpbuttonargs);
+ }else{
+ $helpbuttonargs=$helpbuttonargs;
+ }
+ //we do this to to return html instead of printing it
+ //without having to specify it in every call to make a button.
+ $defaultargs=array('', '', 'moodle', true, false, '', true);
+ $helpbuttonargs=$helpbuttonargs + $defaultargs ;
+ $this->_helpbutton=call_user_func_array('helpbutton', $helpbuttonargs);
+ }
+ /**
+ * get html for help button
+ *
+ * @access public
+ * @return string html for help button
+ */
+ function getHelpButton(){
+ return $this->_helpbutton;
+ }
+}
+?>
\ No newline at end of file
--- /dev/null
+<?php
+/**
+ * formslib.php - library of classes for creating forms in Moodle, based on PEAR QuickForms.
+ * THIS IS NOT YET PART OF THE MOODLE API, IT IS HERE FOR TESTING ONLY
+ * @author Jamie Pratt
+ * @version $Id$
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ */
+
+//point pear include path to moodles lib/pear so that includes and requires will search there for files before anywhere else.
+if (FALSE===strstr(ini_get('include_path'), $CFG->libdir.'/pear' )){
+ ini_set('include_path', $CFG->libdir.'/pear' . PATH_SEPARATOR . ini_get('include_path'));
+}
+require_once 'HTML/QuickForm.php';
+require_once 'HTML/QuickForm/DHTMLRulesTableless.php';
+require_once 'HTML/QuickForm/Renderer/Tableless.php';
+
+class moodleform extends HTML_QuickForm_DHTMLRulesTableless{
+ /**
+ * Class constructor - same parameters as HTML_QuickForm_DHTMLRulesTableless
+ * @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 none
+ * @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
+ */
+ function moodleform($formName='', $method='post', $action='', $target='', $attributes=null){
+ global $CFG;
+ //we need to override the constructor, we don't call the parent constructor
+ //at all because it strips slashes depending on the magic quotes setting
+ //whereas Moodle already has added slashes whether magic quotes is on or not.
+
+ //also added check for sesskey and added sesskey to all forms
+ //and told class to ask Moodle for the max upload file size
+ HTML_Common::HTML_Common($attributes);
+ $method = (strtoupper($method) == 'GET') ? 'get' : 'post';
+ $action = ($action == '') ? $_SERVER['PHP_SELF'] : $action;
+ $target = empty($target) ? array() : array('target' => $target);
+ //no 'name' atttribute for form in xhtml strict :
+ $attributes = array('action'=>$action, 'method'=>$method, 'id'=>$formName) + $target;
+ $this->updateAttributes($attributes);
+ //check for sesskey for this form
+ //if it is not present then we don't accept any input
+ if (isset($_REQUEST['_qf__' . $formName])) {
+ $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;
+ }
+ }
+ }
+
+ $this->_flagSubmitted = count($this->_submitValues) > 0 || count($this->_submitFiles) > 0;
+ }
+
+ //check sesskey
+ if ($this->_flagSubmitted){
+ confirm_sesskey($this->_submitValues['_qf__' . $formName]);
+ }
+ unset($this->_submitValues['_qf__' . $formName]);
+ //add sesskey to all forms
+ $this->addElement('hidden', '_qf__' . $formName, sesskey());
+
+ if (preg_match('/^([0-9]+)([a-zA-Z]*)$/', get_max_upload_file_size(), $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'];
+ }
+ }
+ //this is custom stuff for Moodle :
+ $oldclass= $this->getAttribute('class');
+ if (!empty($oldclass)){
+ $this->updateAttributes(array('class'=>$oldclass.' mform'));
+ }else {
+ $this->updateAttributes(array('class'=>'mform'));
+ }
+ $this->_helpImageURL="$CFG->wwwroot/lib/form/req.gif";
+ $this->_reqHTML =
+ helpbutton('requiredelement', get_string('requiredelement', 'form'),'moodle',
+ true, false, '', true, '<img alt="'.get_string('requiredelement', 'form').'" src="'.
+ $this->_helpImageURL.'" />');
+ $this->setRequiredNote(get_string('denotesreq', 'form', $this->getReqHTML()));
+ }
+ function getReqHTML(){
+ return $this->_reqHTML;
+ }
+ /**
+ * Class constructor - same parameters as HTML_QuickForm_DHTMLRulesTableless
+ * @param array $buttons An associative array representing help button to attach to
+ * to the form. keys of array correspond to names of elements in form.
+ *
+ * @access public
+ */
+ function add_help_buttons($buttons, $suppresscheck=false){
+
+ foreach ($this->_elements as $no => $element){
+ if (array_key_exists($element->getName(), $buttons)){
+
+ //dynamically create a property so we don't have to modify element
+ //class :
+ $this->_elements[$no]->setHelpButton($buttons[$element->getName()]);
+ unset($buttons[$element->getName()]);
+ }
+
+ }
+ if (count($buttons)&& !$suppresscheck){
+ print_error('nonexistentformelements', 'form', '', join(', ', array_keys($buttons)));
+ }
+ }
+ /**
+ * Applies a data filter for the given field(s)
+ * We can use any PARAM_
+ *
+ * @param mixed $element Form element name or array of such names
+ * @param mixed $filter Callback, either function name or array(&$object, 'method') or PARAM_ integer
+ * @since 2.0
+ * @access public
+ */
+ function applyFilter($element, $filter){
+ if (is_numeric($filter)){
+ $filter=create_function('$value', "clean_param(\$value, $filter);");
+ }
+ parent::applyFilter($element, $filter);
+ }
+ function exportValue($element, $addslashes=true){
+ $unfiltered=parent::exportValue($element);
+ if ($addslashes){
+ return HTML_QuickForm::_recursiveFilter('addslashes',$unfiltered);
+ } else {
+ return $unfiltered;
+ }
+ }
+ function exportValues($elementList, $addslashes=true){
+ $unfiltered=parent::exportValues($elementList);
+ if ($addslashes){
+ return HTML_QuickForm::_recursiveFilter('addslashes',$unfiltered);
+ } else {
+ return $unfiltered;
+ }
+ }
+}
+
+/**
+ * A renderer for moodleform that only uses XHTML and CSS and no
+ * table tags, extends PEAR class HTML_QuickForm_Renderer_Tableless
+ *
+ * Stylesheet is part of standard theme and should be automatically included.
+ *
+ * @author Jamie Pratt <me@jamiep.org>
+ * @license gpl license
+ */
+class moodleform_renderer extends HTML_QuickForm_Renderer_Tableless{
+
+ /**
+ * Element template array
+ * @var array
+ * @access private
+ */
+ var $_elementTemplates;
+ var $_htmleditors=array();
+ function moodleform_renderer(){
+ $this->_elementTemplates=array('default'=>"\n\t\t<div class=\"qfrow\"><label class=\"qflabel\">{label}{help}<!-- BEGIN required -->{req}<!-- END required --></label><div class=\"qfelement<!-- BEGIN error --> error<!-- END error -->\"><!-- BEGIN error --><span class=\"error\">{error}</span><br /><!-- END error -->{element}</div></div><br />",
+ 'wide'=>"\n\t\t<div class=\"qfrow\"><label class=\"qflabel\">{label}{help}<!-- BEGIN required -->{req}<!-- END required --></label><br /><div class=\"qfelementwide<!-- BEGIN error --> error<!-- END error -->\"><!-- BEGIN error --><span class=\"error\">{error}</span><br /><!-- END error -->{element}</span></div><br />");
+
+ parent::HTML_QuickForm_Renderer_Tableless();
+ }
+ function startForm(&$form){
+ $this->_reqHTML=$form->getReqHTML();
+ $this->_elementTemplates=str_replace('{req}', $this->_reqHTML, $this->_elementTemplates);
+ parent::startForm($form);
+ }
+ function startGroup(&$group, $required, $error){
+ if (method_exists($group, 'getElementTemplateType')){
+ $html = $this->_elementTemplates[$element->getElementTemplateType()];
+ }else{
+ $html = $this->_elementTemplates['default'];
+
+ }
+ if (method_exists($group, 'getHelpButton')){
+ $html =str_replace('{help}', $group->getHelpButton(), $html);
+ }else{
+ $html =str_replace('{help}', '', $html);
+
+ }
+ $this->_templates[$group->getName()]=$html;
+ // Fix for bug in tableless quickforms that didn't allow you to stop a
+ // fieldset before a group of elements.
+ // if the element name indicates the end of a fieldset, close the fieldset
+ if ( in_array($group->getName(), $this->_stopFieldsetElements)
+ && $this->_fieldsetsOpen > 0
+ ) {
+ $this->_html .= $this->_closeFieldsetTemplate;
+ $this->_fieldsetsOpen--;
+ }
+ parent::startGroup($group, $required, $error);
+ }
+ function renderElement(&$element, $required, $error){
+ if (method_exists($element, 'getElementTemplateType')){
+ $html = $this->_elementTemplates[$element->getElementTemplateType()];
+ }else{
+ $html = $this->_elementTemplates['default'];
+
+ }
+ if (method_exists($element, 'getHelpButton')){
+ $html=str_replace('{help}', $element->getHelpButton(), $html);
+ }else{
+ $html=str_replace('{help}', '', $html);
+
+ }
+ $this->_templates[$element->getName()]=$html;
+
+ parent::renderElement($element, $required, $error);
+ }
+
+
+}
+
+class moodleform_filter{
+ var $paramtype;
+ var $default;
+ function moodleform_filter($paramtype, $default){
+ $this->paramtype=$paramtype;
+ $this->default=$default;
+ }
+ function required_param($value){
+ if (isset($value)) {
+ $param = $value;
+ } else {
+ error('A required parameter was missing');
+ }
+
+ return $this->clean_param($param);
+ }
+ function optional_param($value){
+ if (!isset($value)) {
+ return $this->default;
+ }
+ return $this->clean_param($value);
+ }
+ function clean_param($value){
+ //clean param expects vars with slashes
+ $value=HTML_QuickForm::_recursiveFilter('addslashes', $value);
+ $value=clean_param($value, $this->paramtype);
+ return HTML_QuickForm::_recursiveFilter('stripslashes', $value);
+ }
+}
+
+$GLOBALS['_HTML_QuickForm_default_renderer']=& new moodleform_renderer();
+
+moodleform::registerElementType('checkbox', "$CFG->libdir/form/checkbox.php", 'moodleform_checkbox');
+moodleform::registerElementType('file', "$CFG->libdir/form/file.php", 'moodleform_file');
+moodleform::registerElementType('group', "$CFG->libdir/form/group.php", 'moodleform_group');
+moodleform::registerElementType('password', "$CFG->libdir/form/password.php", 'moodleform_password');
+moodleform::registerElementType('radio', "$CFG->libdir/form/radio.php", 'moodleform_radio');
+moodleform::registerElementType('select', "$CFG->libdir/form/select.php", 'moodleform_select');
+moodleform::registerElementType('text', "$CFG->libdir/form/text.php", 'moodleform_text');
+moodleform::registerElementType('textarea', "$CFG->libdir/form/textarea.php", 'moodleform_textarea');
+moodleform::registerElementType('date_selector', "$CFG->libdir/form/dateselector.php", 'moodleform_date_selector');
+moodleform::registerElementType('htmleditor', "$CFG->libdir/form/htmleditor.php", 'moodleform_htmleditor');
+
+if ($CFG->debug >= DEBUG_ALL){
+ PEAR::setErrorHandling(PEAR_ERROR_PRINT);
+}
+?>
\ No newline at end of file
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP Version 4 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Author: Adam Daniel <adaniel1@eesus.jnj.com> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+/**
+ * Base class for all HTML classes
+ *
+ * @author Adam Daniel <adaniel1@eesus.jnj.com>
+ * @category HTML
+ * @package HTML_Common
+ * @version 1.2.2
+ * @abstract
+ */
+
+/**
+ * Base class for all HTML classes
+ *
+ * @author Adam Daniel <adaniel1@eesus.jnj.com>
+ * @version 1.7
+ * @since PHP 4.0.3pl1
+ * @abstract
+ */
+class HTML_Common {
+
+ /**
+ * Associative array of table attributes
+ * @var array
+ * @access private
+ */
+ var $_attributes = array();
+
+ /**
+ * Tab offset of the table
+ * @var int
+ * @access private
+ */
+ var $_tabOffset = 0;
+
+ /**
+ * Tab string
+ * @var string
+ * @since 1.7
+ * @access private
+ */
+ var $_tab = "\11";
+
+ /**
+ * Contains the line end string
+ * @var string
+ * @since 1.7
+ * @access private
+ */
+ var $_lineEnd = "\12";
+
+ /**
+ * HTML comment on the object
+ * @var string
+ * @since 1.5
+ * @access private
+ */
+ var $_comment = '';
+
+ /**
+ * Class constructor
+ * @param mixed $attributes Associative array of table tag attributes
+ * or HTML attributes name="value" pairs
+ * @param int $tabOffset Indent offset in tabs
+ * @access public
+ */
+ function HTML_Common($attributes = null, $tabOffset = 0)
+ {
+ $this->setAttributes($attributes);
+ $this->setTabOffset($tabOffset);
+ } // end constructor
+
+ /**
+ * Returns the current API version
+ * @access public
+ * @returns double
+ */
+ function apiVersion()
+ {
+ return 1.7;
+ } // end func apiVersion
+
+ /**
+ * Returns the lineEnd
+ *
+ * @since 1.7
+ * @access private
+ * @return string
+ * @throws
+ */
+ function _getLineEnd()
+ {
+ return $this->_lineEnd;
+ } // end func getLineEnd
+
+ /**
+ * Returns a string containing the unit for indenting HTML
+ *
+ * @since 1.7
+ * @access private
+ * @return string
+ */
+ function _getTab()
+ {
+ return $this->_tab;
+ } // end func _getTab
+
+ /**
+ * Returns a string containing the offset for the whole HTML code
+ *
+ * @return string
+ * @access private
+ */
+ function _getTabs()
+ {
+ return str_repeat($this->_getTab(), $this->_tabOffset);
+ } // end func _getTabs
+
+ /**
+ * Returns an HTML formatted attribute string
+ * @param array $attributes
+ * @return string
+ * @access private
+ */
+ function _getAttrString($attributes)
+ {
+ $strAttr = '';
+
+ if (is_array($attributes)) {
+ foreach ($attributes as $key => $value) {
+ $strAttr .= ' ' . $key . '="' . htmlspecialchars($value) . '"';
+ }
+ }
+ return $strAttr;
+ } // end func _getAttrString
+
+ /**
+ * Returns a valid atrributes array from either a string or array
+ * @param mixed $attributes Either a typical HTML attribute string or an associative array
+ * @access private
+ */
+ function _parseAttributes($attributes)
+ {
+ if (is_array($attributes)) {
+ $ret = array();
+ foreach ($attributes as $key => $value) {
+ if (is_int($key)) {
+ $key = $value = strtolower($value);
+ } else {
+ $key = strtolower($key);
+ }
+ $ret[$key] = $value;
+ }
+ return $ret;
+
+ } elseif (is_string($attributes)) {
+ $preg = "/(([A-Za-z_:]|[^\\x00-\\x7F])([A-Za-z0-9_:.-]|[^\\x00-\\x7F])*)" .
+ "([ \\n\\t\\r]+)?(=([ \\n\\t\\r]+)?(\"[^\"]*\"|'[^']*'|[^ \\n\\t\\r]*))?/";
+ if (preg_match_all($preg, $attributes, $regs)) {
+ for ($counter=0; $counter<count($regs[1]); $counter++) {
+ $name = $regs[1][$counter];
+ $check = $regs[0][$counter];
+ $value = $regs[7][$counter];
+ if (trim($name) == trim($check)) {
+ $arrAttr[strtolower(trim($name))] = strtolower(trim($name));
+ } else {
+ if (substr($value, 0, 1) == "\"" || substr($value, 0, 1) == "'") {
+ $value = substr($value, 1, -1);
+ }
+ $arrAttr[strtolower(trim($name))] = trim($value);
+ }
+ }
+ return $arrAttr;
+ }
+ }
+ } // end func _parseAttributes
+
+ /**
+ * Returns the array key for the given non-name-value pair attribute
+ *
+ * @param string $attr Attribute
+ * @param array $attributes Array of attribute
+ * @since 1.0
+ * @access private
+ * @return bool
+ * @throws
+ */
+ function _getAttrKey($attr, $attributes)
+ {
+ if (isset($attributes[strtolower($attr)])) {
+ return true;
+ } else {
+ return null;
+ }
+ } //end func _getAttrKey
+
+ /**
+ * Updates the attributes in $attr1 with the values in $attr2 without changing the other existing attributes
+ * @param array $attr1 Original attributes array
+ * @param array $attr2 New attributes array
+ * @access private
+ */
+ function _updateAttrArray(&$attr1, $attr2)
+ {
+ if (!is_array($attr2)) {
+ return false;
+ }
+ foreach ($attr2 as $key => $value) {
+ $attr1[$key] = $value;
+ }
+ } // end func _updateAtrrArray
+
+ /**
+ * Removes the given attribute from the given array
+ *
+ * @param string $attr Attribute name
+ * @param array $attributes Attribute array
+ * @since 1.4
+ * @access private
+ * @return void
+ * @throws
+ */
+ function _removeAttr($attr, &$attributes)
+ {
+ $attr = strtolower($attr);
+ if (isset($attributes[$attr])) {
+ unset($attributes[$attr]);
+ }
+ } //end func _removeAttr
+
+ /**
+ * Returns the value of the given attribute
+ *
+ * @param string $attr Attribute name
+ * @since 1.5
+ * @access public
+ * @return void
+ * @throws
+ */
+ function getAttribute($attr)
+ {
+ $attr = strtolower($attr);
+ if (isset($this->_attributes[$attr])) {
+ return $this->_attributes[$attr];
+ }
+ return null;
+ } //end func getAttribute
+
+ /**
+ * Sets the HTML attributes
+ * @param mixed $attributes Either a typical HTML attribute string or an associative array
+ * @access public
+ */
+ function setAttributes($attributes)
+ {
+ $this->_attributes = $this->_parseAttributes($attributes);
+ } // end func setAttributes
+
+ /**
+ * Returns the assoc array (default) or string of attributes
+ *
+ * @param bool Whether to return the attributes as string
+ * @since 1.6
+ * @access public
+ * @return mixed attributes
+ */
+ function getAttributes($asString = false)
+ {
+ if ($asString) {
+ return $this->_getAttrString($this->_attributes);
+ } else {
+ return $this->_attributes;
+ }
+ } //end func getAttributes
+
+ /**
+ * Updates the passed attributes without changing the other existing attributes
+ * @param mixed $attributes Either a typical HTML attribute string or an associative array
+ * @access public
+ */
+ function updateAttributes($attributes)
+ {
+ $this->_updateAttrArray($this->_attributes, $this->_parseAttributes($attributes));
+ } // end func updateAttributes
+
+ /**
+ * Removes an attribute
+ *
+ * @param string $attr Attribute name
+ * @since 1.4
+ * @access public
+ * @return void
+ * @throws
+ */
+ function removeAttribute($attr)
+ {
+ $this->_removeAttr($attr, $this->_attributes);
+ } //end func removeAttribute
+
+ /**
+ * Sets the line end style to Windows, Mac, Unix or a custom string.
+ *
+ * @param string $style "win", "mac", "unix" or custom string.
+ * @since 1.7
+ * @access public
+ * @return void
+ */
+ function setLineEnd($style)
+ {
+ switch ($style) {
+ case 'win':
+ $this->_lineEnd = "\15\12";
+ break;
+ case 'unix':
+ $this->_lineEnd = "\12";
+ break;
+ case 'mac':
+ $this->_lineEnd = "\15";
+ break;
+ default:
+ $this->_lineEnd = $style;
+ }
+ } // end func setLineEnd
+
+ /**
+ * Sets the tab offset
+ *
+ * @param int $offset
+ * @access public
+ */
+ function setTabOffset($offset)
+ {
+ $this->_tabOffset = $offset;
+ } // end func setTabOffset
+
+ /**
+ * Returns the tabOffset
+ *
+ * @since 1.5
+ * @access public
+ * @return int
+ */
+ function getTabOffset()
+ {
+ return $this->_tabOffset;
+ } //end func getTabOffset
+
+ /**
+ * Sets the string used to indent HTML
+ *
+ * @since 1.7
+ * @param string $string String used to indent ("\11", "\t", ' ', etc.).
+ * @access public
+ * @return void
+ */
+ function setTab($string)
+ {
+ $this->_tab = $string;
+ } // end func setTab
+
+ /**
+ * Sets the HTML comment to be displayed at the beginning of the HTML string
+ *
+ * @param string
+ * @since 1.4
+ * @access public
+ * @return void
+ */
+ function setComment($comment)
+ {
+ $this->_comment = $comment;
+ } // end func setHtmlComment
+
+ /**
+ * Returns the HTML comment
+ *
+ * @since 1.5
+ * @access public
+ * @return string
+ */
+ function getComment()
+ {
+ return $this->_comment;
+ } //end func getComment
+
+ /**
+ * Abstract method. Must be extended to return the objects HTML
+ *
+ * @access public
+ * @return string
+ * @abstract
+ */
+ function toHtml()
+ {
+ return '';
+ } // end func toHtml
+
+ /**
+ * Displays the HTML to the screen
+ *
+ * @access public
+ */
+ function display()
+ {
+ print $this->toHtml();
+ } // end func display
+
+} // end class HTML_Common
+?>
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP version 4.0 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2003 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> |
+// | Bertrand Mansion <bmansion@mamasam.com> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+require_once('PEAR.php');
+require_once('HTML/Common.php');
+
+$GLOBALS['HTML_QUICKFORM_ELEMENT_TYPES'] =
+ array(
+ 'group' =>array('HTML/QuickForm/group.php','HTML_QuickForm_group'),
+ 'hidden' =>array('HTML/QuickForm/hidden.php','HTML_QuickForm_hidden'),
+ 'reset' =>array('HTML/QuickForm/reset.php','HTML_QuickForm_reset'),
+ 'checkbox' =>array('HTML/QuickForm/checkbox.php','HTML_QuickForm_checkbox'),
+ 'file' =>array('HTML/QuickForm/file.php','HTML_QuickForm_file'),
+ 'image' =>array('HTML/QuickForm/image.php','HTML_QuickForm_image'),
+ 'password' =>array('HTML/QuickForm/password.php','HTML_QuickForm_password'),
+ 'radio' =>array('HTML/QuickForm/radio.php','HTML_QuickForm_radio'),
+ 'button' =>array('HTML/QuickForm/button.php','HTML_QuickForm_button'),
+ 'submit' =>array('HTML/QuickForm/submit.php','HTML_QuickForm_submit'),
+ 'select' =>array('HTML/QuickForm/select.php','HTML_QuickForm_select'),
+ 'hiddenselect' =>array('HTML/QuickForm/hiddenselect.php','HTML_QuickForm_hiddenselect'),
+ 'text' =>array('HTML/QuickForm/text.php','HTML_QuickForm_text'),
+ 'textarea' =>array('HTML/QuickForm/textarea.php','HTML_QuickForm_textarea'),
+ 'link' =>array('HTML/QuickForm/link.php','HTML_QuickForm_link'),
+ 'advcheckbox' =>array('HTML/QuickForm/advcheckbox.php','HTML_QuickForm_advcheckbox'),
+ 'date' =>array('HTML/QuickForm/date.php','HTML_QuickForm_date'),
+ 'static' =>array('HTML/QuickForm/static.php','HTML_QuickForm_static'),
+ 'header' =>array('HTML/QuickForm/header.php', 'HTML_QuickForm_header'),
+ 'html' =>array('HTML/QuickForm/html.php', 'HTML_QuickForm_html'),
+ 'hierselect' =>array('HTML/QuickForm/hierselect.php', 'HTML_QuickForm_hierselect'),
+ 'autocomplete' =>array('HTML/QuickForm/autocomplete.php', 'HTML_QuickForm_autocomplete'),
+ 'xbutton' =>array('HTML/QuickForm/xbutton.php','HTML_QuickForm_xbutton')
+ );
+
+$GLOBALS['_HTML_QuickForm_registered_rules'] = array(
+ 'required' => array('html_quickform_rule_required', 'HTML/QuickForm/Rule/Required.php'),
+ 'maxlength' => array('html_quickform_rule_range', 'HTML/QuickForm/Rule/Range.php'),
+ 'minlength' => array('html_quickform_rule_range', 'HTML/QuickForm/Rule/Range.php'),
+ 'rangelength' => array('html_quickform_rule_range', 'HTML/QuickForm/Rule/Range.php'),
+ 'email' => array('html_quickform_rule_email', 'HTML/QuickForm/Rule/Email.php'),
+ 'regex' => array('html_quickform_rule_regex', 'HTML/QuickForm/Rule/Regex.php'),
+ 'lettersonly' => array('html_quickform_rule_regex', 'HTML/QuickForm/Rule/Regex.php'),
+ 'alphanumeric' => array('html_quickform_rule_regex', 'HTML/QuickForm/Rule/Regex.php'),
+ 'numeric' => array('html_quickform_rule_regex', 'HTML/QuickForm/Rule/Regex.php'),
+ 'nopunctuation' => array('html_quickform_rule_regex', 'HTML/QuickForm/Rule/Regex.php'),
+ 'nonzero' => array('html_quickform_rule_regex', 'HTML/QuickForm/Rule/Regex.php'),
+ 'callback' => array('html_quickform_rule_callback', 'HTML/QuickForm/Rule/Callback.php'),
+ 'compare' => array('html_quickform_rule_compare', 'HTML/QuickForm/Rule/Compare.php')
+);
+
+// {{{ error codes
+
+/*
+ * Error codes for the QuickForm interface, which will be mapped to textual messages
+ * in the QuickForm::errorMessage() function. If you are to add a new error code, be
+ * sure to add the textual messages to the QuickForm::errorMessage() function as well
+ */
+
+define('QUICKFORM_OK', 1);
+define('QUICKFORM_ERROR', -1);
+define('QUICKFORM_INVALID_RULE', -2);
+define('QUICKFORM_NONEXIST_ELEMENT', -3);
+define('QUICKFORM_INVALID_FILTER', -4);
+define('QUICKFORM_UNREGISTERED_ELEMENT', -5);
+define('QUICKFORM_INVALID_ELEMENT_NAME', -6);
+define('QUICKFORM_INVALID_PROCESS', -7);
+define('QUICKFORM_DEPRECATED', -8);
+define('QUICKFORM_INVALID_DATASOURCE', -9);
+
+// }}}
+
+/**
+* Create, validate and process HTML forms
+*
+* @author Adam Daniel <adaniel1@eesus.jnj.com>
+* @author Bertrand Mansion <bmansion@mamasam.com>
+* @version 2.0
+* @since PHP 4.0.3pl1
+*/
+class HTML_QuickForm extends HTML_Common {
+ // {{{ properties
+
+ /**
+ * Array containing the form fields
+ * @since 1.0
+ * @var array
+ * @access private
+ */
+ var $_elements = array();
+
+ /**
+ * Array containing element name to index map
+ * @since 1.1
+ * @var array
+ * @access private
+ */
+ var $_elementIndex = array();
+
+ /**
+ * Array containing indexes of duplicate elements
+ * @since 2.10
+ * @var array
+ * @access private
+ */
+ var $_duplicateIndex = array();
+
+ /**
+ * Array containing required field IDs
+ * @since 1.0
+ * @var array
+ * @access private
+ */
+ var $_required = array();
+
+ /**
+ * Prefix message in javascript alert if error
+ * @since 1.0
+ * @var string
+ * @access public
+ */
+ var $_jsPrefix = 'Invalid information entered.';
+
+ /**
+ * Postfix message in javascript alert if error
+ * @since 1.0
+ * @var string
+ * @access public
+ */
+ var $_jsPostfix = 'Please correct these fields.';
+
+ /**
+ * Datasource object implementing the informal
+ * datasource protocol
+ * @since 3.3
+ * @var object
+ * @access private
+ */
+ var $_datasource;
+
+ /**
+ * Array of default form values
+ * @since 2.0
+ * @var array
+ * @access private
+ */
+ var $_defaultValues = array();
+
+ /**
+ * Array of constant form values
+ * @since 2.0
+ * @var array
+ * @access private
+ */
+ var $_constantValues = array();
+
+ /**
+ * Array of submitted form values
+ * @since 1.0
+ * @var array
+ * @access private
+ */
+ var $_submitValues = array();
+
+ /**
+ * Array of submitted form files
+ * @since 1.0
+ * @var integer
+ * @access public
+ */
+ var $_submitFiles = array();
+
+ /**
+ * Value for maxfilesize hidden element if form contains file input
+ * @since 1.0
+ * @var integer
+ * @access public
+ */
+ var $_maxFileSize = 1048576; // 1 Mb = 1048576
+
+ /**
+ * Flag to know if all fields are frozen
+ * @since 1.0
+ * @var boolean
+ * @access private
+ */
+ var $_freezeAll = false;
+
+ /**
+ * Array containing the form rules
+ * @since 1.0
+ * @var array
+ * @access private
+ */
+ var $_rules = array();
+
+ /**
+ * Form rules, global variety
+ * @var array
+ * @access private
+ */
+ var $_formRules = array();
+
+ /**
+ * Array containing the validation errors
+ * @since 1.0
+ * @var array
+ * @access private
+ */
+ var $_errors = array();
+
+ /**
+ * Note for required fields in the form
+ * @var string
+ * @since 1.0
+ * @access private
+ */
+ var $_requiredNote = '<span style="font-size:80%; color:#ff0000;">*</span><span style="font-size:80%;"> denotes required field</span>';
+
+ /**
+ * Whether the form was submitted
+ * @var boolean
+ * @access private
+ */
+ var $_flagSubmitted = false;
+
+ // }}}
+ // {{{ constructor
+
+ /**
+ * Class constructor
+ * @param string $formName Form's name.
+ * @param string $method (optional)Form's method defaults to 'POST'
+ * @param string $action (optional)Form's action
+ * @param string $target (optional)Form's target defaults to '_self'
+ * @param mixed $attributes (optional)Extra attributes for <form> tag
+ * @param bool $trackSubmit (optional)Whether to track if the form was submitted by adding a special hidden field
+ * @access public
+ */
+ function HTML_QuickForm($formName='', $method='post', $action='', $target='', $attributes=null, $trackSubmit = false)
+ {
+ HTML_Common::HTML_Common($attributes);
+ $method = (strtoupper($method) == 'GET') ? 'get' : 'post';
+ $action = ($action == '') ? $_SERVER['PHP_SELF'] : $action;
+ $target = empty($target) ? array() : array('target' => $target);
+ $attributes = array('action'=>$action, 'method'=>$method, 'name'=>$formName, 'id'=>$formName) + $target;
+ $this->updateAttributes($attributes);
+ if (!$trackSubmit || isset($_REQUEST['_qf__' . $formName])) {
+ 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'];
+ }
+ }
+ } // 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
+ */
+ 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
+ */
+ 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
+ */
+ 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 object extended class of HTML_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 object a new 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);
+ $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 object reference to element
+ * @access public
+ * @throws HTML_QuickForm_Error
+ */
+ function &addElement($element)
+ {
+ if (is_object($element) && is_subclass_of($element, 'html_quickform_element')) {
+ $elementObject = &$element;
+ $elementObject->onQuickFormEvent('updateValue', null, $this);
+ } else {
+ $args = func_get_args();
+ $elementObject =& $this->_loadElement('addElement', $element, array_slice($args, 1));
+ 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 object HTML_QuickForm_element Element to insert
+ * @param string Name of the element before which the new one is inserted
+ * @return object HTML_QuickForm_element reference to inserted element
+ * @throws HTML_QuickForm_Error
+ */
+ function &insertElementBefore(&$element, $nameAfter)
+ {
+ if (!empty($this->_duplicateIndex[$nameAfter])) {
+ $error = 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 object reference to added group of elements
+ * @since 2.8
+ * @access public
+ * @throws PEAR_Error
+ */
+ function &addGroup($elements, $name=null, $groupLabel='', $separator=null, $appendName = true)
+ {
+ 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 object 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 = 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 object HTML_QuickForm_element a reference to the removed element
+ * @throws HTML_QuickForm_Error
+ */
+ function &removeElement($elementName, $removeRules = true)
+ {
+ if (!isset($this->_elementIndex[$elementName])) {
+ $error = 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) {
+ unset($this->_rules[$elementName], $this->_errors[$elementName]);
+ }
+ return $el;
+ } // end func removeElement
+
+ // }}}
+ // {{{ addRule()
+
+ /**
+ * Adds a validation rule for the given field
+ *
+ * If the element is in fact a group, it will be considered as a whole.
+ * To validate grouped elements as separated entities,
+ * use addGroupRule instead of addRule.
+ *
+ * @param string $element Form element name
+ * @param string $message Message to display for invalid data
+ * @param string $type Rule type, use getRegisteredRules() to get types
+ * @param string $format (optional)Required for extra rule data
+ * @param string $validation (optional)Where to perform validation: "server", "client"
+ * @param boolean $reset Client-side validation: reset the form element to its original value if there is an error?
+ * @param boolean $force Force the rule to be applied, even if the target form element does not exist
+ * @since 1.0
+ * @access public
+ * @throws HTML_QuickForm_Error
+ */
+ function addRule($element, $message, $type, $format=null, $validation='server', $reset = false, $force = false)
+ {
+ if (!$force) {
+ if (!is_array($element) && !$this->elementExists($element)) {
+ return 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
+ */
+ 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 puplic
+ * @param array $a original array
+ * @param array $b array which will be merged into first one
+ * @return array merged array
+ */
+ 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
+ */
+ 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
+ */
+ 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.
+ } elseif (is_array($submitValue)) {
+ if (false === ($pos = strpos($target, '['))) {
+ $isUpload = !empty($this->_submitFiles[$target]);
+ } else {
+ $base = substr($target, 0, $pos);
+ $idx = "['" . str_replace(array(']', '['), array('', "']['"), substr($target, $pos + 1, -1)) . "']";
+ eval("\$isUpload = isset(\$this->_submitFiles['{$base}']['name']{$idx});");
+ }
+ if ($isUpload && (!isset($submitValue['error']) || 0 != $submitValue['error'])) {
+ continue 2;
+ }
+ }
+ }
+ if (isset($rule['dependent']) && is_array($rule['dependent'])) {
+ $values = array($submitValue);
+ foreach ($rule['dependent'] as $elName) {
+ $values[] = $this->getSubmitValue($elName);
+ }
+ $result = $registry->validate($rule['type'], $values, $rule['format'], true);
+ } elseif (is_array($submitValue) && !isset($rule['howmany'])) {
+ $result = $registry->validate($rule['type'], $submitValue, $rule['format'], true);
+ } else {
+ $result = $registry->validate($rule['type'], $submitValue, $rule['format'], false);
+ }
+
+ if (!$result || (!empty($rule['howmany']) && $rule['howmany'] > (int)$result)) {
+ if (isset($rule['group'])) {
+ $this->_errors[$rule['group']] = $rule['message'];
+ } else {
+ $this->_errors[$target] = $rule['message'];
+ }
+ }
+ }
+ }
+
+ // process the global rules 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
+ */
+ 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');
+ $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';
+ $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
+ */
+ 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
+ */
+ 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
+ */
+ 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 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
+?>
\ No newline at end of file
--- /dev/null
+<?php
+/**
+ * DHTML replacement for the standard JavaScript alert window for client-side
+ * validation
+ *
+ * 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_DHTMLRulesTableless
+ * @author Alexey Borzov <borz_off@cs.msu.su>
+ * @author Adam Daniel <adaniel1@eesus.jnj.com>
+ * @author Bertrand Mansion <bmansion@mamasam.com>
+ * @author Justin Patrin <papercrane@gmail.com>
+ * @author Mark Wiesemann <wiesemann@php.net>
+ * @copyright 2005-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version CVS: $Id$
+ * @link http://pear.php.net/package/HTML_QuickForm_DHTMLRulesTableless
+ */
+
+require_once 'HTML/QuickForm.php';
+
+/**
+ * This is a DHTML replacement for the standard JavaScript alert window for
+ * client-side validation of forms built with HTML_QuickForm
+ *
+ * @category HTML
+ * @package HTML_QuickForm_DHTMLRulesTableless
+ * @author Alexey Borzov <borz_off@cs.msu.su>
+ * @author Adam Daniel <adaniel1@eesus.jnj.com>
+ * @author Bertrand Mansion <bmansion@mamasam.com>
+ * @author Justin Patrin <papercrane@gmail.com>
+ * @author Mark Wiesemann <wiesemann@php.net>
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version Release: 0.1.2
+ * @link http://pear.php.net/package/HTML_QuickForm_DHTMLRulesTableless
+ */
+class HTML_QuickForm_DHTMLRulesTableless extends HTML_QuickForm {
+ // {{{ getValidationScript()
+
+ /**
+ * Returns the client side validation script
+ *
+ * The code here was copied from HTML_QuickForm and slightly modified to run rules per-element
+ *
+ * @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 $idx => $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[$elementName][] = $registry->getValidationScript($element, $elementName, $rule);
+ }
+ }
+ }
+ $js = '
+<script type="text/javascript">
+//<![CDATA[
+function qf_errorHandler(element, _qfMsg) {
+ div = element.parentNode;
+ if (_qfMsg != \'\') {
+ span = document.createElement("span");
+ span.className = "error";
+ span.appendChild(document.createTextNode(_qfMsg.substring(3)));
+ br = document.createElement("br");
+
+ var errorDiv = document.getElementById(element.name + \'_errorDiv\');
+ if (!errorDiv) {
+ errorDiv = document.createElement("div");
+ errorDiv.id = element.name + \'_errorDiv\';
+ }
+ while (errorDiv.firstChild) {
+ errorDiv.removeChild(errorDiv.firstChild);
+ }
+
+ errorDiv.insertBefore(br, errorDiv.firstChild);
+ errorDiv.insertBefore(span, errorDiv.firstChild);
+ element.parentNode.insertBefore(errorDiv, element.parentNode.firstChild);
+
+ if (div.className.substr(div.className.length - 6, 6) != " error"
+ && div.className != "error") {
+ div.className += " error";
+ }
+
+ return false;
+ } else {
+ var errorDiv = document.getElementById(element.name + \'_errorDiv\');
+ if (errorDiv) {
+ errorDiv.parentNode.removeChild(errorDiv);
+ }
+
+ if (div.className.substr(div.className.length - 6, 6) == " error") {
+ div.className = div.className.substr(0, div.className.length - 6);
+ } else if (div.className == "error") {
+ div.className = "";
+ }
+
+ return true;
+ }
+}';
+ $validateJS = '';
+ foreach ($test as $elementName => $jsArr) {
+ $js .= '
+function validate_' . $this->_attributes['id'] . '_' . $elementName . '(element) {
+ var value = \'\';
+ var errFlag = new Array();
+ var _qfGroups = {};
+ var _qfMsg = \'\';
+ var frm = element.parentNode;
+ while (frm && frm.nodeName != "FORM") {
+ frm = frm.parentNode;
+ }
+' . join("\n", $jsArr) . '
+ return qf_errorHandler(element, _qfMsg);
+}
+';
+ $validateJS .= '
+ ret = validate_' . $this->_attributes['id'] . '_' . $elementName.'(frm.elements[\''.$elementName.'\']) && ret;';
+ unset($element);
+ $element =& $this->getElement($elementName);
+ $valFunc = 'validate_' . $this->_attributes['id'] . '_' . $elementName . '(this)';
+ $onBlur = $element->getAttribute('onBlur');
+ $onChange = $element->getAttribute('onChange');
+ $element->updateAttributes(array('onBlur' => $onBlur . $valFunc,
+ 'onChange' => $onChange . $valFunc));
+ }
+ $js .= '
+function validate_' . $this->_attributes['id'] . '(frm) {
+ var ret = true;
+' . $validateJS . ';
+ return ret;
+}
+//]]>
+</script>';
+ return $js;
+ } // end func getValidationScript
+
+ // }}}
+
+ function display() {
+ $this->getValidationScript();
+ return parent::display();
+ }
+}
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP version 4.0 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2003 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Author: Alexey Borzov <borz_off@cs.msu.su> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+/**
+ * An abstract base class for QuickForm renderers
+ *
+ * The class implements a Visitor design pattern
+ *
+ * @abstract
+ * @author Alexey Borzov <borz_off@cs.msu.su>
+ */
+class HTML_QuickForm_Renderer
+{
+ /**
+ * Constructor
+ *
+ * @access public
+ */
+ function HTML_QuickForm_Renderer()
+ {
+ } // end constructor
+
+ /**
+ * Called when visiting a form, before processing any form elements
+ *
+ * @param object An HTML_QuickForm object being visited
+ * @access public
+ * @return void
+ * @abstract
+ */
+ function startForm(&$form)
+ {
+ return;
+ } // end func startForm
+
+ /**
+ * Called when visiting a form, after processing all form elements
+ *
+ * @param object An HTML_QuickForm object being visited
+ * @access public
+ * @return void
+ * @abstract
+ */
+ function finishForm(&$form)
+ {
+ return;
+ } // end func finishForm
+
+ /**
+ * Called when visiting a header element
+ *
+ * @param object An HTML_QuickForm_header element being visited
+ * @access public
+ * @return void
+ * @abstract
+ */
+ function renderHeader(&$header)
+ {
+ return;
+ } // end func renderHeader
+
+ /**
+ * Called when visiting an element
+ *
+ * @param object An HTML_QuickForm_element object being visited
+ * @param bool Whether an element is required
+ * @param string An error message associated with an element
+ * @access public
+ * @return void
+ * @abstract
+ */
+ function renderElement(&$element, $required, $error)
+ {
+ return;
+ } // end func renderElement
+
+ /**
+ * Called when visiting a hidden element
+ *
+ * @param object An HTML_QuickForm_hidden object being visited
+ * @access public
+ * @return void
+ * @abstract
+ */
+ function renderHidden(&$element)
+ {
+ return;
+ } // end func renderHidden
+
+ /**
+ * Called when visiting a raw HTML/text pseudo-element
+ *
+ * Seems that this should not be used when using a template-based renderer
+ *
+ * @param object An HTML_QuickForm_html element being visited
+ * @access public
+ * @return void
+ * @abstract
+ */
+ function renderHtml(&$data)
+ {
+ return;
+ } // end func renderHtml
+
+ /**
+ * Called when visiting a group, before processing any group elements
+ *
+ * @param object An HTML_QuickForm_group object being visited
+ * @param bool Whether a group is required
+ * @param string An error message associated with a group
+ * @access public
+ * @return void
+ * @abstract
+ */
+ function startGroup(&$group, $required, $error)
+ {
+ return;
+ } // end func startGroup
+
+ /**
+ * Called when visiting a group, after processing all group elements
+ *
+ * @param object An HTML_QuickForm_group object being visited
+ * @access public
+ * @return void
+ * @abstract
+ */
+ function finishGroup(&$group)
+ {
+ return;
+ } // end func finishGroup
+} // end class HTML_QuickForm_Renderer
+?>
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP version 4.0 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2003 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Alexey Borzov <borz_off@cs.msu.su> |
+// | Adam Daniel <adaniel1@eesus.jnj.com> |
+// | Bertrand Mansion <bmansion@mamasam.com> |
+// | Thomas Schulz <ths@4bconsult.de> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+require_once 'HTML/QuickForm/Renderer.php';
+
+/**
+ * A concrete renderer for HTML_QuickForm, makes an array of form contents
+ *
+ * Based on old toArray() code.
+ *
+ * The form array structure is the following:
+ * array(
+ * 'frozen' => 'whether the form is frozen',
+ * 'javascript' => 'javascript for client-side validation',
+ * 'attributes' => 'attributes for <form> tag',
+ * 'requirednote => 'note about the required elements',
+ * // if we set the option to collect hidden elements
+ * 'hidden' => 'collected html of all hidden elements',
+ * // if there were some validation errors:
+ * 'errors' => array(
+ * '1st element name' => 'Error for the 1st element',
+ * ...
+ * 'nth element name' => 'Error for the nth element'
+ * ),
+ * // if there are no headers in the form:
+ * 'elements' => array(
+ * element_1,
+ * ...
+ * element_N
+ * )
+ * // if there are headers in the form:
+ * 'sections' => array(
+ * array(
+ * 'header' => 'Header text for the first header',
+ * 'name' => 'Header name for the first header',
+ * 'elements' => array(
+ * element_1,
+ * ...
+ * element_K1
+ * )
+ * ),
+ * ...
+ * array(
+ * 'header' => 'Header text for the Mth header',
+ * 'name' => 'Header name for the Mth header',
+ * 'elements' => array(
+ * element_1,
+ * ...
+ * element_KM
+ * )
+ * )
+ * )
+ * );
+ *
+ * where element_i is an array of the form:
+ * array(
+ * 'name' => 'element name',
+ * 'value' => 'element value',
+ * 'type' => 'type of the element',
+ * 'frozen' => 'whether element is frozen',
+ * 'label' => 'label for the element',
+ * 'required' => 'whether element is required',
+ * 'error' => 'error associated with the element',
+ * 'style' => 'some information about element style (e.g. for Smarty)',
+ * // if element is not a group
+ * 'html' => 'HTML for the element'
+ * // if element is a group
+ * 'separator' => 'separator for group elements',
+ * 'elements' => array(
+ * element_1,
+ * ...
+ * element_N
+ * )
+ * );
+ *
+ * @access public
+ */
+class HTML_QuickForm_Renderer_Array extends HTML_QuickForm_Renderer
+{
+ /**
+ * An array being generated
+ * @var array
+ */
+ var $_ary;
+
+ /**
+ * Number of sections in the form (i.e. number of headers in it)
+ * @var integer
+ */
+ var $_sectionCount;
+
+ /**
+ * Current section number
+ * @var integer
+ */
+ var $_currentSection;
+
+ /**
+ * Array representing current group
+ * @var array
+ */
+ var $_currentGroup = null;
+
+ /**
+ * Additional style information for different elements
+ * @var array
+ */
+ var $_elementStyles = array();
+
+ /**
+ * true: collect all hidden elements into string; false: process them as usual form elements
+ * @var bool
+ */
+ var $_collectHidden = false;
+
+ /**
+ * true: render an array of labels to many labels, $key 0 named 'label', the rest "label_$key"
+ * false: leave labels as defined
+ * @var bool
+ */
+ var $staticLabels = false;
+
+ /**
+ * Constructor
+ *
+ * @param bool true: collect all hidden elements into string; false: process them as usual form elements
+ * @param bool true: render an array of labels to many labels, $key 0 to 'label' and the oterh to "label_$key"
+ * @access public
+ */
+ function HTML_QuickForm_Renderer_Array($collectHidden = false, $staticLabels = false)
+ {
+ $this->HTML_QuickForm_Renderer();
+ $this->_collectHidden = $collectHidden;
+ $this->_staticLabels = $staticLabels;
+ } // end constructor
+
+
+ /**
+ * Returns the resultant array
+ *
+ * @access public
+ * @return array
+ */
+ function toArray()
+ {
+ return $this->_ary;
+ }
+
+
+ function startForm(&$form)
+ {
+ $this->_ary = array(
+ 'frozen' => $form->isFrozen(),
+ 'javascript' => $form->getValidationScript(),
+ 'attributes' => $form->getAttributes(true),
+ 'requirednote' => $form->getRequiredNote(),
+ 'errors' => array()
+ );
+ if ($this->_collectHidden) {
+ $this->_ary['hidden'] = '';
+ }
+ $this->_elementIdx = 1;
+ $this->_currentSection = null;
+ $this->_sectionCount = 0;
+ } // end func startForm
+
+
+ function renderHeader(&$header)
+ {
+ $this->_ary['sections'][$this->_sectionCount] = array(
+ 'header' => $header->toHtml(),
+ 'name' => $header->getName()
+ );
+ $this->_currentSection = $this->_sectionCount++;
+ } // end func renderHeader
+
+
+ function renderElement(&$element, $required, $error)
+ {
+ $elAry = $this->_elementToArray($element, $required, $error);
+ if (!empty($error)) {
+ $this->_ary['errors'][$elAry['name']] = $error;
+ }
+ $this->_storeArray($elAry);
+ } // end func renderElement
+
+
+ function renderHidden(&$element)
+ {
+ if ($this->_collectHidden) {
+ $this->_ary['hidden'] .= $element->toHtml() . "\n";
+ } else {
+ $this->renderElement($element, false, null);
+ }
+ } // end func renderHidden
+
+
+ function startGroup(&$group, $required, $error)
+ {
+ $this->_currentGroup = $this->_elementToArray($group, $required, $error);
+ if (!empty($error)) {
+ $this->_ary['errors'][$this->_currentGroup['name']] = $error;
+ }
+ } // end func startGroup
+
+
+ function finishGroup(&$group)
+ {
+ $this->_storeArray($this->_currentGroup);
+ $this->_currentGroup = null;
+ } // end func finishGroup
+
+
+ /**
+ * Creates an array representing an element
+ *
+ * @access private
+ * @param object An HTML_QuickForm_element object
+ * @param bool Whether an element is required
+ * @param string Error associated with the element
+ * @return array
+ */
+ function _elementToArray(&$element, $required, $error)
+ {
+ $ret = array(
+ 'name' => $element->getName(),
+ 'value' => $element->getValue(),
+ 'type' => $element->getType(),
+ 'frozen' => $element->isFrozen(),
+ 'required' => $required,
+ 'error' => $error
+ );
+ // render label(s)
+ $labels = $element->getLabel();
+ if (is_array($labels) && $this->_staticLabels) {
+ foreach($labels as $key => $label) {
+ $key = is_int($key)? $key + 1: $key;
+ if (1 === $key) {
+ $ret['label'] = $label;
+ } else {
+ $ret['label_' . $key] = $label;
+ }
+ }
+ } else {
+ $ret['label'] = $labels;
+ }
+
+ // set the style for the element
+ if (isset($this->_elementStyles[$ret['name']])) {
+ $ret['style'] = $this->_elementStyles[$ret['name']];
+ }
+ if ('group' == $ret['type']) {
+ $ret['separator'] = $element->_separator;
+ $ret['elements'] = array();
+ } else {
+ $ret['html'] = $element->toHtml();
+ }
+ return $ret;
+ }
+
+
+ /**
+ * Stores an array representation of an element in the form array
+ *
+ * @access private
+ * @param array Array representation of an element
+ * @return void
+ */
+ function _storeArray($elAry)
+ {
+ // where should we put this element...
+ if (is_array($this->_currentGroup) && ('group' != $elAry['type'])) {
+ $this->_currentGroup['elements'][] = $elAry;
+ } elseif (isset($this->_currentSection)) {
+ $this->_ary['sections'][$this->_currentSection]['elements'][] = $elAry;
+ } else {
+ $this->_ary['elements'][] = $elAry;
+ }
+ }
+
+
+ /**
+ * Sets a style to use for element rendering
+ *
+ * @param mixed element name or array ('element name' => 'style name')
+ * @param string style name if $elementName is not an array
+ * @access public
+ * @return void
+ */
+ function setElementStyle($elementName, $styleName = null)
+ {
+ if (is_array($elementName)) {
+ $this->_elementStyles = array_merge($this->_elementStyles, $elementName);
+ } else {
+ $this->_elementStyles[$elementName] = $styleName;
+ }
+ }
+}
+?>
\ No newline at end of file
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP version 4.0 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2003 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Alexey Borzov <borz_off@cs.msu.su> |
+// | Adam Daniel <adaniel1@eesus.jnj.com> |
+// | Bertrand Mansion <bmansion@mamasam.com> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+require_once('HTML/QuickForm/Renderer.php');
+
+/**
+ * A concrete renderer for HTML_QuickForm,
+ * based on QuickForm 2.x built-in one
+ *
+ * @access public
+ */
+class HTML_QuickForm_Renderer_Default extends HTML_QuickForm_Renderer
+{
+ /**
+ * The HTML of the form
+ * @var string
+ * @access private
+ */
+ var $_html;
+
+ /**
+ * Header Template string
+ * @var string
+ * @access private
+ */
+ var $_headerTemplate =
+ "\n\t<tr>\n\t\t<td style=\"white-space: nowrap; background-color: #CCCCCC;\" align=\"left\" valign=\"top\" colspan=\"2\"><b>{header}</b></td>\n\t</tr>";
+
+ /**
+ * Element template string
+ * @var string
+ * @access private
+ */
+ var $_elementTemplate =
+ "\n\t<tr>\n\t\t<td align=\"right\" valign=\"top\"><!-- BEGIN required --><span style=\"color: #ff0000\">*</span><!-- END required --><b>{label}</b></td>\n\t\t<td valign=\"top\" align=\"left\"><!-- BEGIN error --><span style=\"color: #ff0000\">{error}</span><br /><!-- END error -->\t{element}</td>\n\t</tr>";
+
+ /**
+ * Form template string
+ * @var string
+ * @access private
+ */
+ var $_formTemplate =
+ "\n<form{attributes}>\n<div>\n{hidden}<table border=\"0\">\n{content}\n</table>\n</div>\n</form>";
+
+ /**
+ * Required Note template string
+ * @var string
+ * @access private
+ */
+ var $_requiredNoteTemplate =
+ "\n\t<tr>\n\t\t<td></td>\n\t<td align=\"left\" valign=\"top\">{requiredNote}</td>\n\t</tr>";
+
+ /**
+ * Array containing the templates for customised elements
+ * @var array
+ * @access private
+ */
+ var $_templates = array();
+
+ /**
+ * Array containing the templates for group wraps.
+ *
+ * These templates are wrapped around group elements and groups' own
+ * templates wrap around them. This is set by setGroupTemplate().
+ *
+ * @var array
+ * @access private
+ */
+ var $_groupWraps = array();
+
+ /**
+ * Array containing the templates for elements within groups
+ * @var array
+ * @access private
+ */
+ var $_groupTemplates = array();
+
+ /**
+ * True if we are inside a group
+ * @var bool
+ * @access private
+ */
+ var $_inGroup = false;
+
+ /**
+ * Array with HTML generated for group elements
+ * @var array
+ * @access private
+ */
+ var $_groupElements = array();
+
+ /**
+ * Template for an element inside a group
+ * @var string
+ * @access private
+ */
+ var $_groupElementTemplate = '';
+
+ /**
+ * HTML that wraps around the group elements
+ * @var string
+ * @access private
+ */
+ var $_groupWrap = '';
+
+ /**
+ * HTML for the current group
+ * @var string
+ * @access private
+ */
+ var $_groupTemplate = '';
+
+ /**
+ * Collected HTML of the hidden fields
+ * @var string
+ * @access private
+ */
+ var $_hiddenHtml = '';
+
+ /**
+ * Constructor
+ *
+ * @access public
+ */
+ function HTML_QuickForm_Renderer_Default()
+ {
+ $this->HTML_QuickForm_Renderer();
+ } // end constructor
+
+ /**
+ * returns the HTML generated for the form
+ *
+ * @access public
+ * @return string
+ */
+ function toHtml()
+ {
+ // _hiddenHtml is cleared in finishForm(), so this only matters when
+ // finishForm() was not called (e.g. group::toHtml(), bug #3511)
+ return $this->_hiddenHtml . $this->_html;
+ } // end func toHtml
+
+ /**
+ * Called when visiting a form, before processing any form elements
+ *
+ * @param object An HTML_QuickForm object being visited
+ * @access public
+ * @return void
+ */
+ function startForm(&$form)
+ {
+ $this->_html = '';
+ $this->_hiddenHtml = '';
+ } // end func startForm
+
+ /**
+ * Called when visiting a form, after processing all form elements
+ * Adds required note, form attributes, validation javascript and form content.
+ *
+ * @param object An HTML_QuickForm object being visited
+ * @access public
+ * @return void
+ */
+ function finishForm(&$form)
+ {
+ // add a required note, if one is needed
+ if (!empty($form->_required) && !$form->_freezeAll) {
+ $this->_html .= str_replace('{requiredNote}', $form->getRequiredNote(), $this->_requiredNoteTemplate);
+ }
+ // add form attributes and content
+ $html = str_replace('{attributes}', $form->getAttributes(true), $this->_formTemplate);
+ if (strpos($this->_formTemplate, '{hidden}')) {
+ $html = str_replace('{hidden}', $this->_hiddenHtml, $html);
+ } else {
+ $this->_html .= $this->_hiddenHtml;
+ }
+ $this->_hiddenHtml = '';
+ $this->_html = str_replace('{content}', $this->_html, $html);
+ // add a validation script
+ if ('' != ($script = $form->getValidationScript())) {
+ $this->_html = $script . "\n" . $this->_html;
+ }
+ } // end func finishForm
+
+ /**
+ * Called when visiting a header element
+ *
+ * @param object An HTML_QuickForm_header element being visited
+ * @access public
+ * @return void
+ */
+ function renderHeader(&$header)
+ {
+ $name = $header->getName();
+ if (!empty($name) && isset($this->_templates[$name])) {
+ $this->_html .= str_replace('{header}', $header->toHtml(), $this->_templates[$name]);
+ } else {
+ $this->_html .= str_replace('{header}', $header->toHtml(), $this->_headerTemplate);
+ }
+ } // end func renderHeader
+
+ /**
+ * Helper method for renderElement
+ *
+ * @param string Element name
+ * @param mixed Element label (if using an array of labels, you should set the appropriate template)
+ * @param bool Whether an element is required
+ * @param string Error message associated with the element
+ * @access private
+ * @see renderElement()
+ * @return string Html for element
+ */
+ function _prepareTemplate($name, $label, $required, $error)
+ {
+ if (is_array($label)) {
+ $nameLabel = array_shift($label);
+ } else {
+ $nameLabel = $label;
+ }
+ if (isset($this->_templates[$name])) {
+ $html = str_replace('{label}', $nameLabel, $this->_templates[$name]);
+ } else {
+ $html = str_replace('{label}', $nameLabel, $this->_elementTemplate);
+ }
+ if ($required) {
+ $html = str_replace('<!-- BEGIN required -->', '', $html);
+ $html = str_replace('<!-- END required -->', '', $html);
+ } else {
+ $html = preg_replace("/([ \t\n\r]*)?<!-- BEGIN required -->(\s|\S)*<!-- END required -->([ \t\n\r]*)?/iU", '', $html);
+ }
+ if (isset($error)) {
+ $html = str_replace('{error}', $error, $html);
+ $html = str_replace('<!-- BEGIN error -->', '', $html);
+ $html = str_replace('<!-- END error -->', '', $html);
+ } else {
+ $html = preg_replace("/([ \t\n\r]*)?<!-- BEGIN error -->(\s|\S)*<!-- END error -->([ \t\n\r]*)?/iU", '', $html);
+ }
+ if (is_array($label)) {
+ foreach($label as $key => $text) {
+ $key = is_int($key)? $key + 2: $key;
+ $html = str_replace("{label_{$key}}", $text, $html);
+ $html = str_replace("<!-- BEGIN label_{$key} -->", '', $html);
+ $html = str_replace("<!-- END label_{$key} -->", '', $html);
+ }
+ }
+ if (strpos($html, '{label_')) {
+ $html = preg_replace('/\s*<!-- BEGIN label_(\S+) -->.*<!-- END label_\1 -->\s*/i', '', $html);
+ }
+ return $html;
+ } // end func _prepareTemplate
+
+ /**
+ * Renders an element Html
+ * Called when visiting an element
+ *
+ * @param object An HTML_QuickForm_element object being visited
+ * @param bool Whether an element is required
+ * @param string An error message associated with an element
+ * @access public
+ * @return void
+ */
+ function renderElement(&$element, $required, $error)
+ {
+ if (!$this->_inGroup) {
+ $html = $this->_prepareTemplate($element->getName(), $element->getLabel(), $required, $error);
+ $this->_html .= str_replace('{element}', $element->toHtml(), $html);
+
+ } elseif (!empty($this->_groupElementTemplate)) {
+ $html = str_replace('{label}', $element->getLabel(), $this->_groupElementTemplate);
+ if ($required) {
+ $html = str_replace('<!-- BEGIN required -->', '', $html);
+ $html = str_replace('<!-- END required -->', '', $html);
+ } else {
+ $html = preg_replace("/([ \t\n\r]*)?<!-- BEGIN required -->(\s|\S)*<!-- END required -->([ \t\n\r]*)?/iU", '', $html);
+ }
+ $this->_groupElements[] = str_replace('{element}', $element->toHtml(), $html);
+
+ } else {
+ $this->_groupElements[] = $element->toHtml();
+ }
+ } // end func renderElement
+
+ /**
+ * Renders an hidden element
+ * Called when visiting a hidden element
+ *
+ * @param object An HTML_QuickForm_hidden object being visited
+ * @access public
+ * @return void
+ */
+ function renderHidden(&$element)
+ {
+ $this->_hiddenHtml .= $element->toHtml() . "\n";
+ } // end func renderHidden
+
+ /**
+ * Called when visiting a raw HTML/text pseudo-element
+ *
+ * @param object An HTML_QuickForm_html element being visited
+ * @access public
+ * @return void
+ */
+ function renderHtml(&$data)
+ {
+ $this->_html .= $data->toHtml();
+ } // end func renderHtml
+
+ /**
+ * Called when visiting a group, before processing any group elements
+ *
+ * @param object An HTML_QuickForm_group object being visited
+ * @param bool Whether a group is required
+ * @param string An error message associated with a group
+ * @access public
+ * @return void
+ */
+ function startGroup(&$group, $required, $error)
+ {
+ $name = $group->getName();
+ $this->_groupTemplate = $this->_prepareTemplate($name, $group->getLabel(), $required, $error);
+ $this->_groupElementTemplate = empty($this->_groupTemplates[$name])? '': $this->_groupTemplates[$name];
+ $this->_groupWrap = empty($this->_groupWraps[$name])? '': $this->_groupWraps[$name];
+ $this->_groupElements = array();
+ $this->_inGroup = true;
+ } // end func startGroup
+
+ /**
+ * Called when visiting a group, after processing all group elements
+ *
+ * @param object An HTML_QuickForm_group object being visited
+ * @access public
+ * @return void
+ */
+ function finishGroup(&$group)
+ {
+ $separator = $group->_separator;
+ if (is_array($separator)) {
+ $count = count($separator);
+ $html = '';
+ for ($i = 0; $i < count($this->_groupElements); $i++) {
+ $html .= (0 == $i? '': $separator[($i - 1) % $count]) . $this->_groupElements[$i];
+ }
+ } else {
+ if (is_null($separator)) {
+ $separator = ' ';
+ }
+ $html = implode((string)$separator, $this->_groupElements);
+ }
+ if (!empty($this->_groupWrap)) {
+ $html = str_replace('{content}', $html, $this->_groupWrap);
+ }
+ $this->_html .= str_replace('{element}', $html, $this->_groupTemplate);
+ $this->_inGroup = false;
+ } // end func finishGroup
+
+ /**
+ * Sets element template
+ *
+ * @param string The HTML surrounding an element
+ * @param string (optional) Name of the element to apply template for
+ * @access public
+ * @return void
+ */
+ function setElementTemplate($html, $element = null)
+ {
+ if (is_null($element)) {
+ $this->_elementTemplate = $html;
+ } else {
+ $this->_templates[$element] = $html;
+ }
+ } // end func setElementTemplate
+
+
+ /**
+ * Sets template for a group wrapper
+ *
+ * This template is contained within a group-as-element template
+ * set via setTemplate() and contains group's element templates, set
+ * via setGroupElementTemplate()
+ *
+ * @param string The HTML surrounding group elements
+ * @param string Name of the group to apply template for
+ * @access public
+ * @return void
+ */
+ function setGroupTemplate($html, $group)
+ {
+ $this->_groupWraps[$group] = $html;
+ } // end func setGroupTemplate
+
+ /**
+ * Sets element template for elements within a group
+ *
+ * @param string The HTML surrounding an element
+ * @param string Name of the group to apply template for
+ * @access public
+ * @return void
+ */
+ function setGroupElementTemplate($html, $group)
+ {
+ $this->_groupTemplates[$group] = $html;
+ } // end func setGroupElementTemplate
+
+ /**
+ * Sets header template
+ *
+ * @param string The HTML surrounding the header
+ * @access public
+ * @return void
+ */
+ function setHeaderTemplate($html)
+ {
+ $this->_headerTemplate = $html;
+ } // end func setHeaderTemplate
+
+ /**
+ * Sets form template
+ *
+ * @param string The HTML surrounding the form tags
+ * @access public
+ * @return void
+ */
+ function setFormTemplate($html)
+ {
+ $this->_formTemplate = $html;
+ } // end func setFormTemplate
+
+ /**
+ * Sets the note indicating required fields template
+ *
+ * @param string The HTML surrounding the required note
+ * @access public
+ * @return void
+ */
+ function setRequiredNoteTemplate($html)
+ {
+ $this->_requiredNoteTemplate = $html;
+ } // end func setRequiredNoteTemplate
+
+ /**
+ * Clears all the HTML out of the templates that surround notes, elements, etc.
+ * Useful when you want to use addData() to create a completely custom form look
+ *
+ * @access public
+ * @return void
+ */
+ function clearAllTemplates()
+ {
+ $this->setElementTemplate('{element}');
+ $this->setFormTemplate("\n\t<form{attributes}>{content}\n\t</form>\n");
+ $this->setRequiredNoteTemplate('');
+ $this->_templates = array();
+ } // end func clearAllTemplates
+} // end class HTML_QuickForm_Renderer_Default
+?>
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP version 4.0 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2003 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Author: Ron McClain <ron@humaniq.com> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+require_once('HTML/QuickForm/Renderer.php');
+
+/**
+ * A concrete renderer for HTML_QuickForm, makes an object from form contents
+ *
+ * Based on HTML_Quickform_Renderer_Array code
+ *
+ * @access public
+ */
+class HTML_QuickForm_Renderer_Object extends HTML_QuickForm_Renderer
+{
+ /**
+ * The object being generated
+ * @var object $_obj
+ */
+ var $_obj= null;
+
+ /**
+ * Number of sections in the form (i.e. number of headers in it)
+ * @var integer $_sectionCount
+ */
+ var $_sectionCount;
+
+ /**
+ * Current section number
+ * @var integer $_currentSection
+ */
+ var $_currentSection;
+
+ /**
+ * Object representing current group
+ * @var object $_currentGroup
+ */
+ var $_currentGroup = null;
+
+ /**
+ * Class of Element Objects
+ * @var object $_elementType
+ */
+ var $_elementType = 'QuickFormElement';
+
+ /**
+ * Additional style information for different elements
+ * @var array $_elementStyles
+ */
+ var $_elementStyles = array();
+
+ /**
+ * true: collect all hidden elements into string; false: process them as usual form elements
+ * @var bool $_collectHidden
+ */
+ var $_collectHidden = false;
+
+
+ /**
+ * Constructor
+ *
+ * @param collecthidden bool true: collect all hidden elements
+ * @access public
+ */
+ function HTML_QuickForm_Renderer_Object($collecthidden = false)
+ {
+ $this->HTML_QuickForm_Renderer();
+ $this->_collectHidden = $collecthidden;
+ $this->_obj = new QuickformForm;
+ }
+
+ /**
+ * Return the rendered Object
+ * @access public
+ */
+ function toObject()
+ {
+ return $this->_obj;
+ }
+
+ /**
+ * Set the class of the form elements. Defaults to QuickformElement.
+ * @param type string Name of element class
+ * @access public
+ */
+ function setElementType($type)
+ {
+ $this->_elementType = $type;
+ }
+
+ function startForm(&$form)
+ {
+ $this->_obj->frozen = $form->isFrozen();
+ $this->_obj->javascript = $form->getValidationScript();
+ $this->_obj->attributes = $form->getAttributes(true);
+ $this->_obj->requirednote = $form->getRequiredNote();
+ $this->_obj->errors = new StdClass;
+
+ if($this->_collectHidden) {
+ $this->_obj->hidden = '';
+ }
+ $this->_elementIdx = 1;
+ $this->_currentSection = null;
+ $this->_sectionCount = 0;
+ } // end func startForm
+
+ function renderHeader(&$header)
+ {
+ $hobj = new StdClass;
+ $hobj->header = $header->toHtml();
+ $this->_obj->sections[$this->_sectionCount] = $hobj;
+ $this->_currentSection = $this->_sectionCount++;
+ }
+
+ function renderElement(&$element, $required, $error)
+ {
+ $elObj = $this->_elementToObject($element, $required, $error);
+ if(!empty($error)) {
+ $name = $elObj->name;
+ $this->_obj->errors->$name = $error;
+ }
+ $this->_storeObject($elObj);
+ } // end func renderElement
+
+ function renderHidden(&$element)
+ {
+ if($this->_collectHidden) {
+ $this->_obj->hidden .= $element->toHtml() . "\n";
+ } else {
+ $this->renderElement($element, false, null);
+ }
+ } //end func renderHidden
+
+ function startGroup(&$group, $required, $error)
+ {
+ $this->_currentGroup = $this->_elementToObject($group, $required, $error);
+ if(!empty($error)) {
+ $name = $this->_currentGroup->name;
+ $this->_obj->errors->$name = $error;
+ }
+ } // end func startGroup
+
+ function finishGroup(&$group)
+ {
+ $this->_storeObject($this->_currentGroup);
+ $this->_currentGroup = null;
+ } // end func finishGroup
+
+ /**
+ * Creates an object representing an element
+ *
+ * @access private
+ * @param element object An HTML_QuickForm_element object
+ * @param required bool Whether an element is required
+ * @param error string Error associated with the element
+ * @return object
+ */
+ function _elementToObject(&$element, $required, $error)
+ {
+ if($this->_elementType) {
+ $ret = new $this->_elementType;
+ }
+ $ret->name = $element->getName();
+ $ret->value = $element->getValue();
+ $ret->type = $element->getType();
+ $ret->frozen = $element->isFrozen();
+ $labels = $element->getLabel();
+ if (is_array($labels)) {
+ $ret->label = array_shift($labels);
+ foreach ($labels as $key => $label) {
+ $key = is_int($key)? $key + 2: $key;
+ $ret->{'label_' . $key} = $label;
+ }
+ } else {
+ $ret->label = $labels;
+ }
+ $ret->required = $required;
+ $ret->error = $error;
+
+ if(isset($this->_elementStyles[$ret->name])) {
+ $ret->style = $this->_elementStyles[$ret->name];
+ $ret->styleTemplate = "styles/". $ret->style .".html";
+ }
+ if($ret->type == 'group') {
+ $ret->separator = $element->_separator;
+ $ret->elements = array();
+ } else {
+ $ret->html = $element->toHtml();
+ }
+ return $ret;
+ }
+
+ /**
+ * Stores an object representation of an element in the form array
+ *
+ * @access private
+ * @param elObj object Object representation of an element
+ * @return void
+ */
+ function _storeObject($elObj)
+ {
+ $name = $elObj->name;
+ if(is_object($this->_currentGroup) && $elObj->type != 'group') {
+ $this->_currentGroup->elements[] = $elObj;
+ } elseif (isset($this->_currentSection)) {
+ $this->_obj->sections[$this->_currentSection]->elements[] = $elObj;
+ } else {
+ $this->_obj->elements[] = $elObj;
+ }
+ }
+
+ function setElementStyle($elementName, $styleName = null)
+ {
+ if(is_array($elementName)) {
+ $this->_elementStyles = array_merge($this->_elementStyles, $elementName);
+ } else {
+ $this->_elementStyles[$elementName] = $styleName;
+ }
+ }
+
+} // end class HTML_QuickForm_Renderer_Object
+
+
+
+/**
+ * Convenience class for the form object passed to outputObject()
+ *
+ * Eg.
+ * {form.outputJavaScript():h}
+ * {form.outputHeader():h}
+ * <table>
+ * <tr>
+ * <td>{form.name.label:h}</td><td>{form.name.html:h}</td>
+ * </tr>
+ * </table>
+ * </form>
+ */
+class QuickformForm
+{
+ /**
+ * Whether the form has been frozen
+ * @var boolean $frozen
+ */
+ var $frozen;
+
+ /**
+ * Javascript for client-side validation
+ * @var string $javascript
+ */
+ var $javascript;
+
+ /**
+ * Attributes for form tag
+ * @var string $attributes
+ */
+ var $attributes;
+
+ /**
+ * Note about required elements
+ * @var string $requirednote
+ */
+ var $requirednote;
+
+ /**
+ * Collected html of all hidden variables
+ * @var string $hidden
+ */
+ var $hidden;
+
+ /**
+ * Set if there were validation errors.
+ * StdClass object with element names for keys and their
+ * error messages as values
+ * @var object $errors
+ */
+ var $errors;
+
+ /**
+ * Array of QuickformElementObject elements. If there are headers in the form
+ * this will be empty and the elements will be in the
+ * separate sections
+ * @var array $elements
+ */
+ var $elements;
+
+ /**
+ * Array of sections contained in the document
+ * @var array $sections
+ */
+ var $sections;
+
+ /**
+ * Output <form> header
+ * {form.outputHeader():h}
+ * @return string <form attributes>
+ */
+ function outputHeader()
+ {
+ return "<form " . $this->attributes . ">\n";
+ }
+
+ /**
+ * Output form javascript
+ * {form.outputJavaScript():h}
+ * @return string Javascript
+ */
+ function outputJavaScript()
+ {
+ return $this->javascript;
+ }
+} // end class QuickformForm
+
+
+/**
+ * Convenience class describing a form element.
+ * The properties defined here will be available from
+ * your flexy templates by referencing
+ * {form.zip.label:h}, {form.zip.html:h}, etc.
+ */
+class QuickformElement
+{
+ /**
+ * Element name
+ * @var string $name
+ */
+ var $name;
+
+ /**
+ * Element value
+ * @var mixed $value
+ */
+ var $value;
+
+ /**
+ * Type of element
+ * @var string $type
+ */
+ var $type;
+
+ /**
+ * Whether the element is frozen
+ * @var boolean $frozen
+ */
+ var $frozen;
+
+ /**
+ * Label for the element
+ * @var string $label
+ */
+ var $label;
+
+ /**
+ * Whether element is required
+ * @var boolean $required
+ */
+ var $required;
+
+ /**
+ * Error associated with the element
+ * @var string $error
+ */
+ var $error;
+
+ /**
+ * Some information about element style
+ * @var string $style
+ */
+ var $style;
+
+ /**
+ * HTML for the element
+ * @var string $html
+ */
+ var $html;
+
+ /**
+ * If element is a group, the group separator
+ * @var mixed $separator
+ */
+ var $separator;
+
+ /**
+ * If element is a group, an array of subelements
+ * @var array $elements
+ */
+ var $elements;
+
+ function isType($type)
+ {
+ return ($this->type == $type);
+ }
+
+ function notFrozen()
+ {
+ return !$this->frozen;
+ }
+
+ function isButton()
+ {
+ return ($this->type == "submit" || $this->type == "reset");
+ }
+
+
+ /**
+ * XXX: why does it use Flexy when all other stuff here does not depend on it?
+ */
+ function outputStyle()
+ {
+ ob_start();
+ HTML_Template_Flexy::staticQuickTemplate('styles/' . $this->style . '.html', $this);
+ $ret = ob_get_contents();
+ ob_end_clean();
+ return $ret;
+ }
+} // end class QuickformElement
+?>
--- /dev/null
+<?php
+/**
+ * A renderer for HTML_QuickForm that only uses XHTML and CSS but no
+ * table tags
+ *
+ * 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_Renderer_Tableless
+ * @author Alexey Borzov <borz_off@cs.msu.su>
+ * @author Adam Daniel <adaniel1@eesus.jnj.com>
+ * @author Bertrand Mansion <bmansion@mamasam.com>
+ * @author Mark Wiesemann <wiesemann@php.net>
+ * @copyright 2005-2006 The PHP Group
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version CVS: $Id$
+ * @link http://pear.php.net/package/HTML_QuickForm_Renderer_Tableless
+ */
+
+require_once 'HTML/QuickForm/Renderer/Default.php';
+
+/**
+ * A renderer for HTML_QuickForm that only uses XHTML and CSS but no
+ * table tags
+ *
+ * You need to specify a stylesheet like the one that you find in
+ * data/stylesheet.css to make this work.
+ *
+ * @category HTML
+ * @package HTML_QuickForm_Renderer_Tableless
+ * @author Alexey Borzov <borz_off@cs.msu.su>
+ * @author Adam Daniel <adaniel1@eesus.jnj.com>
+ * @author Bertrand Mansion <bmansion@mamasam.com>
+ * @author Mark Wiesemann <wiesemann@php.net>
+ * @license http://www.php.net/license/3_01.txt PHP License 3.01
+ * @version Release: 0.3.3
+ * @link http://pear.php.net/package/HTML_QuickForm_Renderer_Tableless
+ */
+class HTML_QuickForm_Renderer_Tableless extends HTML_QuickForm_Renderer_Default
+{
+ /**
+ * Header Template string
+ * @var string
+ * @access private
+ */
+ var $_headerTemplate =
+ "\n\t\t<legend>{header}</legend>";
+
+ /**
+ * Element template string
+ * @var string
+ * @access private
+ */
+ var $_elementTemplate =
+ "\n\t\t<div class=\"qfrow\"><label class=\"qflabel\"><!-- BEGIN required --><span class=\"required\">*</span><!-- END required -->{label}</label>{help}<div class=\"qfelement<!-- BEGIN error --> error<!-- END error -->\"><!-- BEGIN error --><span class=\"error\">{error}</span><br /><!-- END error -->{element}</div></div><br />";
+
+ /**
+ * Form template string
+ * @var string
+ * @access private
+ */
+ var $_formTemplate =
+ "\n<form{attributes}>\n\t<div style=\"display: none;\">{hidden}</div>\n{content}\n</form>";
+
+ /**
+ * Template used when opening a fieldset
+ * @var string
+ * @access private
+ */
+ var $_openFieldsetTemplate = "\n\t<fieldset{id}>";
+
+ /**
+ * Template used when opening a hidden fieldset
+ * (i.e. a fieldset that is opened when there is no header element)
+ * @var string
+ * @access private
+ */
+ var $_openHiddenFieldsetTemplate = "\n\t<fieldset class=\"hidden\">";
+
+ /**
+ * Template used when closing a fieldset
+ * @var string
+ * @access private
+ */
+ var $_closeFieldsetTemplate = "\n\t</fieldset>";
+
+ /**
+ * Required Note template string
+ * @var string
+ * @access private
+ */
+ var $_requiredNoteTemplate =
+ "\n\t\t{requiredNote}";
+
+ /**
+ * How many fieldsets are open
+ * @var integer
+ * @access private
+ */
+ var $_fieldsetsOpen = 0;
+
+ /**
+ * Array of element names that indicate the end of a fieldset
+ * (a new one will be opened when a the next header element occurs)
+ * @var array
+ * @access private
+ */
+ var $_stopFieldsetElements = array();
+
+ /**
+ * Constructor
+ *
+ * @access public
+ */
+ function HTML_QuickForm_Renderer_Tableless()
+ {
+ $this->HTML_QuickForm_Renderer_Default();
+ } // end constructor
+
+ /**
+ * Called when visiting a header element
+ *
+ * @param object An HTML_QuickForm_header element being visited
+ * @access public
+ * @return void
+ */
+ function renderHeader(&$header)
+ {
+ $name = $header->getName();
+ $id = empty($name) ? '' : ' id="' . $name . '"';
+ if (is_null($header->_text)) {
+ $header_html = '';
+ }
+ elseif (!empty($name) && isset($this->_templates[$name])) {
+ $header_html = str_replace('{header}', $header->toHtml(), $this->_templates[$name]);
+ } else {
+ $header_html = str_replace('{header}', $header->toHtml(), $this->_headerTemplate);
+ }
+ if ($this->_fieldsetsOpen > 0) {
+ $this->_html .= $this->_closeFieldsetTemplate;
+ $this->_fieldsetsOpen--;
+ }
+ $openFieldsetTemplate = str_replace('{id}', $id, $this->_openFieldsetTemplate);
+ $this->_html .= $openFieldsetTemplate . $header_html;
+ $this->_fieldsetsOpen++;
+ } // end func renderHeader
+
+ /**
+ * Renders an element Html
+ * Called when visiting an element
+ *
+ * @param object An HTML_QuickForm_element object being visited
+ * @param bool Whether an element is required
+ * @param string An error message associated with an element
+ * @access public
+ * @return void
+ */
+ function renderElement(&$element, $required, $error)
+ {
+ // if the element name indicates the end of a fieldset, close the fieldset
+ if ( in_array($element->getName(), $this->_stopFieldsetElements)
+ && $this->_fieldsetsOpen > 0
+ ) {
+ $this->_html .= $this->_closeFieldsetTemplate;
+ $this->_fieldsetsOpen--;
+ }
+ // if no fieldset was opened, we need to open a hidden one here to get
+ // XHTML validity
+ if ($this->_fieldsetsOpen === 0) {
+ $this->_html .= $this->_openHiddenFieldsetTemplate;
+ $this->_fieldsetsOpen++;
+ }
+ if (!$this->_inGroup) {
+ $html = $this->_prepareTemplate($element->getName(), $element->getLabel(), $required, $error);
+ // the following lines (until the "elseif") were changed / added
+ // compared to the default renderer
+ $element_html = $element->toHtml();
+ if (!is_null($element->getAttribute('id'))) {
+ $id = $element->getAttribute('id');
+ } else {
+ $id = $element->getName();
+ }
+ $html = str_replace('<label', '<label for="' . $id . '"', $html);
+ $element_html = str_replace('name="' . $id . '"',
+ 'id="' . $id . '" name="' . $id . '"',
+ $element_html);
+ $this->_html .= str_replace('{element}', $element_html, $html);
+ } elseif (!empty($this->_groupElementTemplate)) {
+ $html = str_replace('{label}', $element->getLabel(), $this->_groupElementTemplate);
+ if ($required) {
+ $html = str_replace('<!-- BEGIN required -->', '', $html);
+ $html = str_replace('<!-- END required -->', '', $html);
+ } else {
+ $html = preg_replace("/([ \t\n\r]*)?<!-- BEGIN required -->(\s|\S)*<!-- END required -->([ \t\n\r]*)?/i", '', $html);
+ }
+ $this->_groupElements[] = str_replace('{element}', $element->toHtml(), $html);
+
+ } else {
+ $this->_groupElements[] = $element->toHtml();
+ }
+ } // end func renderElement
+
+ /**
+ * Called when visiting a form, before processing any form elements
+ *
+ * @param object An HTML_QuickForm object being visited
+ * @access public
+ * @return void
+ */
+ function startForm(&$form)
+ {
+ $this->_fieldsetsOpen = 0;
+ parent::startForm($form);
+ } // end func startForm
+
+ /**
+ * Called when visiting a form, after processing all form elements
+ * Adds required note, form attributes, validation javascript and form content.
+ *
+ * @param object An HTML_QuickForm object being visited
+ * @access public
+ * @return void
+ */
+ function finishForm(&$form)
+ {
+ // add a required note, if one is needed
+ if (!empty($form->_required) && !$form->_freezeAll) {
+ $this->_html .= str_replace('{requiredNote}', $form->getRequiredNote(), $this->_requiredNoteTemplate);
+ }
+ // close the open fieldset
+ if ($this->_fieldsetsOpen > 0) {
+ $this->_html .= $this->_closeFieldsetTemplate;
+ $this->_fieldsetsOpen--;
+ }
+ // add form attributes and content
+ $html = str_replace('{attributes}', $form->getAttributes(true), $this->_formTemplate);
+ if (strpos($this->_formTemplate, '{hidden}')) {
+ $html = str_replace('{hidden}', $this->_hiddenHtml, $html);
+ } else {
+ $this->_html .= $this->_hiddenHtml;
+ }
+ $this->_hiddenHtml = '';
+ $this->_html = str_replace('{content}', $this->_html, $html);
+ $this->_html = str_replace('></label>', '> </label>', $this->_html);
+ // add a validation script
+ if ('' != ($script = $form->getValidationScript())) {
+ $this->_html = $script . "\n" . $this->_html;
+ }
+ } // end func finishForm
+
+ /**
+ * Sets the template used when opening a fieldset
+ *
+ * @param string The HTML used when opening a fieldset
+ * @access public
+ * @return void
+ */
+ function setOpenFieldsetTemplate($html)
+ {
+ $this->_openFieldsetTemplate = $html;
+ } // end func setOpenFieldsetTemplate
+
+ /**
+ * Sets the template used when opening a hidden fieldset
+ * (i.e. a fieldset that is opened when there is no header element)
+ *
+ * @param string The HTML used when opening a hidden fieldset
+ * @access public
+ * @return void
+ */
+ function setOpenHiddenFieldsetTemplate($html)
+ {
+ $this->_openHiddenFieldsetTemplate = $html;
+ } // end func setOpenHiddenFieldsetTemplate
+
+ /**
+ * Sets the template used when closing a fieldset
+ *
+ * @param string The HTML used when closing a fieldset
+ * @access public
+ * @return void
+ */
+ function setCloseFieldsetTemplate($html)
+ {
+ $this->_closeFieldsetTemplate = $html;
+ } // end func setCloseFieldsetTemplate
+
+ /**
+ * Adds one or more element names that indicate the end of a fieldset
+ * (a new one will be opened when a the next header element occurs)
+ *
+ * @param mixed Element name(s) (as array or string)
+ * @access public
+ * @return void
+ */
+ function addStopFieldsetElements($element)
+ {
+ if (is_array($element)) {
+ $this->_stopFieldsetElements = array_merge($this->_stopFieldsetElements,
+ $element);
+ } else {
+ $this->_stopFieldsetElements[] = $element;
+ }
+ } // end func addStopFieldsetElements
+
+} // end class HTML_QuickForm_Renderer_Default
+?>
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP version 4.0 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2003 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Bertrand Mansion <bmansion@mamasam.com> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+class HTML_QuickForm_Rule
+{
+ /**
+ * Name of the rule to use in validate method
+ *
+ * This property is used in more global rules like Callback and Regex
+ * to determine which callback and which regex is to be used for validation
+ *
+ * @var string
+ * @access public
+ */
+ var $name;
+
+ /**
+ * Validates a value
+ *
+ * @access public
+ * @abstract
+ */
+ function validate($value)
+ {
+ return true;
+ }
+
+ /**
+ * Sets the rule name
+ *
+ * @access public
+ */
+ function setName($ruleName)
+ {
+ $this->name = $ruleName;
+ }
+
+ /**
+ * Returns the javascript test (the test should return true if the value is INVALID)
+ *
+ * @param mixed Options for the rule
+ * @access public
+ * @return array first element is code to setup validation, second is the check itself
+ */
+ function getValidationScript($options = null)
+ {
+ return array('', '');
+ }
+}
+?>
\ No newline at end of file
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP version 4.0 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2003 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Bertrand Mansion <bmansion@mamasam.com> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+require_once('HTML/QuickForm/Rule.php');
+
+/**
+* Validates values using callback functions or methods
+* @version 1.0
+*/
+class HTML_QuickForm_Rule_Callback extends HTML_QuickForm_Rule
+{
+ /**
+ * Array of callbacks
+ *
+ * Array is in the format:
+ * $_data['rulename'] = array('functionname', 'classname');
+ * If the callback is not a method, then the class name is not set.
+ *
+ * @var array
+ * @access private
+ */
+ var $_data = array();
+
+ /**
+ * Whether to use BC mode for specific rules
+ *
+ * Previous versions of QF passed element's name as a first parameter
+ * to validation functions, but not to validation methods. This behaviour
+ * is emulated if you are using 'function' as rule type when registering.
+ *
+ * @var array
+ * @access private
+ */
+ var $_BCMode = array();
+
+ /**
+ * Validates a value using a callback
+ *
+ * @param string $value Value to be checked
+ * @param mixed $options Options for callback
+ * @access public
+ * @return boolean true if value is valid
+ */
+ function validate($value, $options = null)
+ {
+ if (isset($this->_data[$this->name])) {
+ $callback = $this->_data[$this->name];
+ if (isset($callback[1])) {
+ return call_user_func(array($callback[1], $callback[0]), $value, $options);
+ } elseif ($this->_BCMode[$this->name]) {
+ return $callback[0]('', $value, $options);
+ } else {
+ return $callback[0]($value, $options);
+ }
+ } elseif (is_callable($options)) {
+ return call_user_func($options, $value);
+ } else {
+ return true;
+ }
+ } // end func validate
+
+ /**
+ * Adds new callbacks to the callbacks list
+ *
+ * @param string $name Name of rule
+ * @param string $callback Name of function or method
+ * @param string $class Name of class containing the method
+ * @param bool $BCMode Backwards compatibility mode
+ * @access public
+ */
+ function addData($name, $callback, $class = null, $BCMode = false)
+ {
+ if (!empty($class)) {
+ $this->_data[$name] = array($callback, $class);
+ } else {
+ $this->_data[$name] = array($callback);
+ }
+ $this->_BCMode[$name] = $BCMode;
+ } // end func addData
+
+
+ function getValidationScript($options = null)
+ {
+ if (isset($this->_data[$this->name])) {
+ $callback = $this->_data[$this->name][0];
+ $params = ($this->_BCMode[$this->name]? "'', {jsVar}": '{jsVar}') .
+ (isset($options)? ", '{$options}'": '');
+ } else {
+ $callback = is_array($options)? $options[1]: $options;
+ $params = '{jsVar}';
+ }
+ return array('', "{jsVar} != '' && !{$callback}({$params})");
+ } // end func getValidationScript
+
+} // end class HTML_QuickForm_Rule_Callback
+?>
\ No newline at end of file
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP version 4.0 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2003 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Author: Alexey Borzov <avb@php.net> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+require_once 'HTML/QuickForm/Rule.php';
+
+/**
+ * Rule to compare two form fields
+ *
+ * The most common usage for this is to ensure that the password
+ * confirmation field matches the password field
+ *
+ * @access public
+ * @package HTML_QuickForm
+ * @version $Revision$
+ */
+class HTML_QuickForm_Rule_Compare extends HTML_QuickForm_Rule
+{
+ /**
+ * Possible operators to use
+ * @var array
+ * @access private
+ */
+ var $_operators = array(
+ 'eq' => '==',
+ 'neq' => '!=',
+ 'gt' => '>',
+ 'gte' => '>=',
+ 'lt' => '<',
+ 'lte' => '<='
+ );
+
+
+ /**
+ * Returns the operator to use for comparing the values
+ *
+ * @access private
+ * @param string operator name
+ * @return string operator to use for validation
+ */
+ function _findOperator($name)
+ {
+ if (empty($name)) {
+ return '==';
+ } elseif (isset($this->_operators[$name])) {
+ return $this->_operators[$name];
+ } elseif (in_array($name, $this->_operators)) {
+ return $name;
+ } else {
+ return '==';
+ }
+ }
+
+
+ function validate($values, $operator = null)
+ {
+ $operator = $this->_findOperator($operator);
+ if ('==' != $operator && '!=' != $operator) {
+ $compareFn = create_function('$a, $b', 'return floatval($a) ' . $operator . ' floatval($b);');
+ } else {
+ $compareFn = create_function('$a, $b', 'return $a ' . $operator . ' $b;');
+ }
+
+ return $compareFn($values[0], $values[1]);
+ }
+
+
+ function getValidationScript($operator = null)
+ {
+ $operator = $this->_findOperator($operator);
+ if ('==' != $operator && '!=' != $operator) {
+ $check = "!(Number({jsVar}[0]) {$operator} Number({jsVar}[1]))";
+ } else {
+ $check = "!({jsVar}[0] {$operator} {jsVar}[1])";
+ }
+ return array('', "'' != {jsVar}[0] && {$check}");
+ }
+}
+?>
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP version 4.0 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2003 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Bertrand Mansion <bmansion@mamasam.com> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+require_once('HTML/QuickForm/Rule.php');
+
+/**
+* Email validation rule
+* @version 1.0
+*/
+class HTML_QuickForm_Rule_Email extends HTML_QuickForm_Rule
+{
+ var $regex = '/^((\"[^\"\f\n\r\t\v\b]+\")|([\w\!\#\$\%\&\'\*\+\-\~\/\^\`\|\{\}]+(\.[\w\!\#\$\%\&\'\*\+\-\~\/\^\`\|\{\}]+)*))@((\[(((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9])))\])|(((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9])))|((([A-Za-z0-9\-])+\.)+[A-Za-z\-]+))$/';
+
+ /**
+ * Validates an email address
+ *
+ * @param string $email Email address
+ * @param boolean $checkDomain True if dns check should be performed
+ * @access public
+ * @return boolean true if email is valid
+ */
+ function validate($email, $checkDomain = false)
+ {
+ if (preg_match($this->regex, $email)) {
+ if ($checkDomain && function_exists('checkdnsrr')) {
+ $tokens = explode('@', $email);
+ if (checkdnsrr($tokens[1], 'MX') || checkdnsrr($tokens[1], 'A')) {
+ return true;
+ }
+ return false;
+ }
+ return true;
+ }
+ return false;
+ } // end func validate
+
+
+ function getValidationScript($options = null)
+ {
+ return array(" var regex = " . $this->regex . ";\n", "{jsVar} != '' && !regex.test({jsVar})");
+ } // end func getValidationScript
+
+} // end class HTML_QuickForm_Rule_Email
+?>
\ No newline at end of file
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP version 4.0 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2003 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Bertrand Mansion <bmansion@mamasam.com> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+require_once('HTML/QuickForm/Rule.php');
+
+/**
+* Validates values using range comparison
+* @version 1.0
+*/
+class HTML_QuickForm_Rule_Range extends HTML_QuickForm_Rule
+{
+ /**
+ * Validates a value using a range comparison
+ *
+ * @param string $value Value to be checked
+ * @param mixed $options Int for length, array for range
+ * @access public
+ * @return boolean true if value is valid
+ */
+ function validate($value, $options)
+ {
+ $length = strlen($value);
+ switch ($this->name) {
+ case 'minlength': return ($length >= $options);
+ case 'maxlength': return ($length <= $options);
+ default: return ($length >= $options[0] && $length <= $options[1]);
+ }
+ } // end func validate
+
+
+ function getValidationScript($options = null)
+ {
+ switch ($this->name) {
+ case 'minlength':
+ $test = '{jsVar}.length < '.$options;
+ break;
+ case 'maxlength':
+ $test = '{jsVar}.length > '.$options;
+ break;
+ default:
+ $test = '({jsVar}.length < '.$options[0].' || {jsVar}.length > '.$options[1].')';
+ }
+ return array('', "{jsVar} != '' && {$test}");
+ } // end func getValidationScript
+
+} // end class HTML_QuickForm_Rule_Range
+?>
\ No newline at end of file
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP version 4.0 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2003 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Bertrand Mansion <bmansion@mamasam.com> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+require_once('HTML/QuickForm/Rule.php');
+
+/**
+* Validates values using regular expressions
+* @version 1.0
+*/
+class HTML_QuickForm_Rule_Regex extends HTML_QuickForm_Rule
+{
+ /**
+ * Array of regular expressions
+ *
+ * Array is in the format:
+ * $_data['rulename'] = 'pattern';
+ *
+ * @var array
+ * @access private
+ */
+ var $_data = array(
+ 'lettersonly' => '/^[a-zA-Z]+$/',
+ 'alphanumeric' => '/^[a-zA-Z0-9]+$/',
+ 'numeric' => '/(^-?\d\d*\.\d*$)|(^-?\d\d*$)|(^-?\.\d\d*$)/',
+ 'nopunctuation' => '/^[^().\/\*\^\?#!@$%+=,\"\'><~\[\]{}]+$/',
+ 'nonzero' => '/^-?[1-9][0-9]*/'
+ );
+
+ /**
+ * Validates a value using a regular expression
+ *
+ * @param string $value Value to be checked
+ * @param string $regex Regular expression
+ * @access public
+ * @return boolean true if value is valid
+ */
+ function validate($value, $regex = null)
+ {
+ if (isset($this->_data[$this->name])) {
+ if (!preg_match($this->_data[$this->name], $value)) {
+ return false;
+ }
+ } else {
+ if (!preg_match($regex, $value)) {
+ return false;
+ }
+ }
+ return true;
+ } // end func validate
+
+ /**
+ * Adds new regular expressions to the list
+ *
+ * @param string $name Name of rule
+ * @param string $pattern Regular expression pattern
+ * @access public
+ */
+ function addData($name, $pattern)
+ {
+ $this->_data[$name] = $pattern;
+ } // end func addData
+
+
+ function getValidationScript($options = null)
+ {
+ $regex = isset($this->_data[$this->name]) ? $this->_data[$this->name] : $options;
+
+ return array(" var regex = " . $regex . ";\n", "{jsVar} != '' && !regex.test({jsVar})");
+ } // end func getValidationScript
+
+} // end class HTML_QuickForm_Rule_Regex
+?>
\ No newline at end of file
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP version 4.0 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2003 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Bertrand Mansion <bmansion@mamasam.com> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+require_once('HTML/QuickForm/Rule.php');
+
+/**
+* Required elements validation
+* @version 1.0
+*/
+class HTML_QuickForm_Rule_Required extends HTML_QuickForm_Rule
+{
+ /**
+ * Checks if an element is empty
+ *
+ * @param string $value Value to check
+ * @param mixed $options Not used yet
+ * @access public
+ * @return boolean true if value is not empty
+ */
+ function validate($value, $options = null)
+ {
+ if ((string)$value == '') {
+ return false;
+ }
+ return true;
+ } // end func validate
+
+
+ function getValidationScript($options = null)
+ {
+ return array('', "{jsVar} == ''");
+ } // end func getValidationScript
+
+} // end class HTML_QuickForm_Rule_Required
+?>
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP version 4.0 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2003 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> |
+// | Alexey Borzov <borz_off@cs.msu.su> |
+// | Bertrand Mansion <bmansion@mamasam.com> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+/**
+* Registers rule objects and uses them for validation
+*
+*/
+class HTML_QuickForm_RuleRegistry
+{
+ /**
+ * Array containing references to used rules
+ * @var array
+ * @access private
+ */
+ var $_rules = array();
+
+
+ /**
+ * Returns a singleton of HTML_QuickForm_RuleRegistry
+ *
+ * Usually, only one RuleRegistry object is needed, this is the reason
+ * why it is recommended to use this method to get the validation object.
+ *
+ * @access public
+ * @static
+ * @return object Reference to the HTML_QuickForm_RuleRegistry singleton
+ */
+ function &singleton()
+ {
+ static $obj;
+ if (!isset($obj)) {
+ $obj = new HTML_QuickForm_RuleRegistry();
+ }
+ return $obj;
+ } // end func singleton
+
+ /**
+ * Registers a new validation rule
+ *
+ * In order to use a custom rule in your form, you need to register it
+ * first. For regular expressions, one can directly use the 'regex' type
+ * rule in addRule(), this is faster than registering the rule.
+ *
+ * Functions and methods can be registered. Use the 'function' type.
+ * When registering a method, specify the class name as second parameter.
+ *
+ * You can also register an HTML_QuickForm_Rule subclass with its own
+ * validate() method.
+ *
+ * @param string $ruleName Name of validation rule
+ * @param string $type Either: 'regex', 'function' or null
+ * @param string $data1 Name of function, regular expression or
+ * HTML_QuickForm_Rule object class name
+ * @param string $data2 Object parent of above function or HTML_QuickForm_Rule file path
+ * @access public
+ * @return void
+ */
+ function registerRule($ruleName, $type, $data1, $data2 = null)
+ {
+ $type = strtolower($type);
+ if ($type == 'regex') {
+ // Regular expression
+ $rule =& $this->getRule('regex');
+ $rule->addData($ruleName, $data1);
+ $GLOBALS['_HTML_QuickForm_registered_rules'][$ruleName] = $GLOBALS['_HTML_QuickForm_registered_rules']['regex'];
+
+ } elseif ($type == 'function' || $type == 'callback') {
+ // Callback function
+ $rule =& $this->getRule('callback');
+ $rule->addData($ruleName, $data1, $data2, 'function' == $type);
+ $GLOBALS['_HTML_QuickForm_registered_rules'][$ruleName] = $GLOBALS['_HTML_QuickForm_registered_rules']['callback'];
+
+ } elseif (is_object($data1)) {
+ // An instance of HTML_QuickForm_Rule
+ $this->_rules[strtolower(get_class($data1))] = $data1;
+ $GLOBALS['_HTML_QuickForm_registered_rules'][$ruleName] = array(strtolower(get_class($data1)), null);
+
+ } else {
+ // Rule class name
+ $GLOBALS['_HTML_QuickForm_registered_rules'][$ruleName] = array(strtolower($data1), $data2);
+ }
+ } // end func registerRule
+
+ /**
+ * Returns a reference to the requested rule object
+ *
+ * @param string $ruleName Name of the requested rule
+ * @access public
+ * @return object
+ */
+ function &getRule($ruleName)
+ {
+ list($class, $path) = $GLOBALS['_HTML_QuickForm_registered_rules'][$ruleName];
+
+ if (!isset($this->_rules[$class])) {
+ if (!empty($path)) {
+ include_once($path);
+ }
+ $this->_rules[$class] =& new $class();
+ }
+ $this->_rules[$class]->setName($ruleName);
+ return $this->_rules[$class];
+ } // end func getRule
+
+ /**
+ * Performs validation on the given values
+ *
+ * @param string $ruleName Name of the rule to be used
+ * @param mixed $values Can be a scalar or an array of values
+ * to be validated
+ * @param mixed $options Options used by the rule
+ * @param mixed $multiple Whether to validate an array of values altogether
+ * @access public
+ * @return mixed true if no error found, int of valid values (when an array of values is given) or false if error
+ */
+ function validate($ruleName, $values, $options = null, $multiple = false)
+ {
+ $rule =& $this->getRule($ruleName);
+
+ if (is_array($values) && !$multiple) {
+ $result = 0;
+ foreach ($values as $value) {
+ if ($rule->validate($value, $options) === true) {
+ $result++;
+ }
+ }
+ return ($result == 0) ? false : $result;
+ } else {
+ return $rule->validate($values, $options);
+ }
+ } // end func validate
+
+ /**
+ * Returns the validation test in javascript code
+ *
+ * @param mixed Element(s) the rule applies to
+ * @param string Element name, in case $element is not array
+ * @param array Rule data
+ * @access public
+ * @return string JavaScript for the rule
+ */
+ function getValidationScript(&$element, $elementName, $ruleData)
+ {
+ $reset = (isset($ruleData['reset'])) ? $ruleData['reset'] : false;
+ $rule =& $this->getRule($ruleData['type']);
+ if (!is_array($element)) {
+ list($jsValue, $jsReset) = $this->_getJsValue($element, $elementName, $reset, null);
+ } else {
+ $jsValue = " value = new Array();\n";
+ $jsReset = '';
+ for ($i = 0; $i < count($element); $i++) {
+ list($tmp_value, $tmp_reset) = $this->_getJsValue($element[$i], $element[$i]->getName(), $reset, $i);
+ $jsValue .= "\n" . $tmp_value;
+ $jsReset .= $tmp_reset;
+ }
+ }
+ $jsField = isset($ruleData['group'])? $ruleData['group']: $elementName;
+ list ($jsPrefix, $jsCheck) = $rule->getValidationScript($ruleData['format']);
+ if (!isset($ruleData['howmany'])) {
+ $js = $jsValue . "\n" . $jsPrefix .
+ " if (" . str_replace('{jsVar}', 'value', $jsCheck) . " && !errFlag['{$jsField}']) {\n" .
+ " errFlag['{$jsField}'] = true;\n" .
+ " _qfMsg = _qfMsg + '\\n - {$ruleData['message']}';\n" .
+ $jsReset .
+ " }\n";
+ } else {
+ $js = $jsValue . "\n" . $jsPrefix .
+ " var res = 0;\n" .
+ " for (var i = 0; i < value.length; i++) {\n" .
+ " if (!(" . str_replace('{jsVar}', 'value[i]', $jsCheck) . ")) {\n" .
+ " res++;\n" .
+ " }\n" .
+ " }\n" .
+ " if (res < {$ruleData['howmany']} && !errFlag['{$jsField}']) {\n" .
+ " errFlag['{$jsField}'] = true;\n" .
+ " _qfMsg = _qfMsg + '\\n - {$ruleData['message']}';\n" .
+ $jsReset .
+ " }\n";
+ }
+ return $js;
+ } // end func getValidationScript
+
+
+ /**
+ * Returns JavaScript to get and to reset the element's value
+ *
+ * @access private
+ * @param object HTML_QuickForm_element element being processed
+ * @param string element's name
+ * @param bool whether to generate JavaScript to reset the value
+ * @param integer value's index in the array (only used for multielement rules)
+ * @return array first item is value javascript, second is reset
+ */
+ function _getJsValue(&$element, $elementName, $reset = false, $index = null)
+ {
+ $jsIndex = isset($index)? '[' . $index . ']': '';
+ $tmp_reset = $reset? " var field = frm.elements['$elementName'];\n": '';
+ if (is_a($element, 'html_quickform_group')) {
+ $value = " _qfGroups['{$elementName}'] = {";
+ $elements =& $element->getElements();
+ for ($i = 0, $count = count($elements); $i < $count; $i++) {
+ $append = ($elements[$i]->getType() == 'select' && $elements[$i]->getMultiple())? '[]': '';
+ $value .= "'" . $element->getElementName($i) . $append . "': true" .
+ ($i < $count - 1? ', ': '');
+ }
+ $value .=
+ "};\n" .
+ " value{$jsIndex} = new Array();\n" .
+ " var valueIdx = 0;\n" .
+ " for (var i = 0; i < frm.elements.length; i++) {\n" .
+ " var _element = frm.elements[i];\n" .
+ " if (_element.name in _qfGroups['{$elementName}']) {\n" .
+ " switch (_element.type) {\n" .
+ " case 'checkbox':\n" .
+ " case 'radio':\n" .
+ " if (_element.checked) {\n" .
+ " value{$jsIndex}[valueIdx++] = _element.value;\n" .
+ " }\n" .
+ " break;\n" .
+ " case 'select-one':\n" .
+ " if (-1 != _element.selectedIndex) {\n" .
+ " value{$jsIndex}[valueIdx++] = _element.options[_element.selectedIndex].value;\n" .
+ " }\n" .
+ " break;\n" .
+ " case 'select-multiple':\n" .
+ " var tmpVal = new Array();\n" .
+ " var tmpIdx = 0;\n" .
+ " for (var j = 0; j < _element.options.length; j++) {\n" .
+ " if (_element.options[j].selected) {\n" .
+ " tmpVal[tmpIdx++] = _element.options[j].value;\n" .
+ " }\n" .
+ " }\n" .
+ " if (tmpIdx > 0) {\n" .
+ " value{$jsIndex}[valueIdx++] = tmpVal;\n" .
+ " }\n" .
+ " break;\n" .
+ " default:\n" .
+ " value{$jsIndex}[valueIdx++] = _element.value;\n" .
+ " }\n" .
+ " }\n" .
+ " }\n";
+ if ($reset) {
+ $tmp_reset =
+ " for (var i = 0; i < frm.elements.length; i++) {\n" .
+ " var _element = frm.elements[i];\n" .
+ " if (_element.name in _qfGroups['{$elementName}']) {\n" .
+ " switch (_element.type) {\n" .
+ " case 'checkbox':\n" .
+ " case 'radio':\n" .
+ " _element.checked = _element.defaultChecked;\n" .
+ " break;\n" .
+ " case 'select-one':\n" .
+ " case 'select-multiple':\n" .
+ " for (var j = 0; j < _element.options.length; j++) {\n" .
+ " _element.options[j].selected = _element.options[j].defaultSelected;\n" .
+ " }\n" .
+ " break;\n" .
+ " default:\n" .
+ " _element.value = _element.defaultValue;\n" .
+ " }\n" .
+ " }\n" .
+ " }\n";
+ }
+
+ } elseif ($element->getType() == 'select') {
+ if ($element->getMultiple()) {
+ $elementName .= '[]';
+ $value =
+ " value{$jsIndex} = new Array();\n" .
+ " var valueIdx = 0;\n" .
+ " for (var i = 0; i < frm.elements['{$elementName}'].options.length; i++) {\n" .
+ " if (frm.elements['{$elementName}'].options[i].selected) {\n" .
+ " value{$jsIndex}[valueIdx++] = frm.elements['{$elementName}'].options[i].value;\n" .
+ " }\n" .
+ " }\n";
+ } else {
+ $value = " value{$jsIndex} = frm.elements['{$elementName}'].selectedIndex == -1? '': frm.elements['{$elementName}'].options[frm.elements['{$elementName}'].selectedIndex].value;\n";
+ }
+ if ($reset) {
+ $tmp_reset .=
+ " for (var i = 0; i < field.options.length; i++) {\n" .
+ " field.options[i].selected = field.options[i].defaultSelected;\n" .
+ " }\n";
+ }
+
+ } elseif ($element->getType() == 'checkbox') {
+ if (is_a($element, 'html_quickform_advcheckbox')) {
+ $value = " value{$jsIndex} = frm.elements['$elementName'][1].checked? frm.elements['$elementName'][1].value: frm.elements['$elementName'][0].value;\n";
+ $tmp_reset .= $reset ? " field[1].checked = field[1].defaultChecked;\n" : '';
+ } else {
+ $value = " value{$jsIndex} = frm.elements['$elementName'].checked? '1': '';\n";
+ $tmp_reset .= $reset ? " field.checked = field.defaultChecked;\n" : '';
+ }
+
+ } elseif ($element->getType() == 'radio') {
+ $value = " value{$jsIndex} = '';\n" .
+ // Fix for bug #5644
+ " var els = 'length' in frm.elements['$elementName']? frm.elements['$elementName']: [ frm.elements['$elementName'] ];\n" .
+ " for (var i = 0; i < els.length; i++) {\n" .
+ " if (els[i].checked) {\n" .
+ " value{$jsIndex} = els[i].value;\n" .
+ " }\n" .
+ " }";
+ if ($reset) {
+ $tmp_reset .= " for (var i = 0; i < field.length; i++) {\n" .
+ " field[i].checked = field[i].defaultChecked;\n" .
+ " }";
+ }
+
+ } else {
+ $value = " value{$jsIndex} = frm.elements['$elementName'].value;";
+ $tmp_reset .= ($reset) ? " field.value = field.defaultValue;\n" : '';
+ }
+ return array($value, $tmp_reset);
+ }
+} // end class HTML_QuickForm_RuleRegistry
+?>
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP version 4.0 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> |
+// | Bertrand Mansion <bmansion@mamasam.com> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+require_once('HTML/QuickForm/checkbox.php');
+
+/**
+ * HTML class for an advanced checkbox type field
+ *
+ * Basically this fixes a problem that HTML has had
+ * where checkboxes can only pass a single value (the
+ * value of the checkbox when checked). A value for when
+ * the checkbox is not checked cannot be passed, and
+ * furthermore the checkbox variable doesn't even exist if
+ * the checkbox was submitted unchecked.
+ *
+ * It works by prepending a hidden field with the same name and
+ * another "unchecked" value to the checbox. If the checkbox is
+ * checked, PHP overwrites the value of the hidden field with
+ * its value.
+ *
+ * @author Jason Rust <jrust@php.net>
+ * @since 2.0
+ * @access public
+ */
+class HTML_QuickForm_advcheckbox extends HTML_QuickForm_checkbox
+{
+ // {{{ properties
+
+ /**
+ * The values passed by the hidden elment
+ *
+ * @var array
+ * @access private
+ */
+ var $_values = null;
+
+ /**
+ * The default value
+ *
+ * @var boolean
+ * @access private
+ */
+ var $_currentValue = null;
+
+ // }}}
+ // {{{ constructor
+
+ /**
+ * Class constructor
+ *
+ * @param string $elementName (optional)Input field name attribute
+ * @param string $elementLabel (optional)Input field label
+ * @param string $text (optional)Text to put after the checkbox
+ * @param mixed $attributes (optional)Either a typical HTML attribute string
+ * or an associative array
+ * @param mixed $values (optional)Values to pass if checked or not checked
+ *
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function HTML_QuickForm_advcheckbox($elementName=null, $elementLabel=null, $text=null, $attributes=null, $values=null)
+ {
+ $this->HTML_QuickForm_checkbox($elementName, $elementLabel, $text, $attributes);
+ $this->setValues($values);
+ } //end constructor
+
+ // }}}
+ // {{{ getPrivateName()
+
+ /**
+ * Gets the private name for the element
+ *
+ * @param string $elementName The element name to make private
+ *
+ * @access public
+ * @return string
+ *
+ * @deprecated Deprecated since 3.2.6, both generated elements have the same name
+ */
+ function getPrivateName($elementName)
+ {
+ return '__'.$elementName;
+ }
+
+ // }}}
+ // {{{ getOnclickJs()
+
+ /**
+ * Create the javascript for the onclick event which will
+ * set the value of the hidden field
+ *
+ * @param string $elementName The element name
+ *
+ * @access public
+ * @return string
+ *
+ * @deprecated Deprecated since 3.2.6, this element no longer uses any javascript
+ */
+ function getOnclickJs($elementName)
+ {
+ $onclickJs = 'if (this.checked) { this.form[\''.$elementName.'\'].value=\''.addcslashes($this->_values[1], '\'').'\'; }';
+ $onclickJs .= 'else { this.form[\''.$elementName.'\'].value=\''.addcslashes($this->_values[0], '\'').'\'; }';
+ return $onclickJs;
+ }
+
+ // }}}
+ // {{{ setValues()
+
+ /**
+ * Sets the values used by the hidden element
+ *
+ * @param mixed $values The values, either a string or an array
+ *
+ * @access public
+ * @return void
+ */
+ function setValues($values)
+ {
+ if (empty($values)) {
+ // give it default checkbox behavior
+ $this->_values = array('', 1);
+ } elseif (is_scalar($values)) {
+ // if it's string, then assume the value to
+ // be passed is for when the element is checked
+ $this->_values = array('', $values);
+ } else {
+ $this->_values = $values;
+ }
+ $this->updateAttributes(array('value' => $this->_values[1]));
+ $this->setChecked($this->_currentValue == $this->_values[1]);
+ }
+
+ // }}}
+ // {{{ setValue()
+
+ /**
+ * Sets the element's value
+ *
+ * @param mixed Element's value
+ * @access public
+ */
+ function setValue($value)
+ {
+ $this->setChecked(isset($this->_values[1]) && $value == $this->_values[1]);
+ $this->_currentValue = $value;
+ }
+
+ // }}}
+ // {{{ getValue()
+
+ /**
+ * Returns the element's value
+ *
+ * @access public
+ * @return mixed
+ */
+ function getValue()
+ {
+ if (is_array($this->_values)) {
+ return $this->_values[$this->getChecked()? 1: 0];
+ } else {
+ return null;
+ }
+ }
+
+ // }}}
+ // {{{ toHtml()
+
+ /**
+ * Returns the checkbox element in HTML
+ * and the additional hidden element in HTML
+ *
+ * @access public
+ * @return string
+ */
+ function toHtml()
+ {
+ if ($this->_flagFrozen) {
+ return parent::toHtml();
+ } else {
+ return '<input' . $this->_getAttrString(array(
+ 'type' => 'hidden',
+ 'name' => $this->getName(),
+ 'value' => $this->_values[0]
+ )) . ' />' . parent::toHtml();
+
+ }
+ } //end func toHtml
+
+ // }}}
+ // {{{ getFrozenHtml()
+
+ /**
+ * Unlike checkbox, this has to append a hidden input in both
+ * checked and non-checked states
+ */
+ function getFrozenHtml()
+ {
+ return ($this->getChecked()? '<tt>[x]</tt>': '<tt>[ ]</tt>') .
+ $this->_getPersistantData();
+ }
+
+ // }}}
+ // {{{ onQuickFormEvent()
+
+ /**
+ * Called by HTML_QuickForm whenever form event is made on this element
+ *
+ * @param string $event Name of event
+ * @param mixed $arg event arguments
+ * @param object $caller calling object
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function onQuickFormEvent($event, $arg, &$caller)
+ {
+ switch ($event) {
+ case 'updateValue':
+ // constant values override both default and submitted ones
+ // default values are overriden by submitted
+ $value = $this->_findValue($caller->_constantValues);
+ if (null === $value) {
+ $value = $this->_findValue($caller->_submitValues);
+ if (null === $value) {
+ $value = $this->_findValue($caller->_defaultValues);
+ }
+ }
+ if (null !== $value) {
+ $this->setValue($value);
+ }
+ break;
+ default:
+ parent::onQuickFormEvent($event, $arg, $caller);
+ }
+ return true;
+ } // end func onQuickFormLoad
+
+ // }}}
+ // {{{ exportValue()
+
+ /**
+ * This element has a value even if it is not checked, thus we override
+ * checkbox's behaviour here
+ */
+ function exportValue(&$submitValues, $assoc)
+ {
+ $value = $this->_findValue($submitValues);
+ if (null === $value) {
+ $value = $this->getValue();
+ } elseif (is_array($this->_values) && ($value != $this->_values[0]) && ($value != $this->_values[1])) {
+ $value = null;
+ }
+ return $this->_prepareValue($value, $assoc);
+ }
+ // }}}
+} //end class HTML_QuickForm_advcheckbox
+?>
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP Version 4 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2003 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Author: Matteo Di Giovinazzo <matteodg@infinito.it> |
+// | |
+// | For the JavaScript code thanks to Martin Honnen and |
+// | Nicholas C. Zakas |
+// | See: |
+// | http://www.faqts.com/knowledge_base/view.phtml/aid/13562 |
+// | and |
+// | http://www.sitepoint.com/article/1220 |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+
+require_once("HTML/QuickForm/text.php");
+
+
+/**
+ * Class to dynamically create an HTML input text element that
+ * at every keypressed javascript event, check in an array of options
+ * if there's a match and autocomplete the text in case of match.
+ *
+ * Ex:
+ * $autocomplete =& $form->addElement('autocomplete', 'fruit', 'Favourite fruit:');
+ * $options = array("Apple", "Orange", "Pear", "Strawberry");
+ * $autocomplete->setOptions($options);
+ *
+ * @author Matteo Di Giovinazzo <matteodg@infinito.it>
+ */
+class HTML_QuickForm_autocomplete extends HTML_QuickForm_text
+{
+ // {{{ properties
+
+ /**
+ * Options for the autocomplete input text element
+ *
+ * @var array
+ * @access private
+ */
+ var $_options = array();
+
+ /**
+ * "One-time" javascript (containing functions), see bug #4611
+ *
+ * @var string
+ * @access private
+ */
+ var $_js = '';
+
+ // }}}
+ // {{{ constructor
+
+ /**
+ * Class constructor
+ *
+ * @param string $elementName (optional)Input field name attribute
+ * @param string $elementLabel (optional)Input field label in form
+ * @param array $options (optional)Autocomplete options
+ * @param mixed $attributes (optional)Either a typical HTML attribute string
+ * or an associative array. Date format is passed along the attributes.
+ * @access public
+ * @return void
+ */
+ function HTML_QuickForm_autocomplete($elementName = null, $elementLabel = null, $options = null, $attributes = null)
+ {
+ $this->HTML_QuickForm_text($elementName, $elementLabel, $attributes);
+ $this->_persistantFreeze = true;
+ $this->_type = 'autocomplete';
+ if (isset($options)) {
+ $this->setOptions($options);
+ }
+ } //end constructor
+
+ // }}}
+ // {{{ setOptions()
+
+ /**
+ * Sets the options for the autocomplete input text element
+ *
+ * @param array $options Array of options for the autocomplete input text element
+ * @access public
+ * @return void
+ */
+ function setOptions($options)
+ {
+ $this->_options = array_values($options);
+ } // end func setOptions
+
+ // }}}
+ // {{{ toHtml()
+
+ /**
+ * Returns Html for the autocomplete input text element
+ *
+ * @access public
+ * @return string
+ */
+ function toHtml()
+ {
+ // prevent problems with grouped elements
+ $arrayName = str_replace(array('[', ']'), array('__', ''), $this->getName()) . '_values';
+
+ $this->updateAttributes(array(
+ 'onkeypress' => 'return autocomplete(this, event, ' . $arrayName . ');'
+ ));
+ if ($this->_flagFrozen) {
+ $js = '';
+ } else {
+ $js = "<script type=\"text/javascript\">\n//<![CDATA[\n";
+ if (!defined('HTML_QUICKFORM_AUTOCOMPLETE_EXISTS')) {
+ $this->_js .= <<<EOS
+
+/* begin javascript for autocomplete */
+function setSelectionRange(input, selectionStart, selectionEnd) {
+ if (input.setSelectionRange) {
+ input.setSelectionRange(selectionStart, selectionEnd);
+ }
+ else if (input.createTextRange) {
+ var range = input.createTextRange();
+ range.collapse(true);
+ range.moveEnd("character", selectionEnd);
+ range.moveStart("character", selectionStart);
+ range.select();
+ }
+ input.focus();
+}
+
+function setCaretToPosition(input, position) {
+ setSelectionRange(input, position, position);
+}
+
+function replaceSelection (input, replaceString) {
+ var len = replaceString.length;
+ if (input.setSelectionRange) {
+ var selectionStart = input.selectionStart;
+ var selectionEnd = input.selectionEnd;
+
+ input.value = input.value.substring(0, selectionStart) + replaceString + input.value.substring(selectionEnd);
+ input.selectionStart = selectionStart + len;
+ input.selectionEnd = selectionStart + len;
+ }
+ else if (document.selection) {
+ var range = document.selection.createRange();
+ var saved_range = range.duplicate();
+
+ if (range.parentElement() == input) {
+ range.text = replaceString;
+ range.moveEnd("character", saved_range.selectionStart + len);
+ range.moveStart("character", saved_range.selectionStart + len);
+ range.select();
+ }
+ }
+ input.focus();
+}
+
+
+function autocompleteMatch (text, values) {
+ for (var i = 0; i < values.length; i++) {
+ if (values[i].toUpperCase().indexOf(text.toUpperCase()) == 0) {
+ return values[i];
+ }
+ }
+
+ return null;
+}
+
+function autocomplete(textbox, event, values) {
+ if (textbox.setSelectionRange || textbox.createTextRange) {
+ switch (event.keyCode) {
+ case 38: // up arrow
+ case 40: // down arrow
+ case 37: // left arrow
+ case 39: // right arrow
+ case 33: // page up
+ case 34: // page down
+ case 36: // home
+ case 35: // end
+ case 13: // enter
+ case 9: // tab
+ case 27: // esc
+ case 16: // shift
+ case 17: // ctrl
+ case 18: // alt
+ case 20: // caps lock
+ case 8: // backspace
+ case 46: // delete
+ return true;
+ break;
+
+ default:
+ var c = String.fromCharCode(
+ (event.charCode == undefined) ? event.keyCode : event.charCode
+ );
+ replaceSelection(textbox, c);
+ sMatch = autocompleteMatch(textbox.value, values);
+ var len = textbox.value.length;
+
+ if (sMatch != null) {
+ textbox.value = sMatch;
+ setSelectionRange(textbox, len, textbox.value.length);
+ }
+ return false;
+ }
+ }
+ else {
+ return true;
+ }
+}
+/* end javascript for autocomplete */
+
+EOS;
+ define('HTML_QUICKFORM_AUTOCOMPLETE_EXISTS', true);
+ }
+ $jsEscape = array(
+ "\r" => '\r',
+ "\n" => '\n',
+ "\t" => '\t',
+ "'" => "\\'",
+ '"' => '\"',
+ '\\' => '\\\\'
+ );
+
+ $js .= $this->_js;
+ $js .= 'var ' . $arrayName . " = new Array();\n";
+ for ($i = 0; $i < count($this->_options); $i++) {
+ $js .= $arrayName . '[' . $i . "] = '" . strtr($this->_options[$i], $jsEscape) . "';\n";
+ }
+ $js .= "//]]>\n</script>";
+ }
+ return $js . parent::toHtml();
+ }// end func toHtml
+
+ // }}}
+} // end class HTML_QuickForm_autocomplete
+?>
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP version 4.0 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> |
+// | Bertrand Mansion <bmansion@mamasam.com> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+require_once("HTML/QuickForm/input.php");
+
+/**
+ * HTML class for a button type element
+ *
+ * @author Adam Daniel <adaniel1@eesus.jnj.com>
+ * @author Bertrand Mansion <bmansion@mamasam.com>
+ * @version 1.1
+ * @since PHP4.04pl1
+ * @access public
+ */
+class HTML_QuickForm_button extends HTML_QuickForm_input
+{
+ // {{{ constructor
+
+ /**
+ * Class constructor
+ *
+ * @param string $elementName (optional)Input field name attribute
+ * @param string $value (optional)Input field value
+ * @param mixed $attributes (optional)Either a typical HTML attribute string
+ * or an associative array
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function HTML_QuickForm_button($elementName=null, $value=null, $attributes=null)
+ {
+ HTML_QuickForm_input::HTML_QuickForm_input($elementName, null, $attributes);
+ $this->_persistantFreeze = false;
+ $this->setValue($value);
+ $this->setType('button');
+ } //end constructor
+
+ // }}}
+ // {{{ freeze()
+
+ /**
+ * Freeze the element so that only its value is returned
+ *
+ * @access public
+ * @return void
+ */
+ function freeze()
+ {
+ return false;
+ } //end func freeze
+
+ // }}}
+
+} //end class HTML_QuickForm_button
+?>
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP version 4.0 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> |
+// | Bertrand Mansion <bmansion@mamasam.com> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+require_once("HTML/QuickForm/input.php");
+
+/**
+ * HTML class for a checkbox type field
+ *
+ * @author Adam Daniel <adaniel1@eesus.jnj.com>
+ * @author Bertrand Mansion <bmansion@mamasam.com>
+ * @version 1.1
+ * @since PHP4.04pl1
+ * @access public
+ */
+class HTML_QuickForm_checkbox extends HTML_QuickForm_input
+{
+ // {{{ properties
+
+ /**
+ * Checkbox display text
+ * @var string
+ * @since 1.1
+ * @access private
+ */
+ var $_text = '';
+
+ // }}}
+ // {{{ constructor
+
+ /**
+ * Class constructor
+ *
+ * @param string $elementName (optional)Input field name attribute
+ * @param string $elementLabel (optional)Input field value
+ * @param string $text (optional)Checkbox display text
+ * @param mixed $attributes (optional)Either a typical HTML attribute string
+ * or an associative array
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function HTML_QuickForm_checkbox($elementName=null, $elementLabel=null, $text='', $attributes=null)
+ {
+ HTML_QuickForm_input::HTML_QuickForm_input($elementName, $elementLabel, $attributes);
+ $this->_persistantFreeze = true;
+ $this->_text = $text;
+ $this->setType('checkbox');
+ $this->updateAttributes(array('value'=>1));
+ $this->_generateId();
+ } //end constructor
+
+ // }}}
+ // {{{ setChecked()
+
+ /**
+ * Sets whether a checkbox is checked
+ *
+ * @param bool $checked Whether the field is checked or not
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function setChecked($checked)
+ {
+ if (!$checked) {
+ $this->removeAttribute('checked');
+ } else {
+ $this->updateAttributes(array('checked'=>'checked'));
+ }
+ } //end func setChecked
+
+ // }}}
+ // {{{ getChecked()
+
+ /**
+ * Returns whether a checkbox is checked
+ *
+ * @since 1.0
+ * @access public
+ * @return bool
+ */
+ function getChecked()
+ {
+ return (bool)$this->getAttribute('checked');
+ } //end func getChecked
+
+ // }}}
+ // {{{ toHtml()
+
+ /**
+ * Returns the checkbox element in HTML
+ *
+ * @since 1.0
+ * @access public
+ * @return string
+ */
+ function toHtml()
+ {
+ if (0 == strlen($this->_text)) {
+ $label = '';
+ } elseif ($this->_flagFrozen) {
+ $label = $this->_text;
+ } else {
+ $label = '<label for="' . $this->getAttribute('id') . '">' . $this->_text . '</label>';
+ }
+ return HTML_QuickForm_input::toHtml() . $label;
+ } //end func toHtml
+
+ // }}}
+ // {{{ getFrozenHtml()
+
+ /**
+ * Returns the value of field without HTML tags
+ *
+ * @since 1.0
+ * @access public
+ * @return string
+ */
+ function getFrozenHtml()
+ {
+ if ($this->getChecked()) {
+ return '<tt>[x]</tt>' .
+ $this->_getPersistantData();
+ } else {
+ return '<tt>[ ]</tt>';
+ }
+ } //end func getFrozenHtml
+
+ // }}}
+ // {{{ setText()
+
+ /**
+ * Sets the checkbox text
+ *
+ * @param string $text
+ * @since 1.1
+ * @access public
+ * @return void
+ */
+ function setText($text)
+ {
+ $this->_text = $text;
+ } //end func setText
+
+ // }}}
+ // {{{ getText()
+
+ /**
+ * Returns the checkbox text
+ *
+ * @since 1.1
+ * @access public
+ * @return string
+ */
+ function getText()
+ {
+ return $this->_text;
+ } //end func getText
+
+ // }}}
+ // {{{ setValue()
+
+ /**
+ * Sets the value of the form element
+ *
+ * @param string $value Default value of the form element
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function setValue($value)
+ {
+ return $this->setChecked($value);
+ } // end func setValue
+
+ // }}}
+ // {{{ getValue()
+
+ /**
+ * Returns the value of the form element
+ *
+ * @since 1.0
+ * @access public
+ * @return bool
+ */
+ function getValue()
+ {
+ return $this->getChecked();
+ } // end func getValue
+
+ // }}}
+ // {{{ onQuickFormEvent()
+
+ /**
+ * Called by HTML_QuickForm whenever form event is made on this element
+ *
+ * @param string $event Name of event
+ * @param mixed $arg event arguments
+ * @param object $caller calling object
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function onQuickFormEvent($event, $arg, &$caller)
+ {
+ switch ($event) {
+ case 'updateValue':
+ // constant values override both default and submitted ones
+ // default values are overriden by submitted
+ $value = $this->_findValue($caller->_constantValues);
+ if (null === $value) {
+ // if no boxes were checked, then there is no value in the array
+ // yet we don't want to display default value in this case
+ if ($caller->isSubmitted()) {
+ $value = $this->_findValue($caller->_submitValues);
+ } else {
+ $value = $this->_findValue($caller->_defaultValues);
+ }
+ }
+ if (null !== $value) {
+ $this->setChecked($value);
+ }
+ break;
+ case 'setGroupValue':
+ $this->setChecked($arg);
+ break;
+ default:
+ parent::onQuickFormEvent($event, $arg, $caller);
+ }
+ return true;
+ } // end func onQuickFormEvent
+
+ // }}}
+ // {{{ exportValue()
+
+ /**
+ * Return true if the checkbox is checked, null if it is not checked (getValue() returns false)
+ */
+ function exportValue(&$submitValues, $assoc = false)
+ {
+ $value = $this->_findValue($submitValues);
+ if (null === $value) {
+ $value = $this->getChecked()? true: null;
+ }
+ return $this->_prepareValue($value, $assoc);
+ }
+
+ // }}}
+} //end class HTML_QuickForm_checkbox
+?>
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP Version 4 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2003 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Alexey Borzov <avb@php.net> |
+// | Adam Daniel <adaniel1@eesus.jnj.com> |
+// | Bertrand Mansion <bmansion@mamasam.com> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+require_once 'HTML/QuickForm/group.php';
+require_once 'HTML/QuickForm/select.php';
+
+/**
+ * Class for a group of elements used to input dates (and times).
+ *
+ * Inspired by original 'date' element but reimplemented as a subclass
+ * of HTML_QuickForm_group
+ *
+ * @author Alexey Borzov <avb@php.net>
+ * @access public
+ */
+class HTML_QuickForm_date extends HTML_QuickForm_group
+{
+ // {{{ properties
+
+ /**
+ * Various options to control the element's display.
+ *
+ * Currently known options are
+ * 'language': date language
+ * 'format': Format of the date, based on PHP's date() function.
+ * The following characters are recognised in format string:
+ * D => Short names of days
+ * l => Long names of days
+ * d => Day numbers
+ * M => Short names of months
+ * F => Long names of months
+ * m => Month numbers
+ * Y => Four digit year
+ * y => Two digit year
+ * h => 12 hour format
+ * H => 23 hour format
+ * i => Minutes
+ * s => Seconds
+ * a => am/pm
+ * A => AM/PM
+ * 'minYear': Minimum year in year select
+ * 'maxYear': Maximum year in year select
+ * 'addEmptyOption': Should an empty option be added to the top of
+ * each select box?
+ * 'emptyOptionValue': The value passed by the empty option.
+ * 'emptyOptionText': The text displayed for the empty option.
+ * 'optionIncrement': Step to increase the option values by (works for 'i' and 's')
+ *
+ * @access private
+ * @var array
+ */
+ var $_options = array(
+ 'language' => 'en',
+ 'format' => 'dMY',
+ 'minYear' => 2001,
+ 'maxYear' => 2010,
+ 'addEmptyOption' => false,
+ 'emptyOptionValue' => '',
+ 'emptyOptionText' => ' ',
+ 'optionIncrement' => array('i' => 1, 's' => 1)
+ );
+
+ /**
+ * These complement separators, they are appended to the resultant HTML
+ * @access private
+ * @var array
+ */
+ var $_wrap = array('', '');
+
+ /**
+ * Options in different languages
+ *
+ * Note to potential translators: to avoid encoding problems please send
+ * your translations with "weird" letters encoded as HTML Unicode entities
+ *
+ * @access private
+ * @var array
+ */
+ var $_locale = array(
+ 'en' => array (
+ 'weekdays_short'=> array ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'),
+ 'weekdays_long' => array ('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'),
+ 'months_short' => array ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'),
+ 'months_long' => array ('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December')
+ ),
+ 'de' => array (
+ 'weekdays_short'=> array ('So', 'Mon', 'Di', 'Mi', 'Do', 'Fr', 'Sa'),
+ 'weekdays_long' => array ('Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'),
+ 'months_short' => array ('Jan', 'Feb', 'März', 'April', 'Mai', 'Juni', 'Juli', 'Aug', 'Sept', 'Okt', 'Nov', 'Dez'),
+ 'months_long' => array ('Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember')
+ ),
+ 'fr' => array (
+ 'weekdays_short'=> array ('Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam'),
+ 'weekdays_long' => array ('Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi'),
+ 'months_short' => array ('Jan', 'Fév', 'Mar', 'Avr', 'Mai', 'Juin', 'Juil', 'Août', 'Sep', 'Oct', 'Nov', 'Déc'),
+ 'months_long' => array ('Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre')
+ ),
+ 'hu' => array (
+ 'weekdays_short'=> array ('V', 'H', 'K', 'Sze', 'Cs', 'P', 'Szo'),
+ 'weekdays_long' => array ('vasárnap', 'hétfő', 'kedd', 'szerda', 'csütörtök', 'péntek', 'szombat'),
+ 'months_short' => array ('jan', 'feb', 'márc', 'ápr', 'máj', 'jún', 'júl', 'aug', 'szept', 'okt', 'nov', 'dec'),
+ 'months_long' => array ('január', 'február', 'március', 'április', 'május', 'június', 'július', 'augusztus', 'szeptember', 'október', 'november', 'december')
+ ),
+ 'pl' => array (
+ 'weekdays_short'=> array ('Nie', 'Pn', 'Wt', 'Śr', 'Czw', 'Pt', 'Sob'),
+ 'weekdays_long' => array ('Niedziela', 'Poniedziałek', 'Wtorek', 'Środa', 'Czwartek', 'Piątek', 'Sobota'),
+ 'months_short' => array ('Sty', 'Lut', 'Mar', 'Kwi', 'Maj', 'Cze', 'Lip', 'Sie', 'Wrz', 'Paź', 'Lis', 'Gru'),
+ 'months_long' => array ('Styczeń', 'Luty', 'Marzec', 'Kwiecień', 'Maj', 'Czerwiec', 'Lipiec', 'Sierpień', 'Wrzesień', 'Październik', 'Listopad', 'Grudzień')
+ ),
+ 'sl' => array (
+ 'weekdays_short'=> array ('Ned', 'Pon', 'Tor', 'Sre', 'Cet', 'Pet', 'Sob'),
+ 'weekdays_long' => array ('Nedelja', 'Ponedeljek', 'Torek', 'Sreda', 'Cetrtek', 'Petek', 'Sobota'),
+ 'months_short' => array ('Jan', 'Feb', 'Mar', 'Apr', 'Maj', 'Jun', 'Jul', 'Avg', 'Sep', 'Okt', 'Nov', 'Dec'),
+ 'months_long' => array ('Januar', 'Februar', 'Marec', 'April', 'Maj', 'Junij', 'Julij', 'Avgust', 'September', 'Oktober', 'November', 'December')
+ ),
+ 'ru' => array (
+ 'weekdays_short'=> array ('Вс', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб'),
+ 'weekdays_long' => array ('Воскресенье', 'Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота'),
+ 'months_short' => array ('Янв', 'Фев', 'Мар', 'Апр', 'Май', 'Июн', 'Июл', 'Авг', 'Сен', 'Окт', 'Ноя', 'Дек'),
+ 'months_long' => array ('Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь')
+ ),
+ 'es' => array (
+ 'weekdays_short'=> array ('Dom', 'Lun', 'Mar', 'Mié', 'Jue', 'Vie', 'Sáb'),
+ 'weekdays_long' => array ('Domingo', 'Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado'),
+ 'months_short' => array ('Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic'),
+ 'months_long' => array ('Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre')
+ ),
+ 'da' => array (
+ 'weekdays_short'=> array ('Søn', 'Man', 'Tir', 'Ons', 'Tor', 'Fre', 'Lør'),
+ 'weekdays_long' => array ('Søndag', 'Mandag', 'Tirsdag', 'Onsdag', 'Torsdag', 'Fredag', 'Lørdag'),
+ 'months_short' => array ('Jan', 'Feb', 'Mar', 'Apr', 'Maj', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec'),
+ 'months_long' => array ('Januar', 'Februar', 'Marts', 'April', 'Maj', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'December')
+ ),
+ 'is' => array (
+ 'weekdays_short'=> array ('Sun', 'Mán', 'Þri', 'Mið', 'Fim', 'Fös', 'Lau'),
+ 'weekdays_long' => array ('Sunnudagur', 'Mánudagur', 'Þriðjudagur', 'Miðvikudagur', 'Fimmtudagur', 'Föstudagur', 'Laugardagur'),
+ 'months_short' => array ('Jan', 'Feb', 'Mar', 'Apr', 'Maí', 'Jún', 'Júl', 'Ágú', 'Sep', 'Okt', 'Nóv', 'Des'),
+ 'months_long' => array ('Janúar', 'Febrúar', 'Mars', 'Apríl', 'Maí', 'Júní', 'Júlí', 'Ágúst', 'September', 'Október', 'Nóvember', 'Desember')
+ ),
+ 'it' => array (
+ 'weekdays_short'=> array ('Dom', 'Lun', 'Mar', 'Mer', 'Gio', 'Ven', 'Sab'),
+ 'weekdays_long' => array ('Domenica', 'Lunedì', 'Martedì', 'Mercoledì', 'Giovedì', 'Venerdì', 'Sabato'),
+ 'months_short' => array ('Gen', 'Feb', 'Mar', 'Apr', 'Mag', 'Giu', 'Lug', 'Ago', 'Set', 'Ott', 'Nov', 'Dic'),
+ 'months_long' => array ('Gennaio', 'Febbraio', 'Marzo', 'Aprile', 'Maggio', 'Giugno', 'Luglio', 'Agosto', 'Settembre', 'Ottobre', 'Novembre', 'Dicembre')
+ ),
+ 'sk' => array (
+ 'weekdays_short'=> array ('Ned', 'Pon', 'Uto', 'Str', 'Štv', 'Pia', 'Sob'),
+ 'weekdays_long' => array ('Nedeža', 'Pondelok', 'Utorok', 'Streda', 'Štvrtok', 'Piatok', 'Sobota'),
+ 'months_short' => array ('Jan', 'Feb', 'Mar', 'Apr', 'Máj', 'Jún', 'Júl', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec'),
+ 'months_long' => array ('Január', 'Február', 'Marec', 'Apríl', 'Máj', 'Jún', 'Júl', 'August', 'September', 'Október', 'November', 'December')
+ ),
+ 'cs' => array (
+ 'weekdays_short'=> array ('Ne', 'Po', 'Út', 'St', 'Čt', 'Pá', 'So'),
+ 'weekdays_long' => array ('Neděle', 'Pondělí', 'Úterý', 'Středa', 'Čtvrtek', 'Pátek', 'Sobota'),
+ 'months_short' => array ('Led', 'Úno', 'Bře', 'Dub', 'Kvě', 'Čen', 'Čec', 'Srp', 'Zář', 'Říj', 'Lis', 'Pro'),
+ 'months_long' => array ('Leden', 'Únor', 'Březen', 'Duben', 'Květen', 'Červen', 'Červenec', 'Srpen', 'Září', 'Říjen', 'Listopad', 'Prosinec')
+ ),
+ 'hy' => array (
+ 'weekdays_short'=> array ('Կրկ', 'Երկ', 'Երք', 'Չրք', 'Հնգ', 'Ուր', 'Շբթ'),
+ 'weekdays_long' => array ('Կիրակի', 'Երկուշաբթի', 'Երեքշաբթի', 'Չորեքշաբթի', 'Հինգշաբթի', 'Ուրբաթ', 'Շաբաթ'),
+ 'months_short' => array ('Հնվ', 'Փտր', 'Մրտ', 'Ապր', 'Մյս', 'Հնս', 'Հլս', 'Օգս', 'Սպտ', 'Հկտ', 'Նյմ', 'Դկտ'),
+ 'months_long' => array ('Հունվար', 'Փետրվար', 'Մարտ', 'Ապրիլ', 'Մայիս', 'Հունիս', 'Հուլիս', 'Օգոստոս', 'Սեպտեմբեր', 'Հոկտեմբեր', 'Նոյեմբեր', 'Դեկտեմբեր')
+ ),
+ 'nl' => array (
+ 'weekdays_short'=> array ('Zo', 'Ma', 'Di', 'Wo', 'Do', 'Vr', 'Za'),
+ 'weekdays_long' => array ('Zondag', 'Maandag', 'Dinsdag', 'Woensdag', 'Donderdag', 'Vrijdag', 'Zaterdag'),
+ 'months_short' => array ('Jan', 'Feb', 'Mar', 'Apr', 'Mei', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec'),
+ 'months_long' => array ('Januari', 'Februari', 'Maart', 'April', 'Mei', 'Juni', 'Juli', 'Augustus', 'September', 'Oktober', 'November', 'December')
+ ),
+ 'et' => array (
+ 'weekdays_short'=> array ('P', 'E', 'T', 'K', 'N', 'R', 'L'),
+ 'weekdays_long' => array ('Pühapäev', 'Esmaspäev', 'Teisipäev', 'Kolmapäev', 'Neljapäev', 'Reede', 'Laupäev'),
+ 'months_short' => array ('Jaan', 'Veebr', 'Märts', 'Aprill', 'Mai', 'Juuni', 'Juuli', 'Aug', 'Sept', 'Okt', 'Nov', 'Dets'),
+ 'months_long' => array ('Jaanuar', 'Veebruar', 'Märts', 'Aprill', 'Mai', 'Juuni', 'Juuli', 'August', 'September', 'Oktoober', 'November', 'Detsember')
+ ),
+ 'tr' => array (
+ 'weekdays_short'=> array ('Paz', 'Pzt', 'Sal', 'Çar', 'Per', 'Cum', 'Cts'),
+ 'weekdays_long' => array ('Pazar', 'Pazartesi', 'Salı', 'Çarşamba', 'Perşembe', 'Cuma', 'Cumartesi'),
+ 'months_short' => array ('Ock', 'Şbt', 'Mrt', 'Nsn', 'Mys', 'Hzrn', 'Tmmz', 'Ağst', 'Eyl', 'Ekm', 'Ksm', 'Arlk'),
+ 'months_long' => array ('Ocak', 'Şubat', 'Mart', 'Nisan', 'Mayıs', 'Haziran', 'Temmuz', 'Ağustos', 'Eylül', 'Ekim', 'Kasım', 'Aralık')
+ ),
+ 'no' => array (
+ 'weekdays_short'=> array ('Søn', 'Man', 'Tir', 'Ons', 'Tor', 'Fre', 'Lør'),
+ 'weekdays_long' => array ('Søndag', 'Mandag', 'Tirsdag', 'Onsdag', 'Torsdag', 'Fredag', 'Lørdag'),
+ 'months_short' => array ('Jan', 'Feb', 'Mar', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Des'),
+ 'months_long' => array ('Januar', 'Februar', 'Mars', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Desember')
+ ),
+ 'eo' => array (
+ 'weekdays_short'=> array ('Dim', 'Lun', 'Mar', 'Mer', 'Ĵaŭ', 'Ven', 'Sab'),
+ 'weekdays_long' => array ('Dimanĉo', 'Lundo', 'Mardo', 'Merkredo', 'Ĵaŭdo', 'Vendredo', 'Sabato'),
+ 'months_short' => array ('Jan', 'Feb', 'Mar', 'Apr', 'Maj', 'Jun', 'Jul', 'Aŭg', 'Sep', 'Okt', 'Nov', 'Dec'),
+ 'months_long' => array ('Januaro', 'Februaro', 'Marto', 'Aprilo', 'Majo', 'Junio', 'Julio', 'Aŭgusto', 'Septembro', 'Oktobro', 'Novembro', 'Decembro')
+ ),
+ 'ua' => array (
+ 'weekdays_short'=> array('Ндл', 'Пнд', 'Втр', 'Срд', 'Чтв', 'Птн', 'Сбт'),
+ 'weekdays_long' => array('Неділя', 'Понеділок', 'Вівторок', 'Середа', 'Четвер', 'П\'ятниця', 'Субота'),
+ 'months_short' => array('Січ', 'Лют', 'Бер', 'Кві', 'Тра', 'Чер', 'Лип', 'Сер', 'Вер', 'Жов', 'Лис', 'Гру'),
+ 'months_long' => array('Січень', 'Лютий', 'Березень', 'Квітень', 'Травень', 'Червень', 'Липень', 'Серпень', 'Вересень', 'Жовтень', 'Листопад', 'Грудень')
+ ),
+ 'ro' => array (
+ 'weekdays_short'=> array ('Dum', 'Lun', 'Mar', 'Mie', 'Joi', 'Vin', 'Sam'),
+ 'weekdays_long' => array ('Duminica', 'Luni', 'Marti', 'Miercuri', 'Joi', 'Vineri', 'Sambata'),
+ 'months_short' => array ('Ian', 'Feb', 'Mar', 'Apr', 'Mai', 'Iun', 'Iul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'),
+ 'months_long' => array ('Ianuarie', 'Februarie', 'Martie', 'Aprilie', 'Mai', 'Iunie', 'Iulie', 'August', 'Septembrie', 'Octombrie', 'Noiembrie', 'Decembrie')
+ ),
+ 'he' => array (
+ 'weekdays_short'=> array ('ראשון', 'שני', 'שלישי', 'רביעי', 'חמישי', 'שישי', 'שבת'),
+ 'weekdays_long' => array ('יום ראשון', 'יום שני', 'יום שלישי', 'יום רביעי', 'יום חמישי', 'יום שישי', 'שבת'),
+ 'months_short' => array ('ינואר', 'פברואר', 'מרץ', 'אפריל', 'מאי', 'יוני', 'יולי', 'אוגוסט', 'ספטמבר', 'אוקטובר', 'נובמבר', 'דצמבר'),
+ 'months_long' => array ('ינואר', 'פברואר', 'מרץ', 'אפריל', 'מאי', 'יוני', 'יולי', 'אוגוסט', 'ספטמבר', 'אוקטובר', 'נובמבר', 'דצמבר')
+ ),
+ 'sv' => array (
+ 'weekdays_short'=> array ('Sön', 'Mån', 'Tis', 'Ons', 'Tor', 'Fre', 'Lör'),
+ 'weekdays_long' => array ('Söndag', 'Måndag', 'Tisdag', 'Onsdag', 'Torsdag', 'Fredag', 'Lördag'),
+ 'months_short' => array ('Jan', 'Feb', 'Mar', 'Apr', 'Maj', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec'),
+ 'months_long' => array ('Januari', 'Februari', 'Mars', 'April', 'Maj', 'Juni', 'Juli', 'Augusti', 'September', 'Oktober', 'November', 'December')
+ ),
+ 'pt' => array (
+ 'weekdays_short'=> array ('Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sáb'),
+ 'weekdays_long' => array ('Domingo', 'Segunda-feira', 'Terça-feira', 'Quarta-feira', 'Quinta-feira', 'Sexta-feira', 'Sábado'),
+ 'months_short' => array ('Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez'),
+ 'months_long' => array ('Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro')
+ ),
+ 'tw' => array (
+ 'weekdays_short'=> array ('週日','週一', '週二','週三', '週四','週五', '週六'),
+ 'weekdays_long' => array ('星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'),
+ 'months_short' => array ('一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'),
+ 'months_long' => array ('一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月')
+ ),
+ 'pt-br' => array (
+ 'weekdays_short'=> array ('Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sáb'),
+ 'weekdays_long' => array ('Domingo', 'Segunda', 'Terça', 'Quarta', 'Quinta', 'Sexta', 'Sábado'),
+ 'months_short' => array ('Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez'),
+ 'months_long' => array ('Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro')
+ )
+ );
+
+ // }}}
+ // {{{ constructor
+
+ /**
+ * Class constructor
+ *
+ * @access public
+ * @param string Element's name
+ * @param mixed Label(s) for an element
+ * @param array Options to control the element's display
+ * @param mixed Either a typical HTML attribute string or an associative array
+ */
+ function HTML_QuickForm_date($elementName = null, $elementLabel = null, $options = array(), $attributes = null)
+ {
+ $this->HTML_QuickForm_element($elementName, $elementLabel, $attributes);
+ $this->_persistantFreeze = true;
+ $this->_appendName = true;
+ $this->_type = 'date';
+ // set the options, do not bother setting bogus ones
+ if (is_array($options)) {
+ foreach ($options as $name => $value) {
+ if ('language' == $name) {
+ $this->_options['language'] = isset($this->_locale[$value])? $value: 'en';
+ } elseif (isset($this->_options[$name])) {
+ if (is_array($value) && is_array($this->_options[$name])) {
+ $this->_options[$name] = @array_merge($this->_options[$name], $value);
+ } else {
+ $this->_options[$name] = $value;
+ }
+ }
+ }
+ }
+ }
+
+ // }}}
+ // {{{ _createElements()
+
+ function _createElements()
+ {
+ $this->_separator = $this->_elements = array();
+ $separator = '';
+ $locale =& $this->_locale[$this->_options['language']];
+ $backslash = false;
+ for ($i = 0, $length = strlen($this->_options['format']); $i < $length; $i++) {
+ $sign = $this->_options['format']{$i};
+ if ($backslash) {
+ $backslash = false;
+ $separator .= $sign;
+ } else {
+ $loadSelect = true;
+ switch ($sign) {
+ case 'D':
+ // Sunday is 0 like with 'w' in date()
+ $options = $locale['weekdays_short'];
+ break;
+ case 'l':
+ $options = $locale['weekdays_long'];
+ break;
+ case 'd':
+ $options = $this->_createOptionList(1, 31);
+ break;
+ case 'M':
+ $options = $locale['months_short'];
+ array_unshift($options , '');
+ unset($options[0]);
+ break;
+ case 'm':
+ $options = $this->_createOptionList(1, 12);
+ break;
+ case 'F':
+ $options = $locale['months_long'];
+ array_unshift($options , '');
+ unset($options[0]);
+ break;
+ case 'Y':
+ $options = $this->_createOptionList(
+ $this->_options['minYear'],
+ $this->_options['maxYear'],
+ $this->_options['minYear'] > $this->_options['maxYear']? -1: 1
+ );
+ break;
+ case 'y':
+ $options = $this->_createOptionList(
+ $this->_options['minYear'],
+ $this->_options['maxYear'],
+ $this->_options['minYear'] > $this->_options['maxYear']? -1: 1
+ );
+ array_walk($options, create_function('&$v,$k','$v = substr($v,-2);'));
+ break;
+ case 'h':
+ $options = $this->_createOptionList(1, 12);
+ break;
+ case 'g':
+ $options = $this->_createOptionList(1, 12);
+ array_walk($options, create_function('&$v,$k', '$v = intval($v);'));
+ break;
+ case 'H':
+ $options = $this->_createOptionList(0, 23);
+ break;
+ case 'i':
+ $options = $this->_createOptionList(0, 59, $this->_options['optionIncrement']['i']);
+ break;
+ case 's':
+ $options = $this->_createOptionList(0, 59, $this->_options['optionIncrement']['s']);
+ break;
+ case 'a':
+ $options = array('am' => 'am', 'pm' => 'pm');
+ break;
+ case 'A':
+ $options = array('AM' => 'AM', 'PM' => 'PM');
+ break;
+ case 'W':
+ $options = $this->_createOptionList(1, 53);
+ break;
+ case '\\':
+ $backslash = true;
+ $loadSelect = false;
+ break;
+ default:
+ $separator .= (' ' == $sign? ' ': $sign);
+ $loadSelect = false;
+ }
+
+ if ($loadSelect) {
+ if (0 < count($this->_elements)) {
+ $this->_separator[] = $separator;
+ } else {
+ $this->_wrap[0] = $separator;
+ }
+ $separator = '';
+ // Should we add an empty option to the top of the select?
+ if (!is_array($this->_options['addEmptyOption']) && $this->_options['addEmptyOption'] ||
+ is_array($this->_options['addEmptyOption']) && !empty($this->_options['addEmptyOption'][$sign])) {
+
+ // Using '+' array operator to preserve the keys
+ if (is_array($this->_options['emptyOptionText']) && !empty($this->_options['emptyOptionText'][$sign])) {
+ $options = array($this->_options['emptyOptionValue'] => $this->_options['emptyOptionText'][$sign]) + $options;
+ } else {
+ $options = array($this->_options['emptyOptionValue'] => $this->_options['emptyOptionText']) + $options;
+ }
+ }
+ $this->_elements[] =& new HTML_QuickForm_select($sign, null, $options, $this->getAttributes());
+ }
+ }
+ }
+ $this->_wrap[1] = $separator . ($backslash? '\\': '');
+ }
+
+ // }}}
+ // {{{ _createOptionList()
+
+ /**
+ * Creates an option list containing the numbers from the start number to the end, inclusive
+ *
+ * @param int The start number
+ * @param int The end number
+ * @param int Increment by this value
+ * @access private
+ * @return array An array of numeric options.
+ */
+ function _createOptionList($start, $end, $step = 1)
+ {
+ for ($i = $start, $options = array(); $start > $end? $i >= $end: $i <= $end; $i += $step) {
+ $options[$i] = sprintf('%02d', $i);
+ }
+ return $options;
+ }
+
+ // }}}
+ // {{{ setValue()
+
+ function setValue($value)
+ {
+ if (empty($value)) {
+ $value = array();
+ } elseif (is_scalar($value)) {
+ if (!is_numeric($value)) {
+ $value = strtotime($value);
+ }
+ // might be a unix epoch, then we fill all possible values
+ $arr = explode('-', date('w-d-n-Y-h-H-i-s-a-A-W', (int)$value));
+ $value = array(
+ 'D' => $arr[0],
+ 'l' => $arr[0],
+ 'd' => $arr[1],
+ 'M' => $arr[2],
+ 'm' => $arr[2],
+ 'F' => $arr[2],
+ 'Y' => $arr[3],
+ 'y' => $arr[3],
+ 'h' => $arr[4],
+ 'g' => $arr[4],
+ 'H' => $arr[5],
+ 'i' => $arr[6],
+ 's' => $arr[7],
+ 'a' => $arr[8],
+ 'A' => $arr[9],
+ 'W' => $arr[10]
+ );
+ }
+ parent::setValue($value);
+ }
+
+ // }}}
+ // {{{ toHtml()
+
+ function toHtml()
+ {
+ include_once('HTML/QuickForm/Renderer/Default.php');
+ $renderer =& new HTML_QuickForm_Renderer_Default();
+ $renderer->setElementTemplate('{element}');
+ parent::accept($renderer);
+ return $this->_wrap[0] . $renderer->toHtml() . $this->_wrap[1];
+ }
+
+ // }}}
+ // {{{ accept()
+
+ function accept(&$renderer, $required = false, $error = null)
+ {
+ $renderer->renderElement($this, $required, $error);
+ }
+
+ // }}}
+ // {{{ onQuickFormEvent()
+
+ function onQuickFormEvent($event, $arg, &$caller)
+ {
+ if ('updateValue' == $event) {
+ // we need to call setValue(), 'cause the default/constant value
+ // may be in fact a timestamp, not an array
+ return HTML_QuickForm_element::onQuickFormEvent($event, $arg, $caller);
+ } else {
+ return parent::onQuickFormEvent($event, $arg, $caller);
+ }
+ }
+
+ // }}}
+}
+?>
\ No newline at end of file
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP version 4.0 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> |
+// | Bertrand Mansion <bmansion@mamasam.com> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+require_once('HTML/Common.php');
+
+/**
+ * Base class for form elements
+ *
+ * @author Adam Daniel <adaniel1@eesus.jnj.com>
+ * @author Bertrand Mansion <bmansion@mamasam.com>
+ * @version 1.3
+ * @since PHP4.04pl1
+ * @access public
+ * @abstract
+ */
+class HTML_QuickForm_element extends HTML_Common
+{
+ // {{{ properties
+
+ /**
+ * Label of the field
+ * @var string
+ * @since 1.3
+ * @access private
+ */
+ var $_label = '';
+
+ /**
+ * Form element type
+ * @var string
+ * @since 1.0
+ * @access private
+ */
+ var $_type = '';
+
+ /**
+ * Flag to tell if element is frozen
+ * @var boolean
+ * @since 1.0
+ * @access private
+ */
+ var $_flagFrozen = false;
+
+ /**
+ * Does the element support persistant data when frozen
+ * @var boolean
+ * @since 1.3
+ * @access private
+ */
+ var $_persistantFreeze = false;
+
+ // }}}
+ // {{{ constructor
+
+ /**
+ * Class constructor
+ *
+ * @param string Name of the element
+ * @param mixed Label(s) for the element
+ * @param mixed Associative array of tag attributes or HTML attributes name="value" pairs
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function HTML_QuickForm_element($elementName=null, $elementLabel=null, $attributes=null)
+ {
+ HTML_Common::HTML_Common($attributes);
+ if (isset($elementName)) {
+ $this->setName($elementName);
+ }
+ if (isset($elementLabel)) {
+ $this->setLabel($elementLabel);
+ }
+ } //end constructor
+
+ // }}}
+ // {{{ apiVersion()
+
+ /**
+ * Returns the current API version
+ *
+ * @since 1.0
+ * @access public
+ * @return float
+ */
+ function apiVersion()
+ {
+ return 2.0;
+ } // end func apiVersion
+
+ // }}}
+ // {{{ getType()
+
+ /**
+ * Returns element type
+ *
+ * @since 1.0
+ * @access public
+ * @return string
+ */
+ function getType()
+ {
+ return $this->_type;
+ } // end func getType
+
+ // }}}
+ // {{{ setName()
+
+ /**
+ * Sets the input field name
+ *
+ * @param string $name Input field name attribute
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function setName($name)
+ {
+ // interface method
+ } //end func setName
+
+ // }}}
+ // {{{ getName()
+
+ /**
+ * Returns the element name
+ *
+ * @since 1.0
+ * @access public
+ * @return string
+ */
+ function getName()
+ {
+ // interface method
+ } //end func getName
+
+ // }}}
+ // {{{ setValue()
+
+ /**
+ * Sets the value of the form element
+ *
+ * @param string $value Default value of the form element
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function setValue($value)
+ {
+ // interface
+ } // end func setValue
+
+ // }}}
+ // {{{ getValue()
+
+ /**
+ * Returns the value of the form element
+ *
+ * @since 1.0
+ * @access public
+ * @return mixed
+ */
+ function getValue()
+ {
+ // interface
+ return null;
+ } // end func getValue
+
+ // }}}
+ // {{{ freeze()
+
+ /**
+ * Freeze the element so that only its value is returned
+ *
+ * @access public
+ * @return void
+ */
+ function freeze()
+ {
+ $this->_flagFrozen = true;
+ } //end func freeze
+
+ // }}}
+ // {{{ unfreeze()
+
+ /**
+ * Unfreezes the element so that it becomes editable
+ *
+ * @access public
+ * @return void
+ * @since 3.2.4
+ */
+ function unfreeze()
+ {
+ $this->_flagFrozen = false;
+ }
+
+ // }}}
+ // {{{ getFrozenHtml()
+
+ /**
+ * Returns the value of field without HTML tags
+ *
+ * @since 1.0
+ * @access public
+ * @return string
+ */
+ function getFrozenHtml()
+ {
+ $value = $this->getValue();
+ return ('' != $value? htmlspecialchars($value): ' ') .
+ $this->_getPersistantData();
+ } //end func getFrozenHtml
+
+ // }}}
+ // {{{ _getPersistantData()
+
+ /**
+ * Used by getFrozenHtml() to pass the element's value if _persistantFreeze is on
+ *
+ * @access private
+ * @return string
+ */
+ function _getPersistantData()
+ {
+ if (!$this->_persistantFreeze) {
+ return '';
+ } else {
+ $id = $this->getAttribute('id');
+ return '<input' . $this->_getAttrString(array(
+ 'type' => 'hidden',
+ 'name' => $this->getName(),
+ 'value' => $this->getValue()
+ ) + (isset($id)? array('id' => $id): array())) . ' />';
+ }
+ }
+
+ // }}}
+ // {{{ isFrozen()
+
+ /**
+ * Returns whether or not the element is frozen
+ *
+ * @since 1.3
+ * @access public
+ * @return bool
+ */
+ function isFrozen()
+ {
+ return $this->_flagFrozen;
+ } // end func isFrozen
+
+ // }}}
+ // {{{ setPersistantFreeze()
+
+ /**
+ * Sets wether an element value should be kept in an hidden field
+ * when the element is frozen or not
+ *
+ * @param bool $persistant True if persistant value
+ * @since 2.0
+ * @access public
+ * @return void
+ */
+ function setPersistantFreeze($persistant=false)
+ {
+ $this->_persistantFreeze = $persistant;
+ } //end func setPersistantFreeze
+
+ // }}}
+ // {{{ setLabel()
+
+ /**
+ * Sets display text for the element
+ *
+ * @param string $label Display text for the element
+ * @since 1.3
+ * @access public
+ * @return void
+ */
+ function setLabel($label)
+ {
+ $this->_label = $label;
+ } //end func setLabel
+
+ // }}}
+ // {{{ getLabel()
+
+ /**
+ * Returns display text for the element
+ *
+ * @since 1.3
+ * @access public
+ * @return string
+ */
+ function getLabel()
+ {
+ return $this->_label;
+ } //end func getLabel
+
+ // }}}
+ // {{{ _findValue()
+
+ /**
+ * Tries to find the element value from the values array
+ *
+ * @since 2.7
+ * @access private
+ * @return mixed
+ */
+ function _findValue(&$values)
+ {
+ if (empty($values)) {
+ return null;
+ }
+ $elementName = $this->getName();
+ if (isset($values[$elementName])) {
+ return $values[$elementName];
+ } elseif (strpos($elementName, '[')) {
+ $myVar = "['" . str_replace(array(']', '['), array('', "']['"), $elementName) . "']";
+ return eval("return (isset(\$values$myVar)) ? \$values$myVar : null;");
+ } else {
+ return null;
+ }
+ } //end func _findValue
+
+ // }}}
+ // {{{ onQuickFormEvent()
+
+ /**
+ * Called by HTML_QuickForm whenever form event is made on this element
+ *
+ * @param string $event Name of event
+ * @param mixed $arg event arguments
+ * @param object $caller calling object
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function onQuickFormEvent($event, $arg, &$caller)
+ {
+ switch ($event) {
+ case 'createElement':
+ $className = get_class($this);
+ $this->$className($arg[0], $arg[1], $arg[2], $arg[3], $arg[4]);
+ break;
+ case 'addElement':
+ $this->onQuickFormEvent('createElement', $arg, $caller);
+ $this->onQuickFormEvent('updateValue', null, $caller);
+ break;
+ case 'updateValue':
+ // constant values override both default and submitted ones
+ // default values are overriden by submitted
+ $value = $this->_findValue($caller->_constantValues);
+ if (null === $value) {
+ $value = $this->_findValue($caller->_submitValues);
+ if (null === $value) {
+ $value = $this->_findValue($caller->_defaultValues);
+ }
+ }
+ if (null !== $value) {
+ $this->setValue($value);
+ }
+ break;
+ case 'setGroupValue':
+ $this->setValue($arg);
+ }
+ return true;
+ } // end func onQuickFormEvent
+
+ // }}}
+ // {{{ accept()
+
+ /**
+ * Accepts a renderer
+ *
+ * @param object An HTML_QuickForm_Renderer object
+ * @param bool Whether an element is required
+ * @param string An error message associated with an element
+ * @access public
+ * @return void
+ */
+ function accept(&$renderer, $required=false, $error=null)
+ {
+ $renderer->renderElement($this, $required, $error);
+ } // end func accept
+
+ // }}}
+ // {{{ _generateId()
+
+ /**
+ * Automatically generates and assigns an 'id' attribute for the element.
+ *
+ * Currently used to ensure that labels work on radio buttons and
+ * checkboxes. Per idea of Alexander Radivanovich.
+ *
+ * @access private
+ * @return void
+ */
+ function _generateId()
+ {
+ static $idx = 1;
+
+ if (!$this->getAttribute('id')) {
+ $this->updateAttributes(array('id' => 'qf_' . substr(md5(microtime() . $idx++), 0, 6)));
+ }
+ } // end func _generateId
+
+ // }}}
+ // {{{ exportValue()
+
+ /**
+ * Returns a 'safe' element's value
+ *
+ * @param array array of submitted values to search
+ * @param bool whether to return the value as associative array
+ * @access public
+ * @return mixed
+ */
+ function exportValue(&$submitValues, $assoc = false)
+ {
+ $value = $this->_findValue($submitValues);
+ if (null === $value) {
+ $value = $this->getValue();
+ }
+ return $this->_prepareValue($value, $assoc);
+ }
+
+ // }}}
+ // {{{ _prepareValue()
+
+ /**
+ * Used by exportValue() to prepare the value for returning
+ *
+ * @param mixed the value found in exportValue()
+ * @param bool whether to return the value as associative array
+ * @access private
+ * @return mixed
+ */
+ function _prepareValue($value, $assoc)
+ {
+ if (null === $value) {
+ return null;
+ } elseif (!$assoc) {
+ return $value;
+ } else {
+ $name = $this->getName();
+ if (!strpos($name, '[')) {
+ return array($name => $value);
+ } else {
+ $valueAry = array();
+ $myIndex = "['" . str_replace(array(']', '['), array('', "']['"), $name) . "']";
+ eval("\$valueAry$myIndex = \$value;");
+ return $valueAry;
+ }
+ }
+ }
+
+ // }}}
+} // end class HTML_QuickForm_element
+?>
\ No newline at end of file
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP version 4.0 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> |
+// | Bertrand Mansion <bmansion@mamasam.com> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+require_once("HTML/QuickForm/input.php");
+
+// register file-related rules
+if (class_exists('HTML_QuickForm')) {
+ HTML_QuickForm::registerRule('uploadedfile', 'callback', '_ruleIsUploadedFile', 'HTML_QuickForm_file');
+ HTML_QuickForm::registerRule('maxfilesize', 'callback', '_ruleCheckMaxFileSize', 'HTML_QuickForm_file');
+ HTML_QuickForm::registerRule('mimetype', 'callback', '_ruleCheckMimeType', 'HTML_QuickForm_file');
+ HTML_QuickForm::registerRule('filename', 'callback', '_ruleCheckFileName', 'HTML_QuickForm_file');
+}
+
+/**
+ * HTML class for a file type element
+ *
+ * @author Adam Daniel <adaniel1@eesus.jnj.com>
+ * @author Bertrand Mansion <bmansion@mamasam.com>
+ * @version 1.0
+ * @since PHP4.04pl1
+ * @access public
+ */
+class HTML_QuickForm_file extends HTML_QuickForm_input
+{
+ // {{{ properties
+
+ /**
+ * Uploaded file data, from $_FILES
+ * @var array
+ */
+ var $_value = null;
+
+ // }}}
+ // {{{ constructor
+
+ /**
+ * Class constructor
+ *
+ * @param string Input field name attribute
+ * @param string Input field label
+ * @param mixed (optional)Either a typical HTML attribute string
+ * or an associative array
+ * @since 1.0
+ * @access public
+ */
+ function HTML_QuickForm_file($elementName=null, $elementLabel=null, $attributes=null)
+ {
+ HTML_QuickForm_input::HTML_QuickForm_input($elementName, $elementLabel, $attributes);
+ $this->setType('file');
+ } //end constructor
+
+ // }}}
+ // {{{ setSize()
+
+ /**
+ * Sets size of file element
+ *
+ * @param int Size of file element
+ * @since 1.0
+ * @access public
+ */
+ function setSize($size)
+ {
+ $this->updateAttributes(array('size' => $size));
+ } //end func setSize
+
+ // }}}
+ // {{{ getSize()
+
+ /**
+ * Returns size of file element
+ *
+ * @since 1.0
+ * @access public
+ * @return int
+ */
+ function getSize()
+ {
+ return $this->getAttribute('size');
+ } //end func getSize
+
+ // }}}
+ // {{{ freeze()
+
+ /**
+ * Freeze the element so that only its value is returned
+ *
+ * @access public
+ * @return bool
+ */
+ function freeze()
+ {
+ return false;
+ } //end func freeze
+
+ // }}}
+ // {{{ setValue()
+
+ /**
+ * Sets value for file element.
+ *
+ * Actually this does nothing. The function is defined here to override
+ * HTML_Quickform_input's behaviour of setting the 'value' attribute. As
+ * no sane user-agent uses <input type="file">'s value for anything
+ * (because of security implications) we implement file's value as a
+ * read-only property with a special meaning.
+ *
+ * @param mixed Value for file element
+ * @since 3.0
+ * @access public
+ */
+ function setValue($value)
+ {
+ return null;
+ } //end func setValue
+
+ // }}}
+ // {{{ getValue()
+
+ /**
+ * Returns information about the uploaded file
+ *
+ * @since 3.0
+ * @access public
+ * @return array
+ */
+ function getValue()
+ {
+ return $this->_value;
+ } // end func getValue
+
+ // }}}
+ // {{{ onQuickFormEvent()
+
+ /**
+ * Called by HTML_QuickForm whenever form event is made on this element
+ *
+ * @param string Name of event
+ * @param mixed event arguments
+ * @param object calling object
+ * @since 1.0
+ * @access public
+ * @return bool
+ */
+ function onQuickFormEvent($event, $arg, &$caller)
+ {
+ switch ($event) {
+ case 'updateValue':
+ if ($caller->getAttribute('method') == 'get') {
+ return PEAR::raiseError('Cannot add a file upload field to a GET method form');
+ }
+ $this->_value = $this->_findValue();
+ $caller->updateAttributes(array('enctype' => 'multipart/form-data'));
+ $caller->setMaxFileSize();
+ break;
+ case 'addElement':
+ $this->onQuickFormEvent('createElement', $arg, $caller);
+ return $this->onQuickFormEvent('updateValue', null, $caller);
+ break;
+ case 'createElement':
+ $className = get_class($this);
+ $this->$className($arg[0], $arg[1], $arg[2]);
+ break;
+ }
+ return true;
+ } // end func onQuickFormEvent
+
+ // }}}
+ // {{{ moveUploadedFile()
+
+ /**
+ * Moves an uploaded file into the destination
+ *
+ * @param string Destination directory path
+ * @param string New file name
+ * @access public
+ * @return bool Whether the file was moved successfully
+ */
+ function moveUploadedFile($dest, $fileName = '')
+ {
+ if ($dest != '' && substr($dest, -1) != '/') {
+ $dest .= '/';
+ }
+ $fileName = ($fileName != '') ? $fileName : basename($this->_value['name']);
+ if (move_uploaded_file($this->_value['tmp_name'], $dest . $fileName)) {
+ return true;
+ } else {
+ return false;
+ }
+ } // end func moveUploadedFile
+
+ // }}}
+ // {{{ isUploadedFile()
+
+ /**
+ * Checks if the element contains an uploaded file
+ *
+ * @access public
+ * @return bool true if file has been uploaded, false otherwise
+ */
+ function isUploadedFile()
+ {
+ return $this->_ruleIsUploadedFile($this->_value);
+ } // end func isUploadedFile
+
+ // }}}
+ // {{{ _ruleIsUploadedFile()
+
+ /**
+ * Checks if the given element contains an uploaded file
+ *
+ * @param array Uploaded file info (from $_FILES)
+ * @access private
+ * @return bool true if file has been uploaded, false otherwise
+ */
+ function _ruleIsUploadedFile($elementValue)
+ {
+ if ((isset($elementValue['error']) && $elementValue['error'] == 0) ||
+ (!empty($elementValue['tmp_name']) && $elementValue['tmp_name'] != 'none')) {
+ return is_uploaded_file($elementValue['tmp_name']);
+ } else {
+ return false;
+ }
+ } // end func _ruleIsUploadedFile
+
+ // }}}
+ // {{{ _ruleCheckMaxFileSize()
+
+ /**
+ * Checks that the file does not exceed the max file size
+ *
+ * @param array Uploaded file info (from $_FILES)
+ * @param int Max file size
+ * @access private
+ * @return bool true if filesize is lower than maxsize, false otherwise
+ */
+ function _ruleCheckMaxFileSize($elementValue, $maxSize)
+ {
+ if (!empty($elementValue['error']) &&
+ (UPLOAD_ERR_FORM_SIZE == $elementValue['error'] || UPLOAD_ERR_INI_SIZE == $elementValue['error'])) {
+ return false;
+ }
+ if (!HTML_QuickForm_file::_ruleIsUploadedFile($elementValue)) {
+ return true;
+ }
+ return ($maxSize >= @filesize($elementValue['tmp_name']));
+ } // end func _ruleCheckMaxFileSize
+
+ // }}}
+ // {{{ _ruleCheckMimeType()
+
+ /**
+ * Checks if the given element contains an uploaded file of the right mime type
+ *
+ * @param array Uploaded file info (from $_FILES)
+ * @param mixed Mime Type (can be an array of allowed types)
+ * @access private
+ * @return bool true if mimetype is correct, false otherwise
+ */
+ function _ruleCheckMimeType($elementValue, $mimeType)
+ {
+ if (!HTML_QuickForm_file::_ruleIsUploadedFile($elementValue)) {
+ return true;
+ }
+ if (is_array($mimeType)) {
+ return in_array($elementValue['type'], $mimeType);
+ }
+ return $elementValue['type'] == $mimeType;
+ } // end func _ruleCheckMimeType
+
+ // }}}
+ // {{{ _ruleCheckFileName()
+
+ /**
+ * Checks if the given element contains an uploaded file of the filename regex
+ *
+ * @param array Uploaded file info (from $_FILES)
+ * @param string Regular expression
+ * @access private
+ * @return bool true if name matches regex, false otherwise
+ */
+ function _ruleCheckFileName($elementValue, $regex)
+ {
+ if (!HTML_QuickForm_file::_ruleIsUploadedFile($elementValue)) {
+ return true;
+ }
+ return preg_match($regex, $elementValue['name']);
+ } // end func _ruleCheckFileName
+
+ // }}}
+ // {{{ _findValue()
+
+ /**
+ * Tries to find the element value from the values array
+ *
+ * Needs to be redefined here as $_FILES is populated differently from
+ * other arrays when element name is of the form foo[bar]
+ *
+ * @access private
+ * @return mixed
+ */
+ function _findValue()
+ {
+ if (empty($_FILES)) {
+ return null;
+ }
+ $elementName = $this->getName();
+ if (isset($_FILES[$elementName])) {
+ return $_FILES[$elementName];
+ } elseif (false !== ($pos = strpos($elementName, '['))) {
+ $base = substr($elementName, 0, $pos);
+ $idx = "['" . str_replace(array(']', '['), array('', "']['"), substr($elementName, $pos + 1, -1)) . "']";
+ $props = array('name', 'type', 'size', 'tmp_name', 'error');
+ $code = "if (!isset(\$_FILES['{$base}']['name']{$idx})) {\n" .
+ " return null;\n" .
+ "} else {\n" .
+ " \$value = array();\n";
+ foreach ($props as $prop) {
+ $code .= " \$value['{$prop}'] = \$_FILES['{$base}']['{$prop}']{$idx};\n";
+ }
+ return eval($code . " return \$value;\n}\n");
+ } else {
+ return null;
+ }
+ }
+
+ // }}}
+} // end class HTML_QuickForm_file
+?>
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP version 4.0 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> |
+// | Bertrand Mansion <bmansion@mamasam.com> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+require_once("HTML/QuickForm/element.php");
+
+/**
+ * HTML class for a form element group
+ *
+ * @author Adam Daniel <adaniel1@eesus.jnj.com>
+ * @author Bertrand Mansion <bmansion@mamasam.com>
+ * @version 1.0
+ * @since PHP4.04pl1
+ * @access public
+ */
+class HTML_QuickForm_group extends HTML_QuickForm_element
+{
+ // {{{ properties
+
+ /**
+ * Name of the element
+ * @var string
+ * @since 1.0
+ * @access private
+ */
+ var $_name = '';
+
+ /**
+ * Array of grouped elements
+ * @var array
+ * @since 1.0
+ * @access private
+ */
+ var $_elements = array();
+
+ /**
+ * String to separate elements
+ * @var mixed
+ * @since 2.5
+ * @access private
+ */
+ var $_separator = null;
+
+ /**
+ * Required elements in this group
+ * @var array
+ * @since 2.5
+ * @access private
+ */
+ var $_required = array();
+
+ /**
+ * Whether to change elements' names to $groupName[$elementName] or leave them as is
+ * @var bool
+ * @since 3.0
+ * @access private
+ */
+ var $_appendName = true;
+
+ // }}}
+ // {{{ constructor
+
+ /**
+ * Class constructor
+ *
+ * @param string $elementName (optional)Group name
+ * @param array $elementLabel (optional)Group label
+ * @param array $elements (optional)Group elements
+ * @param mixed $separator (optional)Use a string for one separator,
+ * use an array to alternate the separators.
+ * @param bool $appendName (optional)whether to change elements' names to
+ * the form $groupName[$elementName] or leave
+ * them as is.
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function HTML_QuickForm_group($elementName=null, $elementLabel=null, $elements=null, $separator=null, $appendName = true)
+ {
+ $this->HTML_QuickForm_element($elementName, $elementLabel);
+ $this->_type = 'group';
+ if (isset($elements) && is_array($elements)) {
+ $this->setElements($elements);
+ }
+ if (isset($separator)) {
+ $this->_separator = $separator;
+ }
+ if (isset($appendName)) {
+ $this->_appendName = $appendName;
+ }
+ } //end constructor
+
+ // }}}
+ // {{{ setName()
+
+ /**
+ * Sets the group name
+ *
+ * @param string $name Group name
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function setName($name)
+ {
+ $this->_name = $name;
+ } //end func setName
+
+ // }}}
+ // {{{ getName()
+
+ /**
+ * Returns the group name
+ *
+ * @since 1.0
+ * @access public
+ * @return string
+ */
+ function getName()
+ {
+ return $this->_name;
+ } //end func getName
+
+ // }}}
+ // {{{ setValue()
+
+ /**
+ * Sets values for group's elements
+ *
+ * @param mixed Values for group's elements
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function setValue($value)
+ {
+ $this->_createElementsIfNotExist();
+ foreach (array_keys($this->_elements) as $key) {
+ if (!$this->_appendName) {
+ $v = $this->_elements[$key]->_findValue($value);
+ if (null !== $v) {
+ $this->_elements[$key]->onQuickFormEvent('setGroupValue', $v, $this);
+ }
+
+ } else {
+ $elementName = $this->_elements[$key]->getName();
+ $index = strlen($elementName) ? $elementName : $key;
+ if (is_array($value)) {
+ if (isset($value[$index])) {
+ $this->_elements[$key]->onQuickFormEvent('setGroupValue', $value[$index], $this);
+ }
+ } elseif (isset($value)) {
+ $this->_elements[$key]->onQuickFormEvent('setGroupValue', $value, $this);
+ }
+ }
+ }
+ } //end func setValue
+
+ // }}}
+ // {{{ getValue()
+
+ /**
+ * Returns the value of the group
+ *
+ * @since 1.0
+ * @access public
+ * @return mixed
+ */
+ function getValue()
+ {
+ $value = null;
+ foreach (array_keys($this->_elements) as $key) {
+ $element =& $this->_elements[$key];
+ switch ($element->getType()) {
+ case 'radio':
+ $v = $element->getChecked()? $element->getValue(): null;
+ break;
+ case 'checkbox':
+ $v = $element->getChecked()? true: null;
+ break;
+ default:
+ $v = $element->getValue();
+ }
+ if (null !== $v) {
+ $elementName = $element->getName();
+ if (is_null($elementName)) {
+ $value = $v;
+ } else {
+ if (!is_array($value)) {
+ $value = is_null($value)? array(): array($value);
+ }
+ if ('' === $elementName) {
+ $value[] = $v;
+ } else {
+ $value[$elementName] = $v;
+ }
+ }
+ }
+ }
+ return $value;
+ } // end func getValue
+
+ // }}}
+ // {{{ setElements()
+
+ /**
+ * Sets the grouped elements
+ *
+ * @param array $elements Array of elements
+ * @since 1.1
+ * @access public
+ * @return void
+ */
+ function setElements($elements)
+ {
+ $this->_elements = array_values($elements);
+ if ($this->_flagFrozen) {
+ $this->freeze();
+ }
+ } // end func setElements
+
+ // }}}
+ // {{{ getElements()
+
+ /**
+ * Gets the grouped elements
+ *
+ * @since 2.4
+ * @access public
+ * @return array
+ */
+ function &getElements()
+ {
+ $this->_createElementsIfNotExist();
+ return $this->_elements;
+ } // end func getElements
+
+ // }}}
+ // {{{ getGroupType()
+
+ /**
+ * Gets the group type based on its elements
+ * Will return 'mixed' if elements contained in the group
+ * are of different types.
+ *
+ * @access public
+ * @return string group elements type
+ */
+ function getGroupType()
+ {
+ $this->_createElementsIfNotExist();
+ $prevType = '';
+ foreach (array_keys($this->_elements) as $key) {
+ $type = $this->_elements[$key]->getType();
+ if ($type != $prevType && $prevType != '') {
+ return 'mixed';
+ }
+ $prevType = $type;
+ }
+ return $type;
+ } // end func getGroupType
+
+ // }}}
+ // {{{ toHtml()
+
+ /**
+ * Returns Html for the group
+ *
+ * @since 1.0
+ * @access public
+ * @return string
+ */
+ function toHtml()
+ {
+ include_once('HTML/QuickForm/Renderer/Default.php');
+ $renderer =& new HTML_QuickForm_Renderer_Default();
+ $renderer->setElementTemplate('{element}');
+ $this->accept($renderer);
+ return $renderer->toHtml();
+ } //end func toHtml
+
+ // }}}
+ // {{{ getElementName()
+
+ /**
+ * Returns the element name inside the group such as found in the html form
+ *
+ * @param mixed $index Element name or element index in the group
+ * @since 3.0
+ * @access public
+ * @return mixed string with element name, false if not found
+ */
+ function getElementName($index)
+ {
+ $this->_createElementsIfNotExist();
+ $elementName = false;
+ if (is_int($index) && isset($this->_elements[$index])) {
+ $elementName = $this->_elements[$index]->getName();
+ if (isset($elementName) && $elementName == '') {
+ $elementName = $index;
+ }
+ if ($this->_appendName) {
+ if (is_null($elementName)) {
+ $elementName = $this->getName();
+ } else {
+ $elementName = $this->getName().'['.$elementName.']';
+ }
+ }
+
+ } elseif (is_string($index)) {
+ foreach (array_keys($this->_elements) as $key) {
+ $elementName = $this->_elements[$key]->getName();
+ if ($index == $elementName) {
+ if ($this->_appendName) {
+ $elementName = $this->getName().'['.$elementName.']';
+ }
+ break;
+ } elseif ($this->_appendName && $this->getName().'['.$elementName.']' == $index) {
+ break;
+ }
+ }
+ }
+ return $elementName;
+ } //end func getElementName
+
+ // }}}
+ // {{{ getFrozenHtml()
+
+ /**
+ * Returns the value of field without HTML tags
+ *
+ * @since 1.3
+ * @access public
+ * @return string
+ */
+ function getFrozenHtml()
+ {
+ $flags = array();
+ $this->_createElementsIfNotExist();
+ foreach (array_keys($this->_elements) as $key) {
+ if (false === ($flags[$key] = $this->_elements[$key]->isFrozen())) {
+ $this->_elements[$key]->freeze();
+ }
+ }
+ $html = $this->toHtml();
+ foreach (array_keys($this->_elements) as $key) {
+ if (!$flags[$key]) {
+ $this->_elements[$key]->unfreeze();
+ }
+ }
+ return $html;
+ } //end func getFrozenHtml
+
+ // }}}
+ // {{{ onQuickFormEvent()
+
+ /**
+ * Called by HTML_QuickForm whenever form event is made on this element
+ *
+ * @param string $event Name of event
+ * @param mixed $arg event arguments
+ * @param object $caller calling object
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function onQuickFormEvent($event, $arg, &$caller)
+ {
+ switch ($event) {
+ case 'updateValue':
+ $this->_createElementsIfNotExist();
+ foreach (array_keys($this->_elements) as $key) {
+ if ($this->_appendName) {
+ $elementName = $this->_elements[$key]->getName();
+ if (is_null($elementName)) {
+ $this->_elements[$key]->setName($this->getName());
+ } elseif ('' === $elementName) {
+ $this->_elements[$key]->setName($this->getName() . '[' . $key . ']');
+ } else {
+ $this->_elements[$key]->setName($this->getName() . '[' . $elementName . ']');
+ }
+ }
+ $this->_elements[$key]->onQuickFormEvent('updateValue', $arg, $caller);
+ if ($this->_appendName) {
+ $this->_elements[$key]->setName($elementName);
+ }
+ }
+ break;
+
+ default:
+ parent::onQuickFormEvent($event, $arg, $caller);
+ }
+ return true;
+ } // end func onQuickFormEvent
+
+ // }}}
+ // {{{ accept()
+
+ /**
+ * Accepts a renderer
+ *
+ * @param object An HTML_QuickForm_Renderer object
+ * @param bool Whether a group is required
+ * @param string An error message associated with a group
+ * @access public
+ * @return void
+ */
+ function accept(&$renderer, $required = false, $error = null)
+ {
+ $this->_createElementsIfNotExist();
+ $renderer->startGroup($this, $required, $error);
+ $name = $this->getName();
+ foreach (array_keys($this->_elements) as $key) {
+ $element =& $this->_elements[$key];
+
+ if ($this->_appendName) {
+ $elementName = $element->getName();
+ if (isset($elementName)) {
+ $element->setName($name . '['. (strlen($elementName)? $elementName: $key) .']');
+ } else {
+ $element->setName($name);
+ }
+ }
+
+ $required = !$element->isFrozen() && in_array($element->getName(), $this->_required);
+
+ $element->accept($renderer, $required);
+
+ // restore the element's name
+ if ($this->_appendName) {
+ $element->setName($elementName);
+ }
+ }
+ $renderer->finishGroup($this);
+ } // end func accept
+
+ // }}}
+ // {{{ exportValue()
+
+ /**
+ * As usual, to get the group's value we access its elements and call
+ * their exportValue() methods
+ */
+ function exportValue(&$submitValues, $assoc = false)
+ {
+ $value = null;
+ foreach (array_keys($this->_elements) as $key) {
+ $elementName = $this->_elements[$key]->getName();
+ if ($this->_appendName) {
+ if (is_null($elementName)) {
+ $this->_elements[$key]->setName($this->getName());
+ } elseif ('' === $elementName) {
+ $this->_elements[$key]->setName($this->getName() . '[' . $key . ']');
+ } else {
+ $this->_elements[$key]->setName($this->getName() . '[' . $elementName . ']');
+ }
+ }
+ $v = $this->_elements[$key]->exportValue($submitValues, $assoc);
+ if ($this->_appendName) {
+ $this->_elements[$key]->setName($elementName);
+ }
+ if (null !== $v) {
+ // Make $value an array, we will use it like one
+ if (null === $value) {
+ $value = array();
+ }
+ if ($assoc) {
+ // just like HTML_QuickForm::exportValues()
+ $value = HTML_QuickForm::arrayMerge($value, $v);
+ } else {
+ // just like getValue(), but should work OK every time here
+ if (is_null($elementName)) {
+ $value = $v;
+ } elseif ('' === $elementName) {
+ $value[] = $v;
+ } else {
+ $value[$elementName] = $v;
+ }
+ }
+ }
+ }
+ // do not pass the value through _prepareValue, we took care of this already
+ return $value;
+ }
+
+ // }}}
+ // {{{ _createElements()
+
+ /**
+ * Creates the group's elements.
+ *
+ * This should be overriden by child classes that need to create their
+ * elements. The method will be called automatically when needed, calling
+ * it from the constructor is discouraged as the constructor is usually
+ * called _twice_ on element creation, first time with _no_ parameters.
+ *
+ * @access private
+ * @abstract
+ */
+ function _createElements()
+ {
+ // abstract
+ }
+
+ // }}}
+ // {{{ _createElementsIfNotExist()
+
+ /**
+ * A wrapper around _createElements()
+ *
+ * This method calls _createElements() if the group's _elements array
+ * is empty. It also performs some updates, e.g. freezes the created
+ * elements if the group is already frozen.
+ *
+ * @access private
+ */
+ function _createElementsIfNotExist()
+ {
+ if (empty($this->_elements)) {
+ $this->_createElements();
+ if ($this->_flagFrozen) {
+ $this->freeze();
+ }
+ }
+ }
+
+ // }}}
+ // {{{ freeze()
+
+ function freeze()
+ {
+ parent::freeze();
+ foreach (array_keys($this->_elements) as $key) {
+ $this->_elements[$key]->freeze();
+ }
+ }
+
+ // }}}
+ // {{{ unfreeze()
+
+ function unfreeze()
+ {
+ parent::unfreeze();
+ foreach (array_keys($this->_elements) as $key) {
+ $this->_elements[$key]->unfreeze();
+ }
+ }
+
+ // }}}
+ // {{{ setPersistantFreeze()
+
+ function setPersistantFreeze($persistant = false)
+ {
+ parent::setPersistantFreeze($persistant);
+ foreach (array_keys($this->_elements) as $key) {
+ $this->_elements[$key]->setPersistantFreeze($persistant);
+ }
+ }
+
+ // }}}
+} //end class HTML_QuickForm_group
+?>
\ No newline at end of file
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP version 4.0 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2003 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Author: Alexey Borzov <borz_off@cs.msu.su> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+require_once 'HTML/QuickForm/static.php';
+
+/**
+ * A pseudo-element used for adding headers to form
+ *
+ * @author Alexey Borzov <borz_off@cs.msu.su>
+ * @access public
+ */
+class HTML_QuickForm_header extends HTML_QuickForm_static
+{
+ // {{{ constructor
+
+ /**
+ * Class constructor
+ *
+ * @param string $elementName Header name
+ * @param string $text Header text
+ * @access public
+ * @return void
+ */
+ function HTML_QuickForm_header($elementName = null, $text = null)
+ {
+ $this->HTML_QuickForm_static($elementName, null, $text);
+ $this->_type = 'header';
+ }
+
+ // }}}
+ // {{{ accept()
+
+ /**
+ * Accepts a renderer
+ *
+ * @param object An HTML_QuickForm_Renderer object
+ * @access public
+ * @return void
+ */
+ function accept(&$renderer)
+ {
+ $renderer->renderHeader($this);
+ } // end func accept
+
+ // }}}
+
+} //end class HTML_QuickForm_header
+?>
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP version 4.0 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> |
+// | Bertrand Mansion <bmansion@mamasam.com> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+require_once("HTML/QuickForm/input.php");
+
+/**
+ * HTML class for a hidden type element
+ *
+ * @author Adam Daniel <adaniel1@eesus.jnj.com>
+ * @author Bertrand Mansion <bmansion@mamasam.com>
+ * @version 1.0
+ * @since PHP4.04pl1
+ * @access public
+ */
+class HTML_QuickForm_hidden extends HTML_QuickForm_input
+{
+ // {{{ constructor
+
+ /**
+ * Class constructor
+ *
+ * @param string $elementName (optional)Input field name attribute
+ * @param string $value (optional)Input field value
+ * @param mixed $attributes (optional)Either a typical HTML attribute string
+ * or an associative array
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function HTML_QuickForm_hidden($elementName=null, $value='', $attributes=null)
+ {
+ HTML_QuickForm_input::HTML_QuickForm_input($elementName, null, $attributes);
+ $this->setType('hidden');
+ $this->setValue($value);
+ } //end constructor
+
+ // }}}
+ // {{{ freeze()
+
+ /**
+ * Freeze the element so that only its value is returned
+ *
+ * @access public
+ * @return void
+ */
+ function freeze()
+ {
+ return false;
+ } //end func freeze
+
+ // }}}
+ // {{{ accept()
+
+ /**
+ * Accepts a renderer
+ *
+ * @param object An HTML_QuickForm_Renderer object
+ * @access public
+ * @return void
+ */
+ function accept(&$renderer)
+ {
+ $renderer->renderHidden($this);
+ } // end func accept
+
+ // }}}
+
+} //end class HTML_QuickForm_hidden
+?>
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP version 4.0 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> |
+// | Bertrand Mansion <bmansion@mamasam.com> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+require_once('HTML/QuickForm/select.php');
+
+/**
+ * This class takes the same arguments as a select element, but instead
+ * of creating a select ring it creates hidden elements for all values
+ * already selected with setDefault or setConstant. This is useful if
+ * you have a select ring that you don't want visible, but you need all
+ * selected values to be passed.
+ *
+ * @author Isaac Shepard <ishepard@bsiweb.com>
+ *
+ * @version 1.0
+ * @since 2.1
+ * @access public
+ */
+class HTML_QuickForm_hiddenselect extends HTML_QuickForm_select
+{
+ // {{{ constructor
+
+ /**
+ * Class constructor
+ *
+ * @param string Select name attribute
+ * @param mixed Label(s) for the select (not used)
+ * @param mixed Data to be used to populate options
+ * @param mixed Either a typical HTML attribute string or an associative array (not used)
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function HTML_QuickForm_hiddenselect($elementName=null, $elementLabel=null, $options=null, $attributes=null)
+ {
+ HTML_QuickForm_element::HTML_QuickForm_element($elementName, $elementLabel, $attributes);
+ $this->_persistantFreeze = true;
+ $this->_type = 'hiddenselect';
+ if (isset($options)) {
+ $this->load($options);
+ }
+ } //end constructor
+
+ // }}}
+ // {{{ toHtml()
+
+ /**
+ * Returns the SELECT in HTML
+ *
+ * @since 1.0
+ * @access public
+ * @return string
+ * @throws
+ */
+ function toHtml()
+ {
+ $tabs = $this->_getTabs();
+ $name = $this->getPrivateName();
+ $strHtml = '';
+
+ foreach ($this->_values as $key => $val) {
+ for ($i = 0, $optCount = count($this->_options); $i < $optCount; $i++) {
+ if ($val == $this->_options[$i]['attr']['value']) {
+ $strHtml .= $tabs . '<input' . $this->_getAttrString(array(
+ 'type' => 'hidden',
+ 'name' => $name,
+ 'value' => $val
+ )) . " />\n" ;
+ }
+ }
+ }
+
+ return $strHtml;
+ } //end func toHtml
+
+ // }}}
+ // {{{ accept()
+
+ /**
+ * This is essentially a hidden element and should be rendered as one
+ */
+ function accept(&$renderer)
+ {
+ $renderer->renderHidden($this);
+ }
+
+ // }}}
+} //end class HTML_QuickForm_hiddenselect
+?>
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP version 4.0 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2004 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Herim Vasquez <vasquezh@iro.umontreal.ca> |
+// | Bertrand Mansion <bmansion@mamasam.com> |
+// | Alexey Borzov <avb@php.net>
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+require_once('HTML/QuickForm/group.php');
+require_once('HTML/QuickForm/select.php');
+
+/**
+ * Class to dynamically create two or more HTML Select elements
+ * The first select changes the content of the second select and so on.
+ * This element is considered as a group. Selects will be named
+ * groupName[0], groupName[1], groupName[2]...
+ *
+ * @author Herim Vasquez <vasquezh@iro.umontreal.ca>
+ * @author Bertrand Mansion <bmansion@mamasam.com>
+ * @version 1.0
+ * @since PHP4.04pl1
+ * @access public
+ */
+class HTML_QuickForm_hierselect extends HTML_QuickForm_group
+{
+ // {{{ properties
+
+ /**
+ * Options for all the select elements
+ *
+ * Format is a bit more complex as we need to know which options
+ * are related to the ones in the previous select:
+ *
+ * Ex:
+ * // first select
+ * $select1[0] = 'Pop';
+ * $select1[1] = 'Classical';
+ * $select1[2] = 'Funeral doom';
+ *
+ * // second select
+ * $select2[0][0] = 'Red Hot Chil Peppers';
+ * $select2[0][1] = 'The Pixies';
+ * $select2[1][0] = 'Wagner';
+ * $select2[1][1] = 'Strauss';
+ * $select2[2][0] = 'Pantheist';
+ * $select2[2][1] = 'Skepticism';
+ *
+ * // If only need two selects
+ * // - and using the depracated functions
+ * $sel =& $form->addElement('hierselect', 'cds', 'Choose CD:');
+ * $sel->setMainOptions($select1);
+ * $sel->setSecOptions($select2);
+ *
+ * // - and using the new setOptions function
+ * $sel =& $form->addElement('hierselect', 'cds', 'Choose CD:');
+ * $sel->setOptions(array($select1, $select2));
+ *
+ * // If you have a third select with prices for the cds
+ * $select3[0][0][0] = '15.00$';
+ * $select3[0][0][1] = '17.00$';
+ * etc
+ *
+ * // You can now use
+ * $sel =& $form->addElement('hierselect', 'cds', 'Choose CD:');
+ * $sel->setOptions(array($select1, $select2, $select3));
+ *
+ * @var array
+ * @access private
+ */
+ var $_options = array();
+
+ /**
+ * Number of select elements on this group
+ *
+ * @var int
+ * @access private
+ */
+ var $_nbElements = 0;
+
+ /**
+ * The javascript used to set and change the options
+ *
+ * @var string
+ * @access private
+ */
+ var $_js = '';
+
+ // }}}
+ // {{{ constructor
+
+ /**
+ * Class constructor
+ *
+ * @param string $elementName (optional)Input field name attribute
+ * @param string $elementLabel (optional)Input field label in form
+ * @param mixed $attributes (optional)Either a typical HTML attribute string
+ * or an associative array. Date format is passed along the attributes.
+ * @param mixed $separator (optional)Use a string for one separator,
+ * use an array to alternate the separators.
+ * @access public
+ * @return void
+ */
+ function HTML_QuickForm_hierselect($elementName=null, $elementLabel=null, $attributes=null, $separator=null)
+ {
+ $this->HTML_QuickForm_element($elementName, $elementLabel, $attributes);
+ $this->_persistantFreeze = true;
+ if (isset($separator)) {
+ $this->_separator = $separator;
+ }
+ $this->_type = 'hierselect';
+ $this->_appendName = true;
+ } //end constructor
+
+ // }}}
+ // {{{ setOptions()
+
+ /**
+ * Initialize the array structure containing the options for each select element.
+ * Call the functions that actually do the magic.
+ *
+ * @param array $options Array of options defining each element
+ *
+ * @access public
+ * @return void
+ */
+ function setOptions($options)
+ {
+ $this->_options = $options;
+
+ if (empty($this->_elements)) {
+ $this->_nbElements = count($this->_options);
+ $this->_createElements();
+ } else {
+ // setDefaults has probably been called before this function
+ // check if all elements have been created
+ $totalNbElements = count($this->_options);
+ for ($i = $this->_nbElements; $i < $totalNbElements; $i ++) {
+ $this->_elements[] =& new HTML_QuickForm_select($i, null, array(), $this->getAttributes());
+ $this->_nbElements++;
+ }
+ }
+
+ $this->_setOptions();
+ } // end func setMainOptions
+
+ // }}}
+ // {{{ setMainOptions()
+
+ /**
+ * Sets the options for the first select element. Deprecated. setOptions() should be used.
+ *
+ * @param array $array Options for the first select element
+ *
+ * @access public
+ * @deprecated Deprecated since release 3.2.2
+ * @return void
+ */
+ function setMainOptions($array)
+ {
+ $this->_options[0] = $array;
+
+ if (empty($this->_elements)) {
+ $this->_nbElements = 2;
+ $this->_createElements();
+ }
+ } // end func setMainOptions
+
+ // }}}
+ // {{{ setSecOptions()
+
+ /**
+ * Sets the options for the second select element. Deprecated. setOptions() should be used.
+ * The main _options array is initialized and the _setOptions function is called.
+ *
+ * @param array $array Options for the second select element
+ *
+ * @access public
+ * @deprecated Deprecated since release 3.2.2
+ * @return void
+ */
+ function setSecOptions($array)
+ {
+ $this->_options[1] = $array;
+
+ if (empty($this->_elements)) {
+ $this->_nbElements = 2;
+ $this->_createElements();
+ } else {
+ // setDefaults has probably been called before this function
+ // check if all elements have been created
+ $totalNbElements = 2;
+ for ($i = $this->_nbElements; $i < $totalNbElements; $i ++) {
+ $this->_elements[] =& new HTML_QuickForm_select($i, null, array(), $this->getAttributes());
+ $this->_nbElements++;
+ }
+ }
+
+ $this->_setOptions();
+ } // end func setSecOptions
+
+ // }}}
+ // {{{ _setOptions()
+
+ /**
+ * Sets the options for each select element
+ *
+ * @access private
+ * @return void
+ */
+ function _setOptions()
+ {
+ $toLoad = '';
+ foreach (array_keys($this->_elements) AS $key) {
+ $array = eval("return isset(\$this->_options[{$key}]{$toLoad})? \$this->_options[{$key}]{$toLoad}: null;");
+ if (is_array($array)) {
+ $select =& $this->_elements[$key];
+ $select->_options = array();
+ $select->loadArray($array);
+
+ $value = is_array($v = $select->getValue()) ? $v[0] : key($array);
+ $toLoad .= '[\'' . str_replace(array('\\', '\''), array('\\\\', '\\\''), $value) . '\']';
+ }
+ }
+ } // end func _setOptions
+
+ // }}}
+ // {{{ setValue()
+
+ /**
+ * Sets values for group's elements
+ *
+ * @param array $value An array of 2 or more values, for the first,
+ * the second, the third etc. select
+ *
+ * @access public
+ * @return void
+ */
+ function setValue($value)
+ {
+ // fix for bug #6766. Hope this doesn't break anything more
+ // after bug #7961. Forgot that _nbElements was used in
+ // _createElements() called in several places...
+ $this->_nbElements = max($this->_nbElements, count($value));
+ parent::setValue($value);
+ $this->_setOptions();
+ } // end func setValue
+
+ // }}}
+ // {{{ _createElements()
+
+ /**
+ * Creates all the elements for the group
+ *
+ * @access private
+ * @return void
+ */
+ function _createElements()
+ {
+ for ($i = 0; $i < $this->_nbElements; $i++) {
+ $this->_elements[] =& new HTML_QuickForm_select($i, null, array(), $this->getAttributes());
+ }
+ } // end func _createElements
+
+ // }}}
+ // {{{ toHtml()
+
+ function toHtml()
+ {
+ $this->_js = '';
+ if (!$this->_flagFrozen) {
+ // set the onchange attribute for each element except last
+ $keys = array_keys($this->_elements);
+ $onChange = array();
+ for ($i = 0; $i < count($keys) - 1; $i++) {
+ $select =& $this->_elements[$keys[$i]];
+ $onChange[$i] = $select->getAttribute('onchange');
+ $select->updateAttributes(
+ array('onchange' => '_hs_swapOptions(this.form, \'' . $this->_escapeString($this->getName()) . '\', ' . $keys[$i] . ');' . $onChange[$i])
+ );
+ }
+
+ // create the js function to call
+ if (!defined('HTML_QUICKFORM_HIERSELECT_EXISTS')) {
+ $this->_js .= <<<JAVASCRIPT
+function _hs_findOptions(ary, keys)
+{
+ var key = keys.shift();
+ if (!key in ary) {
+ return {};
+ } else if (0 == keys.length) {
+ return ary[key];
+ } else {
+ return _hs_findOptions(ary[key], keys);
+ }
+}
+
+function _hs_findSelect(form, groupName, selectIndex)
+{
+ if (groupName+'['+ selectIndex +']' in form) {
+ return form[groupName+'['+ selectIndex +']'];
+ } else {
+ return form[groupName+'['+ selectIndex +'][]'];
+ }
+}
+
+function _hs_unescapeEntities(str)
+{
+ var div = document.createElement('div');
+ div.innerHTML = str;
+ return div.childNodes[0] ? div.childNodes[0].nodeValue : '';
+}
+
+function _hs_replaceOptions(ctl, optionList)
+{
+ var j = 0;
+ ctl.options.length = 0;
+ for (i in optionList) {
+ var optionText = (-1 == optionList[i].indexOf('&'))? optionList[i]: _hs_unescapeEntities(optionList[i]);
+ ctl.options[j++] = new Option(optionText, i, false, false);
+ }
+}
+
+function _hs_setValue(ctl, value)
+{
+ var testValue = {};
+ if (value instanceof Array) {
+ for (var i = 0; i < value.length; i++) {
+ testValue[value[i]] = true;
+ }
+ } else {
+ testValue[value] = true;
+ }
+ for (var i = 0; i < ctl.options.length; i++) {
+ if (ctl.options[i].value in testValue) {
+ ctl.options[i].selected = true;
+ }
+ }
+}
+
+function _hs_swapOptions(form, groupName, selectIndex)
+{
+ var hsValue = [];
+ for (var i = 0; i <= selectIndex; i++) {
+ hsValue[i] = _hs_findSelect(form, groupName, i).value;
+ }
+
+ _hs_replaceOptions(_hs_findSelect(form, groupName, selectIndex + 1),
+ _hs_findOptions(_hs_options[groupName][selectIndex], hsValue));
+ if (selectIndex + 1 < _hs_options[groupName].length) {
+ _hs_swapOptions(form, groupName, selectIndex + 1);
+ }
+}
+
+function _hs_onReset(form, groupNames)
+{
+ for (var i = 0; i < groupNames.length; i++) {
+ try {
+ for (var j = 0; j <= _hs_options[groupNames[i]].length; j++) {
+ _hs_setValue(_hs_findSelect(form, groupNames[i], j), _hs_defaults[groupNames[i]][j]);
+ if (j < _hs_options[groupNames[i]].length) {
+ _hs_replaceOptions(_hs_findSelect(form, groupNames[i], j + 1),
+ _hs_findOptions(_hs_options[groupNames[i]][j], _hs_defaults[groupNames[i]].slice(0, j + 1)));
+ }
+ }
+ } catch (e) {
+ if (!(e instanceof TypeError)) {
+ throw e;
+ }
+ }
+ }
+}
+
+function _hs_setupOnReset(form, groupNames)
+{
+ setTimeout(function() { _hs_onReset(form, groupNames); }, 25);
+}
+
+function _hs_onReload()
+{
+ var ctl;
+ for (var i = 0; i < document.forms.length; i++) {
+ for (var j in _hs_defaults) {
+ if (ctl = _hs_findSelect(document.forms[i], j, 0)) {
+ for (var k = 0; k < _hs_defaults[j].length; k++) {
+ _hs_setValue(_hs_findSelect(document.forms[i], j, k), _hs_defaults[j][k]);
+ }
+ }
+ }
+ }
+
+ if (_hs_prevOnload) {
+ _hs_prevOnload();
+ }
+}
+
+var _hs_prevOnload = null;
+if (window.onload) {
+ _hs_prevOnload = window.onload;
+}
+window.onload = _hs_onReload;
+
+var _hs_options = {};
+var _hs_defaults = {};
+
+JAVASCRIPT;
+ define('HTML_QUICKFORM_HIERSELECT_EXISTS', true);
+ }
+ // option lists
+ $jsParts = array();
+ for ($i = 1; $i < $this->_nbElements; $i++) {
+ $jsParts[] = $this->_convertArrayToJavascript($this->_options[$i]);
+ }
+ $this->_js .= "\n_hs_options['" . $this->_escapeString($this->getName()) . "'] = [\n" .
+ implode(",\n", $jsParts) .
+ "\n];\n";
+ // default value; if we don't actually have any values yet just use
+ // the first option (for single selects) or empty array (for multiple)
+ $values = array();
+ foreach (array_keys($this->_elements) as $key) {
+ if (is_array($v = $this->_elements[$key]->getValue())) {
+ $values[] = count($v) > 1? $v: $v[0];
+ } else {
+ // XXX: accessing the supposedly private _options array
+ $values[] = $this->_elements[$key]->getMultiple() || empty($this->_elements[$key]->_options[0])?
+ array():
+ $this->_elements[$key]->_options[0]['attr']['value'];
+ }
+ }
+ $this->_js .= "_hs_defaults['" . $this->_escapeString($this->getName()) . "'] = " .
+ $this->_convertArrayToJavascript($values, false) . ";\n";
+ }
+ include_once('HTML/QuickForm/Renderer/Default.php');
+ $renderer =& new HTML_QuickForm_Renderer_Default();
+ $renderer->setElementTemplate('{element}');
+ parent::accept($renderer);
+
+ if (!empty($onChange)) {
+ $keys = array_keys($this->_elements);
+ for ($i = 0; $i < count($keys) - 1; $i++) {
+ $this->_elements[$keys[$i]]->updateAttributes(array('onchange' => $onChange[$i]));
+ }
+ }
+ return (empty($this->_js)? '': "<script type=\"text/javascript\">\n//<![CDATA[\n" . $this->_js . "//]]>\n</script>") .
+ $renderer->toHtml();
+ } // end func toHtml
+
+ // }}}
+ // {{{ accept()
+
+ function accept(&$renderer, $required = false, $error = null)
+ {
+ $renderer->renderElement($this, $required, $error);
+ } // end func accept
+
+ // }}}
+ // {{{ onQuickFormEvent()
+
+ function onQuickFormEvent($event, $arg, &$caller)
+ {
+ if ('updateValue' == $event) {
+ // we need to call setValue() so that the secondary option
+ // matches the main option
+ return HTML_QuickForm_element::onQuickFormEvent($event, $arg, $caller);
+ } else {
+ $ret = parent::onQuickFormEvent($event, $arg, $caller);
+ // add onreset handler to form to properly reset hierselect (see bug #2970)
+ if ('addElement' == $event) {
+ $onReset = $caller->getAttribute('onreset');
+ if (strlen($onReset)) {
+ if (strpos($onReset, '_hs_setupOnReset')) {
+ $caller->updateAttributes(array('onreset' => str_replace('_hs_setupOnReset(this, [', "_hs_setupOnReset(this, ['" . $this->_escapeString($this->getName()) . "', ", $onReset)));
+ } else {
+ $caller->updateAttributes(array('onreset' => "var temp = function() { {$onReset} } ; if (!temp()) { return false; } ; if (typeof _hs_setupOnReset != 'undefined') { return _hs_setupOnReset(this, ['" . $this->_escapeString($this->getName()) . "']); } "));
+ }
+ } else {
+ $caller->updateAttributes(array('onreset' => "if (typeof _hs_setupOnReset != 'undefined') { return _hs_setupOnReset(this, ['" . $this->_escapeString($this->getName()) . "']); } "));
+ }
+ }
+ return $ret;
+ }
+ } // end func onQuickFormEvent
+
+ // }}}
+ // {{{ _convertArrayToJavascript()
+
+ /**
+ * Converts PHP array to its Javascript analog
+ *
+ * @access private
+ * @param array PHP array to convert
+ * @param bool Generate Javascript object literal (default, works like PHP's associative array) or array literal
+ * @return string Javascript representation of the value
+ */
+ function _convertArrayToJavascript($array, $assoc = true)
+ {
+ if (!is_array($array)) {
+ return $this->_convertScalarToJavascript($array);
+ } else {
+ $items = array();
+ foreach ($array as $key => $val) {
+ $item = $assoc? "'" . $this->_escapeString($key) . "': ": '';
+ if (is_array($val)) {
+ $item .= $this->_convertArrayToJavascript($val, $assoc);
+ } else {
+ $item .= $this->_convertScalarToJavascript($val);
+ }
+ $items[] = $item;
+ }
+ }
+ $js = implode(', ', $items);
+ return $assoc? '{ ' . $js . ' }': '[' . $js . ']';
+ }
+
+ // }}}
+ // {{{ _convertScalarToJavascript()
+
+ /**
+ * Converts PHP's scalar value to its Javascript analog
+ *
+ * @access private
+ * @param mixed PHP value to convert
+ * @return string Javascript representation of the value
+ */
+ function _convertScalarToJavascript($val)
+ {
+ if (is_bool($val)) {
+ return $val ? 'true' : 'false';
+ } elseif (is_int($val) || is_double($val)) {
+ return $val;
+ } elseif (is_string($val)) {
+ return "'" . $this->_escapeString($val) . "'";
+ } elseif (is_null($val)) {
+ return 'null';
+ } else {
+ // don't bother
+ return '{}';
+ }
+ }
+
+ // }}}
+ // {{{ _escapeString()
+
+ /**
+ * Quotes the string so that it can be used in Javascript string constants
+ *
+ * @access private
+ * @param string
+ * @return string
+ */
+ function _escapeString($str)
+ {
+ return strtr($str,array(
+ "\r" => '\r',
+ "\n" => '\n',
+ "\t" => '\t',
+ "'" => "\\'",
+ '"' => '\"',
+ '\\' => '\\\\'
+ ));
+ }
+
+ // }}}
+} // end class HTML_QuickForm_hierselect
+?>
\ No newline at end of file
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP version 4.0 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2003 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Author: Alexey Borzov <borz_off@cs.msu.su> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+require_once 'HTML/QuickForm/static.php';
+
+/**
+ * A pseudo-element used for adding raw HTML to form
+ *
+ * Intended for use with the default renderer only, template-based
+ * ones may (and probably will) completely ignore this
+ *
+ * @author Alexey Borzov <borz_off@cs.msu.su>
+ * @access public
+ */
+class HTML_QuickForm_html extends HTML_QuickForm_static
+{
+ // {{{ constructor
+
+ /**
+ * Class constructor
+ *
+ * @param string $text raw HTML to add
+ * @access public
+ * @return void
+ */
+ function HTML_QuickForm_html($text = null)
+ {
+ $this->HTML_QuickForm_static(null, null, $text);
+ $this->_type = 'html';
+ }
+
+ // }}}
+ // {{{ accept()
+
+ /**
+ * Accepts a renderer
+ *
+ * @param object An HTML_QuickForm_Renderer object
+ * @access public
+ * @return void
+ */
+ function accept(&$renderer)
+ {
+ $renderer->renderHtml($this);
+ } // end func accept
+
+ // }}}
+
+} //end class HTML_QuickForm_header
+?>
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP version 4.0 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> |
+// | Bertrand Mansion <bmansion@mamasam.com> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+require_once("HTML/QuickForm/input.php");
+
+/**
+ * HTML class for a image type element
+ *
+ * @author Adam Daniel <adaniel1@eesus.jnj.com>
+ * @author Bertrand Mansion <bmansion@mamasam.com>
+ * @version 1.0
+ * @since PHP4.04pl1
+ * @access public
+ */
+class HTML_QuickForm_image extends HTML_QuickForm_input
+{
+ // {{{ constructor
+
+ /**
+ * Class constructor
+ *
+ * @param string $elementName (optional)Element name attribute
+ * @param string $src (optional)Image source
+ * @param mixed $attributes (optional)Either a typical HTML attribute string
+ * or an associative array
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function HTML_QuickForm_image($elementName=null, $src='', $attributes=null)
+ {
+ HTML_QuickForm_input::HTML_QuickForm_input($elementName, null, $attributes);
+ $this->setType('image');
+ $this->setSource($src);
+ } // end class constructor
+
+ // }}}
+ // {{{ setSource()
+
+ /**
+ * Sets source for image element
+ *
+ * @param string $src source for image element
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function setSource($src)
+ {
+ $this->updateAttributes(array('src' => $src));
+ } // end func setSource
+
+ // }}}
+ // {{{ setBorder()
+
+ /**
+ * Sets border size for image element
+ *
+ * @param string $border border for image element
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function setBorder($border)
+ {
+ $this->updateAttributes(array('border' => $border));
+ } // end func setBorder
+
+ // }}}
+ // {{{ setAlign()
+
+ /**
+ * Sets alignment for image element
+ *
+ * @param string $align alignment for image element
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function setAlign($align)
+ {
+ $this->updateAttributes(array('align' => $align));
+ } // end func setAlign
+
+ // }}}
+ // {{{ freeze()
+
+ /**
+ * Freeze the element so that only its value is returned
+ *
+ * @access public
+ * @return void
+ */
+ function freeze()
+ {
+ return false;
+ } //end func freeze
+
+ // }}}
+
+} // end class HTML_QuickForm_image
+?>
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP version 4.0 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> |
+// | Bertrand Mansion <bmansion@mamasam.com> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+require_once("HTML/QuickForm/element.php");
+
+/**
+ * Base class for input form elements
+ *
+ * @author Adam Daniel <adaniel1@eesus.jnj.com>
+ * @author Bertrand Mansion <bmansion@mamasam.com>
+ * @version 1.0
+ * @since PHP4.04pl1
+ * @access public
+ * @abstract
+ */
+class HTML_QuickForm_input extends HTML_QuickForm_element
+{
+ // {{{ constructor
+
+ /**
+ * Class constructor
+ *
+ * @param string Input field name attribute
+ * @param mixed Label(s) for the input field
+ * @param mixed Either a typical HTML attribute string or an associative array
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function HTML_QuickForm_input($elementName=null, $elementLabel=null, $attributes=null)
+ {
+ $this->HTML_QuickForm_element($elementName, $elementLabel, $attributes);
+ } //end constructor
+
+ // }}}
+ // {{{ setType()
+
+ /**
+ * Sets the element type
+ *
+ * @param string $type Element type
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function setType($type)
+ {
+ $this->_type = $type;
+ $this->updateAttributes(array('type'=>$type));
+ } // end func setType
+
+ // }}}
+ // {{{ setName()
+
+ /**
+ * Sets the input field name
+ *
+ * @param string $name Input field name attribute
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function setName($name)
+ {
+ $this->updateAttributes(array('name'=>$name));
+ } //end func setName
+
+ // }}}
+ // {{{ getName()
+
+ /**
+ * Returns the element name
+ *
+ * @since 1.0
+ * @access public
+ * @return string
+ */
+ function getName()
+ {
+ return $this->getAttribute('name');
+ } //end func getName
+
+ // }}}
+ // {{{ setValue()
+
+ /**
+ * Sets the value of the form element
+ *
+ * @param string $value Default value of the form element
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function setValue($value)
+ {
+ $this->updateAttributes(array('value'=>$value));
+ } // end func setValue
+
+ // }}}
+ // {{{ getValue()
+
+ /**
+ * Returns the value of the form element
+ *
+ * @since 1.0
+ * @access public
+ * @return string
+ */
+ function getValue()
+ {
+ return $this->getAttribute('value');
+ } // end func getValue
+
+ // }}}
+ // {{{ toHtml()
+
+ /**
+ * Returns the input field in HTML
+ *
+ * @since 1.0
+ * @access public
+ * @return string
+ */
+ function toHtml()
+ {
+ if ($this->_flagFrozen) {
+ return $this->getFrozenHtml();
+ } else {
+ return $this->_getTabs() . '<input' . $this->_getAttrString($this->_attributes) . ' />';
+ }
+ } //end func toHtml
+
+ // }}}
+ // {{{ onQuickFormEvent()
+
+ /**
+ * Called by HTML_QuickForm whenever form event is made on this element
+ *
+ * @param string $event Name of event
+ * @param mixed $arg event arguments
+ * @param object $caller calling object
+ * @since 1.0
+ * @access public
+ * @return void
+ * @throws
+ */
+ function onQuickFormEvent($event, $arg, &$caller)
+ {
+ // do not use submit values for button-type elements
+ $type = $this->getType();
+ if (('updateValue' != $event) ||
+ ('submit' != $type && 'reset' != $type && 'image' != $type && 'button' != $type)) {
+ parent::onQuickFormEvent($event, $arg, $caller);
+ } else {
+ $value = $this->_findValue($caller->_constantValues);
+ if (null === $value) {
+ $value = $this->_findValue($caller->_defaultValues);
+ }
+ if (null !== $value) {
+ $this->setValue($value);
+ }
+ }
+ return true;
+ } // end func onQuickFormEvent
+
+ // }}}
+ // {{{ exportValue()
+
+ /**
+ * We don't need values from button-type elements (except submit) and files
+ */
+ function exportValue(&$submitValues, $assoc = false)
+ {
+ $type = $this->getType();
+ if ('reset' == $type || 'image' == $type || 'button' == $type || 'file' == $type) {
+ return null;
+ } else {
+ return parent::exportValue($submitValues, $assoc);
+ }
+ }
+
+ // }}}
+} // end class HTML_QuickForm_element
+?>
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP version 4.0 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> |
+// | Bertrand Mansion <bmansion@mamasam.com> |
+// +----------------------------------------------------------------------+
+//
+
+require_once 'HTML/QuickForm/static.php';
+
+/**
+ * HTML class for a link type field
+ *
+ * @author Adam Daniel <adaniel1@eesus.jnj.com>
+ * @author Bertrand Mansion <bmansion@mamasam.com>
+ * @version 1.0
+ * @since PHP4.04pl1
+ * @access public
+ */
+class HTML_QuickForm_link extends HTML_QuickForm_static
+{
+ // {{{ properties
+
+ /**
+ * Link display text
+ * @var string
+ * @since 1.0
+ * @access private
+ */
+ var $_text = "";
+
+ // }}}
+ // {{{ constructor
+
+ /**
+ * Class constructor
+ *
+ * @param string $elementLabel (optional)Link label
+ * @param string $href (optional)Link href
+ * @param string $text (optional)Link display text
+ * @param mixed $attributes (optional)Either a typical HTML attribute string
+ * or an associative array
+ * @since 1.0
+ * @access public
+ * @return void
+ * @throws
+ */
+ function HTML_QuickForm_link($elementName=null, $elementLabel=null, $href=null, $text=null, $attributes=null)
+ {
+ HTML_QuickForm_element::HTML_QuickForm_element($elementName, $elementLabel, $attributes);
+ $this->_persistantFreeze = false;
+ $this->_type = 'link';
+ $this->setHref($href);
+ $this->_text = $text;
+ } //end constructor
+
+ // }}}
+ // {{{ setName()
+
+ /**
+ * Sets the input field name
+ *
+ * @param string $name Input field name attribute
+ * @since 1.0
+ * @access public
+ * @return void
+ * @throws
+ */
+ function setName($name)
+ {
+ $this->updateAttributes(array('name'=>$name));
+ } //end func setName
+
+ // }}}
+ // {{{ getName()
+
+ /**
+ * Returns the element name
+ *
+ * @since 1.0
+ * @access public
+ * @return string
+ * @throws
+ */
+ function getName()
+ {
+ return $this->getAttribute('name');
+ } //end func getName
+
+ // }}}
+ // {{{ setValue()
+
+ /**
+ * Sets value for textarea element
+ *
+ * @param string $value Value for password element
+ * @since 1.0
+ * @access public
+ * @return void
+ * @throws
+ */
+ function setValue($value)
+ {
+ return;
+ } //end func setValue
+
+ // }}}
+ // {{{ getValue()
+
+ /**
+ * Returns the value of the form element
+ *
+ * @since 1.0
+ * @access public
+ * @return void
+ * @throws
+ */
+ function getValue()
+ {
+ return;
+ } // end func getValue
+
+
+ // }}}
+ // {{{ setHref()
+
+ /**
+ * Sets the links href
+ *
+ * @param string $href
+ * @since 1.0
+ * @access public
+ * @return void
+ * @throws
+ */
+ function setHref($href)
+ {
+ $this->updateAttributes(array('href'=>$href));
+ } // end func setHref
+
+ // }}}
+ // {{{ toHtml()
+
+ /**
+ * Returns the textarea element in HTML
+ *
+ * @since 1.0
+ * @access public
+ * @return string
+ * @throws
+ */
+ function toHtml()
+ {
+ $tabs = $this->_getTabs();
+ $html = "$tabs<a".$this->_getAttrString($this->_attributes).">";
+ $html .= $this->_text;
+ $html .= "</a>";
+ return $html;
+ } //end func toHtml
+
+ // }}}
+ // {{{ getFrozenHtml()
+
+ /**
+ * Returns the value of field without HTML tags (in this case, value is changed to a mask)
+ *
+ * @since 1.0
+ * @access public
+ * @return string
+ * @throws
+ */
+ function getFrozenHtml()
+ {
+ return;
+ } //end func getFrozenHtml
+
+ // }}}
+
+} //end class HTML_QuickForm_textarea
+?>
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP version 4.0 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> |
+// | Bertrand Mansion <bmansion@mamasam.com> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+require_once("HTML/QuickForm/input.php");
+
+/**
+ * HTML class for a password type field
+ *
+ * @author Adam Daniel <adaniel1@eesus.jnj.com>
+ * @author Bertrand Mansion <bmansion@mamasam.com>
+ * @version 1.1
+ * @since PHP4.04pl1
+ * @access public
+ */
+class HTML_QuickForm_password extends HTML_QuickForm_input
+{
+ // {{{ constructor
+
+ /**
+ * Class constructor
+ *
+ * @param string $elementName (optional)Input field name attribute
+ * @param string $elementLabel (optional)Input field label
+ * @param mixed $attributes (optional)Either a typical HTML attribute string
+ * or an associative array
+ * @since 1.0
+ * @access public
+ * @return void
+ * @throws
+ */
+ function HTML_QuickForm_password($elementName=null, $elementLabel=null, $attributes=null)
+ {
+ HTML_QuickForm_input::HTML_QuickForm_input($elementName, $elementLabel, $attributes);
+ $this->setType('password');
+ } //end constructor
+
+ // }}}
+ // {{{ setSize()
+
+ /**
+ * Sets size of password element
+ *
+ * @param string $size Size of password field
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function setSize($size)
+ {
+ $this->updateAttributes(array('size'=>$size));
+ } //end func setSize
+
+ // }}}
+ // {{{ setMaxlength()
+
+ /**
+ * Sets maxlength of password element
+ *
+ * @param string $maxlength Maximum length of password field
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function setMaxlength($maxlength)
+ {
+ $this->updateAttributes(array('maxlength'=>$maxlength));
+ } //end func setMaxlength
+
+ // }}}
+ // {{{ getFrozenHtml()
+
+ /**
+ * Returns the value of field without HTML tags (in this case, value is changed to a mask)
+ *
+ * @since 1.0
+ * @access public
+ * @return string
+ * @throws
+ */
+ function getFrozenHtml()
+ {
+ $value = $this->getValue();
+ return ('' != $value? '**********': ' ') .
+ $this->_getPersistantData();
+ } //end func getFrozenHtml
+
+ // }}}
+
+} //end class HTML_QuickForm_password
+?>
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP version 4.0 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> |
+// | Bertrand Mansion <bmansion@mamasam.com> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+require_once('HTML/QuickForm/input.php');
+
+/**
+ * HTML class for a radio type element
+ *
+ * @author Adam Daniel <adaniel1@eesus.jnj.com>
+ * @author Bertrand Mansion <bmansion@mamasam.com>
+ * @version 1.1
+ * @since PHP4.04pl1
+ * @access public
+ */
+class HTML_QuickForm_radio extends HTML_QuickForm_input
+{
+ // {{{ properties
+
+ /**
+ * Radio display text
+ * @var string
+ * @since 1.1
+ * @access private
+ */
+ var $_text = '';
+
+ // }}}
+ // {{{ constructor
+
+ /**
+ * Class constructor
+ *
+ * @param string Input field name attribute
+ * @param mixed Label(s) for a field
+ * @param string Text to display near the radio
+ * @param string Input field value
+ * @param mixed Either a typical HTML attribute string or an associative array
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function HTML_QuickForm_radio($elementName=null, $elementLabel=null, $text=null, $value=null, $attributes=null)
+ {
+ $this->HTML_QuickForm_element($elementName, $elementLabel, $attributes);
+ if (isset($value)) {
+ $this->setValue($value);
+ }
+ $this->_persistantFreeze = true;
+ $this->setType('radio');
+ $this->_text = $text;
+ $this->_generateId();
+ } //end constructor
+
+ // }}}
+ // {{{ setChecked()
+
+ /**
+ * Sets whether radio button is checked
+ *
+ * @param bool $checked Whether the field is checked or not
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function setChecked($checked)
+ {
+ if (!$checked) {
+ $this->removeAttribute('checked');
+ } else {
+ $this->updateAttributes(array('checked'=>'checked'));
+ }
+ } //end func setChecked
+
+ // }}}
+ // {{{ getChecked()
+
+ /**
+ * Returns whether radio button is checked
+ *
+ * @since 1.0
+ * @access public
+ * @return string
+ */
+ function getChecked()
+ {
+ return $this->getAttribute('checked');
+ } //end func getChecked
+
+ // }}}
+ // {{{ toHtml()
+
+ /**
+ * Returns the radio element in HTML
+ *
+ * @since 1.0
+ * @access public
+ * @return string
+ */
+ function toHtml()
+ {
+ if (0 == strlen($this->_text)) {
+ $label = '';
+ } elseif ($this->_flagFrozen) {
+ $label = $this->_text;
+ } else {
+ $label = '<label for="' . $this->getAttribute('id') . '">' . $this->_text . '</label>';
+ }
+ return HTML_QuickForm_input::toHtml() . $label;
+ } //end func toHtml
+
+ // }}}
+ // {{{ getFrozenHtml()
+
+ /**
+ * Returns the value of field without HTML tags
+ *
+ * @since 1.0
+ * @access public
+ * @return string
+ */
+ function getFrozenHtml()
+ {
+ if ($this->getChecked()) {
+ return '<tt>(x)</tt>' .
+ $this->_getPersistantData();
+ } else {
+ return '<tt>( )</tt>';
+ }
+ } //end func getFrozenHtml
+
+ // }}}
+ // {{{ setText()
+
+ /**
+ * Sets the radio text
+ *
+ * @param string $text Text to display near the radio button
+ * @since 1.1
+ * @access public
+ * @return void
+ */
+ function setText($text)
+ {
+ $this->_text = $text;
+ } //end func setText
+
+ // }}}
+ // {{{ getText()
+
+ /**
+ * Returns the radio text
+ *
+ * @since 1.1
+ * @access public
+ * @return string
+ */
+ function getText()
+ {
+ return $this->_text;
+ } //end func getText
+
+ // }}}
+ // {{{ onQuickFormEvent()
+
+ /**
+ * Called by HTML_QuickForm whenever form event is made on this element
+ *
+ * @param string $event Name of event
+ * @param mixed $arg event arguments
+ * @param object $caller calling object
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function onQuickFormEvent($event, $arg, &$caller)
+ {
+ switch ($event) {
+ case 'updateValue':
+ // constant values override both default and submitted ones
+ // default values are overriden by submitted
+ $value = $this->_findValue($caller->_constantValues);
+ if (null === $value) {
+ $value = $this->_findValue($caller->_submitValues);
+ if (null === $value) {
+ $value = $this->_findValue($caller->_defaultValues);
+ }
+ }
+ if ($value == $this->getValue()) {
+ $this->setChecked(true);
+ } else {
+ $this->setChecked(false);
+ }
+ break;
+ case 'setGroupValue':
+ if ($arg == $this->getValue()) {
+ $this->setChecked(true);
+ } else {
+ $this->setChecked(false);
+ }
+ break;
+ default:
+ parent::onQuickFormEvent($event, $arg, $caller);
+ }
+ return true;
+ } // end func onQuickFormLoad
+
+ // }}}
+ // {{{ exportValue()
+
+ /**
+ * Returns the value attribute if the radio is checked, null if it is not
+ */
+ function exportValue(&$submitValues, $assoc = false)
+ {
+ $value = $this->_findValue($submitValues);
+ if (null === $value) {
+ $value = $this->getChecked()? $this->getValue(): null;
+ } elseif ($value != $this->getValue()) {
+ $value = null;
+ }
+ return $this->_prepareValue($value, $assoc);
+ }
+
+ // }}}
+} //end class HTML_QuickForm_radio
+?>
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP version 4.0 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> |
+// | Bertrand Mansion <bmansion@mamasam.com> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+require_once("HTML/QuickForm/input.php");
+
+/**
+ * HTML class for a reset type element
+ *
+ * @author Adam Daniel <adaniel1@eesus.jnj.com>
+ * @author Bertrand Mansion <bmansion@mamasam.com>
+ * @version 1.1
+ * @since PHP4.04pl1
+ * @access public
+ */
+class HTML_QuickForm_reset extends HTML_QuickForm_input
+{
+ // {{{ constructor
+
+ /**
+ * Class constructor
+ *
+ * @param string $elementName (optional)Input field name attribute
+ * @param string $value (optional)Input field value
+ * @param mixed $attributes (optional)Either a typical HTML attribute string
+ * or an associative array
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function HTML_QuickForm_reset($elementName=null, $value=null, $attributes=null)
+ {
+ HTML_QuickForm_input::HTML_QuickForm_input($elementName, null, $attributes);
+ $this->setValue($value);
+ $this->setType('reset');
+ } //end constructor
+
+ // }}}
+ // {{{ freeze()
+
+ /**
+ * Freeze the element so that only its value is returned
+ *
+ * @access public
+ * @return void
+ */
+ function freeze()
+ {
+ return false;
+ } //end func freeze
+
+ // }}}
+
+} //end class HTML_QuickForm_reset
+?>
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP version 4.0 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2003 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> |
+// | Bertrand Mansion <bmansion@mamasam.com> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+require_once('HTML/QuickForm/element.php');
+
+/**
+ * Class to dynamically create an HTML SELECT
+ *
+ * @author Adam Daniel <adaniel1@eesus.jnj.com>
+ * @author Bertrand Mansion <bmansion@mamasam.com>
+ * @version 1.0
+ * @since PHP4.04pl1
+ * @access public
+ */
+class HTML_QuickForm_select extends HTML_QuickForm_element {
+
+ // {{{ properties
+
+ /**
+ * Contains the select options
+ *
+ * @var array
+ * @since 1.0
+ * @access private
+ */
+ var $_options = array();
+
+ /**
+ * Default values of the SELECT
+ *
+ * @var string
+ * @since 1.0
+ * @access private
+ */
+ var $_values = null;
+
+ // }}}
+ // {{{ constructor
+
+ /**
+ * Class constructor
+ *
+ * @param string Select name attribute
+ * @param mixed Label(s) for the select
+ * @param mixed Data to be used to populate options
+ * @param mixed Either a typical HTML attribute string or an associative array
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function HTML_QuickForm_select($elementName=null, $elementLabel=null, $options=null, $attributes=null)
+ {
+ HTML_QuickForm_element::HTML_QuickForm_element($elementName, $elementLabel, $attributes);
+ $this->_persistantFreeze = true;
+ $this->_type = 'select';
+ if (isset($options)) {
+ $this->load($options);
+ }
+ } //end constructor
+
+ // }}}
+ // {{{ apiVersion()
+
+ /**
+ * Returns the current API version
+ *
+ * @since 1.0
+ * @access public
+ * @return double
+ */
+ function apiVersion()
+ {
+ return 2.3;
+ } //end func apiVersion
+
+ // }}}
+ // {{{ setSelected()
+
+ /**
+ * Sets the default values of the select box
+ *
+ * @param mixed $values Array or comma delimited string of selected values
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function setSelected($values)
+ {
+ if (is_string($values) && $this->getMultiple()) {
+ $values = split("[ ]?,[ ]?", $values);
+ }
+ if (is_array($values)) {
+ $this->_values = array_values($values);
+ } else {
+ $this->_values = array($values);
+ }
+ } //end func setSelected
+
+ // }}}
+ // {{{ getSelected()
+
+ /**
+ * Returns an array of the selected values
+ *
+ * @since 1.0
+ * @access public
+ * @return array of selected values
+ */
+ function getSelected()
+ {
+ return $this->_values;
+ } // end func getSelected
+
+ // }}}
+ // {{{ setName()
+
+ /**
+ * Sets the input field name
+ *
+ * @param string $name Input field name attribute
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function setName($name)
+ {
+ $this->updateAttributes(array('name' => $name));
+ } //end func setName
+
+ // }}}
+ // {{{ getName()
+
+ /**
+ * Returns the element name
+ *
+ * @since 1.0
+ * @access public
+ * @return string
+ */
+ function getName()
+ {
+ return $this->getAttribute('name');
+ } //end func getName
+
+ // }}}
+ // {{{ getPrivateName()
+
+ /**
+ * Returns the element name (possibly with brackets appended)
+ *
+ * @since 1.0
+ * @access public
+ * @return string
+ */
+ function getPrivateName()
+ {
+ if ($this->getAttribute('multiple')) {
+ return $this->getName() . '[]';
+ } else {
+ return $this->getName();
+ }
+ } //end func getPrivateName
+
+ // }}}
+ // {{{ setValue()
+
+ /**
+ * Sets the value of the form element
+ *
+ * @param mixed $values Array or comma delimited string of selected values
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function setValue($value)
+ {
+ $this->setSelected($value);
+ } // end func setValue
+
+ // }}}
+ // {{{ getValue()
+
+ /**
+ * Returns an array of the selected values
+ *
+ * @since 1.0
+ * @access public
+ * @return array of selected values
+ */
+ function getValue()
+ {
+ return $this->_values;
+ } // end func getValue
+
+ // }}}
+ // {{{ setSize()
+
+ /**
+ * Sets the select field size, only applies to 'multiple' selects
+ *
+ * @param int $size Size of select field
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function setSize($size)
+ {
+ $this->updateAttributes(array('size' => $size));
+ } //end func setSize
+
+ // }}}
+ // {{{ getSize()
+
+ /**
+ * Returns the select field size
+ *
+ * @since 1.0
+ * @access public
+ * @return int
+ */
+ function getSize()
+ {
+ return $this->getAttribute('size');
+ } //end func getSize
+
+ // }}}
+ // {{{ setMultiple()
+
+ /**
+ * Sets the select mutiple attribute
+ *
+ * @param bool $multiple Whether the select supports multi-selections
+ * @since 1.2
+ * @access public
+ * @return void
+ */
+ function setMultiple($multiple)
+ {
+ if ($multiple) {
+ $this->updateAttributes(array('multiple' => 'multiple'));
+ } else {
+ $this->removeAttribute('multiple');
+ }
+ } //end func setMultiple
+
+ // }}}
+ // {{{ getMultiple()
+
+ /**
+ * Returns the select mutiple attribute
+ *
+ * @since 1.2
+ * @access public
+ * @return bool true if multiple select, false otherwise
+ */
+ function getMultiple()
+ {
+ return (bool)$this->getAttribute('multiple');
+ } //end func getMultiple
+
+ // }}}
+ // {{{ addOption()
+
+ /**
+ * Adds a new OPTION to the SELECT
+ *
+ * @param string $text Display text for the OPTION
+ * @param string $value Value for the OPTION
+ * @param mixed $attributes Either a typical HTML attribute string
+ * or an associative array
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function addOption($text, $value, $attributes=null)
+ {
+ if (null === $attributes) {
+ $attributes = array('value' => $value);
+ } else {
+ $attributes = $this->_parseAttributes($attributes);
+ if (isset($attributes['selected'])) {
+ // the 'selected' attribute will be set in toHtml()
+ $this->_removeAttr('selected', $attributes);
+ if (is_null($this->_values)) {
+ $this->_values = array($value);
+ } elseif (!in_array($value, $this->_values)) {
+ $this->_values[] = $value;
+ }
+ }
+ $this->_updateAttrArray($attributes, array('value' => $value));
+ }
+ $this->_options[] = array('text' => $text, 'attr' => $attributes);
+ } // end func addOption
+
+ // }}}
+ // {{{ loadArray()
+
+ /**
+ * Loads the options from an associative array
+ *
+ * @param array $arr Associative array of options
+ * @param mixed $values (optional) Array or comma delimited string of selected values
+ * @since 1.0
+ * @access public
+ * @return PEAR_Error on error or true
+ * @throws PEAR_Error
+ */
+ function loadArray($arr, $values=null)
+ {
+ if (!is_array($arr)) {
+ return PEAR::raiseError('Argument 1 of HTML_Select::loadArray is not a valid array');
+ }
+ if (isset($values)) {
+ $this->setSelected($values);
+ }
+ foreach ($arr as $key => $val) {
+ // Warning: new API since release 2.3
+ $this->addOption($val, $key);
+ }
+ return true;
+ } // end func loadArray
+
+ // }}}
+ // {{{ loadDbResult()
+
+ /**
+ * Loads the options from DB_result object
+ *
+ * If no column names are specified the first two columns of the result are
+ * used as the text and value columns respectively
+ * @param object $result DB_result object
+ * @param string $textCol (optional) Name of column to display as the OPTION text
+ * @param string $valueCol (optional) Name of column to use as the OPTION value
+ * @param mixed $values (optional) Array or comma delimited string of selected values
+ * @since 1.0
+ * @access public
+ * @return PEAR_Error on error or true
+ * @throws PEAR_Error
+ */
+ function loadDbResult(&$result, $textCol=null, $valueCol=null, $values=null)
+ {
+ if (!is_object($result) || !is_a($result, 'db_result')) {
+ return PEAR::raiseError('Argument 1 of HTML_Select::loadDbResult is not a valid DB_result');
+ }
+ if (isset($values)) {
+ $this->setValue($values);
+ }
+ $fetchMode = ($textCol && $valueCol) ? DB_FETCHMODE_ASSOC : DB_FETCHMODE_ORDERED;
+ while (is_array($row = $result->fetchRow($fetchMode)) ) {
+ if ($fetchMode == DB_FETCHMODE_ASSOC) {
+ $this->addOption($row[$textCol], $row[$valueCol]);
+ } else {
+ $this->addOption($row[0], $row[1]);
+ }
+ }
+ return true;
+ } // end func loadDbResult
+
+ // }}}
+ // {{{ loadQuery()
+
+ /**
+ * Queries a database and loads the options from the results
+ *
+ * @param mixed $conn Either an existing DB connection or a valid dsn
+ * @param string $sql SQL query string
+ * @param string $textCol (optional) Name of column to display as the OPTION text
+ * @param string $valueCol (optional) Name of column to use as the OPTION value
+ * @param mixed $values (optional) Array or comma delimited string of selected values
+ * @since 1.1
+ * @access public
+ * @return void
+ * @throws PEAR_Error
+ */
+ function loadQuery(&$conn, $sql, $textCol=null, $valueCol=null, $values=null)
+ {
+ if (is_string($conn)) {
+ require_once('DB.php');
+ $dbConn = &DB::connect($conn, true);
+ if (DB::isError($dbConn)) {
+ return $dbConn;
+ }
+ } elseif (is_subclass_of($conn, "db_common")) {
+ $dbConn = &$conn;
+ } else {
+ return PEAR::raiseError('Argument 1 of HTML_Select::loadQuery is not a valid type');
+ }
+ $result = $dbConn->query($sql);
+ if (DB::isError($result)) {
+ return $result;
+ }
+ $this->loadDbResult($result, $textCol, $valueCol, $values);
+ $result->free();
+ if (is_string($conn)) {
+ $dbConn->disconnect();
+ }
+ return true;
+ } // end func loadQuery
+
+ // }}}
+ // {{{ load()
+
+ /**
+ * Loads options from different types of data sources
+ *
+ * This method is a simulated overloaded method. The arguments, other than the
+ * first are optional and only mean something depending on the type of the first argument.
+ * If the first argument is an array then all arguments are passed in order to loadArray.
+ * If the first argument is a db_result then all arguments are passed in order to loadDbResult.
+ * If the first argument is a string or a DB connection then all arguments are
+ * passed in order to loadQuery.
+ * @param mixed $options Options source currently supports assoc array or DB_result
+ * @param mixed $param1 (optional) See function detail
+ * @param mixed $param2 (optional) See function detail
+ * @param mixed $param3 (optional) See function detail
+ * @param mixed $param4 (optional) See function detail
+ * @since 1.1
+ * @access public
+ * @return PEAR_Error on error or true
+ * @throws PEAR_Error
+ */
+ function load(&$options, $param1=null, $param2=null, $param3=null, $param4=null)
+ {
+ switch (true) {
+ case is_array($options):
+ return $this->loadArray($options, $param1);
+ break;
+ case (is_a($options, 'db_result')):
+ return $this->loadDbResult($options, $param1, $param2, $param3);
+ break;
+ case (is_string($options) && !empty($options) || is_subclass_of($options, "db_common")):
+ return $this->loadQuery($options, $param1, $param2, $param3, $param4);
+ break;
+ }
+ } // end func load
+
+ // }}}
+ // {{{ toHtml()
+
+ /**
+ * Returns the SELECT in HTML
+ *
+ * @since 1.0
+ * @access public
+ * @return string
+ */
+ function toHtml()
+ {
+ if ($this->_flagFrozen) {
+ return $this->getFrozenHtml();
+ } else {
+ $tabs = $this->_getTabs();
+ $strHtml = '';
+
+ if ($this->getComment() != '') {
+ $strHtml .= $tabs . '<!-- ' . $this->getComment() . " //-->\n";
+ }
+
+ if (!$this->getMultiple()) {
+ $attrString = $this->_getAttrString($this->_attributes);
+ } else {
+ $myName = $this->getName();
+ $this->setName($myName . '[]');
+ $attrString = $this->_getAttrString($this->_attributes);
+ $this->setName($myName);
+ }
+ $strHtml .= $tabs . '<select' . $attrString . ">\n";
+
+ foreach ($this->_options as $option) {
+ if (is_array($this->_values) && in_array((string)$option['attr']['value'], $this->_values)) {
+ $this->_updateAttrArray($option['attr'], array('selected' => 'selected'));
+ }
+ $strHtml .= $tabs . "\t<option" . $this->_getAttrString($option['attr']) . '>' .
+ $option['text'] . "</option>\n";
+ }
+
+ return $strHtml . $tabs . '</select>';
+ }
+ } //end func toHtml
+
+ // }}}
+ // {{{ getFrozenHtml()
+
+ /**
+ * Returns the value of field without HTML tags
+ *
+ * @since 1.0
+ * @access public
+ * @return string
+ */
+ function getFrozenHtml()
+ {
+ $value = array();
+ if (is_array($this->_values)) {
+ foreach ($this->_values as $key => $val) {
+ for ($i = 0, $optCount = count($this->_options); $i < $optCount; $i++) {
+ if ((string)$val == (string)$this->_options[$i]['attr']['value']) {
+ $value[$key] = $this->_options[$i]['text'];
+ break;
+ }
+ }
+ }
+ }
+ $html = empty($value)? ' ': join('<br />', $value);
+ if ($this->_persistantFreeze) {
+ $name = $this->getPrivateName();
+ // Only use id attribute if doing single hidden input
+ if (1 == count($value)) {
+ $id = $this->getAttribute('id');
+ $idAttr = isset($id)? array('id' => $id): array();
+ } else {
+ $idAttr = array();
+ }
+ foreach ($value as $key => $item) {
+ $html .= '<input' . $this->_getAttrString(array(
+ 'type' => 'hidden',
+ 'name' => $name,
+ 'value' => $this->_values[$key]
+ ) + $idAttr) . ' />';
+ }
+ }
+ return $html;
+ } //end func getFrozenHtml
+
+ // }}}
+ // {{{ exportValue()
+
+ /**
+ * We check the options and return only the values that _could_ have been
+ * selected. We also return a scalar value if select is not "multiple"
+ */
+ function exportValue(&$submitValues, $assoc = false)
+ {
+ $value = $this->_findValue($submitValues);
+ if (is_null($value)) {
+ $value = $this->getValue();
+ } elseif(!is_array($value)) {
+ $value = array($value);
+ }
+ if (is_array($value) && !empty($this->_options)) {
+ $cleanValue = null;
+ foreach ($value as $v) {
+ for ($i = 0, $optCount = count($this->_options); $i < $optCount; $i++) {
+ if ($v == $this->_options[$i]['attr']['value']) {
+ $cleanValue[] = $v;
+ break;
+ }
+ }
+ }
+ } else {
+ $cleanValue = $value;
+ }
+ if (is_array($cleanValue) && !$this->getMultiple()) {
+ return $this->_prepareValue($cleanValue[0], $assoc);
+ } else {
+ return $this->_prepareValue($cleanValue, $assoc);
+ }
+ }
+
+ // }}}
+ // {{{ onQuickFormEvent()
+
+ function onQuickFormEvent($event, $arg, &$caller)
+ {
+ if ('updateValue' == $event) {
+ $value = $this->_findValue($caller->_constantValues);
+ if (null === $value) {
+ $value = $this->_findValue($caller->_submitValues);
+ // Fix for bug #4465 & #5269
+ // XXX: should we push this to element::onQuickFormEvent()?
+ if (null === $value && (!$caller->isSubmitted() || !$this->getMultiple())) {
+ $value = $this->_findValue($caller->_defaultValues);
+ }
+ }
+ if (null !== $value) {
+ $this->setValue($value);
+ }
+ return true;
+ } else {
+ return parent::onQuickFormEvent($event, $arg, $caller);
+ }
+ }
+
+ // }}}
+} //end class HTML_QuickForm_select
+?>
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP version 4.0 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2003 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> |
+// | Bertrand Mansion <bmansion@mamasam.com> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+require_once("HTML/QuickForm/element.php");
+
+/**
+ * HTML class for static data
+ *
+ * @author Wojciech Gdela <eltehaem@poczta.onet.pl>
+ * @access public
+ */
+class HTML_QuickForm_static extends HTML_QuickForm_element {
+
+ // {{{ properties
+
+ /**
+ * Display text
+ * @var string
+ * @access private
+ */
+ var $_text = null;
+
+ // }}}
+ // {{{ constructor
+
+ /**
+ * Class constructor
+ *
+ * @param string $elementLabel (optional)Label
+ * @param string $text (optional)Display text
+ * @access public
+ * @return void
+ */
+ function HTML_QuickForm_static($elementName=null, $elementLabel=null, $text=null)
+ {
+ HTML_QuickForm_element::HTML_QuickForm_element($elementName, $elementLabel);
+ $this->_persistantFreeze = false;
+ $this->_type = 'static';
+ $this->_text = $text;
+ } //end constructor
+
+ // }}}
+ // {{{ setName()
+
+ /**
+ * Sets the element name
+ *
+ * @param string $name Element name
+ * @access public
+ * @return void
+ */
+ function setName($name)
+ {
+ $this->updateAttributes(array('name'=>$name));
+ } //end func setName
+
+ // }}}
+ // {{{ getName()
+
+ /**
+ * Returns the element name
+ *
+ * @access public
+ * @return string
+ */
+ function getName()
+ {
+ return $this->getAttribute('name');
+ } //end func getName
+
+ // }}}
+ // {{{ setText()
+
+ /**
+ * Sets the text
+ *
+ * @param string $text
+ * @access public
+ * @return void
+ */
+ function setText($text)
+ {
+ $this->_text = $text;
+ } // end func setText
+
+ // }}}
+ // {{{ setValue()
+
+ /**
+ * Sets the text (uses the standard setValue call to emulate a form element.
+ *
+ * @param string $text
+ * @access public
+ * @return void
+ */
+ function setValue($text)
+ {
+ $this->setText($text);
+ } // end func setValue
+
+ // }}}
+ // {{{ toHtml()
+
+ /**
+ * Returns the static text element in HTML
+ *
+ * @access public
+ * @return string
+ */
+ function toHtml()
+ {
+ return $this->_getTabs() . $this->_text;
+ } //end func toHtml
+
+ // }}}
+ // {{{ getFrozenHtml()
+
+ /**
+ * Returns the value of field without HTML tags
+ *
+ * @access public
+ * @return string
+ */
+ function getFrozenHtml()
+ {
+ return $this->toHtml();
+ } //end func getFrozenHtml
+
+ // }}}
+ // {{{ onQuickFormEvent()
+
+ /**
+ * Called by HTML_QuickForm whenever form event is made on this element
+ *
+ * @param string $event Name of event
+ * @param mixed $arg event arguments
+ * @param object $caller calling object
+ * @since 1.0
+ * @access public
+ * @return void
+ * @throws
+ */
+ function onQuickFormEvent($event, $arg, &$caller)
+ {
+ switch ($event) {
+ case 'updateValue':
+ // do NOT use submitted values for static elements
+ $value = $this->_findValue($caller->_constantValues);
+ if (null === $value) {
+ $value = $this->_findValue($caller->_defaultValues);
+ }
+ if (null !== $value) {
+ $this->setValue($value);
+ }
+ break;
+ default:
+ parent::onQuickFormEvent($event, $arg, $caller);
+ }
+ return true;
+ } // end func onQuickFormEvent
+
+ // }}}
+ // {{{ exportValue()
+
+ /**
+ * We override this here because we don't want any values from static elements
+ */
+ function exportValue(&$submitValues, $assoc = false)
+ {
+ return null;
+ }
+
+ // }}}
+} //end class HTML_QuickForm_static
+?>
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP version 4.0 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> |
+// | Bertrand Mansion <bmansion@mamasam.com> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+require_once("HTML/QuickForm/input.php");
+
+/**
+ * HTML class for a submit type element
+ *
+ * @author Adam Daniel <adaniel1@eesus.jnj.com>
+ * @author Bertrand Mansion <bmansion@mamasam.com>
+ * @version 1.0
+ * @since PHP4.04pl1
+ * @access public
+ */
+class HTML_QuickForm_submit extends HTML_QuickForm_input
+{
+ // {{{ constructor
+
+ /**
+ * Class constructor
+ *
+ * @param string Input field name attribute
+ * @param string Input field value
+ * @param mixed Either a typical HTML attribute string or an associative array
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function HTML_QuickForm_submit($elementName=null, $value=null, $attributes=null)
+ {
+ HTML_QuickForm_input::HTML_QuickForm_input($elementName, null, $attributes);
+ $this->setValue($value);
+ $this->setType('submit');
+ } //end constructor
+
+ // }}}
+ // {{{ freeze()
+
+ /**
+ * Freeze the element so that only its value is returned
+ *
+ * @access public
+ * @return void
+ */
+ function freeze()
+ {
+ return false;
+ } //end func freeze
+
+ // }}}
+ // {{{ exportValue()
+
+ /**
+ * Only return the value if it is found within $submitValues (i.e. if
+ * this particular submit button was clicked)
+ */
+ function exportValue(&$submitValues, $assoc = false)
+ {
+ return $this->_prepareValue($this->_findValue($submitValues), $assoc);
+ }
+
+ // }}}
+} //end class HTML_QuickForm_submit
+?>
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP version 4.0 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> |
+// | Bertrand Mansion <bmansion@mamasam.com> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+require_once("HTML/QuickForm/input.php");
+
+/**
+ * HTML class for a text field
+ *
+ * @author Adam Daniel <adaniel1@eesus.jnj.com>
+ * @author Bertrand Mansion <bmansion@mamasam.com>
+ * @version 1.0
+ * @since PHP4.04pl1
+ * @access public
+ */
+class HTML_QuickForm_text extends HTML_QuickForm_input
+{
+
+ // {{{ constructor
+
+ /**
+ * Class constructor
+ *
+ * @param string $elementName (optional)Input field name attribute
+ * @param string $elementLabel (optional)Input field label
+ * @param mixed $attributes (optional)Either a typical HTML attribute string
+ * or an associative array
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function HTML_QuickForm_text($elementName=null, $elementLabel=null, $attributes=null)
+ {
+ HTML_QuickForm_input::HTML_QuickForm_input($elementName, $elementLabel, $attributes);
+ $this->_persistantFreeze = true;
+ $this->setType('text');
+ } //end constructor
+
+ // }}}
+ // {{{ setSize()
+
+ /**
+ * Sets size of text field
+ *
+ * @param string $size Size of text field
+ * @since 1.3
+ * @access public
+ * @return void
+ */
+ function setSize($size)
+ {
+ $this->updateAttributes(array('size'=>$size));
+ } //end func setSize
+
+ // }}}
+ // {{{ setMaxlength()
+
+ /**
+ * Sets maxlength of text field
+ *
+ * @param string $maxlength Maximum length of text field
+ * @since 1.3
+ * @access public
+ * @return void
+ */
+ function setMaxlength($maxlength)
+ {
+ $this->updateAttributes(array('maxlength'=>$maxlength));
+ } //end func setMaxlength
+
+ // }}}
+
+} //end class HTML_QuickForm_text
+?>
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP version 4.0 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Adam Daniel <adaniel1@eesus.jnj.com> |
+// | Bertrand Mansion <bmansion@mamasam.com> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+require_once("HTML/QuickForm/element.php");
+
+/**
+ * HTML class for a textarea type field
+ *
+ * @author Adam Daniel <adaniel1@eesus.jnj.com>
+ * @author Bertrand Mansion <bmansion@mamasam.com>
+ * @version 1.0
+ * @since PHP4.04pl1
+ * @access public
+ */
+class HTML_QuickForm_textarea extends HTML_QuickForm_element
+{
+ // {{{ properties
+
+ /**
+ * Field value
+ * @var string
+ * @since 1.0
+ * @access private
+ */
+ var $_value = null;
+
+ // }}}
+ // {{{ constructor
+
+ /**
+ * Class constructor
+ *
+ * @param string Input field name attribute
+ * @param mixed Label(s) for a field
+ * @param mixed Either a typical HTML attribute string or an associative array
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function HTML_QuickForm_textarea($elementName=null, $elementLabel=null, $attributes=null)
+ {
+ HTML_QuickForm_element::HTML_QuickForm_element($elementName, $elementLabel, $attributes);
+ $this->_persistantFreeze = true;
+ $this->_type = 'textarea';
+ } //end constructor
+
+ // }}}
+ // {{{ setName()
+
+ /**
+ * Sets the input field name
+ *
+ * @param string $name Input field name attribute
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function setName($name)
+ {
+ $this->updateAttributes(array('name'=>$name));
+ } //end func setName
+
+ // }}}
+ // {{{ getName()
+
+ /**
+ * Returns the element name
+ *
+ * @since 1.0
+ * @access public
+ * @return string
+ */
+ function getName()
+ {
+ return $this->getAttribute('name');
+ } //end func getName
+
+ // }}}
+ // {{{ setValue()
+
+ /**
+ * Sets value for textarea element
+ *
+ * @param string $value Value for textarea element
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function setValue($value)
+ {
+ $this->_value = $value;
+ } //end func setValue
+
+ // }}}
+ // {{{ getValue()
+
+ /**
+ * Returns the value of the form element
+ *
+ * @since 1.0
+ * @access public
+ * @return string
+ */
+ function getValue()
+ {
+ return $this->_value;
+ } // end func getValue
+
+ // }}}
+ // {{{ setWrap()
+
+ /**
+ * Sets wrap type for textarea element
+ *
+ * @param string $wrap Wrap type
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function setWrap($wrap)
+ {
+ $this->updateAttributes(array('wrap' => $wrap));
+ } //end func setWrap
+
+ // }}}
+ // {{{ setRows()
+
+ /**
+ * Sets height in rows for textarea element
+ *
+ * @param string $rows Height expressed in rows
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function setRows($rows)
+ {
+ $this->updateAttributes(array('rows' => $rows));
+ } //end func setRows
+
+ // }}}
+ // {{{ setCols()
+
+ /**
+ * Sets width in cols for textarea element
+ *
+ * @param string $cols Width expressed in cols
+ * @since 1.0
+ * @access public
+ * @return void
+ */
+ function setCols($cols)
+ {
+ $this->updateAttributes(array('cols' => $cols));
+ } //end func setCols
+
+ // }}}
+ // {{{ toHtml()
+
+ /**
+ * Returns the textarea element in HTML
+ *
+ * @since 1.0
+ * @access public
+ * @return string
+ */
+ function toHtml()
+ {
+ if ($this->_flagFrozen) {
+ return $this->getFrozenHtml();
+ } else {
+ return $this->_getTabs() .
+ '<textarea' . $this->_getAttrString($this->_attributes) . '>' .
+ // because we wrap the form later we don't want the text indented
+ preg_replace("/(\r\n|\n|\r)/", '
', htmlspecialchars($this->_value)) .
+ '</textarea>';
+ }
+ } //end func toHtml
+
+ // }}}
+ // {{{ getFrozenHtml()
+
+ /**
+ * Returns the value of field without HTML tags (in this case, value is changed to a mask)
+ *
+ * @since 1.0
+ * @access public
+ * @return string
+ */
+ function getFrozenHtml()
+ {
+ $value = htmlspecialchars($this->getValue());
+ if ($this->getAttribute('wrap') == 'off') {
+ $html = $this->_getTabs() . '<pre>' . $value."</pre>\n";
+ } else {
+ $html = nl2br($value)."\n";
+ }
+ return $html . $this->_getPersistantData();
+ } //end func getFrozenHtml
+
+ // }}}
+
+} //end class HTML_QuickForm_textarea
+?>
--- /dev/null
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
+// +----------------------------------------------------------------------+
+// | PHP Version 4 |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2003 The PHP Group |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.0 of the PHP license, |
+// | that is bundled with this package in the file LICENSE, and is |
+// | available at through the world-wide-web at |
+// | http://www.php.net/license/2_02.txt. |
+// | If you did not receive a copy of the PHP license and are unable to |
+// | obtain it through the world-wide-web, please send a note to |
+// | license@php.net so we can mail you a copy immediately. |
+// +----------------------------------------------------------------------+
+// | Authors: Alexey Borzov <avb@php.net> |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+require_once 'HTML/QuickForm/element.php';
+
+/**
+ * Class for HTML 4.0 <button> element
+ *
+ * @author Alexey Borzov <avb@php.net>
+ * @since 3.2.3
+ * @access public
+ */
+class HTML_QuickForm_xbutton extends HTML_QuickForm_element
+{
+ /**
+ * Contents of the <button> tag
+ * @var string
+ * @access private
+ */
+ var $_content;
+
+ /**
+ * Class constructor
+ *
+ * @param string Button name
+ * @param string Button content (HTML to add between <button></button> tags)
+ * @param mixed Either a typical HTML attribute string or an associative array
+ * @access public
+ */
+ function HTML_QuickForm_xbutton($elementName = null, $elementContent = null, $attributes = null)
+ {
+ $this->HTML_QuickForm_element($elementName, null, $attributes);
+ $this->setContent($elementContent);
+ $this->setPersistantFreeze(false);
+ $this->_type = 'xbutton';
+ }
+
+
+ function toHtml()
+ {
+ return '<button' . $this->getAttributes(true) . '>' . $this->_content . '</button>';
+ }
+
+
+ function getFrozenHtml()
+ {
+ return $this->toHtml();
+ }
+
+
+ function freeze()
+ {
+ return false;
+ }
+
+
+ function setName($name)
+ {
+ $this->updateAttributes(array(
+ 'name' => $name
+ ));
+ }
+
+
+ function getName()
+ {
+ return $this->getAttribute('name');
+ }
+
+
+ function setValue($value)
+ {
+ $this->updateAttributes(array(
+ 'value' => $value
+ ));
+ }
+
+
+ function getValue()
+ {
+ return $this->getAttribute('value');
+ }
+
+
+ /**
+ * Sets the contents of the button element
+ *
+ * @param string Button content (HTML to add between <button></button> tags)
+ */
+ function setContent($content)
+ {
+ $this->_content = $content;
+ }
+
+
+ function onQuickFormEvent($event, $arg, &$caller)
+ {
+ if ('updateValue' != $event) {
+ return parent::onQuickFormEvent($event, $arg, $caller);
+ } else {
+ $value = $this->_findValue($caller->_constantValues);
+ if (null === $value) {
+ $value = $this->_findValue($caller->_defaultValues);
+ }
+ if (null !== $value) {
+ $this->setValue($value);
+ }
+ }
+ return true;
+ }
+
+
+ /**
+ * Returns a 'safe' element's value
+ *
+ * The value is only returned if the button's type is "submit" and if this
+ * particlular button was clicked
+ */
+ function exportValue(&$submitValues, $assoc = false)
+ {
+ if ('submit' == $this->getAttribute('type')) {
+ return $this->_prepareValue($this->_findValue($submitValues), $assoc);
+ } else {
+ return null;
+ }
+ }
+}
+?>
////////////////////////////////////////////////////////////////////////////////
-$THEME->standardsheets = array('styles_layout');
+$THEME->standardsheets = array('styles_layout','styles_form');
/// This variable can be set to an array containing
/// filenames from the *STANDARD* theme. If the
/// stylesheet files you want included in this theme, and in what order
////////////////////////////////////////////////////////////////////////////////
-$THEME->standardsheets = array('styles_layout');
+$THEME->standardsheets = array('styles_layout','styles_form');
///$THEME->standardsheets = true;
/// This variable can be set to an array containing
////////////////////////////////////////////////////////////////////////////////
-$THEME->standardsheets = array('styles_layout','styles_fonts','styles_color');
+$THEME->standardsheets = array('styles_layout','styles_fonts','styles_color','styles_form');
/// This variable can be set to an array containing
/// filenames from the *STANDARD* theme. If the
////////////////////////////////////////////////////////////////////////////////
-$THEME->standardsheets = array('styles_layout');
+$THEME->standardsheets = array('styles_layout','styles_form');
/// This variable can be set to an array containing
/// filenames from the *STANDARD* theme. If the
////////////////////////////////////////////////////////////////////////////////
-$THEME->standardsheets = array('styles_layout');
+$THEME->standardsheets = array('styles_layout','styles_form');
/// This variable can be set to an array containing
/// filenames from the *STANDARD* theme. If the
////////////////////////////////////////////////////////////////////////////////
-$THEME->sheets = array('styles_layout', 'styles_fonts', 'styles_color');
+$THEME->sheets = array('styles_layout', 'styles_fonts', 'styles_color','styles_form');
/// This variable is an array containing the names of all the
/// stylesheet files you want included in this theme, and in what order
--- /dev/null
+/*******************************************************************
+ styles_form.css
+
+ This CSS file contains all css required for new css and xhtml only
+ moodleforms.
+*/
+form.mform {
+ margin: 0;
+ padding: 0;
+ width: 100%;
+}
+form.mform fieldset {
+ border: 1px solid black;
+ padding: 10px 0;
+ margin: 0;
+ width:100%;
+}
+form.mform fieldset.hidden {
+ border: 0;
+}
+form.mform fieldset legend {
+ font-weight: bold;
+}
+form.mform label {
+ margin: 0 0 0 5px;
+}
+form.mform label.qflabel {
+ display: block;
+ float: left;
+ width: 40%;
+ padding: 0;
+ margin: 5px 0 0 0;
+ text-align: right;
+}
+
+form.mform input, form.mform select {
+ width: auto;
+}
+form.mform textarea {
+ }
+form.mform br {
+ clear: left;
+}
+form.mform div.qfelement {
+ display: inline;
+ float: left;
+ margin: 5px 0 0 10px;
+ padding: 0;
+}
+
+form.mform div.qfelementwide {
+ margin: 0 10% 10px 10%;
+}
+
+form.mform span.error, form.mform span.required {
+ color: red;
+}
+form.mform div.error {
+ border: 1px solid red;
+ padding: 5px;
+ color: inherit;
+}
\ No newline at end of file
////////////////////////////////////////////////////////////////////////////////
-$THEME->standardsheets = array('styles_layout','styles_fonts','styles_color','styles_moz');
+$THEME->standardsheets = array('styles_layout','styles_fonts','styles_color','styles_moz','styles_form');
/// This variable can be set to an array containing
/// filenames from the *STANDARD* theme. If the
////////////////////////////////////////////////////////////////////////////////
-$THEME->standardsheets = array('styles_layout','styles_fonts','styles_color','styles_moz');
+$THEME->standardsheets = array('styles_layout','styles_fonts','styles_color','styles_moz','styles_form');
/// This variable can be set to an array containing
/// filenames from the *STANDARD* theme. If the
////////////////////////////////////////////////////////////////////////////////
-$THEME->standardsheets = array('styles_layout','styles_fonts','styles_color','styles_moz');
+$THEME->standardsheets = array('styles_layout','styles_fonts','styles_color','styles_moz','styles_form');
/// This variable can be set to an array containing
/// filenames from the *STANDARD* theme. If the
////////////////////////////////////////////////////////////////////////////////
-$THEME->standardsheets = array('styles_layout','styles_fonts','styles_color','styles_moz');
+$THEME->standardsheets = array('styles_layout','styles_fonts','styles_color','styles_moz','styles_form');
/// This variable can be set to an array containing
/// filenames from the *STANDARD* theme. If the
////////////////////////////////////////////////////////////////////////////////
-$THEME->standardsheets = array('styles_layout','styles_fonts','styles_color','styles_moz');
+$THEME->standardsheets = array('styles_layout','styles_fonts','styles_color','styles_moz','styles_form');
/// This variable can be set to an array containing
/// filenames from the *STANDARD* theme. If the
////////////////////////////////////////////////////////////////////////////////
-$THEME->standardsheets = array('styles_layout','styles_fonts','styles_color');
+$THEME->standardsheets = array('styles_layout','styles_fonts','styles_color','styles_form');
/// This variable can be set to an array containing
/// filenames from the *STANDARD* theme. If the