marek_mar
12-03-2005, 06:12 PM
I've written this simple class as a part of a project I've been doing. It required lots of forms so I quickly saw a need for it.
class form
{
var $name = '';
var $action = '';
var $data = array();
var $error = array();
var $valid = array();
var $submit = array();
function form($name, $action)
{
$this->name = $name;
$this->action = $action;
return true;
}
function add($name, $type, $human_value, $value = false, $max = false, $min = false, $size = false)
{
if(isset($this->data[$name]))
{
return -1;
}
if($type == 'submit')
{
$this->submit[] = $name;
}
if(!$type != 'select')
{
$this->data[$name] = array_slice(func_get_args(), 1);
return true;
}
$this->data[$name] = array(func_get_arg(1), array_slice(func_get_args(), 1));
return true;
}
function add_option($select, $value, $human_value = false)
{
if(!isset($this->data[$select]) || ($this->data[$select][0] != 'select' && $this->data[$select][0] != 'radio'))
{
return false;
}
$this->data[$select][] = array_slice(func_get_args(), 1);
return true;
}
function raw($data)
{
$this->data[] = array('raw', $data);
return true;
}
function check_submit()
{
for($i = 0, $n = count($this->submit); $i < $n; $i++)
{
if(isset($_POST[$this->submit[$i]]))
{
return $this->submit[$i];
break;
}
}
return false;
}
function get_valid_values()
{
$ret = array();
for($i = 0, $n = count($this->valid); $i < $n ; $i++)
{
if($this->data[$this->valid[$i]][0] == 'select' || $this->data[$this->valid[$i]][0] == 'radio')
{
$ret[$this->valid[$i]] = $this->data[$this->valid[$i]][$_POST[$this->valid[$i]] + 1][0];
}
else
{
$ret[$this->valid[$i]] = $_POST[$this->valid[$i]];
}
}
return $ret;
}
function make($show_errors = true)
{
$ret = array();
$submit = $this->check_submit();
$i = 1;
$ret[] = '<form name="' . $this->name . '" action="' . $this->action . '" method="POST">';
foreach($this->data as $name => $values)
{
$ret[$i] = (strlen($values[1]) && $values[0] != 'raw') ? '<label for="' . $name . '">' . $values[1] . ': </label>' : '';
switch($values[0])
{
case 'raw':
$ret[$i] = $values[1];
break;
case 'textarea':
$ret[$i] .= '<br /><textarea name="' . $name . '" id="' . $name . '"' . ((isset($values[5]) && is_array($values[5])) ? 'cols="' . $values[5][0] . '" rows="' . $values[5][1] . '"' : '') . '>' . (($submit && isset($_POST[$name])) ? $_POST[$name] : $values[2]) . '</textarea>';
$ret[$i] .= ($show_errors && isset($this->error[$name])) ? "<br />\n{$this->error[$name]}\n" : '';
break;
case 'select':
$ret[$i] .= '<select name="' . $name . '" id="' . $name . '">' . "\n";
for($j = 2, $m = count($values); $j < $m; $j++)
{
$ret[$i] .= '<option value="' . ($j - 1) . '"' . ((isset($_REQUEST[$name]) && ($_REQUEST[$name] == ($j - 1))) ? ' selected="selected"' : '') . '>' . (isset($values[$j][1]) ? $values[$j][1] : $values[$j][0]) . '</option>' . "\n";
}
$ret[$i] .= '</select>';
$ret[$i] .= ($show_errors && isset($this->error[$name])) ? "<br />\n{$this->error[$name]}\n" : '';
break;
case 'radio':
for($j = 2, $m = count($values); $j < $m; $j++)
{
$ret[$i] .= '<input type="radio" name="' . $name . '" id="' . $name . ($j - 1) . '"' . ' value="' . ($j - 1) . '"' . ((isset($_POST[$name]) && ($_POST[$name] == ($j - 1))) ? ' checked="checked"' : '') . '/><label for="' . $name . ($j - 1) . '">' . (isset($values[$j][1]) ? $values[$j][1] : $values[$j][0]) . "</lable>\n";
}
break;
case 'checkbox':
$ret[$i] = '<input type="checkbox" name="' . $name . '" id="' . $name . '"' . ' value="1"' . ((isset($_POST[$name]) && $_POST[$name]) ? ' checked="checked"' : '') . '/><label for="' . $name . '">' . (isset($values[1]) ? $values[1] : $values[0]) . "</lable>\n";
$ret[$i] .= ($show_errors && isset($this->error[$name])) ? "<br />\n{$this->error[$name]}\n" : '';
break;
case 'number':
case 'email':
$ret[$i] .= '<input type="text" name="' . $name . '" id="' . $name . '"' . (((isset($values[2]) && $values[2]) || $submit) ? ' value="' . (($submit && isset($_POST[$name])) ? $_POST[$name] : $values[2]) . '"' : '') . ((isset($values[5]) && $values[5]) ? ' size="' . $values[5] . '"' : '') . ((isset($values[3]) && $values[3]) ? ' maxlength="' . (($values[0] == 'number') ? strlen($values[3]) : $values[3]) . '"' : '') . '/>';
$ret[$i] .= ($show_errors && isset($this->error[$name])) ? "<br />\n{$this->error[$name]}\n" : '';
break;
case 'submit':
$ret[$i] = '<input type="submit" name="' . $name . '" value="' . $values[1] . '"/>';
break;
default:
$ret[$i] .= '<input type="' . $values[0] . '" name="' . $name . '" id="' . $name . '"' . (((isset($values[2]) && $values[2]) || $submit) ? ' value="' . (($submit && isset($_POST[$name])) ? $_POST[$name] : $values[2]) . '"' : '') . ((isset($values[5]) && $values[5]) ? ' size="' . $values[5] . '"' : '') . ((isset($values[3]) && $values[3]) ? ' maxlength="' . $values[3] . '"' : '') . '/>';
$ret[$i] .= ($show_errors && isset($this->error[$name])) ? "<br />\n{$this->error[$name]}\n" : '';
break;
}
$i++;
$ret[] = '</form>';
}
return $ret;
}
function validate($filled = false)
{
foreach($this->data as $name => $values)
{
if(!isset($_POST[$name]))
{
$_POST[$name] = '';
}
$_POST[$name] = trim($_POST[$name]);
$_POST[$name] = (get_magic_quotes_gpc()) ? stripslashes($_POST[$name]) : $_POST[$name];
if(is_array($filled) && in_array($name, $filled) && !strlen($_POST[$name]))
{
$this->error[$name] = 'Value must be set.';
continue;
}
switch($values[0])
{
case 'raw':
break;
case 'number':
if(!is_numeric($_POST[$name]))
{
$this->error[$name] = 'Value must be a number.';
}
if((isset($values[3]) && $values[3] !== false && (float) $_POST[$name] > (float) $values[3]) || (isset($values[4]) && $values[4] !== false && (float) $_POST[$name] < (float) $values[4]))
{
$this->error[$name] = 'Value is too big/small. Value should be between ' . ((isset($values[4])) ? $values[4] : '0') . ' and ' . $values[3] . '.';
}
break;
case 'select':
case 'radio':
if(!is_numeric($_POST[$name]))
{
$this->error[$name] = 'Unpredicted value.';
}
break;
case 'email':
if(!preg_match('/^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/', $_POST[$name]))
{
$this->error[$name] = 'Value is not an email address.';
}
break;
default:
if((isset($values[3]) && $values[3] !== false && strlen($_POST[$name]) >= $values[3]) || (isset($values[4]) && $values[4] !== false && strlen($_POST[$name]) <= $values[4]))
{
$this->error[$name] = 'Value is too long/short. Value should be between ' . ((isset($values[4])) ? $values[4] : '0') . ' and ' . $values[3] . ' characters long.';
}
break;
}
if(!isset($this->error[$name]))
{
$this->valid[] = $name;
}
}
if(count($this->error))
{
return $this->error;
}
return true;
}
}
Ok that's the class and now how to use it:
$form = new form('form name', 'file the form should submit to');
Both arguments are required for the constructor.
It returns true.
To add a form element you use the add() method.
$form->add('elenent name', 'element type', 'description', 'default value', /* maximum length */ 10, /* minimum length */ 0, /* size */ 10);
Arguments after "description" are optional. The last three should be either int or float. If the type is "textarea" the $size argument should be a two element array (width, height).
The types are: text, password, textarea, radio, checkbox, select, number*, email and submit.
It returns bool(true) or int(-1) if an element with the same name exists.
To add options to the select or radio element you use the add_option() method.
$form->add_option('name of the select element to which this option belongs', 'the returned value', 'the value presented to the user');
The last argument is optional. The value of the 2nd argument will be used if it is not set.
It returns bool(true) or bool(false) if there is no select element with the given name.
The make() method returns an array with the form. It return an array so you can add whatever you like inbetween the fields.
$form->make(/* show errors */ true);
The argument is optional and defaults to true. It will print errors below the form elemnts that were filled in incorrectly.
The validate() method validates the form.
$form->validate(array('these', 'are', 'the', 'names', 'of elemnts', 'that', 'must be', 'filled in'));
The argument is optional. It must be an array.
It returns bool(true) or an array with all the errors.
The check_submit() method checks if a form has been submited.
if(false !== $form->check_submit())
{
print 'Form was submitted';
}
It returns the name of the submit button user or false.
The get_valid_values() method returns an associative array with all the values that passed the validation.
var_dump($form->get_valid_values());
To add something between the form elements and not have to play with the array returned by form::make() you can add some raw HTML with the raw() method.
$form->raw('Some HTML');
An example:
$form = new form('upload', $_SERVER['PHP_SELF']);
$form->add('filename', 'text', 'Name', false, 100);
$form->add('comment', 'textarea', 'Comments', 'Put comments here', 10, 2, array(100, 20));
$form->add('guess', 'number', 'Guess a numer from 1 to 10', false, 10, 1, 2);
$form->add('order', 'select', 'Sort order');
$form->raw('Hello there!<br>');
$form->add_option('order', 'ASC', 'Ascending');
$form->add_option('order', 'DESC', 'Descending');
$form->add('email', 'email', 'eMail', false, 100);
$form->add('choice', 'radio', 'Are you sure?');
$form->add_option('choice', 'he is stupid', 'No');
$form->add_option('choice', 'he is smart', 'Yes');
$form->add('agreement', 'checkbox', 'I agree to be good');
$form->add('submit', 'submit', 'Upload');
if($form->check_submit())
{
if(true === $form->validate(array('filename', 'agreement')))
{
print 'Form is filled out correctly.';
}
}
print implode("<br />\n", $form->make());
var_dump($form->get_valid_values());
I may update this if needed.
NOTES:
It does not support arrays (element names with []). Then again it might... to some extent... It was not needed.
*The number type is validated by the size of the number not by the length.
class form
{
var $name = '';
var $action = '';
var $data = array();
var $error = array();
var $valid = array();
var $submit = array();
function form($name, $action)
{
$this->name = $name;
$this->action = $action;
return true;
}
function add($name, $type, $human_value, $value = false, $max = false, $min = false, $size = false)
{
if(isset($this->data[$name]))
{
return -1;
}
if($type == 'submit')
{
$this->submit[] = $name;
}
if(!$type != 'select')
{
$this->data[$name] = array_slice(func_get_args(), 1);
return true;
}
$this->data[$name] = array(func_get_arg(1), array_slice(func_get_args(), 1));
return true;
}
function add_option($select, $value, $human_value = false)
{
if(!isset($this->data[$select]) || ($this->data[$select][0] != 'select' && $this->data[$select][0] != 'radio'))
{
return false;
}
$this->data[$select][] = array_slice(func_get_args(), 1);
return true;
}
function raw($data)
{
$this->data[] = array('raw', $data);
return true;
}
function check_submit()
{
for($i = 0, $n = count($this->submit); $i < $n; $i++)
{
if(isset($_POST[$this->submit[$i]]))
{
return $this->submit[$i];
break;
}
}
return false;
}
function get_valid_values()
{
$ret = array();
for($i = 0, $n = count($this->valid); $i < $n ; $i++)
{
if($this->data[$this->valid[$i]][0] == 'select' || $this->data[$this->valid[$i]][0] == 'radio')
{
$ret[$this->valid[$i]] = $this->data[$this->valid[$i]][$_POST[$this->valid[$i]] + 1][0];
}
else
{
$ret[$this->valid[$i]] = $_POST[$this->valid[$i]];
}
}
return $ret;
}
function make($show_errors = true)
{
$ret = array();
$submit = $this->check_submit();
$i = 1;
$ret[] = '<form name="' . $this->name . '" action="' . $this->action . '" method="POST">';
foreach($this->data as $name => $values)
{
$ret[$i] = (strlen($values[1]) && $values[0] != 'raw') ? '<label for="' . $name . '">' . $values[1] . ': </label>' : '';
switch($values[0])
{
case 'raw':
$ret[$i] = $values[1];
break;
case 'textarea':
$ret[$i] .= '<br /><textarea name="' . $name . '" id="' . $name . '"' . ((isset($values[5]) && is_array($values[5])) ? 'cols="' . $values[5][0] . '" rows="' . $values[5][1] . '"' : '') . '>' . (($submit && isset($_POST[$name])) ? $_POST[$name] : $values[2]) . '</textarea>';
$ret[$i] .= ($show_errors && isset($this->error[$name])) ? "<br />\n{$this->error[$name]}\n" : '';
break;
case 'select':
$ret[$i] .= '<select name="' . $name . '" id="' . $name . '">' . "\n";
for($j = 2, $m = count($values); $j < $m; $j++)
{
$ret[$i] .= '<option value="' . ($j - 1) . '"' . ((isset($_REQUEST[$name]) && ($_REQUEST[$name] == ($j - 1))) ? ' selected="selected"' : '') . '>' . (isset($values[$j][1]) ? $values[$j][1] : $values[$j][0]) . '</option>' . "\n";
}
$ret[$i] .= '</select>';
$ret[$i] .= ($show_errors && isset($this->error[$name])) ? "<br />\n{$this->error[$name]}\n" : '';
break;
case 'radio':
for($j = 2, $m = count($values); $j < $m; $j++)
{
$ret[$i] .= '<input type="radio" name="' . $name . '" id="' . $name . ($j - 1) . '"' . ' value="' . ($j - 1) . '"' . ((isset($_POST[$name]) && ($_POST[$name] == ($j - 1))) ? ' checked="checked"' : '') . '/><label for="' . $name . ($j - 1) . '">' . (isset($values[$j][1]) ? $values[$j][1] : $values[$j][0]) . "</lable>\n";
}
break;
case 'checkbox':
$ret[$i] = '<input type="checkbox" name="' . $name . '" id="' . $name . '"' . ' value="1"' . ((isset($_POST[$name]) && $_POST[$name]) ? ' checked="checked"' : '') . '/><label for="' . $name . '">' . (isset($values[1]) ? $values[1] : $values[0]) . "</lable>\n";
$ret[$i] .= ($show_errors && isset($this->error[$name])) ? "<br />\n{$this->error[$name]}\n" : '';
break;
case 'number':
case 'email':
$ret[$i] .= '<input type="text" name="' . $name . '" id="' . $name . '"' . (((isset($values[2]) && $values[2]) || $submit) ? ' value="' . (($submit && isset($_POST[$name])) ? $_POST[$name] : $values[2]) . '"' : '') . ((isset($values[5]) && $values[5]) ? ' size="' . $values[5] . '"' : '') . ((isset($values[3]) && $values[3]) ? ' maxlength="' . (($values[0] == 'number') ? strlen($values[3]) : $values[3]) . '"' : '') . '/>';
$ret[$i] .= ($show_errors && isset($this->error[$name])) ? "<br />\n{$this->error[$name]}\n" : '';
break;
case 'submit':
$ret[$i] = '<input type="submit" name="' . $name . '" value="' . $values[1] . '"/>';
break;
default:
$ret[$i] .= '<input type="' . $values[0] . '" name="' . $name . '" id="' . $name . '"' . (((isset($values[2]) && $values[2]) || $submit) ? ' value="' . (($submit && isset($_POST[$name])) ? $_POST[$name] : $values[2]) . '"' : '') . ((isset($values[5]) && $values[5]) ? ' size="' . $values[5] . '"' : '') . ((isset($values[3]) && $values[3]) ? ' maxlength="' . $values[3] . '"' : '') . '/>';
$ret[$i] .= ($show_errors && isset($this->error[$name])) ? "<br />\n{$this->error[$name]}\n" : '';
break;
}
$i++;
$ret[] = '</form>';
}
return $ret;
}
function validate($filled = false)
{
foreach($this->data as $name => $values)
{
if(!isset($_POST[$name]))
{
$_POST[$name] = '';
}
$_POST[$name] = trim($_POST[$name]);
$_POST[$name] = (get_magic_quotes_gpc()) ? stripslashes($_POST[$name]) : $_POST[$name];
if(is_array($filled) && in_array($name, $filled) && !strlen($_POST[$name]))
{
$this->error[$name] = 'Value must be set.';
continue;
}
switch($values[0])
{
case 'raw':
break;
case 'number':
if(!is_numeric($_POST[$name]))
{
$this->error[$name] = 'Value must be a number.';
}
if((isset($values[3]) && $values[3] !== false && (float) $_POST[$name] > (float) $values[3]) || (isset($values[4]) && $values[4] !== false && (float) $_POST[$name] < (float) $values[4]))
{
$this->error[$name] = 'Value is too big/small. Value should be between ' . ((isset($values[4])) ? $values[4] : '0') . ' and ' . $values[3] . '.';
}
break;
case 'select':
case 'radio':
if(!is_numeric($_POST[$name]))
{
$this->error[$name] = 'Unpredicted value.';
}
break;
case 'email':
if(!preg_match('/^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/', $_POST[$name]))
{
$this->error[$name] = 'Value is not an email address.';
}
break;
default:
if((isset($values[3]) && $values[3] !== false && strlen($_POST[$name]) >= $values[3]) || (isset($values[4]) && $values[4] !== false && strlen($_POST[$name]) <= $values[4]))
{
$this->error[$name] = 'Value is too long/short. Value should be between ' . ((isset($values[4])) ? $values[4] : '0') . ' and ' . $values[3] . ' characters long.';
}
break;
}
if(!isset($this->error[$name]))
{
$this->valid[] = $name;
}
}
if(count($this->error))
{
return $this->error;
}
return true;
}
}
Ok that's the class and now how to use it:
$form = new form('form name', 'file the form should submit to');
Both arguments are required for the constructor.
It returns true.
To add a form element you use the add() method.
$form->add('elenent name', 'element type', 'description', 'default value', /* maximum length */ 10, /* minimum length */ 0, /* size */ 10);
Arguments after "description" are optional. The last three should be either int or float. If the type is "textarea" the $size argument should be a two element array (width, height).
The types are: text, password, textarea, radio, checkbox, select, number*, email and submit.
It returns bool(true) or int(-1) if an element with the same name exists.
To add options to the select or radio element you use the add_option() method.
$form->add_option('name of the select element to which this option belongs', 'the returned value', 'the value presented to the user');
The last argument is optional. The value of the 2nd argument will be used if it is not set.
It returns bool(true) or bool(false) if there is no select element with the given name.
The make() method returns an array with the form. It return an array so you can add whatever you like inbetween the fields.
$form->make(/* show errors */ true);
The argument is optional and defaults to true. It will print errors below the form elemnts that were filled in incorrectly.
The validate() method validates the form.
$form->validate(array('these', 'are', 'the', 'names', 'of elemnts', 'that', 'must be', 'filled in'));
The argument is optional. It must be an array.
It returns bool(true) or an array with all the errors.
The check_submit() method checks if a form has been submited.
if(false !== $form->check_submit())
{
print 'Form was submitted';
}
It returns the name of the submit button user or false.
The get_valid_values() method returns an associative array with all the values that passed the validation.
var_dump($form->get_valid_values());
To add something between the form elements and not have to play with the array returned by form::make() you can add some raw HTML with the raw() method.
$form->raw('Some HTML');
An example:
$form = new form('upload', $_SERVER['PHP_SELF']);
$form->add('filename', 'text', 'Name', false, 100);
$form->add('comment', 'textarea', 'Comments', 'Put comments here', 10, 2, array(100, 20));
$form->add('guess', 'number', 'Guess a numer from 1 to 10', false, 10, 1, 2);
$form->add('order', 'select', 'Sort order');
$form->raw('Hello there!<br>');
$form->add_option('order', 'ASC', 'Ascending');
$form->add_option('order', 'DESC', 'Descending');
$form->add('email', 'email', 'eMail', false, 100);
$form->add('choice', 'radio', 'Are you sure?');
$form->add_option('choice', 'he is stupid', 'No');
$form->add_option('choice', 'he is smart', 'Yes');
$form->add('agreement', 'checkbox', 'I agree to be good');
$form->add('submit', 'submit', 'Upload');
if($form->check_submit())
{
if(true === $form->validate(array('filename', 'agreement')))
{
print 'Form is filled out correctly.';
}
}
print implode("<br />\n", $form->make());
var_dump($form->get_valid_values());
I may update this if needed.
NOTES:
It does not support arrays (element names with []). Then again it might... to some extent... It was not needed.
*The number type is validated by the size of the number not by the length.