rendered paste body<?phpclass Qf_Utils { static public function form_value($value) { if (!isset($value)) { return ''; } $string = strval($value); return strlen($string) > 0 ? htmlentities($string, ENT_QUOTES) : ''; } static public function html_string($string) { return isset($string) && strlen($string) > 0 ? nl2br(htmlentities($string, ENT_QUOTES)) : ' '; } static public function js_string($string) { return addslashes($string); }}class Qf_Element { public $label; // Label associated with element public $name; // Name of form element public $value; // Value assigned to element public $filters; public $validators; public $error; // Validation error message protected $attributes; // Other html attributes public function __construct($name, $value, $label, $attributes) { $this->label = $label; $this->name = $name; $this->value = $value; $this->attributes = $attributes; } /** * @return string The html to display this element */ public function view() { return Qf_Utils::html_string($this->value); } public function allowMultiple() { return false; } /** * Override this function if custom javascript is needed to determine if a value was entered */ public function jsEmpty() { return 'isEmpty('.$this->jsElement().')'; } /** * Override this function if custom javascript is needed to be called before processing the element */ public function jsClean() { return null; } public function jsElement() { return "form.elements['".$this->name."']"; } protected function htmlAttributes() { $html = ''; foreach($this->attributes as $name => $value) { $html .= ' '.$name.'="'.Qf_Utils::form_value($value).'"'; } return $html; } protected function choice($type, $label, $value, $checked) { $html = '<label><input type="'.$type.'" name="'.$this->name.'" value="'.$value.'"'; if ($checked) { $html .= ' checked'; } $html .= '>'.$label.'</label>'; return $html; } protected function input($type, $checked = false) { $html = '<input type="'.$type.'" name="'.$this->name.'" value="'.$this->value.'"'; if ($checked) { $html .= ' checked'; } $this->htmlAttributes(); $html .= '>'; return $html; } /** * @return string The html to edit this element */ public function edit() { return view(); } }/** * Textbox element */class Qf_Text extends Qf_Element { public function edit() { return $this->input('text'); } public function jsClean() { return $this->jsElement().'.value = trim('.$this->jsElement().'.value)'; }}/** * Password element */class Qf_Password extends Qf_Element { public function edit() { return $this->input('password'); } public function view() { return str_repeat('*', strlen($this->value)); }}/** * Textarea element */class Qf_Textarea extends Qf_Element { public function edit() { $html = '<textarea name="'.$this->name.'"'.$this->htmlAttributes().'>'; $html .= Qf_Utils::form_value($this->value); $html .= '</textarea>'; return $html; }}/** * Checkbox element for boolean values */class Qf_Checkflag extends Qf_Element { public function __construct($name, $value, $label, $attributes) { $value = isset($value) && ($value === true || $value == 'true' || $value == 't' || $value == 1); parent::__construct($name, $value, $label, $attributes); } public function edit() { return $this->input('checkbox'); }}/** * Radio group element, used for selecting between multiple choices */class Qf_Radio extends Qf_Element { private $options; // value => text pairs of radio choices public function setOptions($options) { $this->options = $options; } public function edit() { $html = '<span class="radio-group">'."\n"; foreach($this->options as $value => $text) { $html .= "\t\t".$this->choice('radio', $text, $value, $this->value == $value)."\n"; } $html .= "\t".'</span>'; return $html; } public function jsEmpty() { return '!isRadioSelected('.$this->jsElement().')'; }}/** * Check group element, used for selecting multiple choices */class Qf_Checkbox extends Qf_Element { private $options; // value => text pairs of radio choices public function setOptions($options) { $this->options = $options; } public function edit() { $html = '<span class="check-group">'."\n"; foreach($this->options as $value => $text) { $html .= "\t\t".$this->choice('checkbox', $text, $value, $this->value == $value)."\n"; } $html .= "\t".'</span>'; return $html; } public function allowMultiple() { return true; } public function jsEmpty() { return '!isCheckboxSelected('.$this->jsElement().')'; } }/** * Drop down element for selecting between multiple choices */class Qf_Select extends Qf_Element { private $options; // value => text pairs of radio choices public function setOptions($options) { $this->options = $options; } public function edit() { $html = '<select name="'.$this->name.'"'.$this->htmlAttributes().'>'."\n"; foreach($this->options as $value => $text) { $html .= "\t\t".'<option value="'.$value.'">'.$text.'</option>'."\n"; } $html .= "\t".'</select>'; return $html; }}/** * Radio group element for boolean fields */class Qf_Yes_no extends Qf_Element { private $yesLabel; private $yesValue; private $noLabel; private $noValue; public function _config($yesLabel, $yesValue, $noLabel, $noValue) { $this->yesLabel = $yesLabel; $this->yesValue = $yesValue; $this->noLabel = $noLabel; $this->noValue = $noValue; } public function edit() { $html = '<span class="yes-no">'."\n"; $html .= "\t\t".$this->choice('radio', $this->yesLabel, $this->yesValue, $this->value == $this->yesValue)."\n"; $html .= "\t\t".$this->choice('radio', $this->noLabel, $this->noValue, $this->value == $this->noValue)."\n"; $html .= "\t".'</span>'; return $html; } public function jsEmpty() { return '!isRadioSelected('.$this->jsElement().')'; } }/** * Date element */class Qf_Date extends Qf_Element { public function edit() { if ($this->value) { $dateString = date('Y-m-d', $this->value); } else { $dateString = ''; } $html = '<span class="date"'.$this->htmlAttributes().'>'; $html .= '<input type="text" id="date_'.$this->name.'" name="'.$this->name.'" value="'.$dateString.'" size="10" maxLength="10">'; $html .= '<img id="trigger_'.$this->name.'" style="cursor: pointer;" src="/lib/quickform2/images/cal.gif" border="0" alt="Calendar">'; $html .= '<script type="text/javascript"><!--'; $html .= 'Calendar.setup({ inputField : "date_'.$this->name.'", ifFormat : "%Y-%m-%d", button : "trigger_'.$this->name.'"});'; $html .= "\n".'//--></script>'; $html .= '</span>'; return $html; } public function view() { if ($this->value) { $dateString = date('Y-m-d', $this->value); } else { $dateString = ''; } return $dateString; } public function jsClean() { return $this->jsElement().'.value = trim('.$this->jsElement().'.value)'; } }/** * Time element */class Qf_Time extends Qf_Element { private $blanks; // Wether to have blank time options public function _allowBlanks($allowBlanks) { $this->blanks = $allowBlanks; } public function edit() { $HOUR = range(1, 12); $MINUTE = range(0, 59); $html = '<span class="time">'; $html .= '<select name="'.$this->name.'_hour">'; if ($this->blanks) { $html .= '<option value=""> </option>'; } foreach($HOUR as $hr) { $html .= '<option>'.$hr.'</option>'; } $html .= '</select>:'; $html .= '<select name="'.$this->name.'_minute">'; if ($this->blanks) { $html .= '<option value=""> </option>'; } foreach($MINUTE as $min) { $html .= '<option>'.sprintf('%02d', $min).'</option>'; } $html .= '</select> '; $html .= '<select name="'.$this->name.'_ampm">'; if ($this->blanks) { $html .= '<option value=""> </option>'; } $html .= '<option>AM</option>'; $html .= '<option>PM</option>'; $html .= '</select></span>'; return $html; } public function jsEmpty() { return "(form.elements['".$this->name."_hour'].value == '' || form.elements['".$this->name."_minute'].value == '' || form.elements['".$this->name."_ampm'].value == '')"; }}class Qf_Filter { public function clean($string) { return $string; } public function jsClean(Qf_Element $element) { return null; }}/** * Trim and removeslashes */class Default_Qf_Filter extends Qf_Filter { private function removeslashes($string) { if (get_magic_quotes_gpc() == TRUE) { return stripslashes($string); } else { return $string; } } public function clean($string) { return trim(self::removeslashes($string)); } public function jsClean(Qf_Element $element) { return $element->jsClean(); }}class Qf_Validator { private $message; public function __construct($message) { $this->message = $message; } public function mayCache() { return true; } public function getMessage() { return $this->message; } public function validate($value) { return true; } /** * Generate javascript to validate on the client side * * @return string Javascript code */ public function jsValidate(Qf_Element $element) { return 'true'; }}class Required_Qf_Validator extends Qf_Validator { public function __construct() { parent::__construct('is required'); } public function validate($value) { if (isset($value) && strlen($value) > 0) { return true; } return false; } public function jsValidate(Qf_Element $element) { return $element->jsEmpty(); }}class Min_length_Qf_Validator extends Qf_Validator { private $length; public function __construct($length) { $this->length = $length; parent::__construct('must be longer then '.$length.' characters'); } public function mayCache() { return false; } public function validate($value) { if (strlen($value) >= $this->length) { return true; } return false; }}class Max_length_Qf_Validator extends Qf_Validator { private $length; public function __construct($length) { $this->length = $length; parent::__construct('must be shorter then '.$length.' characters'); } public function mayCache() { return false; } public function validate($value) { if (strlen($value) <= $this->length) { return true; } return false; }}class Exact_length_Qf_Validator extends Qf_Validator { private $length; public function __construct($length) { $this->length = $length; parent::__construct('must be '.$length.' characters in length'); } public function mayCache() { return false; } public function validate($value) { if (strlen($value) == $this->length) { return true; } return false; } }class Integer_Qf_Validator extends Qf_Validator { public function __construct() { parent::__construct('must be an integer'); } public function validate($value) { if (preg_match('/(^-?\d\d*$)/', $value) == 0) { return false; } return true; } public function jsValidate(Qf_Element $element) { return '!isInteger('.$element->jsElement().'.value)'; }}class Numeric_Qf_Validator extends Qf_Validator { public function __construct() { parent::__construct('must be a number'); } public function validate($value) { if (is_numeric($value)) { return true; } return false; } public function jsValidate(Qf_Element $element) { return '!isNumeric('.$element->jsElement().'.value)'; }}class Alpha_Qf_Validator extends Qf_Validator { public function __construct() { parent::__construct('must only contain alphabetical characters'); } public function validate($value) { if (preg_match('/^[a-z]++$/iD', $value) == 0) { return false; } return true; } public function jsValidate(Qf_Element $element) { return '!isAlpha('.$element->jsElement().'.value)'; }}class Alphanumeric_Qf_Validator extends Qf_Validator { public function __construct() { parent::__construct('must only contain alphabetical and digit characters'); } public function validate($value) { if (preg_match('/^[a-z0-9]++$/iD', $value) == 0) { return false; } return true; } public function jsValidate(Qf_Element $element) { return '!isAlphaNumeric('.$element->jsElement().'.value)'; } }class Currency_Qf_Validator extends Qf_Validator { public function __construct() { parent::__construct('must be a currency value'); } public function validate($value) { if (!isset($value) || trim($value) == '') { return false; } // strip currency characters $strMinus = ''; if (preg_match('/\(/', $value)) { $strMinus = '-'; } $value = $strMinus . str_replace(array('(', ')', ',', '$'), '', $value); if (is_numeric($value)) { return true; } else { return false; } } public function jsValidate(Qf_Element $element) { return '!isCurrency('.$element->jsElement().'.value)'; }}class Email_Qf_Validator extends Qf_Validator { public function __construct() { parent::__construct('must be a valid email address'); } public function validate($email) { if (preg_match('/^(?!\.)[-+_a-z0-9.]++(?<!\.)@(?![-.])[-a-z0-9.]+(?<!\.)\.[a-z]{2,6}$/iD', $email) == 0) { return false; } return true; } public function jsValidate() { return '!isEmail('.$element->jsElement().'.value)'; }}class Regex_Qf_Validator extends Qf_Validator { private $regex; public function __construct($regex, $message = 'is invalid') { $this->regex = $regex; parent::__construct($message); } public function validate($value) { if (preg_match($regex, $value) == 0) { return false; } return true; } public function jsValidate() { return '!'.$regex.'.test('.$element->jsElement().'.value)'; }}class Quickform { private $name; private $action; private $method; private $includeCalendar = false; private $viewOnly = false; private $elements = array(); private $submitLabel; private $containerName = 'qf'; private $errors = array(); // List of validation errors public function __construct($name, $action, $method) { $this->name = $name; $this->action = $action; $this->method = $method; } public function setSubmitLabel($label) { $this->submitLabel = $label; } public function isSubmit() { return isset($_POST[$this->name.'_submit']); } public function addElement(Qf_Element $element) { $element->name = $this->containerName.'['.$element->name.']'; if ($element->allowMultiple()) { $element->name .= '[]'; // Rename field so PHP receives values in array } $this->elements[] = $element; if (is_a($element, 'Qf_Date')) { $this->includeCalendar = true; } } public function getFieldValues() { return $_POST[$this->containerName]; } public function isValid() { $valid = true; // assume form is valid $errors = array(); foreach($this->elements as $element) { $element->error = null; foreach($element->validators as $validator) { if (!$validator->validate($element->value)) { $errorMessage = $element->label.' '.$validator->getMessage(); $element->error = $errorMessage; $errors[] = $errorMessage; $valid = false; break; } } } $this->errors = $errors; return $valid; } private function js_validate() { $html = '<script type="text/javascript"><!--'; $html .= "function validate_".$this->name."(){ var form = document.forms['".$this->name."']; clearErrors('".$this->name."'); var valid = true; // Assume form is valid var field = null;"; foreach($this->elements as $field) { foreach($field->filters as $filter) { $jsFilter = $filter->jsClean($field); if ($jsFilter) { $html .= "\n\t".$jsFilter.';'; } } $firstValidator = true; foreach($field->validators as $validator) { if ($firstValidator) { $html .= "\n\t"; } else { $html .= " else "; } $html .= "if (isError('".$this->name."', '".$field->name."', ".$validator->jsValidate($field).", '".$field->label.' '.$validator->getMessage()."')) { valid = false; }"; $firstValidator = false; } } $html .= " return valid;}"; $html .= "\n".'//--></script>'; return $html; } public function html() { $html = ''; if (!$this->viewOnly) { $html .= '<form class="quickform" name="'.$this->name.'" action="'.$this->action.'" method="'.$this->method.'" onSubmit="return validate_'.$this->name.'()">'."\n"; $html .= '<style type="text/css"><!-- @import url(/lib/quickform2/style.css); --></style>'."\n"; $html .= '<span id="'.$this->name.'_error_hint" class="error"'; if (count($this->errors) == 0) { $html .= ' style="display: none;"'; } $html .= '>The following errors exist:</span>'."\n"; $html .= '<ul id="'.$this->name.'_error_list" class="error_list">'."\n"; foreach($this->errors as $error) { $html .= "\t".'<li>'.$error.'</li>'."\n"; } $html .= '</ul>'."\n"; $html .= '<script type="text/javascript" src="/lib/quickform2/client_validation.js"></script>'."\n"; $html .= $this->js_validate(); if ($this->includeCalendar) { $html .= '<style type="text/css"><!-- @import url(/lib/quickform2/calendar/calendar-win2k-1.css); --></style><script type="text/javascript" src="/lib/quickform2/calendar/calendar.js"></script><script type="text/javascript" src="/lib/quickform2/calendar/lang/calendar-en.js"></script><script type="text/javascript" src="/lib/quickform2/calendar/calendar-setup.js"></script>'; } } $html .= '<table>'; foreach($this->elements as $field) { $html .= '<tr>'."\n"; $html .= "\t".'<th id="label_'.$field->name.'"'; if ($field->error) { $html .= ' class="error"'; } $html .= '>'.$field->label.'</th>'."\n"; if ($this->viewOnly) { $html .= "\t".'<td>'.$field->view().'</td>'."\n"; } else { $html .= "\t".'<td>'.$field->edit().'</td>'."\n"; } $html .= '</tr>'; } if (!$this->viewOnly) { $html .= '<tr>'."\n"; $html .= "\t".'<td colspan="2" align="right">'; $html .= '<input type="submit" name="'.$this->name.'_submit" value="'.$this->submitLabel.'">'; $html .= '</td>'."\n"; $html .= '</tr>'; } $html .= '</table>'."\n"; if (!$this->viewOnly) { $html .= '</form>'."\n"; } return $html; }}function config_get(&$config, $item, $default = null) { if (array_key_exists($item, $config)) { $value = $config[$item]; return $value; } else { return $default; } }function config_get_once(&$config, $item, $default = null) { if (array_key_exists($item, $config)) { $value = $config[$item]; unset($config[$item]); return $value; } else { return $default; }}function build_quickform($form) { $defaultFilter = new Default_Qf_Filter(); $requiredValidator = new Required_Qf_Validator(); // Common filters and validators $qf_filters = array(); $qf_validators = array(); $qf = new Quickform($form['name'], $form['action'], $form['method']); $qf->setSubmitLabel(config_get($form, 'submit', 'Submit')); foreach($form['elements'] as $element) { $label = config_get_once($element, 'label'); $name = config_get_once($element, 'name'); $type = config_get_once($element, 'type'); $value = config_get_once($element, 'value'); $filterConfig = config_get_once($element, 'filter', array()); $filters = array($defaultFilter); foreach($filterConfig as $filterName) { $filterName .= '_Qf_Filter'; if (!array_key_exists($filterName, $qf_filters)) { $qf_filters[$filterName] = new $filterName; } $filters[] = $qf_filters[$validatorName]; } $optional = config_get_once($element, 'optional', false); $validatorConfig = config_get_once($element, 'validators', array()); $validators = array(); if (!$optional && $type != 'checkflag') { $validators[] = $requiredValidator; } foreach($validatorConfig as $vConfig) { $vConfig = explode('=', $vConfig); $validatorName = $vConfig[0]; $params = array(); if ($vConfig[1]) { $params = explode(',', $vConfig[1]); } $validatorName .= '_Qf_Validator'; if (!array_key_exists($validatorName, $qf_validators)) { if (count($params) == 1) { $validator = new $validatorName($params[0]); } else if (count($params) == 2) { $validator = new $validatorName($params[0], $params[1]); } else if (count($params) > 2) { $validator = new $validatorName($params); } else { $validator = new $validatorName; } if ($validator->mayCache()) { $qf_validators[$validatorName] = $validator; $validators[] = $qf_validators[$validatorName]; } else { $validators[] = $validator; } } else { $validators[] = $qf_validators[$validatorName]; } } $className = 'Qf_'.ucfirst($type); $qfField = new $className($name, $value, $label, $element); if ($type == 'select') { $selectOption = config_get_once($element, 'selectOption', true); $options = config_get_once($element, 'options', array()); if ($selectOption) { $options = array_merge(array('' => '(select)'), $options); } $qfField->setOptions($options); } else if ($type == 'radio' || $type == 'checkbox') { $options = config_get_once($element, 'options', array()); $qfField->setOptions($options); } else if ($type == 'yes_no') { $yesLabel = config_get_once($element, 'yesLabel', 'Yes'); $yesValue = config_get_once($element, 'yesValue', 'true'); $noLabel = config_get_once($element, 'noLabel', 'No'); $noValue = config_get_once($element, 'noValue', 'false'); $qfField->_config($yesLabel, $yesValue, $noLabel, $noValue); } else if ($type == 'time') { $allowBlanks = config_get_once($element, 'allowBlanks', true); $qfField->_allowBlanks($allowBlanks); } $qfField->filters = $filters; $qfField->validators = $validators; $qf->addElement($qfField); } return $qf;}