diff --git a/interface/index.htm b/interface/index.htm
index d3384f2ec15e89dcf41fb5fa92fe8fb658a662f2..39606dbb3710e1939027c58888cc37edf4c8d956 100644
--- a/interface/index.htm
+++ b/interface/index.htm
@@ -1,12 +1,8 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 <html>
 <head>
-<title>Scrigo CMS</title>
-<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-<meta http-equiv="refresh" content="0;URL=web/index.php">
+  <meta http-equiv="refresh" content="0;URL=web/index.php">
 </head>
-
 <body>
-
 </body>
 </html>
diff --git a/interface/lib/classes/form.inc.php b/interface/lib/classes/form.inc.php
index 6c3d0ccbc05268325c80022ac8d5bd2da247c2bf..e3c1bff1a7f19019b73c4f6d782975ca3cda2b99 100644
--- a/interface/lib/classes/form.inc.php
+++ b/interface/lib/classes/form.inc.php
@@ -1,474 +1,474 @@
-<?php
-/*
-Copyright (c) 2005, Till Brehm, projektfarm Gmbh
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
-      and/or other materials provided with the distribution.
-    * Neither the name of ISPConfig nor the names of its contributors
-      may be used to endorse or promote products derived from this software without
-      specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/**
-* Formularbehandlung
-*
-* Funktionen zur Umwandlung von Formulardaten
-* sowie zum vorbereiten von HTML und SQL
-* Ausgaben
-*
-*	Tabellendefinition
-*	
-*	Datentypen:
-*	- INTEGER (Wandelt Ausdrücke in Int um)
-*	- DOUBLE
-*	- CURRENCY (Formatiert Zahlen nach Währungsnotation)
-*	- VARCHAR (kein weiterer Format Check)
-*	- DATE (Datumsformat, Timestamp Umwandlung)
-*	
-*	Formtype:
-*	- TEXT (normales Textfeld)
-*	- PASSWORD (Feldinhalt wird nicht angezeigt)
-*	- SELECT (Gibt Werte als option Feld aus)
-*	- MULTIPLE (Select-Feld mit nehreren Werten)
-*	
-*	VALUE:
-*	- Wert oder Array
-*	
-*	SEPARATOR
-*	- Trennzeichen für multiple Felder
-*
-*	Hinweis:
-*	Das ID-Feld ist nicht bei den Table Values einzufügen.
-*
-* @package form
-* @author Till Brehm
-* @version 1.1
-*/
-
-class form {
-	
-	/**
-	* Definition der Tabelle (array)
-	* @var tableDef
-	*/
-	var $tableDef;
-	
-	/**
-	* Private
-	* @var action
-	*/
-	var $action;
-	
-	/**
-	* Tabellenname (String)
-	* @var table_name
-	*/
-	var $table_name;
-	
-	/**
-	* Debug Variable
-	* @var debug
-	*/
-	var $debug = 0;
-	
-	/**
-	* name des primary Field der Tabelle (string)
-	* @var table_index
-	*/
-	var $table_index;
-	
-	/**
-	* enthält die Fehlermeldung bei Überprüfung
-	* der Variablen mit Regex
-	* @var errorMessage
-	*/
-	var $errorMessage;
-	
-	var $dateformat = "d.m.Y";
-    var $formDef;
-	
-	/**
-	* Laden der Tabellendefinition
-	*
-	* @param file: Pfad zur Tabellendefinition
-	* @return true
-	*/
-	function loadTableDef($file) {
-		global $app,$conf;
-		
-		include_once($file);
-		$this->tableDef = $table;
-		$this->table_name = $table_name;
-		$this->table_index = $table_index;
-		return true;
-	}
-    
-    function loadFormDef($file) {
-		global $app,$conf;
-		
-		include_once($file);
-		$this->formDef = $form;
-		return true;
-	}
-	
-	
-	/**
-	* Konvertiert die Daten des übergebenen assoziativen
-	* Arrays in "menschenlesbare" Form.
-	* Datentyp Konvertierung, z.B. für Ausgabe in Listen.
-	*
-	* @param record
-	* @return record
-	*/
-	function decode($record) {
-		if(is_array($record)) {
-			foreach($record as $key => $val) {
-				switch ($this->tableDef[$key]['datatype']) {
-				case 'VARCHAR':
-					$new_record[$key] = stripslashes($val);
-				break;
-				
-				case 'DATE':
-					if($val > 0) {
-						$new_record[$key] = date($this->dateformat,$val);
-					}
-				break;
-				
-				case 'INTEGER':
-					$new_record[$key] = intval($val);
-				break;
-				
-				case 'DOUBLE':
-					$new_record[$key] = $val;
-				break;
-				
-				case 'CURRENCY':
-					$new_record[$key] = number_format($val, 2, ',', '');
-				break;
-				
-				default:
-					$new_record[$key] = stripslashes($val);
-				}
-			}
-			
-		}
-	return $new_record;
-	}
-	
-	/**
-	* Record für Ausgabe in Formularen vorbereiten.
-	*
-	* @param record = Datensatz als Array
-	* @param action = NEW oder EDIT 
-	* @return record
-	*/
-	function getHTML($record,$action = 'NEW') {
-		
-		global $app;
-		
-		if(!is_array($this->tableDef)) $app->error("Keine Tabellendefinition vorhanden.");
-		
-		$new_record = array();
-		if($action == 'EDIT') {
-			$record = $this->decode($record);
-			if(is_array($record)) {
-				foreach($record as $key => $val) {
-					switch ($this->tableDef[$key]['formtype']) {
-					case 'SELECT':
-						if(is_array($this->tableDef[$key]['value'])) {
-							$out = '';
-							foreach($this->tableDef[$key]['value'] as $k => $v) {
-								$selected = ($k == $val)?' SELECTED':'';
-								$out .= "<option value='$k'$selected>$v</option>\r\n";
-							}
-						}
-						$new_record[$key] = $out;
-					break;
-					case 'MULTIPLE':
-						if(is_array($this->tableDef[$key]['value'])) {
-							
-							// aufsplitten ergebnisse
-							$vals = explode($this->tableDef[$key]['separator'],$val);
-							
-							// HTML schreiben
-							$out = '';
-							foreach($this->tableDef[$key]['value'] as $k => $v) {
-								
-								$selected = '';
-								foreach($vals as $tvl) {
-									if(trim($tvl) == trim($k)) $selected = ' SELECTED';
-								}
-								
-								$out .= "<option value='$k'$selected>$v</option>\r\n";
-							}
-						}
-						$new_record[$key] = $out;
-					break;
-					
-					case 'PASSWORD':
-						$new_record[$key] = '';
-					break;
-					
-					default:
-						$new_record[$key] = htmlspecialchars($val);
-					}
-				}
-			}
-		} else {
-			foreach($this->tableDef as $key => $val) {
-				switch ($this->tableDef[$key]['formtype']) {
-				case 'SELECT':
-					if(is_array($this->tableDef[$key]['value'])) {
-						$out = '';
-						foreach($this->tableDef[$key]['value'] as $k => $v) {
-							$selected = ($k == $val)?' SELECTED':'';
-							$out .= "<option value='$k'$selected>$v</option>\r\n";
-						}
-					}
-					$new_record[$key] = $out;
-				break;
-				case 'MULTIPLE':
-						if(is_array($this->tableDef[$key]['value'])) {
-							
-							// aufsplitten ergebnisse
-							$vals = explode($this->tableDef[$key]['separator'],$val);
-							
-							// HTML schreiben
-							$out = '';
-							foreach($this->tableDef[$key]['value'] as $k => $v) {
-								
-								$out .= "<option value='$k'>$v</option>\r\n";
-							}
-						}
-						$new_record[$key] = $out;
-					break;
-				
-				case 'PASSWORD':
-					$new_record[$key] = '';
-				break;
-				
-				default:
-					$new_record[$key] = htmlspecialchars($this->tableDef[$key]['value']);
-				}
-			}
-		
-		}
-		
-		if($this->debug == 1) $this->dbg($new_record);
-		
-		return $new_record;
-	}
-	
-	/**
-	* Record in "maschinen lesbares" Format überführen
-	* und Werte gegen reguläre Ausdrücke prüfen.
-	*
-	* @param record = Datensatz als Array
-	* @return record
-	*/
-	function encode($record) {
-		
-		$this->errorMessage = '';
-		
-		if(is_array($record)) {
-			foreach($record as $key => $val) {
-				switch ($this->tableDef[$key]['datatype']) {
-				case 'VARCHAR':
-					if(!is_array($val)) {
-						$new_record[$key] = mysql_real_escape_string($val);
-					} else {
-						$new_record[$key] = implode($this->tableDef[$key]['separator'],$val);
-					}
-				break;
-				case 'DATE':
-					if($val > 0) {
-						list($tag,$monat,$jahr) = explode('.',$val);
-						$new_record[$key] = mktime(0,0,0,$monat,$tag,$jahr);
-					}
-				break;
-				case 'INTEGER':
-					$new_record[$key] = intval($val);
-				break;
-				case 'DOUBLE':
-					$new_record[$key] = mysql_real_escape_string($val);
-				break;
-				case 'CURRENCY':
-					$new_record[$key] = str_replace(",",".",$val);
-				break;
-				}
-				
-				if($this->tableDef[$key]['regex'] != '') {
-					// Enable that "." matches also newlines
-					$this->tableDef[$key]['regex'] .= 's';
-					if(!preg_match($this->tableDef[$key]['regex'], $val)) {
-						$this->errorMessage .= $this->tableDef[$key]['errmsg']."<br>\r\n";
-					}
-				}
-			}
-			
-		}
-		return $new_record;
-	}
-	
-	/**
-	* SQL Statement für Record erzeugen.
-	*
-	* @param record = Datensatz als Array
-	* @param action = INSERT oder UPDATE
-	* @param primary_id
-	* @return record
-	*/
-	function getSQL($record, $action = 'INSERT', $primary_id = 0, $sql_ext_where = '') {
-		
-		global $app;
-		
-		$record = $this->encode($record);
-		$sql_insert_key = '';
-		$sql_insert_val = '';
-		$sql_update = '';
-		
-		if(!is_array($this->tableDef)) $app->error("Keine Tabellendefinition vorhanden.");
-		
-		// gehe durch alle Felder des Records
-		if(is_array($record)) {
-        foreach($record as $key => $val) {
-			// Wenn es kein leeres Passwortfeld ist
-			if (!($this->tableDef[$key]['formtype'] == 'PASSWORD' and $val == '')) {
-				// gehe durch alle Felder der TableDef
-				foreach($this->tableDef as $tk => $tv) {
-					// Wenn Feld in TableDef enthalten ist
-					if($tk == $key) {
-						// Erzeuge Insert oder Update Quelltext
-						if($action == "INSERT") {
-							
-							if($this->tableDef[$key]['formtype'] == 'PASSWORD') {
-								$sql_insert_key .= "`$key`, ";
-								$sql_insert_val .= "md5('$val'), ";
-							//} elseif($this->tableDef[$key]['formtype'] == 'MULTIPLE') {
-							//	$val = implode($this->tableDef[$key]['separator'],$val);
-							//	$sql_insert_key .= "`$key`, ";
-							//	$sql_insert_val .= "'$val', ";
-							} else {
-								$sql_insert_key .= "`$key`, ";
-								$sql_insert_val .= "'$val', ";
-							}
-							
-						} else {
-							
-							if($this->tableDef[$key]['formtype'] == 'PASSWORD') {
-								$sql_update .= "`$key` = md5('$val'), ";
-							//} elseif($this->tableDef[$key]['formtype'] == 'MULTIPLE') {
-							//	$val = implode($this->tableDef[$key]['separator'],$val);
-							//	$sql_update .= "`$key` = '$val', ";
-							} else {
-								$sql_update .= "`$key` = '$val', ";
-							}
-							
-						}
-					}
-				}
-			}
-		}
-        }
-		
-		// Füge Backticks nur bei unvollständigen Tabellennamen ein
-		if(stristr($this->table_name,'.')) {
-			$escape = '';
-		} else {
-			$escape = '`';
-		}
-		
-		
-		if($action == "INSERT") {
-			$sql_insert_key = substr($sql_insert_key,0,-2);
-			$sql_insert_val = substr($sql_insert_val,0,-2);
-			$sql = "INSERT INTO ".$escape.$this->table_name.$escape." ($sql_insert_key) VALUES ($sql_insert_val)";
-		} else {
-			if($primary_id != 0) {
-				$sql_update = substr($sql_update,0,-2);
-				$sql = "UPDATE ".$escape.$this->table_name.$escape." SET ".$sql_update." WHERE ".$this->table_index ." = ".$primary_id;
-				if($sql_ext_where != '') $sql .= " and ".$sql_ext_where;
-			} else {
-				$app->error("Primary ID fehlt!");
-			}
-		}
-		
-		return $sql;
-	}
-	
-	/**
-	* Debugging arrays.
-	*
-	* @param array_data
-	*/
-	function dbg($array_data) {
-		
-		echo "<pre>";
-		print_r($array_data);
-		echo "</pre>";
-		
-	}
-    
-    
-    function showForm() {
-    	global $app,$conf;
-        
-        if(!is_array($this->formDef)) die("Form Definition wurde nicht geladen.");
-        
-        if($this->errorMessage == '') {
-        	// wenn kein Fehler vorliegt
-			if($_REQUEST["next_tab"] != '') {
-            	// wenn nächster Tab bekannt
-            	$active_tab = $_REQUEST["next_tab"];
-            } else {
-            	// ansonsten ersten tab nehmen
-            	$active_tab = $this->formDef["tabs"][0]["name"];
-            }
-		} else {
-        	// bei Fehlern den gleichen Tab nochmal anzeigen
-            $active_tab = $_SESSION["s"]["form"]["tab"];
-		}
-        
-        // definiere Tabs
-        foreach( $this->formDef["tabs"] as $tab) {
-            
-            if($tab["name"] == $active_tab) {
-            	$app->tpl->setInclude('content_tpl',$tab["template"]);
-                $tab["active"] = 1;
-                $_SESSION["s"]["form"]["tab"] = $tab["name"];
-            } else {
-            	$tab["active"] = 0;
-            }
-			
-            $frmTab[] = $tab;
-        }
-        
-        // setze Loop
-        $app->tpl->setLoop("formTab", $frmTab);
-
-		// Formular action setzen
-		$app->tpl->setVar('form_action',$this->formDef["action"]);
-    }
-	
-	
-}
-
+<?php
+/*
+Copyright (c) 2005, Till Brehm, projektfarm Gmbh
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+    * Neither the name of ISPConfig nor the names of its contributors
+      may be used to endorse or promote products derived from this software without
+      specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/**
+* Formularbehandlung
+*
+* Funktionen zur Umwandlung von Formulardaten
+* sowie zum vorbereiten von HTML und SQL
+* Ausgaben
+*
+*	Tabellendefinition
+*	
+*	Datentypen:
+*	- INTEGER (Wandelt Ausdrücke in Int um)
+*	- DOUBLE
+*	- CURRENCY (Formatiert Zahlen nach Währungsnotation)
+*	- VARCHAR (kein weiterer Format Check)
+*	- DATE (Datumsformat, Timestamp Umwandlung)
+*	
+*	Formtype:
+*	- TEXT (normales Textfeld)
+*	- PASSWORD (Feldinhalt wird nicht angezeigt)
+*	- SELECT (Gibt Werte als option Feld aus)
+*	- MULTIPLE (Select-Feld mit nehreren Werten)
+*	
+*	VALUE:
+*	- Wert oder Array
+*	
+*	SEPARATOR
+*	- Trennzeichen für multiple Felder
+*
+*	Hinweis:
+*	Das ID-Feld ist nicht bei den Table Values einzufügen.
+*
+* @package form
+* @author Till Brehm
+* @version 1.1
+*/
+
+class form {
+	
+	/**
+	* Definition der Tabelle (array)
+	* @var tableDef
+	*/
+	var $tableDef;
+	
+	/**
+	* Private
+	* @var action
+	*/
+	var $action;
+	
+	/**
+	* Tabellenname (String)
+	* @var table_name
+	*/
+	var $table_name;
+	
+	/**
+	* Debug Variable
+	* @var debug
+	*/
+	var $debug = 0;
+	
+	/**
+	* name des primary Field der Tabelle (string)
+	* @var table_index
+	*/
+	var $table_index;
+	
+	/**
+	* enthält die Fehlermeldung bei Überprüfung
+	* der Variablen mit Regex
+	* @var errorMessage
+	*/
+	var $errorMessage;
+	
+	var $dateformat = "d.m.Y";
+    var $formDef;
+	
+	/**
+	* Laden der Tabellendefinition
+	*
+	* @param file: Pfad zur Tabellendefinition
+	* @return true
+	*/
+	function loadTableDef($file) {
+		global $app,$conf;
+		
+		include_once($file);
+		$this->tableDef = $table;
+		$this->table_name = $table_name;
+		$this->table_index = $table_index;
+		return true;
+	}
+    
+    function loadFormDef($file) {
+		global $app,$conf;
+		
+		include_once($file);
+		$this->formDef = $form;
+		return true;
+	}
+	
+	
+	/**
+	* Konvertiert die Daten des übergebenen assoziativen
+	* Arrays in "menschenlesbare" Form.
+	* Datentyp Konvertierung, z.B. für Ausgabe in Listen.
+	*
+	* @param record
+	* @return record
+	*/
+	function decode($record) {
+		if(is_array($record)) {
+			foreach($record as $key => $val) {
+				switch ($this->tableDef[$key]['datatype']) {
+				case 'VARCHAR':
+					$new_record[$key] = stripslashes($val);
+				break;
+				
+				case 'DATE':
+					if($val > 0) {
+						$new_record[$key] = date($this->dateformat,$val);
+					}
+				break;
+				
+				case 'INTEGER':
+					$new_record[$key] = intval($val);
+				break;
+				
+				case 'DOUBLE':
+					$new_record[$key] = $val;
+				break;
+				
+				case 'CURRENCY':
+					$new_record[$key] = number_format($val, 2, ',', '');
+				break;
+				
+				default:
+					$new_record[$key] = stripslashes($val);
+				}
+			}
+			
+		}
+	return $new_record;
+	}
+	
+	/**
+	* Record für Ausgabe in Formularen vorbereiten.
+	*
+	* @param record = Datensatz als Array
+	* @param action = NEW oder EDIT 
+	* @return record
+	*/
+	function getHTML($record,$action = 'NEW') {
+		
+		global $app;
+		
+		if(!is_array($this->tableDef)) $app->error("Keine Tabellendefinition vorhanden.");
+		
+		$new_record = array();
+		if($action == 'EDIT') {
+			$record = $this->decode($record);
+			if(is_array($record)) {
+				foreach($record as $key => $val) {
+					switch ($this->tableDef[$key]['formtype']) {
+					case 'SELECT':
+						if(is_array($this->tableDef[$key]['value'])) {
+							$out = '';
+							foreach($this->tableDef[$key]['value'] as $k => $v) {
+								$selected = ($k == $val)?' SELECTED':'';
+								$out .= "<option value='$k'$selected>$v</option>\r\n";
+							}
+						}
+						$new_record[$key] = $out;
+					break;
+					case 'MULTIPLE':
+						if(is_array($this->tableDef[$key]['value'])) {
+							
+							// aufsplitten ergebnisse
+							$vals = explode($this->tableDef[$key]['separator'],$val);
+							
+							// HTML schreiben
+							$out = '';
+							foreach($this->tableDef[$key]['value'] as $k => $v) {
+								
+								$selected = '';
+								foreach($vals as $tvl) {
+									if(trim($tvl) == trim($k)) $selected = ' SELECTED';
+								}
+								
+								$out .= "<option value='$k'$selected>$v</option>\r\n";
+							}
+						}
+						$new_record[$key] = $out;
+					break;
+					
+					case 'PASSWORD':
+						$new_record[$key] = '';
+					break;
+					
+					default:
+						$new_record[$key] = htmlspecialchars($val);
+					}
+				}
+			}
+		} else {
+			foreach($this->tableDef as $key => $val) {
+				switch ($this->tableDef[$key]['formtype']) {
+				case 'SELECT':
+					if(is_array($this->tableDef[$key]['value'])) {
+						$out = '';
+						foreach($this->tableDef[$key]['value'] as $k => $v) {
+							$selected = ($k == $val)?' SELECTED':'';
+							$out .= "<option value='$k'$selected>$v</option>\r\n";
+						}
+					}
+					$new_record[$key] = $out;
+				break;
+				case 'MULTIPLE':
+						if(is_array($this->tableDef[$key]['value'])) {
+							
+							// aufsplitten ergebnisse
+							$vals = explode($this->tableDef[$key]['separator'],$val);
+							
+							// HTML schreiben
+							$out = '';
+							foreach($this->tableDef[$key]['value'] as $k => $v) {
+								
+								$out .= "<option value='$k'>$v</option>\r\n";
+							}
+						}
+						$new_record[$key] = $out;
+					break;
+				
+				case 'PASSWORD':
+					$new_record[$key] = '';
+				break;
+				
+				default:
+					$new_record[$key] = htmlspecialchars($this->tableDef[$key]['value']);
+				}
+			}
+		
+		}
+		
+		if($this->debug == 1) $this->dbg($new_record);
+		
+		return $new_record;
+	}
+	
+	/**
+	* Record in "maschinen lesbares" Format überführen
+	* und Werte gegen reguläre Ausdrücke prüfen.
+	*
+	* @param record = Datensatz als Array
+	* @return record
+	*/
+	function encode($record) {
+		
+		$this->errorMessage = '';
+		
+		if(is_array($record)) {
+			foreach($record as $key => $val) {
+				switch ($this->tableDef[$key]['datatype']) {
+				case 'VARCHAR':
+					if(!is_array($val)) {
+						$new_record[$key] = mysql_real_escape_string($val);
+					} else {
+						$new_record[$key] = implode($this->tableDef[$key]['separator'],$val);
+					}
+				break;
+				case 'DATE':
+					if($val > 0) {
+						list($tag,$monat,$jahr) = explode('.',$val);
+						$new_record[$key] = mktime(0,0,0,$monat,$tag,$jahr);
+					}
+				break;
+				case 'INTEGER':
+					$new_record[$key] = intval($val);
+				break;
+				case 'DOUBLE':
+					$new_record[$key] = mysql_real_escape_string($val);
+				break;
+				case 'CURRENCY':
+					$new_record[$key] = str_replace(",",".",$val);
+				break;
+				}
+				
+				if($this->tableDef[$key]['regex'] != '') {
+					// Enable that "." matches also newlines
+					$this->tableDef[$key]['regex'] .= 's';
+					if(!preg_match($this->tableDef[$key]['regex'], $val)) {
+						$this->errorMessage .= $this->tableDef[$key]['errmsg']."<br>\r\n";
+					}
+				}
+			}
+			
+		}
+		return $new_record;
+	}
+	
+	/**
+	* SQL Statement für Record erzeugen.
+	*
+	* @param record = Datensatz als Array
+	* @param action = INSERT oder UPDATE
+	* @param primary_id
+	* @return record
+	*/
+	function getSQL($record, $action = 'INSERT', $primary_id = 0, $sql_ext_where = '') {
+		
+		global $app;
+		
+		$record = $this->encode($record);
+		$sql_insert_key = '';
+		$sql_insert_val = '';
+		$sql_update = '';
+		
+		if(!is_array($this->tableDef)) $app->error("Keine Tabellendefinition vorhanden.");
+		
+		// gehe durch alle Felder des Records
+		if(is_array($record)) {
+        foreach($record as $key => $val) {
+			// Wenn es kein leeres Passwortfeld ist
+			if (!($this->tableDef[$key]['formtype'] == 'PASSWORD' and $val == '')) {
+				// gehe durch alle Felder der TableDef
+				foreach($this->tableDef as $tk => $tv) {
+					// Wenn Feld in TableDef enthalten ist
+					if($tk == $key) {
+						// Erzeuge Insert oder Update Quelltext
+						if($action == "INSERT") {
+							
+							if($this->tableDef[$key]['formtype'] == 'PASSWORD') {
+								$sql_insert_key .= "`$key`, ";
+								$sql_insert_val .= "md5('$val'), ";
+							//} elseif($this->tableDef[$key]['formtype'] == 'MULTIPLE') {
+							//	$val = implode($this->tableDef[$key]['separator'],$val);
+							//	$sql_insert_key .= "`$key`, ";
+							//	$sql_insert_val .= "'$val', ";
+							} else {
+								$sql_insert_key .= "`$key`, ";
+								$sql_insert_val .= "'$val', ";
+							}
+							
+						} else {
+							
+							if($this->tableDef[$key]['formtype'] == 'PASSWORD') {
+								$sql_update .= "`$key` = md5('$val'), ";
+							//} elseif($this->tableDef[$key]['formtype'] == 'MULTIPLE') {
+							//	$val = implode($this->tableDef[$key]['separator'],$val);
+							//	$sql_update .= "`$key` = '$val', ";
+							} else {
+								$sql_update .= "`$key` = '$val', ";
+							}
+							
+						}
+					}
+				}
+			}
+		}
+        }
+		
+		// Füge Backticks nur bei unvollständigen Tabellennamen ein
+		if(stristr($this->table_name,'.')) {
+			$escape = '';
+		} else {
+			$escape = '`';
+		}
+		
+		
+		if($action == "INSERT") {
+			$sql_insert_key = substr($sql_insert_key,0,-2);
+			$sql_insert_val = substr($sql_insert_val,0,-2);
+			$sql = "INSERT INTO ".$escape.$this->table_name.$escape." ($sql_insert_key) VALUES ($sql_insert_val)";
+		} else {
+			if($primary_id != 0) {
+				$sql_update = substr($sql_update,0,-2);
+				$sql = "UPDATE ".$escape.$this->table_name.$escape." SET ".$sql_update." WHERE ".$this->table_index ." = ".$primary_id;
+				if($sql_ext_where != '') $sql .= " and ".$sql_ext_where;
+			} else {
+				$app->error("Primary ID fehlt!");
+			}
+		}
+		
+		return $sql;
+	}
+	
+	/**
+	* Debugging arrays.
+	*
+	* @param array_data
+	*/
+	function dbg($array_data) {
+		
+		echo "<pre>";
+		print_r($array_data);
+		echo "</pre>";
+		
+	}
+    
+    
+    function showForm() {
+    	global $app,$conf;
+        
+        if(!is_array($this->formDef)) die("Form Definition wurde nicht geladen.");
+        
+        if($this->errorMessage == '') {
+        	// wenn kein Fehler vorliegt
+			if($_REQUEST["next_tab"] != '') {
+            	// wenn nächster Tab bekannt
+            	$active_tab = $_REQUEST["next_tab"];
+            } else {
+            	// ansonsten ersten tab nehmen
+            	$active_tab = $this->formDef["tabs"][0]["name"];
+            }
+		} else {
+        	// bei Fehlern den gleichen Tab nochmal anzeigen
+            $active_tab = $_SESSION["s"]["form"]["tab"];
+		}
+        
+        // definiere Tabs
+        foreach( $this->formDef["tabs"] as $tab) {
+            
+            if($tab["name"] == $active_tab) {
+            	$app->tpl->setInclude('content_tpl',$tab["template"]);
+                $tab["active"] = 1;
+                $_SESSION["s"]["form"]["tab"] = $tab["name"];
+            } else {
+            	$tab["active"] = 0;
+            }
+			
+            $frmTab[] = $tab;
+        }
+        
+        // setze Loop
+        $app->tpl->setLoop("formTab", $frmTab);
+
+		// Formular action setzen
+		$app->tpl->setVar('form_action',$this->formDef["action"]);
+    }
+	
+	
+}
+
 ?>
\ No newline at end of file
diff --git a/interface/lib/classes/listform.inc.php b/interface/lib/classes/listform.inc.php
index ca3b97db91f999adbe3328a0c3fe1e47ce12845d..e1284bccfbcb57de68533b0766ed4efc579d9fc0 100644
--- a/interface/lib/classes/listform.inc.php
+++ b/interface/lib/classes/listform.inc.php
@@ -1,347 +1,347 @@
-<?php
-
-/*
-Copyright (c) 2007, Till Brehm, projektfarm Gmbh
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
-      and/or other materials provided with the distribution.
-    * Neither the name of ISPConfig nor the names of its contributors
-      may be used to endorse or promote products derived from this software without
-      specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/**
-* Listenbehandlung
-*
-* @package listform
-* @author Till Brehm
-* @version 1.1
-*/
-
-class listform {
-
-    private $debug = 0;
-    private $errorMessage;
-    public  $listDef;
-    public  $searchValues;
-    public  $pagingHTML;
-    private $pagingValues;
-    private $searchChanged = 0;
-    private $module;
-	private $dateformat = 'd.m.Y';
-
-    public function loadListDef($file, $module = '')
-    {
-        global $app,$conf;
-        if(!is_file($file)){
-            die("List-Definition: $file not found.");
-        }
-        require_once($file);
-        $this->listDef = $liste;
-        $this->module = $module;
-		
-		//* Fill datasources
-		foreach($this->listDef['item'] as $key => $field) {
-			if(@is_array($field['datasource'])) {
-                $this->listDef['item'][$key]['value'] = $this->getDatasourceData($field);
-            }
-		}
-        return true;
-    }
-		
-	/**
-    * Get the key => value array of a form filed from a datasource definitiom
-    *
-    * @param field = array with field definition
-    * @param record = Dataset as array
-    * @return array key => value array for the value field of a form
-    */
-    private function getDatasourceData($field)
-    {
-        global $app;
-        $values = array();
-
-        if($field['datasource']['type'] == 'SQL') {
-
-            //** Preparing SQL string. We will replace some common placeholders
-            $querystring = $field['datasource']['querystring'];
-            $querystring = str_replace('{USERID}', $_SESSION['s']['user']['userid'], $querystring);
-            $querystring = str_replace('{GROUPID}', $_SESSION['s']['user']['default_group'], $querystring);
-            $querystring = str_replace('{GROUPS}', $_SESSION['s']['user']['groups'], $querystring);
-            //TODO:
-            //$table_idx = $this->formDef['db_table_idx'];
-            //$querystring = str_replace("{RECORDID}",$record[$table_idx],$querystring);
-			$app->uses('tform');
-            $querystring = str_replace("{AUTHSQL}",$app->tform->getAuthSQL('r'),$querystring);
-
-            //* Getting the records
-            $tmp_records = $app->db->queryAllRecords($querystring);
-            if($app->db->errorMessage != '') die($app->db->errorMessage);
-            if(is_array($tmp_records)) {
-                $key_field = $field['datasource']['keyfield'];
-                $value_field = $field['datasource']['valuefield'];
-                foreach($tmp_records as $tmp_rec) {
-                    $tmp_id = $tmp_rec[$key_field];
-                    $values[$tmp_id] = $tmp_rec[$value_field];
-                }
-            }
-        }
-
-        if($field['datasource']['type'] == 'CUSTOM') {
-            //* Calls a custom class to validate this record
-            if($field['datasource']['class'] != '' and $field['datasource']['function'] != '') {
-                $datasource_class = $field['datasource']['class'];
-                $datasource_function = $field['datasource']['function'];
-                $app->uses($datasource_class);
-				$record = array();
-                $values = $app->$datasource_class->$datasource_function($field, $record);
-            } else {
-                $this->errorMessage .= "Custom datasource class or function is empty<br>\r\n";
-            }
-        }
-        return $values;
-    }
-
-    public function getSearchSQL($sql_where = '') 
-    {
-        global $db;
-
-        //* Get config variable
-        $list_name = $this->listDef['name'];
-        $search_prefix = $this->listDef['search_prefix'];
-
-        //* store retrieval query
-        foreach($this->listDef['item'] as $i) {
-            $field = $i['field'];
-
-            //*TODO: comment =  hat sich die suche ge�ndert
-            if(isset($_REQUEST[$search_prefix.$field]) && isset($_SESSION['search'][$list_name][$search_prefix.$field]) && $_REQUEST[$search_prefix.$field] != $_SESSION['search'][$list_name][$search_prefix.$field]){
-                    $this->searchChanged = 1;
-            }
-
-            //* Store field in session
-            if(isset($_REQUEST[$search_prefix.$field])){
-                $_SESSION['search'][$list_name][$search_prefix.$field] = $_REQUEST[$search_prefix.$field];
-            }
-
-            if(isset($i['formtype']) && $i['formtype'] == 'SELECT'){
-                if(is_array($i['value'])) {
-                    $out = '<option value=""></option>';
-                    foreach($i['value'] as $k => $v) {
-                        // TODO: this could be more elegant
-                        $selected = (isset($_SESSION['search'][$list_name][$search_prefix.$field]) 
-                                        && $k == $_SESSION['search'][$list_name][$search_prefix.$field] 
-                                        && $_SESSION['search'][$list_name][$search_prefix.$field] != '')
-                                        ? ' SELECTED' : '';
-                        $out .= "<option value='$k'$selected>$v</option>\r\n";
-                    }
-                }
-                    $this->searchValues[$search_prefix.$field] = $out;
-            } else {
-                if(isset($_SESSION['search'][$list_name][$search_prefix.$field])){
-                    $this->searchValues[$search_prefix.$field] = $_SESSION['search'][$list_name][$search_prefix.$field];
-                }
-            }
-        }
-
-        //* Store variables in object | $this->searchValues = $_SESSION["search"][$list_name];
-        foreach($this->listDef['item'] as $i) {
-            $field = $i['field'];
-            // if($_REQUEST[$search_prefix.$field] != '') $sql_where .= " $field ".$i["op"]." '".$i["prefix"].$_REQUEST[$search_prefix.$field].$i["suffix"]."' and";
-		    if(isset($_SESSION['search'][$list_name][$search_prefix.$field]) && $_SESSION['search'][$list_name][$search_prefix.$field] != ''){
-                $sql_where .= " $field ".$i['op']." '".$i['prefix'].$_SESSION['search'][$list_name][$search_prefix.$field].$i['suffix']."' and";
-            }
-        }
-
-        return ( $sql_where != '' ) ? $sql_where = substr($sql_where,0,-3) : '1';
-    }
-
-    public function getPagingSQL($sql_where = '1') 
-    {
-        global $app, $conf;
-
-        //* Get Config variables
-        $list_name          = $this->listDef['name'];
-        $search_prefix      = $this->listDef['search_prefix'];
-        $records_per_page   = $this->listDef['records_per_page'];
-        $table              = $this->listDef['table'];
-
-        //* set PAGE to zero, if in session not set
-        if(!isset($_SESSION['search'][$list_name]['page']) || $_SESSION['search'][$list_name]['page'] == ''){
-            $_SESSION['search'][$list_name]['page'] = 0;
-        }
-
-        //* set PAGE to worth request variable "PAGE" - ? setze page auf wert der request variablen "page"
-        if(isset($_REQUEST["page"])) $_SESSION["search"][$list_name]["page"] = $_REQUEST["page"];
-
-        //* PAGE to 0 set, if look for themselves ?  page auf 0 setzen, wenn suche sich ge�ndert hat.
-        if($this->searchChanged == 1) $_SESSION['search'][$list_name]['page'] = 0;
-
-        $sql_von = $_SESSION['search'][$list_name]['page'] * $records_per_page;
-        $record_count = $app->db->queryOneRecord("SELECT count(*) AS anzahl FROM $table WHERE $sql_where");
-        $pages = intval(($record_count['anzahl'] - 1) / $records_per_page);
-
-
-        $vars['list_file']      = $_SESSION['s']['module']['name'].'/'.$this->listDef['file'];
-        $vars['page']           = $_SESSION['search'][$list_name]['page'];
-        $vars['last_page']      = $_SESSION['search'][$list_name]['page'] - 1;
-        $vars['next_page']      = $_SESSION['search'][$list_name]['page'] + 1;
-        $vars['pages']          = $pages;
-        $vars['max_pages']      = $pages + 1;
-        $vars['records_gesamt'] = $record_count['anzahl'];
-        $vars['page_params']    = (isset($this->listDef['page_params'])) ? $this->listDef['page_params'] : '';
-        //$vars['module'] = $_SESSION['s']['module']['name'];
-
-        if($_SESSION['search'][$list_name]['page'] > 0) $vars['show_page_back'] = 1;
-        if($_SESSION['search'][$list_name]['page'] <= $vars['pages'] - 1) $vars['show_page_next'] = 1;
-
-        $this->pagingValues = $vars;
-        $this->pagingHTML = $this->getPagingHTML($vars);
-
-        //* Return limit sql
-        return "LIMIT $sql_von, $records_per_page";
-    }
-
-    public function getPagingHTML($vars)
-    {
-        global $app;
-        $content = '<a href="'."javascript:loadContent('".$vars['list_file'].'?page=0'.$vars['page_params']."');".'">'
-                    .'<img src="themes/'.$_SESSION['s']['theme'].'/images/btn_left.png" border="0"></a> &nbsp; ';
-        //* Show Back 
-        if(isset($vars['show_page_back']) && $vars['show_page_back'] == 1){
-            $content .= '<a href="'."javascript:loadContent('".$vars['list_file'].'?page='.$vars['last_page'].$vars['page_params']."');".'">'
-                        .'<img src="themes/'.$_SESSION['s']['theme'].'/images/btn_back.png" border="0"></a> ';
-        }
-        $content .= ' '.$app->lng('Page').' '.$vars['next_page'].' '.$app->lng('of').' '.$vars['max_pages'].' ';
-        //* Show Next
-        if(isset($vars['show_page_next']) && $vars['show_page_next'] == 1){
-            $content .= '<a href="'."javascript:loadContent('".$vars['list_file'].'?page='.$vars['next_page'].$vars['page_params']."');".'">'
-                        .'<img src="themes/'.$_SESSION['s']['theme'].'/images/btn_next.png" border="0"></a> &nbsp; ';
-        }
-        $content .= '<a href="'."javascript:loadContent('".$vars['list_file'].'?page='.$vars['pages'].$vars['page_params']."');".'">'
-                    .'<img src="themes/'.$_SESSION['s']['theme'].'/images/btn_right.png" border="0"></a>';
-        return $content;
-    }
-		
-	public function getPagingHTMLasTXT($vars)
-    {
-        global $app;
-        $content = '[<a href="'.$vars['list_file'].'?page=0'.$vars['page_params'].'">|&lt;&lt; </a>]';
-        if($vars['show_page_back'] == 1){
-            $content .= '[<< <a href="'.$vars['list_file'].'?page='.$vars['last_page'].$vars['page_params'].'">'.$app->lng('Back').'</a>] ';
-        }
-        $content .= ' '.$app->lng('Page').' '.$vars['next_page'].' '.$app->lng('of').' '.$vars['max_pages'].' ';
-        if($vars['show_page_next'] == 1){
-            $content .= '[<a href="'.$vars['list_file'].'?page='.$vars['next_page'].$vars['page_params'].'">'.$app->lng('Next').' >></a>] ';
-        }
-        $content .= '[<a href="'.$vars['list_file'].'?page='.$vars['pages'].$vars['page_params'].'"> &gt;&gt;|</a>]';
-        return $content;
-    }
-
-    public function getSortSQL()
-    {
-        global $app, $conf;
-        //* Get config vars
-        $sort_field = $this->listDef['sort_field'];
-        $sort_direction = $this->listDef['sort_direction'];
-        return ($sort_field != '' && $sort_direction != '') ? "ORDER BY $sort_field $sort_direction" : '';
-    }
-
-    public function decode($record) 
-    {
-        if(is_array($record)) {
-            foreach($this->listDef['item'] as $field){
-                $key = $field['field'];
-				if(isset($record[$key])) {
-                	switch ($field['datatype']){
-                    case 'VARCHAR':
-                    case 'TEXT':
-                        $record[$key] = stripslashes($record[$key]);
-                         break;
-
-                    case 'DATE':
-                        $record[$key] = ($record[$key] > 0) ? date($this->dateformat,$record[$key]) : '';
-                        break;
-
-                    case 'INTEGER':
-                        $record[$key] = intval($record[$key]);
-                        break;
-
-                    case 'DOUBLE':
-                        $record[$key] = $record[$key];
-                        break;
-
-                    case 'CURRENCY':
-                        $record[$key] = number_format($record[$key], 2, ',', '');
-                        break;
-
-                    default:
-                        $record[$key] = stripslashes($record[$key]);
-                	}
-				}
-            }
-        }
-        return $record;
-    }
-
-    public function encode($record)
-    {
-        if(is_array($record)) {
-            foreach($this->listDef['item'] as $field){
-                $key = $field['field'];
-                switch($field['datatype']){
-
-                    case 'VARCHAR':
-                    case 'TEXT':
-                        if(!is_array($record[$key])) {
-                            $record[$key] = mysql_real_escape_string($record[$key]);
-                        } else {
-                            $record[$key] = implode($this->tableDef[$key]['separator'],$record[$key]);
-                        }
-                        break;
-                    
-                    case 'DATE':
-                        if($record[$key] > 0) {
-                            list($tag,$monat,$jahr) = explode('.',$record[$key]);
-                            $record[$key] = mktime(0,0,0,$monat,$tag,$jahr);
-                        }
-                        break;
-
-                    case 'INTEGER':
-                        $record[$key] = intval($record[$key]);
-                        break;
-
-                    case 'DOUBLE':
-                        $record[$key] = mysql_real_escape_string($record[$key]);
-                        break;
-
-                    case 'CURRENCY':
-                        $record[$key] = str_replace(',', '.', $record[$key]);
-                        break;
-                }
-            }
-        }
-        return $record;
-    }
-
-}
-
+<?php
+
+/*
+Copyright (c) 2007, Till Brehm, projektfarm Gmbh
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+    * Neither the name of ISPConfig nor the names of its contributors
+      may be used to endorse or promote products derived from this software without
+      specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/**
+* Listenbehandlung
+*
+* @package listform
+* @author Till Brehm
+* @version 1.1
+*/
+
+class listform {
+
+    private $debug = 0;
+    private $errorMessage;
+    public  $listDef;
+    public  $searchValues;
+    public  $pagingHTML;
+    private $pagingValues;
+    private $searchChanged = 0;
+    private $module;
+	private $dateformat = 'd.m.Y';
+
+    public function loadListDef($file, $module = '')
+    {
+        global $app,$conf;
+        if(!is_file($file)){
+            die("List-Definition: $file not found.");
+        }
+        require_once($file);
+        $this->listDef = $liste;
+        $this->module = $module;
+		
+		//* Fill datasources
+		foreach($this->listDef['item'] as $key => $field) {
+			if(@is_array($field['datasource'])) {
+                $this->listDef['item'][$key]['value'] = $this->getDatasourceData($field);
+            }
+		}
+        return true;
+    }
+		
+	/**
+    * Get the key => value array of a form filed from a datasource definitiom
+    *
+    * @param field = array with field definition
+    * @param record = Dataset as array
+    * @return array key => value array for the value field of a form
+    */
+    private function getDatasourceData($field)
+    {
+        global $app;
+        $values = array();
+
+        if($field['datasource']['type'] == 'SQL') {
+
+            //** Preparing SQL string. We will replace some common placeholders
+            $querystring = $field['datasource']['querystring'];
+            $querystring = str_replace('{USERID}', $_SESSION['s']['user']['userid'], $querystring);
+            $querystring = str_replace('{GROUPID}', $_SESSION['s']['user']['default_group'], $querystring);
+            $querystring = str_replace('{GROUPS}', $_SESSION['s']['user']['groups'], $querystring);
+            //TODO:
+            //$table_idx = $this->formDef['db_table_idx'];
+            //$querystring = str_replace("{RECORDID}",$record[$table_idx],$querystring);
+			$app->uses('tform');
+            $querystring = str_replace("{AUTHSQL}",$app->tform->getAuthSQL('r'),$querystring);
+
+            //* Getting the records
+            $tmp_records = $app->db->queryAllRecords($querystring);
+            if($app->db->errorMessage != '') die($app->db->errorMessage);
+            if(is_array($tmp_records)) {
+                $key_field = $field['datasource']['keyfield'];
+                $value_field = $field['datasource']['valuefield'];
+                foreach($tmp_records as $tmp_rec) {
+                    $tmp_id = $tmp_rec[$key_field];
+                    $values[$tmp_id] = $tmp_rec[$value_field];
+                }
+            }
+        }
+
+        if($field['datasource']['type'] == 'CUSTOM') {
+            //* Calls a custom class to validate this record
+            if($field['datasource']['class'] != '' and $field['datasource']['function'] != '') {
+                $datasource_class = $field['datasource']['class'];
+                $datasource_function = $field['datasource']['function'];
+                $app->uses($datasource_class);
+				$record = array();
+                $values = $app->$datasource_class->$datasource_function($field, $record);
+            } else {
+                $this->errorMessage .= "Custom datasource class or function is empty<br>\r\n";
+            }
+        }
+        return $values;
+    }
+
+    public function getSearchSQL($sql_where = '') 
+    {
+        global $db;
+
+        //* Get config variable
+        $list_name = $this->listDef['name'];
+        $search_prefix = $this->listDef['search_prefix'];
+
+        //* store retrieval query
+        foreach($this->listDef['item'] as $i) {
+            $field = $i['field'];
+
+            //*TODO: comment =  hat sich die suche ge�ndert
+            if(isset($_REQUEST[$search_prefix.$field]) && isset($_SESSION['search'][$list_name][$search_prefix.$field]) && $_REQUEST[$search_prefix.$field] != $_SESSION['search'][$list_name][$search_prefix.$field]){
+                    $this->searchChanged = 1;
+            }
+
+            //* Store field in session
+            if(isset($_REQUEST[$search_prefix.$field])){
+                $_SESSION['search'][$list_name][$search_prefix.$field] = $_REQUEST[$search_prefix.$field];
+            }
+
+            if(isset($i['formtype']) && $i['formtype'] == 'SELECT'){
+                if(is_array($i['value'])) {
+                    $out = '<option value=""></option>';
+                    foreach($i['value'] as $k => $v) {
+                        // TODO: this could be more elegant
+                        $selected = (isset($_SESSION['search'][$list_name][$search_prefix.$field]) 
+                                        && $k == $_SESSION['search'][$list_name][$search_prefix.$field] 
+                                        && $_SESSION['search'][$list_name][$search_prefix.$field] != '')
+                                        ? ' SELECTED' : '';
+                        $out .= "<option value='$k'$selected>$v</option>\r\n";
+                    }
+                }
+                    $this->searchValues[$search_prefix.$field] = $out;
+            } else {
+                if(isset($_SESSION['search'][$list_name][$search_prefix.$field])){
+                    $this->searchValues[$search_prefix.$field] = $_SESSION['search'][$list_name][$search_prefix.$field];
+                }
+            }
+        }
+
+        //* Store variables in object | $this->searchValues = $_SESSION["search"][$list_name];
+        foreach($this->listDef['item'] as $i) {
+            $field = $i['field'];
+            // if($_REQUEST[$search_prefix.$field] != '') $sql_where .= " $field ".$i["op"]." '".$i["prefix"].$_REQUEST[$search_prefix.$field].$i["suffix"]."' and";
+		    if(isset($_SESSION['search'][$list_name][$search_prefix.$field]) && $_SESSION['search'][$list_name][$search_prefix.$field] != ''){
+                $sql_where .= " $field ".$i['op']." '".$i['prefix'].$_SESSION['search'][$list_name][$search_prefix.$field].$i['suffix']."' and";
+            }
+        }
+
+        return ( $sql_where != '' ) ? $sql_where = substr($sql_where,0,-3) : '1';
+    }
+
+    public function getPagingSQL($sql_where = '1') 
+    {
+        global $app, $conf;
+
+        //* Get Config variables
+        $list_name          = $this->listDef['name'];
+        $search_prefix      = $this->listDef['search_prefix'];
+        $records_per_page   = $this->listDef['records_per_page'];
+        $table              = $this->listDef['table'];
+
+        //* set PAGE to zero, if in session not set
+        if(!isset($_SESSION['search'][$list_name]['page']) || $_SESSION['search'][$list_name]['page'] == ''){
+            $_SESSION['search'][$list_name]['page'] = 0;
+        }
+
+        //* set PAGE to worth request variable "PAGE" - ? setze page auf wert der request variablen "page"
+        if(isset($_REQUEST["page"])) $_SESSION["search"][$list_name]["page"] = $_REQUEST["page"];
+
+        //* PAGE to 0 set, if look for themselves ?  page auf 0 setzen, wenn suche sich ge�ndert hat.
+        if($this->searchChanged == 1) $_SESSION['search'][$list_name]['page'] = 0;
+
+        $sql_von = $_SESSION['search'][$list_name]['page'] * $records_per_page;
+        $record_count = $app->db->queryOneRecord("SELECT count(*) AS anzahl FROM $table WHERE $sql_where");
+        $pages = intval(($record_count['anzahl'] - 1) / $records_per_page);
+
+
+        $vars['list_file']      = $_SESSION['s']['module']['name'].'/'.$this->listDef['file'];
+        $vars['page']           = $_SESSION['search'][$list_name]['page'];
+        $vars['last_page']      = $_SESSION['search'][$list_name]['page'] - 1;
+        $vars['next_page']      = $_SESSION['search'][$list_name]['page'] + 1;
+        $vars['pages']          = $pages;
+        $vars['max_pages']      = $pages + 1;
+        $vars['records_gesamt'] = $record_count['anzahl'];
+        $vars['page_params']    = (isset($this->listDef['page_params'])) ? $this->listDef['page_params'] : '';
+        //$vars['module'] = $_SESSION['s']['module']['name'];
+
+        if($_SESSION['search'][$list_name]['page'] > 0) $vars['show_page_back'] = 1;
+        if($_SESSION['search'][$list_name]['page'] <= $vars['pages'] - 1) $vars['show_page_next'] = 1;
+
+        $this->pagingValues = $vars;
+        $this->pagingHTML = $this->getPagingHTML($vars);
+
+        //* Return limit sql
+        return "LIMIT $sql_von, $records_per_page";
+    }
+
+    public function getPagingHTML($vars)
+    {
+        global $app;
+        $content = '<a href="'."javascript:loadContent('".$vars['list_file'].'?page=0'.$vars['page_params']."');".'">'
+                    .'<img src="themes/'.$_SESSION['s']['theme'].'/icons/x16/arrow_stop_180.png"></a> &nbsp; ';
+        //* Show Back 
+        if(isset($vars['show_page_back']) && $vars['show_page_back'] == 1){
+            $content .= '<a href="'."javascript:loadContent('".$vars['list_file'].'?page='.$vars['last_page'].$vars['page_params']."');".'">'
+                        .'<img src="themes/'.$_SESSION['s']['theme'].'/icons/x16/arrow_180.png"></a> ';
+        }
+        $content .= ' '.$app->lng('Page').' '.$vars['next_page'].' '.$app->lng('of').' '.$vars['max_pages'].' ';
+        //* Show Next
+        if(isset($vars['show_page_next']) && $vars['show_page_next'] == 1){
+            $content .= '<a href="'."javascript:loadContent('".$vars['list_file'].'?page='.$vars['next_page'].$vars['page_params']."');".'">'
+                        .'<img src="themes/'.$_SESSION['s']['theme'].'/icons/x16/arrow.png"></a> &nbsp; ';
+        }
+        $content .= '<a href="'."javascript:loadContent('".$vars['list_file'].'?page='.$vars['pages'].$vars['page_params']."');".'">'
+                    .'<img src="themes/'.$_SESSION['s']['theme'].'/icons/x16/arrow_stop.png"></a>';
+        return $content;
+    }
+		
+	public function getPagingHTMLasTXT($vars)
+    {
+        global $app;
+        $content = '[<a href="'.$vars['list_file'].'?page=0'.$vars['page_params'].'">|&lt;&lt; </a>]';
+        if($vars['show_page_back'] == 1){
+            $content .= '[<< <a href="'.$vars['list_file'].'?page='.$vars['last_page'].$vars['page_params'].'">'.$app->lng('Back').'</a>] ';
+        }
+        $content .= ' '.$app->lng('Page').' '.$vars['next_page'].' '.$app->lng('of').' '.$vars['max_pages'].' ';
+        if($vars['show_page_next'] == 1){
+            $content .= '[<a href="'.$vars['list_file'].'?page='.$vars['next_page'].$vars['page_params'].'">'.$app->lng('Next').' >></a>] ';
+        }
+        $content .= '[<a href="'.$vars['list_file'].'?page='.$vars['pages'].$vars['page_params'].'"> &gt;&gt;|</a>]';
+        return $content;
+    }
+
+    public function getSortSQL()
+    {
+        global $app, $conf;
+        //* Get config vars
+        $sort_field = $this->listDef['sort_field'];
+        $sort_direction = $this->listDef['sort_direction'];
+        return ($sort_field != '' && $sort_direction != '') ? "ORDER BY $sort_field $sort_direction" : '';
+    }
+
+    public function decode($record) 
+    {
+        if(is_array($record)) {
+            foreach($this->listDef['item'] as $field){
+                $key = $field['field'];
+				if(isset($record[$key])) {
+                	switch ($field['datatype']){
+                    case 'VARCHAR':
+                    case 'TEXT':
+                        $record[$key] = stripslashes($record[$key]);
+                         break;
+
+                    case 'DATE':
+                        $record[$key] = ($record[$key] > 0) ? date($this->dateformat,$record[$key]) : '';
+                        break;
+
+                    case 'INTEGER':
+                        $record[$key] = intval($record[$key]);
+                        break;
+
+                    case 'DOUBLE':
+                        $record[$key] = $record[$key];
+                        break;
+
+                    case 'CURRENCY':
+                        $record[$key] = number_format($record[$key], 2, ',', '');
+                        break;
+
+                    default:
+                        $record[$key] = stripslashes($record[$key]);
+                	}
+				}
+            }
+        }
+        return $record;
+    }
+
+    public function encode($record)
+    {
+        if(is_array($record)) {
+            foreach($this->listDef['item'] as $field){
+                $key = $field['field'];
+                switch($field['datatype']){
+
+                    case 'VARCHAR':
+                    case 'TEXT':
+                        if(!is_array($record[$key])) {
+                            $record[$key] = mysql_real_escape_string($record[$key]);
+                        } else {
+                            $record[$key] = implode($this->tableDef[$key]['separator'],$record[$key]);
+                        }
+                        break;
+                    
+                    case 'DATE':
+                        if($record[$key] > 0) {
+                            list($tag,$monat,$jahr) = explode('.',$record[$key]);
+                            $record[$key] = mktime(0,0,0,$monat,$tag,$jahr);
+                        }
+                        break;
+
+                    case 'INTEGER':
+                        $record[$key] = intval($record[$key]);
+                        break;
+
+                    case 'DOUBLE':
+                        $record[$key] = mysql_real_escape_string($record[$key]);
+                        break;
+
+                    case 'CURRENCY':
+                        $record[$key] = str_replace(',', '.', $record[$key]);
+                        break;
+                }
+            }
+        }
+        return $record;
+    }
+
+}
+
 ?>
\ No newline at end of file
diff --git a/interface/lib/classes/listform_actions.inc.php b/interface/lib/classes/listform_actions.inc.php
index 4a198f5216a513989baef4ee132d81225b616f0f..04bdebba6364d52dc6ab8aa240af95518366f2dd 100644
--- a/interface/lib/classes/listform_actions.inc.php
+++ b/interface/lib/classes/listform_actions.inc.php
@@ -1,169 +1,169 @@
-<?php
-
-/*
-Copyright (c) 2005, Till Brehm, projektfarm Gmbh
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
-      and/or other materials provided with the distribution.
-    * Neither the name of ISPConfig nor the names of its contributors
-      may be used to endorse or promote products derived from this software without
-      specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/**
-* Action framework for the listform library.
-*
-* @author Till Brehm <t.brehm@scrigo.org>
-* @copyright Copyright &copy; 2005, Till Brehm
-*/
-
-class listform_actions {
-	
-	private $id;
-	public $idx_key;
-	public $DataRowColor;
-	public  $SQLExtWhere = '';
-	public  $SQLOrderBy = '';
-	
-	public function onLoad()
-    {
-		global $app, $conf, $list_def_file;
-		
-		$app->uses('tpl,listform,tform');
-		
-		//* Clear session variable that is used when lists are embedded with the listview plugin
-		$_SESSION['s']['form']['return_to'] = '';
-		
-		// Load list definition
-		$app->listform->loadListDef($list_def_file);
-		
-		if(!is_file('templates/'.$app->listform->listDef["name"].'_list.htm')) {
-			$app->uses('listform_tpl_generator');
-			$app->listform_tpl_generator->buildHTML($app->listform->listDef);
-		}
-		
-		$app->tpl->newTemplate("listpage.tpl.htm");
-		$app->tpl->setInclude('content_tpl','templates/'.$app->listform->listDef["name"].'_list.htm');
-
-		// Getting Datasets from DB
-		$records = $app->db->queryAllRecords($this->getQueryString());
-
-		$this->DataRowColor = "#FFFFFF";
-		$records_new = '';
-		if(is_array($records)) {
-			$this->idx_key = $app->listform->listDef["table_idx"]; 
-			foreach($records as $rec) {
-				$records_new[] = $this->prepareDataRow($rec);
-			}
-		}
-
-		$app->tpl->setLoop('records',$records_new);
-
-		$this->onShow();
-		
-		
-	}
-	
-	public function prepareDataRow($rec)
-    {
-		global $app;
-		
-		$rec = $app->listform->decode($rec);
-
-		//* Alternating datarow colors
-		$this->DataRowColor = ($this->DataRowColor == '#FFFFFF') ? '#EEEEEE' : '#FFFFFF';
-		$rec['bgcolor'] = $this->DataRowColor;
-		
-		//* substitute value for select fields
-		foreach($app->listform->listDef['item'] as $field) {
-			$key = $field['field'];
-			if(isset($field['formtype']) && $field['formtype'] == 'SELECT') {
-				if(strtolower($rec[$key]) == 'y' or strtolower($rec[$key]) == 'n') {
-					// Set a additional image variable for bolean fields
-					$rec['_'.$key.'_'] = (strtolower($rec[$key]) == 'y')?'list_icon_true.png':'list_icon_false.png';
-				}
-				//* substitute value for select field
-				$rec[$key] = @$field['value'][$rec[$key]];
-			}
-		}
-		
-		//* The variable "id" contains always the index variable
-		$rec['id'] = $rec[$this->idx_key];
-		return $rec;
-	}
-	
-	private function getQueryString() {
-		global $app;
-		$sql_where = '';
-
-		//* Generate the search sql
-		if($app->listform->listDef['auth'] != 'no') {
-			if($_SESSION['s']['user']['typ'] == "admin") {
-				$sql_where = '';
-			} else {
-				$sql_where = $app->tform->getAuthSQL('r').' and';
-			}
-		}		
-		if($this->SQLExtWhere != '') {
-			$sql_where .= ' '.$this->SQLExtWhere.' and';
-		}
-
-		$sql_where = $app->listform->getSearchSQL($sql_where);
-		$app->tpl->setVar($app->listform->searchValues);
-		
-		$order_by_sql = $this->SQLOrderBy;
-
-		//* Generate SQL for paging
-		$limit_sql = $app->listform->getPagingSQL($sql_where);
-		$app->tpl->setVar('paging',$app->listform->pagingHTML);
-
-		return 'SELECT * FROM '.$app->listform->listDef['table']." WHERE $sql_where $order_by_sql $limit_sql";
-	}
-	
-	
-	private function onShow()
-    {
-		global $app;
-		
-		//* Set global Language File
-		$lng_file = ISPC_LIB_PATH.'/lang/'.$_SESSION['s']['language'].'.lng';
-		include($lng_file);
-		$app->tpl->setVar($wb);
-		
-		//* Set local Language File
-		$lng_file = 'lib/lang/'.$_SESSION['s']['language'].'_'.$app->listform->listDef['name'].'_list.lng';
-		include($lng_file);
-		$app->tpl->setVar($wb);
-		$app->tpl->setVar('form_action', $app->listform->listDef['file']);
-		
-		//* Parse the templates and send output to the browser
-		$this->onShowEnd();
-	}
-	
-	private function onShowEnd()
-    {
-		global $app;
-		$app->tpl_defaults();
-		$app->tpl->pparse();
-	}
-}
-
+<?php
+
+/*
+Copyright (c) 2005, Till Brehm, projektfarm Gmbh
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+    * Neither the name of ISPConfig nor the names of its contributors
+      may be used to endorse or promote products derived from this software without
+      specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/**
+* Action framework for the listform library.
+*
+* @author Till Brehm <t.brehm@scrigo.org>
+* @copyright Copyright &copy; 2005, Till Brehm
+*/
+
+class listform_actions {
+	
+	private $id;
+	public $idx_key;
+	public $DataRowColor;
+	public  $SQLExtWhere = '';
+	public  $SQLOrderBy = '';
+	
+	public function onLoad()
+    {
+		global $app, $conf, $list_def_file;
+		
+		$app->uses('tpl,listform,tform');
+		
+		//* Clear session variable that is used when lists are embedded with the listview plugin
+		$_SESSION['s']['form']['return_to'] = '';
+		
+		// Load list definition
+		$app->listform->loadListDef($list_def_file);
+		
+		if(!is_file('templates/'.$app->listform->listDef["name"].'_list.htm')) {
+			$app->uses('listform_tpl_generator');
+			$app->listform_tpl_generator->buildHTML($app->listform->listDef);
+		}
+		
+		$app->tpl->newTemplate("listpage.tpl.htm");
+		$app->tpl->setInclude('content_tpl','templates/'.$app->listform->listDef["name"].'_list.htm');
+
+		// Getting Datasets from DB
+		$records = $app->db->queryAllRecords($this->getQueryString());
+
+		$this->DataRowColor = "#FFFFFF";
+		$records_new = '';
+		if(is_array($records)) {
+			$this->idx_key = $app->listform->listDef["table_idx"]; 
+			foreach($records as $rec) {
+				$records_new[] = $this->prepareDataRow($rec);
+			}
+		}
+
+		$app->tpl->setLoop('records',$records_new);
+
+		$this->onShow();
+		
+		
+	}
+	
+	public function prepareDataRow($rec)
+    {
+		global $app;
+		
+		$rec = $app->listform->decode($rec);
+
+		//* Alternating datarow colors
+		$this->DataRowColor = ($this->DataRowColor == '#FFFFFF') ? '#EEEEEE' : '#FFFFFF';
+		$rec['bgcolor'] = $this->DataRowColor;
+		
+		//* substitute value for select fields
+		foreach($app->listform->listDef['item'] as $field) {
+			$key = $field['field'];
+			if(isset($field['formtype']) && $field['formtype'] == 'SELECT') {
+				if(strtolower($rec[$key]) == 'y' or strtolower($rec[$key]) == 'n') {
+					// Set a additional image variable for bolean fields
+					$rec['_'.$key.'_'] = (strtolower($rec[$key]) == 'y')?'x16/tick_circle.png':'x16/cross_circle.png';
+				}
+				//* substitute value for select field
+				$rec[$key] = @$field['value'][$rec[$key]];
+			}
+		}
+		
+		//* The variable "id" contains always the index variable
+		$rec['id'] = $rec[$this->idx_key];
+		return $rec;
+	}
+	
+	private function getQueryString() {
+		global $app;
+		$sql_where = '';
+
+		//* Generate the search sql
+		if($app->listform->listDef['auth'] != 'no') {
+			if($_SESSION['s']['user']['typ'] == "admin") {
+				$sql_where = '';
+			} else {
+				$sql_where = $app->tform->getAuthSQL('r').' and';
+			}
+		}		
+		if($this->SQLExtWhere != '') {
+			$sql_where .= ' '.$this->SQLExtWhere.' and';
+		}
+
+		$sql_where = $app->listform->getSearchSQL($sql_where);
+		$app->tpl->setVar($app->listform->searchValues);
+		
+		$order_by_sql = $this->SQLOrderBy;
+
+		//* Generate SQL for paging
+		$limit_sql = $app->listform->getPagingSQL($sql_where);
+		$app->tpl->setVar('paging',$app->listform->pagingHTML);
+
+		return 'SELECT * FROM '.$app->listform->listDef['table']." WHERE $sql_where $order_by_sql $limit_sql";
+	}
+	
+	
+	private function onShow()
+    {
+		global $app;
+		
+		//* Set global Language File
+		$lng_file = ISPC_LIB_PATH.'/lang/'.$_SESSION['s']['language'].'.lng';
+		include($lng_file);
+		$app->tpl->setVar($wb);
+		
+		//* Set local Language File
+		$lng_file = 'lib/lang/'.$_SESSION['s']['language'].'_'.$app->listform->listDef['name'].'_list.lng';
+		include($lng_file);
+		$app->tpl->setVar($wb);
+		$app->tpl->setVar('form_action', $app->listform->listDef['file']);
+		
+		//* Parse the templates and send output to the browser
+		$this->onShowEnd();
+	}
+	
+	private function onShowEnd()
+    {
+		global $app;
+		$app->tpl_defaults();
+		$app->tpl->pparse();
+	}
+}
+
 ?>
\ No newline at end of file
diff --git a/interface/lib/classes/listform_tpl_generator.inc.php b/interface/lib/classes/listform_tpl_generator.inc.php
index 4c9c263bae5ef7e7e99d19b65aa9c49a6568a9cd..36d026ed6200c0be3b7f0be7969dfcd92aa6e8d4 100644
--- a/interface/lib/classes/listform_tpl_generator.inc.php
+++ b/interface/lib/classes/listform_tpl_generator.inc.php
@@ -1,151 +1,179 @@
-<?php
-
-/*
-Copyright (c) 2005, Till Brehm, projektfarm Gmbh
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
-      and/or other materials provided with the distribution.
-    * Neither the name of ISPConfig nor the names of its contributors
-      may be used to endorse or promote products derived from this software without
-      specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-
-class listform_tpl_generator {
-	
-	function buildHTML($listDef,$module = '') {
-		
-		global $app;
-		
-		if($module == '') $module = $_SESSION["s"]["module"]["name"];
-		
-		$lang = array();
-		$html = '<div class="frmTextHead"><tmpl_var name="list_head_txt"></div><br />
-<input type="button" value="{tmpl_var name="add_new_record_txt"}" class="button" onClick="'."loadContent('".$module."/".$listDef["edit_file"]."');".'" /><div class="buttonEnding"></div><br /><br />
-<table width="100%" border="0" cellspacing="0" cellpadding="4" class="listTable">
-  <tr>
-';
-		
-		$lang["list_head_txt"] = $listDef["name"];
-		foreach($listDef["item"] as $field) {
-			$key = $field["field"];
-			$html .= "    <td class=\"tblHead\"><tmpl_var name=\"".$key."_txt\"></td>\r\n";
-			$lang[$key."_txt"] = $key;
-		}
-		
-		$html .= '    <td class="tblHead">&nbsp;</td>
-  </tr>
-  <tr>
-';
-  
-  		foreach($listDef["item"] as $field) {
-			$key = $field["field"];
-			if($field["formtype"] == 'SELECT') {
-				$html .= "    <td class=\"frmText11\"><select name=\"".$listDef["search_prefix"].$key."\" onChange=\"submitForm('pageForm','".$module."/".$listDef["file"]."');\">{tmpl_var name='".$listDef["search_prefix"].$key."'}</select></td>\r\n";
-			} else {
-				$html .= "    <td class=\"frmText11\"><input type=\"text\" name=\"".$listDef["search_prefix"].$key."\" value=\"{tmpl_var name='".$listDef["search_prefix"].$key."'}\" class=\"text\" /></td>\r\n";
-			}
-		}
-		
-		$html .= '    <td class="frmText11" align="right"><input name="Filter" type="button" id="Filter" value="{tmpl_var name="filter_txt"}" class="button" onClick="'."submitForm('pageForm','".$module."/".$listDef["file"]."');".'"><div class="buttonEnding"></div></td>
-  </tr>
-  <tmpl_loop name="records">
-  <tr bgcolor="{tmpl_var name="bgcolor"}">
-';
-		
-		foreach($listDef["item"] as $field) {
-			$key = $field["field"];
-			$html .= "    <td class=\"frmText11\"><a href=\"#\" onClick=\"loadContent('".$module."/".$listDef["edit_file"]."?id={tmpl_var name='id'}');\" class=\"frmText11\">{tmpl_var name=\"".$key."\"}</a></td>\r\n";
-		}
-		
-		$html .= "    <td class=\"frmText11\" align=\"right\"><a href=\"javascript: del_record('".$module."/".$listDef["delete_file"]."?id={tmpl_var name='id'}&phpsessid={tmpl_var name='phpsessid'}','{tmpl_var name='delete_confirmation'}');\" class=\"frmText11\"><img src=\"themes/{tmpl_var name='theme'}/icons/list_icon_delete.png\" alt=\"{tmpl_var name='delete_txt'}\" border=\"0\" /></a></td>
-  </tr>
-  </tmpl_loop>
-";
-  $html .= '
-  <tr>
-  	<td colspan="'.(count($listDef["item"])+1).'" height="40" align="center" class="tblFooter"><tmpl_var name="paging"></td>
-  </tr>
-</table>';
-		
-		if($module == '') {
-			$filename = 'templates/'.$listDef["name"].'_list.htm';
-		} else {
-			$filename = '../'.$module.'/templates/'.$listDef["name"].'_list.htm';
-		}
-		
-		
-		// speichere Template
-		if (!$handle = fopen($filename, 'w')) { 
-        	print "Cannot open file ($filename)"; 
-        	exit; 
-   		} 
- 
-   		if (!fwrite($handle, $html)) { 
-			print "Cannot write to file ($filename)"; 
-			exit; 
-		}
-		fclose($handle);
-		
-		$lang["page_txt"] = 'Page';
-		$lang["page_of_txt"] = 'of';
-		$lang["page_next_txt"] = 'Next';
-		$lang["page_back_txt"] = 'Back';
-		$lang["delete_txt"] = 'Delete';
-		$lang["filter_txt"] = 'Filter';
-		$lang["add_new_record_txt"] = 'Add new record';
-		
-		// speichere language Datei
-		$this->lng_add($lang,$listDef,$module);
-    }
-	
-	function lng_add($lang,$listDef,$module = '') {
-		global $go_api, $go_info,$conf;
-		
-		if($module == '') {
-			$lng_file = "lib/lang/".$conf["language"]."_".$listDef['name']."_list.lng";
-		} else {
-			$lng_file = '../'.$module."/lib/lang/en_".$listDef['name']."_list.lng";
-		}
-		
-		if(is_file($lng_file)) {
-			include_once($lng_file);
-		} else {
-			$wb = array();
-		}
-		
-		$wb_out = array_merge($lang,$wb);
-		
-		if(is_array($wb_out)) {
-			$fp = fopen ($lng_file, "w");
-			fwrite($fp,"<?php\r\n");
-			foreach($wb_out as $key => $val) {
-				$new_line = '$wb["'.$key.'"] = '."'$val';\r\n";
-				fwrite($fp,$new_line);
-				
-			}
-			fwrite($fp,"?>");
-			fclose($fp);
-		}
-	}
-}
-
+<?php
+
+/*
+Copyright (c) 2005, Till Brehm, projektfarm Gmbh
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+    * Neither the name of ISPConfig nor the names of its contributors
+      may be used to endorse or promote products derived from this software without
+      specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+class listform_tpl_generator {
+	
+	function buildHTML($listDef,$module = '') {
+		
+		global $app;
+		
+		if($module == '') $module = $_SESSION["s"]["module"]["name"];
+
+		$lang = array();
+		$html = '<h2><tmpl_var name="list_head_txt"></h2>
+
+<div class="panel panel_list_'.$listDef["name"].'">
+
+  <div class="pnl_toolsarea">
+    <fieldset><legend>Tools</legend>
+      <div class="buttons">
+        <button class="iconstxt icoAdd" type="button" onClick="'."loadContent('".$module."/".$listDef["edit_file"]."');".'">
+          <span>{tmpl_var name="add_new_record_txt"}</span>
+        </button>
+      </div>
+    </fieldset>
+  </div>
+
+  <div class="pnl_listarea">
+    <fieldset><legend><tmpl_var name="list_head_txt"></legend>
+      <table class="list">
+        <thead>
+          <tr>
+';
+		
+		$lang["list_head_txt"] = $listDef["name"];
+		foreach($listDef["item"] as $field) {
+			$key = $field["field"];
+			$html .= "            <th class=\"tbl_col_".$key."\" scope=\"col\"><tmpl_var name=\"".$key."_txt\"></th>\r\n";
+			$lang[$key."_txt"] = $key;
+		}
+		
+		$html .= '            <th class="tbl_col_buttons" scope="col">&nbsp;</th>
+          </tr>
+          <tr>
+';
+  
+  		foreach($listDef["item"] as $field) {
+			$key = $field["field"];
+			if($field["formtype"] == 'SELECT') {
+				$html .= "            <td class=\"tbl_col_".$key."\"><select name=\"".$listDef["search_prefix"].$key."\" onChange=\"submitForm('pageForm','".$module."/".$listDef["file"]."');\">{tmpl_var name='".$listDef["search_prefix"].$key."'}</select></td>\r\n";
+			} else {
+				$html .= "            <td class=\"tbl_col_".$key."\"><input type=\"text\" name=\"".$listDef["search_prefix"].$key."\" value=\"{tmpl_var name='".$listDef["search_prefix"].$key."'}\" /></td>\r\n";
+			}
+		}
+		
+		$html .= '            <td class="tbl_col_buttons"><div class="buttons"><button type="button" class="icons16 icoFilter" name="Filter" id="Filter" value="{tmpl_var name="filter_txt"}" onClick="'."submitForm('pageForm','".$module."/".$listDef["file"]."');".'"><span>{tmpl_var name="filter_txt"}</span></button></div></td>
+          </tr>
+        </thead>
+        <tbody>
+          <tmpl_loop name="records">
+          <tr class="tbl_row_<tmpl_if name=\'__EVEN__\'}even<tmpl_else>uneven</tmpl_if>">
+';
+		
+		foreach($listDef["item"] as $field) {
+			$key = $field["field"];
+			$html .= "            <td class=\"tbl_col_".$key."\"><a href=\"#\" onClick=\"loadContent('".$module."/".$listDef["edit_file"]."?id={tmpl_var name='id'}');\">{tmpl_var name=\"".$key."\"}</a></td>\r\n";
+		}
+		
+		$html .= "            <td class=\"tbl_col_buttons\">
+              <div class=\"buttons icons16\">    
+                <a class=\"icons16 icoDelete\" href=\"javascript: del_record('".$module."/".$listDef["delete_file"]."?id={tmpl_var name='id'}&phpsessid={tmpl_var name='phpsessid'}','{tmpl_var name='delete_confirmation'}');\"><span>{tmpl_var name='delete_txt'}</span></a>
+              </div>
+            </td>
+          </tr>
+          </tmpl_loop>
+        </tbody>";
+  $html .= '
+        <tfoot>
+          <tr>
+            <td class="tbl_footer tbl_paging" colspan="'.(count($listDef["item"])+1).'"><tmpl_var name="paging"></td>
+          </tr>
+        </tfoot>
+      </table>
+    </fieldset>
+  </div>
+
+</div>
+';
+		
+		if($module == '') {
+			$filename = 'templates/'.$listDef["name"].'_list.htm';
+		} else {
+			$filename = '../'.$module.'/templates/'.$listDef["name"].'_list.htm';
+		}
+		
+		
+		// save template
+		if (!$handle = fopen($filename, 'w')) { 
+        	print "Cannot open file ($filename)"; 
+        	exit; 
+   		} 
+ 
+   		if (!fwrite($handle, $html)) { 
+			print "Cannot write to file ($filename)"; 
+			exit; 
+		}
+		fclose($handle);
+		
+		$lang["page_txt"] = 'Page';
+		$lang["page_of_txt"] = 'of';
+		$lang["page_next_txt"] = 'Next';
+		$lang["page_back_txt"] = 'Back';
+		$lang["delete_txt"] = 'Delete';
+		$lang["filter_txt"] = 'Filter';
+		$lang["add_new_record_txt"] = 'Add new record';
+		
+		// save language file
+		$this->lng_add($lang,$listDef,$module);
+    }
+	
+	function lng_add($lang,$listDef,$module = '') {
+		global $go_api, $go_info,$conf;
+		
+		if($module == '') {
+			$lng_file = "lib/lang/".$conf["language"]."_".$listDef['name']."_list.lng";
+		} else {
+			$lng_file = '../'.$module."/lib/lang/en_".$listDef['name']."_list.lng";
+		}
+		
+		if(is_file($lng_file)) {
+			include_once($lng_file);
+		} else {
+			$wb = array();
+		}
+		
+		$wb_out = array_merge($lang,$wb);
+		
+		if(is_array($wb_out)) {
+			$fp = fopen ($lng_file, "w");
+			fwrite($fp,"<?php\r\n");
+			foreach($wb_out as $key => $val) {
+				$new_line = '$wb["'.$key.'"] = '."'$val';\r\n";
+				fwrite($fp,$new_line);
+				
+			}
+			fwrite($fp,"?>");
+			fclose($fp);
+		}
+	}
+}
+
 ?>
\ No newline at end of file
diff --git a/interface/lib/classes/plugin_dbhistory.inc.php b/interface/lib/classes/plugin_dbhistory.inc.php
index 6f06430a85642e24dbbd5297de360a7b0aa516d1..7c2c4e3bd287c197604000d858dc012caeca0922 100644
--- a/interface/lib/classes/plugin_dbhistory.inc.php
+++ b/interface/lib/classes/plugin_dbhistory.inc.php
@@ -26,9 +26,9 @@ class plugin_dbhistory extends plugin_base {
 			
 			$records = $app->db->queryAllRecords($sql);
 			if(is_array($records)) {
-				$content .= '<table width="100%">';
+				$content .= '<table>';
 				foreach($records as $rec) {
-					$content .= "<tr><td class='frmText11' bgcolor='#EEEEEE'><b>".date("d.m.Y",$rec["tstamp"])." ".$rec["user"]."</b></td></tr>";
+					$content .= "<tr><td>".date("d.m.Y",$rec["tstamp"])."</td><td>".$rec["user"]."</td></tr>";
 				}
 				$content .= '</table>';
 			}
diff --git a/interface/lib/classes/tform.inc.php b/interface/lib/classes/tform.inc.php
index 27e749c88f3154be332c688519c12d173392a670..518e7fc2895fbbf3e6ebd8f8e6511fb87cf16d9b 100644
--- a/interface/lib/classes/tform.inc.php
+++ b/interface/lib/classes/tform.inc.php
@@ -1,1063 +1,1073 @@
-<?php
-
-/*
-Copyright (c) 2005, Till Brehm, projektfarm Gmbh
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
-      and/or other materials provided with the distribution.
-    * Neither the name of ISPConfig nor the names of its contributors
-      may be used to endorse or promote products derived from this software without
-      specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/**
-* Formularbehandlung
-*
-* Funktionen zur Umwandlung von Formulardaten
-* sowie zum vorbereiten von HTML und SQL
-* Ausgaben
-*
-*        Tabellendefinition
-*
-*        Datentypen:
-*        - INTEGER (Wandelt Ausdrücke in Int um)
-*        - DOUBLE
-*        - CURRENCY (Formatiert Zahlen nach Währungsnotation)
-*        - VARCHAR (kein weiterer Format Check)
-*        - DATE (Datumsformat, Timestamp Umwandlung)
-*
-*        Formtype:
-*        - TEXT (normales Textfeld)
-*        - PASSWORD (Feldinhalt wird nicht angezeigt)
-*        - SELECT (Gibt Werte als option Feld aus)
-*        - MULTIPLE (Select-Feld mit nehreren Werten)
-*
-*        VALUE:
-*        - Wert oder Array
-*
-*        SEPARATOR
-*        - Trennzeichen für multiple Felder
-*
-*        Hinweis:
-*        Das ID-Feld ist nicht bei den Table Values einzufügen.
-*
-* @package form
-* @author Till Brehm
-* @version 1.1
-*/
-
-class tform {
-
-        /**
-        * Definition der Tabelle (array)
-        * @var tableDef
-        */
-        var $tableDef;
-
-        /**
-        * Private
-        * @var action
-        */
-        var $action;
-
-        /**
-        * Tabellenname (String)
-        * @var table_name
-        */
-        var $table_name;
-
-        /**
-        * Debug Variable
-        * @var debug
-        */
-        var $debug = 0;
-
-        /**
-        * name des primary Field der Tabelle (string)
-        * @var table_index
-        */
-        var $table_index;
-
-        /**
-        * enthält die Fehlermeldung bei Überprüfung
-        * der Variablen mit Regex
-        * @var errorMessage
-        */
-        var $errorMessage = '';
-
-        var $dateformat = "d.m.Y";
-    	var $formDef;
-        var $wordbook;
-        var $module;
-        var $primary_id;
-		var $diffrec = array();
-
-        /**
-        * Laden der Tabellendefinition
-        *
-        * @param file: Pfad zur Tabellendefinition
-        * @return true
-        */
-        /*
-        function loadTableDef($file) {
-                global $app,$conf;
-
-                include_once($file);
-                $this->tableDef = $table;
-                $this->table_name = $table_name;
-                $this->table_index = $table_index;
-                return true;
-        }
-        */
-
-    function loadFormDef($file,$module = '') {
-                global $app,$conf;
-
-                include_once($file);
-                $this->formDef = $form;
-
-                $this->module = $module;
-				$wb = array();
-				
-                if($module == '') {
-					if(is_file("lib/lang/".$_SESSION["s"]["language"]."_".$this->formDef["name"].".lng")) {
-                        include_once("lib/lang/".$_SESSION["s"]["language"]."_".$this->formDef["name"].".lng");
-					}
-                } else {
-					if(is_file("../$module/lib/lang/".$_SESSION["s"]["language"]."_".$this->formDef["name"].".lng")) {
-                        include_once("../$module/lib/lang/".$_SESSION["s"]["language"]."_".$this->formDef["name"].".lng");
-					}
-                }
-                $this->wordbook = $wb;
-
-                return true;
-        }
-
-
-        /**
-        * Konvertiert die Daten des übergebenen assoziativen
-        * Arrays in "menschenlesbare" Form.
-        * Datentyp Konvertierung, z.B. für Ausgabe in Listen.
-        *
-        * @param record
-        * @return record
-        */
-        function decode($record,$tab) {
-                if(!is_array($this->formDef['tabs'][$tab])) $app->error("Tab ist leer oder existiert nicht (TAB: $tab).");
-                $new_record = '';
-				if(is_array($record)) {
-                        foreach($this->formDef['tabs'][$tab]['fields'] as $key => $field) {
-                                switch ($field['datatype']) {
-                                case 'VARCHAR':
-                                        $new_record[$key] = stripslashes($record[$key]);
-                                break;
-
-                                case 'TEXT':
-                                        $new_record[$key] = stripslashes($record[$key]);
-                                break;
-
-                                case 'DATE':
-                                        if($record[$key] > 0) {
-                                                $new_record[$key] = date($this->dateformat,$record[$key]);
-                                        }
-                                break;
-
-                                case 'INTEGER':
-                                        $new_record[$key] = intval($record[$key]);
-                                break;
-
-                                case 'DOUBLE':
-                                        $new_record[$key] = $record[$key];
-                                break;
-
-                                case 'CURRENCY':
-                                        $new_record[$key] = number_format($record[$key], 2, ',', '');
-                                break;
-
-                                default:
-                                        $new_record[$key] = stripslashes($record[$key]);
-                                }
-                        }
-
-                }
-				
-        return $new_record;
-        }
-
-        /**
-        * Get the key => value array of a form filed from a datasource definitiom
-        *
-        * @param field = array with field definition
-        * @param record = Dataset as array
-        * @return key => value array for the value field of a form
-        */
-
-        function getDatasourceData($field, $record) {
-                global $app;
-
-                $values = array();
-
-                if($field["datasource"]["type"] == 'SQL') {
-
-                        // Preparing SQL string. We will replace some
-                        // common placeholders
-                        $querystring = $field["datasource"]["querystring"];
-                        $querystring = str_replace("{USERID}",$_SESSION["s"]["user"]["userid"],$querystring);
-                        $querystring = str_replace("{GROUPID}",$_SESSION["s"]["user"]["default_group"],$querystring);
-                        $querystring = str_replace("{GROUPS}",$_SESSION["s"]["user"]["groups"],$querystring);
-                        $table_idx = $this->formDef['db_table_idx'];
-						
-						$tmp_recordid = (isset($record[$table_idx]))?$record[$table_idx]:0;
-                        $querystring = str_replace("{RECORDID}",$tmp_recordid,$querystring);
-						unset($tmp_recordid);
-						
-                        $querystring = str_replace("{AUTHSQL}",$this->getAuthSQL('r'),$querystring);
-
-                        // Getting the records
-                        $tmp_records = $app->db->queryAllRecords($querystring);
-                        if($app->db->errorMessage != '') die($app->db->errorMessage);
-                        if(is_array($tmp_records)) {
-                                $key_field = $field["datasource"]["keyfield"];
-                                $value_field = $field["datasource"]["valuefield"];
-                                foreach($tmp_records as $tmp_rec) {
-                                        $tmp_id = $tmp_rec[$key_field];
-                                        $values[$tmp_id] = $tmp_rec[$value_field];
-                                }
-                        }
-                }
-
-                if($field["datasource"]["type"] == 'CUSTOM') {
-                        // Calls a custom class to validate this record
-                        if($field["datasource"]['class'] != '' and $field["datasource"]['function'] != '') {
-                                $datasource_class = $field["datasource"]['class'];
-                                $datasource_function = $field["datasource"]['function'];
-                                $app->uses($datasource_class);
-                                $values = $app->$datasource_class->$datasource_function($field, $record);
-                        } else {
-                                $this->errorMessage .= "Custom datasource class or function is empty<br>\r\n";
-                        }
-                }
-
-                return $values;
-
-        }
-
-
-        /**
-        * Record für Ausgabe in Formularen vorbereiten.
-        *
-        * @param record = Datensatz als Array
-        * @param action = NEW oder EDIT
-        * @return record
-        */
-        function getHTML($record, $tab, $action = 'NEW') {
-
-                global $app;
-
-                $this->action = $action;
-
-                if(!is_array($this->formDef)) $app->error("Keine Formdefinition vorhanden.");
-                if(!is_array($this->formDef['tabs'][$tab])) $app->error("Tab ist leer oder existiert nicht (TAB: $tab).");
-
-                $new_record = array();
-                if($action == 'EDIT') {
-                        $record = $this->decode($record,$tab);
-                        if(is_array($record)) {
-                                foreach($this->formDef['tabs'][$tab]['fields'] as $key => $field) {
-                                        $val = $record[$key];
-
-                                        // If Datasource is set, get the data from there
-                                        if(isset($field['datasource']) && is_array($field['datasource'])) {
-                                                $field["value"] = $this->getDatasourceData($field, $record);
-                                        }
-
-                                        switch ($field['formtype']) {
-                                        case 'SELECT':
-												$out = '';
-                                                if(is_array($field['value'])) {
-                                                        foreach($field['value'] as $k => $v) {
-                                                                $selected = ($k == $val)?' SELECTED':'';
-                                                                $out .= "<option value='$k'$selected>$v</option>\r\n";
-                                                        }
-                                                }
-                                                $new_record[$key] = $out;
-                                        break;
-                                        case 'MULTIPLE':
-                                                if(is_array($field['value'])) {
-
-                                                        // aufsplitten ergebnisse
-                                                        $vals = explode($field['separator'],$val);
-
-                                                        // HTML schreiben
-                                                        $out = '';
-                                                        foreach($field['value'] as $k => $v) {
-
-                                                                $selected = '';
-                                                                foreach($vals as $tvl) {
-                                                                        if(trim($tvl) == trim($k)) $selected = ' SELECTED';
-                                                                }
-
-                                                                $out .= "<option value='$k'$selected>$v</option>\r\n";
-                                                        }
-                                                }
-                                                $new_record[$key] = $out;
-                                        break;
-
-                                        case 'PASSWORD':
-                                                $new_record[$key] = '';
-                                        break;
-
-                                        case 'CHECKBOX':
-                                                $checked = ($val == $field['value'][1])?' CHECKED':'';
-                                                $new_record[$key] = "<input name=\"".$key."\" type=\"checkbox\" value=\"".$field['value'][1]."\" $checked>\r\n";
-                                        break;
-
-                                        case 'CHECKBOXARRAY':
-                                                if(is_array($field['value'])) {
-
-                                                        // aufsplitten ergebnisse
-                                                        $vals = explode($field['separator'],$val);
-
-                                                        // HTML schreiben
-                                                        $out = '';
-                                                        foreach($field['value'] as $k => $v) {
-
-                                                                $checked = '';
-                                                                foreach($vals as $tvl) {
-                                                                        if(trim($tvl) == trim($k)) $checked = ' CHECKED';
-                                                                }
-
-                                                                $out .= "<input name=\"".$key."[]\" type=\"checkbox\" value=\"$k\" $checked>$v <br />\r\n";
-                                                        }
-                                                }
-                                                $new_record[$key] = $out;
-                                        break;
-
-                                        case 'RADIO':
-                                                if(is_array($field['value'])) {
-
-                                                        // HTML schreiben
-                                                        $out = '';
-                                                        foreach($field['value'] as $k => $v) {
-                                                                $checked = ($k == $val)?' CHECKED':'';
-                                                                $out .= "<input name='".$key."[]' type='radio' value='$k'$checked> $v<br>\r\n";
-                                                        }
-                                                }
-                                                $new_record[$key] = $out;
-                                        break;
-
-                                        default:
-                                                $new_record[$key] = htmlspecialchars($record[$key]);
-                                        }
-                                }
-                        }
-                } else {
-                        // Action: NEW
-                        foreach($this->formDef['tabs'][$tab]['fields'] as $key => $field) {
-
-                                // If Datasource is set, get the data from there
-                                if(@is_array($field['datasource'])) {
-                                        $field["value"] = $this->getDatasourceData($field, $record);
-                                }
-
-                                switch ($field['formtype']) {
-                                case 'SELECT':
-                                        if(is_array($field['value'])) {
-                                                $out = '';
-                                                foreach($field['value'] as $k => $v) {
-                                                    //$selected = ($k == $val)?' SELECTED':'';
-													$selected = '';
-                                                    $out .= "<option value='$k'$selected>$v</option>\r\n";
-                                                }
-                                        }
-                                        if(isset($out)) $new_record[$key] = $out;
-                                break;
-                                case 'MULTIPLE':
-                                                if(is_array($field['value'])) {
-
-                                                        // aufsplitten ergebnisse
-                                                        $vals = explode($field['separator'],$val);
-
-                                                        // HTML schreiben
-                                                        $out = '';
-                                                        foreach($field['value'] as $k => $v) {
-
-                                                                $out .= "<option value='$k'>$v</option>\r\n";
-                                                        }
-                                                }
-                                                $new_record[$key] = $out;
-                                        break;
-
-                                case 'PASSWORD':
-                                        $new_record[$key] = '';
-                                break;
-
-                                case 'CHECKBOX':
-                                        // $checked = (empty($field["default"]))?'':' CHECKED';
-										$checked = ($field["default"] == $field['value'][1])?' CHECKED':'';
-                                        $new_record[$key] = "<input name=\"".$key."\" type=\"checkbox\" value=\"".$field['value'][1]."\" $checked>\r\n";
-                                break;
-
-                                case 'CHECKBOXARRAY':
-                                        if(is_array($field['value'])) {
-
-                                                // aufsplitten ergebnisse
-                                                $vals = explode($field['separator'],$field["default"]);
-
-                                                // HTML schreiben
-                                                $out = '';
-                                                foreach($field['value'] as $k => $v) {
-
-                                                        $checked = '';
-                                                        foreach($vals as $tvl) {
-                                                                if(trim($tvl) == trim($k)) $checked = ' CHECKED';
-                                                        }
-
-                                                        $out .= "<input name=\"".$key."[]\" type=\"checkbox\" value=\"$k\" $checked> $v<br />\r\n";
-                                                }
-                                        }
-                                        $new_record[$key] = $out;
-                                break;
-
-                                case 'RADIO':
-                                        if(is_array($field['value'])) {
-
-                                                // HTML schreiben
-                                                $out = '';
-                                                foreach($field['value'] as $k => $v) {
-                                                        $checked = ($k == $field["default"])?' CHECKED':'';
-                                                        $out .= "<input name='".$key."[]' type='radio' value='$k'$checked> $v<br>\r\n";
-                                                }
-                                        }
-                                        $new_record[$key] = $out;
-                                break;
-
-                                default:
-                                        $new_record[$key] = htmlspecialchars($field['default']);
-                                }
-                        }
-
-                }
-
-                if($this->debug == 1) $this->dbg($new_record);
-
-                return $new_record;
-        }
-
-        /**
-        * Record in "maschinen lesbares" Format überführen
-        * und Werte gegen reguläre Ausdrücke prüfen.
-        *
-        * @param record = Datensatz als Array
-        * @return record
-        */
-        function encode($record,$tab) {
-			global $app;
-			
-                if(!is_array($this->formDef['tabs'][$tab])) $app->error("Tab ist leer oder existiert nicht (TAB: $tab).");
-                //$this->errorMessage = '';
-
-                if(is_array($record)) {
-                        foreach($this->formDef['tabs'][$tab]['fields'] as $key => $field) {
-
-                                if(isset($field['validators']) && is_array($field['validators'])) $this->validateField($key, (isset($record[$key]))?$record[$key]:'', $field['validators']);
-
-                                switch ($field['datatype']) {
-                                case 'VARCHAR':
-                                        if(!@is_array($record[$key])) {
-                                                $new_record[$key] = (isset($record[$key]))?$app->db->quote($record[$key]):'';
-                                        } else {
-                                                $new_record[$key] = implode($field['separator'],$record[$key]);
-                                        }
-                                break;
-                                case 'TEXT':
-                                        if(!is_array($record[$key])) {
-                                                $new_record[$key] = $app->db->quote($record[$key]);
-                                        } else {
-                                                $new_record[$key] = implode($field['separator'],$record[$key]);
-                                        }
-                                break;
-                                case 'DATE':
-                                        if($record[$key] > 0) {
-                                                list($tag,$monat,$jahr) = explode('.',$record[$key]);
-                                                $new_record[$key] = mktime(0,0,0,$monat,$tag,$jahr);
-                                        } else {
-											$new_record[$key] = 0;
-										}
-                                break;
-                                case 'INTEGER':
-                                        $new_record[$key] = (isset($record[$key]))?intval($record[$key]):0;
-                                        //if($new_record[$key] != $record[$key]) $new_record[$key] = $field['default'];
-                                        //if($key == 'refresh') die($record[$key]);
-                                break;
-                                case 'DOUBLE':
-                                        $new_record[$key] = $app->db->quote($record[$key]);
-                                break;
-                                case 'CURRENCY':
-                                        $new_record[$key] = str_replace(",",".",$record[$key]);
-                                break;
-                                }
-
-                                // The use of the field value is deprecated, use validators instead
-                                if(isset($field['regex']) && $field['regex'] != '') {
-                                        // Enable that "." matches also newlines
-                                        $field['regex'] .= 's';
-                                        if(!preg_match($field['regex'], $record[$key])) {
-                                                $errmsg = $field['errmsg'];
-                                                $this->errorMessage .= $this->wordbook[$errmsg]."<br>\r\n";
-                                        }
-                                }
-
-
-                        }
-                }
-                return $new_record;
-        }
-
-        /**
-        * process the validators for a given field.
-        *
-        * @param field_name = Name of the field
-        * @param field_value = value of the field
-        * @param validatoors = Array of validators
-        * @return record
-        */
-
-        function validateField($field_name, $field_value, $validators) {
-
-                global $app;
-				
-				$escape = '`';
-				
-                // loop trough the validators
-                foreach($validators as $validator) {
-
-                        switch ($validator['type']) {
-                                case 'REGEX':
-                                        $validator['regex'] .= 's';
-                                        if(!preg_match($validator['regex'], $field_value)) {
-                                                $errmsg = $validator['errmsg'];
-                                                if(isset($this->wordbook[$errmsg])) {
-                                                	$this->errorMessage .= $this->wordbook[$errmsg]."<br>\r\n";
-												} else {
-													$this->errorMessage .= $errmsg."<br>\r\n";
-												}
-                                        }
-                                break;
-                                case 'UNIQUE':
-                                        if($this->action == 'NEW') {
-                                                $num_rec = $app->db->queryOneRecord("SELECT count(*) as number FROM ".$escape.$this->formDef['db_table'].$escape. " WHERE $field_name = '".$app->db->quote($field_value)."'");
-                                                if($num_rec["number"] > 0) {
-                                                        $errmsg = $validator['errmsg'];
-														if(isset($this->wordbook[$errmsg])) {
-                                                        	$this->errorMessage .= $this->wordbook[$errmsg]."<br>\r\n";
-														} else {
-															$this->errorMessage .= $errmsg."<br>\r\n";
-														}
-                                                }
-                                        } else {
-                                                $num_rec = $app->db->queryOneRecord("SELECT count(*) as number FROM ".$escape.$this->formDef['db_table'].$escape. " WHERE $field_name = '".$app->db->quote($field_value)."' AND ".$this->formDef['db_table_idx']." != ".$this->primary_id);
-                                                if($num_rec["number"] > 0) {
-                                                        $errmsg = $validator['errmsg'];
-                                                        if(isset($this->wordbook[$errmsg])) {
-                                                        	$this->errorMessage .= $this->wordbook[$errmsg]."<br>\r\n";
-														} else {
-															$this->errorMessage .= $errmsg."<br>\r\n";
-														}
-                                                }
-                                        }
-                                break;
-                                case 'NOTEMPTY':
-                                        if(empty($field_value)) {
-                                                $errmsg = $validator['errmsg'];
-                                                if(isset($this->wordbook[$errmsg])) {
-                                                    $this->errorMessage .= $this->wordbook[$errmsg]."<br>\r\n";
-												} else {
-													$this->errorMessage .= $errmsg."<br>\r\n";
-												}
-                                        }
-                                break;
-                                case 'ISEMAIL':
-                                        if(!preg_match("/^\w+[\w.-]*\w+@\w+[\w.-]*\w+\.[a-z]{2,10}$/i", $field_value)) {
-                                                $errmsg = $validator['errmsg'];
-                                                if(isset($this->wordbook[$errmsg])) {
-                                                    $this->errorMessage .= $this->wordbook[$errmsg]."<br>\r\n";
-												} else {
-													$this->errorMessage .= $errmsg."<br>\r\n";
-												}
-                                        }
-                                break;
-                                case 'ISINT':
-                                        $tmpval = intval($field_value);
-                                        if($tmpval === 0 and !empty($field_value)) {
-                                                $errmsg = $validator['errmsg'];
-                                                if(isset($this->wordbook[$errmsg])) {
-                                                    $this->errorMessage .= $this->wordbook[$errmsg]."<br>\r\n";
-												} else {
-													$this->errorMessage .= $errmsg."<br>\r\n";
-												}
-                                        }
-                                break;
-                                case 'ISPOSITIVE':
-                                        if(!is_numeric($field_value) || $field_value <= 0){
-                                          $errmsg = $validator['errmsg'];
-                                          if(isset($this->wordbook[$errmsg])) {
-                                             $this->errorMessage .= $this->wordbook[$errmsg]."<br>\r\n";
-										  } else {
-											 $this->errorMessage .= $errmsg."<br>\r\n";
-										  }
-                                        }
-                                break;
-                                case 'CUSTOM':
-                                        // Calls a custom class to validate this record
-                                        if($validator['class'] != '' and $validator['function'] != '') {
-                                                $validator_class = $validator['class'];
-                                                $validator_function = $validator['function'];
-                                                $app->uses($validator_class);
-                                                $this->errorMessage .= $app->$validator_class->$validator_function($field_name, $field_value, $validator);
-                                        } else {
-                                                $this->errorMessage .= "Custom validator class or function is empty<br>\r\n";
-                                        }
-                                break;
-								default:
-									$this->errorMessage .= "Unknown Validator: ".$validator['type'];
-								break;
-                        }
-
-
-                }
-
-                return true;
-        }
-
-        /**
-        * SQL Statement für Record erzeugen.
-        *
-        * @param record = Datensatz als Array
-        * @param action = INSERT oder UPDATE
-        * @param primary_id
-        * @return record
-        */
-        function getSQL($record, $tab, $action = 'INSERT', $primary_id = 0, $sql_ext_where = '') {
-
-                global $app;
-
-                // If there are no data records on the tab, return empty sql string
-                if(count($this->formDef['tabs'][$tab]['fields']) == 0) return '';
-
-                // checking permissions
-                if($this->formDef['auth'] == 'yes' && $_SESSION["s"]["user"]["typ"] != 'admin') {
-                        if($action == "INSERT") {
-                                if(!$this->checkPerm($primary_id,'i')) $this->errorMessage .= "Insert denied.<br>\r\n";
-                        } else {
-                                if(!$this->checkPerm($primary_id,'u')) $this->errorMessage .= "Update denied.<br>\r\n";
-                        }
-                }
-
-                $this->action = $action;
-                $this->primary_id = $primary_id;
-
-                $record = $this->encode($record,$tab);
-                $sql_insert_key = '';
-                $sql_insert_val = '';
-                $sql_update = '';
-
-                if(!is_array($this->formDef)) $app->error("Keine Formulardefinition vorhanden.");
-                if(!is_array($this->formDef['tabs'][$tab])) $app->error("Tab ist leer oder existiert nicht (TAB: $tab).");
-
-                // gehe durch alle Felder des Tabs
-                if(is_array($record)) {
-                foreach($this->formDef['tabs'][$tab]['fields'] as $key => $field) {
-                                // Wenn es kein leeres Passwortfeld ist
-                                if (!($field['formtype'] == 'PASSWORD' and $record[$key] == '')) {
-                                        // Erzeuge Insert oder Update Quelltext
-                                        if($action == "INSERT") {
-                                                if($field['formtype'] == 'PASSWORD') {
-                                                        $sql_insert_key .= "`$key`, ";
-                                                        if($field['encryption'] == 'CRYPT') {
-                                                                $salt="$1$";
-																for ($n=0;$n<11;$n++) {
-																	$salt.=chr(mt_rand(64,126));
-																}
-																$salt.="$";
-																// $salt = substr(md5(time()),0,2);
-																$record[$key] = crypt($record[$key],$salt);
-																$sql_insert_val .= "'".$app->db->quote($record[$key])."', ";
-														} elseif ($field['encryption'] == 'MYSQL') {
-																$sql_insert_val .= "PASSWORD('".$app->db->quote($record[$key])."'), ";
-														} elseif ($field['encryption'] == 'CLEARTEXT') {
-																$sql_insert_val .= "'".$app->db->quote($record[$key])."', ";
-                                                        } else {
-                                                                $record[$key] = md5($record[$key]);
-																$sql_insert_val .= "'".$app->db->quote($record[$key])."', ";
-                                                        }
-														
-                                                } elseif ($field['formtype'] == 'CHECKBOX') {
-                                                        $sql_insert_key .= "`$key`, ";
-														if($record[$key] == '') {
-															// if a checkbox is not set, we set it to the unchecked value
-															$sql_insert_val .= "'".$field['value'][0]."', ";
-															$record[$key] = $field['value'][0];
-														} else {
-															$sql_insert_val .= "'".$record[$key]."', ";
-														}
-                                                } else {
-                                                        $sql_insert_key .= "`$key`, ";
-                                                        $sql_insert_val .= "'".$record[$key]."', ";
-                                                }
-                                        } else {
-                                                if($field['formtype'] == 'PASSWORD') {
-														if(isset($field['encryption']) && $field['encryption'] == 'CRYPT') {
-                                                                $salt="$1$";
-																for ($n=0;$n<11;$n++) {
-																	$salt.=chr(mt_rand(64,126));
-																}
-																$salt.="$";
-																// $salt = substr(md5(time()),0,2);
-																$record[$key] = crypt($record[$key],$salt);
-																$sql_update .= "`$key` = '".$app->db->quote($record[$key])."', ";
-														} elseif (isset($field['encryption']) && $field['encryption'] == 'MYSQL') {
-																$sql_update .= "`$key` = PASSWORD('".$app->db->quote($record[$key])."'), ";
-														} elseif (isset($field['encryption']) && $field['encryption'] == 'CLEARTEXT') {
-																$sql_update .= "`$key` = '".$app->db->quote($record[$key])."', ";
-                                                        } else {
-                                                                $record[$key] = md5($record[$key]);
-																$sql_update .= "`$key` = '".$app->db->quote($record[$key])."', ";
-                                                        }
-                                                        
-                                                } elseif ($field['formtype'] == 'CHECKBOX') {
-														if($record[$key] == '') {
-															// if a checkbox is not set, we set it to the unchecked value
-															$sql_update .= "`$key` = '".$field['value'][0]."', ";
-															$record[$key] = $field['value'][0];
-														} else {
-															$sql_update .= "`$key` = '".$record[$key]."', ";
-														}
-                                                } else {
-                                                        $sql_update .= "`$key` = '".$record[$key]."', ";
-                                                }
-                                        }
-                                } else {
-									// we unset the password filed, if empty to tell the datalog function 
-									// that the password has not been changed
-								    unset($record[$key]);
-								}
-                        }
-        }
-
-
-                // Füge Backticks nur bei unvollständigen Tabellennamen ein
-                if(stristr($this->formDef['db_table'],'.')) {
-                        $escape = '';
-                } else {
-                        $escape = '`';
-                }
-
-
-                if($action == "INSERT") {
-                        if($this->formDef['auth'] == 'yes') {
-                                // Setze User und Gruppe
-                                $sql_insert_key .= "`sys_userid`, ";
-                                $sql_insert_val .= ($this->formDef["auth_preset"]["userid"] > 0)?"'".$this->formDef["auth_preset"]["userid"]."', ":"'".$_SESSION["s"]["user"]["userid"]."', ";
-                                $sql_insert_key .= "`sys_groupid`, ";
-                                $sql_insert_val .= ($this->formDef["auth_preset"]["groupid"] > 0)?"'".$this->formDef["auth_preset"]["groupid"]."', ":"'".$_SESSION["s"]["user"]["default_group"]."', ";
-                                $sql_insert_key .= "`sys_perm_user`, ";
-                                $sql_insert_val .= "'".$this->formDef["auth_preset"]["perm_user"]."', ";
-                                $sql_insert_key .= "`sys_perm_group`, ";
-                                $sql_insert_val .= "'".$this->formDef["auth_preset"]["perm_group"]."', ";
-                                $sql_insert_key .= "`sys_perm_other`, ";
-                                $sql_insert_val .= "'".$this->formDef["auth_preset"]["perm_other"]."', ";
-                        }
-                        $sql_insert_key = substr($sql_insert_key,0,-2);
-                        $sql_insert_val = substr($sql_insert_val,0,-2);
-                        $sql = "INSERT INTO ".$escape.$this->formDef['db_table'].$escape." ($sql_insert_key) VALUES ($sql_insert_val)";
-                } else {
-                        if($primary_id != 0) {
-                                $sql_update = substr($sql_update,0,-2);
-                                $sql = "UPDATE ".$escape.$this->formDef['db_table'].$escape." SET ".$sql_update." WHERE ".$this->getAuthSQL('u')." AND ".$this->formDef['db_table_idx']." = ".$primary_id;
-                                if($sql_ext_where != '') $sql .= " and ".$sql_ext_where;
-                        } else {
-                                $app->error("Primary ID fehlt!");
-                        }
-                }
-                
-                return $sql;
-        }
-
-        /**
-        * Debugging arrays.
-        *
-        * @param array_data
-        */
-        function dbg($array_data) {
-
-                echo "<pre>";
-                print_r($array_data);
-                echo "</pre>";
-
-        }
-
-
-    function showForm() {
-            global $app,$conf;
-
-        if(!is_array($this->formDef)) die("Form Definition wurde nicht geladen.");
-
-                $active_tab = $this->getNextTab();
-
-        // definiere Tabs
-        foreach( $this->formDef["tabs"] as $key => $tab) {
-
-            $tab['name'] = $key;
-            if($tab['name'] == $active_tab) {
-
-                // Wenn Modul gesetzt, dann setzte template pfad relativ zu modul.
-                if($this->module != '') $tab["template"] = "../".$this->module."/".$tab["template"];
-
-                // überprüfe, ob das Template existiert, wenn nicht
-                // dann generiere das Template
-				
-				// Translate the title of the tab
-				$tab['title'] = $this->lng($tab['title']);
-								
-                if(!is_file($tab["template"])) {
-                     $app->uses('tform_tpl_generator');
-                     $app->tform_tpl_generator->buildHTML($this->formDef,$tab['name']);
-                }
-
-                $app->tpl->setInclude('content_tpl',$tab["template"]);
-                $tab["active"] = 1;
-                $_SESSION["s"]["form"]["tab"] = $tab['name'];
-            } else {
-                    $tab["active"] = 0;
-            }
-
-                        // Die Datenfelder werden für die Tabs nicht benötigt
-                        unset($tab["fields"]);
-                        unset($tab["plugins"]);
-
-            $frmTab[] = $tab;
-        }
-
-        // setting form tabs
-        $app->tpl->setLoop("formTab", $frmTab);
-
-                // Set form action
-                $app->tpl->setVar('form_action',$this->formDef["action"]);
-                $app->tpl->setVar('form_active_tab',$active_tab);
-
-                // Set form title
-                $form_hint = '<b>'.$this->lng($this->formDef["title"]).'</b>';
-                if($this->formDef["description"] != '') $form_hint .= '<br><br>'.$this->lng($this->formDef["description"]);
-                $app->tpl->setVar('form_hint',$form_hint);
-
-                // Set Wordbook for this form
-
-                $app->tpl->setVar($this->wordbook);
-    	}
-
-		function getDataRecord($primary_id) {
-			global $app;
-			$escape = '`';
-			$sql = "SELECT * FROM ".$escape.$this->formDef['db_table'].$escape." WHERE ".$this->formDef['db_table_idx']." = ".$primary_id;
-            return $app->db->queryOneRecord($sql);
-		}
-		
-
-        function datalogSave($action,$primary_id, $record_old, $record_new) {
-                global $app,$conf;
-
-                // Füge Backticks nur bei unvollständigen Tabellennamen ein
-                if(stristr($this->formDef['db_table'],'.')) {
-                        $escape = '';
-                } else {
-                        $escape = '`';
-                }
-
-                $diffrec = array();
-				
-                if(is_array($record_new) && count($record_new) > 0) {
-                        foreach($record_new as $key => $val) {
-                                if(@$record_old[$key] != $val) {
-										// Record has changed
-                                        $diffrec[$key] = array('old' => @$record_old[$key],
-                                                               'new' => $val);
-                                }
-                        }
-                } elseif(is_array($record_old)) {
-                        foreach($record_old as $key => $val) {
-                                if($record_new[$key] != $val) {
-										// Record has changed
-                                        $diffrec[$key] = array('new' => $record_new[$key],
-                                                               'old' => $val);
-                                }
-                        }
-                }
-				$this->diffrec = $diffrec;
-				
-				
-				// Full diff records for ISPConfig, they have a different format then the simple diffrec
-				$diffrec_full = array();
-
-                if(is_array($record_old) && count($record_old) > 0) {
-                        foreach($record_old as $key => $val) {
-                                //if(isset($record_new[$key]) && $record_new[$key] != $val) {
-								if(!isset($record_new[$key]) || $record_new[$key] != $val) {
-                                    // Record has changed
-									$diffrec_full['old'][$key] = $val;
-									$diffrec_full['new'][$key] = $record_new[$key];
-                                } else {
-									$diffrec_full['old'][$key] = $val;
-									$diffrec_full['new'][$key] = $val;
-								}
-                        }
-                } elseif(is_array($record_new)) {
-                        foreach($record_new as $key => $val) {
-                                if(isset($record_new[$key]) && $record_old[$key] != $val) {
-                                    // Record has changed
-									$diffrec_full['new'][$key] = $val;
-									$diffrec_full['old'][$key] = $record_old[$key];
-                                } else {
-									$diffrec_full['new'][$key] = $val;
-									$diffrec_full['old'][$key] = $val;
-								}
-                        }
-                }
-				
-				// Insert the server_id, if the record has a server_id
-				$server_id = (isset($record_old["server_id"]) && $record_old["server_id"] > 0)?$record_old["server_id"]:0;
-				if(isset($record_new["server_id"])) $server_id = $record_new["server_id"];
-
-                if(count($this->diffrec) > 0) {
-						$diffstr = $app->db->quote(serialize($diffrec_full));
-                        $username = $app->db->quote($_SESSION["s"]["user"]["username"]);
-                        $dbidx = $this->formDef['db_table_idx'].":".$primary_id;
-                        // $action = ($action == 'INSERT')?'i':'u';
-						
-						if($action == 'INSERT') $action = 'i';
-						if($action == 'UPDATE') $action = 'u';
-						if($action == 'DELETE') $action = 'd';
-                        $sql = "INSERT INTO sys_datalog (dbtable,dbidx,server_id,action,tstamp,user,data) VALUES ('".$this->formDef['db_table']."','$dbidx','$server_id','$action','".time()."','$username','$diffstr')";
-						$app->db->query($sql);
-                }
-
-                return true;
-
-        }
-
-        function getAuthSQL($perm) {
-				if($_SESSION["s"]["user"]["typ"] == 'admin') {
-					return '1';
-				} else {
-                	$groups = ( $_SESSION["s"]["user"]["groups"] ) ? $_SESSION["s"]["user"]["groups"] : 0;
-					$sql = '(';
-                	$sql .= "(sys_userid = ".$_SESSION["s"]["user"]["userid"]." AND sys_perm_user like '%$perm%') OR  ";
-                	$sql .= "(sys_groupid IN (".$groups.") AND sys_perm_group like '%$perm%') OR ";
-                	$sql .= "sys_perm_other like '%$perm%'";
-                	$sql .= ')';
-
-                	return $sql;
-				}
-        }
-
-        /*
-        Diese funktion überprüft, ob ein User die Berechtigung $perm für den Datensatz mit der ID $record_id
-        hat. It record_id = 0, dann wird gegen die user Defaults des Formulares getestet.
-        */
-        function checkPerm($record_id,$perm) {
-                global $app;
-
-                if($record_id > 0) {
-                        // Füge Backticks nur bei unvollständigen Tabellennamen ein
-                        if(stristr($this->formDef['db_table'],'.')) {
-                                $escape = '';
-                        } else {
-                                $escape = '`';
-                        }
-
-                        $sql = "SELECT ".$this->formDef['db_table_idx']." FROM ".$escape.$this->formDef['db_table'].$escape." WHERE ".$this->formDef['db_table_idx']." = ".$record_id." AND ".$this->getAuthSQL($perm);
-                        if($record = $app->db->queryOneRecord($sql)) {
-                                return true;
-                        } else {
-                                return false;
-                        }
-                } else {
-                        $result = false;
-                        if(@$this->formDef["auth_preset"]["userid"] == $_SESSION["s"]["user"]["userid"] && stristr($perm,$this->formDef["auth_preset"]["perm_user"])) $result = true;
-                        if(@$this->formDef["auth_preset"]["groupid"] == $_SESSION["s"]["user"]["groupid"] && stristr($perm,$this->formDef["auth_preset"]["perm_group"])) $result = true;
-                        if(@stristr($this->formDef["auth_preset"]["perm_other"],$perm)) $result = true;
-
-                        // if preset == 0, everyone can insert a record of this type
-                        if($this->formDef["auth_preset"]["userid"] == 0 AND $this->formDef["auth_preset"]["groupid"] == 0 AND (@stristr($this->formDef["auth_preset"]["perm_user"],$perm) OR @stristr($this->formDef["auth_preset"]["perm_group"],$perm))) $result = true;
-
-                        return $result;
-
-                }
-
-        }
-
-        function getNextTab() {
-                // Welcher Tab wird angezeigt
-                if($this->errorMessage == '') {
-                    // wenn kein Fehler vorliegt
-                    if(isset($_REQUEST["next_tab"]) && $_REQUEST["next_tab"] != '') {
-                                // wenn nächster Tab bekannt
-                                $active_tab = $_REQUEST["next_tab"];
-                    } else {
-                        // ansonsten ersten tab nehmen
-                        $active_tab = $this->formDef['tab_default'];
-                    }
-                } else {
-                    // bei Fehlern den gleichen Tab nochmal anzeigen
-                    $active_tab = $_SESSION["s"]["form"]["tab"];
-                }
-
-                return $active_tab;
-        }
-
-        function getCurrentTab() {
-                return $_SESSION["s"]["form"]["tab"];
-        }
-		
-		function isReadonlyTab($tab) {
-			if(isset($this->formDef['tabs'][$tab]['readonly']) && $this->formDef['tabs'][$tab]['readonly'] == true) {
-				return true;
-			} else {
-				return false;
-			}
-        }
-		
-		
-		// translation function for forms, tries the form wordbook first and if this fails, it tries the global wordbook
-		function lng($msg) {
-			global $app;
-			
-			if(isset($this->wordbook[$msg])) {
-				return $this->wordbook[$msg];
-			} else {
-				return $app->lng($msg);
-			}
-			
-		}
-
-}
-
+<?php
+
+/*
+Copyright (c) 2005, Till Brehm, projektfarm Gmbh
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+    * Neither the name of ISPConfig nor the names of its contributors
+      may be used to endorse or promote products derived from this software without
+      specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/**
+* Formularbehandlung
+*
+* Funktionen zur Umwandlung von Formulardaten
+* sowie zum vorbereiten von HTML und SQL
+* Ausgaben
+*
+*        Tabellendefinition
+*
+*        Datentypen:
+*        - INTEGER (Wandelt Ausdrücke in Int um)
+*        - DOUBLE
+*        - CURRENCY (Formatiert Zahlen nach Währungsnotation)
+*        - VARCHAR (kein weiterer Format Check)
+*        - DATE (Datumsformat, Timestamp Umwandlung)
+*
+*        Formtype:
+*        - TEXT (normales Textfeld)
+*        - PASSWORD (Feldinhalt wird nicht angezeigt)
+*        - SELECT (Gibt Werte als option Feld aus)
+*        - MULTIPLE (Select-Feld mit nehreren Werten)
+*
+*        VALUE:
+*        - Wert oder Array
+*
+*        SEPARATOR
+*        - Trennzeichen für multiple Felder
+*
+*        Hinweis:
+*        Das ID-Feld ist nicht bei den Table Values einzufügen.
+*
+* @package form
+* @author Till Brehm
+* @version 1.1
+*/
+
+class tform {
+
+        /**
+        * Definition der Tabelle (array)
+        * @var tableDef
+        */
+        var $tableDef;
+
+        /**
+        * Private
+        * @var action
+        */
+        var $action;
+
+        /**
+        * Tabellenname (String)
+        * @var table_name
+        */
+        var $table_name;
+
+        /**
+        * Debug Variable
+        * @var debug
+        */
+        var $debug = 0;
+
+        /**
+        * name des primary Field der Tabelle (string)
+        * @var table_index
+        */
+        var $table_index;
+
+        /**
+        * enthält die Fehlermeldung bei Überprüfung
+        * der Variablen mit Regex
+        * @var errorMessage
+        */
+        var $errorMessage = '';
+
+        var $dateformat = "d.m.Y";
+    	var $formDef;
+        var $wordbook;
+        var $module;
+        var $primary_id;
+		var $diffrec = array();
+
+        /**
+        * Laden der Tabellendefinition
+        *
+        * @param file: Pfad zur Tabellendefinition
+        * @return true
+        */
+        /*
+        function loadTableDef($file) {
+                global $app,$conf;
+
+                include_once($file);
+                $this->tableDef = $table;
+                $this->table_name = $table_name;
+                $this->table_index = $table_index;
+                return true;
+        }
+        */
+
+    function loadFormDef($file,$module = '') {
+                global $app,$conf;
+
+                include_once($file);
+                $this->formDef = $form;
+
+                $this->module = $module;
+				$wb = array();
+				
+                if($module == '') {
+					if(is_file("lib/lang/".$_SESSION["s"]["language"]."_".$this->formDef["name"].".lng")) {
+                        include_once("lib/lang/".$_SESSION["s"]["language"]."_".$this->formDef["name"].".lng");
+					}
+                } else {
+					if(is_file("../$module/lib/lang/".$_SESSION["s"]["language"]."_".$this->formDef["name"].".lng")) {
+                        include_once("../$module/lib/lang/".$_SESSION["s"]["language"]."_".$this->formDef["name"].".lng");
+					}
+                }
+                $this->wordbook = $wb;
+
+                return true;
+        }
+
+
+        /**
+        * Konvertiert die Daten des übergebenen assoziativen
+        * Arrays in "menschenlesbare" Form.
+        * Datentyp Konvertierung, z.B. für Ausgabe in Listen.
+        *
+        * @param record
+        * @return record
+        */
+        function decode($record,$tab) {
+                if(!is_array($this->formDef['tabs'][$tab])) $app->error("Tab ist leer oder existiert nicht (TAB: $tab).");
+                $new_record = '';
+				if(is_array($record)) {
+                        foreach($this->formDef['tabs'][$tab]['fields'] as $key => $field) {
+                                switch ($field['datatype']) {
+                                case 'VARCHAR':
+                                        $new_record[$key] = stripslashes($record[$key]);
+                                break;
+
+                                case 'TEXT':
+                                        $new_record[$key] = stripslashes($record[$key]);
+                                break;
+
+                                case 'DATE':
+                                        if($record[$key] > 0) {
+                                                $new_record[$key] = date($this->dateformat,$record[$key]);
+                                        }
+                                break;
+
+                                case 'INTEGER':
+                                        $new_record[$key] = intval($record[$key]);
+                                break;
+
+                                case 'DOUBLE':
+                                        $new_record[$key] = $record[$key];
+                                break;
+
+                                case 'CURRENCY':
+                                        $new_record[$key] = number_format($record[$key], 2, ',', '');
+                                break;
+
+                                default:
+                                        $new_record[$key] = stripslashes($record[$key]);
+                                }
+                        }
+
+                }
+				
+        return $new_record;
+        }
+
+        /**
+        * Get the key => value array of a form filed from a datasource definitiom
+        *
+        * @param field = array with field definition
+        * @param record = Dataset as array
+        * @return key => value array for the value field of a form
+        */
+
+        function getDatasourceData($field, $record) {
+                global $app;
+
+                $values = array();
+
+                if($field["datasource"]["type"] == 'SQL') {
+
+                        // Preparing SQL string. We will replace some
+                        // common placeholders
+                        $querystring = $field["datasource"]["querystring"];
+                        $querystring = str_replace("{USERID}",$_SESSION["s"]["user"]["userid"],$querystring);
+                        $querystring = str_replace("{GROUPID}",$_SESSION["s"]["user"]["default_group"],$querystring);
+                        $querystring = str_replace("{GROUPS}",$_SESSION["s"]["user"]["groups"],$querystring);
+                        $table_idx = $this->formDef['db_table_idx'];
+						
+						$tmp_recordid = (isset($record[$table_idx]))?$record[$table_idx]:0;
+                        $querystring = str_replace("{RECORDID}",$tmp_recordid,$querystring);
+						unset($tmp_recordid);
+						
+                        $querystring = str_replace("{AUTHSQL}",$this->getAuthSQL('r'),$querystring);
+
+                        // Getting the records
+                        $tmp_records = $app->db->queryAllRecords($querystring);
+                        if($app->db->errorMessage != '') die($app->db->errorMessage);
+                        if(is_array($tmp_records)) {
+                                $key_field = $field["datasource"]["keyfield"];
+                                $value_field = $field["datasource"]["valuefield"];
+                                foreach($tmp_records as $tmp_rec) {
+                                        $tmp_id = $tmp_rec[$key_field];
+                                        $values[$tmp_id] = $tmp_rec[$value_field];
+                                }
+                        }
+                }
+
+                if($field["datasource"]["type"] == 'CUSTOM') {
+                        // Calls a custom class to validate this record
+                        if($field["datasource"]['class'] != '' and $field["datasource"]['function'] != '') {
+                                $datasource_class = $field["datasource"]['class'];
+                                $datasource_function = $field["datasource"]['function'];
+                                $app->uses($datasource_class);
+                                $values = $app->$datasource_class->$datasource_function($field, $record);
+                        } else {
+                                $this->errorMessage .= "Custom datasource class or function is empty<br>\r\n";
+                        }
+                }
+
+                return $values;
+
+        }
+
+
+        /**
+        * Record für Ausgabe in Formularen vorbereiten.
+        *
+        * @param record = Datensatz als Array
+        * @param action = NEW oder EDIT
+        * @return record
+        */
+        function getHTML($record, $tab, $action = 'NEW') {
+
+                global $app;
+
+                $this->action = $action;
+
+                if(!is_array($this->formDef)) $app->error("Keine Formdefinition vorhanden.");
+                if(!is_array($this->formDef['tabs'][$tab])) $app->error("Tab ist leer oder existiert nicht (TAB: $tab).");
+
+                $new_record = array();
+                if($action == 'EDIT') {
+                        $record = $this->decode($record,$tab);
+                        if(is_array($record)) {
+                                foreach($this->formDef['tabs'][$tab]['fields'] as $key => $field) {
+                                        $val = $record[$key];
+
+                                        // If Datasource is set, get the data from there
+                                        if(isset($field['datasource']) && is_array($field['datasource'])) {
+                                                $field["value"] = $this->getDatasourceData($field, $record);
+                                        }
+
+                                        switch ($field['formtype']) {
+                                        case 'SELECT':
+												$out = '';
+                                                if(is_array($field['value'])) {
+                                                        foreach($field['value'] as $k => $v) {
+                                                                $selected = ($k == $val)?' SELECTED':'';
+                                                                $out .= "<option value='$k'$selected>$v</option>\r\n";
+                                                        }
+                                                }
+                                                $new_record[$key] = $out;
+                                        break;
+                                        case 'MULTIPLE':
+                                                if(is_array($field['value'])) {
+
+                                                        // aufsplitten ergebnisse
+                                                        $vals = explode($field['separator'],$val);
+
+                                                        // HTML schreiben
+                                                        $out = '';
+                                                        foreach($field['value'] as $k => $v) {
+
+                                                                $selected = '';
+                                                                foreach($vals as $tvl) {
+                                                                        if(trim($tvl) == trim($k)) $selected = ' SELECTED';
+                                                                }
+
+                                                                $out .= "<option value='$k'$selected>$v</option>\r\n";
+                                                        }
+                                                }
+                                                $new_record[$key] = $out;
+                                        break;
+
+                                        case 'PASSWORD':
+                                                $new_record[$key] = '';
+                                        break;
+
+                                        case 'CHECKBOX':
+                                                $checked = ($val == $field['value'][1])?' CHECKED':'';
+                                                $new_record[$key] = "<input name=\"".$key."\" type=\"checkbox\" value=\"".$field['value'][1]."\" $checked>\r\n";
+                                        break;
+
+                                        case 'CHECKBOXARRAY':
+                                                if(is_array($field['value'])) {
+
+                                                        // aufsplitten ergebnisse
+                                                        $vals = explode($field['separator'],$val);
+
+                                                        // HTML schreiben
+                                                        $out = '';
+                                                        foreach($field['value'] as $k => $v) {
+
+                                                                $checked = '';
+                                                                foreach($vals as $tvl) {
+                                                                        if(trim($tvl) == trim($k)) $checked = ' CHECKED';
+                                                                }
+                                                                $out .= "<span class=\"wf_oneChoice\">\r\n
+                                                                <input type=\"checkbox\" value=\"$k\" id=\"".$key."[]\" name=\"".$key."[]\" $checked>\r\n
+                                                                <label for=\"".$key."[]\" id=\"".$key."[]-L\" class=\"wf_postField\">$v</label>\r\n
+                                                                </span><br />\r\n";
+                                                        }
+                                                }
+                                                $new_record[$key] = $out;
+                                        break;
+
+                                        case 'RADIO':
+                                                if(is_array($field['value'])) {
+
+                                                        // HTML schreiben
+                                                        $out = '';
+                                                        foreach($field['value'] as $k => $v) {
+                                                                $checked = ($k == $val)?' CHECKED':'';
+                                                                $out .= "<span class=\"wf_oneChoice\">\r\n
+                                                                <input type=\"radio\" value=\"$k\" id=\"".$key."[]\" name=\"".$key."[]\" $checked>\r\n
+                                                                <label for=\"".$key."[]\" id=\"".$key."[]-L\" class=\"wf_postField\">$v</label>\r\n
+                                                                </span><br />\r\n";
+                                                        }
+                                                }
+                                                $new_record[$key] = $out;
+                                        break;
+
+                                        default:
+                                                $new_record[$key] = htmlspecialchars($record[$key]);
+                                        }
+                                }
+                        }
+                } else {
+                        // Action: NEW
+                        foreach($this->formDef['tabs'][$tab]['fields'] as $key => $field) {
+
+                                // If Datasource is set, get the data from there
+                                if(@is_array($field['datasource'])) {
+                                        $field["value"] = $this->getDatasourceData($field, $record);
+                                }
+
+                                switch ($field['formtype']) {
+                                case 'SELECT':
+                                        if(is_array($field['value'])) {
+                                                $out = '';
+                                                foreach($field['value'] as $k => $v) {
+                                                    //$selected = ($k == $val)?' SELECTED':'';
+													$selected = '';
+                                                    $out .= "<option value='$k'$selected>$v</option>\r\n";
+                                                }
+                                        }
+                                        if(isset($out)) $new_record[$key] = $out;
+                                break;
+                                case 'MULTIPLE':
+                                                if(is_array($field['value'])) {
+
+                                                        // aufsplitten ergebnisse
+                                                        $vals = explode($field['separator'],$val);
+
+                                                        // HTML schreiben
+                                                        $out = '';
+                                                        foreach($field['value'] as $k => $v) {
+
+                                                                $out .= "<option value='$k'>$v</option>\r\n";
+                                                        }
+                                                }
+                                                $new_record[$key] = $out;
+                                        break;
+
+                                case 'PASSWORD':
+                                        $new_record[$key] = '';
+                                break;
+
+                                case 'CHECKBOX':
+                                        // $checked = (empty($field["default"]))?'':' CHECKED';
+										                    $checked = ($field["default"] == $field['value'][1])?' CHECKED':'';
+                                        $new_record[$key] = "<input name=\"".$key."\" type=\"checkbox\" value=\"".$field['value'][1]."\" $checked>\r\n";
+                                break;
+
+                                case 'CHECKBOXARRAY':
+                                        if(is_array($field['value'])) {
+
+                                                // aufsplitten ergebnisse
+                                                $vals = explode($field['separator'],$field["default"]);
+
+                                                // HTML schreiben
+                                                $out = '';
+                                                foreach($field['value'] as $k => $v) {
+
+                                                        $checked = '';
+                                                        foreach($vals as $tvl) {
+                                                                if(trim($tvl) == trim($k)) $checked = ' CHECKED';
+                                                        }
+                                                        $out .= "<span class=\"wf_oneChoice\">\r\n
+                                                        <input type=\"checkbox\" value=\"$k\" id=\"".$key."[]\" name=\"".$key."[]\" $checked>\r\n
+                                                        <label for=\"".$key."[]\" id=\"".$key."[]-L\" class=\"wf_postField\">$v</label>\r\n
+                                                        </span><br />\r\n";
+                                                }
+                                        }
+                                        $new_record[$key] = $out;
+                                break;
+
+                                case 'RADIO':
+                                        if(is_array($field['value'])) {
+
+                                                // HTML schreiben
+                                                $out = '';
+                                                foreach($field['value'] as $k => $v) {
+                                                        $checked = ($k == $field["default"])?' CHECKED':'';
+                                                        $out .= "<span class=\"wf_oneChoice\">\r\n
+                                                        <input type=\"radio\" value=\"$k\" id=\"".$key."[]\" name=\"".$key."[]\" $checked>\r\n
+                                                        <label for=\"".$key."[]\" id=\"".$key."[]-L\" class=\"wf_postField\">$v</label>\r\n
+                                                        </span><br />\r\n";
+                                                }
+                                        }
+                                        $new_record[$key] = $out;
+                                break;
+
+                                default:
+                                        $new_record[$key] = htmlspecialchars($field['default']);
+                                }
+                        }
+
+                }
+
+                if($this->debug == 1) $this->dbg($new_record);
+
+                return $new_record;
+        }
+
+        /**
+        * Record in "maschinen lesbares" Format überführen
+        * und Werte gegen reguläre Ausdrücke prüfen.
+        *
+        * @param record = Datensatz als Array
+        * @return record
+        */
+        function encode($record,$tab) {
+			global $app;
+			
+                if(!is_array($this->formDef['tabs'][$tab])) $app->error("Tab ist leer oder existiert nicht (TAB: $tab).");
+                //$this->errorMessage = '';
+
+                if(is_array($record)) {
+                        foreach($this->formDef['tabs'][$tab]['fields'] as $key => $field) {
+
+                                if(isset($field['validators']) && is_array($field['validators'])) $this->validateField($key, (isset($record[$key]))?$record[$key]:'', $field['validators']);
+
+                                switch ($field['datatype']) {
+                                case 'VARCHAR':
+                                        if(!@is_array($record[$key])) {
+                                                $new_record[$key] = (isset($record[$key]))?$app->db->quote($record[$key]):'';
+                                        } else {
+                                                $new_record[$key] = implode($field['separator'],$record[$key]);
+                                        }
+                                break;
+                                case 'TEXT':
+                                        if(!is_array($record[$key])) {
+                                                $new_record[$key] = $app->db->quote($record[$key]);
+                                        } else {
+                                                $new_record[$key] = implode($field['separator'],$record[$key]);
+                                        }
+                                break;
+                                case 'DATE':
+                                        if($record[$key] > 0) {
+                                                list($tag,$monat,$jahr) = explode('.',$record[$key]);
+                                                $new_record[$key] = mktime(0,0,0,$monat,$tag,$jahr);
+                                        } else {
+											$new_record[$key] = 0;
+										}
+                                break;
+                                case 'INTEGER':
+                                        $new_record[$key] = (isset($record[$key]))?intval($record[$key]):0;
+                                        //if($new_record[$key] != $record[$key]) $new_record[$key] = $field['default'];
+                                        //if($key == 'refresh') die($record[$key]);
+                                break;
+                                case 'DOUBLE':
+                                        $new_record[$key] = $app->db->quote($record[$key]);
+                                break;
+                                case 'CURRENCY':
+                                        $new_record[$key] = str_replace(",",".",$record[$key]);
+                                break;
+                                }
+
+                                // The use of the field value is deprecated, use validators instead
+                                if(isset($field['regex']) && $field['regex'] != '') {
+                                        // Enable that "." matches also newlines
+                                        $field['regex'] .= 's';
+                                        if(!preg_match($field['regex'], $record[$key])) {
+                                                $errmsg = $field['errmsg'];
+                                                $this->errorMessage .= $this->wordbook[$errmsg]."<br>\r\n";
+                                        }
+                                }
+
+
+                        }
+                }
+                return $new_record;
+        }
+
+        /**
+        * process the validators for a given field.
+        *
+        * @param field_name = Name of the field
+        * @param field_value = value of the field
+        * @param validatoors = Array of validators
+        * @return record
+        */
+
+        function validateField($field_name, $field_value, $validators) {
+
+                global $app;
+				
+				$escape = '`';
+				
+                // loop trough the validators
+                foreach($validators as $validator) {
+
+                        switch ($validator['type']) {
+                                case 'REGEX':
+                                        $validator['regex'] .= 's';
+                                        if(!preg_match($validator['regex'], $field_value)) {
+                                                $errmsg = $validator['errmsg'];
+                                                if(isset($this->wordbook[$errmsg])) {
+                                                	$this->errorMessage .= $this->wordbook[$errmsg]."<br>\r\n";
+												} else {
+													$this->errorMessage .= $errmsg."<br>\r\n";
+												}
+                                        }
+                                break;
+                                case 'UNIQUE':
+                                        if($this->action == 'NEW') {
+                                                $num_rec = $app->db->queryOneRecord("SELECT count(*) as number FROM ".$escape.$this->formDef['db_table'].$escape. " WHERE $field_name = '".$app->db->quote($field_value)."'");
+                                                if($num_rec["number"] > 0) {
+                                                        $errmsg = $validator['errmsg'];
+														if(isset($this->wordbook[$errmsg])) {
+                                                        	$this->errorMessage .= $this->wordbook[$errmsg]."<br>\r\n";
+														} else {
+															$this->errorMessage .= $errmsg."<br>\r\n";
+														}
+                                                }
+                                        } else {
+                                                $num_rec = $app->db->queryOneRecord("SELECT count(*) as number FROM ".$escape.$this->formDef['db_table'].$escape. " WHERE $field_name = '".$app->db->quote($field_value)."' AND ".$this->formDef['db_table_idx']." != ".$this->primary_id);
+                                                if($num_rec["number"] > 0) {
+                                                        $errmsg = $validator['errmsg'];
+                                                        if(isset($this->wordbook[$errmsg])) {
+                                                        	$this->errorMessage .= $this->wordbook[$errmsg]."<br>\r\n";
+														} else {
+															$this->errorMessage .= $errmsg."<br>\r\n";
+														}
+                                                }
+                                        }
+                                break;
+                                case 'NOTEMPTY':
+                                        if(empty($field_value)) {
+                                                $errmsg = $validator['errmsg'];
+                                                if(isset($this->wordbook[$errmsg])) {
+                                                    $this->errorMessage .= $this->wordbook[$errmsg]."<br>\r\n";
+												} else {
+													$this->errorMessage .= $errmsg."<br>\r\n";
+												}
+                                        }
+                                break;
+                                case 'ISEMAIL':
+                                        if(!preg_match("/^\w+[\w.-]*\w+@\w+[\w.-]*\w+\.[a-z]{2,10}$/i", $field_value)) {
+                                                $errmsg = $validator['errmsg'];
+                                                if(isset($this->wordbook[$errmsg])) {
+                                                    $this->errorMessage .= $this->wordbook[$errmsg]."<br>\r\n";
+												} else {
+													$this->errorMessage .= $errmsg."<br>\r\n";
+												}
+                                        }
+                                break;
+                                case 'ISINT':
+                                        $tmpval = intval($field_value);
+                                        if($tmpval === 0 and !empty($field_value)) {
+                                                $errmsg = $validator['errmsg'];
+                                                if(isset($this->wordbook[$errmsg])) {
+                                                    $this->errorMessage .= $this->wordbook[$errmsg]."<br>\r\n";
+												} else {
+													$this->errorMessage .= $errmsg."<br>\r\n";
+												}
+                                        }
+                                break;
+                                case 'ISPOSITIVE':
+                                        if(!is_numeric($field_value) || $field_value <= 0){
+                                          $errmsg = $validator['errmsg'];
+                                          if(isset($this->wordbook[$errmsg])) {
+                                             $this->errorMessage .= $this->wordbook[$errmsg]."<br>\r\n";
+										  } else {
+											 $this->errorMessage .= $errmsg."<br>\r\n";
+										  }
+                                        }
+                                break;
+                                case 'CUSTOM':
+                                        // Calls a custom class to validate this record
+                                        if($validator['class'] != '' and $validator['function'] != '') {
+                                                $validator_class = $validator['class'];
+                                                $validator_function = $validator['function'];
+                                                $app->uses($validator_class);
+                                                $this->errorMessage .= $app->$validator_class->$validator_function($field_name, $field_value, $validator);
+                                        } else {
+                                                $this->errorMessage .= "Custom validator class or function is empty<br>\r\n";
+                                        }
+                                break;
+								default:
+									$this->errorMessage .= "Unknown Validator: ".$validator['type'];
+								break;
+                        }
+
+
+                }
+
+                return true;
+        }
+
+        /**
+        * SQL Statement für Record erzeugen.
+        *
+        * @param record = Datensatz als Array
+        * @param action = INSERT oder UPDATE
+        * @param primary_id
+        * @return record
+        */
+        function getSQL($record, $tab, $action = 'INSERT', $primary_id = 0, $sql_ext_where = '') {
+
+                global $app;
+
+                // If there are no data records on the tab, return empty sql string
+                if(count($this->formDef['tabs'][$tab]['fields']) == 0) return '';
+
+                // checking permissions
+                if($this->formDef['auth'] == 'yes' && $_SESSION["s"]["user"]["typ"] != 'admin') {
+                        if($action == "INSERT") {
+                                if(!$this->checkPerm($primary_id,'i')) $this->errorMessage .= "Insert denied.<br>\r\n";
+                        } else {
+                                if(!$this->checkPerm($primary_id,'u')) $this->errorMessage .= "Update denied.<br>\r\n";
+                        }
+                }
+
+                $this->action = $action;
+                $this->primary_id = $primary_id;
+
+                $record = $this->encode($record,$tab);
+                $sql_insert_key = '';
+                $sql_insert_val = '';
+                $sql_update = '';
+
+                if(!is_array($this->formDef)) $app->error("Keine Formulardefinition vorhanden.");
+                if(!is_array($this->formDef['tabs'][$tab])) $app->error("Tab ist leer oder existiert nicht (TAB: $tab).");
+
+                // gehe durch alle Felder des Tabs
+                if(is_array($record)) {
+                foreach($this->formDef['tabs'][$tab]['fields'] as $key => $field) {
+                                // Wenn es kein leeres Passwortfeld ist
+                                if (!($field['formtype'] == 'PASSWORD' and $record[$key] == '')) {
+                                        // Erzeuge Insert oder Update Quelltext
+                                        if($action == "INSERT") {
+                                                if($field['formtype'] == 'PASSWORD') {
+                                                        $sql_insert_key .= "`$key`, ";
+                                                        if($field['encryption'] == 'CRYPT') {
+                                                                $salt="$1$";
+																for ($n=0;$n<11;$n++) {
+																	$salt.=chr(mt_rand(64,126));
+																}
+																$salt.="$";
+																// $salt = substr(md5(time()),0,2);
+																$record[$key] = crypt($record[$key],$salt);
+																$sql_insert_val .= "'".$app->db->quote($record[$key])."', ";
+														} elseif ($field['encryption'] == 'MYSQL') {
+																$sql_insert_val .= "PASSWORD('".$app->db->quote($record[$key])."'), ";
+														} elseif ($field['encryption'] == 'CLEARTEXT') {
+																$sql_insert_val .= "'".$app->db->quote($record[$key])."', ";
+                                                        } else {
+                                                                $record[$key] = md5($record[$key]);
+																$sql_insert_val .= "'".$app->db->quote($record[$key])."', ";
+                                                        }
+														
+                                                } elseif ($field['formtype'] == 'CHECKBOX') {
+                                                        $sql_insert_key .= "`$key`, ";
+														if($record[$key] == '') {
+															// if a checkbox is not set, we set it to the unchecked value
+															$sql_insert_val .= "'".$field['value'][0]."', ";
+															$record[$key] = $field['value'][0];
+														} else {
+															$sql_insert_val .= "'".$record[$key]."', ";
+														}
+                                                } else {
+                                                        $sql_insert_key .= "`$key`, ";
+                                                        $sql_insert_val .= "'".$record[$key]."', ";
+                                                }
+                                        } else {
+                                                if($field['formtype'] == 'PASSWORD') {
+														if(isset($field['encryption']) && $field['encryption'] == 'CRYPT') {
+                                                                $salt="$1$";
+																for ($n=0;$n<11;$n++) {
+																	$salt.=chr(mt_rand(64,126));
+																}
+																$salt.="$";
+																// $salt = substr(md5(time()),0,2);
+																$record[$key] = crypt($record[$key],$salt);
+																$sql_update .= "`$key` = '".$app->db->quote($record[$key])."', ";
+														} elseif (isset($field['encryption']) && $field['encryption'] == 'MYSQL') {
+																$sql_update .= "`$key` = PASSWORD('".$app->db->quote($record[$key])."'), ";
+														} elseif (isset($field['encryption']) && $field['encryption'] == 'CLEARTEXT') {
+																$sql_update .= "`$key` = '".$app->db->quote($record[$key])."', ";
+                                                        } else {
+                                                                $record[$key] = md5($record[$key]);
+																$sql_update .= "`$key` = '".$app->db->quote($record[$key])."', ";
+                                                        }
+                                                        
+                                                } elseif ($field['formtype'] == 'CHECKBOX') {
+														if($record[$key] == '') {
+															// if a checkbox is not set, we set it to the unchecked value
+															$sql_update .= "`$key` = '".$field['value'][0]."', ";
+															$record[$key] = $field['value'][0];
+														} else {
+															$sql_update .= "`$key` = '".$record[$key]."', ";
+														}
+                                                } else {
+                                                        $sql_update .= "`$key` = '".$record[$key]."', ";
+                                                }
+                                        }
+                                } else {
+									// we unset the password filed, if empty to tell the datalog function 
+									// that the password has not been changed
+								    unset($record[$key]);
+								}
+                        }
+        }
+
+
+                // Füge Backticks nur bei unvollständigen Tabellennamen ein
+                if(stristr($this->formDef['db_table'],'.')) {
+                        $escape = '';
+                } else {
+                        $escape = '`';
+                }
+
+
+                if($action == "INSERT") {
+                        if($this->formDef['auth'] == 'yes') {
+                                // Setze User und Gruppe
+                                $sql_insert_key .= "`sys_userid`, ";
+                                $sql_insert_val .= ($this->formDef["auth_preset"]["userid"] > 0)?"'".$this->formDef["auth_preset"]["userid"]."', ":"'".$_SESSION["s"]["user"]["userid"]."', ";
+                                $sql_insert_key .= "`sys_groupid`, ";
+                                $sql_insert_val .= ($this->formDef["auth_preset"]["groupid"] > 0)?"'".$this->formDef["auth_preset"]["groupid"]."', ":"'".$_SESSION["s"]["user"]["default_group"]."', ";
+                                $sql_insert_key .= "`sys_perm_user`, ";
+                                $sql_insert_val .= "'".$this->formDef["auth_preset"]["perm_user"]."', ";
+                                $sql_insert_key .= "`sys_perm_group`, ";
+                                $sql_insert_val .= "'".$this->formDef["auth_preset"]["perm_group"]."', ";
+                                $sql_insert_key .= "`sys_perm_other`, ";
+                                $sql_insert_val .= "'".$this->formDef["auth_preset"]["perm_other"]."', ";
+                        }
+                        $sql_insert_key = substr($sql_insert_key,0,-2);
+                        $sql_insert_val = substr($sql_insert_val,0,-2);
+                        $sql = "INSERT INTO ".$escape.$this->formDef['db_table'].$escape." ($sql_insert_key) VALUES ($sql_insert_val)";
+                } else {
+                        if($primary_id != 0) {
+                                $sql_update = substr($sql_update,0,-2);
+                                $sql = "UPDATE ".$escape.$this->formDef['db_table'].$escape." SET ".$sql_update." WHERE ".$this->getAuthSQL('u')." AND ".$this->formDef['db_table_idx']." = ".$primary_id;
+                                if($sql_ext_where != '') $sql .= " and ".$sql_ext_where;
+                        } else {
+                                $app->error("Primary ID fehlt!");
+                        }
+                }
+                
+                return $sql;
+        }
+
+        /**
+        * Debugging arrays.
+        *
+        * @param array_data
+        */
+        function dbg($array_data) {
+
+                echo "<pre>";
+                print_r($array_data);
+                echo "</pre>";
+
+        }
+
+
+    function showForm() {
+            global $app,$conf;
+
+        if(!is_array($this->formDef)) die("Form Definition wurde nicht geladen.");
+
+                $active_tab = $this->getNextTab();
+
+        // definiere Tabs
+        foreach( $this->formDef["tabs"] as $key => $tab) {
+
+            $tab['name'] = $key;
+            if($tab['name'] == $active_tab) {
+
+                // Wenn Modul gesetzt, dann setzte template pfad relativ zu modul.
+                if($this->module != '') $tab["template"] = "../".$this->module."/".$tab["template"];
+
+                // überprüfe, ob das Template existiert, wenn nicht
+                // dann generiere das Template
+				
+				// Translate the title of the tab
+				$tab['title'] = $this->lng($tab['title']);
+								
+                if(!is_file($tab["template"])) {
+                     $app->uses('tform_tpl_generator');
+                     $app->tform_tpl_generator->buildHTML($this->formDef,$tab['name']);
+                }
+
+                $app->tpl->setInclude('content_tpl',$tab["template"]);
+                $tab["active"] = 1;
+                $_SESSION["s"]["form"]["tab"] = $tab['name'];
+            } else {
+                    $tab["active"] = 0;
+            }
+
+                        // Die Datenfelder werden für die Tabs nicht benötigt
+                        unset($tab["fields"]);
+                        unset($tab["plugins"]);
+
+            $frmTab[] = $tab;
+        }
+
+        // setting form tabs
+        $app->tpl->setLoop("formTab", $frmTab);
+
+                // Set form action
+                $app->tpl->setVar('form_action',$this->formDef["action"]);
+                $app->tpl->setVar('form_active_tab',$active_tab);
+
+                // Set form title
+                $form_hint = $this->lng($this->formDef["title"]);
+                if($this->formDef["description"] != '') $form_hint .= '<div class="pageForm_description">'.$this->lng($this->formDef["description"]).'</div>';
+                $app->tpl->setVar('form_hint',$form_hint);
+
+                // Set Wordbook for this form
+
+                $app->tpl->setVar($this->wordbook);
+    	}
+
+		function getDataRecord($primary_id) {
+			global $app;
+			$escape = '`';
+			$sql = "SELECT * FROM ".$escape.$this->formDef['db_table'].$escape." WHERE ".$this->formDef['db_table_idx']." = ".$primary_id;
+            return $app->db->queryOneRecord($sql);
+		}
+		
+
+        function datalogSave($action,$primary_id, $record_old, $record_new) {
+                global $app,$conf;
+
+                // Füge Backticks nur bei unvollständigen Tabellennamen ein
+                if(stristr($this->formDef['db_table'],'.')) {
+                        $escape = '';
+                } else {
+                        $escape = '`';
+                }
+
+                $diffrec = array();
+				
+                if(is_array($record_new) && count($record_new) > 0) {
+                        foreach($record_new as $key => $val) {
+                                if(@$record_old[$key] != $val) {
+										// Record has changed
+                                        $diffrec[$key] = array('old' => @$record_old[$key],
+                                                               'new' => $val);
+                                }
+                        }
+                } elseif(is_array($record_old)) {
+                        foreach($record_old as $key => $val) {
+                                if($record_new[$key] != $val) {
+										// Record has changed
+                                        $diffrec[$key] = array('new' => $record_new[$key],
+                                                               'old' => $val);
+                                }
+                        }
+                }
+				$this->diffrec = $diffrec;
+				
+				
+				// Full diff records for ISPConfig, they have a different format then the simple diffrec
+				$diffrec_full = array();
+
+                if(is_array($record_old) && count($record_old) > 0) {
+                        foreach($record_old as $key => $val) {
+                                //if(isset($record_new[$key]) && $record_new[$key] != $val) {
+								if(!isset($record_new[$key]) || $record_new[$key] != $val) {
+                                    // Record has changed
+									$diffrec_full['old'][$key] = $val;
+									$diffrec_full['new'][$key] = $record_new[$key];
+                                } else {
+									$diffrec_full['old'][$key] = $val;
+									$diffrec_full['new'][$key] = $val;
+								}
+                        }
+                } elseif(is_array($record_new)) {
+                        foreach($record_new as $key => $val) {
+                                if(isset($record_new[$key]) && $record_old[$key] != $val) {
+                                    // Record has changed
+									$diffrec_full['new'][$key] = $val;
+									$diffrec_full['old'][$key] = $record_old[$key];
+                                } else {
+									$diffrec_full['new'][$key] = $val;
+									$diffrec_full['old'][$key] = $val;
+								}
+                        }
+                }
+				
+				// Insert the server_id, if the record has a server_id
+				$server_id = (isset($record_old["server_id"]) && $record_old["server_id"] > 0)?$record_old["server_id"]:0;
+				if(isset($record_new["server_id"])) $server_id = $record_new["server_id"];
+
+                if(count($this->diffrec) > 0) {
+						$diffstr = $app->db->quote(serialize($diffrec_full));
+                        $username = $app->db->quote($_SESSION["s"]["user"]["username"]);
+                        $dbidx = $this->formDef['db_table_idx'].":".$primary_id;
+                        // $action = ($action == 'INSERT')?'i':'u';
+						
+						if($action == 'INSERT') $action = 'i';
+						if($action == 'UPDATE') $action = 'u';
+						if($action == 'DELETE') $action = 'd';
+                        $sql = "INSERT INTO sys_datalog (dbtable,dbidx,server_id,action,tstamp,user,data) VALUES ('".$this->formDef['db_table']."','$dbidx','$server_id','$action','".time()."','$username','$diffstr')";
+						$app->db->query($sql);
+                }
+
+                return true;
+
+        }
+
+        function getAuthSQL($perm) {
+				if($_SESSION["s"]["user"]["typ"] == 'admin') {
+					return '1';
+				} else {
+                	$groups = ( $_SESSION["s"]["user"]["groups"] ) ? $_SESSION["s"]["user"]["groups"] : 0;
+					$sql = '(';
+                	$sql .= "(sys_userid = ".$_SESSION["s"]["user"]["userid"]." AND sys_perm_user like '%$perm%') OR  ";
+                	$sql .= "(sys_groupid IN (".$groups.") AND sys_perm_group like '%$perm%') OR ";
+                	$sql .= "sys_perm_other like '%$perm%'";
+                	$sql .= ')';
+
+                	return $sql;
+				}
+        }
+
+        /*
+        Diese funktion überprüft, ob ein User die Berechtigung $perm für den Datensatz mit der ID $record_id
+        hat. It record_id = 0, dann wird gegen die user Defaults des Formulares getestet.
+        */
+        function checkPerm($record_id,$perm) {
+                global $app;
+
+                if($record_id > 0) {
+                        // Füge Backticks nur bei unvollständigen Tabellennamen ein
+                        if(stristr($this->formDef['db_table'],'.')) {
+                                $escape = '';
+                        } else {
+                                $escape = '`';
+                        }
+
+                        $sql = "SELECT ".$this->formDef['db_table_idx']." FROM ".$escape.$this->formDef['db_table'].$escape." WHERE ".$this->formDef['db_table_idx']." = ".$record_id." AND ".$this->getAuthSQL($perm);
+                        if($record = $app->db->queryOneRecord($sql)) {
+                                return true;
+                        } else {
+                                return false;
+                        }
+                } else {
+                        $result = false;
+                        if(@$this->formDef["auth_preset"]["userid"] == $_SESSION["s"]["user"]["userid"] && stristr($perm,$this->formDef["auth_preset"]["perm_user"])) $result = true;
+                        if(@$this->formDef["auth_preset"]["groupid"] == $_SESSION["s"]["user"]["groupid"] && stristr($perm,$this->formDef["auth_preset"]["perm_group"])) $result = true;
+                        if(@stristr($this->formDef["auth_preset"]["perm_other"],$perm)) $result = true;
+
+                        // if preset == 0, everyone can insert a record of this type
+                        if($this->formDef["auth_preset"]["userid"] == 0 AND $this->formDef["auth_preset"]["groupid"] == 0 AND (@stristr($this->formDef["auth_preset"]["perm_user"],$perm) OR @stristr($this->formDef["auth_preset"]["perm_group"],$perm))) $result = true;
+
+                        return $result;
+
+                }
+
+        }
+
+        function getNextTab() {
+                // Welcher Tab wird angezeigt
+                if($this->errorMessage == '') {
+                    // wenn kein Fehler vorliegt
+                    if(isset($_REQUEST["next_tab"]) && $_REQUEST["next_tab"] != '') {
+                                // wenn nächster Tab bekannt
+                                $active_tab = $_REQUEST["next_tab"];
+                    } else {
+                        // ansonsten ersten tab nehmen
+                        $active_tab = $this->formDef['tab_default'];
+                    }
+                } else {
+                    // bei Fehlern den gleichen Tab nochmal anzeigen
+                    $active_tab = $_SESSION["s"]["form"]["tab"];
+                }
+
+                return $active_tab;
+        }
+
+        function getCurrentTab() {
+                return $_SESSION["s"]["form"]["tab"];
+        }
+		
+		function isReadonlyTab($tab) {
+			if(isset($this->formDef['tabs'][$tab]['readonly']) && $this->formDef['tabs'][$tab]['readonly'] == true) {
+				return true;
+			} else {
+				return false;
+			}
+        }
+		
+		
+		// translation function for forms, tries the form wordbook first and if this fails, it tries the global wordbook
+		function lng($msg) {
+			global $app;
+			
+			if(isset($this->wordbook[$msg])) {
+				return $this->wordbook[$msg];
+			} else {
+				return $app->lng($msg);
+			}
+			
+		}
+
+}
+
 ?>
\ No newline at end of file
diff --git a/interface/lib/classes/tform_actions.inc.php b/interface/lib/classes/tform_actions.inc.php
index 812c792965f42d2b4a71f92277a3b3b6d42b1cdb..c5b6db99e82c9d46e3e3291b859429e5ec339063 100644
--- a/interface/lib/classes/tform_actions.inc.php
+++ b/interface/lib/classes/tform_actions.inc.php
@@ -1,580 +1,580 @@
-<?php
-
-/*
-Copyright (c) 2005, Till Brehm, projektfarm Gmbh
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
-      and/or other materials provided with the distribution.
-    * Neither the name of ISPConfig nor the names of its contributors
-      may be used to endorse or promote products derived from this software without
-      specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/**
-* Action framework for the tform library.
-*
-* @author Till Brehm <t.brehm@scrigo.org>
-* @copyright Copyright &copy; 2005, Till Brehm
-*/
-
-class tform_actions {
-
-        var $id;
-        var $activeTab;
-        var $dataRecord;
-        var $plugins = array();
-		var $oldDataRecord; // This array is only filled during updates and when db_history is enabled.
-
-        function onLoad() {
-                global $app, $conf, $tform_def_file;
-
-                // Loading template classes and initialize template
-                if(!is_object($app->tpl)) $app->uses('tpl');
-                if(!is_object($app->tform)) $app->uses('tform');
-
-                $app->tpl->newTemplate("tabbed_form.tpl.htm");
-
-                // Load table definition from file
-                $app->tform->loadFormDef($tform_def_file);
-				
-				// Importing ID
-                $this->id = (isset($_REQUEST["id"]))?intval($_REQUEST["id"]):0;
-				
-				// show print version of the form
-				if(isset($_GET["print_form"]) && $_GET["print_form"] == 1) {
-					die('Function disabled.');
-					$this->onPrintForm();
-				}
-				
-				// send this form by email
-				if(isset($_GET["send_form_by_mail"]) && $_GET["send_form_by_mail"] == 1) {
-					die('Function disabled.');
-					$this->onMailSendForm();
-				}
-
-                if(count($_POST) > 1) {
-                        $this->dataRecord = $_POST;
-                        $this->onSubmit();
-                } else {
-                        $this->onShow();
-                }
-        }
-
-        /**
-        * Function called on page submit
-        */
-
-        function onSubmit() {
-                global $app, $conf;
-
-                // Calling the action functions
-                if($this->id > 0) {
-                        $this->onUpdate();
-                } else {
-                        $this->onInsert();
-                }
-        }
-
-        /**
-        * Function called on data update
-        */
-
-        function onUpdate() {
-                global $app, $conf;
-				
-				$this->onBeforeUpdate();
-				
-                $ext_where = '';
-                $sql = $app->tform->getSQL($this->dataRecord,$app->tform->getCurrentTab(),'UPDATE',$this->id,$ext_where);
-                if($app->tform->errorMessage == '') {
-						
-						if($app->tform->formDef['db_history'] == 'yes') {
-							$this->oldDataRecord = $app->tform->getDataRecord($this->id);
-						}
-						
-						// Save record in database
-						$this->onUpdateSave($sql);
-						
-						// loading plugins
-						$next_tab = $app->tform->getCurrentTab();
-                		$this->loadPlugins($next_tab);
-
-                        // Call plugin
-                        foreach($this->plugins as $plugin) {
-                                $plugin->onInsert();
-                        }
-
-                        $this->onAfterUpdate();
-						
-						// Write data history (sys_datalog)
-						if($app->tform->formDef['db_history'] == 'yes') {
-							$new_data_record = $app->tform->getDataRecord($this->id);
-							$app->tform->datalogSave('UPDATE',$this->id,$this->oldDataRecord,$new_data_record);
-							unset($new_data_record);
-							unset($old_data_record);
-						}
-
-                        if($_REQUEST["next_tab"] == '') {
-                           $list_name = $_SESSION["s"]["form"]["return_to"];
-						   // When a list is embedded inside of a form
-						   
-                           //if($list_name != '' && $_SESSION["s"]["list"][$list_name]["parent_id"] != $this->id && $_SESSION["s"]["list"][$list_name]["parent_name"] != $app->tform->formDef["name"]) {
-						   if($list_name != '' && $_SESSION["s"]["list"][$list_name]["parent_name"] != $app->tform->formDef["name"]) {
-                                $redirect = "Location: ".$_SESSION["s"]["list"][$list_name]["parent_script"]."?id=".$_SESSION["s"]["list"][$list_name]["parent_id"]."&next_tab=".$_SESSION["s"]["list"][$list_name]["parent_tab"];
-                                $_SESSION["s"]["form"]["return_to"] = '';
-                                session_write_close();
-                                header($redirect);
-							// When a returnto variable is set
-							} elseif ($_SESSION["s"]["form"]["return_to_url"] != '') {
-								$redirect = $_SESSION["s"]["form"]["return_to_url"];
-								$_SESSION["s"]["form"]["return_to_url"] = '';
-								session_write_close();
-								header("Location: ".$redirect);
-								exit;
-								// Use the default list of the form
-                        	} else {
-                            	header("Location: ".$app->tform->formDef['list_default']);
-                        	}
-                        	exit;
-                    	} else {
-                                $this->onShow();
-                        }
-                } else {
-                        $this->onError();
-                }
-        }
-		
-		/*
-		 Save record in database
-		*/
-		
-		function onUpdateSave($sql) {
-			global $app;
-			if(!empty($sql) && !$app->tform->isReadonlyTab($app->tform->getCurrentTab())) {
-				$app->db->query($sql);
-				if($app->db->errorMessage != '') die($app->db->errorMessage);
-			}
-		}
-		
-
-        /**
-        * Function called on data insert
-        */
-
-        function onInsert() {
-                global $app, $conf;
-				
-				$this->onBeforeInsert();
-
-                $ext_where = '';
-                $sql = $app->tform->getSQL($this->dataRecord,$app->tform->getCurrentTab(),'INSERT',$this->id,$ext_where);
-                if($app->tform->errorMessage == '') {
-						
-						$this->id = $this->onInsertSave($sql);
-						
-						// loading plugins
-						$next_tab = $app->tform->getCurrentTab();
-                		$this->loadPlugins($next_tab);
-						
-                        // Call plugin
-                        foreach($this->plugins as $plugin) {
-                                $plugin->onInsert();
-                        }
-
-                        $this->onAfterInsert();
-						
-						// Write data history (sys_datalog)
-						if($app->tform->formDef['db_history'] == 'yes') {
-							$new_data_record = $app->tform->getDataRecord($this->id);
-							$app->tform->datalogSave('INSERT',$this->id,array(),$new_data_record);
-							unset($new_data_record);
-						}
-						
-
-                     if($_REQUEST["next_tab"] == '') {
-                         $list_name = $_SESSION["s"]["form"]["return_to"];
-                         // if($list_name != '' && $_SESSION["s"]["list"][$list_name]["parent_id"] != $this->id && $_SESSION["s"]["list"][$list_name]["parent_name"] != $app->tform->formDef["name"]) {
-						 if($list_name != '' && $_SESSION["s"]["list"][$list_name]["parent_name"] != $app->tform->formDef["name"]) {
-                            $redirect = "Location: ".$_SESSION["s"]["list"][$list_name]["parent_script"]."?id=".$_SESSION["s"]["list"][$list_name]["parent_id"]."&next_tab=".$_SESSION["s"]["list"][$list_name]["parent_tab"];
-                            $_SESSION["s"]["form"]["return_to"] = '';
-                            session_write_close();
-                            header($redirect);
-							exit;
-                        } elseif ($_SESSION["s"]["form"]["return_to_url"] != '') {
-							$_SESSION["s"]["form"]["return_to_url"] = '';
-							session_write_close();
-							header("Location: ".$_SESSION["s"]["form"]["return_to_url"]);
-							exit;
-						} else {
-                                header("Location: ".$app->tform->formDef['list_default']);
-                        }
-                        exit;
-                    } else {
-                            $this->onShow();
-                        }
-                } else {
-                        $this->onError();
-                }
-        }
-		
-		/*
-		 Save record in database
-		*/
-		
-		function onInsertSave($sql) {
-			global $app, $conf;
-			$app->db->query($sql);
-            if($app->db->errorMessage != '') die($app->db->errorMessage);
-            return $app->db->insertID();
-		}
-
-        function onBeforeUpdate() {
-            global $app, $conf;
-        }
-
-        function onBeforeInsert() {
-            global $app, $conf;
-        }
-		
-		function onAfterUpdate() {
-            global $app, $conf;
-        }
-
-        function onAfterInsert() {
-            global $app, $conf;
-        }
-
-
-        /**
-        * Function called on data insert or update error
-        */
-
-        function onError() {
-                global $app, $conf;
-
-                $app->tpl->setVar("error","<b>".$app->lng('Error').":</b><br>".$app->tform->errorMessage);
-                $app->tpl->setVar($this->dataRecord);
-                $this->onShow();
-        }
-
-        /**
-        * Function called on data delete
-        */
-
-        function onDelete() {
-                global $app, $conf,$list_def_file,$tform_def_file;
-
-                include_once($list_def_file);
-
-                // Loading tform framework
-                if(!is_object($app->tform)) $app->uses('tform');
-
-                // Load table definition from file
-                $app->tform->loadFormDef($tform_def_file);
-
-                // importing ID
-                $this->id = intval($_REQUEST["id"]);
-
-                if($this->id > 0) {
-
-                        // checking permissions
-                        if($app->tform->formDef['auth'] == 'yes' && $_SESSION["s"]["user"]["typ"] != 'admin') {
-                                if($app->tform->checkPerm($this->id,'d') == false) $app->error($app->lng('error_no_delete_permission'));
-                        }
-
-                        //$this->dataRecord = $app->db->queryOneRecord("SELECT * FROM ".$liste["table"]." WHERE ".$liste["table_idx"]." = ".$this->id);
-						$this->dataRecord = $app->tform->getDataRecord($this->id);
-						
-						$this->onBeforeDelete();
-
-                        // Saving record to datalog when db_history enabled
-                        if($app->tform->formDef["db_history"] == 'yes') {
-							//$old_data_record = $app->tform->getDataRecord($this->id);
-							$app->tform->datalogSave('DELETE',$this->id,$this->dataRecord,array());
-                        }
-
-                        $app->db->query("DELETE FROM ".$app->tform->formDef['db_table']." WHERE ".$app->tform->formDef['db_table_idx']." = ".$this->id." LIMIT 1");
-						
-						
-						// loading plugins
-						$next_tab = $app->tform->getCurrentTab();
-                		$this->loadPlugins($next_tab);
-						
-						
-                        // Call plugin
-                        foreach($this->plugins as $plugin) {
-                                $plugin->onDelete();
-                        }
-						
-						$this->onAfterDelete();
-                }
-
-                		//header("Location: ".$liste["file"]."?PHPSESSID=".$_SESSION["s"]["id"]);
-                 $list_name = $_SESSION["s"]["form"]["return_to"];
-                 if($list_name != '' && $_SESSION["s"]["list"][$list_name]["parent_id"] != $this->id && $_SESSION["s"]["list"][$list_name]["parent_name"] != $app->tform->formDef["name"]) {
-                        $redirect = "Location: ".$_SESSION["s"]["list"][$list_name]["parent_script"]."?id=".$_SESSION["s"]["list"][$list_name]["parent_id"]."&next_tab=".$_SESSION["s"]["list"][$list_name]["parent_tab"];
-                        $_SESSION["s"]["form"]["return_to"] = '';
-                        session_write_close();
-                        header($redirect);
-                } else {
-                    header("Location: ".$liste["file"]);
-                }
-                exit;
-
-        }
-		
-		function onBeforeDelete() {
-            global $app, $conf;
-        }
-		
-		function onAfterDelete() {
-            global $app, $conf;
-        }
-		
-		/**
-        * Function to print the form content
-        */
-		
-		function onPrintForm() {
-			global $app, $conf;
-			
-			if($app->tform->formDef['template_print'] == '') die('No print template available.');
-			
-			$app->tpl->newTemplate("print.tpl.htm");
-			$app->tpl->setInclude("content_tpl",$app->tform->formDef['template_print']);
-
-			if($app->tform->formDef['auth'] == 'no') {
-            	$sql = "SELECT * FROM ".$app->tform->formDef['db_table']." WHERE ".$app->tform->formDef['db_table_idx']." = ".$this->id;
-            } else {
-            	$sql = "SELECT * FROM ".$app->tform->formDef['db_table']." WHERE ".$app->tform->formDef['db_table_idx']." = ".$this->id." AND ".$app->tform->getAuthSQL('u');
-            }
-            if(!$record = $app->db->queryOneRecord($sql)) $app->error($app->lng('error_no_view_permission'));
-			
-			$record["datum"] = date("d.m.Y");
-			
-			$app->tpl->setVar($app->tform->wordbook);
-
-			$app->tpl->setVar($record);
-			$app->tpl_defaults();
-			$app->tpl->pparse();
-			exit;
-			
-		}
-		
-		/**
-        * Function to print the form content
-        */
-		
-		function onMailSendForm() {
-			global $app, $conf;
-			
-			if($app->tform->formDef['template_mailsend'] == '') die('No print template available.');
-			
-			if($_POST["email"] == '' && $_POST["sender"] == '') {
-				// Zeige Formular zum versenden an.
-				$app->tpl->newTemplate("form.tpl.htm");
-				$app->tpl->setInclude("content_tpl",$app->tform->formDef['template_mailsend']);
-				$app->tpl->setVar('show_form',1);
-				$app->tpl->setVar("form_action",$app->tform->formDef['action'].'?send_form_by_mail=1');
-				$app->tpl->setVar("id",$this->id);
-				$app->tpl_defaults();
-				$app->tpl->pparse();
-				exit;
-			} else {
-				$app->tpl->newTemplate("mail.tpl.htm");
-				$app->tpl->setInclude("content_tpl",$app->tform->formDef['template_mailsend']);
-				$app->tpl->setVar('show_mail',1);
-				if($app->tform->formDef['auth'] == 'no') {
-            		$sql = "SELECT * FROM ".$app->tform->formDef['db_table']." WHERE ".$app->tform->formDef['db_table_idx']." = ".$this->id;
-            	} else {
-            		$sql = "SELECT * FROM ".$app->tform->formDef['db_table']." WHERE ".$app->tform->formDef['db_table_idx']." = ".$this->id." AND ".$app->tform->getAuthSQL('u');
-            	}
-            	if(!$record = $app->db->queryOneRecord($sql)) $app->error($app->lng('error_no_view_permission'));
-			
-				$record["datum"] = date("d.m.Y");
-				$record["mailmessage"] = $_POST["message"];
-			
-				$app->tpl->setVar($app->tform->wordbook);
-
-				$app->tpl->setVar($record);
-				$app->tpl_defaults();
-				
-				$email_message = $app->tpl->grab();
-				$email = $_POST["email"];
-				$sender = $_POST["sender"];
-				
-				$headers  = "MIME-Version: 1.0\n";
-				$headers .= "Content-type: text/html; charset=iso-8859-1\n";
-				$headers .= "From: $sender\n";
-				
-				if (!ereg('^[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+' . '@' . '([-!#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\.)+' . '[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+$', $sender)) {
-    				$sender = 'noreply@iprguard.de';
-  				}
-				
-				if (ereg('^[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+' . '@' . '([-!#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\.)+' . '[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+$', $email)) {
-    				mail($email, 'Domainrecherche Statement '.$record["domain"], $email_message, $headers);
-  				}
-				echo "<p>&nbsp;</p><p>Email wurde versand.</p>";
-				exit;
-			}
-			
-			
-
-			if($app->tform->formDef['auth'] == 'no') {
-            	$sql = "SELECT * FROM ".$app->tform->formDef['db_table']." WHERE ".$app->tform->formDef['db_table_idx']." = ".$this->id;
-            } else {
-            	$sql = "SELECT * FROM ".$app->tform->formDef['db_table']." WHERE ".$app->tform->formDef['db_table_idx']." = ".$this->id." AND ".$app->tform->getAuthSQL('u');
-            }
-            if(!$record = $app->db->queryOneRecord($sql)) $app->error($app->lng('error_no_view_permission'));
-			
-			$record["datum"] = date("d.m.Y");
-			
-			$app->tpl->setVar($app->tform->wordbook);
-
-			$app->tpl->setVar($record);
-			$app->tpl_defaults();
-			$app->tpl->pparse();
-			exit;
-			
-		}
-
-        /**
-        * Function called on page show
-        */
-
-        function onShow() {
-                global $app, $conf;
-
-                // Which tab do we render
-                $this->active_tab = $app->tform->getNextTab();
-
-                if($this->id > 0) {
-                        $this->onShowEdit();
-                } else {
-                        $this->onShowNew();
-                }
-
-                // make Form and Tabs
-                $app->tform->showForm();
-
-                // Setting default values
-                $app->tpl_defaults();
-				
-				// Show the navigation bar of the form
-				if(isset($app->tform->formDef['navibar']) && $app->tform->formDef['navibar'] == 'yes') {
-					$navibar = '';
-					if($app->tform->formDef['template_print'] != '') {
-						$navibar .= '<a href="'.$app->tform->formDef['action'].'?id='.$this->id.'&print_form=1" target="_blank"><img src="../themes/iprg/icons/printer.png" border="0" alt="Drucken" /></a> &nbsp;';
-					}
-					if($app->tform->formDef['template_mailsend'] != '') {
-						$navibar .= "<a href=\"#\" onClick=\"window.open('".$app->tform->formDef['action'].'?id='.$this->id."&send_form_by_mail=1','send','width=370,height=240')\"><img src=\"../themes/iprg/icons/mail.png\" border=\"0\" alt=\"Als E-Mail versenden\" /></a>";
-					}
-					$app->tpl->setVar('form_navibar',$navibar);
-				}
-				
-				
-				// loading plugins
-                $this->loadPlugins($this->active_tab);
-
-                // Calling the Plugin onShow Events and set the data in the
-                // plugins placeholder in the template
-                foreach($this->plugins as $plugin_name => $plugin) {
-                        $app->tpl->setVar($plugin_name,$plugin->onShow());
-                }
-
-                // Parse the templates and send output to the browser
-                $this->onShowEnd();
-
-        }
-
-        /**
-        * Function called on new record
-        */
-
-        function onShowNew() {
-                global $app, $conf;
-
-                if($app->tform->errorMessage == '') {
-                        $record = array();
-                        $record = $app->tform->getHTML($record, $app->tform->formDef['tab_default'],'NEW');
-                } else {
-                        $record = $app->tform->getHTML($app->tform->encode($_POST,$this->active_tab),$this->active_tab,'EDIT');
-                }
-
-                $app->tpl->setVar($record);
-        }
-
-        /**
-        * Function called on edit record
-        */
-
-        function onShowEdit() {
-                global $app, $conf;
-
-                // bestehenden Datensatz anzeigen
-                if($app->tform->errorMessage == '') {
-                        if($app->tform->formDef['auth'] == 'yes' && $_SESSION["s"]["user"]["typ"] != 'admin') {
-                        	$sql = "SELECT * FROM ".$app->tform->formDef['db_table']." WHERE ".$app->tform->formDef['db_table_idx']." = ".$this->id." AND ".$app->tform->getAuthSQL('u');
-                        } else {
-                        	$sql = "SELECT * FROM ".$app->tform->formDef['db_table']." WHERE ".$app->tform->formDef['db_table_idx']." = ".$this->id;
-                        }
-                        if(!$record = $app->db->queryOneRecord($sql)) $app->error($app->lng('error_no_view_permission'));
-                } else {
-                        // $record = $app->tform->encode($_POST,$this->active_tab);
-						$record = $app->tform->encode($this->dataRecord,$this->active_tab);
-                }
-
-                $this->dataRecord = $record;
-
-            	// Userdaten umwandeln
-                $record = $app->tform->getHTML($record, $this->active_tab,'EDIT');
-                $record['id'] = $this->id;
-
-                $app->tpl->setVar($record);
-        }
-
-        function onShowEnd() {
-                global $app, $conf;
-
-                // Template parsen
-                $app->tpl->pparse();
-        }
-		
-		function loadPlugins($next_tab) {
-			global $app;
-			if(@is_array($app->tform->formDef["tabs"][$next_tab]["plugins"])) {
-                 $app->load('plugin_base');
-                 foreach($app->tform->formDef["tabs"][$next_tab]["plugins"] as $plugin_name => $plugin_settings) {
-                      $plugin_class = $plugin_settings["class"];
-                      $app->load($plugin_class);
-                      $this->plugins[$plugin_name] = new $plugin_class;
-                      $this->plugins[$plugin_name]->setOptions($plugin_name,$plugin_settings['options']);
-					  // Make the data of the form easily accessible for the plugib
-					  $this->plugins[$plugin_name]->form = $this;
-                      $this->plugins[$plugin_name]->onLoad();
-                  }
-             }
-		}
-
-
-}
-
+<?php
+
+/*
+Copyright (c) 2005, Till Brehm, projektfarm Gmbh
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+    * Neither the name of ISPConfig nor the names of its contributors
+      may be used to endorse or promote products derived from this software without
+      specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/**
+* Action framework for the tform library.
+*
+* @author Till Brehm <t.brehm@scrigo.org>
+* @copyright Copyright &copy; 2005, Till Brehm
+*/
+
+class tform_actions {
+
+        var $id;
+        var $activeTab;
+        var $dataRecord;
+        var $plugins = array();
+		var $oldDataRecord; // This array is only filled during updates and when db_history is enabled.
+
+        function onLoad() {
+                global $app, $conf, $tform_def_file;
+
+                // Loading template classes and initialize template
+                if(!is_object($app->tpl)) $app->uses('tpl');
+                if(!is_object($app->tform)) $app->uses('tform');
+
+                $app->tpl->newTemplate("tabbed_form.tpl.htm");
+
+                // Load table definition from file
+                $app->tform->loadFormDef($tform_def_file);
+				
+				// Importing ID
+                $this->id = (isset($_REQUEST["id"]))?intval($_REQUEST["id"]):0;
+				
+				// show print version of the form
+				if(isset($_GET["print_form"]) && $_GET["print_form"] == 1) {
+					die('Function disabled.');
+					$this->onPrintForm();
+				}
+				
+				// send this form by email
+				if(isset($_GET["send_form_by_mail"]) && $_GET["send_form_by_mail"] == 1) {
+					die('Function disabled.');
+					$this->onMailSendForm();
+				}
+
+                if(count($_POST) > 1) {
+                        $this->dataRecord = $_POST;
+                        $this->onSubmit();
+                } else {
+                        $this->onShow();
+                }
+        }
+
+        /**
+        * Function called on page submit
+        */
+
+        function onSubmit() {
+                global $app, $conf;
+
+                // Calling the action functions
+                if($this->id > 0) {
+                        $this->onUpdate();
+                } else {
+                        $this->onInsert();
+                }
+        }
+
+        /**
+        * Function called on data update
+        */
+
+        function onUpdate() {
+                global $app, $conf;
+				
+				$this->onBeforeUpdate();
+				
+                $ext_where = '';
+                $sql = $app->tform->getSQL($this->dataRecord,$app->tform->getCurrentTab(),'UPDATE',$this->id,$ext_where);
+                if($app->tform->errorMessage == '') {
+						
+						if($app->tform->formDef['db_history'] == 'yes') {
+							$this->oldDataRecord = $app->tform->getDataRecord($this->id);
+						}
+						
+						// Save record in database
+						$this->onUpdateSave($sql);
+						
+						// loading plugins
+						$next_tab = $app->tform->getCurrentTab();
+                		$this->loadPlugins($next_tab);
+
+                        // Call plugin
+                        foreach($this->plugins as $plugin) {
+                                $plugin->onInsert();
+                        }
+
+                        $this->onAfterUpdate();
+						
+						// Write data history (sys_datalog)
+						if($app->tform->formDef['db_history'] == 'yes') {
+							$new_data_record = $app->tform->getDataRecord($this->id);
+							$app->tform->datalogSave('UPDATE',$this->id,$this->oldDataRecord,$new_data_record);
+							unset($new_data_record);
+							unset($old_data_record);
+						}
+
+                        if($_REQUEST["next_tab"] == '') {
+                           $list_name = $_SESSION["s"]["form"]["return_to"];
+						   // When a list is embedded inside of a form
+						   
+                           //if($list_name != '' && $_SESSION["s"]["list"][$list_name]["parent_id"] != $this->id && $_SESSION["s"]["list"][$list_name]["parent_name"] != $app->tform->formDef["name"]) {
+						   if($list_name != '' && $_SESSION["s"]["list"][$list_name]["parent_name"] != $app->tform->formDef["name"]) {
+                                $redirect = "Location: ".$_SESSION["s"]["list"][$list_name]["parent_script"]."?id=".$_SESSION["s"]["list"][$list_name]["parent_id"]."&next_tab=".$_SESSION["s"]["list"][$list_name]["parent_tab"];
+                                $_SESSION["s"]["form"]["return_to"] = '';
+                                session_write_close();
+                                header($redirect);
+							// When a returnto variable is set
+							} elseif ($_SESSION["s"]["form"]["return_to_url"] != '') {
+								$redirect = $_SESSION["s"]["form"]["return_to_url"];
+								$_SESSION["s"]["form"]["return_to_url"] = '';
+								session_write_close();
+								header("Location: ".$redirect);
+								exit;
+								// Use the default list of the form
+                        	} else {
+                            	header("Location: ".$app->tform->formDef['list_default']);
+                        	}
+                        	exit;
+                    	} else {
+                                $this->onShow();
+                        }
+                } else {
+                        $this->onError();
+                }
+        }
+		
+		/*
+		 Save record in database
+		*/
+		
+		function onUpdateSave($sql) {
+			global $app;
+			if(!empty($sql) && !$app->tform->isReadonlyTab($app->tform->getCurrentTab())) {
+				$app->db->query($sql);
+				if($app->db->errorMessage != '') die($app->db->errorMessage);
+			}
+		}
+		
+
+        /**
+        * Function called on data insert
+        */
+
+        function onInsert() {
+                global $app, $conf;
+				
+				$this->onBeforeInsert();
+
+                $ext_where = '';
+                $sql = $app->tform->getSQL($this->dataRecord,$app->tform->getCurrentTab(),'INSERT',$this->id,$ext_where);
+                if($app->tform->errorMessage == '') {
+						
+						$this->id = $this->onInsertSave($sql);
+						
+						// loading plugins
+						$next_tab = $app->tform->getCurrentTab();
+                		$this->loadPlugins($next_tab);
+						
+                        // Call plugin
+                        foreach($this->plugins as $plugin) {
+                                $plugin->onInsert();
+                        }
+
+                        $this->onAfterInsert();
+						
+						// Write data history (sys_datalog)
+						if($app->tform->formDef['db_history'] == 'yes') {
+							$new_data_record = $app->tform->getDataRecord($this->id);
+							$app->tform->datalogSave('INSERT',$this->id,array(),$new_data_record);
+							unset($new_data_record);
+						}
+						
+
+                     if($_REQUEST["next_tab"] == '') {
+                         $list_name = $_SESSION["s"]["form"]["return_to"];
+                         // if($list_name != '' && $_SESSION["s"]["list"][$list_name]["parent_id"] != $this->id && $_SESSION["s"]["list"][$list_name]["parent_name"] != $app->tform->formDef["name"]) {
+						 if($list_name != '' && $_SESSION["s"]["list"][$list_name]["parent_name"] != $app->tform->formDef["name"]) {
+                            $redirect = "Location: ".$_SESSION["s"]["list"][$list_name]["parent_script"]."?id=".$_SESSION["s"]["list"][$list_name]["parent_id"]."&next_tab=".$_SESSION["s"]["list"][$list_name]["parent_tab"];
+                            $_SESSION["s"]["form"]["return_to"] = '';
+                            session_write_close();
+                            header($redirect);
+							exit;
+                        } elseif ($_SESSION["s"]["form"]["return_to_url"] != '') {
+							$_SESSION["s"]["form"]["return_to_url"] = '';
+							session_write_close();
+							header("Location: ".$_SESSION["s"]["form"]["return_to_url"]);
+							exit;
+						} else {
+                                header("Location: ".$app->tform->formDef['list_default']);
+                        }
+                        exit;
+                    } else {
+                            $this->onShow();
+                        }
+                } else {
+                        $this->onError();
+                }
+        }
+		
+		/*
+		 Save record in database
+		*/
+		
+		function onInsertSave($sql) {
+			global $app, $conf;
+			$app->db->query($sql);
+            if($app->db->errorMessage != '') die($app->db->errorMessage);
+            return $app->db->insertID();
+		}
+
+        function onBeforeUpdate() {
+            global $app, $conf;
+        }
+
+        function onBeforeInsert() {
+            global $app, $conf;
+        }
+		
+		function onAfterUpdate() {
+            global $app, $conf;
+        }
+
+        function onAfterInsert() {
+            global $app, $conf;
+        }
+
+
+        /**
+        * Function called on data insert or update error
+        */
+
+        function onError() {
+                global $app, $conf;
+
+                $app->tpl->setVar("error","<b>".$app->lng('Error').":</b><br>".$app->tform->errorMessage);
+                $app->tpl->setVar($this->dataRecord);
+                $this->onShow();
+        }
+
+        /**
+        * Function called on data delete
+        */
+
+        function onDelete() {
+                global $app, $conf,$list_def_file,$tform_def_file;
+
+                include_once($list_def_file);
+
+                // Loading tform framework
+                if(!is_object($app->tform)) $app->uses('tform');
+
+                // Load table definition from file
+                $app->tform->loadFormDef($tform_def_file);
+
+                // importing ID
+                $this->id = intval($_REQUEST["id"]);
+
+                if($this->id > 0) {
+
+                        // checking permissions
+                        if($app->tform->formDef['auth'] == 'yes' && $_SESSION["s"]["user"]["typ"] != 'admin') {
+                                if($app->tform->checkPerm($this->id,'d') == false) $app->error($app->lng('error_no_delete_permission'));
+                        }
+
+                        //$this->dataRecord = $app->db->queryOneRecord("SELECT * FROM ".$liste["table"]." WHERE ".$liste["table_idx"]." = ".$this->id);
+						$this->dataRecord = $app->tform->getDataRecord($this->id);
+						
+						$this->onBeforeDelete();
+
+                        // Saving record to datalog when db_history enabled
+                        if($app->tform->formDef["db_history"] == 'yes') {
+							//$old_data_record = $app->tform->getDataRecord($this->id);
+							$app->tform->datalogSave('DELETE',$this->id,$this->dataRecord,array());
+                        }
+
+                        $app->db->query("DELETE FROM ".$app->tform->formDef['db_table']." WHERE ".$app->tform->formDef['db_table_idx']." = ".$this->id." LIMIT 1");
+						
+						
+						// loading plugins
+						$next_tab = $app->tform->getCurrentTab();
+                		$this->loadPlugins($next_tab);
+						
+						
+                        // Call plugin
+                        foreach($this->plugins as $plugin) {
+                                $plugin->onDelete();
+                        }
+						
+						$this->onAfterDelete();
+                }
+
+                		//header("Location: ".$liste["file"]."?PHPSESSID=".$_SESSION["s"]["id"]);
+                 $list_name = $_SESSION["s"]["form"]["return_to"];
+                 if($list_name != '' && $_SESSION["s"]["list"][$list_name]["parent_id"] != $this->id && $_SESSION["s"]["list"][$list_name]["parent_name"] != $app->tform->formDef["name"]) {
+                        $redirect = "Location: ".$_SESSION["s"]["list"][$list_name]["parent_script"]."?id=".$_SESSION["s"]["list"][$list_name]["parent_id"]."&next_tab=".$_SESSION["s"]["list"][$list_name]["parent_tab"];
+                        $_SESSION["s"]["form"]["return_to"] = '';
+                        session_write_close();
+                        header($redirect);
+                } else {
+                    header("Location: ".$liste["file"]);
+                }
+                exit;
+
+        }
+		
+		function onBeforeDelete() {
+            global $app, $conf;
+        }
+		
+		function onAfterDelete() {
+            global $app, $conf;
+        }
+		
+		/**
+        * Function to print the form content
+        */
+		
+		function onPrintForm() {
+			global $app, $conf;
+			
+			if($app->tform->formDef['template_print'] == '') die('No print template available.');
+			
+			$app->tpl->newTemplate("print.tpl.htm");
+			$app->tpl->setInclude("content_tpl",$app->tform->formDef['template_print']);
+
+			if($app->tform->formDef['auth'] == 'no') {
+            	$sql = "SELECT * FROM ".$app->tform->formDef['db_table']." WHERE ".$app->tform->formDef['db_table_idx']." = ".$this->id;
+            } else {
+            	$sql = "SELECT * FROM ".$app->tform->formDef['db_table']." WHERE ".$app->tform->formDef['db_table_idx']." = ".$this->id." AND ".$app->tform->getAuthSQL('u');
+            }
+            if(!$record = $app->db->queryOneRecord($sql)) $app->error($app->lng('error_no_view_permission'));
+			
+			$record["datum"] = date("d.m.Y");
+			
+			$app->tpl->setVar($app->tform->wordbook);
+
+			$app->tpl->setVar($record);
+			$app->tpl_defaults();
+			$app->tpl->pparse();
+			exit;
+			
+		}
+		
+		/**
+        * Function to print the form content
+        */
+		
+		function onMailSendForm() {
+			global $app, $conf;
+			
+			if($app->tform->formDef['template_mailsend'] == '') die('No print template available.');
+			
+			if($_POST["email"] == '' && $_POST["sender"] == '') {
+				// Zeige Formular zum versenden an.
+				$app->tpl->newTemplate("form.tpl.htm");
+				$app->tpl->setInclude("content_tpl",$app->tform->formDef['template_mailsend']);
+				$app->tpl->setVar('show_form',1);
+				$app->tpl->setVar("form_action",$app->tform->formDef['action'].'?send_form_by_mail=1');
+				$app->tpl->setVar("id",$this->id);
+				$app->tpl_defaults();
+				$app->tpl->pparse();
+				exit;
+			} else {
+				$app->tpl->newTemplate("mail.tpl.htm");
+				$app->tpl->setInclude("content_tpl",$app->tform->formDef['template_mailsend']);
+				$app->tpl->setVar('show_mail',1);
+				if($app->tform->formDef['auth'] == 'no') {
+            		$sql = "SELECT * FROM ".$app->tform->formDef['db_table']." WHERE ".$app->tform->formDef['db_table_idx']." = ".$this->id;
+            	} else {
+            		$sql = "SELECT * FROM ".$app->tform->formDef['db_table']." WHERE ".$app->tform->formDef['db_table_idx']." = ".$this->id." AND ".$app->tform->getAuthSQL('u');
+            	}
+            	if(!$record = $app->db->queryOneRecord($sql)) $app->error($app->lng('error_no_view_permission'));
+			
+				$record["datum"] = date("d.m.Y");
+				$record["mailmessage"] = $_POST["message"];
+			
+				$app->tpl->setVar($app->tform->wordbook);
+
+				$app->tpl->setVar($record);
+				$app->tpl_defaults();
+				
+				$email_message = $app->tpl->grab();
+				$email = $_POST["email"];
+				$sender = $_POST["sender"];
+				
+				$headers  = "MIME-Version: 1.0\n";
+				$headers .= "Content-type: text/html; charset=iso-8859-1\n";
+				$headers .= "From: $sender\n";
+				
+				if (!ereg('^[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+' . '@' . '([-!#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\.)+' . '[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+$', $sender)) {
+    				$sender = 'noreply@iprguard.de';
+  				}
+				
+				if (ereg('^[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+' . '@' . '([-!#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\.)+' . '[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+$', $email)) {
+    				mail($email, 'Domainrecherche Statement '.$record["domain"], $email_message, $headers);
+  				}
+				echo "<p>&nbsp;</p><p>Email wurde versand.</p>";
+				exit;
+			}
+			
+			
+
+			if($app->tform->formDef['auth'] == 'no') {
+            	$sql = "SELECT * FROM ".$app->tform->formDef['db_table']." WHERE ".$app->tform->formDef['db_table_idx']." = ".$this->id;
+            } else {
+            	$sql = "SELECT * FROM ".$app->tform->formDef['db_table']." WHERE ".$app->tform->formDef['db_table_idx']." = ".$this->id." AND ".$app->tform->getAuthSQL('u');
+            }
+            if(!$record = $app->db->queryOneRecord($sql)) $app->error($app->lng('error_no_view_permission'));
+			
+			$record["datum"] = date("d.m.Y");
+			
+			$app->tpl->setVar($app->tform->wordbook);
+
+			$app->tpl->setVar($record);
+			$app->tpl_defaults();
+			$app->tpl->pparse();
+			exit;
+			
+		}
+
+        /**
+        * Function called on page show
+        */
+
+        function onShow() {
+                global $app, $conf;
+
+                // Which tab do we render
+                $this->active_tab = $app->tform->getNextTab();
+
+                if($this->id > 0) {
+                        $this->onShowEdit();
+                } else {
+                        $this->onShowNew();
+                }
+
+                // make Form and Tabs
+                $app->tform->showForm();
+
+                // Setting default values
+                $app->tpl_defaults();
+				
+				// Show the navigation bar of the form
+				if(isset($app->tform->formDef['navibar']) && $app->tform->formDef['navibar'] == 'yes') {
+					$navibar = '';
+					if($app->tform->formDef['template_print'] != '') {
+						$navibar .= '<a href="'.$app->tform->formDef['action'].'?id='.$this->id.'&print_form=1" target="_blank"><img src="../themes/iprg/icons/printer.png" border="0" alt="Drucken" /></a> &nbsp;';
+					}
+					if($app->tform->formDef['template_mailsend'] != '') {
+						$navibar .= "<a href=\"#\" onClick=\"window.open('".$app->tform->formDef['action'].'?id='.$this->id."&send_form_by_mail=1','send','width=370,height=240')\"><img src=\"../themes/iprg/icons/mail.png\" border=\"0\" alt=\"Als E-Mail versenden\" /></a>";
+					}
+					$app->tpl->setVar('form_navibar',$navibar);
+				}
+				
+				
+				// loading plugins
+                $this->loadPlugins($this->active_tab);
+
+                // Calling the Plugin onShow Events and set the data in the
+                // plugins placeholder in the template
+                foreach($this->plugins as $plugin_name => $plugin) {
+                        $app->tpl->setVar($plugin_name,$plugin->onShow());
+                }
+
+                // Parse the templates and send output to the browser
+                $this->onShowEnd();
+
+        }
+
+        /**
+        * Function called on new record
+        */
+
+        function onShowNew() {
+                global $app, $conf;
+
+                if($app->tform->errorMessage == '') {
+                        $record = array();
+                        $record = $app->tform->getHTML($record, $app->tform->formDef['tab_default'],'NEW');
+                } else {
+                        $record = $app->tform->getHTML($app->tform->encode($_POST,$this->active_tab),$this->active_tab,'EDIT');
+                }
+
+                $app->tpl->setVar($record);
+        }
+
+        /**
+        * Function called on edit record
+        */
+
+        function onShowEdit() {
+                global $app, $conf;
+
+                // bestehenden Datensatz anzeigen
+                if($app->tform->errorMessage == '') {
+                        if($app->tform->formDef['auth'] == 'yes' && $_SESSION["s"]["user"]["typ"] != 'admin') {
+                        	$sql = "SELECT * FROM ".$app->tform->formDef['db_table']." WHERE ".$app->tform->formDef['db_table_idx']." = ".$this->id." AND ".$app->tform->getAuthSQL('u');
+                        } else {
+                        	$sql = "SELECT * FROM ".$app->tform->formDef['db_table']." WHERE ".$app->tform->formDef['db_table_idx']." = ".$this->id;
+                        }
+                        if(!$record = $app->db->queryOneRecord($sql)) $app->error($app->lng('error_no_view_permission'));
+                } else {
+                        // $record = $app->tform->encode($_POST,$this->active_tab);
+						$record = $app->tform->encode($this->dataRecord,$this->active_tab);
+                }
+
+                $this->dataRecord = $record;
+
+            	// Userdaten umwandeln
+                $record = $app->tform->getHTML($record, $this->active_tab,'EDIT');
+                $record['id'] = $this->id;
+
+                $app->tpl->setVar($record);
+        }
+
+        function onShowEnd() {
+                global $app, $conf;
+
+                // Template parsen
+                $app->tpl->pparse();
+        }
+		
+		function loadPlugins($next_tab) {
+			global $app;
+			if(@is_array($app->tform->formDef["tabs"][$next_tab]["plugins"])) {
+                 $app->load('plugin_base');
+                 foreach($app->tform->formDef["tabs"][$next_tab]["plugins"] as $plugin_name => $plugin_settings) {
+                      $plugin_class = $plugin_settings["class"];
+                      $app->load($plugin_class);
+                      $this->plugins[$plugin_name] = new $plugin_class;
+                      $this->plugins[$plugin_name]->setOptions($plugin_name,$plugin_settings['options']);
+					  // Make the data of the form easily accessible for the plugib
+					  $this->plugins[$plugin_name]->form = $this;
+                      $this->plugins[$plugin_name]->onLoad();
+                  }
+             }
+		}
+
+
+}
+
 ?>
\ No newline at end of file
diff --git a/interface/lib/classes/tform_tpl_generator.inc.php b/interface/lib/classes/tform_tpl_generator.inc.php
index 9311f14eab95c70b6bfe54ad3f87d11bee836d3e..1f10e8efec24e9048977d3d2ba4d2b28e3559245 100644
--- a/interface/lib/classes/tform_tpl_generator.inc.php
+++ b/interface/lib/classes/tform_tpl_generator.inc.php
@@ -1,316 +1,355 @@
-<?php
-
-/*
-Copyright (c) 2005, Till Brehm, projektfarm Gmbh
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
-      and/or other materials provided with the distribution.
-    * Neither the name of ISPConfig nor the names of its contributors
-      may be used to endorse or promote products derived from this software without
-      specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-
-class tform_tpl_generator {
-	
-	function buildHTML($formDef,$tab) {
-		
-		global $app;
-		
-		$module = $_SESSION["s"]["module"]["name"];
-		
-		$html = '<table width="500" border="0" cellspacing="0" cellpadding="2">';
-		$lang = array();
-		
-		foreach($formDef['tabs'][$tab]['fields'] as $key => $field) {
-			switch ($field['formtype']) {
-				case 'TEXT':
-					$html .= "
-  <tr>
-    <td class=\"frmText11\">{tmpl_var name='".$key."_txt'}:</td>
-    <td class=\"frmText11\"><input name=\"".$key."\" type=\"text\" class=\"text\" value=\"{tmpl_var name='".$key."'}\" size=\"".$field['width']."\" maxlength=\"".$field['maxlength']."\"></td>
-  </tr>";
-				break;
-				case 'TEXTAREA':
-					$html .= "
-  <tr>
-    <td class=\"frmText11\">{tmpl_var name='".$key."_txt'}:</td>
-    <td class=\"frmText11\"><textarea name='$key' cols='".$field['cols']."' rows='".$field['rows']."'>{tmpl_var name='".$key."'}</textarea></td>
-  </tr>";
-				break;
-				case 'SELECT':
-				$html .= "
-  <tr>
-    <td class=\"frmText11\">{tmpl_var name='".$key."_txt'}:</td>
-    <td class=\"frmText11\">
-		<select name=\"".$key."\" class=\"text\">
-			{tmpl_var name='".$key."'}
-		</select>
-	</td>
-  </tr>";
-				break;
-				case 'MULTIPLE':
-				$html .= "
-  <tr>
-    <td class=\"frmText11\">{tmpl_var name='".$key."_txt'}:</td>
-    <td class=\"frmText11\">
-		<select name=\"".$key."\" class=\"text\" size=\"".$field['rows']."\" multiple>
-			{tmpl_var name='".$key."'}
-		</select>
-	</td>
-  </tr>";
-				break;
-				case 'PASSWORD':
-				$html .= "
-  <tr>
-    <td class=\"frmText11\">{tmpl_var name='".$key."_txt'}:</td>
-    <td class=\"frmText11\"><input name=\"".$key."\" type=\"password\" class=\"text\" value=\"{tmpl_var name='".$key."'}\" size=\"".$field['width']."\" maxlength=\"".$field['maxlength']."\"></td>
-  </tr>";
-				break;
-				case 'CHECKBOX':
-				$html .= "
-  <tr>
-    <td class=\"frmText11\">{tmpl_var name='".$key."_txt'}:</td>
-    <td class=\"frmText11\">{tmpl_var name='".$key."'}</td>
-  </tr>";
-				break;
-				case 'CHECKBOXARRAY':
-				$html .= "
-  <tr>
-    <td class=\"frmText11\">{tmpl_var name='".$key."_txt'}:</td>
-    <td class=\"frmText11\">{tmpl_var name='".$key."'}</td>
-  </tr>";
-				break;
-				case 'RADIO':
-				$html .= "
-  <tr>
-    <td class=\"frmText11\">{tmpl_var name='".$key."_txt'}:</td>
-    <td class=\"frmText11\">{tmpl_var name='".$key."'}</td>
-  </tr>";
-				break;
-			}
-			
-			// Language File Eintrag für "Feld-Titel" anlegen
-			$lang[$key."_txt"] = $key;
-			
-			// language File Eintrag, für error-Text anlegen
-			if(isset($field["errmsg"]) && $field["errmsg"] != '') {
-				$errmsg = $field["errmsg"];
-				$lang[$errmsg] = $errmsg;
-			}
-			
-			
-		}
-		
-		$html .= "  <tr>
-    <td class=\"frmText11\">&nbsp;</td>
-    <td class=\"frmText11\">&nbsp;</td>
-  </tr>
-  <tr>
-    <td>&nbsp;</td>
-    <td><input name=\"btn_save\" type=\"button\" class=\"button\" value=\"{tmpl_var name='btn_save_txt'}\" onClick=\"submitForm('pageForm','".$module."/".$formDef["action"]."');\"><div class=\"buttonEnding\"></div>&nbsp;
-      <input name=\"btn_cancel\" type=\"button\" class=\"button\" value=\"{tmpl_var name='btn_cancel_txt'}\" onClick=\"loadContent('".$module."/".$formDef["list_default"]."');\"><div class=\"buttonEnding\"></div>
-    </td>
-  </tr>";
-		
-		$lang['btn_save_txt'] = "Save";
-		$lang['btn_cancel_txt'] = "Cancel";
-		
-		$html .= "\r\n</table>\r\n<input type=\"hidden\" name=\"id\" value=\"{tmpl_var name='id'}\">";
-		
-		// speichere Template
-		if (!$handle = fopen($formDef['tabs'][$tab]['template'], 'w')) { 
-        	print "Cannot open file ($filename)"; 
-        	exit; 
-   		} 
- 
-   		if (!fwrite($handle, $html)) { 
-			print "Cannot write to file ($filename)"; 
-			exit; 
-		}
-		fclose($handle);
-		
-		// speichere language Datei
-		$this->lng_add($lang,$formDef);
-		
-		// überprüfe, ob es die Tabelle schon gibt,
-		// ansonsten wird sie angelegt
-		$tables = $app->db->getTables();
-		
-		if(!@in_array($formDef['db_table'],$tables)) {
-			// Datenbank noch nicht vorhanden
-			
-			$columns = array();
-			
-			// füge ID Feld hinzu
-			$col = array(	'action' 		=> 'add',
-							'name'			=> $formDef["db_table_idx"],
-							'type'			=> 'int64',
-							'typeValue'		=> '',
-							'defaultValue'	=> false,
-							'notNull'		=> true,
-							'autoInc'		=> true,
-							'option'		=> 'primary'
-						);
-					
-			$columns[] = $col;
-			$app->db->show_error_messages = true;
-			
-			if($formDef["auth"] == 'yes') {
-				
-				$col = array(	'action' 		=> 'add',
-								'name'			=> 'sys_userid',
-								'type'			=> 'int32',
-								'typeValue'		=> '',
-								'defaultValue'	=> '0',
-								'notNull'		=> true
-							);
-				$columns[] = $col;
-				$col = array(	'action' 		=> 'add',
-								'name'			=> 'sys_groupid',
-								'type'			=> 'int32',
-								'typeValue'		=> '',
-								'defaultValue'	=> '0',
-								'notNull'		=> true
-							);
-				$columns[] = $col;
-				$col = array(	'action' 		=> 'add',
-								'name'			=> 'sys_perm_user',
-								'type'			=> 'varchar',
-								'typeValue'		=> '5',
-								'defaultValue'	=> 'NULL',
-								'notNull'		=> true
-							);
-				$columns[] = $col;
-				$col = array(	'action' 		=> 'add',
-								'name'			=> 'sys_perm_group',
-								'type'			=> 'varchar',
-								'typeValue'		=> '5',
-								'defaultValue'	=> 'NULL',
-								'notNull'		=> true
-							);
-				$columns[] = $col;
-				$col = array(	'action' 		=> 'add',
-								'name'			=> 'sys_perm_other',
-								'type'			=> 'varchar',
-								'typeValue'		=> '5',
-								'defaultValue'	=> 'NULL',
-								'notNull'		=> true
-							);
-				$columns[] = $col;
-			
-			}
-			
-			
-			foreach($formDef['tabs'] as $tab) {
-				foreach($tab["fields"] as $name => $field) {
-					/*
-				       $columns = array(action =>   add | alter | drop
-				                        name =>     Spaltenname
-				                        name_new => neuer Spaltenname, nur bei 'alter' belegt
-				                        type =>     42go-Meta-Type: int16, int32, int64, double, char, varchar, text, blob
-				                        typeValue => Wert z.B. bei Varchar
-				                        defaultValue =>  Default Wert
-				                        notNull =>   true | false
-				                        autoInc =>   true | false
-				                        option =>   unique | primary | index)
-				       
-				       
-					*/
-					switch ($field["datatype"]) {
-						case 'INTEGER':
-							$type = 'int32';
-							$typevalue = '';
-							$defaultValue	= ($field["default"] != '')?$field["default"]:'0';
-						break;
-						case 'DOUBLE':
-							$type = 'double';
-							$typevalue = '';
-							$defaultValue	= ($field["default"] != '')?$field["default"]:'0';
-						break;
-						case 'CURRENCY':
-							$type = 'double';
-							$typevalue = '';
-							$defaultValue	= ($field["default"] != '')?$field["default"]:'0';
-						break;
-						case 'VARCHAR':
-							$type = 'varchar';
-							$typeValue = ($field["maxlength"] > 0 and $field["maxlength"] <= 256)?$field["maxlength"]:255;
-							// $defaultValue	= ($field["default"] != '')?$field["default"]:'NOT NULL';
-							$defaultValue	= ($field["default"] != '')?$field["default"]:'NULL';
-						break;
-						case 'TEXT':
-							$type = 'text';
-							$typevalue = '';
-							$defaultValue = 'NULL';
-						break;
-						case 'DATE':
-							$type = 'int64';
-							$typevalue = '';
-							$defaultValue	= ($field["default"] != '')?$field["default"]:'0';
-						break;
-					}
-					
-					
-					$col = array(	'action' 		=> 'add',
-									'name'			=> $name,
-									'type'			=> $type,
-									'typeValue'		=> $typeValue,
-									'defaultValue'	=> $defaultValue,
-									'notNull'		=> true
-									);
-					
-					$columns[] = $col;
-				}
-			}
-		
-		$app->db->createTable($formDef["db_table"],$columns);
-		
-		}
-    }
-	
-	function lng_add($lang,$formDef) {
-		global $go_api, $go_info,$conf;
-		
-		$lng_file = "lib/lang/".$conf["language"]."_".$formDef['name'].".lng";
-		if(is_file($lng_file)) {
-			include($lng_file);
-		} else {
-			$wb = array();
-		}
-		
-		$wb_out = array_merge($lang,$wb);
-		
-		if(is_array($wb_out)) {
-			$fp = fopen ($lng_file, "w");
-			fwrite($fp,"<?php\r\n");
-			foreach($wb_out as $key => $val) {
-				$new_line = '$wb["'.$key.'"] = '."'$val';\r\n";
-				fwrite($fp,$new_line);
-				
-			}
-			fwrite($fp,"?>");
-			fclose($fp);
-		}
-	}
-}
-
+<?php
+
+/*
+Copyright (c) 2005, Till Brehm, projektfarm Gmbh
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+    * Neither the name of ISPConfig nor the names of its contributors
+      may be used to endorse or promote products derived from this software without
+      specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+class tform_tpl_generator {
+	
+	function buildHTML($formDef,$tab) {
+		
+		global $app;
+		
+		$module = $_SESSION["s"]["module"]["name"];
+		
+		$html = '<h2><tmpl_var name="list_head_txt"></h2>
+
+<div class="panel panel_'.$formDef['name'].'">
+
+  <div class="pnl_formsarea">
+    <fieldset id="wf_area_'.$formDef['name'].'"><legend>'.$formDef['tabs'][$tab]['title'].'</legend>';
+		$lang = array();
+		
+		foreach($formDef['tabs'][$tab]['fields'] as $key => $field) {
+			switch ($field['formtype']) {
+				case 'TEXT':
+					$html .= "\r\n      <span class=\"wf_oneField\">
+        <label for=\"".$key."\" class=\"wf_preField\">{tmpl_var name='".$key."_txt'}</label>
+        <input type=\"text\" id=\"".$key."\" name=\"".$key."\" value=\"{tmpl_var name='".$key."'}\" size=\"".$field['width']."\" maxlength=\"".$field['maxlength']."\"";
+          if ($field['required'] == true ) {
+  					$html .= " class=\"wf_required\"><span class=\"wf_reqMark\">*</span><br>";
+          } else {
+  	 				$html .= ">";
+          }
+					$html .= "\r\n      </span>";
+				break;
+				case 'TEXTAREA':
+					$html .= "\r\n      <span class=\"wf_oneField\">
+        <label for=\"".$key."\" class=\"wf_preField\">{tmpl_var name='".$key."_txt'}</label>
+        <textarea id=\"".$key."\" name=\"".$key."\" cols='".$field['cols']."' rows='".$field['rows']."'";
+          if ($field['required'] == true ) {
+  					$html .= " class=\"wf_required\">";
+          } else {
+  	 				$html .= ">";
+          }
+					$html .= "{tmpl_var name='".$key."'}</textarea>";
+          if ($field['required'] == true ) {
+  					$html .= "<span class=\"wf_reqMark\">*</span><br>";
+          }
+					$html .= "\r\n      </span>";
+				break;
+				case 'SELECT':
+					$html .= "\r\n      <span class=\"wf_oneField\">
+        <label for=\"".$key."\" class=\"wf_preField\">{tmpl_var name='".$key."_txt'}</label>
+        <select id=\"".$key."\" name=\"".$key."\"";
+          if ($field['required'] == true ) {
+  					$html .= " class=\"wf_required\">";
+          } else {
+  	 				$html .= ">";
+          }
+					$html .= "{tmpl_var name='".$key."'}</select>";
+          if ($field['required'] == true ) {
+  					$html .= "<span class=\"wf_reqMark\">*</span><br>";
+          }
+					$html .= "\r\n      </span>";
+				break;
+				case 'MULTIPLE':
+					$html .= "\r\n      <span class=\"wf_oneField\">
+        <label for=\"".$key."\" class=\"wf_preField\">{tmpl_var name='".$key."_txt'}</label>
+        <select multiple id=\"".$key."\" name=\"".$key."\"";
+          if ($field['required'] == true ) {
+  					$html .= " class=\"wf_required\">";
+          } else {
+  	 				$html .= ">";
+          }
+					$html .= "{tmpl_var name='".$key."'}</select>";
+          if ($field['required'] == true ) {
+  					$html .= "<span class=\"wf_reqMark\">*</span><br>";
+          }
+					$html .= "\r\n      </span>";
+				break;
+				case 'PASSWORD':
+					$html .= "\r\n      <span class=\"wf_oneField\">
+        <label for=\"".$key."\" class=\"wf_preField\">{tmpl_var name='".$key."_txt'}</label>
+        <input type=\"password\" id=\"".$key."\" name=\"".$key."\" value=\"{tmpl_var name='".$key."'}\" size=\"".$field['width']."\" maxlength=\"".$field['maxlength']."\"";
+          if ($field['required'] == true ) {
+  					$html .= " class=\"wf_required\"><span class=\"wf_reqMark\">*</span><br>";
+          } else {
+  	 				$html .= ">";
+          }
+					$html .= "\r\n      </span>";
+				break;
+				case 'CHECKBOX':
+					$html .= "\r\n      <span class=\"wf_oneField\">
+        <label for=\"".$key."\" class=\"wf_preField\">{tmpl_var name='".$key."_txt'}</label>";
+          if ($field['required'] == true ) {
+  					$html .= "                    <span class=\"wf_required\">
+                      {tmpl_var name='".$key."'}
+                    </span>
+                    <span class=\"wf_reqMark\">*</span><br>";
+          } else {
+  					$html .= "                    <span class=\"\">
+                      {tmpl_var name='".$key."'}
+                    </span>";
+          }
+          $html .= "\r\n      </span>";
+				break;
+				case 'CHECKBOXARRAY':
+					$html .= "\r\n      <span class=\"wf_oneField\">
+        <span class=\"wf_label wf_preField\">{tmpl_var name='".$key."_txt'}</span>";
+  					$html .= "                    <fieldset>
+                      {tmpl_var name='".$key."'}
+                    </fieldset>";
+            $html .= "\r\n      </span>";
+				break;
+				case 'RADIO':
+					$html .= "      <span class=\"wf_oneField\">
+        <span class=\"wf_label wf_preField\">{tmpl_var name='".$key."_txt'}</span>";
+  					$html .= "                    <fieldset>
+                      {tmpl_var name='".$key."'}
+                    </fieldset>";
+            $html .= "\r\n      </span>";
+				break;
+			}
+			
+			// Language File Eintrag für "Feld-Titel" anlegen
+			$lang[$key."_txt"] = $key;
+			
+			// language File Eintrag, für error-Text anlegen
+			if(isset($field["errmsg"]) && $field["errmsg"] != '') {
+				$errmsg = $field["errmsg"];
+				$lang[$errmsg] = $errmsg;
+			}
+			
+		}
+		
+		$html .= "
+    </fieldset>
+
+    <input type=\"hidden\" name=\"id\" value=\"{tmpl_var name='id'}\">
+
+    <div class=\"wf_actions buttons\">
+      <button class=\"positive iconstxt icoPositive\" type=\"button\" value=\"{tmpl_var name='btn_save_txt'}\" onClick=\"submitForm('pageForm','".$module."/".$formDef["action"]."');\"><span>{tmpl_var name='btn_save_txt'}</span></button>
+      <button class=\"negative iconstxt icoNegative\" type=\"button\" value=\"{tmpl_var name='btn_cancel_txt'}\" onClick=\"loadContent('".$module."/".$formDef["list_default"]."');\"><span>{tmpl_var name='btn_cancel_txt'}</span></button>
+    </div>
+  </div>
+  
+</div>
+";
+
+		$lang['btn_save_txt'] = "Save";
+		$lang['btn_cancel_txt'] = "Cancel";
+				
+		// speichere Template
+		if (!$handle = fopen($formDef['tabs'][$tab]['template'], 'w')) { 
+        	print "Cannot open file ($filename)"; 
+        	exit; 
+   		} 
+ 
+   		if (!fwrite($handle, $html)) { 
+			print "Cannot write to file ($filename)"; 
+			exit; 
+		}
+		fclose($handle);
+		
+		// speichere language Datei
+		$this->lng_add($lang,$formDef);
+		
+		// überprüfe, ob es die Tabelle schon gibt,
+		// ansonsten wird sie angelegt
+		$tables = $app->db->getTables();
+		
+		if(!@in_array($formDef['db_table'],$tables)) {
+			// Datenbank noch nicht vorhanden
+			
+			$columns = array();
+			
+			// füge ID Feld hinzu
+			$col = array(	'action' 		=> 'add',
+							'name'			=> $formDef["db_table_idx"],
+							'type'			=> 'int64',
+							'typeValue'		=> '',
+							'defaultValue'	=> false,
+							'notNull'		=> true,
+							'autoInc'		=> true,
+							'option'		=> 'primary'
+						);
+					
+			$columns[] = $col;
+			$app->db->show_error_messages = true;
+			
+			if($formDef["auth"] == 'yes') {
+				
+				$col = array(	'action' 		=> 'add',
+								'name'			=> 'sys_userid',
+								'type'			=> 'int32',
+								'typeValue'		=> '',
+								'defaultValue'	=> '0',
+								'notNull'		=> true
+							);
+				$columns[] = $col;
+				$col = array(	'action' 		=> 'add',
+								'name'			=> 'sys_groupid',
+								'type'			=> 'int32',
+								'typeValue'		=> '',
+								'defaultValue'	=> '0',
+								'notNull'		=> true
+							);
+				$columns[] = $col;
+				$col = array(	'action' 		=> 'add',
+								'name'			=> 'sys_perm_user',
+								'type'			=> 'varchar',
+								'typeValue'		=> '5',
+								'defaultValue'	=> 'NULL',
+								'notNull'		=> true
+							);
+				$columns[] = $col;
+				$col = array(	'action' 		=> 'add',
+								'name'			=> 'sys_perm_group',
+								'type'			=> 'varchar',
+								'typeValue'		=> '5',
+								'defaultValue'	=> 'NULL',
+								'notNull'		=> true
+							);
+				$columns[] = $col;
+				$col = array(	'action' 		=> 'add',
+								'name'			=> 'sys_perm_other',
+								'type'			=> 'varchar',
+								'typeValue'		=> '5',
+								'defaultValue'	=> 'NULL',
+								'notNull'		=> true
+							);
+				$columns[] = $col;
+			
+			}
+			
+			
+			foreach($formDef['tabs'] as $tab) {
+				foreach($tab["fields"] as $name => $field) {
+					/*
+				       $columns = array(action =>   add | alter | drop
+				                        name =>     Spaltenname
+				                        name_new => neuer Spaltenname, nur bei 'alter' belegt
+				                        type =>     42go-Meta-Type: int16, int32, int64, double, char, varchar, text, blob
+				                        typeValue => Wert z.B. bei Varchar
+				                        defaultValue =>  Default Wert
+				                        notNull =>   true | false
+				                        autoInc =>   true | false
+				                        option =>   unique | primary | index)
+				       
+				       
+					*/
+					switch ($field["datatype"]) {
+						case 'INTEGER':
+							$type = 'int32';
+							$typevalue = '';
+							$defaultValue	= ($field["default"] != '')?$field["default"]:'0';
+						break;
+						case 'DOUBLE':
+							$type = 'double';
+							$typevalue = '';
+							$defaultValue	= ($field["default"] != '')?$field["default"]:'0';
+						break;
+						case 'CURRENCY':
+							$type = 'double';
+							$typevalue = '';
+							$defaultValue	= ($field["default"] != '')?$field["default"]:'0';
+						break;
+						case 'VARCHAR':
+							$type = 'varchar';
+							$typeValue = ($field["maxlength"] > 0 and $field["maxlength"] <= 256)?$field["maxlength"]:255;
+							// $defaultValue	= ($field["default"] != '')?$field["default"]:'NOT NULL';
+							$defaultValue	= ($field["default"] != '')?$field["default"]:'NULL';
+						break;
+						case 'TEXT':
+							$type = 'text';
+							$typevalue = '';
+							$defaultValue = 'NULL';
+						break;
+						case 'DATE':
+							$type = 'int64';
+							$typevalue = '';
+							$defaultValue	= ($field["default"] != '')?$field["default"]:'0';
+						break;
+					}
+					
+					
+					$col = array(	'action' 		=> 'add',
+									'name'			=> $name,
+									'type'			=> $type,
+									'typeValue'		=> $typeValue,
+									'defaultValue'	=> $defaultValue,
+									'notNull'		=> true
+									);
+					
+					$columns[] = $col;
+				}
+			}
+		
+		$app->db->createTable($formDef["db_table"],$columns);
+		
+		}
+    }
+	
+	function lng_add($lang,$formDef) {
+		global $go_api, $go_info,$conf;
+		
+		$lng_file = "lib/lang/".$conf["language"]."_".$formDef['name'].".lng";
+		if(is_file($lng_file)) {
+			include($lng_file);
+		} else {
+			$wb = array();
+		}
+		
+		$wb_out = array_merge($lang,$wb);
+		
+		if(is_array($wb_out)) {
+			$fp = fopen ($lng_file, "w");
+			fwrite($fp,"<?php\r\n");
+			foreach($wb_out as $key => $val) {
+				$new_line = '$wb["'.$key.'"] = '."'$val';\r\n";
+				fwrite($fp,$new_line);
+				
+			}
+			fwrite($fp,"?>");
+			fclose($fp);
+		}
+	}
+}
+
 ?>
\ No newline at end of file
diff --git a/interface/lib/config.inc.php b/interface/lib/config.inc.php
index 68ad22c244dc05079cb630f0b03f63ff36c0a5a9..101edf59853304af6512eb527789cb5baa995a5f 100644
--- a/interface/lib/config.inc.php
+++ b/interface/lib/config.inc.php
@@ -31,7 +31,7 @@ error_reporting(E_ALL|E_NOTICE);
 
 header('Pragma: no-cache');
 header('Cache-Control: no-store, no-cache, max-age=0, must-revalidate');
-header('Content-Type: text/html');
+header('Content-Type: text/html; charset=utf-8');
 //* TODO: Js caching - pedro
 
 //** Key paramaters
@@ -114,8 +114,7 @@ $conf['programs']['wput']		= ISPC_ROOT_PATH."\\tools\\wput\\wput.exe";
 
 //** Themes
 $conf['theme']					= 'default';
-$conf['html_content_encoding']	= 'text/html; charset=iso-8859-1';
-$conf['logo'] 					= 'themes/default/images/mydnsconfig_logo.gif';
+$conf['html_content_encoding']	= 'text/html; charset=utf-8';
 
 //** Default Language
 $conf['language']       = 'en';