/**
* Simple Forms Class
*
* @author Steve Dibb
*
*/
class Form {
function __construct() {
/** Form element types */
$this->arr_element_types = array('button', 'checkbox', 'hidden', 'password', 'radio', 'reset', 'select', 'submit', 'text', 'textarea');
/** Form element templates */
$this->arr_template_types = array('yesno');
/** Array of form elements and their properties */
$this->arr_elements = array();
/** Form element types that can have more than one possible value */
$this->arr_types_with_options = array('checkbox', 'radio', 'select');
/** A mix of HTML possible properties and display options */
$this->arr_element_properties = array(
'button' => array('style', 'value', 'class'),
'checkbox' => array('options', 'delimiter', 'style', 'multiple', 'class', 'display_one'),
'hidden' => array('value'),
'password' => array('size', 'style', 'maxlength', 'value', 'class'),
'radio' => array('options', 'delimiter', 'display_one'),
'reset' => array('value', 'style', 'class'),
'select' => array('options', 'size', 'multiple', 'style', 'class'),
'submit' => array('style', 'value', 'class'),
'text' => array('size', 'maxlength', 'value', 'style', 'class'),
'textarea' => array('wrap', 'rows', 'cols', 'value', 'style', 'class')
);
/** Possible form element properties */
$this->arr_element_html_properties = array('class', 'style', 'size', 'maxlength', 'wrap', 'rows', 'cols');
/** Display constants */
define('DISPLAY_ONE', 1);
define('DISPLAY_OPTION', 2);
define('DISPLAY_TEXT', 3);
}
/**
* Creates a new form element
*
* @param string form type
* @param string form name
*/
function addElement($element, $type, $value = null) {
$element = trim($element);
$type = trim($type);
if(empty($type) || empty($element) || !is_string($type) || !is_string($element)) {
trigger_error('Passed invalid parameters to Form::addElement()', E_USER_WARNING);
return false;
}
if(!in_array($type, $this->arr_element_types)) {
trigger_error('Passed invalid element type to Form::addElement()', E_USER_WARNING);
return false;
}
// If one is previously set of the same name, erase all settings
if(isset($this->arr_elements[$element]))
unset($this->arr_elements[$element]);
$this->arr_elements[$element]['type'] = $type;
// If the element can have options, create a blank array
if($this->elementTypeHasProperty($type, 'options')) {
$this->arr_elements[$element]['options'] = array();
}
if($this->elementTypeHasProperty($type, 'multiple'))
$this->arr_elements[$element]['selected'] = array();
// Set default display to the first item for radio buttons and checkboxes
if($this->elementTypeHasProperty($type, 'display_one')) {
$this->arr_elements[$element]['display']['counter'] = 0;
$this->arr_elements[$element]['display']['pair'] = 0;
}
// Set the default value
if(!is_null($value) && $this->elementTypeHasProperty($type, 'value'))
$this->setValue($element, $value);
return true;
}
/**
* Add a blank header to a form select menu
*
* @param string element name
* @param string blank value
*/
function addBlankHeader($element, $value = '') {
if($this->verifyElement($element) && $this->arr_elements[$element]['type'] == 'select') {
$this->arr_elements[$element]['properties']['blank'] = true;
if(is_string($value) && !empty($value))
$this->arr_elements[$element]['properties']['blank_header'] = $value;
}
}
/**
* Add an option to a form element
*
* @param string element name
* @param string key value
* @param string option value
* @param string default option
*/
function addOption($element, $value, $display_name = '', $default = false) {
if($this->verifyElement($element)) {
// Only add options if the type allows it
if($this->elementTypeHasProperty($this->arr_elements[$element]['type'], 'options')) {
$this->arr_elements[$element]['options'][$value] = $display_name;
if($default) {
if($this->elementTypeHasProperty($this->arr_elements[$element]['type'], 'multiple'))
$this->addSelected($element, $value);
else
$this->setDefault($element, $value);
}
}
}
}
/**
* Add any string, value to a form element's option
*
* @param string element name
* @param string key name
* @param string key value
*/
function addOptionString($element, $key = 0, $string, $value = null) {
$this->addString($element, $string, $value, $key);
}
/**
* Add an option to be selected or checked
*
* Toggles the option if it's already specified
*
* @param string element name
* @param string key value
*/
function addSelected($element, $key) {
if($this->verifyElement($element)) {
if($this->elementTypeHasProperty($this->arr_elements[$element]['type'], 'multiple') && array_key_exists($key, $this->arr_elements[$element]['options'])) {
$arr_key = array_search($key, $this->arr_elements[$element]['selected']);
// Tack it on
if($arr_key === false)
$this->arr_elements[$element]['selected'][] = (string)$key;
// If the value is already in the array, remove it, and clean up the array again
else {
unset($this->arr_elements[$element]['selected'][$arr_key]);
$this->arr_elements[$element]['selected'] = array_merge($this->arr_elements[$element]['selected']);
}
}
}
}
/**
* Add any string, value to a form element
*
* @param string element name
* @param string key name
* @param string key value
*/
function addString($element, $string, $value = null, $option = null) {
if($this->verifyElement($element)) {
$string = trim($string);
if(empty($string) || !is_string($string)) {
trigger_error('Passed an invalid string to Form::addString()', E_USER_WARNING);
return false;
}
elseif(!is_null($value)) {
$value = trim($value);
if(empty($value) || !is_string($value)) {
trigger_error('Passed an invalid value to Form::addString()', E_USER_WARNING);
return false;
}
}
elseif(!is_null($option)) {
$option = trim($option);
if(empty($option) || !is_string($option)) {
trigger_error('Passed an invalid value to Form::addString()', E_USER_WARNING);
return false;
}
}
if(is_null($option))
$this->arr_elements[$element]['strings'][$string] = $value;
else
$this->arr_elements[$element]['option_strings'][$option][$string] = $value;
return true;
}
else
return false;
}
/**
* Add a predefined template
*
* @param string element name
* @param string template type
*/
function addTemplate($element, $template) {
$element = trim($element);
$template = trim($template);
if(empty($template) || empty($element) || !is_string($template) || !is_string($element)) {
trigger_error('Passed invalid parameters to Form::addTemplate()', E_USER_WARNING);
}
if(!in_array($template, $this->arr_template_types)) {
trigger_error('Passed invalid template type to Form::addTemplate()', E_USER_WARNING);
}
switch($template) {
/**
* Yes-No template
* Creates two radio buttons, Yes and No
* with values being 1 and 0
*/
case 'yesno':
$this->addElement($element, 'radio');
$this->addOption($element, 1, 'Yes');
$this->addOption($element, 0, 'No');
break;
}
}
/**
* Display a form element
*
* Optionally display only one at a time
* for checkboxes & radio buttons
*
* Wrapper function to getElement()
*
* @param string element name
* @param string display one checkbox or radio button
* @see getElement()
* @return HTML string
*/
function displayElement($element, $display_options = null) {
echo $this->getElement($element, $display_options);
}
/**
* Return a form element
*
* Optionally display only one at a time
* for checkboxes & radio buttons
*
* @param string element name
* @param string display one checkbox or radio button
* @return HTML string
*/
function getElement($element, $display_options = null) {
// Kick them out if the element isn't created
if(!$this->verifyElement($element))
return '';
extract($this->arr_elements[$element]);
$html = '';
$html_values = "name='$element'";
// Tack on the optional HTML values
if(is_array($properties))
foreach($properties as $k => $v) {
if(in_array($k, $this->arr_element_html_properties)) {
$v = str_replace("'", "\'", $v);
$html_values .= "$k='$v' ";
}
}
// Add on the customized strings
$html_values .= $this->getStrings($element);
// Set the default delimiter
if($this->elementTypeHasProperty($type, 'delimiter') && !isset($options['delimiter']))
$delimiter = ' ';
// Anal spacing nazi at work
if(!empty($html_values))
$html_values = ' '.$html_values;
switch($type) {
case 'hidden':
$html = "\n";
break;
case 'password':
$html = "\n";
break;
case 'checkbox':
case 'radio':
$x = 0;
$arr_html[$element] = $arr_keys[$element] = $arr_values[$element] = array();
foreach($options as $key => $value) {
$str_options = $this->getStrings($element, $key);
$arr_html[$element][$x] .= "arr_elements[$element]['selected']))) {
$arr_html[$element][$x] .= " checked";
}
if(!empty($str))
$arr_html[$element][$x] .= " $str";
if(!empty($str_options))
$arr_html[$element][$x] .= " $str_options";
$arr_options[$element][$x] = $arr_html[$element][$x] .= "{$html_values} />";
$arr_html[$element][$x] .= " {$value}{$delimiter}\n";
$arr_text[$element][$x] = $value;
$x++;
}
break;
case 'reset':
$html = "\n";
break;
case 'select':
// Turn the select statement into an array if multiple is turned on
if($properties['multiple'] && (substr($element, 2, -1) != '[]'))
$display = "{$element}[]";
else
$display =& $element;
$html = "