<?
///simple class to help with outputting form tags with post and pre filled data
/** All values are escaped*/
class Form {
///adds class "field_input_NAME" to all form tags
static $defaultClassOn;
///used to specify value behavior where input ($_POST, $_GET) overrides form function value
const TO_INPUT = 1;
///used to specify value behavior where form function value overrides input ($_POST, $_GET)
const TO_PARAM = 2;
///used to specify value behavior where self::values is used before other two methods
const TO_ARRAY = 3;
///the the of behavior for determining what the actual value of a form field should be
static $valueBehavior = self::TO_INPUT;
///an array of keys to values used in conjuction with TO_ARRAY to serve as override values for form fields
static $values;
/// resolves the value for a given form name based on self::$valueBehavior
static function resolveValue($name, $value){
if (self::$valueBehavior == self::TO_PARAM || !$name){
return $value;
}
if (self::$valueBehavior == self::TO_INPUT){
if (isset(Page::$in[$name])){
return Page::$in[$name];
}
return $value;
} elseif (self::$valueBehavior == self::TO_ARRAY && is_array(self::$values)){
if (isset(self::$values[$name])){
return self::$values[$name];
}
}
if (!isset($value) && isset(Page::$in[$name])){
return Page::$in[$name];
}
return $value;
}
///total number of fields generated. Used when no name provided
static $fieldCount = 0;
///used internally. Generates the additional attributes provides for a field
static function additionalAttributes($x,$name){
$classes = explode(' ',$x['class']);
if(self::$defaultClassOn){
$defaultClass = 'field_input_'.($name ? $name : self::$fieldCount);
array_unshift($classes,$defaultClass);
}
unset($x['class']);
if($classes){
$additions[] = 'class="'.implode(' ',$classes).'"';
}
self::$fieldCount++;
if($x['extra']){
$additions[] = $x['extra'];
}
unset($x['extra']);
$attributeTypes = array('id','title','alt');
foreach($attributeTypes as $attribute){
if($x[$attribute]){
$additions[] = $attribute.'="'.$x[$attribute].'"';
unset($x[$attribute]);
}
}
if($x){
//add onclick events
foreach($x as $k=>$v){
if(strtolower(substr($k,0,2)) == 'on'){
$additions[] = $k.'="'.$v.'"';
}
}
}
if($additions){
return ' '.implode(' ',$additions).' ';
}
}
/// create a <select> tag
/**
@param name attribute of tag
@param value attribute of tag
@param options array array(value=>text,value=>text) key to value where key is the option value and value is the option text. I did it this way because in the backend the values are usually the keys;
@param x list of options including "id", "class", "on[click|mouseover|...]", "alt", "title" and "extra", which is included in the tag
@note this is a simplified version which doesn't have option groups or freeform options. I might introduce the more complicated version later
*/
static function select($name, $value, $options = null, $x = null){
$value = self::resolveValue($name, $value);
$field = '<select name="'.$name.'" '.self::additionalAttributes($x,$name).'>';
if ($value && isset($options[$value])){
$selected[$value] = '<option selected=1 value="'.htmlspecialchars($value).'">'.$options[$value].'</option>';
}
if ($x['none']){
$value = 0;
if (isset($x['noneValue'])){
$value = $x['noneValue'];
}
$field .= '<option value="'.$value.'">'.$x['none'].'</option>';
}
if ($options){
foreach ($options as $v=>$k){
if ($selected[$v]){
$field .= $selected[$v];
} else {
$field .= '<option value="'.htmlspecialchars($v).'">'.ucwords($k).'</option>';
}
}
}
return $field.'</select>';
}
/// create a <input type="radio"> element
/** checked if "checked" = true or if resolvedValue = value
@param name attribute of tag
@param value attribute of tag
@param checked indicates whether field is checked or not
@param x list of options including "id", "class", "on[click|mouseover|...]", "alt", "title" and "extra", which is included in the tag
*/
static function radio($name, $value, $checked=null, $x=null){
$actualValue = self::resolveValue($name,null);
if($actualValue == $value){
$checked = true;
}
return '<input type="radio" name="'.$name.'" '.(self::hasValue($value)?' checked':null).self::additionalAttributes($x,$name).' value="'.htmlspecialchars($option).'" />';
}
/// create an <input type="checkbox"> element
/** checked if "checked" = true or if resolvedValue = value
@param name attribute of tag
@param checked indicates whether field is checked or not
@param x list of options including "id", "class", "on[click|mouseover|...]", "alt", "title" and "extra", which is included in the tag
@note the only value is 1, because checkboxes should probably be unique in the name and values other than 1 are unnecessary
*/
static function checkbox($name, $checked=null, $x=null){
$value = self::resolveValue($name,$value);
return '<input type="checkbox" name="'.$name.'" '.(self::hasValue($value)?' checked="1" ':null).self::additionalAttributes($x,$name).' value=1 />';
}
/// create an <input type="text"> element
/** checked if "checked" = true or if resolvedValue = value
@param name attribute of tag
@param value attribute of tag
@param x list of options including "id", "class", "on[click|mouseover|...]", "alt", "title" and "extra", which is included in the tag
*/
static function text($name, $value=null, $x=null){
$value = self::resolveValue($name,$value);
return '<input type="text" name="'.$name.'" '.(self::hasValue($value)?' value="'.htmlspecialchars($value).'" ':null).self::additionalAttributes($x,$name).'/>';
}
/// create an <input type="file"> element
/** checked if "checked" = true or if resolvedValue = value
@param name attribute of tag
@param value attribute of tag
@param x list of options including "id", "class", "on[click|mouseover|...]", "alt", "title" and "extra", which is included in the tag
*/
static function file($name, $value=null, $x=null){
$value = self::resolveValue($name,$value);
return '<input type="file" name="'.$name.'" '.(self::hasValue($value)?' value="'.htmlspecialchars($value).'" ':null).self::additionalAttributes($x,$name).'/>';
}
/// create a <textarea> element
/** checked if "checked" = true or if resolvedValue = value
@param name attribute of tag
@param value attribute of tag
@param x list of options including "id", "class", "on[click|mouseover|...]", "alt", "title" and "extra", which is included in the tag
*/
static function textarea($name, $value=null, $x=null){
$value = self::resolveValue($name,$value);
return '<textarea name="'.$name.'" '.self::additionalAttributes($x,$name).'>'.(self::hasValue($value)?htmlspecialchars($value):null).'</textarea>';
}
/// create an <input type="password"> element
/** checked if "checked" = true or if resolvedValue = value
@param name attribute of tag
@param value attribute of tag
@param x list of options including "id", "class", "on[click|mouseover|...]", "alt", "title" and "extra", which is included in the tag
*/
static function password($name, $value=null, $x=null){
$value = self::resolveValue($name,$value);
return '<input type="password" name="'.$name.'"'.(self::hasValue($value)?'value="'.htmlspecialchars($value).'" ':null).self::additionalAttributes($x,$name).'/>';
}
/// create an <input type="hidden"> element
/** checked if "checked" = true or if resolvedValue = value
@param name attribute of tag
@param value attribute of tag
@param x list of options including "id", "class", "on[click|mouseover|...]", "alt", "title" and "extra", which is included in the tag
*/
static function hidden($name,$value=null,$x=null){
$value = self::resolveValue($name,$value);
return '<input type="hidden" name="'.$name.'" '.(self::hasValue($value)?'value="'.htmlspecialchars($value).'" ':null).self::additionalAttributes($x,$name).'/>';
}
/// create an <input type="submit"> element
/** checked if "checked" = true or if resolvedValue = value
@param name attribute of tag
@param value attribute of tag
@param x list of options including "id", "class", "on[click|mouseover|...]", "alt", "title" and "extra", which is included in the tag
@note value and name are switchedin param position because it is more likely the value will be desired input than the name.
*/
static function submit($value=null,$name=null,$x=null){
return '<input type="submit" name="'.$name.'" '.(self::hasValue($value)?'value="'.htmlspecialchars($value).'" ':null).self::additionalAttributes($x,$name).'/>';
}
///used to determine if a value actually exists
static function hasValue($value){
if($value || $value === '0' || $value === 0){
return true;
}
}
}
Form::$defaultClassOn = Config::$x['defaultFormFieldClassOn'];