tbrehm
2007-02-22 25ece9c51091bf98f06a4578deb2175e6dfb1112
Updated several base libraries and added advanced search functionality.
9 files modified
6 files added
4485 ■■■■■ changed files
config/exim4/exim4_without_amavisd.conf.template 554 ●●●●● patch | view | raw | blame | history
interface/lib/classes/datasources_enbion.inc.php 53 ●●●●● patch | view | raw | blame | history
interface/lib/classes/db_mysql.inc.php 28 ●●●● patch | view | raw | blame | history
interface/lib/classes/listform.inc.php 671 ●●●● patch | view | raw | blame | history
interface/lib/classes/listform_actions.inc.php 312 ●●●● patch | view | raw | blame | history
interface/lib/classes/listform_tpl_generator.inc.php 10 ●●●● patch | view | raw | blame | history
interface/lib/classes/plugin_base.inc.php 1 ●●●● patch | view | raw | blame | history
interface/lib/classes/plugin_dbhistory.inc.php 41 ●●●●● patch | view | raw | blame | history
interface/lib/classes/plugin_listview.inc.php 15 ●●●●● patch | view | raw | blame | history
interface/lib/classes/searchform.inc.php 364 ●●●●● patch | view | raw | blame | history
interface/lib/classes/searchform_actions.inc.php 199 ●●●●● patch | view | raw | blame | history
interface/lib/classes/searchform_tpl_generator.inc.php 175 ●●●●● patch | view | raw | blame | history
interface/lib/classes/tform.inc.php 1831 ●●●● patch | view | raw | blame | history
interface/lib/classes/tform_actions.inc.php 174 ●●●●● patch | view | raw | blame | history
interface/lib/classes/tform_tpl_generator.inc.php 57 ●●●●● patch | view | raw | blame | history
config/exim4/exim4_without_amavisd.conf.template
New file
@@ -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
interface/lib/classes/datasources_enbion.inc.php
New file
@@ -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;
    }
}
?>
interface/lib/classes/db_mysql.inc.php
@@ -147,6 +147,11 @@
            return mysql_num_rows($this->queryId);
        }
        
        function affectedRows()
        {
            return mysql_affected_rows($this->linkId);
        }
        // returns mySQL insert id
        function insertID()
        {
@@ -256,12 +261,23 @@
       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
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;
        }
}
?>
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();
    }
}
?>
interface/lib/classes/listform_tpl_generator.inc.php
@@ -56,7 +56,11 @@
  
          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 @@
    }
    
    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";
        }
interface/lib/classes/plugin_base.inc.php
@@ -4,6 +4,7 @@
    
    var $plugin_name;
    var $options;
    var $form;
    
    function onLoad() {
    
interface/lib/classes/plugin_dbhistory.inc.php
New file
@@ -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;
        }
}
?>
interface/lib/classes/plugin_listview.inc.php
@@ -20,10 +20,13 @@
                $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 @@
                // 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 @@
                                // 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];
interface/lib/classes/searchform.inc.php
New file
@@ -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;
        }
}
?>
interface/lib/classes/searchform_actions.inc.php
New file
@@ -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();
    }
}
?>
interface/lib/classes/searchform_tpl_generator.inc.php
New file
@@ -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);
        }
    }
}
?>
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"];
        }
}
?>
interface/lib/classes/tform_actions.inc.php
@@ -56,6 +56,16 @@
                
                // 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 @@
                        $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 @@
                        }
                        $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 @@
                        
                        // 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 @@
                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 @@
                // 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 @@
                $this->dataRecord = $record;
            // Userdaten umwandeln
                // Userdaten umwandeln
                $record = $app->tform->getHTML($record, $this->active_tab,'EDIT');
                $record['id'] = $this->id;
@@ -360,6 +508,8 @@
                      $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();
                  }
             }
interface/lib/classes/tform_tpl_generator.inc.php
@@ -43,22 +43,22 @@
                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 @@
                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 @@
                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 @@
                            'name'            => $formDef["db_table_idx"],
                            'type'            => 'int64',
                            'typeValue'        => '',
                            'defaultValue'    => '',
                            'defaultValue'    => false,
                            'notNull'        => true,
                            'autoInc'        => true,
                            'option'        => 'primary'
@@ -178,7 +178,7 @@
                                'name'            => 'sys_userid',
                                'type'            => 'int32',
                                'typeValue'        => '',
                                'defaultValue'    => '',
                                'defaultValue'    => '0',
                                'notNull'        => true
                            );
                $columns[] = $col;
@@ -186,7 +186,7 @@
                                'name'            => 'sys_groupid',
                                'type'            => 'int32',
                                'typeValue'        => '',
                                'defaultValue'    => '',
                                'defaultValue'    => '0',
                                'notNull'        => true
                            );
                $columns[] = $col;
@@ -194,7 +194,7 @@
                                'name'            => 'sys_perm_user',
                                'type'            => 'varchar',
                                'typeValue'        => '5',
                                'defaultValue'    => '',
                                'defaultValue'    => 'NULL',
                                'notNull'        => true
                            );
                $columns[] = $col;
@@ -202,7 +202,7 @@
                                'name'            => 'sys_perm_group',
                                'type'            => 'varchar',
                                'typeValue'        => '5',
                                'defaultValue'    => '',
                                'defaultValue'    => 'NULL',
                                'notNull'        => true
                            );
                $columns[] = $col;
@@ -210,7 +210,7 @@
                                'name'            => 'sys_perm_other',
                                'type'            => 'varchar',
                                'typeValue'        => '5',
                                'defaultValue'    => '',
                                'defaultValue'    => 'NULL',
                                'notNull'        => true
                            );
                $columns[] = $col;
@@ -237,26 +237,33 @@
                        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 @@
                                    'name'            => $name,
                                    'type'            => $type,
                                    'typeValue'        => $typeValue,
                                    'defaultValue'    => $field["default"],
                                    'defaultValue'    => $defaultValue,
                                    'notNull'        => true
                                    );
                    
@@ -279,9 +286,9 @@
    }
    
    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 {