diff --git a/config/exim4/exim4_without_amavisd.conf.template b/config/exim4/exim4_without_amavisd.conf.template
new file mode 100644
index 0000000000000000000000000000000000000000..20bdcba86b284139bd54a233e7ec94a92703a719
--- /dev/null
+++ b/config/exim4/exim4_without_amavisd.conf.template
@@ -0,0 +1,554 @@
+######################################################################
+#                    MAIN CONFIGURATION SETTINGS                     #
+######################################################################
+
+# MySQL defines
+MYSQL_SERVER=localhost
+MYSQL_USER=root
+MYSQL_PASSWORD=
+MYSQL_DB=mailserver
+MYSQL_EMAILTABLE=mail_box
+MYSQL_DOMAINTABLE=mail_domain
+MYSQL_WHITETABLE=mail_whitelist
+MYSQL_BLACKTABLE=mail_blacklist
+
+# Server ID for Multiserver Setups
+MAILSERVER_ID=1
+MAILSERVER_HOSTNAME=mail.
+MAILSERVER_IP=192.168.0.108
+MAILSERVER_EXIM_BINARY=/usr/sbin/exim4
+MAILSERVER_SPAMC_BINARY=/usr/bin/spamc
+
+# Mailman vars
+MAILMAN_HOME=/var/lib/mailman
+MAILMAN_WRAP=MAILMAN_HOME/mail/wrapper
+MAILMAN_UID=list
+MAILMAN_GID=list
+
+# MySQL queries
+# MYSQL_Q_LDOMAIN=SELECT DISTINCT domain FROM MYSQL_DOMAINTABLE WHERE domain='${quote_mysql:$domain}' AND type = 'local'
+# MYSQL_Q_RDOMAIN=SELECT DISTINCT domain FROM MYSQL_DOMAINTABLE WHERE domain='${quote_mysql:$domain}' AND type = 'relay'
+
+MYSQL_Q_VSCAN=SELECT SUBSTRING_INDEX(email,'@',-1) FROM MYSQL_EMAILTABLE WHERE email=CONCAT('${quote_mysql:$local_part}','@','${quote_mysql:$domain}') AND opt_virscan='yes'
+
+
+MM_HOME=${lookup mysql{SELECT mm_home FROM mail_mailman_domain WHERE domain='${quote_mysql:domain}'}}
+MM_LISTCHK=MM_HOME/lists/${lc::$local_part}/config.pck
+MM_WRAP=${lookup mysql{SELECT mm_wrap FROM mail_mailman_domain WHERE domain='${quote_mysql:domain}'}}
+
+# MySQL connection
+hide mysql_servers = "MYSQL_SERVER/MYSQL_DB/MYSQL_USER/MYSQL_PASSWORD"
+
+# starting 'normal' config
+
+primary_hostname = MAILSERVER_HOSTNAME
+
+domainlist local_domains = mysql;SELECT DISTINCT domain FROM MYSQL_DOMAINTABLE WHERE domain='${quote_mysql:$domain}' AND type = 'local'
+domainlist relay_to_domains = mysql;SELECT DISTINCT domain FROM MYSQL_DOMAINTABLE WHERE domain='${quote_mysql:$domain}' AND (type = 'relay' OR type = 'alias')
+hostlist   relay_from_hosts = 127.0.0.1
+domainlist mmdomains = ${lookup mysql {SELECT domain FROM mail_mailman_domain}}
+
+# acl_smtp_rcpt = acl_check_rcpt
+
+qualify_domain = 
+# qualify_recipient =
+
+# allow_domain_literals
+
+never_users = root
+trusted_users = mail
+
+host_lookup = *
+rfc1413_hosts = *
+rfc1413_query_timeout = 15s
+
+check_spool_space = 50M
+check_log_space = 20M
+return_size_limit = 20k
+message_size_limit = 20M
+
+# sender_unqualified_hosts =
+# recipient_unqualified_hosts =
+
+# percent_hack_domains =
+
+ignore_bounce_errors_after = 2d
+timeout_frozen_after = 7d
+
+deliver_queue_load_max = 8
+queue_only_load = 10
+remote_max_parallel = 15
+
+#tls_certificate = 
+#tls_privatekey = 
+#tls_advertise_hosts = *
+
+# SSL/TLS cert and key
+tls_certificate = /etc/exim4/smtpd.cert
+tls_privatekey = /etc/exim4/smtpd.key
+
+# Advertise TLS to anyone
+tls_advertise_hosts = *
+
+# Require auth over SSL only.
+# auth_over_tls_hosts = *
+
+helo_try_verify_hosts = !+relay_from_hosts
+
+av_scanner = clamd:/var/run/clamav/clamd.ctl
+spamd_address = 127.0.0.1 783
+
+acl_smtp_rcpt = acl_check_rcpt
+#acl_smtp_mail = acl_check_sender
+acl_smtp_connect = acl_check_host
+acl_smtp_data = acl_check_data
+acl_smtp_helo = acl_check_helo
+
+
+######################################################################
+#                       ACL CONFIGURATION                            #
+#         Specifies access control lists for incoming SMTP mail      #
+######################################################################
+
+begin acl
+
+acl_check_rcpt:
+
+  accept  hosts = :
+
+  deny    domains       = +local_domains
+          local_parts   = ^[.] : ^.*[@%!/|]
+
+  deny    domains       = !+local_domains
+          local_parts   = ^[./|] : ^.*[@%!] : ^.*/\\.\\./
+
+  accept  local_parts   = postmaster
+          domains       = +local_domains
+
+  require verify        = sender
+  
+  # Whitelist
+  
+
+  # Blacklist
+  deny    senders = ${lookup mysql {SELECT DISTINCT address FROM MYSQL_BLACKTABLE WHERE '${quote_mysql:$sender_address}' LIKE address \
+                                    AND (recipient = '' OR recipient = '${quote_mysql:$domain}' OR recipient = '${quote_mysql:$local_part}@${quote_mysql:$domain}') \
+                                    AND active = '1' AND server_id = 'MAILSERVER_ID'}{$value}}
+         log_message     = Blacklisted. Sender: <$sender_address> Recipient: <$local_part@$domain>
+
+  accept  domains       = +local_domains
+          endpass
+          verify        = recipient
+
+  accept  domains       = +relay_to_domains
+          endpass
+          verify        = recipient
+
+  accept  hosts         = +relay_from_hosts
+
+  accept  authenticated = *
+
+  deny    message       = relay not permitted
+
+
+acl_check_host:
+        accept
+                hosts = +relay_from_hosts
+        #deny    
+        #        log_message = match host_reject.list
+        #        hosts = /etc/exim4/filters/host_reject.list
+
+        accept
+
+acl_check_helo:
+        accept  hosts = +relay_from_hosts
+		# If the HELO pretend to be this host
+		deny	condition = ${if or { \
+						{eq {${lc:$sender_helo_name}}{MAILSERVER_HOSTNAME}} \
+						{eq {${lc:$sender_helo_name}}{MAILSERVER_IP}} \
+				    	} {true}{false} }
+        # by default we accept
+        accept
+
+
+acl_check_data:
+
+        accept  hosts = +relay_from_hosts
+
+        # if there is a windows executable as attachment then we reject
+        deny    message = This message contains an attachment of a type which we do not accept (.$found_extension) 
+                demime = bat:btm:cmd:com:cpl:dll:exe:lnk:msi:pif:prf:reg:scr:vbs:url
+
+        # spamassassin
+        warn    message = X-SA-Score: $spam_score 
+                spam = nobody:true
+
+        warn    message = X-SA-Report: $spam_report 
+                spam = nobody:true
+                condition = ${if >{$spam_score_int}{0}{true}{false}}
+        
+		warn    message = X-SA-Status: Yes 
+                spam = nobody:true
+                condition = ${if >{$spam_score_int}{50}{true}{false}}
+
+        deny    message = This message scored $spam_score spam points. 
+                spam = nobody:true 
+                condition = ${if >{$spam_score_int}{70}{true}{false}}
+
+        # clamav
+        deny    message = This message contains a virus or other harmful content ($malware_name)
+                demime = * 
+                malware = *
+                log_message = Virus found in Message
+
+        # accept by default
+        accept
+
+
+
+
+######################################################################
+#                      ROUTERS CONFIGURATION                         #
+#               Specifies how addresses are handled                  #
+######################################################################
+#     THE ORDER IN WHICH THE ROUTERS ARE DEFINED IS IMPORTANT!       #
+# An address is passed to each router in turn until it is accepted.  #
+######################################################################
+
+begin routers
+
+fail_router:
+  driver = redirect
+  domains = ${lookup mysql {SELECT SUBSTRING_INDEX(email,'@',-1) FROM MYSQL_EMAILTABLE WHERE email=CONCAT('${quote_mysql:$local_part}','@','${quote_mysql:$domain}') AND active='0'}{$value}}
+  data = ":fail:"
+  allow_fail
+
+domain_aliases:
+   driver=redirect
+   domains=${lookup mysql{SELECT domain FROM mail_domain WHERE domain='${domain}' AND type = 'alias'}}
+   data=$local_part@${lookup mysql{SELECT destination FROM mail_domain WHERE domain='${domain}'}}
+
+mailman_router:
+   driver = accept
+   domains = +mmdomains
+   require_files = MM_LISTCHK
+   local_part_suffix_optional
+   local_part_suffix =  -admin     : \
+            -bounces   : -bounces+* : \
+            -confirm   : -confirm+* : \
+            -join      : -leave     : \
+            -owner      : -request   : \
+            -subscribe : -unsubscribe
+   transport = mailman_transport
+
+dnslookup:
+  driver = dnslookup
+  domains = ! +local_domains
+  transport = remote_smtp
+  ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
+  no_more
+
+# Blacklists werden jetzt in den ACL geprüft
+#blacklist_router:
+#  driver = manualroute
+#  senders = ${lookup mysql {SELECT DISTINCT address FROM MYSQL_BLACKTABLE WHERE '${quote_mysql:$sender_address}' LIKE address AND recipient = '${quote_mysql:$local_part}@${quote_mysql:$domain}'}{$value}}
+#  # condition = "${if !def:h_X-Spam-Flag: {1}{0}}"
+#  # headers_add = X-Spam-Flag: YES
+#  route_list = * localhost
+#  # self = pass
+#  transport = devnull_transport
+#  verify = false
+
+#system_aliases:
+#  driver = redirect
+#  allow_fail
+#  allow_defer
+#  data = ${lookup{$local_part}lsearch{/etc/aliases}}
+#  user = exim
+#  file_transport = address_file
+#  pipe_transport = address_pipe
+
+#mysql_systemalias:
+#   driver = redirect
+#   allow_fail
+#   allow_defer
+#   data = ${lookup mysql{SELECT dest FROM mail_systemalias WHERE local_part='${quote_mysql:$local_part}'}}
+
+mysql_email_alias:
+   driver = redirect
+   allow_fail
+   allow_defer
+   data = ${lookup mysql{ SELECT destination FROM mail_redirect WHERE email='${quote_mysql:$local_part}@${quote_mysql:$domain}' AND type = 'alias'}}
+
+mysql_email_forward:
+   driver = redirect
+   data = ${lookup mysql{ SELECT destination FROM mail_redirect WHERE email='${quote_mysql:$local_part}@${quote_mysql:$domain}' AND type = 'forward'}}
+
+#spamcheck_router:
+#  driver = manualroute
+#  domains = ${lookup mysql {SELECT SUBSTRING_INDEX(email,'@',-1) FROM MYSQL_EMAILTABLE WHERE email=CONCAT('${quote_mysql:$local_part}','@','${quote_mysql:$domain}') AND spamscan='yes'}{$value}}
+#  senders = ! ${lookup mysql {SELECT DISTINCT MYSQL_WHITETABLE.address FROM MYSQL_WHITETABLE WHERE '${quote_mysql:$sender_address}' LIKE MYSQL_WHITETABLE.address}{$value}}
+#  condition = ${if and { \
+#    {!eq {$received_protocol}{spam-scanned}} \
+#    {!eq {$received_protocol}{local}} \
+#    } {1}{0}}
+#  headers_remove = X-Spam-Flag
+#  route_list = "* localhost byname"
+#  transport = spamcheck
+#  verify = false
+
+#spamdelete_router:
+#  driver = manualroute
+#  domains = ${lookup mysql {SELECT SUBSTRING_INDEX(email,'@',-1) FROM MYSQL_EMAILTABLE WHERE email=CONCAT('${quote_mysql:$local_part}','@','${quote_mysql:$domain}') AND spamdelete = '1'}{$value}}
+#  # condition = "${if eq{$h_X-Spam-Flag:}{YES} {1}{0}}"
+#  condition = "${if match{$h_X-Spam-Flag}{YES} {1}{0}}"
+#  route_list = "* localhost byname"
+#  transport = devnull_transport
+#  verify = false
+
+
+spamrewrite_router:
+  driver = manualroute
+  domains = ${lookup mysql {SELECT SUBSTRING_INDEX(email,'@',-1) FROM mail_spamfilter WHERE email='${quote_mysql:$local_part}@${quote_mysql:$domain}'}{$value}}
+  senders = ! ${lookup mysql {SELECT DISTINCT MYSQL_WHITETABLE.address FROM MYSQL_WHITETABLE WHERE '${quote_mysql:$sender_address}' LIKE MYSQL_WHITETABLE.address}{$value}}
+  condition = ${if and { \
+    {>{$spam_score_int}{${lookup mysql {SELECT spam_rewrite_score_int FROM mail_spamfilter WHERE email='${quote_mysql:$local_part}@${quote_mysql:$domain}'}{$value}}}}\
+    {!eq {$received_protocol}{spam-rewrite}} \
+    {!eq {$received_protocol}{local}} \
+    }{true}{false}}
+  headers_remove = Subject
+  headers_add = Subject: ${lookup mysql {SELECT spam_rewrite_subject FROM mail_spamfilter WHERE email='${quote_mysql:$local_part}@${quote_mysql:$domain}'}{$value}} $header_subject
+  route_list = "* localhost byname"
+  transport = spamrewrite_transport
+  verify = false
+
+spamredirect_router:
+  driver = manualroute
+  domains = ${lookup mysql {SELECT SUBSTRING_INDEX(email,'@',-1) FROM mail_spamfilter WHERE email='${quote_mysql:$local_part}@${quote_mysql:$domain}'}{$value}}
+  senders = ! ${lookup mysql {SELECT DISTINCT MYSQL_WHITETABLE.address FROM MYSQL_WHITETABLE WHERE '${quote_mysql:$sender_address}' LIKE MYSQL_WHITETABLE.address}{$value}}
+  condition = ${if >{$spam_score_int}{${lookup mysql {SELECT spam_redirect_score_int FROM mail_spamfilter WHERE email='${quote_mysql:$local_part}@${quote_mysql:$domain}'}{$value}}}{true}{false}}
+  route_list = "* localhost byname"
+  transport = spamredirect_transport
+  verify = false
+
+spamdelete_router:
+  driver = manualroute
+  domains = ${lookup mysql {SELECT SUBSTRING_INDEX(email,'@',-1) FROM mail_spamfilter WHERE email='${quote_mysql:$local_part}@${quote_mysql:$domain}'}{$value}}
+  senders = ! ${lookup mysql {SELECT DISTINCT MYSQL_WHITETABLE.address FROM MYSQL_WHITETABLE WHERE '${quote_mysql:$sender_address}' LIKE MYSQL_WHITETABLE.address}{$value}}
+  condition = ${if and { \
+    {>{$spam_score_int}{${lookup mysql {SELECT spam_delete_score_int FROM mail_spamfilter WHERE email='${quote_mysql:$local_part}@${quote_mysql:$domain}'}{$value}}}}\
+    {!eq {$received_protocol}{spam-rewrite}} \
+    {!eq {$received_protocol}{local}} \
+    }{true}{false}}
+  route_list = "* localhost byname"
+  transport = devnull_transport
+  verify = false
+
+autoresponder_router:
+  driver = accept
+  domains = ${lookup mysql {SELECT SUBSTRING_INDEX(email,'@',-1) FROM MYSQL_EMAILTABLE WHERE email=CONCAT('${quote_mysql:$local_part}','@','${quote_mysql:$domain}') AND autoresponder='yes'}{$value}}
+  transport = autoresponder_transport
+  unseen  
+
+# cc_router:
+#   driver = redirect
+#   data = ${lookup mysql {SELECT cc FROM MYSQL_EMAILTABLE WHERE email=CONCAT('${quote_mysql:$local_part}','@','${quote_mysql:$domain}')}{$value}}
+#   unseen
+
+# forward_router:
+#   driver = redirect
+#   data = ${lookup mysql {SELECT forward FROM MYSQL_EMAILTABLE WHERE email=CONCAT('${quote_mysql:$local_part}','@','${quote_mysql:$domain}') AND forward != ''}{$value}}
+
+local_mailbox_router:
+  driver = accept
+  domains = ${lookup mysql {SELECT SUBSTRING_INDEX(email,'@',-1) FROM MYSQL_EMAILTABLE WHERE email=CONCAT('${quote_mysql:$local_part}','@','${quote_mysql:$domain}') AND maildir != '' AND active = '1'}{$value}}
+  transport = local_delivery
+  
+mysql_catchall_router:
+   driver=redirect
+   data=${lookup mysql{ SELECT destination FROM mail_domain_catchall WHERE domain='${domain}'}}
+   allow_fail
+   allow_defer
+      
+######################################################################
+#                      TRANSPORTS CONFIGURATION                      #
+######################################################################
+#                       ORDER DOES NOT MATTER                        #
+#     Only one appropriate transport is called for each delivery.    #
+######################################################################
+
+begin transports
+
+########################
+# Remote smtp transport
+########################
+
+remote_smtp:
+  driver = smtp
+
+###################
+# Mailman transport
+###################
+
+mailman_transport:
+   driver = pipe
+   command = /var/mailman/lists.mas-services.co.uk/mail/mailman \
+            '${if def:local_part_suffix \
+            {${sg{$local_part_suffix}{-(\\w+)(\\+.*)?}{\$1}}} \
+            {post}}' \
+            $local_part
+   current_directory = ${lookup mysql{SELECT mm_home FROM mail_mailman_domain WHERE domain='${domain}'}}
+   home_directory = ${lookup mysql{SELECT mm_home FROM mail_mailman_domain WHERE domain='${domain}'}}
+   user = ${lookup mysql{SELECT mm_user FROM mail_mailman_domain WHERE domain='${domain}'}}
+   group = ${lookup mysql{SELECT mm_group FROM mail_mailman_domain WHERE domain='${domain}'}}
+
+
+#################################################################################
+# This transport is only for rewriting the header of the message with ***SPAM***
+#################################################################################
+
+spamrewrite_transport:
+  driver = pipe
+  command = MAILSERVER_EXIM_BINARY -oMr spam-rewrite -bS
+  use_bsmtp = true
+  home_directory = "/tmp"
+  current_directory = "/tmp"
+  user = mail
+  group = mail
+  log_output = true
+  return_fail_output = true
+  return_path_add = false
+  message_prefix =
+  message_suffix =
+
+######################################################
+# This transport is only for redirecting SPAM messages
+######################################################
+
+spamredirect_transport:
+  driver = appendfile
+  directory = ${lookup mysql {SELECT concat(spam_redirect_maildir,'/Maildir') FROM mail_spamfilter WHERE email='${quote_mysql:$local_part}@${quote_mysql:$domain}'}{$value}}
+  maildir_format
+  user = mail
+  group = mail
+  mode = 0660
+  directory_mode = 0770
+
+##########################
+# Local delivery transport
+##########################
+
+local_delivery:
+  driver = appendfile
+  directory = ${lookup mysql {SELECT concat(maildir,'/Maildir') FROM MYSQL_EMAILTABLE WHERE email=CONCAT('${quote_mysql:$local_part}','@','${quote_mysql:$domain}')}{$value}}
+  maildir_format
+  user = mail
+  group = mail
+  quota = ${lookup mysql{select quota from MYSQL_EMAILTABLE where email=CONCAT('${quote_mysql:$local_part}','@','${quote_mysql:$domain}')}{${value}M}}
+  quota_is_inclusive = false
+  maildir_tag = ,S=$message_size
+  quota_size_regex = ,S=(\d+):
+  quota_warn_threshold = 75%
+  maildir_use_size_file = false
+  quota_warn_message = "To: $local_part@$domain\n\
+  			Subject: Mailbox quota warning\n\n\
+			This message was automatically generated by the mail delivery software.\n\n\
+			You are now using over 75% of your allocated mail storage quota.\n\n\
+			If your mailbox fills completely, further incoming messages will be automatically\n\
+			returned to their senders.\n\n\
+			Please take note of this and remove unwanted mail from your mailbox.\n"
+  mode = 0660
+  directory_mode = 0770
+
+##########################
+# autoresponder transport
+##########################
+
+autoresponder_transport:
+  driver = autoreply
+  to = ${sender_address}
+  from = "vacation@${domain}"
+  subject = "Autoresponder: ${local_part}@${domain}"
+  text = ${lookup mysql {SELECT autoresponder_text FROM MYSQL_EMAILTABLE WHERE email=CONCAT('${quote_mysql:$local_part}','@','${quote_mysql:$domain}')}{$value}}
+
+##########################
+# devnull transport
+##########################
+
+devnull_transport:
+  driver = appendfile
+  file = /dev/null
+  user = mail
+
+
+######################################################################
+#                      RETRY CONFIGURATION                           #
+######################################################################
+
+begin retry
+
+# This single retry rule applies to all domains and all errors. It specifies
+# retries every 15 minutes for 2 hours, then increasing retry intervals,
+# starting at 1 hour and increasing each time by a factor of 1.5, up to 16
+# hours, then retries every 6 hours until 4 days have passed since the first
+# failed delivery.
+
+# Domain               Error       Retries
+# ------               -----       -------
+
+*                      *           F,2h,15m; G,16h,1h,1.5; F,4d,6h
+
+
+
+######################################################################
+#                      REWRITE CONFIGURATION                         #
+######################################################################
+
+# There are no rewriting specifications in this default configuration file.
+begin rewrite
+
+
+
+######################################################################
+#                   AUTHENTICATION CONFIGURATION                     #
+######################################################################
+
+# There are no authenticator specifications in this default configuration file.
+
+begin authenticators
+
+fixed_plain:
+  driver = plaintext
+  public_name = PLAIN
+  server_condition = ${lookup mysql{SELECT email FROM MYSQL_EMAILTABLE WHERE email='${quote_mysql:$2}' AND cryptpwd=encrypt('${quote_mysql:$3}', cryptpwd) AND active = '1'}{1}fail}
+  server_set_id = $2
+
+fixed_login:
+  driver = plaintext
+  public_name = LOGIN
+  server_prompts = "Username:: : Password::"
+  server_condition = ${lookup mysql{SELECT email FROM MYSQL_EMAILTABLE WHERE email='${quote_mysql:$1}' AND cryptpwd=encrypt('${quote_mysql:$2}', cryptpwd) AND active = '1'}{1}fail}
+  server_set_id = $1
+  
+cram:
+  driver = cram_md5
+  public_name = CRAM-MD5
+  server_secret = "${lookup mysql {SELECT clearpwd FROM mail_box WHERE email = '${sg {$1}{'}{}}' AND active = '1'} {$value} fail}"
+  server_set_id = $1
+
+
+######################################################################
+#                   CONFIGURATION FOR local_scan()                   #
+######################################################################
+
+# If you have built Exim to include a local_scan() function that contains
+# tables for private options, you can define those options here. Remember to
+# uncomment the "begin" line. It is commented by default because it provokes
+# an error with Exim binaries that are not built with LOCAL_SCAN_HAS_OPTIONS
+# set in the Local/Makefile.
+
+# begin local_scan
+
+
+# End of Exim configuration file
+
diff --git a/interface/lib/classes/datasources_enbion.inc.php b/interface/lib/classes/datasources_enbion.inc.php
new file mode 100644
index 0000000000000000000000000000000000000000..11e035ce5882a387ab00f3572c0a70ca596f749b
--- /dev/null
+++ b/interface/lib/classes/datasources_enbion.inc.php
@@ -0,0 +1,53 @@
+<?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 datasources_enbion {
+	
+	function get_employees() {
+		global $app, $conf;
+		
+		$out = array();
+		
+		// Empty item for userlist
+		$out[0] = '';
+		
+		$records = $app->db->queryAllRecords("SELECT * FROM sys_user ORDER BY username");
+		foreach($records as $rec) {
+			$key = $rec["userid"];
+			$out[$key] = $rec['username'];
+		}
+		
+		return $out;
+	}
+	
+	
+}
+
+?>
\ No newline at end of file
diff --git a/interface/lib/classes/db_mysql.inc.php b/interface/lib/classes/db_mysql.inc.php
index bc26ac5670500cbe03e597ff7548caf0bf763413..25ef1312fed57a753dff1e3084a7d9eca9a54e1b 100644
--- a/interface/lib/classes/db_mysql.inc.php
+++ b/interface/lib/classes/db_mysql.inc.php
@@ -147,6 +147,11 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 			return mysql_num_rows($this->queryId);
 		}
 		
+		function affectedRows()
+		{
+			return mysql_affected_rows($this->linkId);
+		}
+		
 		// returns mySQL insert id
 		function insertID()
 		{
@@ -256,12 +261,23 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        foreach($columns as $col){
             $sql .= $col["name"]." ".$this->mapType($col["type"],$col["typeValue"])." ";
        
-            if($col["defaultValue"] != "") $sql .= "DEFAULT '".$col["defaultValue"]."' ";
-            if($col["notNull"] == true) {
-                $sql .= "NOT NULL ";
-            } else {
-                $sql .= "NULL ";
-            }
+            if($col["defaultValue"] != "") {
+				if($col["defaultValue"] == "NULL" or $col["defaultValue"] == "NOT NULL") {
+					$sql .= "DEFAULT ".$col["defaultValue"]." ";
+				} else {
+					$sql .= "DEFAULT '".$col["defaultValue"]."' ";
+				}
+				
+			} elseif($col["defaultValue"] != false) {
+				$sql .= "DEFAULT '' ";
+			}
+			if($col["defaultValue"] != "NULL" && $col["defaultValue"] != "NOT NULL") {
+            	if($col["notNull"] == true) {
+                	$sql .= "NOT NULL ";
+            	} else {
+                	$sql .= "NULL ";
+            	}
+			}
             if($col["autoInc"] == true) $sql .= "auto_increment ";
             $sql.= ",";
             // key Definitionen
diff --git a/interface/lib/classes/listform.inc.php b/interface/lib/classes/listform.inc.php
index 53dd24f42692179ec2cd644cb3fc03bc58889d15..21c18f0c226b365499d59ac12feab166378e2154 100644
--- a/interface/lib/classes/listform.inc.php
+++ b/interface/lib/classes/listform.inc.php
@@ -1,329 +1,344 @@
-<?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.
-*/
-
-/**
-* Listenbehandlung
-*
-* @package listform
-* @author Till Brehm
-* @version 1.1
-*/
-
-class listform {
-
-        var $debug = 0;
-        var $errorMessage;
-    var $listDef;
-        var $searchValues;
-        var $pagingHTML;
-        var $pagingValues;
-        var $searchChanged = 0;
-        var $module;
-
-    function loadListDef($file,$module = '') {
-                global $app,$conf;
-                if(!is_file($file)) die("List-Definition: $file not found.");
-                include_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 key => value array for the value field of a form
-        */
-
-        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);
-                        $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;
-
-        }
-
-        function getSearchSQL($sql_where = "") {
-                global $db;
-
-                // Hole Config Variablen
-                $list_name = $this->listDef["name"];
-                $search_prefix = $this->listDef["search_prefix"];
-
-                // speichere Suchanfrage
-                foreach($this->listDef["item"] as $i) {
-                        $field = $i["field"];
-
-                        // hat sich die suche geändert
-                        if(isset($_REQUEST[$search_prefix.$field]) and $_REQUEST[$search_prefix.$field] != $_SESSION["search"][$list_name][$search_prefix.$field]) $this->searchChanged = 1;
-
-                        // suchfeld in session speichern.
-                        if(isset($_REQUEST[$search_prefix.$field])) $_SESSION["search"][$list_name][$search_prefix.$field] = $_REQUEST[$search_prefix.$field];
-
-                        if($i["formtype"] == "SELECT") {
-                                if(is_array($i['value'])) {
-                                        $out = '<option value=""></option>';
-                                        foreach($i['value'] as $k => $v) {
-                                                $selected = ($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 {
-                                $this->searchValues[$search_prefix.$field] = $_SESSION["search"][$list_name][$search_prefix.$field];
-                        }
-                }
-
-                // Speichere Variablen in Objekt zum späteren einparsen in Template
-                // $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($_SESSION["search"][$list_name][$search_prefix.$field] != '') $sql_where .= " $field ".$i["op"]." '".$i["prefix"].$_SESSION["search"][$list_name][$search_prefix.$field].$i["suffix"]."' and";
-                }
-
-                if($sql_where != '') {
-                        $sql_where = substr($sql_where,0,-3);
-                } else {
-                        $sql_where = "1";
-                }
-
-
-                return $sql_where;
-        }
-
-        function getPagingSQL($sql_where = "1") {
-                global $app, $conf;
-
-                // Hole Config Variablen
-                $list_name                         = $this->listDef["name"];
-                $search_prefix                 = $this->listDef["search_prefix"];
-                $records_per_page         = $this->listDef["records_per_page"];
-                $table                                 = $this->listDef["table"];
-
-                // setze page auf null, wenn in session nicht gesetzt
-                if($_SESSION["search"][$list_name]["page"] == '') $_SESSION["search"][$list_name]["page"] = 0;
-
-                // setze page auf wert der request variablen "page"
-                if(isset($_REQUEST["page"])) $_SESSION["search"][$list_name]["page"] = $_REQUEST["page"];
-
-                // 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"] / $records_per_page);
-
-
-                $vars["list_file"] = $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"] = $this->listDef["page_params"];
-
-
-                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);
-
-                $limit_sql = "LIMIT $sql_von, $records_per_page";
-
-                return $limit_sql;
-        }
-
-        function getPagingHTML($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;
-        }
-
-        function getSortSQL() {
-                global $app, $conf;
-
-                // Hole Config Variablen
-                $sort_field = $this->listDef["sort_field"];
-                $sort_direction = $this->listDef["sort_direction"];
-
-                $sql_sort = '';
-
-                if($sort_field != '' && $sort_direction != '') {
-                        $sql_sort = "ORDER BY $sort_field $sort_direction";
-                }
-
-                return $sql_sort;
-        }
-
-        function decode($record) {
-                if(is_array($record)) {
-                        foreach($this->listDef["item"] as $field) {
-                                $key = $field["field"];
-                                switch ($field['datatype']) {
-                                case 'VARCHAR':
-                                        $record[$key] = stripslashes($record[$key]);
-                                break;
-
-                                case 'TEXT':
-                                        $record[$key] = stripslashes($record[$key]);
-                                break;
-
-                                case 'DATE':
-                                        if($val > 0) {
-                                                $record[$key] = 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;
-        }
-
-
-        function encode($record) {
-
-                if(is_array($record)) {
-                        foreach($this->listDef["item"] as $field) {
-                                $key = $field["field"];
-                                switch ($field['datatype']) {
-                                case 'VARCHAR':
-                                        if(!is_array($record[$key])) {
-                                                $record[$key] = addslashes($record[$key]);
-                                        } else {
-                                                $record[$key] = implode($this->tableDef[$key]['separator'],$record[$key]);
-                                        }
-                                break;
-                                case 'TEXT':
-                                        if(!is_array($record[$key])) {
-                                                $record[$key] = addslashes($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] = addslashes($record[$key]);
-                                break;
-                                case 'CURRENCY':
-                                        $record[$key] = str_replace(",",".",$record[$key]);
-                                break;
-                                }
-
-                        }
-                }
-                return $record;
-        }
-
-}
-
+<?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.
+*/
+
+/**
+* Listenbehandlung
+*
+* @package listform
+* @author Till Brehm
+* @version 1.1
+*/
+
+class listform {
+
+        var $debug = 0;
+        var $errorMessage;
+    var $listDef;
+        var $searchValues;
+        var $pagingHTML;
+        var $pagingValues;
+        var $searchChanged = 0;
+        var $module;
+		var $dateformat = 'd.m.Y';
+
+    function loadListDef($file,$module = '') {
+                global $app,$conf;
+                if(!is_file($file)) die("List-Definition: $file not found.");
+                include_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 key => value array for the value field of a form
+        */
+
+        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);
+                        $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;
+
+        }
+
+        function getSearchSQL($sql_where = "") {
+                global $db;
+
+                // Hole Config Variablen
+                $list_name = $this->listDef["name"];
+                $search_prefix = $this->listDef["search_prefix"];
+
+                // speichere Suchanfrage
+                foreach($this->listDef["item"] as $i) {
+                        $field = $i["field"];
+
+                        // hat sich die suche geändert
+                        if(isset($_REQUEST[$search_prefix.$field]) and $_REQUEST[$search_prefix.$field] != $_SESSION["search"][$list_name][$search_prefix.$field]) $this->searchChanged = 1;
+
+                        // suchfeld in session speichern.
+                        if(isset($_REQUEST[$search_prefix.$field])) $_SESSION["search"][$list_name][$search_prefix.$field] = $_REQUEST[$search_prefix.$field];
+
+                        if($i["formtype"] == "SELECT") {
+                                if(is_array($i['value'])) {
+                                        $out = '<option value=""></option>';
+                                        foreach($i['value'] as $k => $v) {
+                                                $selected = ($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 {
+                                $this->searchValues[$search_prefix.$field] = $_SESSION["search"][$list_name][$search_prefix.$field];
+                        }
+                }
+
+                // Speichere Variablen in Objekt zum späteren einparsen in Template
+                // $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($_SESSION["search"][$list_name][$search_prefix.$field] != '') $sql_where .= " $field ".$i["op"]." '".$i["prefix"].$_SESSION["search"][$list_name][$search_prefix.$field].$i["suffix"]."' and";
+                }
+
+                if($sql_where != '') {
+                        $sql_where = substr($sql_where,0,-3);
+                } else {
+                        $sql_where = "1";
+                }
+
+
+                return $sql_where;
+        }
+
+        function getPagingSQL($sql_where = "1") {
+                global $app, $conf;
+
+                // Hole Config Variablen
+                $list_name                         = $this->listDef["name"];
+                $search_prefix                 = $this->listDef["search_prefix"];
+                $records_per_page         = $this->listDef["records_per_page"];
+                $table                                 = $this->listDef["table"];
+
+                // setze page auf null, wenn in session nicht gesetzt
+                if($_SESSION["search"][$list_name]["page"] == '') $_SESSION["search"][$list_name]["page"] = 0;
+
+                // setze page auf wert der request variablen "page"
+                if(isset($_REQUEST["page"])) $_SESSION["search"][$list_name]["page"] = $_REQUEST["page"];
+
+                // 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"] = $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"] = $this->listDef["page_params"];
+
+
+                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);
+
+                $limit_sql = "LIMIT $sql_von, $records_per_page";
+
+                return $limit_sql;
+        }
+
+        function getPagingHTML($vars) {
+                global $app;
+                $content = '<a href="'.$vars["list_file"].'?page=0'.$vars["page_params"].'"><img src="../themes/iprg/images/btn_left.png" border="0"></a> &nbsp; ';
+                if($vars["show_page_back"] == 1) $content .= '<a href="'.$vars["list_file"].'?page='.$vars["last_page"].$vars["page_params"].'"><img src="../themes/iprg/images/btn_back.png" border="0"></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"].'"><img src="../themes/iprg/images/btn_next.png" border="0"></a> &nbsp; ';
+                $content .= '<a href="'.$vars["list_file"].'?page='.$vars["pages"].$vars["page_params"].'"> <img src="../themes/iprg/images/btn_right.png" border="0"></a>';
+
+                return $content;
+        }
+		
+		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;
+        }
+
+        function getSortSQL() {
+                global $app, $conf;
+
+                // Hole Config Variablen
+                $sort_field = $this->listDef["sort_field"];
+                $sort_direction = $this->listDef["sort_direction"];
+
+                $sql_sort = '';
+
+                if($sort_field != '' && $sort_direction != '') {
+                        $sql_sort = "ORDER BY $sort_field $sort_direction";
+                }
+
+                return $sql_sort;
+        }
+
+        function decode($record) {
+                if(is_array($record)) {
+                        foreach($this->listDef["item"] as $field) {
+                                $key = $field["field"];
+                                switch ($field['datatype']) {
+                                case 'VARCHAR':
+                                        $record[$key] = stripslashes($record[$key]);
+                                break;
+
+                                case 'TEXT':
+                                        $record[$key] = stripslashes($record[$key]);
+                                break;
+
+                                case 'DATE':
+                                        if($record[$key] > 0) {
+                                                $record[$key] = date($this->dateformat,$record[$key]);
+                                        } else {
+											$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;
+        }
+
+
+        function encode($record) {
+
+                if(is_array($record)) {
+                        foreach($this->listDef["item"] as $field) {
+                                $key = $field["field"];
+                                switch ($field['datatype']) {
+                                case 'VARCHAR':
+                                        if(!is_array($record[$key])) {
+                                                $record[$key] = addslashes($record[$key]);
+                                        } else {
+                                                $record[$key] = implode($this->tableDef[$key]['separator'],$record[$key]);
+                                        }
+                                break;
+                                case 'TEXT':
+                                        if(!is_array($record[$key])) {
+                                                $record[$key] = addslashes($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] = addslashes($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 012ebd93dfb88f0f8d35daf9f34a976b7ca81a87..519d661fa28cfc55e3966b56f59ec7fe3eb42600 100644
--- a/interface/lib/classes/listform_actions.inc.php
+++ b/interface/lib/classes/listform_actions.inc.php
@@ -1,154 +1,160 @@
-<?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 {
-	
-	var $id;
-	var $idx_key;
-	var $DataRowColor;
-	var $SQLExtWhere = '';
-	
-	function onLoad() {
-		global $app, $conf, $list_def_file;
-		
-		if(!is_object($app->tpl)) $app->uses('tpl');
-		if(!is_object($app->listform)) $app->uses('listform');
-		if(!is_object($app->tform)) $app->uses('tform');
-		
-		// 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("form.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";
-		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();
-		
-		
-	}
-	
-	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($field['formtype'] == "SELECT") {
-				$rec[$key] = $field['value'][$rec[$key]];
-			}
-		}
-		
-		// The variable "id" contains always the index variable
-		$rec["id"] = $rec[$this->idx_key];
-		
-		return $rec;
-	}
-	
-	function getQueryString() {
-		global $app;
-		
-		// 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);
-
-		// 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 $limit_sql";
-		
-	}
-	
-	
-	function onShow() {
-		global $app;
-		
-		// Language File setzen
-		$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();
-	}
-	
-	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 {
+	
+	var $id;
+	var $idx_key;
+	var $DataRowColor;
+	var $SQLExtWhere = '';
+	var $SQLOrderBy = '';
+	
+	function onLoad() {
+		global $app, $conf, $list_def_file;
+		
+		if(!is_object($app->tpl)) $app->uses('tpl');
+		if(!is_object($app->listform)) $app->uses('listform');
+		if(!is_object($app->tform)) $app->uses('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";
+		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();
+		
+		
+	}
+	
+	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($field['formtype'] == "SELECT") {
+				$rec[$key] = $field['value'][$rec[$key]];
+			}
+		}
+		
+		// The variable "id" contains always the index variable
+		$rec["id"] = $rec[$this->idx_key];
+		
+		return $rec;
+	}
+	
+	function getQueryString() {
+		global $app;
+		
+		// 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";
+		
+	}
+	
+	
+	function onShow() {
+		global $app;
+		
+		// Language File setzen
+		$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();
+	}
+	
+	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 cc80cc4429712787a379dd768f6733cc2c1d5d8a..23c38cd2ba7dedfc2f6d91a8eb9aeb9b7c7de572 100644
--- a/interface/lib/classes/listform_tpl_generator.inc.php
+++ b/interface/lib/classes/listform_tpl_generator.inc.php
@@ -56,7 +56,11 @@ class listform_tpl_generator {
   
   		foreach($listDef["item"] as $field) {
 			$key = $field["field"];
-			$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";
+			if($field["formtype"] == 'SELECT') {
+				$html .= "    <td class=\"frmText11\"><select name=\"".$listDef["search_prefix"].$key."\" onChange=\"document.myform.submit();\">{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="submit" id="Filter" value="{tmpl_var name="filter_txt"}"></td>
@@ -112,10 +116,10 @@ class listform_tpl_generator {
     }
 	
 	function lng_add($lang,$listDef,$module = '') {
-		global $go_api, $go_info;
+		global $go_api, $go_info,$conf;
 		
 		if($module == '') {
-			$lng_file = "lib/lang/en_".$listDef['name']."_list.lng";
+			$lng_file = "lib/lang/".$conf["language"]."_".$listDef['name']."_list.lng";
 		} else {
 			$lng_file = '../'.$module."/lib/lang/en_".$listDef['name']."_list.lng";
 		}
diff --git a/interface/lib/classes/plugin_base.inc.php b/interface/lib/classes/plugin_base.inc.php
index f39cc72c713ac6f7c8c0157da495e8dfcc71b7ee..1ac14829b851eda0c65f0fefed82937135ce5ef3 100644
--- a/interface/lib/classes/plugin_base.inc.php
+++ b/interface/lib/classes/plugin_base.inc.php
@@ -4,6 +4,7 @@ class plugin_base {
 	
 	var $plugin_name;
 	var $options;
+	var $form;
 	
 	function onLoad() {
 	
diff --git a/interface/lib/classes/plugin_dbhistory.inc.php b/interface/lib/classes/plugin_dbhistory.inc.php
new file mode 100644
index 0000000000000000000000000000000000000000..6f06430a85642e24dbbd5297de360a7b0aa516d1
--- /dev/null
+++ b/interface/lib/classes/plugin_dbhistory.inc.php
@@ -0,0 +1,41 @@
+<?php
+
+class plugin_dbhistory extends plugin_base {
+
+        var $module;
+        var $form;
+        var $tab;
+        var $record_id;
+        var $formdef;
+        var $options;
+
+        function onShow() {
+		
+			global $app, $conf;
+			
+			$content = '';
+			
+			$db_table = $app->tform->formDef["db_table"];
+			$db_table_idx = $app->tform->formDef["db_table_idx"];
+			$primary_id = $this->form->id;
+			if($_SESSION["s"]["user"]["typ"] == 'admin') {
+				$sql = "SELECT action, tstamp, user, data FROM sys_datalog WHERE dbtable = '".$db_table."' AND dbidx = '".$db_table_idx.":".$primary_id."'";
+			} else {
+				$sql = "SELECT action, tstamp, user, data FROM sys_datalog WHERE user = '".$_SESSION["s"]["user"]["username"]."' dbtable = '".$db_table."' AND dbidx = '".$db_table_idx.":".$primary_id."'";
+			}
+			
+			$records = $app->db->queryAllRecords($sql);
+			if(is_array($records)) {
+				$content .= '<table width="100%">';
+				foreach($records as $rec) {
+					$content .= "<tr><td class='frmText11' bgcolor='#EEEEEE'><b>".date("d.m.Y",$rec["tstamp"])." ".$rec["user"]."</b></td></tr>";
+				}
+				$content .= '</table>';
+			}
+			
+			return $content;
+
+        }
+}
+
+?>
\ No newline at end of file
diff --git a/interface/lib/classes/plugin_listview.inc.php b/interface/lib/classes/plugin_listview.inc.php
index fe57834ad0e2a3df789734c3827259315509d502..32fe3014b547e814234177e0d0a3e14e9333b27e 100644
--- a/interface/lib/classes/plugin_listview.inc.php
+++ b/interface/lib/classes/plugin_listview.inc.php
@@ -20,10 +20,13 @@ class plugin_listview extends plugin_base {
 
                 $listTpl = new tpl;
                 $listTpl->newTemplate('templates/'.$app->listform->listDef["name"].'_list.htm');
+				
+				//die(print_r($app->tform_actions));
 
                 // Changing some of the list values to reflect that the list is called within a tform page
                 $app->listform->listDef["file"] = $app->tform->formDef["action"];
-                $app->listform->listDef["page_params"] = "&id=".$app->tform_actions->id."&next_tab=".$_SESSION["s"]["form"]["tab"];
+                // $app->listform->listDef["page_params"] = "&id=".$app->tform_actions->id."&next_tab=".$_SESSION["s"]["form"]["tab"];
+				$app->listform->listDef["page_params"] = "&id=".$_REQUEST["id"]."&next_tab=".$_SESSION["s"]["form"]["tab"];
 
 
                 // Generate the SQL for searching
@@ -45,6 +48,8 @@ class plugin_listview extends plugin_base {
                 // Generate SQL for paging
                 $limit_sql = $app->listform->getPagingSQL($sql_where);
                 $listTpl->setVar("paging",$app->listform->pagingHTML);
+				
+				
 
                 // Get the data
                 $records = $app->db->queryAllRecords("SELECT * FROM ".$app->listform->listDef["table"]." WHERE $sql_where $limit_sql");
@@ -59,6 +64,14 @@ class plugin_listview extends plugin_base {
                                 // Change of color
                                 $bgcolor = ($bgcolor == "#FFFFFF")?"#EEEEEE":"#FFFFFF";
                                 $rec["bgcolor"] = $bgcolor;
+								
+								// substitute value for select fields
+								foreach($app->listform->listDef["item"] as $field) {
+									$key = $field["field"];
+									if($field['formtype'] == "SELECT") {
+										$rec[$key] = $field['value'][$rec[$key]];
+									}
+								}
 
                                 // The variable "id" contains always the index field
                                 $rec["id"] = $rec[$idx_key];
diff --git a/interface/lib/classes/searchform.inc.php b/interface/lib/classes/searchform.inc.php
new file mode 100644
index 0000000000000000000000000000000000000000..9102e8e5496a90760e91e242fafb7c2d7083abdd
--- /dev/null
+++ b/interface/lib/classes/searchform.inc.php
@@ -0,0 +1,364 @@
+<?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.
+*/
+
+/**
+* Listenbehandlung
+*
+* @package searchform
+* @author Till Brehm
+* @version 1.1
+*/
+
+class searchform {
+
+        var $debug = 0;
+        var $errorMessage;
+    var $listDef;
+        var $searchValues;
+        var $pagingHTML;
+        var $pagingValues;
+        var $searchChanged = 0;
+        var $module;
+
+    function loadListDef($file,$module = '') {
+                global $app,$conf;
+                if(!is_file($file)) die("List-Definition: $file not found.");
+                include_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 key => value array for the value field of a form
+        */
+
+        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);
+                        $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;
+
+        }
+
+        function getSearchSQL($sql_where = "") {
+                global $db;
+
+                // Hole Config Variablen
+                $list_name = $this->listDef["name"];
+                $search_prefix = $this->listDef["search_prefix"];
+
+                // speichere Suchanfrage
+                foreach($this->listDef["item"] as $i) {
+                        $field = $i["field"];
+
+                        // hat sich die suche geändert
+                        if(isset($_REQUEST[$search_prefix.$field]) and $_REQUEST[$search_prefix.$field] != $_SESSION["search"][$list_name][$search_prefix.$field]) $this->searchChanged = 1;
+
+                        // suchfeld in session speichern.
+                        if(isset($_REQUEST[$search_prefix.$field])) $_SESSION["search"][$list_name][$search_prefix.$field] = $_REQUEST[$search_prefix.$field];
+
+                        if($i["formtype"] == "SELECT") {
+                                if(is_array($i['value'])) {
+                                        $out = '<option value=""></option>';
+                                        foreach($i['value'] as $k => $v) {
+                                                $selected = ($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 {
+                                $this->searchValues[$search_prefix.$field] = $_SESSION["search"][$list_name][$search_prefix.$field];
+                        }
+                }
+
+                // Speichere Variablen in Objekt zum späteren einparsen in Template
+                // $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($_SESSION["search"][$list_name][$search_prefix.$field] != '') $sql_where .= " $field ".$i["op"]." '".$i["prefix"].$_SESSION["search"][$list_name][$search_prefix.$field].$i["suffix"]."' and";
+                }
+
+                if($sql_where != '') {
+                        $sql_where = substr($sql_where,0,-3);
+                } else {
+                        $sql_where = "1";
+                }
+
+
+                return $sql_where;
+        }
+
+        function getPagingSQL($sql_where = "1") {
+                global $app, $conf;
+
+                // Hole Config Variablen
+                $list_name                         = $this->listDef["name"];
+                $search_prefix                 = $this->listDef["search_prefix"];
+                $records_per_page         = $this->listDef["records_per_page"];
+                $table                                 = $this->listDef["table"];
+
+                // setze page auf null, wenn in session nicht gesetzt
+                if($_SESSION["search"][$list_name]["page"] == '') $_SESSION["search"][$list_name]["page"] = 0;
+
+                // setze page auf wert der request variablen "page"
+                if(isset($_REQUEST["page"])) $_SESSION["search"][$list_name]["page"] = $_REQUEST["page"];
+
+                // 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"] = $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"] = $this->listDef["page_params"];
+
+
+                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);
+
+                $limit_sql = "LIMIT $sql_von, $records_per_page";
+
+                return $limit_sql;
+        }
+
+        function getPagingHTML($vars) {
+                global $app;
+                $content = '<a href="'.$vars["list_file"].'?page=0'.$vars["page_params"].'"><img src="../themes/iprg/images/btn_left.png" border="0"></a> &nbsp; ';
+                if($vars["show_page_back"] == 1) $content .= '<a href="'.$vars["list_file"].'?page='.$vars["last_page"].$vars["page_params"].'"><img src="../themes/iprg/images/btn_back.png" border="0"></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"].'"><img src="../themes/iprg/images/btn_next.png" border="0"></a> &nbsp; ';
+                $content .= '<a href="'.$vars["list_file"].'?page='.$vars["pages"].$vars["page_params"].'"> <img src="../themes/iprg/images/btn_right.png" border="0"></a>';
+
+                return $content;
+        }
+		
+		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;
+        }
+
+        function getSortSQL() {
+                global $app, $conf;
+
+                // Hole Config Variablen
+                $sort_field = $this->listDef["sort_field"];
+                $sort_direction = $this->listDef["sort_direction"];
+
+                $sql_sort = '';
+
+                if($sort_field != '' && $sort_direction != '') {
+                        $sql_sort = "ORDER BY $sort_field $sort_direction";
+                }
+
+                return $sql_sort;
+        }
+		
+		function saveSearchSettings($searchresult_name) {
+			global $app, $conf;
+			
+			$list_name = $this->listDef["name"];
+			$settings = $_SESSION["search"][$list_name];
+			unset($settings["page"]);
+			$data = addslashes(serialize($settings));
+			
+			$userid = $_SESSION["s"]["user"]["userid"];
+			$groupid = $_SESSION["s"]["user"]["default_group"];
+			$sys_perm_user = 'riud';
+			$sys_perm_group = 'r';
+			$sys_perm_other = '';
+			$module = $_SESSION["s"]["module"]["name"];
+			$searchform = $this->listDef["name"];
+			$title = $searchresult_name;
+			
+			$sql = " INSERT INTO `searchform` ( `sys_userid` , `sys_groupid` , `sys_perm_user` , `sys_perm_group` , `sys_perm_other` , `module` , `searchform` , `title` , `data` )
+						VALUES ('$userid', '$groupid', '$sys_perm_user', '$sys_perm_group', '$sys_perm_other', '$module', '$searchform', '$title', '$data')";
+			
+			//die($sql);
+			$app->db->query($sql);
+		}
+
+        function decode($record) {
+                if(is_array($record)) {
+                        foreach($this->listDef["item"] as $field) {
+                                $key = $field["field"];
+                                switch ($field['datatype']) {
+                                case 'VARCHAR':
+                                        $record[$key] = stripslashes($record[$key]);
+                                break;
+
+                                case 'TEXT':
+                                        $record[$key] = stripslashes($record[$key]);
+                                break;
+
+                                case 'DATE':
+                                        if($val > 0) {
+                                                $record[$key] = 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;
+        }
+
+
+        function encode($record) {
+
+                if(is_array($record)) {
+                        foreach($this->listDef["item"] as $field) {
+                                $key = $field["field"];
+                                switch ($field['datatype']) {
+                                case 'VARCHAR':
+                                        if(!is_array($record[$key])) {
+                                                $record[$key] = addslashes($record[$key]);
+                                        } else {
+                                                $record[$key] = implode($this->tableDef[$key]['separator'],$record[$key]);
+                                        }
+                                break;
+                                case 'TEXT':
+                                        if(!is_array($record[$key])) {
+                                                $record[$key] = addslashes($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] = addslashes($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/searchform_actions.inc.php b/interface/lib/classes/searchform_actions.inc.php
new file mode 100644
index 0000000000000000000000000000000000000000..97b5ab032cfd4fc9fa7a4c9bf55912ad19743617
--- /dev/null
+++ b/interface/lib/classes/searchform_actions.inc.php
@@ -0,0 +1,199 @@
+<?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 searchform library.
+*
+* @author Till Brehm <t.brehm@scrigo.org>
+* @copyright Copyright &copy; 2005, Till Brehm
+*/
+
+class searchform_actions {
+	
+	var $id;
+	var $idx_key;
+	var $DataRowColor;
+	var $SQLExtWhere = '';
+	var $SQLOrderBy = '';
+	
+	function onLoad() {
+		global $app, $conf, $list_def_file;
+		
+		if(!is_object($app->tpl)) $app->uses('tpl');
+		if(!is_object($app->searchform)) $app->uses('searchform');
+		if(!is_object($app->tform)) $app->uses('tform');
+		
+		// Load list definition
+		$app->searchform->loadListDef($list_def_file);
+		
+		// Delete the search form contents, if requested
+		if($_REQUEST["empty_searchfields"] == 'yes') {
+			$list_name = $app->searchform->listDef["name"];
+			unset($_SESSION["search"][$list_name]);
+		}
+		
+		// Save the search for later usage
+		if($_REQUEST["btn_submit_search_save"] && $_REQUEST["search_save_as"] != '') {
+			$app->searchform->saveSearchSettings($_REQUEST["search_save_as"]);
+		}
+		
+		// Set th returnto value for forms
+		$_SESSION["s"]["form"]["return_to_url"] = $app->searchform->listDef["file"];
+		
+		if(!is_file('templates/'.$app->searchform->listDef["name"].'_search.htm')) {
+			$app->uses('searchform_tpl_generator');
+			$app->searchform_tpl_generator->buildHTML($app->searchform->listDef);
+		}
+		
+		$app->tpl->newTemplate("searchpage.tpl.htm");
+		$app->tpl->setInclude('content_tpl','templates/'.$app->searchform->listDef["name"].'_search.htm');
+
+		// Getting Datasets from DB
+		$records = $app->db->queryAllRecords($this->getQueryString());
+
+
+		$this->DataRowColor = "#FFFFFF";
+		if(is_array($records)) {
+			$this->idx_key = $app->searchform->listDef["table_idx"]; 
+			foreach($records as $rec) {
+				$records_new[] = $this->prepareDataRow($rec);
+			}
+		}
+
+		$app->tpl->setLoop('records',$records_new);
+		
+		//print_r($records_new);
+
+		$this->onShow();
+		
+		
+	}
+	
+	function prepareDataRow($rec) {
+		global $app;
+		
+		$rec = $app->searchform->decode($rec);
+
+		// Alternating datarow colors
+		$this->DataRowColor = ($this->DataRowColor == "#FFFFFF")?"#EEEEEE":"#FFFFFF";
+		$rec["bgcolor"] = $this->DataRowColor;
+		
+		// substitute value for select fields
+		foreach($app->searchform->listDef["item"] as $field) {
+			$key = $field["field"];
+			if($field['formtype'] == "SELECT") {
+				$rec[$key] = $field['value'][$rec[$key]];
+			}
+		}
+		
+		// The variable "id" contains always the index variable
+		$rec["id"] = $rec[$this->idx_key];
+		
+		return $rec;
+	}
+	
+	function getQueryString() {
+		global $app;
+		
+		// Generate the search sql
+		if($app->searchform->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->searchform->getSearchSQL($sql_where);
+		$app->tpl->setVar($app->searchform->searchValues);
+		
+		$order_by_sql = $this->SQLOrderBy;
+
+		// Generate SQL for paging
+		$limit_sql = $app->searchform->getPagingSQL($sql_where);
+		$app->tpl->setVar("paging",$app->searchform->pagingHTML);
+
+		return "SELECT * FROM ".$app->searchform->listDef["table"]." WHERE $sql_where $order_by_sql $limit_sql";
+		
+	}
+	
+	
+	function onShow() {
+		global $app;
+		
+		// Language File setzen
+		$lng_file = "lib/lang/".$_SESSION["s"]["language"]."_".$app->searchform->listDef['name']."_search.lng";
+		include($lng_file);
+		$app->tpl->setVar($wb);
+		$app->tpl->setVar("form_action",$app->searchform->listDef["file"]);
+		
+		// Parse the templates and send output to the browser
+		$this->onShowEnd();
+	}
+	
+	function onShowEnd() {
+		global $app;
+
+		if(count($_REQUEST) > 0) {
+			$app->tpl->setVar('searchresult_visible',1);
+			if($_REQUEST['searchresult_visible'] == 'no') $app->tpl->setVar('searchresult_visible',0);
+			
+			if($_REQUEST['searchform_visible'] == 'yes') {
+				$app->tpl->setVar('searchform_visible',1);
+			} else {
+				$app->tpl->setVar('searchform_visible',0);
+			}
+		} else {
+			$app->tpl->setVar('searchform_visible',1);
+			if($_REQUEST['searchform_visible'] == 'no') $app->tpl->setVar('searchform_visible',0);
+			
+			if($_REQUEST['searchresult_visible'] == 'yes') {
+				$app->tpl->setVar('searchresult_visible',1);
+			} else {
+				$app->tpl->setVar('searchresult_visible',0);
+			}
+		}
+		
+		// make columns visible
+		$visible_columns = explode(",",$app->searchform->listDef['default_columns']);
+		foreach($visible_columns as $col) {
+			$app->tpl->setVar($col.'_visible',1);
+		}
+		
+		$app->tpl_defaults();
+		$app->tpl->pparse();
+	}
+}
+
+?>
\ No newline at end of file
diff --git a/interface/lib/classes/searchform_tpl_generator.inc.php b/interface/lib/classes/searchform_tpl_generator.inc.php
new file mode 100644
index 0000000000000000000000000000000000000000..d72a077583b7d859d494eb56b15ac1f9693f7e50
--- /dev/null
+++ b/interface/lib/classes/searchform_tpl_generator.inc.php
@@ -0,0 +1,175 @@
+<?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 searchform_tpl_generator {
+	
+	function buildHTML($listDef,$module = '') {
+		
+		global $app;
+		
+		$lang = array();
+		$html = '<form name="myform" action="'.$listDef["file"].'" method="POST">
+<div class="frmTextHead"><tmpl_var name="list_head_txt"></div><br />
+<tmpl_if name="searchform_visible">
+<table border="0" cellspacing="0" cellpadding="4">';
+
+		$lang["list_head_txt"] = $listDef["name"];
+		foreach($listDef["item"] as $field) {
+			$key = $field["field"];
+			
+			if($field["formtype"] == 'SELECT') {
+				$html .= "
+  <tr>
+    <td class=\"frmText11\"><tmpl_var name=\"".$key."_txt\">:</td>
+	<td><select name=\"".$listDef["search_prefix"].$key."\">{tmpl_var name='".$listDef["search_prefix"].$key."'}</select></td>
+  </tr>";
+  			} else {
+				$html .= "
+  <tr>
+    <td class=\"frmText11\"><tmpl_var name=\"".$key."_txt\">:</td>
+	<td><input type=\"text\" name=\"".$listDef["search_prefix"].$key."\" value=\"{tmpl_var name='".$listDef["search_prefix"].$key."'}\" class=\"text\" /></td>
+  </tr>";
+  			}
+		}
+
+$html .= '
+  <tr>
+    <td colspan="2" align="center"><input name="Filter" type="image" id="Filter" src="../themes/iprg/images/btn_filter.png"></td>
+  </tr>
+</table>
+</tmpl_if>
+<tmpl_if name="searchresult_visible">
+<p>
+[<a class="frmText11" href="domain_search.php?searchform_visible=yes&searchresult_visible=no&empty_searchfields=yes">Neue Suche</a>] 
+[<a class="frmText11" href="domain_search.php?searchform_visible=yes&searchresult_visible=no&empty_searchfields=no">Suchkriterien ändern</a>]
+Suche speichern unter: <input type="text" name="search_save_as" /> <input type="submit" name="btn_submit_search_save" value="Speichern" /> 
+</p>
+<table width="100%" border="0" cellspacing="0" cellpadding="4">
+  <tr>
+';
+		
+		$lang["list_head_txt"] = $listDef["name"];
+		foreach($listDef["item"] as $field) {
+			$key = $field["field"];
+			$html .= "<tmpl_if name='".$key."_visible'>";
+			$html .= "    <td class=\"tblHead\"><tmpl_var name=\"".$key."_txt\"></td>\r\n";
+			$html .= "</tmpl_if>";
+			$lang[$key."_txt"] = $key;
+		}
+		
+		$html .= '    <td class="tblHead">&nbsp;</td>
+  </tr>
+  <tmpl_loop name="records">
+  <tr bgcolor="{tmpl_var name="bgcolor"}">
+';
+		
+		foreach($listDef["item"] as $field) {
+			$key = $field["field"];
+			$html .= "<tmpl_if name='".$key."_visible'>";
+			$html .= "    <td class=\"frmText11\"><a href=\"".$listDef["edit_file"]."?id={tmpl_var name='id'}\" class=\"frmText11\">{tmpl_var name=\"".$key."\"}</a></td>\r\n";
+			$html .= "</tmpl_if>";
+		}
+		
+		$html .= "    <td class=\"frmText11\" align=\"right\">[<a href=\"javascript: del_record('".$listDef["delete_file"]."?id={tmpl_var name='id'}&phpsessid={tmpl_var name='phpsessid'}');\" class=\"frmText11\">{tmpl_var name='delete_txt'}</a>]</td>
+  </tr>
+  </tmpl_loop>
+";
+  $html .= '
+</table><table width="100%" border="0" cellspacing="0" cellpadding="4">
+  <tr>
+  	<td height="40" align="center" class="tblFooter"><tmpl_var name="paging"></td>
+  </tr>
+</table>
+</tmpl_if>
+</form>';
+		
+		if($module == '') {
+			$filename = 'templates/'.$listDef["name"].'_search.htm';
+		} else {
+			$filename = '../'.$module.'/templates/'.$listDef["name"].'_search.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';
+		
+		// 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']."_search.lng";
+		} else {
+			$lng_file = '../'.$module."/lib/lang/en_".$listDef['name']."_search.lng";
+		}
+		
+		if(is_file($lng_file)) {
+			include_once($lng_file);
+		} else {
+			$wb = array();
+		}
+		
+		$wb_out = array_merge($wb,$lang);
+		
+		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/tform.inc.php b/interface/lib/classes/tform.inc.php
index 0336e11be790cb8a25463057d7c93620b121b4b7..9b32e27ddd6dfed84fb0993953e58443ad2fccfa 100644
--- a/interface/lib/classes/tform.inc.php
+++ b/interface/lib/classes/tform.inc.php
@@ -1,902 +1,931 @@
-<?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;
-
-        /**
-        * 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;
-                if($module == '') {
-                        include_once("lib/lang/".$_SESSION["s"]["language"]."_".$this->formDef["name"].".lng");
-                } else {
-                        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).");
-                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'];
-                        $querystring = str_replace("{RECORDID}",$record[$table_idx],$querystring);
-                        $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(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':'';
-                                                                $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 = (empty($val))?'':' CHECKED';
-                                                $new_record[$key] = "<input name=\"".$key."\" type=\"checkbox\" value=\"".$field['value']."\" $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':'';
-                                                        $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) {
-
-                                                                $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';
-                                        $new_record[$key] = "<input name=\"".$key."\" type=\"checkbox\" value=\"".$field['value']."\" $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) {
-
-                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(is_array($field['validators'])) $this->validateField($key, $record[$key], $field['validators']);
-
-                                switch ($field['datatype']) {
-                                case 'VARCHAR':
-                                        if(!is_array($record[$key])) {
-                                                $new_record[$key] = addslashes($record[$key]);
-                                        } else {
-                                                $new_record[$key] = implode($field['separator'],$record[$key]);
-                                        }
-                                break;
-                                case 'TEXT':
-                                        if(!is_array($record[$key])) {
-                                                $new_record[$key] = addslashes($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);
-                                        }
-                                break;
-                                case 'INTEGER':
-                                        $new_record[$key] = intval($record[$key]);
-                                        //if($new_record[$key] != $record[$key]) $new_record[$key] = $field['default'];
-                                        //if($key == 'refresh') die($record[$key]);
-                                break;
-                                case 'DOUBLE':
-                                        $new_record[$key] = addslashes($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($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;
-
-                // 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'];
-                                                $this->errorMessage .= $this->wordbook[$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'];
-                                                        $this->errorMessage .= $this->wordbook[$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'];
-                                                        $this->errorMessage .= $this->wordbook[$errmsg]."<br>\r\n";
-                                                }
-                                        }
-                                break;
-                                case 'NOTEMPTY':
-                                        if(empty($field_value)) {
-                                                $errmsg = $validator['errmsg'];
-                                                $this->errorMessage .= $this->wordbook[$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'];
-                                                $this->errorMessage .= $this->wordbook[$errmsg]."<br>\r\n";
-                                        }
-                                break;
-                                case 'ISINT':
-                                        $tmpval = intval($field_value);
-                                        if($tmpval === 0 and !empty($field_value)) {
-                                                $errmsg = $validator['errmsg'];
-                                                $this->errorMessage .= $this->wordbook[$errmsg]."<br>\r\n";
-                                        }
-                                break;
-                                case 'ISPOSITIVE':
-                                        if(!is_numeric($field_value) || $field_value <= 0){
-                                          $errmsg = $validator['errmsg'];
-                                          $this->errorMessage .= $this->wordbook[$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($validator);
-                                        } else {
-                                                $this->errorMessage .= "Custom validator class or function is empty<br>\r\n";
-                                        }
-                                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') {
-                        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 .= "Insert 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') {
-                                                                $sql_insert_val .= "'".crypt($record[$key])."', ";
-                                                        } else {
-                                                                $sql_insert_val .= "md5('".$record[$key]."'), ";
-                                                        }
-                                                } else {
-                                                        $sql_insert_key .= "`$key`, ";
-                                                        $sql_insert_val .= "'".$record[$key]."', ";
-                                                }
-                                        } else {
-                                                if($field['formtype'] == 'PASSWORD') {
-                                                        if($field['encryption'] == 'CRYPT') {
-                                                                $sql_update .= "`$key` = '".crypt($record[$key])."', ";
-                                                        } else {
-                                                                $sql_update .= "`$key` = md5('".$record[$key]."'), ";
-                                                        }
-                                                } else {
-                                                        $sql_update .= "`$key` = '".$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->formDef['db_table_idx']." = ".$primary_id;
-                                if($sql_ext_where != '') $sql .= " and ".$sql_ext_where;
-                        } else {
-                                $app->error("Primary ID fehlt!");
-                        }
-                }
-
-                // Daten in History tabelle speichern
-                if($this->errorMessage == '' and $this->formDef['db_history'] == 'yes') $this->datalogSave($action,$primary_id,$record);
-
-                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
-                                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->formDef["title"].'</b>';
-                if($this->formDef["description"] != '') $form_hint .= '<br><br>'.$this->formDef["description"];
-                $app->tpl->setVar('form_hint',$form_hint);
-
-                // Set Wordbook for this form
-
-                $app->tpl->setVar($this->wordbook);
-    }
-
-
-
-        function datalogSave($action,$primary_id,$record_new) {
-                global $app,$conf;
-
-                // Füge Backticks nur bei unvollständigen Tabellennamen ein
-                if(stristr($this->formDef['db_table'],'.')) {
-                        $escape = '';
-                } else {
-                        $escape = '`';
-                }
-
-                if($action == "UPDATE") {
-                        $sql = "SELECT * FROM ".$escape.$this->formDef['db_table'].$escape." WHERE ".$this->formDef['db_table_idx']." = ".$primary_id;
-                        $record_old = $app->db->queryOneRecord($sql);
-                } else {
-                        $record_old = array();
-                }
-
-                $diffrec = array();
-
-                if(is_array($record_new)) {
-                        foreach($record_new as $key => $val) {
-                                if($record_old[$key] != $val) {
-                                        // Datensatz hat sich geändert
-                                        $diffrec[$key] = array('old' => $record_old[$key],
-                                                                           'new' => $val);
-                                }
-                        }
-                }
-				
-				// Insert the server_id, if the record has a server_id
-				$server_id = ($record_old["server_id"] > 0)?$record_old["server_id"]:0;
-
-                if(count($diffrec) > 0) {
-                        
-						// We need the full records in ISPConfig, not only the diffs
-						$diffrec = array(	'old' => $record_old,
-											'new' => $record_new);
-						
-						$diffstr = $app->db->quote(serialize($diffrec));
-                        $username = $app->db->quote($_SESSION["s"]["user"]["username"]);
-                        $dbidx = $this->formDef['db_table_idx'].":".$primary_id;
-                        $action = ($action == 'INSERT')?'i':'u';
-                        $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) {
-
-                $sql = '(';
-                $sql .= "(sys_userid = ".$_SESSION["s"]["user"]["userid"]." AND sys_perm_user like '%$perm%') OR  ";
-                $sql .= "(sys_groupid IN (".$_SESSION["s"]["user"]["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($_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"];
-        }
-
-}
-
+<?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;
+
+        /**
+        * 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;
+                if($module == '') {
+                        include_once("lib/lang/".$_SESSION["s"]["language"]."_".$this->formDef["name"].".lng");
+                } else {
+                        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).");
+                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'];
+                        $querystring = str_replace("{RECORDID}",$record[$table_idx],$querystring);
+                        $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(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':'';
+                                                                $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 = (empty($val))?'':' CHECKED';
+                                                $new_record[$key] = "<input name=\"".$key."\" type=\"checkbox\" value=\"".$field['value']."\" $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':'';
+                                                        $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) {
+
+                                                                $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';
+                                        $new_record[$key] = "<input name=\"".$key."\" type=\"checkbox\" value=\"".$field['value']."\" $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) {
+
+                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(is_array($field['validators'])) $this->validateField($key, $record[$key], $field['validators']);
+
+                                switch ($field['datatype']) {
+                                case 'VARCHAR':
+                                        if(!is_array($record[$key])) {
+                                                $new_record[$key] = addslashes($record[$key]);
+                                        } else {
+                                                $new_record[$key] = implode($field['separator'],$record[$key]);
+                                        }
+                                break;
+                                case 'TEXT':
+                                        if(!is_array($record[$key])) {
+                                                $new_record[$key] = addslashes($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] = intval($record[$key]);
+                                        //if($new_record[$key] != $record[$key]) $new_record[$key] = $field['default'];
+                                        //if($key == 'refresh') die($record[$key]);
+                                break;
+                                case 'DOUBLE':
+                                        $new_record[$key] = addslashes($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($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;
+				
+                // 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'];
+                                                $this->errorMessage .= $this->wordbook[$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($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') {
+                        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 .= "Insert 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') {
+                                                                $sql_insert_val .= "'".crypt($record[$key])."', ";
+                                                        } else {
+                                                                $sql_insert_val .= "md5('".$record[$key]."'), ";
+                                                        }
+                                                } else {
+                                                        $sql_insert_key .= "`$key`, ";
+                                                        $sql_insert_val .= "'".$record[$key]."', ";
+                                                }
+                                        } else {
+                                                if($field['formtype'] == 'PASSWORD') {
+                                                        if($field['encryption'] == 'CRYPT') {
+                                                                $sql_update .= "`$key` = '".crypt($record[$key])."', ";
+                                                        } else {
+                                                                $sql_update .= "`$key` = md5('".$record[$key]."'), ";
+                                                        }
+                                                } else {
+                                                        $sql_update .= "`$key` = '".$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->formDef['db_table_idx']." = ".$primary_id;
+                                if($sql_ext_where != '') $sql .= " and ".$sql_ext_where;
+                        } else {
+                                $app->error("Primary ID fehlt!");
+                        }
+                }
+
+                // Daten in History tabelle speichern
+                if($this->errorMessage == '' and $this->formDef['db_history'] == 'yes') $this->datalogSave($action,$primary_id,$record);
+				// die($sql);
+                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
+                                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->formDef["title"].'</b>';
+                if($this->formDef["description"] != '') $form_hint .= '<br><br>'.$this->formDef["description"];
+                $app->tpl->setVar('form_hint',$form_hint);
+
+                // Set Wordbook for this form
+
+                $app->tpl->setVar($this->wordbook);
+    }
+
+
+
+        function datalogSave($action,$primary_id,$record_new) {
+                global $app,$conf;
+
+                // Füge Backticks nur bei unvollständigen Tabellennamen ein
+                if(stristr($this->formDef['db_table'],'.')) {
+                        $escape = '';
+                } else {
+                        $escape = '`';
+                }
+
+                if($action == "UPDATE") {
+                        $sql = "SELECT * FROM ".$escape.$this->formDef['db_table'].$escape." WHERE ".$this->formDef['db_table_idx']." = ".$primary_id;
+                        $record_old = $app->db->queryOneRecord($sql);
+                } else {
+                        $record_old = array();
+                }
+
+                $diffrec = array();
+
+                if(is_array($record_new)) {
+                        foreach($record_new as $key => $val) {
+                                if($record_old[$key] != $val) {
+                                        // Datensatz hat sich geändert
+                                        $diffrec[$key] = array('old' => $record_old[$key],
+                                                                           'new' => $val);
+                                }
+                        }
+                }
+				
+				// Insert the server_id, if the record has a server_id
+				$server_id = ($record_old["server_id"] > 0)?$record_old["server_id"]:0;
+
+                if(count($diffrec) > 0) {
+                        
+						// We need the full records in ISPConfig, not only the diffs
+						$diffrec = array(	'old' => $record_old,
+											'new' => $record_new);
+						
+						$diffstr = $app->db->quote(serialize($diffrec));
+                        $username = $app->db->quote($_SESSION["s"]["user"]["username"]);
+                        $dbidx = $this->formDef['db_table_idx'].":".$primary_id;
+                        $action = ($action == 'INSERT')?'i':'u';
+                        $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) {
+
+                $sql = '(';
+                $sql .= "(sys_userid = ".$_SESSION["s"]["user"]["userid"]." AND sys_perm_user like '%$perm%') OR  ";
+                $sql .= "(sys_groupid IN (".$_SESSION["s"]["user"]["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($_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"];
+        }
+
+}
+
 ?>
\ 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 26a49128f74ef3a34c946f150fcd2df58557f0dc..0bcc13d3c4bafc1799ebc2b72990af7906aac55f 100644
--- a/interface/lib/classes/tform_actions.inc.php
+++ b/interface/lib/classes/tform_actions.inc.php
@@ -56,6 +56,16 @@ class tform_actions {
 				
 				// Importing ID
                 $this->id = intval($_REQUEST["id"]);
+				
+				// show print version of the form
+				if($_GET["print_form"] == 1) {
+					$this->onPrintForm();
+				}
+				
+				// send this form by email
+				if($_GET["send_form_by_mail"] == 1) {
+					$this->onMailSendForm();
+				}
 
                 if(count($_POST) > 1) {
                         $this->dataRecord = $_POST;
@@ -108,14 +118,25 @@ class tform_actions {
                         $this->onAfterUpdate();
 
                         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"]) {
+                           $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']);
+                            header("Location: ".$app->tform->formDef['list_default']);
                         }
                         exit;
                     } else {
@@ -150,15 +171,23 @@ class tform_actions {
                         }
 
                         $this->onAfterInsert();
+						
 
                      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"]) {
-                                                        $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"];
+                         // 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);
-                        } else {
+							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;
@@ -244,13 +273,13 @@ class tform_actions {
 						
                         // Call plugin
                         foreach($this->plugins as $plugin) {
-                                $plugin->onInsert();
+                                $plugin->onDelete();
                         }
                 }
 
-                //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"]) {
+                		//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();
@@ -261,6 +290,113 @@ class tform_actions {
                 exit;
 
         }
+		
+		/**
+        * 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
@@ -284,8 +420,20 @@ class tform_actions {
                 // Setting default values
                 $app->tpl_defaults();
 				
+				// Show the navigation bar of the form
+				if($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
-				//$next_tab = $app->tform->getNextTab();
                 $this->loadPlugins($this->active_tab);
 
                 // Calling the Plugin onShow Events and set the data in the
@@ -337,7 +485,7 @@ class tform_actions {
 
                 $this->dataRecord = $record;
 
-            // Userdaten umwandeln
+            	// Userdaten umwandeln
                 $record = $app->tform->getHTML($record, $this->active_tab,'EDIT');
                 $record['id'] = $this->id;
 
@@ -360,6 +508,8 @@ class tform_actions {
                       $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();
                   }
              }
diff --git a/interface/lib/classes/tform_tpl_generator.inc.php b/interface/lib/classes/tform_tpl_generator.inc.php
index 1a78288eb8dcd303c1bcb665c02a4604f073bdd8..dcc92ffbf2ddc00154e6139a197e344146fabc4f 100644
--- a/interface/lib/classes/tform_tpl_generator.inc.php
+++ b/interface/lib/classes/tform_tpl_generator.inc.php
@@ -43,22 +43,22 @@ class tform_tpl_generator {
 				case 'TEXT':
 					$html .= "
   <tr>
-    <td width=\"126\" class=\"frmText11\">{tmpl_var name='".$key."_txt'}:</td>
-    <td width=\"366\" class=\"frmText11\"><input name=\"".$key."\" type=\"text\" class=\"text\" value=\"{tmpl_var name='".$key."'}\" size=\"".$field['width']."\" maxlength=\"".$field['maxlength']."\"></td>
+    <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 width=\"126\" class=\"frmText11\">{tmpl_var name='".$key."_txt'}:</td>
-    <td width=\"366\" class=\"frmText11\"><textarea name='$key' cols='".$field['cols']."' rows='".$field['rows']."'>{tmpl_var name='".$key."'}</textarea></td>
+    <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 width=\"126\" class=\"frmText11\">{tmpl_var name='".$key."_txt'}:</td>
-    <td width=\"366\" class=\"frmText11\">
+    <td class=\"frmText11\">{tmpl_var name='".$key."_txt'}:</td>
+    <td class=\"frmText11\">
 		<select name=\"".$key."\" class=\"text\">
 			{tmpl_var name='".$key."'}
 		</select>
@@ -68,8 +68,8 @@ class tform_tpl_generator {
 				case 'MULTIPLE':
 				$html .= "
   <tr>
-    <td width=\"126\" class=\"frmText11\">{tmpl_var name='".$key."_txt'}:</td>
-    <td width=\"366\" class=\"frmText11\">
+    <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>
@@ -79,29 +79,29 @@ class tform_tpl_generator {
 				case 'PASSWORD':
 				$html .= "
   <tr>
-    <td width=\"126\" class=\"frmText11\">{tmpl_var name='".$key."_txt'}:</td>
-    <td width=\"366\" class=\"frmText11\"><input name=\"".$key."\" type=\"password\" class=\"text\" value=\"{tmpl_var name='".$key."'}\" size=\"".$field['width']."\" maxlength=\"".$field['maxlength']."\"></td>
+    <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 width=\"126\" class=\"frmText11\">{tmpl_var name='".$key."_txt'}:</td>
-    <td width=\"366\" class=\"frmText11\">{tmpl_var name='".$key."'}</td>
+    <td class=\"frmText11\">{tmpl_var name='".$key."_txt'}:</td>
+    <td class=\"frmText11\">{tmpl_var name='".$key."'}</td>
   </tr>";
 				break;
 				case 'CHECKBOXARRAY':
 				$html .= "
   <tr>
-    <td width=\"126\" class=\"frmText11\">{tmpl_var name='".$key."_txt'}:</td>
-    <td width=\"366\" class=\"frmText11\">{tmpl_var name='".$key."'}</td>
+    <td class=\"frmText11\">{tmpl_var name='".$key."_txt'}:</td>
+    <td class=\"frmText11\">{tmpl_var name='".$key."'}</td>
   </tr>";
 				break;
 				case 'RADIO':
 				$html .= "
   <tr>
-    <td width=\"126\" class=\"frmText11\">{tmpl_var name='".$key."_txt'}:</td>
-    <td width=\"366\" class=\"frmText11\">{tmpl_var name='".$key."'}</td>
+    <td class=\"frmText11\">{tmpl_var name='".$key."_txt'}:</td>
+    <td class=\"frmText11\">{tmpl_var name='".$key."'}</td>
   </tr>";
 				break;
 			}
@@ -163,7 +163,7 @@ class tform_tpl_generator {
 							'name'			=> $formDef["db_table_idx"],
 							'type'			=> 'int64',
 							'typeValue'		=> '',
-							'defaultValue'	=> '',
+							'defaultValue'	=> false,
 							'notNull'		=> true,
 							'autoInc'		=> true,
 							'option'		=> 'primary'
@@ -178,7 +178,7 @@ class tform_tpl_generator {
 								'name'			=> 'sys_userid',
 								'type'			=> 'int32',
 								'typeValue'		=> '',
-								'defaultValue'	=> '',
+								'defaultValue'	=> '0',
 								'notNull'		=> true
 							);
 				$columns[] = $col;
@@ -186,7 +186,7 @@ class tform_tpl_generator {
 								'name'			=> 'sys_groupid',
 								'type'			=> 'int32',
 								'typeValue'		=> '',
-								'defaultValue'	=> '',
+								'defaultValue'	=> '0',
 								'notNull'		=> true
 							);
 				$columns[] = $col;
@@ -194,7 +194,7 @@ class tform_tpl_generator {
 								'name'			=> 'sys_perm_user',
 								'type'			=> 'varchar',
 								'typeValue'		=> '5',
-								'defaultValue'	=> '',
+								'defaultValue'	=> 'NULL',
 								'notNull'		=> true
 							);
 				$columns[] = $col;
@@ -202,7 +202,7 @@ class tform_tpl_generator {
 								'name'			=> 'sys_perm_group',
 								'type'			=> 'varchar',
 								'typeValue'		=> '5',
-								'defaultValue'	=> '',
+								'defaultValue'	=> 'NULL',
 								'notNull'		=> true
 							);
 				$columns[] = $col;
@@ -210,7 +210,7 @@ class tform_tpl_generator {
 								'name'			=> 'sys_perm_other',
 								'type'			=> 'varchar',
 								'typeValue'		=> '5',
-								'defaultValue'	=> '',
+								'defaultValue'	=> 'NULL',
 								'notNull'		=> true
 							);
 				$columns[] = $col;
@@ -237,26 +237,33 @@ class tform_tpl_generator {
 						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;
 					}
 					
@@ -265,7 +272,7 @@ class tform_tpl_generator {
 									'name'			=> $name,
 									'type'			=> $type,
 									'typeValue'		=> $typeValue,
-									'defaultValue'	=> $field["default"],
+									'defaultValue'	=> $defaultValue,
 									'notNull'		=> true
 									);
 					
@@ -279,9 +286,9 @@ class tform_tpl_generator {
     }
 	
 	function lng_add($lang,$formDef) {
-		global $go_api, $go_info;
+		global $go_api, $go_info,$conf;
 		
-		$lng_file = "lib/lang/en_".$formDef['name'].".lng";
+		$lng_file = "lib/lang/".$conf["language"]."_".$formDef['name'].".lng";
 		if(is_file($lng_file)) {
 			include($lng_file);
 		} else {