I had a spare hour so I extended it to include Validation support.
Obviously it's still rough, but it should be functional and easily extendable.
Library: (each of these classes should really be in a separate file)
PHP Code:
class Form
{
protected $_elements = array();
protected $_action = null;
protected $_method = 'post';
public function __construct()
{
$this->init();
}
public function init()
{}
public function addElement(Form_Element $element)
{
if (null === $element->getName()) {
throw new Exception('Element must have name');
}
$this->_elements[$element->getName()] = $element;
return $this;
}
public function setAction($action)
{
$this->_action = $action;
return $this;
}
public function setMethod($method)
{
$this->_method = $method;
return $this;
}
public function render()
{
$output = '<form action="' . $this->_action . '" method="' . $this->_method . '">';
foreach ($this->_elements as $element) {
$output .= '<pre>' . print_r($element->getErrors(), true) . '</pre>';
$output .= '<p>' . $element->getHtml() . '</p>';
}
$output .= '</form>';
return $output;
}
public function isValid(array $data)
{
$valid = true;
foreach ($this->getElements() as $key => $element) {
if (isset($data[$key])) {
$valid = $element->isValid($data[$key]) && $valid;
$element->setValue($data[$key]);
} else {
$valid = $element->isValid(null) && $valid;
}
}
return $valid;
}
public function getElements()
{
return $this->_elements;
}
}
abstract class Form_Element
{
protected $_name = null;
protected $_validators = array();
protected $_value = null;
protected $_errors = array();
public function __construct($name = null)
{
$this->setName($name);
}
public function setName($name)
{
$this->_name = $name;
}
public function getName()
{
return $this->_name;
}
public function setValue($string)
{
$this->_value = $string;
}
public function addValidator(Validate $validator)
{
$this->_validators[] = $validator;
}
public function isValid($string)
{
$valid = true;
foreach ($this->getValidators() as $validator) {
if ($validator->isValid($string)) {
$valid = true && $valid;
} else {
$valid = false;
$this->_errors[] = $validator->getError();
}
}
return $valid;
}
public function getErrors()
{
return $this->_errors;
}
public function getValidators()
{
return $this->_validators;
}
abstract public function getHtml();
}
class Form_Element_Text extends Form_Element
{
public function getHtml()
{
return '<input type="text" name="' . $this->_name . '" value="' . $this->_value . '"/>';
}
}
class Form_Element_Submit extends Form_Element
{
public function getHtml()
{
return '<input type="submit" name="' . $this->_name . '" />';
}
}
abstract class Validate
{
protected $_options = array();
protected $_error = null;
public function __construct(array $options = array())
{
$this->setOptions($options);
}
public function setOptions(array $options = array())
{
$this->_options = $options;
}
public function getOption($key)
{
return $this->_options[$key];
}
protected function _setError($text)
{
$this->_error = $text;
}
public function getError()
{
if (null === $this->_error) {
return false;
} else {
return $this->_error;
}
}
abstract public function isValid($string);
}
class Validate_StringLength extends Validate
{
public function isValid($string)
{
$length = strlen($string);
if (($length >= $this->getOption('min')) && ($length <= $this->getOption('max'))) {
return true;
}
$this->_setError("\"$string\" length is not >= {$this->getOption('min')} && <= {$this->getOption('max')}");
return false;
}
}
class Validate_Numeric extends Validate
{
public function isValid($string)
{
if (is_numeric($string)) {
return true;
}
$this->_setError("$string is not numeric");
return false;
}
}
Build your form:
PHP Code:
class ExampleForm extends Form
{
public function init()
{
$this->setMethod('post');
$name = new Form_Element_Text('name');
$name->addValidator(
new Validate_StringLength(array(
'min' => 4,
'max' => 20,
))
);
$age = new Form_Element_Text('age');
$age->addValidator(new Validate_Numeric());
$age->addValidator(
new Validate_StringLength(array(
'min' => 1,
'max' => 2,
))
);
$submit = new Form_Element_Submit('submit');
$this->addElement($name)
->addElement($age)
->addElement($submit);
}
}
Use it!
PHP Code:
$form = new ExampleForm();
$form->setAction($_SERVER['PHP_SELF']);
if (!empty($_POST)) {
if ($form->isValid($_POST)) {
echo "Valid form!\n";
}
}
echo $form->render();
This displays the form, validates it, displays error messages, and auto repopulates data automatically for you.
If anyone has questions feel free to ask.
Bookmarks