*/
class FormGenerator
{
public $Fields = array();
private $Data;
private $Repopulate = true;
private $Editing = false;
private $InlineErrors = true;
private $RulePadding = 0;
private $Rules;
function __construct($data)
{
$this->Data = $data;
}
public function TableLayout($tab = 0)
{
$this->processFields();
$output = "\n" . $this->spacer($tab) . "
\n";
$colspan = '';
foreach ($this->Fields as $f) {
if ($f->type == 'checkbox' or $f->type == 'radio') {
$colspan = ' colspan="2"';
$row = $f->type == 'checkbox' ?
$this->spacer(2 + $tab) . "| $f->field $f->label$f->error | \n"
: $this->spacer(2 + $tab) . "$f->label | \n"
. $this->spacer(2 + $tab) ."$f->field$f->error | \n";
} else {
$row = $this->spacer(2 + $tab) . "$f->label | \n";
$row .= $this->spacer(2 + $tab) . "$f->field$f->error | \n";
}
$output .= $this->spacer(1 + $tab) . "\n";
$output .= $row;
$output .= $this->spacer(1 + $tab) . "
\n";
}
$output .= $this->spacer($tab) . '
';
return $output;
}
public function FancyFormLayout($tab = 0)
{
$this->processFields();
$output = "\n" . $this->spacer($tab) . "\n";
return $output;
}
public function Rules()
{
return "Rules."?>\n";
}
public function getLabelLayout() {}
public function repopulate($status)
{
$this->Repopulate = $status;
return $this;
}
public function editing($status)
{
$this->Editing = (boolean) $status;
return $this;
}
public function inlineErrors($status)
{
$this->InlineErrors = $status;
return $this;
}
public function spacer($space = 1)
{
return str_repeat(' ', $space * 4);
}
private function processFields()
{
$this->Fields = array();
$previous = new stdClass();
$lines = explode("\n", $this->Data);
foreach ($lines as $line) {
$line = trim($line);
if (empty($line)) {
continue;
}
$field = array_map('trim', explode(',', $line));
$F = new stdClass();
$F->name = array_shift($field);
$F->type = $this->fetchProperty($field, $previous->type);
$F->display = array_shift($field);
$F->rules = array_shift($field);
$F->special = array_shift($field);
$previous = clone $F;
$this->setPaddingForRules(strlen($F->name));
$this->setField($F);
}
$this->setRules();
}
private function setPaddingForRules($length)
{
if ($length > $this->RulePadding) {
$this->RulePadding = $length;
}
}
private function fetchProperty(&$field, $previousValue = '')
{
$property = array_shift($field);
if (is_null($property) or empty($property)) {
return $previousValue;
}
return $property;
}
private function setField($field)
{
$inputs = array('text', 'password', 'hidden',
'file', 'checkbox', 'radio');
if (in_array($field->type, $inputs)) {
$field->field = $this->input($field);
} else {
$field->field = $this->{$field->type}($field);
}
$field->label = $this->setLabel($field);
$field->error = $this->InlineErrors ? $this->setError($field) : '';
$this->Fields[] = $field;
}
private function setLabel($field)
{
return $this->label($field);
}
private function setRules()
{
$rules = '';
foreach ($this->Fields as $F) {
$rules .= $this->setRule($F);
}
$rules .= '$this->validation->set_rules($rules);' . "\n";
$rules .= '$this->validation->set_fields($fields);' . "\n";
$rules .= '$this->validation->set_error_delimiters(\'\',\'
\');' . "\n";
$this->Rules = $rules;
}
private function setRule($field)
{
$base_pad = 13; // 12 for $rules reflectd on the output string
$max = $base_pad + $this->RulePadding;
$current = $base_pad + strlen($field->name);
$total = $max - $current;
$Padding = str_repeat(' ', $total + 1);
$post_rules = empty($field->rules) ? '' : '|';
return "\$rules ['$field->name']$Padding= 'trim|$field->rules{$post_rules}xss_clean';\n\$fields['$field->name']$Padding= '$field->display';\n";
}
private function setError($field)
{
return 'validation->'. $field->name . '_error; ?>';
}
private function label($field)
{
$class = strpos($field->rules, 'required') !== false
? ' class="required"' : '';
$colon = ':';
if ($field->type == 'radio' or $field->type == 'checkbox') {
$colon = '';
}
return '';
}
private function setClass($field)
{
return "class=\"$field->type\" ";
}
/**
* Possible field types: text, password, hidden, textarea, select,
* checkbox, radio, file.
*
*
*/
private function input($field)
{
if ($field->type == 'checkbox') {
$value = " value=\"1\" " . $this->setCheckboxValue($field);
} else {
$value = ' value="' . $this->setValue($field).'"';
}
return 'setClass($field).'id="'.$field->name.'" type="'.$field->type.'" name="'.$field->name.'" '.$value.' />';
}
private function select($field)
{
return '';
}
private function textarea($field)
{
return '';
}
private function setValue($field)
{
if ($this->Repopulate) {
$v = $this->Editing
? "validation->{$field->name}) ? (\$this->validation->{$field->name}) : \$editing->{$field->name}; ?>"
: 'validation->' . $field->name . '; ?>';
return $v;
}
return '';
}
private function setSelectValue($field)
{
if ($this->Repopulate) {
$selected = "validation->{$field->name} == \$option->value) { echo 'selected=\"selected\"';} ?>";
if ($this->Editing) {
$selected = "validation->{$field->name} == \$option->value or \$editing->{$field->name} == \$option->value) { echo 'selected=\"selected\"';} ?>";
}
$php = "special as \$option): ?>";
$php .= "";
$php .= "";
return $php;
}
}
private function setCheckboxValue($field)
{
if ($this->Repopulate) {
$v = $this->Editing
? "validation->set_checkbox('$field->name', '1')) ? (\$this->validation->set_checkbox('$field->name', '1')) : \$checked; ?>"
: "validation->set_checkbox('$field->name', '1'); ?>";
return $v;
}
}
}
?>
CodeIgniter Formgen
Generate a CodeIgniter "Form View" from a CSV input
Just an experiment in code generation
Format of input
Every line is a form field. The "columns" from left to right are:
- Field Name
- Field Type (text, radio, checkbox, select, textarea)
- Field Label
- CodeIgniter rules
- Special values. This is optional and used for select fields.
inlineErrors(true)
->editing(isset($_GET['editing']))
->repopulate(true)
->TableLayout();
$form .= $formgen->FancyFormLayout();
echo '';
echo $formgen->inlineErrors(false)->repopulate(false)->TableLayout();
echo $formgen->FancyFormLayout();
}
?>