I am trying to rewrite old procedural forms with form processing that repeats alot of code. I thought a class/OOP would work best and being influenced by some of the form classes, I just wrote a simple class (still a beginner, please be kind).
abstract class FormProcess {
var $_valArray = array();
var $_valError = array();
function addValidation( $field, $callback ) {
$this->_valArray[] = array(
'field' => $field,
'callback' => $callback
);
}
function validate() {
$array = array();
foreach( $this->_valArray as $v ) {
$validated = $v['callback'](
$_POST[$v['field']]
);
// Expecting an array back from the callback
if ( isset($validated['error']) ) {
$this->valError[$v['field']] = $validated['error'];
} else {
$array[$v['field']] = $validated['value'];
}
}
return $array;
}
function hasError() {
if (!empty($this->valError)) {
return TRUE;
}
}
abstract function send();
}
The problem is, when I start defining the forms, the callback functions and the send() method seem to repeat themselves and I would to keep the DRY element.
<!DOCTYPE html>
<html>
<head>
<title>Test Form</title>
</head>
<body>
<?php
class ExampleForm extends FormProcess {
private $formName;
public function __construct( $form_name ) {
$this->formName = $form_name;
// For the required inputs specific to this form
$this->addValidation('ip', 'checkIP');
$this->addValidation('time', 'checkTime');
}
public function formReqInput() {
return ' <input type="hidden" name="ip" value="'. $_SERVER['REMOTE_ADDR'] .'" />
<input type="hidden" name="time" value="'. time() .'" />';
}
// Example of a send method
public function send() {
if ( isset($_POST['submit-'.$this->formName]) ) {
$validated = $this->validate();
if ($this->hasError()) {
echo 'Error Found!';
print_r($this->valError);
} else {
echo 'Sending Message';
// go though the validated['values']
}
}
}
}
function checkName($name) {
if ($name == '') {
$var['error'] = 'The name is empty.';
} else {
$var['value'] = trim($name);
}
return $var;
}
function checkSubject($subject) {
if ($subject == '') {
$var['error'] = 'The subject is empty';
} else {
$var['value'] = trim($subject);
}
return $var;
}
// The rest would follow the same pattern...
function checkMessage($message) {}
function checkIP($ip) {}
function checkTime($time) {}
$c = new ExampleForm('testForm');
// For the example I will note only 2 validators
$c->addValidation('name', 'checkName');
$c->addValidation('subject', 'checkSubject');
$c->send();
?>
<form action="form.php" method="post" name="testForm">
<p>
<label>Name:</label>
<input type="text" name="name" value="" />
</p>
<p>
<label>Subject:</label>
<input type="text" name="subject" value="" />
</p>
<p>
<label>Message:</label>
<textarea name="message"></textarea>
</p>
<p>
<?php echo $c->formReqInput(); ?>
<input type="submit" name="submit-testForm" value="Submit Form" />
</p>
</form>
<?php
// class SearchForm, pretty much is a clone to ExampleForm without the FormReqInputs and thier respectable validation...
class SearchForm extends FormProcess {
private $formName;
public function __construct( $form_name ) {
$this->formName = $form_name;
}
public function send() {
if ( isset($_POST['submit-'.$this->formName]) ) {
$validated = $this->validate();
if ($this->hasError()) {
echo 'Error Found!';
print_r($this->valError);
} else {
echo 'Sending Query!';
}
}
}
}
function checkSearchQuery( $query ) {
if (strlen($query) < 4 || $query == 'Search Keywords') {
$var['error'] = 'There was an error in the input provided, please try again.';
} else {
$var['value'] = trim($query);
}
return $var;
}
$s = new SearchForm('searchForm');
$s->addValidation('search_query', 'checkSearchQuery');
$s->send();
?>
<form action="form.php" method="post" name="searchForm">
<p>
<input type="text" name="search_query" id="keywords" value="Search Keywords" />
<input type="submit" name="submit-searchForm" value="Submit Search" />
</p>
</form>
</body>
<script type="text/javascript">
window.onload = searchField();
function searchField() {
var kw = document.getElementById("keywords");
kw.onfocus = function() {
kw.value = '';
}
kw.onblur = function() {
if (kw.value == '') {
kw.value = "Search Keywords";
}
}
}
</script>
</html>
Also any critique of the class is helpful as well, am I missing anything important? I don’t need the form to be rendered, hence why I am not using a framework or the Zend Form class.