Klassen zum Erzeugen und Überprüfen von Formularen
class.T4R_checkform.php
<?php
/*
*Copyright (C) [2007] [Robin Henschel]
*
*This program is free software; you can redistribute it and/or modify it under
*the terms of the GNU General Public License as published by the Free Software
*Foundation; either version 2 of the License, or (at your option) any later
*version.
*
*This program is distributed in the hope that it will be useful, but WITHOUT
*ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
*FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
*You should have received a copy of the GNU General Public License along with
*this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
*St, Fifth Floor, Boston, MA 02110, USA
*/
/**
* Klasse zum Überprüfen eines Formulares das mit der Klasse
* T4R_Form erzeugt worden ist.
*
* @author Robin Henschel <r.henschel@t4r-webdesign.de>
* @version 1.0
* @example ./test.php
*
*/
class T4R_CheckForm extends T4R_Form
{
/**
* In diesem array werden die Eingabefelder gespeichert , welche nicht
* ausgefüllt worden sind.
*
* @access private
*
* @var array(string)
*/
private $missingFields = array();
/**
* Aufruf des Konstruktors der Klasse T4R_Form
*
* @access public
*
* @param string $formName
*/
public function __construct( $formName )
{
parent::__construct($formName);
}
/**
* Überprüft ob in den vorgebenen Feldern ein Inhalt verfügbar ist.
* Die Überprüfung gilt als bestanden, wenn der Inhalt aus mehr wie
* einem Zeichen besteht.
* Der übergebene Parameter muss ein array sein, im Falle das es kein
* array ist, wird eine Exception geworfen.
*
* @access public
*
* @param array(string) $fields
*/
public function checkFields( $fields )
{
if(!is_array($fields))
throw new Exception('argument must be an array');
foreach($fields as $field)
{
if(!isset($_POST[$this->prefix.'_'.$field]) or strlen($_POST[$this->prefix.'_'.$field]) < 1)
$this->missingFields[] = $field;
}
$this->ParseErrorForm();
$this->addValues();
}
/**
* Äquivalent zu der Methode checkFields.
* Die zu Prüfenden Felder werden hier nur aus der .ini Datei gelesen
* und nicht der Methode direkt übergeben.
*
* @access public
*/
public function checkFieldsIni()
{
$check = $this->iniData['check'];
$temp = explode(',', $check);
foreach($temp as $value)
$fields[] = trim($value);
$this->checkFields($fields);
}
/**
* Falls Eingabefehler aufgetaucht sind, werden diese mit dieser
* Methode im Formular sichtbar gemacht.
*
* @access private
*
*/
private function ParseErrorForm()
{
$this->createForm();
foreach($this->missingFields as $missingField)
{
$pos = 0;
while(true)
{
$pos = stripos($this->form, 'name="'.$this->prefix.'_'.$missingField.'"', $pos);
if($pos === false)
break;
$length = $this->addErrorMarker($pos);
$pos += strlen($missingField) + $length;
}
}
}
/**
* Plaziert ein 'Fehlersymbol' vor dem entsprechenden Eingabeelement
*
* @access private
*
* @param int $pos
* @return string
*/
private function addErrorMarker( $pos )
{
$substr = substr($this->form, 0, $pos);
$splitPos = strripos($substr, '</label>');
$start = substr($this->form, 0, $splitPos);
$end = substr($this->form, $splitPos);
$errorMsg = '<span style="color:red">*</span>';
$this->form = $start.$errorMsg.$end;
return strlen($errorMsg);
}
/**
* Fügt die eingegebenen Werte in das Formular ein
*
* @access private
*
*/
private function addValues()
{
$valueString = 'value="';
$valueStringLength = strlen($valueString);
foreach($_POST as $field=>$value)
{
$pos = 0;
$length = strlen($field);
while(true)
{
$pos = stripos($this->form, 'name="'.$field.'"', $pos);
if($pos === false)
break;
if($this->CheckType($pos, $value))
{
$startPos = stripos($this->form, $valueString, $pos);
$endPos = stripos($this->form, '"', $startPos+$valueStringLength);
$start = substr($this->form, 0, $startPos+$valueStringLength);
$end = substr($this->form, $endPos);
$this->form = $start.$value.$end;
}
$pos += $length;
}
}
}
/**
* Diese Methode überprüft um welches Eingabeelement es sich handelt und
* fügt den entsprechenden Inhalt ein. Bei Radiobutton und Checkbox wird
* ggf. das 'checked' attribute gesetzt, bei einem Submitbuton wird keine
* Aktion ausgeführt und bei allen anderen Elementen wird der entsprechende
* Value wert eingefügt.
* Falls es sich um einen Komplett falschen Typ handelt wird eine Exception
* geworfen.
*
* @param int $pos
* @param string $value
* @return string
*/
private function CheckType($pos, $value)
{
$substr = substr($this->form, 0, $pos);
$startPos = strripos($substr, 'type="');
$endPos = stripos($substr, '"', $startPos+7);
$valueString = 'value="';
$valueStringLength = strlen($valueString);
$type = substr($this->form, $startPos+6, $endPos-$startPos-6);
$startPos = stripos($this->form, $valueString, $pos);
$endPos = stripos($this->form, '"', $startPos+$valueStringLength);
$checkValue = substr($this->form, $startPos+$valueStringLength, $endPos-$startPos-$valueStringLength);
switch($type)
{
case 'text':
return true;
break;
case 'radio':
case 'checkbox':
if($checkValue == $value)
{
$endPos = stripos($this->form, '/>', $pos);
$startPos = $endPos - 1;
$string = 'checked="checked" ';
$start = substr($this->form, 0, $startPos);
$end = substr($this->form , $endPos);
$this->form = $start.$string.$end;
}
return false;
break;
case 'submit':
return false;
break;
default:
throw new Exception('wrong input type found');
}
}
/**
* Diese Methode gibt das überprüfte Formular aus.
*
* @return string
*/
public function __tostring()
{
return $this->form;
}
}
?>
class.T4R_form.php
<?php
/*
*Copyright (C) [2007] [Robin Henschel]
*
*This program is free software; you can redistribute it and/or modify it under
*the terms of the GNU General Public License as published by the Free Software
*Foundation; either version 2 of the License, or (at your option) any later
*version.
*
*This program is distributed in the hope that it will be useful, but WITHOUT
*ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
*FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
*You should have received a copy of the GNU General Public License along with
*this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
*St, Fifth Floor, Boston, MA 02110, USA
*/
/**
* Klasse zum einfachen erzeugen eines Formulares.
* Es besteht die Möglichkeit ein Formular über einzelne Aufrufe der
* Methode addField zusammen zu stellen, oder über eine .ini Datei
*
* @author Robin Henschel <r.henschel@t4r-webdesign.de>
* @version 1.0
* @example ./test.php
*
*/
class T4R_Form
{
/**
* In dieser Variablen wird der Inhalt der .ini Datei gespeichert, der zur
* Darstellung des Formulares dient.
*
* @access protected
*
* @var string
*/
protected $iniData;
/**
* Action-URL für das Formular
*
* @access private
*
* @var string
*/
private $url;
/**
* Array mit allen Feldern die in dem Formular angezeigt werden sollen
*
* @access private
*
* @var array
*/
private $fields = array();
/**
* Array mit allen CSS Klassen für das Formular
*
* @access private
*
* @var array
*/
private $cssClass = array();
/**
* Array mit allen zusätzlichen Attributen für das Formular
*
* @access private
*
* @var array
*/
private $attribute = array();
/**
* Diese Variable enthält das komplette Formular sobale es erzeugt worden ist
*
* @access protected
*
* @var string
*/
protected $form = null;
/**
* Der Namen des Formulares
*
* @access private
*
* @var string
*/
private $formName;
/**
* Prefix für das Formular.
* Dieses Prefix wird jedem Eingabefeld vorangestellt, damit es im globalen
* Namensraum keine Namenskonflikte geben kann
*
* @access protected
*
* @var string
*/
protected $prefix = 'T4R_Form';
/**
* Generiert die URL für das Formular, ebenso wie die Bezeichnung
* des Formulares.
* Falls eine ini Datei existiert wird diese geparst
*
* @access public
*
* @param string $formName
*/
public function __construct ($formName)
{
$this->url = $_SERVER['PHP_SELF'];
$this->formName = $formName;
if(is_file('form.ini'))
$this->iniData = parse_ini_file('form.ini', true);
else
$this->iniData = null;
}
/**
* Beim Aufruf dieser Methode wird ein Formular anhand der Definition
* in der .ini Datei erzeugt. Dabei wird nur der Teil der .ini Datei
* benützt welcher zu dem Namen des Formulares gehört.
*
* @access public
*/
public function useIniFile()
{
$this->iniData = $this->iniData[$this->formName];
foreach($this->iniData as $type => $data)
{
switch(strtolower($type))
{
case 'input':
foreach($data as $name)
{
$temp = explode(',', $name);
$this->addField('input', trim($temp[0]), trim($temp[1]), trim($temp[2]));
}
break;
case 'hidden':
foreach($data as $name)
{
$temp = explode(',', $name);
$this->addField('hidden', trim($temp[0]), trim($temp[1]), trim($temp[2]));
}
break;
case 'password':
foreach($data as $name)
{
$temp = explode(',', $name);
$this->addField('pass', trim($temp[0]), trim($temp[1]), trim($temp[2]));
}
break;
case 'radio':
foreach($data as $name)
{
$temp = explode(',', $name);
$this->addField('radio', trim($temp[0]), trim($temp[1]), trim($temp[2]));
}
break;
case 'submit':
foreach($data as $name)
{
$temp = explode(',', $name);
$this->addField('submit', trim($temp[0]), null, trim($temp[1]));
}
break;
case 'css':
foreach($data as $name)
{
$temp = explode(',', $name);
$this->setCSSClass(trim($temp[0]), trim($temp[1]));
}
break;
case 'attr':
foreach($data as $name)
{
$temp = explode(',', $name);
$this->addAttribute(trim($temp[1]), trim($temp[0]), trim($temp[2]));
}
break;
}
}
}
/**
* Methode zum Hinzufügen von Eingabefeldern in das Formular.
* Jedem Namen wird das Prefix vorangestellt.
* Es sind folgende Typen möglich:
* - input (text)
* - input (hidden)
* - input (password)
* - radiobutton
* - checkbox
* - submitbutton
*
* @access public
*
* @param string $type
* @param string $name
* @param string $label
* @param string $value
* @param bool $check
*/
public function addField( $type, $name, $label = null, $value = null, $check = null )
{
switch($type)
{
case 'input':
$name = $this->prefix.'_'.$name;
$this->addInputField($name, $label, $value);
break;
case 'hidden':
$name = $this->prefix.'_'.$name;
$this->addHiddenField($name, $label, $value);
break;
case 'pass':
$name = $this->prefix.'_'.$name;
$this->addPasswordField($name, $label);
break;
case 'radio':
$name = $this->prefix.'_'.$name;
$this->addRadiobutton($name, $value, $label, $check);
break;
case 'check':
$name = $this->prefix.'_'.$name;
$this->addCheckBox($name, $value, $label, $check);
break;
case 'submit':
$this->addSubmitButton($name, $value);
break;
default:
throw (new Exception('Wrong Field type'));
break;
}
}
/**
* Hier lässt sich für jedes Element eine CSS Klasse definieren
*
* @access public
*
* @param string $element
* @param string $class
*/
public function setCSSClass( $element, $class)
{
settype($class, 'string');
settype($element, 'string');
$this->cssClass[$element] = array('class'=>$class);
}
/**
* Falls einen HTML Element ein weiteres Attribute zugewiesen werden soll,
* so ist das hier möglich.
*
* @access public
*
* @param string $tag
* @param string $attribute
* @param string $value
*/
public function addAttribute( $tag, $attribute, $value )
{
settype($tag, 'string');
settype($attribute, 'string');
settype($value, 'string');
$this->attribute[$tag] = array($attribute=>$value);
}
/**
* Falls nicht das Standard .ini File verwendet werden soll, kann mit Hilfe
* dieser Methode ein alternatives .ini File geladen werden
*
* @access public
*
* @param string $file
*/
public function LoadIniFile( $file )
{
if(is_file($file))
$this->iniDate = parse_ini_file($file);
else
throw new Exception('The given file doesn\'t exist');
}
/**
* Überschreibt das Standard Prefix mit einem vom Entwickler ausgesuchten
* Prefix. Das Prefix muss eine Zeichenlänge >1 besitzen.
*
* @access public
*
* @param string $string
*/
public function SetPrefix( $string )
{
if(strlen($string) > 1)
$this->prefix = $string;
else
throw new Exception('length of the prefix must be greater than 1 char');
}
/**
* Fügt dem Formular ein Text-Eingabefeld hinzu
*
* @access privat
*
* @param string $name
* @param string $label
* @param string $value
*/
private function addInputField( $name, $label, $value )
{
$element = '<input type="text" name="'.$name.'" value="'.$value.'" />';
$this->fields[] = array($label, $element);
}
/**
* Fügt dem Formular ein Hidden-Feld hinzu
*
* @access privat
*
* @param string $name
* @param string $label
* @param string $value
*/
private function addHiddenField( $name, $label, $value )
{
$element = '<input type="hidden" name="'.$name.'" value="'.$value.'" />';
$this->fields[] = array($label, $element);
}
/**
* Fügt dem Formular ein Passwort-Eingabefeld hinzu
*
* @access privat
*
* @param string $name
* @param string $label
*/
private function addPasswordField( $name, $label)
{
$element = '<input type="password" name="'.$name.'" />';
$this->fields[] = array($label, $element);
}
/**
* Fügt dem Formular einen Radiobutton hinzu
*
* @access privat
*
* @param string $name
* @param string $value
* @param string $label
* @param bool $check
*/
private function addRadiobutton( $name, $value, $label, $check )
{
if($check === true)
$check = 'checked="checked"';
else
$check = null;
$element = '<input type="radio" name="'.$name.'" value="'.$value.'" '.$check.' />';
$this->fields[] = array($label, $element);
}
/**
* Fügt dem Formular eine Checkbox hinzu
*
* @access privat
*
* @param string $name
* @param string $value
* @param string $label
* @param bool $check
*/
private function addCheckBox( $name, $value, $label, $check )
{
if($check === true)
$check = 'checked="checked"';
else
$check = null;
$element = '<input type="checkbox" name="'.$name.'" value="'.$value.'" '.$check.' />';
$this->fields[] = array($label, $element);
}
/**
* Fügt dem Formular einen Submit-Button hinzu
*
* @access privat
*
* @param string $name
* @param string $value
*/
private function addSubmitButton( $name, $value)
{
$element = '<input type="submit" name="'.$name.'" value="'.$value.'" />';
$this->fields[] = array(null, $element);
}
/**
* Erstellt das Formular und speichert es in einer
* Klassen Variablen ab.
*
* @access protected
*
*/
protected function CreateForm()
{
$form = '<fieldset ><legend >'.$this->formName.'</legend>';
$form .= '<form action="'.$this->url.'" method="post" >';
foreach($this->fields as $field)
{
$form .= '<label >'.$field[0].'</label>';
$form .= $field[1].'<br />';
}
$form .= '</form></fieldset>';
$this->form = $form;
}
/**
* Ergänzt die HTML-Tags um Ihre Attribute
*
* @access private
*
* @param array(string=>string) $attributeArray
*/
private function ParseAttributes( $attributeArray )
{
foreach($attributeArray as $tag => $name)
{
$length = strlen($tag);
$pos = null;
foreach ($name as $attribute => $value)
{
while(true)
{
$lowerCaseForm = strtolower($this->form);
$pos = stripos($lowerCaseForm, '<'.strtolower($tag), $pos);
if($pos === false)
break;
$pos += $length + 1;
$start = substr($this->form, 0, $pos+1);
$end = substr($this->form, $pos);
$this->form = $start.$attribute.'="'.$value.'"'.$end;
}
}
}
}
/**
* Alternative Action-URL für das Formular
*
* @access public
* @exception
*
* @param string $url
*/
public function SetUrl($url)
{
if(is_string($url))
$this->url = $url;
else
throw new Exception('Submitted string is invalid');
}
/**
* Gibt das Formular fertig zur Darstellung zurück
*
* @return string
*/
public function ShowForm()
{
$this->CreateForm();
$this->ParseAttributes($this->cssClass);
$this->ParseAttributes($this->attribute);
return $this->form;
}
/**
* Alternative Möglichkeit das Formular anzeigen zu lassen
*
* @return string
*/
public function __tostring()
{
return $this->ShowForm();
}
}
?>
form.ini
;ini Datei f?r class.T4R_form.php und class.T4R_checkform.php
;Innerhalb dieser Datei ist es m?glich den Aufbau des Formulars
;zu Definieren.
;Da es m?glich ist, innerhalb dieser Datei verschiedene Formulare
;zu Definieren, muss jedes neue Formular mit der Zeile:
;[Formularname]
;eingeleitet werden.
;
;Formularelemente werden auf folgende art Definiert:
;Typ[] = Name, Beschriftung, Inhalt
;
;CSS Eigenschaften kann man wie folgt festlegen:
;CSS[] = Element, Klasse
;
;Andere Attribute kann man einem Element mit der folgenden Zeile zuweisen:
;Attr[] = Attribute, Element, Inhalt
;
;Pflichtfelder k?nnen auch festgelegt werden:
;Check = Element1, Element2,....
[Kontaktformular]
input[] = surname, Vorname:, Robin
input[] = name, Nachname:, Henschel
radio[] = single, Ja,
radio[] = single, Nein,
submit[] = submit, Absenden,
css[] = Form, formCL
css[] = input, inputCL
css[] = label, labelCL
css[] = fieldset, fieldsetCL
css[] = legend, legendCL
attr[] = id, input, test
check = surname, name, single
test.php
<?php
/*
*Copyright (C) [2007] [Robin Henschel]
*
*This program is free software; you can redistribute it and/or modify it under
*the terms of the GNU General Public License as published by the Free Software
*Foundation; either version 2 of the License, or (at your option) any later
*version.
*
*This program is distributed in the hope that it will be useful, but WITHOUT
*ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
*FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
*You should have received a copy of the GNU General Public License along with
*this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
*St, Fifth Floor, Boston, MA 02110, USA
*/
/**
* Einbinden der beiden T4R_Form Klassen
*/
require_once('../form/class.T4R_form.php');
require_once('../form/class.T4R_checkform.php');
/**
* Falls der Submit-Button gedrückt worden ist, wird das Formular
* überprüft.
*/
if(isset($_POST['submit']) && $_POST['submit'] == 'Absenden')
{
/**
* Initialisierung der T4R_CheckForm Klasse mit dem entsprechenden
* Namen des Formulares.
*/
$obj = new T4R_CheckForm('Kontaktformular');
/**
* Definition des Formulares wird aus der .ini Datei gelesen.
*/
$obj->useIniFile();
/**
* Die zu überprüfenden Felder werden ebenfalls aus der .ini Datei
* gelesen.
*/
$obj->checkFieldsIni();
/**
* Ausgabe des überprüften Formulares
*/
echo $obj;
}
else
{
/**
* Initialisierung der T4R_Form Klasse, mit dem entsprechenden
* Namen des Formulares.
*/
$obj = new T4R_Form('Kontaktformular');
/**
* Die diversen Eingabefelder werden erzeugt.
*/
$obj->addField('input', 'surname', 'Vorname: ', 'Robin');
$obj->addField('input', 'name', 'Nachname: ', 'Henschel');
$obj->addField('radio', 'single', 'Ja ');
$obj->addField('radio', 'single', 'Nein ');
$obj->addField('submit', 'submit', '', 'Absenden');
/**
* Die CSS-Klassen werden den einzelnen Elementen zugewiesen.
*/
$obj->setCSSClass('form', 'formCL');
$obj->setCSSClass('input', 'inputCL');
$obj->setCSSClass('label', 'labelCL');
$obj->setCSSClass('fieldset', 'fieldsetCL');
$obj->setCSSClass('legend', 'legendCL');
/**
* Attribute werden den einzelnen Elementen zugewiesen.
*/
$obj->addAttribute('input', 'id', 'test');
/**
* Das fertig erzeugte Formular wird ausgegeben.
*/
echo $obj;
}
?>