tbrehm
2013-08-02 2332b2279d8a8599b4f041370315edc9544b1560
Added support for mongodb. Many thanks to MaddinXx for the patch.
http://www.howtoforge.com/forums/showthread.php?t=62691
2 files added
29 files modified
3716 ■■■■■ changed files
install/sql/incremental/upd_0055.sql 2 ●●●●● patch | view | raw | blame | history
install/sql/ispconfig3.sql 213 ●●●● patch | view | raw | blame | history
interface/lib/classes/tform.inc.php 1806 ●●●● patch | view | raw | blame | history
interface/lib/classes/tools_monitor.inc.php 34 ●●●●● patch | view | raw | blame | history
interface/lib/shelluser_blacklist 3 ●●●● patch | view | raw | blame | history
interface/web/admin/form/server_config.tform.php 72 ●●●● patch | view | raw | blame | history
interface/web/admin/lib/lang/de_server_config.lng 1 ●●●● patch | view | raw | blame | history
interface/web/admin/lib/lang/en_server_config.lng 3 ●●●● patch | view | raw | blame | history
interface/web/admin/templates/server_config_rescue_edit.htm 16 ●●●●● patch | view | raw | blame | history
interface/web/monitor/lib/lang/de.lng 3 ●●●●● patch | view | raw | blame | history
interface/web/monitor/lib/lang/en.lng 3 ●●●●● patch | view | raw | blame | history
interface/web/monitor/lib/module.conf.php 7 ●●●● patch | view | raw | blame | history
interface/web/monitor/show_data.php 7 ●●●●● patch | view | raw | blame | history
interface/web/sites/database_user_edit.php 62 ●●●●● patch | view | raw | blame | history
interface/web/sites/form/database.tform.php 9 ●●●●● patch | view | raw | blame | history
interface/web/sites/form/database_user.tform.php 10 ●●●●● patch | view | raw | blame | history
interface/web/sites/lib/lang/de_database_admin_list.lng 1 ●●●● patch | view | raw | blame | history
interface/web/sites/lib/lang/de_database_list.lng 1 ●●●● patch | view | raw | blame | history
interface/web/sites/lib/lang/de_web_backup_list.lng 1 ●●●● patch | view | raw | blame | history
interface/web/sites/lib/lang/en_database_admin_list.lng 3 ●●●● patch | view | raw | blame | history
interface/web/sites/lib/lang/en_database_list.lng 3 ●●●● patch | view | raw | blame | history
interface/web/sites/lib/lang/en_web_backup_list.lng 9 ●●●●● patch | view | raw | blame | history
interface/web/sites/list/database.list.php 15 ●●●●● patch | view | raw | blame | history
interface/web/sites/templates/database_admin_list.htm 11 ●●●●● patch | view | raw | blame | history
interface/web/sites/templates/database_list.htm 11 ●●●●● patch | view | raw | blame | history
server/cron_daily.php 248 ●●●●● patch | view | raw | blame | history
server/lib/classes/monitor_tools.inc.php 57 ●●●●● patch | view | raw | blame | history
server/mods-available/monitor_core_module.inc.php 44 ●●●● patch | view | raw | blame | history
server/mods-available/rescue_core_module.inc.php 175 ●●●● patch | view | raw | blame | history
server/plugins-available/backup_plugin.inc.php 66 ●●●●● patch | view | raw | blame | history
server/plugins-available/mongo_clientdb_plugin.inc.php 820 ●●●●● patch | view | raw | blame | history
install/sql/incremental/upd_0055.sql
New file
@@ -0,0 +1,2 @@
ALTER TABLE `web_backup` CHANGE `backup_type` `backup_type` enum('web','mongodb','mysql') NOT NULL DEFAULT 'web';
ALTER TABLE `web_database_user` ADD `database_password_mongo` varchar(32) DEFAULT NULL AFTER `database_password`;
install/sql/ispconfig3.sql
@@ -26,24 +26,24 @@
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-- Includes
--
-- Includes
--
-- iso_country_list.sql
--
--
-- This will create and then populate a MySQL table with a list of the names and
-- ISO 3166 codes for countries in existence as of the date below.
--
--
-- For updates to this file, see http://27.org/isocountrylist/
-- For more about ISO 3166, see http://www.iso.ch/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html
--
--
-- Created by getisocountrylist.pl on Sun Nov  2 14:59:20 2003.
-- Wm. Rhodes <iso_country_list@27.org>
--
--
--
--
-- ISPConfig 3
-- DB-Version: 3.0.0.9
--
--
SET FOREIGN_KEY_CHECKS = 0;
@@ -252,9 +252,9 @@
-- --------------------------------------------------------
--
--
-- Table structure for table  `client_template`
--
--
CREATE TABLE `client_template` (
  `template_id` int(11) unsigned NOT NULL auto_increment,
@@ -262,7 +262,7 @@
  `sys_groupid` int(11) unsigned NOT NULL default '0',
  `sys_perm_user` varchar(5) default NULL,
  `sys_perm_group` varchar(5) default NULL,
  `sys_perm_other` varchar(5) default NULL,
  `sys_perm_other` varchar(5) default NULL,
  `template_name` varchar(64) NOT NULL,
  `template_type` varchar(1) NOT NULL default 'm',
  `limit_maildomain` int(11) NOT NULL default '-1',
@@ -330,9 +330,9 @@
-- --------------------------------------------------------
--
--
-- Table structure for table  `cron`
--
--
CREATE TABLE `cron` (
  `id` int(11) unsigned NOT NULL auto_increment,
  `sys_userid` int(11) unsigned NOT NULL default '0',
@@ -355,9 +355,9 @@
-- --------------------------------------------------------
--
--
-- Table structure for table  `directive_snippets`
--
--
CREATE TABLE IF NOT EXISTS `directive_snippets` (
  `directive_snippets_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
@@ -375,9 +375,9 @@
-- --------------------------------------------------------
--
--
-- Table structure for table  `dns_rr`
--
--
CREATE TABLE `dns_rr` (
  `id` int(11) unsigned NOT NULL auto_increment,
@@ -425,9 +425,9 @@
-- --------------------------------------------------------
--
--
-- Table structure for table  `dns_soa`
--
--
CREATE TABLE `dns_soa` (
  `id` int(10) unsigned NOT NULL auto_increment,
@@ -457,9 +457,9 @@
-- --------------------------------------------------------
--
--
-- Table structure for table  `dns_template`
--
--
CREATE TABLE `dns_template` (
  `template_id` int(11) unsigned NOT NULL auto_increment,
@@ -493,9 +493,9 @@
-- --------------------------------------------------------
--
--
-- Table structure for table  `firewall`
--
--
CREATE TABLE `firewall` (
  `firewall_id` int(11) unsigned NOT NULL auto_increment,
@@ -513,9 +513,9 @@
-- --------------------------------------------------------
--
--
-- Table structure for table  `ftp_user`
--
--
CREATE TABLE `ftp_user` (
  `ftp_user_id` int(11) unsigned NOT NULL auto_increment,
@@ -607,9 +607,9 @@
-- --------------------------------------------------------
--
--
-- Table structure for table  `mail_access`
--
--
CREATE TABLE `mail_access` (
  `access_id` int(11) unsigned NOT NULL auto_increment,
@@ -629,9 +629,9 @@
-- --------------------------------------------------------
--
--
-- Table structure for table  `mail_content_filter`
--
--
CREATE TABLE `mail_content_filter` (
  `content_filter_id` int(11) unsigned NOT NULL auto_increment,
@@ -651,9 +651,9 @@
-- --------------------------------------------------------
--
--
-- Table structure for table  `mail_domain`
--
--
CREATE TABLE `mail_domain` (
  `domain_id` int(11) unsigned NOT NULL auto_increment,
@@ -675,9 +675,9 @@
-- --------------------------------------------------------
--
--
-- Table structure for table  `mail_forwarding`
--
--
CREATE TABLE `mail_forwarding` (
  `forwarding_id` int(11) unsigned NOT NULL auto_increment,
@@ -698,9 +698,9 @@
-- --------------------------------------------------------
--
--
-- Table structure for table  `mail_get`
--
--
CREATE TABLE `mail_get` (
  `mailget_id` int(11) unsigned NOT NULL auto_increment,
@@ -764,9 +764,9 @@
-- --------------------------------------------------------
--
--
-- Table structure for table  `mail_traffic`
--
--
CREATE TABLE `mail_traffic` (
  `traffic_id` int(11) unsigned NOT NULL auto_increment,
@@ -779,9 +779,9 @@
-- --------------------------------------------------------
--
--
-- Table structure for table  `mail_transport`
--
--
CREATE TABLE `mail_transport` (
  `transport_id` int(11) unsigned NOT NULL auto_increment,
@@ -802,9 +802,9 @@
-- --------------------------------------------------------
--
--
-- Table structure for table  `mail_user`
--
--
CREATE TABLE `mail_user` (
  `mailuser_id` int(11) unsigned NOT NULL auto_increment,
@@ -848,9 +848,9 @@
-- --------------------------------------------------------
--
--
-- Table structure for table  `mail_user_filter`
--
--
CREATE TABLE `mail_user_filter` (
  `filter_id` int(11) unsigned NOT NULL auto_increment,
@@ -1061,9 +1061,9 @@
-- --------------------------------------------------------
--
--
-- Table structure for table  `remote_session`
--
--
CREATE TABLE `remote_session` (
  `remote_session` varchar(64) NOT NULL,
@@ -1075,9 +1075,9 @@
-- --------------------------------------------------------
--
--
-- Table structure for table  `remote_user`
--
--
CREATE TABLE `remote_user` (
  `remote_userid` int(11) unsigned NOT NULL auto_increment,
@@ -1094,9 +1094,9 @@
-- --------------------------------------------------------
--
--
-- Table structure for table  `server`
--
--
CREATE TABLE `server` (
  `server_id` int(11) unsigned NOT NULL auto_increment,
@@ -1124,9 +1124,9 @@
-- --------------------------------------------------------
--
--
-- Table structure for table  `server_ip`
--
--
CREATE TABLE `server_ip` (
  `server_ip_id` int(11) unsigned NOT NULL auto_increment,
@@ -1200,9 +1200,9 @@
-- --------------------------------------------------------
--
--
-- Table structure for table  `software_package`
--
--
CREATE TABLE `software_package` (
  `package_id` int(11) unsigned NOT NULL auto_increment,
@@ -1223,9 +1223,9 @@
-- --------------------------------------------------------
--
--
-- Table structure for table  `software_repo`
--
--
CREATE TABLE `software_repo` (
  `software_repo_id` int(11) unsigned NOT NULL auto_increment,
@@ -1244,9 +1244,9 @@
-- --------------------------------------------------------
--
--
-- Table structure for table  `software_update`
--
--
CREATE TABLE `software_update` (
  `software_update_id` int(11) unsigned NOT NULL auto_increment,
@@ -1266,9 +1266,9 @@
-- --------------------------------------------------------
--
--
-- Table structure for table  `software_update_inst`
--
--
CREATE TABLE `software_update_inst` (
  `software_update_inst_id` int(11) unsigned NOT NULL auto_increment,
@@ -1282,9 +1282,9 @@
-- --------------------------------------------------------
--
--
-- Table structure for table  `spamfilter_policy`
--
--
CREATE TABLE `spamfilter_policy` (
  `id` int(11) unsigned NOT NULL auto_increment,
@@ -1335,9 +1335,9 @@
-- --------------------------------------------------------
--
--
-- Table structure for table  `spamfilter_users`
--
--
CREATE TABLE `spamfilter_users` (
  `id` int(11) unsigned NOT NULL auto_increment,
@@ -1358,9 +1358,9 @@
-- --------------------------------------------------------
--
--
-- Table structure for table  `spamfilter_wblist`
--
--
CREATE TABLE `spamfilter_wblist` (
  `wblist_id` int(11) unsigned NOT NULL auto_increment,
@@ -1380,9 +1380,9 @@
-- --------------------------------------------------------
--
--
-- Table structure for table  `support_message`
--
--
CREATE TABLE `support_message` (
  `support_message_id` int(11) unsigned NOT NULL auto_increment,
@@ -1414,9 +1414,9 @@
-- --------------------------------------------------------
--
--
-- Table structure for table  `sys_datalog`
--
--
CREATE TABLE `sys_datalog` (
  `datalog_id` int(11) unsigned NOT NULL auto_increment,
@@ -1434,9 +1434,9 @@
-- --------------------------------------------------------
--
--
-- Table structure for table  `sys_dbsync`
--
--
CREATE TABLE `sys_dbsync` (
  `id` int(11) unsigned NOT NULL auto_increment,
@@ -1458,9 +1458,9 @@
-- --------------------------------------------------------
--
--
-- Table structure for table  `sys_filesync`
--
--
CREATE TABLE `sys_filesync` (
  `id` int(11) unsigned NOT NULL auto_increment,
@@ -1478,9 +1478,9 @@
-- --------------------------------------------------------
--
--
-- Table structure for table  `sys_group`
--
--
CREATE TABLE `sys_group` (
  `groupid` int(11) unsigned NOT NULL auto_increment,
@@ -1492,9 +1492,9 @@
-- --------------------------------------------------------
--
--
-- Table structure for table  `sys_ini`
--
--
CREATE TABLE `sys_ini` (
  `sysini_id` int(11) unsigned NOT NULL auto_increment,
@@ -1504,9 +1504,9 @@
-- --------------------------------------------------------
--
--
-- Table structure for table  `sys_log`
--
--
CREATE TABLE `sys_log` (
  `syslog_id` int(11) unsigned NOT NULL auto_increment,
@@ -1572,9 +1572,9 @@
-- --------------------------------------------------------
--
--
-- Table structure for table  `sys_user`
--
--
CREATE TABLE `sys_user` (
  `userid` int(11) unsigned NOT NULL auto_increment,
@@ -1595,7 +1595,7 @@
  `default_group` int(11) unsigned NOT NULL default '0',
  `client_id` int(11) unsigned NOT NULL default '0',
  `id_rsa` VARCHAR( 2000 ) NOT NULL default '',
  `ssh_rsa` VARCHAR( 600 ) NOT NULL default '',
  `ssh_rsa` VARCHAR( 600 ) NOT NULL default '',
  PRIMARY KEY  (`userid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
@@ -1632,14 +1632,14 @@
  `backup_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `server_id` int(10) unsigned NOT NULL,
  `parent_domain_id` int(10) unsigned NOT NULL,
  `backup_type` enum('web','mysql') NOT NULL DEFAULT 'web',
  `backup_type` enum('web','mongodb','mysql') NOT NULL DEFAULT 'web',
  `backup_mode` varchar(64) NOT NULL DEFAULT  '',
  `tstamp` int(10) unsigned NOT NULL,
  `filename` varchar(255) NOT NULL,
  `filesize` VARCHAR(10) NOT NULL,
  PRIMARY KEY (`backup_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
-- --------------------------------------------------------
--
@@ -1688,14 +1688,15 @@
  `database_user` varchar(64) DEFAULT NULL,
  `database_user_prefix` varchar(50) NOT NULL default '',
  `database_password` varchar(64) DEFAULT NULL,
  `database_password_mongo` varchar(32) DEFAULT NULL,
  PRIMARY KEY (`database_user_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
-- --------------------------------------------------------
--
--
-- Table structure for table  `web_domain`
--
--
CREATE TABLE `web_domain` (
  `domain_id` int(11) unsigned NOT NULL auto_increment,
@@ -2095,41 +2096,41 @@
-- --------------------------------------------------------
--
--
-- Dumping data for table `dns_template`
--
--
INSERT INTO `dns_template` (`template_id`, `sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `name`, `fields`, `template`, `visible`) VALUES (1, 1, 1, 'riud', 'riud', '', 'Default', 'DOMAIN,IP,NS1,NS2,EMAIL', '[ZONE]\norigin={DOMAIN}.\nns={NS1}.\nmbox={EMAIL}.\nrefresh=7200\nretry=540\nexpire=604800\nminimum=86400\nttl=3600\n\n[DNS_RECORDS]\nA|{DOMAIN}.|{IP}|0|3600\nA|www|{IP}|0|3600\nA|mail|{IP}|0|3600\nNS|{DOMAIN}.|{NS1}.|0|3600\nNS|{DOMAIN}.|{NS2}.|0|3600\nMX|{DOMAIN}.|mail.{DOMAIN}.|10|3600', 'y');
-- --------------------------------------------------------
--
--
-- Dumping data for table `help_faq`
--
--
INSERT INTO `help_faq` VALUES (1,1,0,'I would like to know ...','Yes, of course.',1,1,'riud','riud','r');
-- --------------------------------------------------------
--
--
-- Dumping data for table `help_faq_sections`
--
--
INSERT INTO `help_faq_sections` VALUES (1,'General',0,NULL,NULL,NULL,NULL,NULL);
-- --------------------------------------------------------
--
--
-- Dumping data for table `software_repo`
--
--
INSERT INTO `software_repo` (`software_repo_id`, `sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `repo_name`, `repo_url`, `repo_username`, `repo_password`, `active`) VALUES (1, 1, 1, 'riud', 'riud', '', 'ISPConfig Addons', 'http://repo.ispconfig.org/addons/', '', '', 'n');
-- --------------------------------------------------------
--
--
-- Dumping data for table `spamfilter_policy`
--
--
INSERT INTO `spamfilter_policy` (`id`, `sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `policy_name`, `virus_lover`, `spam_lover`, `banned_files_lover`, `bad_header_lover`, `bypass_virus_checks`, `bypass_spam_checks`, `bypass_banned_checks`, `bypass_header_checks`, `spam_modifies_subj`, `virus_quarantine_to`, `spam_quarantine_to`, `banned_quarantine_to`, `bad_header_quarantine_to`, `clean_quarantine_to`, `other_quarantine_to`, `spam_tag_level`, `spam_tag2_level`, `spam_kill_level`, `spam_dsn_cutoff_level`, `spam_quarantine_cutoff_level`, `addr_extension_virus`, `addr_extension_spam`, `addr_extension_banned`, `addr_extension_bad_header`, `warnvirusrecip`, `warnbannedrecip`, `warnbadhrecip`, `newvirus_admin`, `virus_admin`, `banned_admin`, `bad_header_admin`, `spam_admin`, `spam_subject_tag`, `spam_subject_tag2`, `message_size_limit`, `banned_rulenames`) VALUES(1, 1, 0, 'riud', 'riud', 'r', 'Non-paying', 'N', 'N', 'N', 'N', 'Y', 'Y', 'Y', 'N', 'Y', '', '', '', '', '', '', 3, 7, 10, 0, 0, '', '', '', '', 'N', 'N', 'N', '', '', '', '', '', '', '', 0, '');
INSERT INTO `spamfilter_policy` (`id`, `sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `policy_name`, `virus_lover`, `spam_lover`, `banned_files_lover`, `bad_header_lover`, `bypass_virus_checks`, `bypass_spam_checks`, `bypass_banned_checks`, `bypass_header_checks`, `spam_modifies_subj`, `virus_quarantine_to`, `spam_quarantine_to`, `banned_quarantine_to`, `bad_header_quarantine_to`, `clean_quarantine_to`, `other_quarantine_to`, `spam_tag_level`, `spam_tag2_level`, `spam_kill_level`, `spam_dsn_cutoff_level`, `spam_quarantine_cutoff_level`, `addr_extension_virus`, `addr_extension_spam`, `addr_extension_banned`, `addr_extension_bad_header`, `warnvirusrecip`, `warnbannedrecip`, `warnbadhrecip`, `newvirus_admin`, `virus_admin`, `banned_admin`, `bad_header_admin`, `spam_admin`, `spam_subject_tag`, `spam_subject_tag2`, `message_size_limit`, `banned_rulenames`) VALUES(2, 1, 0, 'riud', 'riud', 'r', 'Uncensored', 'Y', 'Y', 'Y', 'Y', 'N', 'N', 'N', 'N', 'N', NULL, NULL, NULL, NULL, NULL, NULL, 3, 999, 999, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
@@ -2141,34 +2142,34 @@
-- --------------------------------------------------------
--
--
-- Dumping data for table `sys_group`
--
--
INSERT INTO `sys_group` (`groupid`, `name`, `description`, `client_id`) VALUES (1, 'admin', 'Administrators group', 0);
-- --------------------------------------------------------
--
--
-- Dumping data for table `sys_ini`
--
--
INSERT INTO `sys_ini` (`sysini_id`, `config`) VALUES (1, '');
-- --------------------------------------------------------
--
--
-- Dumping data for table `sys_user`
--
--
INSERT INTO `sys_theme` (`var_id`, `tpl_name`, `username`, `logo_url`) VALUES (NULL, 'default', 'global', 'themes/default/images/header_logo.png');
INSERT INTO `sys_theme` (`var_id`, `tpl_name`, `username`, `logo_url`) VALUES (NULL, 'default-v2', 'global', 'themes/default-v2/images/header_logo.png');
-- --------------------------------------------------------
--
--
-- Dumping data for table `sys_user`
--
--
INSERT INTO `sys_user` (`userid`, `sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `username`, `passwort`, `modules`, `startmodule`, `app_theme`, `typ`, `active`, `language`, `groups`, `default_group`, `client_id`) VALUES (1, 1, 0, 'riud', 'riud', '', 'admin', '21232f297a57a5a743894a0e4a801fc3', 'dashboard,admin,client,mail,monitor,sites,dns,vm,tools,help', 'dashboard', 'default', 'admin', 1, 'en', '1,2', 1, 0);
@@ -2179,5 +2180,5 @@
--
INSERT INTO sys_config VALUES ('1','db','db_version','3.0.5.2');
SET FOREIGN_KEY_CHECKS = 1;
interface/lib/classes/tform.inc.php
@@ -7,14 +7,14 @@
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.
    * 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
@@ -60,250 +60,250 @@
class tform {
        /**
        * Definition of the database table (array)
        * @var tableDef
        */
        var $tableDef;
        /**
        * Definition of the database table (array)
        * @var tableDef
        */
        var $tableDef;
        /**
        * Private
        * @var action
        */
        var $action;
        /**
        * Private
        * @var action
        */
        var $action;
        /**
        * Table name (String)
        * @var table_name
        */
        var $table_name;
        /**
        * Table name (String)
        * @var table_name
        */
        var $table_name;
        /**
        * Debug Variable
        * @var debug
        */
        var $debug = 0;
        /**
        * Debug Variable
        * @var debug
        */
        var $debug = 0;
        /**
        * name of the primary field of the database table (string)
        * @var table_index
        */
        var $table_index;
        /**
        * name of the primary field of the database table (string)
        * @var table_index
        */
        var $table_index;
        /**
        * contains the error messages
        * @var errorMessage
        */
        var $errorMessage = '';
        /**
        * contains the error messages
        * @var errorMessage
        */
        var $errorMessage = '';
        var $dateformat = "d.m.Y";
        var $formDef = array();
        var $wordbook;
        var $module;
        var $primary_id;
        var $dateformat = "d.m.Y";
        var $formDef = array();
        var $wordbook;
        var $module;
        var $primary_id;
        var $diffrec = array();
        /**
        * Loading of the table definition
        *
        * @param file: path to the form definition file
        * @return true
        */
        /*
        function loadTableDef($file) {
                global $app,$conf;
        /**
        * Loading of the table definition
        *
        * @param file: path to the form definition file
        * @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;
        }
        */
                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;
    function loadFormDef($file,$module = '') {
                global $app,$conf;
                include($file);
                $this->formDef = $form;
                include($file);
                $this->formDef = $form;
                $this->module = $module;
                $this->module = $module;
                $wb = array();
                include_once(ISPC_ROOT_PATH.'/lib/lang/'.$_SESSION['s']['language'].'.lng');
                if(is_array($wb)) $wb_global = $wb;
                if($module == '') {
                if($module == '') {
                    $lng_file = "lib/lang/".$_SESSION["s"]["language"]."_".$this->formDef["name"].".lng";
                    if(!file_exists($lng_file)) $lng_file = "lib/lang/en_".$this->formDef["name"].".lng";
                    include($lng_file);
                } else {
                } else {
                    $lng_file = "../$module/lib/lang/".$_SESSION["s"]["language"]."_".$this->formDef["name"].".lng";
                    if(!file_exists($lng_file)) $lng_file = "../$module/lib/lang/en_".$this->formDef["name"].".lng";
                    include($lng_file);
                }
                }
                if(is_array($wb_global)) {
                    $wb = $app->functions->array_merge($wb_global,$wb);
                }
                if(isset($wb_global)) unset($wb_global);
                $this->wordbook = $wb;
                $this->wordbook = $wb;
                $this->dateformat = $app->lng('conf_format_dateshort');
                return true;
        }
                return true;
        }
        /**
        * Converts the data in the array to human readable format
        * Datatype conversion e.g. to show the data in lists
        *
        * @param record
        * @return record
        */
        function decode($record,$tab) {
                global $conf, $app;
        /**
        * Converts the data in the array to human readable format
        * Datatype conversion e.g. to show the data in lists
        *
        * @param record
        * @return record
        */
        function decode($record,$tab) {
                global $conf, $app;
                if(!is_array($this->formDef['tabs'][$tab])) $app->error("Tab does not exist or the tab is empty (TAB: $tab).");
                $new_record = '';
                $new_record = '';
                $table_idx = $this->formDef['db_table_idx'];
                if(isset($record[$table_idx])) $new_record[$table_idx] = $app->functions->intval($record[$table_idx ]);
                if(is_array($record)) {
                        foreach($this->formDef['tabs'][$tab]['fields'] as $key => $field) {
                                //* Apply filter to record value.
                                if(isset($field['filters']) && is_array($field['filters'])) {
                                    $record[$key] = $this->filterField($key, (isset($record[$key]))?$record[$key]:'', $field['filters'], 'SHOW');
                                }
                                switch ($field['datatype']) {
                                case 'VARCHAR':
                                        $new_record[$key] = $record[$key];
                                break;
                                case 'VARCHAR':
                                        $new_record[$key] = $record[$key];
                                break;
                                case 'TEXT':
                                        $new_record[$key] = $record[$key];
                                break;
                                case 'TEXT':
                                        $new_record[$key] = $record[$key];
                                break;
                                case 'DATETSTAMP':
                                        if($record[$key] > 0) {
                                                $new_record[$key] = date($this->dateformat,$record[$key]);
                                        }
                                break;
                                case 'DATETSTAMP':
                                        if($record[$key] > 0) {
                                                $new_record[$key] = date($this->dateformat,$record[$key]);
                                        }
                                break;
                                case 'DATE':
                                        if($record[$key] != '' && $record[$key] != '0000-00-00') {
                                        if($record[$key] != '' && $record[$key] != '0000-00-00') {
                                                $tmp = explode('-',$record[$key]);
                                                $new_record[$key] = date($this->dateformat,mktime(0, 0, 0, $tmp[1]  , $tmp[2], $tmp[0]));
                                        }
                                break;
                                                $new_record[$key] = date($this->dateformat,mktime(0, 0, 0, $tmp[1]  , $tmp[2], $tmp[0]));
                                        }
                                break;
                                case 'INTEGER':
                                        $new_record[$key] = $app->functions->intval($record[$key]);
                                break;
                                case 'INTEGER':
                                        $new_record[$key] = $app->functions->intval($record[$key]);
                                break;
                                case 'DOUBLE':
                                        $new_record[$key] = $record[$key];
                                break;
                                case 'DOUBLE':
                                        $new_record[$key] = $record[$key];
                                break;
                                case 'CURRENCY':
                                        $new_record[$key] = $app->functions->currency_format($record[$key]);
                                break;
                                case 'CURRENCY':
                                        $new_record[$key] = $app->functions->currency_format($record[$key]);
                                break;
                                default:
                                        $new_record[$key] = $record[$key];
                                }
                        }
                                default:
                                        $new_record[$key] = $record[$key];
                                }
                        }
                }
        return $new_record;
        }
                }
        /**
        * Get the key => value array of a form filled 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
        */
        return $new_record;
        }
        function getDatasourceData($field, $record) {
                global $app;
        /**
        * Get the key => value array of a form filled 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
        */
                $values = array();
        function getDatasourceData($field, $record) {
                global $app;
                if($field["datasource"]["type"] == 'SQL') {
                $values = array();
                        // 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'];
                if($field["datasource"]["type"] == 'SQL') {
                        // Preparing SQL string. We will replace some
                        // common placeholders
                        $querystring = $field["datasource"]["querystring"];
                        $querystring = str_replace("{USERID}",$_SESSION["s"]["user"]["userid"],$querystring);
                        $querystring = str_replace("{GROUPID}",$_SESSION["s"]["user"]["default_group"],$querystring);
                        $querystring = str_replace("{GROUPS}",$_SESSION["s"]["user"]["groups"],$querystring);
                        $table_idx = $this->formDef['db_table_idx'];
                        $tmp_recordid = (isset($record[$table_idx]))?$record[$table_idx]:0;
                        $querystring = str_replace("{RECORDID}",$tmp_recordid,$querystring);
                        $querystring = str_replace("{RECORDID}",$tmp_recordid,$querystring);
                        unset($tmp_recordid);
                        $querystring = str_replace("{AUTHSQL}",$this->getAuthSQL('r'),$querystring);
                        // Getting the records
                        $tmp_records = $app->db->queryAllRecords($querystring);
                        if($app->db->errorMessage != '') die($app->db->errorMessage);
                        if(is_array($tmp_records)) {
                                $key_field = $field["datasource"]["keyfield"];
                                $value_field = $field["datasource"]["valuefield"];
                                foreach($tmp_records as $tmp_rec) {
                                        $tmp_id = $tmp_rec[$key_field];
                                        $values[$tmp_id] = $tmp_rec[$value_field];
                                }
                        }
                }
                if($field["datasource"]["type"] == 'CUSTOM') {
                        // Calls a custom class to validate this record
                        if($field["datasource"]['class'] != '' and $field["datasource"]['function'] != '') {
                                $datasource_class = $field["datasource"]['class'];
                                $datasource_function = $field["datasource"]['function'];
                                $app->uses($datasource_class);
                                $values = $app->$datasource_class->$datasource_function($field, $record);
                        } else {
                                $this->errorMessage .= "Custom datasource class or function is empty<br />\r\n";
                        }
                }
                if(isset($field['filters']) && is_array($field['filters'])) {
                    $new_values = array();
                    foreach($values as $index => $value) {
                        $new_index = $this->filterField($index, $index, $field['filters'], 'SHOW');
                        $new_values[$new_index] = $this->filterField($index, (isset($values[$index]))?$values[$index]:'', $field['filters'], 'SHOW');
                    }
                    $values = $new_values;
                    unset($new_values);
                    unset($new_index);
                }
                        $querystring = str_replace("{AUTHSQL}",$this->getAuthSQL('r'),$querystring);
                return $values;
                        // 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";
                        }
                }
                if(isset($field['filters']) && is_array($field['filters'])) {
                    $new_values = array();
                    foreach($values as $index => $value) {
                        $new_index = $this->filterField($index, $index, $field['filters'], 'SHOW');
                        $new_values[$new_index] = $this->filterField($index, (isset($values[$index]))?$values[$index]:'', $field['filters'], 'SHOW');
                    }
                    $values = $new_values;
                    unset($new_values);
                    unset($new_index);
                }
                return $values;
        }
        //* If the parameter 'valuelimit' is set
        function applyValueLimit($limit,$values) {
            global $app;
            $limit_parts = explode(':',$limit);
            //* values are limited to a comma separated list
            if($limit_parts[0] == 'list') {
                $allowed = explode(',',$limit_parts[1]);
            }
            //* values are limited to a field in the client settings
            if($limit_parts[0] == 'client') {
                if($_SESSION["s"]["user"]["typ"] == 'admin') {
@@ -314,7 +314,7 @@
                    $allowed = explode(',',$client['lm']);
                }
            }
            //* values are limited to a field in the reseller settings
            if($limit_parts[0] == 'reseller') {
                if($_SESSION["s"]["user"]["typ"] == 'admin') {
@@ -326,12 +326,12 @@
                    //echo "SELECT parent_client_id FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id";
                    //* If the client belongs to a reseller, we will check against the reseller Limit too
                    if($client['parent_client_id'] != 0) {
                        //* first we need to know the groups of this reseller
                        $tmp = $app->db->queryOneRecord("SELECT userid, groups FROM sys_user WHERE client_id = ".$client['parent_client_id']);
                        $reseller_groups = $tmp["groups"];
                        $reseller_userid = $tmp["userid"];
                        // Get the limits of the reseller of the logged in client
                        $client_group_id = $_SESSION["s"]["user"]["default_group"];
                        $reseller = $app->db->queryOneRecord("SELECT ".$limit_parts[1]." as lm FROM client WHERE client_id = ".$client['parent_client_id']);
@@ -341,7 +341,7 @@
                    }
                } // end if admin
            } // end if reseller
            //* values are limited to a field in the system settings
            if($limit_parts[0] == 'system') {
                $app->uses('getconf');
@@ -349,295 +349,295 @@
                $tmp_key = $limit_parts[2];
                $allowed = $tmp_conf[$tmp_key];
            }
            $values_new = array();
            foreach($values as $key => $val) {
                if(in_array($key,$allowed)) $values_new[$key] = $val;
            }
            return $values_new;
        }
        /**
        * Prepare the data record to show the data in a form.
        *
        * @param record = Datensatz als Array
        * @param action = NEW oder EDIT
        * @return record
        */
        function getHTML($record, $tab, $action = 'NEW') {
        /**
        * Prepare the data record to show the data in a form.
        *
        * @param record = Datensatz als Array
        * @param action = NEW oder EDIT
        * @return record
        */
        function getHTML($record, $tab, $action = 'NEW') {
                global $app;
                global $app;
                $this->action = $action;
                $this->action = $action;
                if(!is_array($this->formDef)) $app->error("No form definition found.");
                if(!is_array($this->formDef['tabs'][$tab])) $app->error("The tab is empty or does not exist (TAB: $tab).");
                if(!is_array($this->formDef)) $app->error("No form definition found.");
                if(!is_array($this->formDef['tabs'][$tab])) $app->error("The tab is empty or does not exist (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) {
                                        if(isset($record[$key])) {
                $new_record = array();
                if($action == 'EDIT') {
                        $record = $this->decode($record,$tab);
                        if(is_array($record)) {
                                foreach($this->formDef['tabs'][$tab]['fields'] as $key => $field) {
                                        if(isset($record[$key])) {
                                            $val = $record[$key];
                                        } else {
                                            $val = '';
                                        }
                                        // If Datasource is set, get the data from there
                                        if(isset($field['datasource']) && is_array($field['datasource'])) {
                                        // If Datasource is set, get the data from there
                                        if(isset($field['datasource']) && is_array($field['datasource'])) {
                                                if(is_array($field["value"])) {
                                                    //$field["value"] = array_merge($field["value"],$this->getDatasourceData($field, $record));
                                                    $field["value"] = $app->functions->array_merge($field["value"],$this->getDatasourceData($field, $record));
                                                } else {
                                                    $field["value"] = $this->getDatasourceData($field, $record);
                                                    $field["value"] = $this->getDatasourceData($field, $record);
                                                }
                                        }
                                        }
                                        // If a limitation for the values is set
                                        if(isset($field['valuelimit']) && is_array($field["value"])) {
                                            $field["value"] = $this->applyValueLimit($field['valuelimit'],$field["value"]);
                                        }
                                        switch ($field['formtype']) {
                                        case 'SELECT':
                                        switch ($field['formtype']) {
                                        case 'SELECT':
                                                $out = '';
                                                if(is_array($field['value'])) {
                                                        foreach($field['value'] as $k => $v) {
                                                                $selected = ($k == $val)?' SELECTED':'';
                                                if(is_array($field['value'])) {
                                                        foreach($field['value'] as $k => $v) {
                                                                $selected = ($k == $val)?' SELECTED':'';
                                                                if(!empty($this->wordbook[$v]))
                                                                    $v = $this->wordbook[$v];
                                                                $out .= "<option value='$k'$selected>".$this->lng($v)."</option>\r\n";
                                                        }
                                                }
                                                $new_record[$key] = $out;
                                        break;
                                        case 'MULTIPLE':
                                                if(is_array($field['value'])) {
                                                                $out .= "<option value='$k'$selected>".$this->lng($v)."</option>\r\n";
                                                        }
                                                }
                                                $new_record[$key] = $out;
                                        break;
                                        case 'MULTIPLE':
                                                if(is_array($field['value'])) {
                                                        // Split
                                                        $vals = explode($field['separator'],$val);
                                                        // Split
                                                        $vals = explode($field['separator'],$val);
                                                        // write HTML
                                                        $out = '';
                                                        foreach($field['value'] as $k => $v) {
                                                        // write HTML
                                                        $out = '';
                                                        foreach($field['value'] as $k => $v) {
                                                                $selected = '';
                                                                foreach($vals as $tvl) {
                                                                        if(trim($tvl) == trim($k)) $selected = ' SELECTED';
                                                                }
                                                                $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;
                                                                $out .= "<option value='$k'$selected>$v</option>\r\n";
                                                        }
                                                }
                                                $new_record[$key] = $out;
                                        break;
                                        case 'PASSWORD':
                                                $new_record[$key] = '';
                                        break;
                                        case 'PASSWORD':
                                                $new_record[$key] = '';
                                        break;
                                        case 'CHECKBOX':
                                                $checked = ($val == $field['value'][1])?' CHECKED':'';
                                                $new_record[$key] = "<input name=\"".$key."\" id=\"".$key."\" value=\"".$field['value'][1]."\" type=\"checkbox\" $checked />\r\n";
                                        break;
                                        case 'CHECKBOX':
                                                $checked = ($val == $field['value'][1])?' CHECKED':'';
                                                $new_record[$key] = "<input name=\"".$key."\" id=\"".$key."\" value=\"".$field['value'][1]."\" type=\"checkbox\" $checked />\r\n";
                                        break;
                                        case 'CHECKBOXARRAY':
                                                if(is_array($field['value'])) {
                                        case 'CHECKBOXARRAY':
                                                if(is_array($field['value'])) {
                                                        // aufsplitten ergebnisse
                                                        $vals = explode($field['separator'],$val);
                                                        // aufsplitten ergebnisse
                                                        $vals = explode($field['separator'],$val);
                                                        // HTML schreiben
                                                        $out = '';
                                                        $elementNo = 0;
                                                        foreach($field['value'] as $k => $v) {
                                                        // HTML schreiben
                                                        $out = '';
                                                        $elementNo = 0;
                                                        foreach($field['value'] as $k => $v) {
                                                                $checked = '';
                                                                foreach($vals as $tvl) {
                                                                        if(trim($tvl) == trim($k)) $checked = ' CHECKED';
                                                                }
                                                                // $out .= "<label for=\"".$key."[]\" class=\"inlineLabel\"><input name=\"".$key."[]\" id=\"".$key."[]\" value=\"$k\" type=\"checkbox\" $checked /> $v</label>\r\n";
                                                                $checked = '';
                                                                foreach($vals as $tvl) {
                                                                        if(trim($tvl) == trim($k)) $checked = ' CHECKED';
                                                                }
                                                                // $out .= "<label for=\"".$key."[]\" class=\"inlineLabel\"><input name=\"".$key."[]\" id=\"".$key."[]\" value=\"$k\" type=\"checkbox\" $checked /> $v</label>\r\n";
                                                                $out .= "<label for=\"".$key.$elementNo."\" class=\"inlineLabel\"><input name=\"".$key."[]\" id=\"".$key.$elementNo."\" value=\"$k\" type=\"checkbox\" $checked /> $v</label><br/>\r\n";
                                                                $elementNo++;
                                                        }
                                                }
                                                $new_record[$key] = $out;
                                        break;
                                                                $elementNo++;
                                                        }
                                                }
                                                $new_record[$key] = $out;
                                        break;
                                        case 'RADIO':
                                                if(is_array($field['value'])) {
                                        case 'RADIO':
                                                if(is_array($field['value'])) {
                                                        // HTML schreiben
                                                        $out = '';
                                                        $elementNo = 0;
                                                        foreach($field['value'] as $k => $v) {
                                                                $checked = ($k == $val)?' CHECKED':'';
                                                                //$out .= "<label for=\"".$key."[]\" class=\"inlineLabel\"><input name=\"".$key."[]\" id=\"".$key."[]\" value=\"$k\" type=\"radio\" $checked/> $v</label>\r\n";
                                                        // HTML schreiben
                                                        $out = '';
                                                        $elementNo = 0;
                                                        foreach($field['value'] as $k => $v) {
                                                                $checked = ($k == $val)?' CHECKED':'';
                                                                //$out .= "<label for=\"".$key."[]\" class=\"inlineLabel\"><input name=\"".$key."[]\" id=\"".$key."[]\" value=\"$k\" type=\"radio\" $checked/> $v</label>\r\n";
                                                                $out .= "<label for=\"".$key.$elementNo."\" class=\"inlineLabel\"><input name=\"".$key."[]\" id=\"".$key.$elementNo."\" value=\"$k\" type=\"radio\" $checked/> $v </label>\r\n";
                                                                $elementNo++;
                                                        }
                                                }
                                                $new_record[$key] = $out;
                                        break;
                                        case 'DATETIME':
                                                if (strtotime($val) !== false) {
                                                    $dt_value = $val;
                                                } elseif ( isset($field['default']) && (strtotime($field['default']) !== false) ) {
                                                    $dt_value = $field['default'];
                                                } else {
                                                    $dt_value = 0;
                                                }
                                                $display_seconds = (isset($field['display_seconds']) && $field['display_seconds'] == true) ? true : false;
                                                $new_record[$key] = $this->_getDateTimeHTML($key, $dt_value, $display_seconds);
                                        break;
                                                                $elementNo++;
                                                        }
                                                }
                                                $new_record[$key] = $out;
                                        break;
                                        default:
                                        case 'DATETIME':
                                                if (strtotime($val) !== false) {
                                                    $dt_value = $val;
                                                } elseif ( isset($field['default']) && (strtotime($field['default']) !== false) ) {
                                                    $dt_value = $field['default'];
                                                } else {
                                                    $dt_value = 0;
                                                }
                                                $display_seconds = (isset($field['display_seconds']) && $field['display_seconds'] == true) ? true : false;
                                                $new_record[$key] = $this->_getDateTimeHTML($key, $dt_value, $display_seconds);
                                        break;
                                        default:
                                            if(isset($record[$key])) {
                                                $new_record[$key] = htmlspecialchars($record[$key]);
                                                $new_record[$key] = htmlspecialchars($record[$key]);
                                            } else {
                                                $new_record[$key] = '';
                                            }
                                        }
                                }
                        }
                } else {
                        // Action: NEW
                        foreach($this->formDef['tabs'][$tab]['fields'] as $key => $field) {
                                        }
                                }
                        }
                } 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'])) {
                                    if(is_array($field["value"])) {
                                // If Datasource is set, get the data from there
                                if(@is_array($field['datasource'])) {
                                    if(is_array($field["value"])) {
                                        $field["value"] = $app->functions->array_merge($field["value"],$this->getDatasourceData($field, $record));
                                    } else {
                                        $field["value"] = $this->getDatasourceData($field, $record);
                                        $field["value"] = $this->getDatasourceData($field, $record);
                                    }
                                }
                                }
                                // If a limitation for the values is set
                                if(isset($field['valuelimit']) && is_array($field["value"])) {
                                    $field["value"] = $this->applyValueLimit($field['valuelimit'],$field["value"]);
                                }
                                switch ($field['formtype']) {
                                case 'SELECT':
                                        if(is_array($field['value'])) {
                                                $out = '';
                                                foreach($field['value'] as $k => $v) {
                                                    $selected = ($k == $field["default"])?' SELECTED':'';
                                                    $out .= "<option value='$k'$selected>".$this->lng($v)."</option>\r\n";
                                                }
                                        }
                                        if(isset($out)) $new_record[$key] = $out;
                                break;
                                case 'MULTIPLE':
                                                if(is_array($field['value'])) {
                                switch ($field['formtype']) {
                                case 'SELECT':
                                        if(is_array($field['value'])) {
                                                $out = '';
                                                foreach($field['value'] as $k => $v) {
                                                    $selected = ($k == $field["default"])?' SELECTED':'';
                                                    $out .= "<option value='$k'$selected>".$this->lng($v)."</option>\r\n";
                                                }
                                        }
                                        if(isset($out)) $new_record[$key] = $out;
                                break;
                                case 'MULTIPLE':
                                                if(is_array($field['value'])) {
                                                        // aufsplitten ergebnisse
                                                        $vals = explode($field['separator'],$val);
                                                        // aufsplitten ergebnisse
                                                        $vals = explode($field['separator'],$val);
                                                        // HTML schreiben
                                                        $out = '';
                                                        foreach($field['value'] as $k => $v) {
                                                        // HTML schreiben
                                                        $out = '';
                                                        foreach($field['value'] as $k => $v) {
                                                                $out .= "<option value='$k'>$v</option>\r\n";
                                                        }
                                                }
                                                $new_record[$key] = $out;
                                        break;
                                                                $out .= "<option value='$k'>$v</option>\r\n";
                                                        }
                                                }
                                                $new_record[$key] = $out;
                                        break;
                                case 'PASSWORD':
                                        $new_record[$key] = '';
                                break;
                                case 'PASSWORD':
                                        $new_record[$key] = '';
                                break;
                                case 'CHECKBOX':
                                        // $checked = (empty($field["default"]))?'':' CHECKED';
                                                            $checked = ($field["default"] == $field['value'][1])?' CHECKED':'';
                                        $new_record[$key] = "<input name=\"".$key."\" id=\"".$key."\" value=\"".$field['value'][1]."\" type=\"checkbox\" $checked />\r\n";
                                break;
                                case 'CHECKBOX':
                                        // $checked = (empty($field["default"]))?'':' CHECKED';
                                                            $checked = ($field["default"] == $field['value'][1])?' CHECKED':'';
                                        $new_record[$key] = "<input name=\"".$key."\" id=\"".$key."\" value=\"".$field['value'][1]."\" type=\"checkbox\" $checked />\r\n";
                                break;
                                case 'CHECKBOXARRAY':
                                        if(is_array($field['value'])) {
                                case 'CHECKBOXARRAY':
                                        if(is_array($field['value'])) {
                                                // aufsplitten ergebnisse
                                                $vals = explode($field['separator'],$field["default"]);
                                                // aufsplitten ergebnisse
                                                $vals = explode($field['separator'],$field["default"]);
                                                // HTML schreiben
                                                $out = '';
                                                $elementNo = 0;
                                                foreach($field['value'] as $k => $v) {
                                                // HTML schreiben
                                                $out = '';
                                                $elementNo = 0;
                                                foreach($field['value'] as $k => $v) {
                                                        $checked = '';
                                                        foreach($vals as $tvl) {
                                                                if(trim($tvl) == trim($k)) $checked = ' CHECKED';
                                                        }
                                                        // $out .= "<label for=\"".$key."[]\" class=\"inlineLabel\"><input name=\"".$key."[]\" id=\"".$key."[]\" value=\"$k\" type=\"checkbox\" $checked /> $v</label>\r\n";
                                                        $checked = '';
                                                        foreach($vals as $tvl) {
                                                                if(trim($tvl) == trim($k)) $checked = ' CHECKED';
                                                        }
                                                        // $out .= "<label for=\"".$key."[]\" class=\"inlineLabel\"><input name=\"".$key."[]\" id=\"".$key."[]\" value=\"$k\" type=\"checkbox\" $checked /> $v</label>\r\n";
                                                        $out .= "<label for=\"".$key.$elementNo."\" class=\"inlineLabel\"><input name=\"".$key."[]\" id=\"".$key.$elementNo."\" value=\"$k\" type=\"checkbox\" $checked /> $v</label> &nbsp;\r\n";
                                                        $elementNo++;
                                                }
                                        }
                                        $new_record[$key] = $out;
                                break;
                                                        $elementNo++;
                                                }
                                        }
                                        $new_record[$key] = $out;
                                break;
                                case 'RADIO':
                                        if(is_array($field['value'])) {
                                case 'RADIO':
                                        if(is_array($field['value'])) {
                                                // HTML schreiben
                                                $out = '';
                                                $elementNo = 0;
                                                foreach($field['value'] as $k => $v) {
                                                        $checked = ($k == $field["default"])?' CHECKED':'';
                                                        //$out .= "<label for=\"".$key."[]\" class=\"inlineLabel\"><input name=\"".$key."[]\" id=\"".$key."[]\" value=\"$k\" type=\"radio\" $checked/> $v</label>\r\n";
                                                // HTML schreiben
                                                $out = '';
                                                $elementNo = 0;
                                                foreach($field['value'] as $k => $v) {
                                                        $checked = ($k == $field["default"])?' CHECKED':'';
                                                        //$out .= "<label for=\"".$key."[]\" class=\"inlineLabel\"><input name=\"".$key."[]\" id=\"".$key."[]\" value=\"$k\" type=\"radio\" $checked/> $v</label>\r\n";
                                                        $out .= "<label for=\"".$key.$elementNo."\" class=\"inlineLabel\"><input name=\"".$key."[]\" id=\"".$key.$elementNo."\" value=\"$k\" type=\"radio\" $checked/> $v</label>\r\n";
                                                        $elementNo++;
                                                }
                                        }
                                        $new_record[$key] = $out;
                                break;
                                case 'DATETIME':
                                        $dt_value = (isset($field['default'])) ? $field['default'] : 0;
                                        $display_seconds = (isset($field['display_seconds']) && $field['display_seconds'] == true) ? true : false;
                                        $new_record[$key] = $this->_getDateTimeHTML($key, $dt_value, $display_seconds);
                                break;
                                                        $elementNo++;
                                                }
                                        }
                                        $new_record[$key] = $out;
                                break;
                                default:
                                        $new_record[$key] = htmlspecialchars($field['default']);
                                }
                        }
                                case 'DATETIME':
                                        $dt_value = (isset($field['default'])) ? $field['default'] : 0;
                                        $display_seconds = (isset($field['display_seconds']) && $field['display_seconds'] == true) ? true : false;
                }
                                        $new_record[$key] = $this->_getDateTimeHTML($key, $dt_value, $display_seconds);
                                break;
                if($this->debug == 1) $this->dbg($new_record);
                                default:
                                        $new_record[$key] = htmlspecialchars($field['default']);
                                }
                        }
                return $new_record;
        }
                }
        /**
        * Rewrite the record data to be stored in the database
        * and check values with regular expressions.
        *
        * @param record = Datensatz als Array
        * @return record
        */
        function encode($record,$tab,$dbencode = true) {
                if($this->debug == 1) $this->dbg($new_record);
                return $new_record;
        }
        /**
        * Rewrite the record data to be stored in the database
        * and check values with regular expressions.
        *
        * @param record = Datensatz als Array
        * @return record
        */
        function encode($record,$tab,$dbencode = true) {
            global $app;
                if(!is_array($this->formDef['tabs'][$tab])) $app->error("Tab is empty or does not exist (TAB: $tab).");
                //$this->errorMessage = '';
                if(is_array($record)) {
                        foreach($this->formDef['tabs'][$tab]['fields'] as $key => $field) {
                if(!is_array($this->formDef['tabs'][$tab])) $app->error("Tab is empty or does not exist (TAB: $tab).");
                //$this->errorMessage = '';
                if(is_array($record)) {
                        foreach($this->formDef['tabs'][$tab]['fields'] as $key => $field) {
                                //* Apply filter to record value
                                if(isset($field['filters']) && is_array($field['filters'])) {
                                if(isset($field['filters']) && is_array($field['filters'])) {
                                    $record[$key] = $this->filterField($key, (isset($record[$key]))?$record[$key]:'', $field['filters'], 'SAVE');
                                }
                                //* Validate record value
@@ -645,31 +645,31 @@
                                    $this->validateField($key, (isset($record[$key]))?$record[$key]:'', $field['validators']);
                                }
                                switch ($field['datatype']) {
                                case 'VARCHAR':
                                        if(!@is_array($record[$key])) {
                                switch ($field['datatype']) {
                                case 'VARCHAR':
                                        if(!@is_array($record[$key])) {
                                                $new_record[$key] = (isset($record[$key]))?$record[$key]:'';
                                        } else {
                                                $new_record[$key] = implode($field['separator'],$record[$key]);
                                        }
                                break;
                                case 'TEXT':
                                        if(!is_array($record[$key])) {
                                                $new_record[$key] = $record[$key];
                                        } else {
                                                $new_record[$key] = implode($field['separator'],$record[$key]);
                                        }
                                break;
                                case 'DATETSTAMP':
                                        if($record[$key] > 0) {
                                                list($tag,$monat,$jahr) = explode('.',$record[$key]);
                                                $new_record[$key] = mktime(0,0,0,$monat,$tag,$jahr);
                                        } else {
                                        } else {
                                                $new_record[$key] = implode($field['separator'],$record[$key]);
                                        }
                                break;
                                case 'TEXT':
                                        if(!is_array($record[$key])) {
                                                $new_record[$key] = $record[$key];
                                        } else {
                                                $new_record[$key] = implode($field['separator'],$record[$key]);
                                        }
                                break;
                                case 'DATETSTAMP':
                                        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;
                                break;
                                case 'DATE':
                                        if($record[$key] != '' && $record[$key] != '0000-00-00') {
                                        if($record[$key] != '' && $record[$key] != '0000-00-00') {
                                                if(function_exists('date_parse_from_format')) {
                                                    $date_parts = date_parse_from_format($this->dateformat,$record[$key]);
                                                    //list($tag,$monat,$jahr) = explode('.',$record[$key]);
@@ -682,67 +682,67 @@
                                                    $tmp = strtotime($record[$key]);
                                                    $new_record[$key] = date('Y-m-d',$tmp);
                                                }
                                        } else {
                                        } else {
                                            $new_record[$key] = '0000-00-00';
                                        }
                                break;
                                case 'INTEGER':
                                break;
                                case 'INTEGER':
                                        $new_record[$key] = (isset($record[$key]))?$app->functions->intval($record[$key]):0;
                                        //if($new_record[$key] != $record[$key]) $new_record[$key] = $field['default'];
                                        //if($key == 'refresh') die($record[$key]);
                                break;
                                case 'DOUBLE':
                                        $new_record[$key] = $record[$key];
                                break;
                                case 'CURRENCY':
                                        $new_record[$key] = str_replace(",",".",$record[$key]);
                                break;
                                case 'DATETIME':
                                        if (is_array($record[$key]))
                                        {
                                            $filtered_values = array_map(create_function('$item','return (int)$item;'), $record[$key]);
                                            extract($filtered_values, EXTR_PREFIX_ALL, '_dt');
                                            if ($_dt_day != 0 && $_dt_month != 0 && $_dt_year != 0) {
                                                $new_record[$key] = date( 'Y-m-d H:i:s', mktime($_dt_hour, $_dt_minute, $_dt_second, $_dt_month, $_dt_day, $_dt_year) );
                                            }
                                        }
                                break;
                                }
                                        //if($new_record[$key] != $record[$key]) $new_record[$key] = $field['default'];
                                        //if($key == 'refresh') die($record[$key]);
                                break;
                                case 'DOUBLE':
                                        $new_record[$key] = $record[$key];
                                break;
                                case 'CURRENCY':
                                        $new_record[$key] = str_replace(",",".",$record[$key]);
                                break;
                                // The use of the field value is deprecated, use validators instead
                                if(isset($field['regex']) && $field['regex'] != '') {
                                        // Enable that "." matches also newlines
                                        $field['regex'] .= 's';
                                        if(!preg_match($field['regex'], $record[$key])) {
                                                $errmsg = $field['errmsg'];
                                                $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
                                        }
                                }
                                case 'DATETIME':
                                        if (is_array($record[$key]))
                                        {
                                            $filtered_values = array_map(create_function('$item','return (int)$item;'), $record[$key]);
                                            extract($filtered_values, EXTR_PREFIX_ALL, '_dt');
                                            if ($_dt_day != 0 && $_dt_month != 0 && $_dt_year != 0) {
                                                $new_record[$key] = date( 'Y-m-d H:i:s', mktime($_dt_hour, $_dt_minute, $_dt_second, $_dt_month, $_dt_day, $_dt_year) );
                                            }
                                        }
                                break;
                                }
                                // The use of the field value is deprecated, use validators instead
                                if(isset($field['regex']) && $field['regex'] != '') {
                                        // Enable that "." matches also newlines
                                        $field['regex'] .= 's';
                                        if(!preg_match($field['regex'], $record[$key])) {
                                                $errmsg = $field['errmsg'];
                                                $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
                                        }
                                }
                                //* Add slashes to all records, when we encode data which shall be inserted into mysql.
                                if($dbencode == true) $new_record[$key] = $app->db->quote($new_record[$key]);
                        }
                }
                return $new_record;
        }
        /**
        * process the filters for a given field.
        *
        * @param field_name = Name of the field
        * @param field_value = value of the field
        * @param filters = Array of filters
        * @param filter_event = 'SAVE'or 'SHOW'
        * @return record
        */
                        }
                }
                return $new_record;
        }
        function filterField($field_name, $field_value, $filters, $filter_event) {
        /**
        * process the filters for a given field.
        *
        * @param field_name = Name of the field
        * @param field_value = value of the field
        * @param filters = Array of filters
        * @param filter_event = 'SAVE'or 'SHOW'
        * @return record
        */
        function filterField($field_name, $field_value, $filters, $filter_event) {
            global $app;
            $returnval = $field_value;
            //* Loop trough all filters
            foreach($filters as $filter) {
                if($filter['event'] == $filter_event) {
@@ -765,157 +765,157 @@
                    }
                }
            }
            return $returnval;
        }
            return $returnval;
        }
        /**
        * 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
        */
        /**
        * 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) {
        function validateField($field_name, $field_value, $validators) {
                global $app;
                global $app;
                $escape = '`';
                // loop trough the validators
                foreach($validators as $validator) {
                        switch ($validator['type']) {
                                case 'REGEX':
                                        $validator['regex'] .= 's';
                                        if(!preg_match($validator['regex'], $field_value)) {
                                                $errmsg = $validator['errmsg'];
                                                if(isset($this->wordbook[$errmsg])) {
                                                    $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
                // loop trough the validators
                foreach($validators as $validator) {
                        switch ($validator['type']) {
                                case 'REGEX':
                                        $validator['regex'] .= 's';
                                        if(!preg_match($validator['regex'], $field_value)) {
                                                $errmsg = $validator['errmsg'];
                                                if(isset($this->wordbook[$errmsg])) {
                                                    $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
                                                } else {
                                                    $this->errorMessage .= $errmsg."<br />\r\n";
                                                }
                                        }
                                break;
                                case 'UNIQUE':
                                        }
                                break;
                                case 'UNIQUE':
                                        if($validator['allowempty'] != 'y') $validator['allowempty'] = 'n';
                                        if($validator['allowempty'] == 'n' || ($validator['allowempty'] == 'y' && $field_value != '')){
                                            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'];
                                                $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";
                                                            $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";
                                                $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";
                                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(function_exists('filter_var')) {
                                        }
                                break;
                                case 'ISEMAIL':
                                    if(function_exists('filter_var')) {
                                        if(filter_var($field_value, FILTER_VALIDATE_EMAIL) === false) {
                                            $errmsg = $validator['errmsg'];
                                            if(isset($this->wordbook[$errmsg])) {
                                                $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
                                            if(isset($this->wordbook[$errmsg])) {
                                                $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
                                            } else {
                                                $this->errorMessage .= $errmsg."<br />\r\n";
                                            }
                                        }
                                        }
                                    } else {
                                        if(!preg_match("/^\w+[\w\.\-\+]*\w{0,}@\w+[\w.-]*\w+\.[a-zA-Z0-9\-]{2,30}$/i", $field_value)) {
                                                $errmsg = $validator['errmsg'];
                                                if(isset($this->wordbook[$errmsg])) {
                                                    $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
                                                $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':
                                break;
                                case 'ISINT':
                                    if(function_exists('filter_var') && $field_value < 2147483647) {
                                        if($field_value != '' && filter_var($field_value, FILTER_VALIDATE_INT) === false) {
                                            $errmsg = $validator['errmsg'];
                                            if(isset($this->wordbook[$errmsg])) {
                                                $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
                                                $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
                                            } else {
                                                $this->errorMessage .= $errmsg."<br />\r\n";
                                            }
                                        }
                                        }
                                    } else {
                                        $tmpval = $app->functions->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";
                                        $tmpval = $app->functions->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";
                                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;
                                        }
                                break;
                case 'ISV6PREFIX':
                    $v6_prefix_ok = 0;
                    $explode_field_value = explode(':',$field_value);
                    if ($explode_field_value[count($explode_field_value)-1]=='' && $explode_field_value[count($explode_field_value)-2]=='' ){
                            if ( count($explode_field_value) <= 9 ) {
                                    if(filter_var(substr($field_value,0,strlen($field_value)-2),FILTER_VALIDATE_IP,FILTER_FLAG_IPV6) or filter_var(substr($field_value,0,strlen($field_value)-2).'::0',FILTER_VALIDATE_IP,FILTER_FLAG_IPV6) or filter_var(substr($field_value,0,strlen($field_value)-2).':0',FILTER_VALIDATE_IP,FILTER_FLAG_IPV6) ) {
                                            $v6_prefix_ok = 1;
                                    }
                            }
                    } else {
                        $v6_prefix_ok = 2;
                            if ( count($explode_field_value) <= 9 ) {
                                    if(filter_var(substr($field_value,0,strlen($field_value)-2),FILTER_VALIDATE_IP,FILTER_FLAG_IPV6) or filter_var(substr($field_value,0,strlen($field_value)-2).'::0',FILTER_VALIDATE_IP,FILTER_FLAG_IPV6) or filter_var(substr($field_value,0,strlen($field_value)-2).':0',FILTER_VALIDATE_IP,FILTER_FLAG_IPV6) ) {
                                            $v6_prefix_ok = 1;
                                    }
                            }
                    } else {
                        $v6_prefix_ok = 2;
                    }
                    // check subnet against defined server-ipv6
                    $sql_v6 = $app->db->queryOneRecord("SELECT ip_address FROM server_ip WHERE ip_type = 'IPv6' AND virtualhost = 'y' LIMIT 0,1");
                    $sql_v6_explode=explode(':',$sql_v6['ip_address']);
                    if ( count($sql_v6_explode) < count($explode_field_value) && isset($sql_v6['ip_address']) )  {
                        $v6_prefix_ok = 3;
                    if ( count($sql_v6_explode) < count($explode_field_value) && isset($sql_v6['ip_address']) )  {
                        $v6_prefix_ok = 3;
                    }
                    if($v6_prefix_ok == 0) {
                        $errmsg = $validator['errmsg'];
                    if($v6_prefix_ok == 0) {
                        $errmsg = $validator['errmsg'];
                    }
                    if($v6_prefix_ok == 2) {
                        $errmsg = 'IPv6 Prefix must end with ::';
                    if($v6_prefix_ok == 2) {
                        $errmsg = 'IPv6 Prefix must end with ::';
                    }
                    if($v6_prefix_ok == 3) {
                        $errmsg = 'IPv6 Prefix too long (according to Server IP Addresses)';
                    if($v6_prefix_ok == 3) {
                        $errmsg = 'IPv6 Prefix too long (according to Server IP Addresses)';
                    }
                    if($v6_prefix_ok <> 1){
                        $this->errorMessage .= $errmsg."<br />\r\n";
                        $this->errorMessage .= $errmsg."<br />\r\n";
                    }
                break;
                                case 'ISIPV4':
@@ -927,15 +927,15 @@
                                    $vip=0;
                                }
                                }else{$vip=0;}
                                        if($vip==0) {
                                        if($vip==0) {
                                        $errmsg = $validator['errmsg'];
                                          if(isset($this->wordbook[$errmsg])) {
                                             $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
                                          if(isset($this->wordbook[$errmsg])) {
                                             $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";
                                          } else {
                                             $this->errorMessage .= $errmsg."<br />\r\n";
                                          }
                                        }
                                break;
                                break;
                                case 'ISIP':
                                if($validator['allowempty'] != 'y') $validator['allowempty'] = 'n';
                                if($validator['allowempty'] == 'y' && $field_value == '') {
@@ -979,13 +979,13 @@
                                        }
                                    }
                                }
                                break;
                                break;
                                case 'RANGE':
                                        //* Checks if the value is within the given range or above / below a value
                                        //* Checks if the value is within the given range or above / below a value
                                        //* Range examples: < 10 = ":10", between 2 and 10 = "2:10", above 5 = "5:".
                                        $range_parts = explode(':',trim($validator['range']));
                                        $ok = true;
                                        if($range_parts[0] != '' && $field_value < $range_parts[0]) {
                                        if($range_parts[0] != '' && $field_value < $range_parts[0]) {
                                            $ok = false;
                                        }
                                        if($range_parts[1] != '' && $field_value > $range_parts[1]) {
@@ -998,76 +998,76 @@
                                            } else {
                                                $this->errorMessage .= $errmsg."<br />\r\n";
                                            }
                                        }
                                        }
                                        unset($range_parts);
                                break;
                                case 'CUSTOM':
                                        // Calls a custom class to validate this record
                                        if($validator['class'] != '' and $validator['function'] != '') {
                                                $validator_class = $validator['class'];
                                                $validator_function = $validator['function'];
                                                $app->uses($validator_class);
                                                $this->errorMessage .= $app->$validator_class->$validator_function($field_name, $field_value, $validator);
                                        } else {
                                                $this->errorMessage .= "Custom validator class or function is empty<br />\r\n";
                                        }
                                break;
                                break;
                                case 'CUSTOM':
                                        // Calls a custom class to validate this record
                                        if($validator['class'] != '' and $validator['function'] != '') {
                                                $validator_class = $validator['class'];
                                                $validator_function = $validator['function'];
                                                $app->uses($validator_class);
                                                $this->errorMessage .= $app->$validator_class->$validator_function($field_name, $field_value, $validator);
                                        } else {
                                                $this->errorMessage .= "Custom validator class or function is empty<br />\r\n";
                                        }
                                break;
                                default:
                                    $this->errorMessage .= "Unknown Validator: ".$validator['type'];
                                break;
                        }
                        }
                }
                }
                return true;
        }
                return true;
        }
        /**
        * Create SQL statement
        *
        * @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 = '') {
        /**
        * Create SQL statement
        *
        * @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;
                global $app;
                // If there are no data records on the tab, return empty sql string
                if(count($this->formDef['tabs'][$tab]['fields']) == 0) return '';
                // If there are no data records on the tab, return empty sql string
                if(count($this->formDef['tabs'][$tab]['fields']) == 0) return '';
                // checking permissions
                if($this->formDef['auth'] == 'yes' && $_SESSION["s"]["user"]["typ"] != 'admin') {
                        if($action == "INSERT") {
                                if(!$this->checkPerm($primary_id,'i')) $this->errorMessage .= "Insert denied.<br />\r\n";
                        } else {
                                if(!$this->checkPerm($primary_id,'u')) $this->errorMessage .= "Update denied.<br />\r\n";
                        }
                }
                // checking permissions
                if($this->formDef['auth'] == 'yes' && $_SESSION["s"]["user"]["typ"] != 'admin') {
                        if($action == "INSERT") {
                                if(!$this->checkPerm($primary_id,'i')) $this->errorMessage .= "Insert denied.<br />\r\n";
                        } else {
                                if(!$this->checkPerm($primary_id,'u')) $this->errorMessage .= "Update denied.<br />\r\n";
                        }
                }
                $this->action = $action;
                $this->primary_id = $primary_id;
                $this->action = $action;
                $this->primary_id = $primary_id;
                $record = $this->encode($record,$tab,true);
                $sql_insert_key = '';
                $sql_insert_val = '';
                $sql_update = '';
                $record = $this->encode($record,$tab,true);
                $sql_insert_key = '';
                $sql_insert_val = '';
                $sql_update = '';
                if(!is_array($this->formDef)) $app->error("Form definition not found.");
                if(!is_array($this->formDef['tabs'][$tab])) $app->error("The tab is empty or does not exist (TAB: $tab).");
                if(!is_array($this->formDef)) $app->error("Form definition not found.");
                if(!is_array($this->formDef['tabs'][$tab])) $app->error("The tab is empty or does not exist (TAB: $tab).");
                // go trough all fields of the tab
                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') {
                // go trough all fields of the tab
                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') {
                                                                $record[$key] = $app->auth->crypt_password(stripslashes($record[$key]));
                                                                $sql_insert_val .= "'".$app->db->quote($record[$key])."', ";
                                                        } elseif ($field['encryption'] == 'MYSQL') {
@@ -1076,13 +1076,13 @@
                                                                $sql_insert_val .= "'".$app->db->quote($record[$key])."', ";
                                                        } elseif ($field['encryption'] == 'CLEARTEXT') {
                                                                $sql_insert_val .= "'".$app->db->quote($record[$key])."', ";
                                                        } else {
                                                                $record[$key] = md5(stripslashes($record[$key]));
                                                        } else {
                                                                $record[$key] = md5(stripslashes($record[$key]));
                                                                $sql_insert_val .= "'".$app->db->quote($record[$key])."', ";
                                                        }
                                                } elseif ($field['formtype'] == 'CHECKBOX') {
                                                        $sql_insert_key .= "`$key`, ";
                                                        }
                                                } elseif ($field['formtype'] == 'CHECKBOX') {
                                                        $sql_insert_key .= "`$key`, ";
                                                        if($record[$key] == '') {
                                                            // if a checkbox is not set, we set it to the unchecked value
                                                            $sql_insert_val .= "'".$field['value'][0]."', ";
@@ -1090,14 +1090,14 @@
                                                        } else {
                                                            $sql_insert_val .= "'".$record[$key]."', ";
                                                        }
                                                } else {
                                                        $sql_insert_key .= "`$key`, ";
                                                        $sql_insert_val .= "'".$record[$key]."', ";
                                                }
                                        } else {
                                                if($field['formtype'] == 'PASSWORD') {
                                                } else {
                                                        $sql_insert_key .= "`$key`, ";
                                                        $sql_insert_val .= "'".$record[$key]."', ";
                                                }
                                        } else {
                                                if($field['formtype'] == 'PASSWORD') {
                                                        if(isset($field['encryption']) && $field['encryption'] == 'CRYPT') {
                                                                $record[$key] = $app->auth->crypt_password(stripslashes($record[$key]));
                                                                $record[$key] = $app->auth->crypt_password(stripslashes($record[$key]));
                                                                $sql_update .= "`$key` = '".$app->db->quote($record[$key])."', ";
                                                        } elseif (isset($field['encryption']) && $field['encryption'] == 'MYSQL') {
                                                                $tmp = $app->db->queryOneRecord("SELECT PASSWORD('".$app->db->quote(stripslashes($record[$key]))."') as `crypted`");
@@ -1105,12 +1105,12 @@
                                                                $sql_update .= "`$key` = '".$app->db->quote($record[$key])."', ";
                                                        } elseif (isset($field['encryption']) && $field['encryption'] == 'CLEARTEXT') {
                                                                $sql_update .= "`$key` = '".$app->db->quote($record[$key])."', ";
                                                        } else {
                                                                $record[$key] = md5(stripslashes($record[$key]));
                                                        } else {
                                                                $record[$key] = md5(stripslashes($record[$key]));
                                                                $sql_update .= "`$key` = '".$app->db->quote($record[$key])."', ";
                                                        }
                                                } elseif ($field['formtype'] == 'CHECKBOX') {
                                                        }
                                                } elseif ($field['formtype'] == 'CHECKBOX') {
                                                        if($record[$key] == '') {
                                                            // if a checkbox is not set, we set it to the unchecked value
                                                            $sql_update .= "`$key` = '".$field['value'][0]."', ";
@@ -1118,343 +1118,343 @@
                                                        } else {
                                                            $sql_update .= "`$key` = '".$record[$key]."', ";
                                                        }
                                                } else {
                                                        $sql_update .= "`$key` = '".$record[$key]."', ";
                                                }
                                        }
                                } else {
                                    // we unset the password filed, if empty to tell the datalog function
                                                } else {
                                                        $sql_update .= "`$key` = '".$record[$key]."', ";
                                                }
                                        }
                                } else {
                                    // we unset the password filed, if empty to tell the datalog function
                                    // that the password has not been changed
                                    unset($record[$key]);
                                    unset($record[$key]);
                                }
                        }
        }
                        }
        }
                // Add backticks for incomplete table names
                if(stristr($this->formDef['db_table'],'.')) {
                        $escape = '';
                } else {
                        $escape = '`';
                }
                // Add backticks for incomplete table names
                if(stristr($this->formDef['db_table'],'.')) {
                        $escape = '';
                } else {
                        $escape = '`';
                }
                if($action == "INSERT") {
                        if($this->formDef['auth'] == 'yes') {
                                // Set user and group
                                $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($action == "INSERT") {
                        if($this->formDef['auth'] == 'yes') {
                                // Set user and group
                                $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($this->formDef['auth'] == 'yes') {
                        if($primary_id != 0) {
                                $sql_update = substr($sql_update,0,-2);
                                $sql = "UPDATE ".$escape.$this->formDef['db_table'].$escape." SET ".$sql_update." WHERE ".$this->getAuthSQL('u')." AND ".$this->formDef['db_table_idx']." = ".$primary_id;
                                if($sql_ext_where != '') $sql .= " and ".$sql_ext_where;
                        } else {
                                $app->error("Primary ID fehlt!");
                        }
                        if($primary_id != 0) {
                                $sql_update = substr($sql_update,0,-2);
                                $sql = "UPDATE ".$escape.$this->formDef['db_table'].$escape." SET ".$sql_update." WHERE ".$this->getAuthSQL('u')." AND ".$this->formDef['db_table_idx']." = ".$primary_id;
                                if($sql_ext_where != '') $sql .= " and ".$sql_ext_where;
                        } else {
                                $app->error("Primary ID fehlt!");
                        }
                    } 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!");
                        }
                                $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!");
                        }
                    }
                    //* return a empty string if there is nothing to update
                    if(trim($sql_update) == '') $sql = '';
                }
                }
                return $sql;
        }
                return $sql;
        }
        /**
        * Debugging arrays.
        *
        * @param array_data
        */
        function dbg($array_data) {
        /**
        * Debugging arrays.
        *
        * @param array_data
        */
        function dbg($array_data) {
                echo "<pre>";
                print_r($array_data);
                echo "</pre>";
                echo "<pre>";
                print_r($array_data);
                echo "</pre>";
        }
        }
    function showForm() {
            global $app,$conf;
    function showForm() {
            global $app,$conf;
        if(!is_array($this->formDef)) die("Form Definition wurde nicht geladen.");
        if(!is_array($this->formDef)) die("Form Definition wurde nicht geladen.");
                $active_tab = $this->getNextTab();
                $active_tab = $this->getNextTab();
        // go trough the tabs
        foreach( $this->formDef["tabs"] as $key => $tab) {
        // go trough the tabs
        foreach( $this->formDef["tabs"] as $key => $tab) {
            $tab['name'] = $key;
            $tab['name'] = $key;
            // Translate the title of the tab
            $tab['title'] = $this->lng($tab['title']);
            if($tab['name'] == $active_tab) {
                // If module is set, then set the template path relative to the module..
                if($this->module != '') $tab["template"] = "../".$this->module."/".$tab["template"];
            if($tab['name'] == $active_tab) {
                // Generate the template if it does not exist yet.
                if(!is_file($tab["template"])) {
                     $app->uses('tform_tpl_generator');
                     $app->tform_tpl_generator->buildHTML($this->formDef,$tab['name']);
                }
                $app->tpl->setVar('readonly_tab', (isset($tab['readonly']) && $tab['readonly'] == true));
                $app->tpl->setInclude('content_tpl',$tab["template"]);
                $tab["active"] = 1;
                $_SESSION["s"]["form"]["tab"] = $tab['name'];
            } else {
                    $tab["active"] = 0;
            }
                // If module is set, then set the template path relative to the module..
                if($this->module != '') $tab["template"] = "../".$this->module."/".$tab["template"];
                        // Unset unused variables.
                        unset($tab["fields"]);
                        unset($tab["plugins"]);
                // Generate the template if it does not exist yet.
            $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);
                if(!is_file($tab["template"])) {
                     $app->uses('tform_tpl_generator');
                     $app->tform_tpl_generator->buildHTML($this->formDef,$tab['name']);
                }
                $app->tpl->setVar('readonly_tab', (isset($tab['readonly']) && $tab['readonly'] == true));
                $app->tpl->setInclude('content_tpl',$tab["template"]);
                $tab["active"] = 1;
                $_SESSION["s"]["form"]["tab"] = $tab['name'];
            } else {
                    $tab["active"] = 0;
            }
                // Set form title
                $form_hint = $this->lng($this->formDef["title"]);
                if($this->formDef["description"] != '') $form_hint .= '<div class="pageForm_description">'.$this->lng($this->formDef["description"]).'</div>';
                $app->tpl->setVar('form_hint',$form_hint);
                        // Unset unused variables.
                        unset($tab["fields"]);
                        unset($tab["plugins"]);
                // Set Wordbook for this form
            $frmTab[] = $tab;
        }
                $app->tpl->setVar($this->wordbook);
        }
        // setting form tabs
        $app->tpl->setLoop("formTab", $frmTab);
                // Set form action
                $app->tpl->setVar('form_action',$this->formDef["action"]);
                $app->tpl->setVar('form_active_tab',$active_tab);
                // Set form title
                $form_hint = $this->lng($this->formDef["title"]);
                if($this->formDef["description"] != '') $form_hint .= '<div class="pageForm_description">'.$this->lng($this->formDef["description"]).'</div>';
                $app->tpl->setVar('form_hint',$form_hint);
                // Set Wordbook for this form
                $app->tpl->setVar($this->wordbook);
        }
        function getDataRecord($primary_id) {
            global $app;
            $escape = '`';
            $sql = "SELECT * FROM ".$escape.$this->formDef['db_table'].$escape." WHERE ".$this->formDef['db_table_idx']." = ".$primary_id;
            return $app->db->queryOneRecord($sql);
            return $app->db->queryOneRecord($sql);
        }
        function datalogSave($action,$primary_id, $record_old, $record_new) {
                global $app,$conf;
        function datalogSave($action,$primary_id, $record_old, $record_new) {
                global $app,$conf;
                $app->db->datalogSave($this->formDef['db_table'], $action, $this->formDef['db_table_idx'], $primary_id, $record_old, $record_new);
                return true;
                /*
                // Add backticks for incomplete table names.
                if(stristr($this->formDef['db_table'],'.')) {
                        $escape = '';
                } else {
                        $escape = '`';
                }
                $this->diffrec = array();
                /*
                // Add backticks for incomplete table names.
                if(stristr($this->formDef['db_table'],'.')) {
                        $escape = '';
                } else {
                        $escape = '`';
                }
                $this->diffrec = array();
                // Full diff records for ISPConfig, they have a different format then the simple diffrec
                $diffrec_full = array();
                if(is_array($record_old) && count($record_old) > 0) {
                        foreach($record_old as $key => $val) {
                                //if(isset($record_new[$key]) && $record_new[$key] != $val) {
                if(is_array($record_old) && count($record_old) > 0) {
                        foreach($record_old as $key => $val) {
                                //if(isset($record_new[$key]) && $record_new[$key] != $val) {
                                if(!isset($record_new[$key]) || $record_new[$key] != $val) {
                                    // Record has changed
                                    // Record has changed
                                    $diffrec_full['old'][$key] = $val;
                                    $diffrec_full['new'][$key] = $record_new[$key];
                                    $this->diffrec[$key] = array(    'new' => $record_new[$key],
                                                                       'old' => $val);
                                } else {
                                                                       'old' => $val);
                                } else {
                                    $diffrec_full['old'][$key] = $val;
                                    $diffrec_full['new'][$key] = $val;
                                }
                        }
                } elseif(is_array($record_new)) {
                        foreach($record_new as $key => $val) {
                                if(isset($record_new[$key]) && $record_old[$key] != $val) {
                                    // Record has changed
                        }
                } elseif(is_array($record_new)) {
                        foreach($record_new as $key => $val) {
                                if(isset($record_new[$key]) && $record_old[$key] != $val) {
                                    // Record has changed
                                    $diffrec_full['new'][$key] = $val;
                                    $diffrec_full['old'][$key] = $record_old[$key];
                                    $this->diffrec[$key] = array(    'old' => @$record_old[$key],
                                                                       'new' => $val);
                                } else {
                                                                       'new' => $val);
                                } else {
                                    $diffrec_full['new'][$key] = $val;
                                    $diffrec_full['old'][$key] = $val;
                                }
                        }
                }
                        }
                }
                //$this->diffrec = $diffrec;
                // Insert the server_id, if the record has a server_id
                $server_id = (isset($record_old["server_id"]) && $record_old["server_id"] > 0)?$record_old["server_id"]:0;
                if(isset($record_new["server_id"])) $server_id = $record_new["server_id"];
                if(count($this->diffrec) > 0) {
                if(count($this->diffrec) > 0) {
                        $diffstr = addslashes(serialize($diffrec_full));
                        $username = $app->db->quote($_SESSION["s"]["user"]["username"]);
                        $dbidx = $this->formDef['db_table_idx'].":".$primary_id;
                        // $action = ($action == 'INSERT')?'i':'u';
                        $username = $app->db->quote($_SESSION["s"]["user"]["username"]);
                        $dbidx = $this->formDef['db_table_idx'].":".$primary_id;
                        // $action = ($action == 'INSERT')?'i':'u';
                        if($action == 'INSERT') $action = 'i';
                        if($action == 'UPDATE') $action = 'u';
                        if($action == 'DELETE') $action = 'd';
                        $sql = "INSERT INTO sys_datalog (dbtable,dbidx,server_id,action,tstamp,user,data) VALUES ('".$this->formDef['db_table']."','$dbidx','$server_id','$action','".time()."','$username','$diffstr')";
                        $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;
                return true;
                */
        }
        }
        function getAuthSQL($perm, $table = '') {
        function getAuthSQL($perm, $table = '') {
                if($_SESSION["s"]["user"]["typ"] == 'admin') {
                    return '1';
                } else {
                    if ($table != ''){
                        $table = ' ' . $table . '.';
                    }
                    $groups = ( $_SESSION["s"]["user"]["groups"] ) ? $_SESSION["s"]["user"]["groups"] : 0;
                    $groups = ( $_SESSION["s"]["user"]["groups"] ) ? $_SESSION["s"]["user"]["groups"] : 0;
                    $sql = '(';
                    $sql .= "(" . $table . "sys_userid = ".$_SESSION["s"]["user"]["userid"]." AND " . $table . "sys_perm_user like '%$perm%') OR  ";
                    $sql .= "(" . $table . "sys_groupid IN (".$groups.") AND " . $table ."sys_perm_group like '%$perm%') OR ";
                    $sql .= $table . "sys_perm_other like '%$perm%'";
                    $sql .= ')';
                    $sql .= "(" . $table . "sys_userid = ".$_SESSION["s"]["user"]["userid"]." AND " . $table . "sys_perm_user like '%$perm%') OR  ";
                    $sql .= "(" . $table . "sys_groupid IN (".$groups.") AND " . $table ."sys_perm_group like '%$perm%') OR ";
                    $sql .= $table . "sys_perm_other like '%$perm%'";
                    $sql .= ')';
                    return $sql;
                    return $sql;
                }
        }
        }
        /*
        This function checks if a user has the parmissions $perm for the data record with the ID $record_id
        If record_id = 0, the the permissions are tested against the defaults of the form file.
        */
        function checkPerm($record_id,$perm) {
                global $app;
        /*
        This function checks if a user has the parmissions $perm for the data record with the ID $record_id
        If record_id = 0, the the permissions are tested against the defaults of the form file.
        */
        function checkPerm($record_id,$perm) {
                global $app;
                if($record_id > 0) {
                        // Add backticks for incomplete table names.
                        if(stristr($this->formDef['db_table'],'.')) {
                                $escape = '';
                        } else {
                                $escape = '`';
                        }
                if($record_id > 0) {
                        // Add backticks for incomplete table names.
                        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;
                        $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;
                        // 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;
                        return $result;
                }
                }
        }
        }
        function getNextTab() {
                // Which tab is shown
                if($this->errorMessage == '') {
                    // If there is no error
                    if(isset($_REQUEST["next_tab"]) && $_REQUEST["next_tab"] != '') {
                                // If the next tab is known
                                $active_tab = $_REQUEST["next_tab"];
                    } else {
                        // else use the default tab
                        $active_tab = $this->formDef['tab_default'];
                    }
                } else {
                    // Show the same tab again in case of an error
                    $active_tab = $_SESSION["s"]["form"]["tab"];
                }
        function getNextTab() {
                // Which tab is shown
                if($this->errorMessage == '') {
                    // If there is no error
                    if(isset($_REQUEST["next_tab"]) && $_REQUEST["next_tab"] != '') {
                                // If the next tab is known
                                $active_tab = $_REQUEST["next_tab"];
                    } else {
                        // else use the default tab
                        $active_tab = $this->formDef['tab_default'];
                    }
                } else {
                    // Show the same tab again in case of an error
                    $active_tab = $_SESSION["s"]["form"]["tab"];
                }
                return $active_tab;
        }
                return $active_tab;
        }
        function getCurrentTab() {
                return $_SESSION["s"]["form"]["tab"];
        }
        function getCurrentTab() {
                return $_SESSION["s"]["form"]["tab"];
        }
        function isReadonlyTab($tab, $primary_id) {
            global $app, $conf;
            // Add backticks for incomplete table names.
            if(stristr($this->formDef['db_table'],'.')) {
                $escape = '';
            } else {
                $escape = '`';
            }
            if(stristr($this->formDef['db_table'],'.')) {
                $escape = '';
            } else {
                $escape = '`';
            }
            $sql = "SELECT sys_userid FROM ".$escape.$this->formDef['db_table'].$escape." WHERE ".$this->formDef['db_table_idx']." = ".$primary_id;
            $record = $app->db->queryOneRecord($sql);
            $record = $app->db->queryOneRecord($sql);
            // return true if the readonly flag of the form is set and the current loggedin user is not the owner of the record.
            if(isset($this->formDef['tabs'][$tab]['readonly']) && $this->formDef['tabs'][$tab]['readonly'] == true && $record['sys_userid'] != $_SESSION["s"]["user"]["userid"]) {
                return true;
            } else {
                return false;
            }
        }
        }
        // translation function for forms, tries the form wordbook first and if this fails, it tries the global wordbook
        function lng($msg) {
            global $app,$conf;
            if(isset($this->wordbook[$msg])) {
                return $this->wordbook[$msg];
            } else {
                return $app->lng($msg);
            }
        }
        function checkClientLimit($limit_name,$sql_where = '') {
            global $app;
            $check_passed = true;
            $limit_name = $app->db->quote($limit_name);
            if($limit_name == '') $app->error('Limit name missing in function checkClientLimit.');
            // Get the limits of the client that is currently logged in
            $client_group_id = $_SESSION["s"]["user"]["default_group"];
            $client = $app->db->queryOneRecord("SELECT $limit_name as number, parent_client_id FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id");
            // Check if the user may add another item
            if($client["number"] >= 0) {
                $sql = "SELECT count(".$this->formDef['db_table_idx'].") as number FROM ".$this->formDef['db_table']." WHERE ".$this->getAuthSQL('u');
@@ -1462,33 +1462,33 @@
                $tmp = $app->db->queryOneRecord($sql);
                if($tmp["number"] >= $client["number"]) $check_passed = false;
            }
            return $check_passed;
        }
        function checkResellerLimit($limit_name,$sql_where = '') {
            global $app;
            $check_passed = true;
            $limit_name = $app->db->quote($limit_name);
            if($limit_name == '') $app->error('Limit name missing in function checkClientLimit.');
            // Get the limits of the client that is currently logged in
            $client_group_id = $_SESSION["s"]["user"]["default_group"];
            $client = $app->db->queryOneRecord("SELECT parent_client_id FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id");
            //* If the client belongs to a reseller, we will check against the reseller Limit too
            if($client['parent_client_id'] != 0) {
                //* first we need to know the groups of this reseller
                $tmp = $app->db->queryOneRecord("SELECT userid, groups FROM sys_user WHERE client_id = ".$client['parent_client_id']);
                $reseller_groups = $tmp["groups"];
                $reseller_userid = $tmp["userid"];
                // Get the limits of the reseller of the logged in client
                $client_group_id = $_SESSION["s"]["user"]["default_group"];
                $reseller = $app->db->queryOneRecord("SELECT $limit_name as number FROM client WHERE client_id = ".$client['parent_client_id']);
                // Check if the user may add another item
                if($reseller["number"] >= 0) {
                    $sql = "SELECT count(".$this->formDef['db_table_idx'].") as number FROM ".$this->formDef['db_table']." WHERE (sys_groupid IN (".$reseller_groups.") or sys_userid = ".$reseller_userid.")";
@@ -1497,13 +1497,13 @@
                    if($tmp["number"] >= $reseller["number"]) $check_passed = false;
                }
            }
            return $check_passed;
        }
        //* get the difference record of two arrays
        function getDiffRecord($record_old,$record_new) {
            if(is_array($record_new) && count($record_new) > 0) {
            foreach($record_new as $key => $val) {
                if(@$record_old[$key] != $val) {
@@ -1522,17 +1522,17 @@
                    }
                }
            return $diffrec;
        }
        /**
         * Generate HTML for DATETIME fields.
         *
         *
         * @access private
         * @param string $form_element Name of the form element.
         * @param string $default_value Selected value for fields.
         * @param bool $display_secons Include seconds selection.
         * @return string HTML
         * @return string HTML
         */
        function _getDateTimeHTML($form_element, $default_value, $display_seconds=false)
        {
@@ -1540,54 +1540,54 @@
            $_showdate = ($_datetime === false) ? false : true;
            $dselect = array('day','month','year','hour','minute');
            if ($display_seconds === true) {
            if ($display_seconds === true) {
                 $dselect[] = 'second';
            }
            $out = '';
            foreach ($dselect as $dt_element)
            {
                 $dt_options = array();
                 $dt_space = 1;
                 switch ($dt_element) {
                     case 'day':
                         for ($i = 1; $i <= 31; $i++) {
                            $dt_options[] = array('name' =>  sprintf('%02d', $i),
                                                  'value' => sprintf('%d', $i));
                        }
                        $selected_value = date('d', $_datetime);
                            $dt_options[] = array('name' =>  sprintf('%02d', $i),
                                                  'value' => sprintf('%d', $i));
                        }
                        $selected_value = date('d', $_datetime);
                         break;
                     case 'month':
                         for ($i = 1; $i <= 12; $i++) {
                            $dt_options[] = array('name' => strftime('%b', mktime(0, 0, 0, $i, 1, 2000)),
                                                  'value' => strftime('%m', mktime(0, 0, 0, $i, 1, 2000)));
                        }
                        $selected_value = date('n', $_datetime);
                            $dt_options[] = array('name' => strftime('%b', mktime(0, 0, 0, $i, 1, 2000)),
                                                  'value' => strftime('%m', mktime(0, 0, 0, $i, 1, 2000)));
                        }
                        $selected_value = date('n', $_datetime);
                         break;
                     case 'year':
                         $start_year = strftime("%Y");
                        $years = range((int)$start_year, (int)($start_year+3));
                        foreach ($years as $year) {
                            $dt_options[] = array('name' => $year,
                                                 'value' => $year);
                        }
                        $selected_value = date('Y', $_datetime);
                        $dt_space = 2;
                        foreach ($years as $year) {
                            $dt_options[] = array('name' => $year,
                                                 'value' => $year);
                        }
                        $selected_value = date('Y', $_datetime);
                        $dt_space = 2;
                         break;
                     case 'hour':
                         foreach(range(0, 23) as $hour) {
                             $dt_options[] = array('name' =>  sprintf('%02d', $hour),
                                                  'value' => sprintf('%d', $hour));
                                                  'value' => sprintf('%d', $hour));
                         }
                         $selected_value = date('G', $_datetime);
                         break;
                     case 'minute':
                         foreach(range(0, 59) as $minute) {
                             if (($minute % 5) == 0) {
@@ -1597,23 +1597,23 @@
                         }
                         $selected_value = (int)floor(date('i', $_datetime));
                         break;
                     case 'second':
                     case 'second':
                         foreach(range(0, 59) as $second) {
                             $dt_options[] = array('name' =>  sprintf('%02d', $second),
                                                    'value' => sprintf('%d', $second));
                                                    'value' => sprintf('%d', $second));
                         }
                         $selected_value = (int)floor(date('s', $_datetime));
                         break;
                 }
                $out .= "<select name=\"".$form_element."[$dt_element]\" id=\"".$form_element."_$dt_element\" class=\"selectInput\" style=\"width: auto; float: none;\">";
                if (!$_showdate) {
                    $out .= "<option value=\"-\" selected=\"selected\">--</option>" . PHP_EOL;
                } else {
                    $out .= "<option value=\"-\">--</option>" . PHP_EOL;
                }
                foreach ($dt_options as $dt_opt) {
                    if ( $_showdate && ($selected_value == $dt_opt['value']) ) {
                        $out .= "<option value=\"{$dt_opt['value']}\" selected=\"selected\">{$dt_opt['name']}</option>" . PHP_EOL;
@@ -1621,10 +1621,10 @@
                        $out .= "<option value=\"{$dt_opt['value']}\">{$dt_opt['name']}</option>" . PHP_EOL;
                    }
                }
                $out .= '</select>' . str_repeat('&nbsp;', $dt_space);
            }
            return $out;
        }
}
interface/lib/classes/tools_monitor.inc.php
@@ -453,6 +453,40 @@
        return $html;
    }
    function showMongoDB() {
        global $app;
        /* fetch the Data from the DB */
        $record = $app->db->queryOneRecord("SELECT data, state FROM monitor_data WHERE type = 'log_mongodb' and server_id = " . $_SESSION['monitor']['server_id'] . " order by created desc");
        if(isset($record['data'])) {
            $html =
                    '<div class="systemmonitor-state state-'.$record['state'].'">
                <div class="systemmonitor-content icons32 ico-'.$record['state'].'">';
            /*
             * First, we have to detect, if there is any monitoring-data.
             * If not (because mongodb is not installed) show this.
            */
            $data = unserialize($record['data']);
            if ($data == '') {
                $html .= '<p>'.
                        'MongoDB is not installed at this server.<br />' .
                        'See more (for debian) <a href="http://www.howtoforge.com/fail2ban_debian_etch" target="htf">here...</a>'.
                        '</p>';
            }
            else {
                $html .= nl2br($data);
            }
            $html .= '</div></div>';
        } else {
            $html = '<p>There is no data available at the moment.</p>';
        }
        return $html;
    }
    function showIPTables() {
        global $app;
        $record = $app->db->queryOneRecord("SELECT data, state FROM monitor_data WHERE type = 'iptables_rules' and server_id = " . $_SESSION['monitor']['server_id'] . " order by created desc");
interface/lib/shelluser_blacklist
@@ -31,4 +31,5 @@
getmail
ispconfig
courier
dovecot
dovecot
mongodb
interface/web/admin/form/server_config.tform.php
@@ -89,9 +89,9 @@
        'v6_prefix' => array(
            'datatype' => 'VARCHAR',
            'formtype' => 'TEXT',
                        'validators' => array(0 => array('type' => 'ISV6PREFIX',
                                        'errmsg' => 'v6_prefix_wrong'),
                        ),
                        'validators' => array(0 => array('type' => 'ISV6PREFIX',
                                        'errmsg' => 'v6_prefix_wrong'),
                        ),
        'default' => ''
        ),
        'gateway' => array(
@@ -117,13 +117,13 @@
            'datatype' => 'VARCHAR',
            'formtype' => 'TEXT',
            'default' => 'server1.domain.tld',
            'filters'   => array( 0 => array( 'event' => 'SAVE',
                                              'type' => 'IDNTOASCII'),
                                  1 => array( 'event' => 'SHOW',
                                              'type' => 'IDNTOUTF8'),
                                  2 => array( 'event' => 'SAVE',
                                              'type' => 'TOLOWER')
                                ),
            'filters'   => array( 0 => array( 'event' => 'SAVE',
                                              'type' => 'IDNTOASCII'),
                                  1 => array( 'event' => 'SHOW',
                                              'type' => 'IDNTOUTF8'),
                                  2 => array( 'event' => 'SAVE',
                                              'type' => 'TOLOWER')
                                ),
            'validators' => array(0 => array('type' => 'NOTEMPTY',
                    'errmsg' => 'hostname_error_empty'),
            ),
@@ -182,9 +182,9 @@
            'formtype' => 'TEXT',
            'default' => '',
            'validators'    => array ( 0 => array (    'type'    => 'REGEX',
                                                                'regex' => '/^[0-9a-zA-Z\:\/\-\.\[\]]{0,255}$/',
                                                                'errmsg'=> 'monit_url_error_regex'),
                                                ),
                                                                'regex' => '/^[0-9a-zA-Z\:\/\-\.\[\]]{0,255}$/',
                                                                'errmsg'=> 'monit_url_error_regex'),
                                                ),
            'value' => '',
            'width' => '40',
            'maxlength' => '255'
@@ -210,9 +210,9 @@
            'formtype' => 'TEXT',
            'default' => '',
            'validators'    => array ( 0 => array (    'type'    => 'REGEX',
                                                                'regex' => '/^[0-9a-zA-Z\:\/\-\.\[\]]{0,255}$/',
                                                                'errmsg'=> 'munin_url_error_regex'),
                                                ),
                                                                'regex' => '/^[0-9a-zA-Z\:\/\-\.\[\]]{0,255}$/',
                                                                'errmsg'=> 'munin_url_error_regex'),
                                                ),
            'value' => '',
            'width' => '40',
            'maxlength' => '255'
@@ -275,19 +275,19 @@
            'width' => '40',
            'maxlength' => '255'
        ),
                'dkim_path' => array(
                        'datatype' => 'VARCHAR',
                        'formtype' => 'TEXT',
                        'default' => '/var/db/dkim',
                        'validators'    => array (  0 => array ('type'  => 'CUSTOM',
                                                                'class' => 'validate_dkim',
                                                                'function' => 'check_dkim_path',
                                                                'errmsg'=> 'dkim_path_error'),
                                                 ),
                        'value' => '',
                        'width' => '40',
                        'maxlength' => '255'
                ),
                'dkim_path' => array(
                        'datatype' => 'VARCHAR',
                        'formtype' => 'TEXT',
                        'default' => '/var/db/dkim',
                        'validators'    => array (  0 => array ('type'  => 'CUSTOM',
                                                                'class' => 'validate_dkim',
                                                                'function' => 'check_dkim_path',
                                                                'errmsg'=> 'dkim_path_error'),
                                                 ),
                        'value' => '',
                        'width' => '40',
                        'maxlength' => '255'
                ),
        'pop3_imap_daemon' => array(
            'datatype' => 'VARCHAR',
            'formtype' => 'SELECT',
@@ -419,8 +419,8 @@
            'formtype' => 'TEXT',
            'default' => '7',
            'value' => '',
            'width' => '20',
            'maxlength' => '255'
            'width' => '20',
            'maxlength' => '255'
        ),
        'overquota_notify_onok' => array(
            'datatype' => 'VARCHAR',
@@ -659,8 +659,8 @@
            'formtype' => 'TEXT',
            'default' => '7',
            'value' => '',
            'width' => '20',
            'maxlength' => '255'
            'width' => '20',
            'maxlength' => '255'
        ),
        'overquota_notify_onok' => array(
            'datatype' => 'VARCHAR',
@@ -1306,6 +1306,12 @@
            'default' => 'n',
            'value' => array(0 => 'n', 1 => 'y')
        ),
        'do_not_try_rescue_mongodb' => array(
            'datatype' => 'VARCHAR',
            'formtype' => 'CHECKBOX',
            'default' => 'n',
            'value' => array(0 => 'n', 1 => 'y')
        ),
        'do_not_try_rescue_mysql' => array(
            'datatype' => 'VARCHAR',
            'formtype' => 'CHECKBOX',
interface/web/admin/lib/lang/de_server_config.lng
@@ -146,6 +146,7 @@
$wb['fastcgi_config_syntax_txt'] = 'FastCGI Konfigurations Syntax';
$wb['try_rescue_txt'] = 'Aktiviere Service Monitoring und Neustart bei Unerreichbarkeit';
$wb['do_not_try_rescue_httpd_txt'] = 'Deaktiviere HTTPD Monitoring';
$wb['do_not_try_rescue_mongodb_txt'] = 'Deaktiviere MongoDB Monitoring';
$wb['do_not_try_rescue_mysql_txt'] = 'Deaktiviere MySQL Monitoring';
$wb['do_not_try_rescue_mail_txt'] = 'Deaktiviere E-Mail Monitoring';
$wb['rescue_description_txt'] = '<b>Information:</b> Falls Sie MySQL stoppen möchten, wählen Sie die Funktion \'Deaktiviere MySQL Monitoring\' und warten Sie 2 bis 3 Minuten. Wenn Sie nicht 2 bis 3 Miunten warten wird ISPConfig versuchen MySQL wieder zu starten.';
interface/web/admin/lib/lang/en_server_config.lng
@@ -151,6 +151,7 @@
$wb["php_fpm_socket_dir_error_empty"] = 'PHP-FPM socket directory is empty.';
$wb["try_rescue_txt"] = 'Enable service monitoring and restart on failure';
$wb["do_not_try_rescue_httpd_txt"] = 'Disable HTTPD monitoring';
$wb["do_not_try_rescue_mongodb_txt"] = 'Disable MongoDB monitoring';
$wb["do_not_try_rescue_mysql_txt"] = 'Disable MySQL monitoring';
$wb["do_not_try_rescue_mail_txt"] = 'Disable Email monitoring';
$wb["rescue_description_txt"] = '<b>Information:</b> If you want to shut down mysql you have to select the "Disable MySQL monitor" checkbox and then wait 2-3 minutes.<br>If you do not wait 2-3 minutes, rescue will try to restart mysql!';
@@ -190,4 +191,4 @@
$wb['munin_password_txt'] = 'Munin Password';
$wb['munin_url_error_regex'] = 'Invalid Munin URL';
$wb['munin_url_note_txt'] = 'Placeholder:';
?>
?>
interface/web/admin/templates/server_config_rescue_edit.htm
@@ -18,6 +18,12 @@
                </div>
            </div>
            <div class="ctrlHolder">
                <p class="label" style="width:300px">{tmpl_var name='do_not_try_rescue_mongodb_txt'}</p>
                <div class="multiField" style="width:100px">
                    {tmpl_var name='do_not_try_rescue_mongodb'}
                </div>
            </div>
            <div class="ctrlHolder">
                <p class="label" style="width:300px">{tmpl_var name='do_not_try_rescue_mysql_txt'}</p>
                <div class="multiField" style="width:100px">
                    {tmpl_var name='do_not_try_rescue_mysql'}
@@ -30,15 +36,15 @@
                </div>
            </div>
        </fieldset>
        <tmpl_var name="rescue_description_txt">
            <input type="hidden" name="id" value="{tmpl_var name='id'}">
            <div class="buttonHolder buttons">
                <button class="positive iconstxt icoPositive" type="button" value="{tmpl_var name='btn_save_txt'}" onclick="submitForm('pageForm','admin/server_config_edit.php');"><span>{tmpl_var name='btn_save_txt'}</span></button>
                <button class="negative iconstxt icoNegative" type="button" value="{tmpl_var name='btn_cancel_txt'}" onclick="loadContent('admin/server_config_list.php');"><span>{tmpl_var name='btn_cancel_txt'}</span></button>
            </div>
    </div>
</div>
</div>
interface/web/monitor/lib/lang/de.lng
@@ -122,6 +122,7 @@
$wb['monitor_services_pop_txt'] = 'POP3 Server:';
$wb['monitor_services_imap_txt'] = 'IMAP Server:';
$wb['monitor_services_mydns_txt'] = 'DNS Server:';
$wb['monitor_services_mongodb_txt'] = 'MongoDB Server:';
$wb['monitor_services_mysql_txt'] = 'MySQL Server:';
$wb['monitor_settings_datafromdate_txt'] = 'Daten vom: ';
$wb['monitor_settings_datetimeformat_txt'] = 'd.m.Y H:i';
@@ -134,6 +135,7 @@
$wb['monitor_title_rkhunterlog_txt'] = 'RKHunter Protokoll';
$wb['monitor_updates_nosupport_txt'] = 'Ihre Distribution wird für die Ãœberwachung nicht unterstützt';
$wb['monitor_title_fail2ban_txt'] = 'Fail2Ban Protokoll';
$wb['monitor_title_mongodb_txt'] = 'MongoDB Protokoll';
$wb['monitor_nosupportedraid1_txt'] = 'At the moment, we support mdadm or mpt-status for monitoring the RAID.<br>We cant find any of them at your server.<br><br>This means we can not support your RAID yet.';
$wb['monitor_serverstate_beancounterok_txt'] = 'The beancounter is ok';
$wb['monitor_serverstate_beancounterinfo_txt'] = 'There are vew failure in the beancounter';
@@ -144,6 +146,7 @@
$wb['monitor_beancounter_nosupport_txt'] = 'This server is not a OpenVz VE and has no beancounter information';
$wb['monitor_title_iptables_txt'] = 'IPTables Regeln';
$wb['Show fail2ban-Log'] = 'Fail2ban Protokoll anzeigen';
$wb['Show MongoDB-Log'] = 'MongoDB Protokoll anzeigen';
$wb['Show IPTables'] = 'IPTables anzeigen';
$wb['Show OpenVz VE BeanCounter'] = 'OpenVz VE BeanCounter anzeigen';
$wb['Show Monit'] = 'Monit anzeigen';
interface/web/monitor/lib/lang/en.lng
@@ -46,6 +46,7 @@
$wb['Show RKHunter-Log'] = 'Show RKHunter-Log';
$wb['Show Jobqueue'] = 'Show Jobqueue';
$wb['Show fail2ban-Log'] = 'Show fail2ban-Log';
$wb['Show MongoDB-Log'] = 'Show MongoDB-Log';
$wb['Show IPTables'] = 'Show IPTables';
$wb['Show OpenVz VE BeanCounter'] = 'Show OpenVz VE BeanCounter';
$wb['monitor_general_serverstate_txt'] = 'Server State';
@@ -131,6 +132,7 @@
$wb['monitor_services_pop_txt'] = 'POP3-Server:';
$wb['monitor_services_imap_txt'] = 'IMAP-Server:';
$wb['monitor_services_mydns_txt'] = 'DNS-Server:';
$wb['monitor_services_mongodb_txt'] = 'MongoDB-Server:';
$wb['monitor_services_mysql_txt'] = 'mySQL-Server:';
$wb['monitor_settings_datafromdate_txt'] = 'Data from: ';
$wb['monitor_settings_datetimeformat_txt'] = 'Y-m-d H:i';
@@ -142,6 +144,7 @@
$wb['monitor_title_raidstate_txt'] = 'RAID Status';
$wb['monitor_title_rkhunterlog_txt'] = 'RKHunter Log';
$wb['monitor_title_fail2ban_txt'] = 'Fail2Ban Log';
$wb['monitor_title_mongodb_txt'] = 'MongoDB Log';
$wb['monitor_title_iptables_txt'] = 'IPTables Rules';
$wb['monitor_title_beancounter_txt'] = 'OpenVz VE BeanCounter';
$wb['monitor_updates_nosupport_txt'] = 'Your distribution is not supported for this monitoring';
interface/web/monitor/lib/module.conf.php
@@ -190,6 +190,11 @@
                  'link'    => 'monitor/show_data.php?type=fail2ban',
                  'html_id' => 'fai2ban');
$items[] = array( 'title'     => "Show MongoDB-Log",
                  'target'     => 'content',
                  'link'    => 'monitor/show_data.php?type=mongodb',
                  'html_id' => 'mongodb');
$items[] = array( 'title'     => "Show IPTables",
                  'target'     => 'content',
                  'link'    => 'monitor/show_data.php?type=iptables',
@@ -198,4 +203,4 @@
$module["nav"][] = array(    'title'    => 'Logfiles',
                            'open'     => 1,
                            'items'    => $items);
?>
?>
interface/web/monitor/show_data.php
@@ -124,6 +124,13 @@
        $title = $app->lng("monitor_title_fail2ban_txt") . ' (' . $monTransSrv . ' : ' . $_SESSION['monitor']['server_name'] . ')';
        $description = '';
        break;
    case 'mongodb':
        $template = 'templates/show_data.htm';
        $output .= $app->tools_monitor->showMongoDB();
        $time = $app->tools_monitor->getDataTime('log_mongodb');
        $title = $app->lng("monitor_title_mongodb_txt") . ' (' . $monTransSrv . ' : ' . $_SESSION['monitor']['server_name'] . ')';
        $description = '';
        break;
    case 'iptables':
        $template = 'templates/show_data.htm';
        $output .= $app->tools_monitor->showIPTables();
interface/web/sites/database_user_edit.php
@@ -57,17 +57,17 @@
         * If the names are restricted -> remove the restriction, so that the
         * data can be edited
         */
        //* Get the database user prefix
        $app->uses('getconf,tools_sites');
        $global_config = $app->getconf->get_global_config('sites');
        $dbuser_prefix = $app->tools_sites->replacePrefix($global_config['dbuser_prefix'], $this->dataRecord);
        if ($_SESSION["s"]["user"]["typ"] != 'admin' && $app->auth->has_clients($_SESSION['s']['user']['userid'])) {
            // Get the limits of the client
            $client_group_id = $_SESSION["s"]["user"]["default_group"];
            $client = $app->db->queryOneRecord("SELECT client.company_name, client.contact_name, client.client_id FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id");
            // Fill the client select field
            $sql = "SELECT sys_group.groupid, sys_group.name, CONCAT(IF(client.company_name != '', CONCAT(client.company_name, ' :: '), ''), client.contact_name, ' (', client.username, IF(client.customer_no != '', CONCAT(', ', client.customer_no), ''), ')') as contactname FROM sys_group, client WHERE sys_group.client_id = client.client_id AND client.parent_client_id = ".$client['client_id']." ORDER BY sys_group.name";
            $records = $app->db->queryAllRecords($sql);
@@ -96,24 +96,24 @@
            }
            $app->tpl->setVar("client_group_id",$client_select);
        }
        if ($this->dataRecord['database_user'] != ""){
            /* REMOVE the restriction */
            $app->tpl->setVar("database_user", $app->tools_sites->removePrefix($this->dataRecord['database_user'], $this->dataRecord['database_user_prefix'], $dbuser_prefix));
        }
        $app->tpl->setVar("database_user_prefix", $app->tools_sites->getPrefix($this->dataRecord['database_user_prefix'], $dbuser_prefix, $global_config['dbuser_prefix']));
        parent::onShowEnd();
    }
    function onSubmit() {
        global $app;
        if($_SESSION['s']['user']['typ'] != 'admin' && !$app->auth->has_clients($_SESSION['s']['user']['userid'])) unset($this->dataRecord["client_group_id"]);
        parent::onSubmit();
    }
@@ -126,35 +126,40 @@
        $dbuser_prefix = $app->tools_sites->replacePrefix($global_config['dbuser_prefix'], $this->dataRecord);
        $this->oldDataRecord = $app->db->queryOneRecord("SELECT * FROM web_database_user WHERE database_user_id = '".$this->id."'");
        $dbuser_prefix = $app->tools_sites->getPrefix($this->oldDataRecord['database_user_prefix'], $dbuser_prefix);
        $this->dataRecord['database_user_prefix'] = $dbuser_prefix;
        //* Database username shall not be empty
        if($this->dataRecord['database_user'] == '') $app->tform->errorMessage .= $app->tform->wordbook["database_user_error_empty"].'<br />';
        if(strlen($dbuser_prefix . $this->dataRecord['database_user']) > 16) $app->tform->errorMessage .= str_replace('{user}',$dbuser_prefix . $this->dataRecord['database_user'],$app->tform->wordbook["database_user_error_len"]).'<br />';
        //* Check database user against blacklist
        $dbuser_blacklist = array($conf['db_user'],'mysql','root');
        if(in_array($dbuser_prefix . $this->dataRecord['database_user'],$dbuser_blacklist)) {
            $app->tform->errorMessage .= $app->lng('Database user not allowed.').'<br />';
        }
        if ($app->tform->errorMessage == ''){
            /* restrict the names if there is no error */
            /* crop user and db names if they are too long -> mysql: user: 16 chars / db: 64 chars */
            $this->dataRecord['database_user'] = substr($dbuser_prefix . $this->dataRecord['database_user'], 0, 16);
        }
        /* prepare password for MongoDB */
        // TODO: this still doens't work as when only the username changes we have no database_password.
        // taking the one from oldData doesn't work as it's encrypted...shit!
        $this->dataRecord['database_password_mongo'] = $this->dataRecord['database_user'].":mongo:".$this->dataRecord['database_password'];
        $this->dataRecord['server_id'] = 0; // we need this on all servers
        parent::onBeforeUpdate();
    }
    function onBeforeInsert() {
        global $app, $conf, $interfaceConf;
        //* Database username shall not be empty
        if($this->dataRecord['database_user'] == '') $app->tform->errorMessage .= $app->tform->wordbook["database_user_error_empty"].'<br />';
@@ -162,11 +167,11 @@
        $app->uses('getconf,tools_sites');
        $global_config = $app->getconf->get_global_config('sites');
        $dbuser_prefix = $app->tools_sites->replacePrefix($global_config['dbuser_prefix'], $this->dataRecord);
        $this->dataRecord['database_user_prefix'] = $dbuser_prefix;
        if(strlen($dbuser_prefix . $this->dataRecord['database_user']) > 16) $app->tform->errorMessage .= str_replace('{user}',$dbuser_prefix . $this->dataRecord['database_user'],$app->tform->wordbook["database_user_error_len"]).'<br />';
        //* Check database user against blacklist
        $dbuser_blacklist = array($conf['db_user'],'mysql','root');
        if(is_array($dbuser_blacklist) && in_array($dbuser_prefix . $this->dataRecord['database_user'],$dbuser_blacklist)) {
@@ -178,15 +183,18 @@
        if ($app->tform->errorMessage == ''){
            $this->dataRecord['database_user'] = substr($dbuser_prefix . $this->dataRecord['database_user'], 0, 16);
        }
        $this->dataRecord['server_id'] = 0; // we need this on all servers
        $this->dataRecord['server_id'] = 0; // we need this on all servers
        /* prepare password for MongoDB */
        $this->dataRecord['database_password_mongo'] = $this->dataRecord['database_user'].":mongo:".$this->dataRecord['database_password'];
        parent::onBeforeInsert();
    }
    function onAfterInsert() {
        global $app, $conf;
        if($_SESSION["s"]["user"]["typ"] == 'admin' && isset($this->dataRecord["client_group_id"])) {
            $client_group_id = $app->functions->intval($this->dataRecord["client_group_id"]);
            $app->db->query("UPDATE web_database_user SET sys_groupid = $client_group_id, sys_perm_group = 'riud' WHERE database_user_id = ".$this->id);
@@ -208,9 +216,9 @@
            $client_group_id = $app->functions->intval($this->dataRecord["client_group_id"]);
            $app->db->query("UPDATE web_database_user SET sys_groupid = $client_group_id, sys_perm_group = 'riud' WHERE database_user_id = ".$this->id);
        }
        /*$password = $app->db->queryOneRecord("SELECT database_password FROM web_database_user WHERE database_user_id = ".$this->id);
        $records = $app->db->queryAllRecords("SELECT DISTINCT server_id FROM web_database WHERE database_user_id = '".$app->functions->intval($this->id)."' UNION SELECT DISTINCT server_id FROM web_database WHERE database_ro_user_id = '".$app->functions->intval($this->id)."'");
        foreach($records as $rec) {
            $new_rec = $this->dataRecord;
interface/web/sites/form/database.tform.php
@@ -29,7 +29,7 @@
    Hint:
    The ID field of the database table is not part of the datafield definition.
    The ID field must be always auto incement (int or bigint).
    Search:
    - searchable = 1 or searchable = 2 include the field in the search
    - searchable = 1: this field will be the title of the search result
@@ -89,7 +89,10 @@
            'datatype'    => 'VARCHAR',
            'formtype'    => 'SELECT',
            'default'    => 'y',
            'value'        => array('mysql' => 'MySQL')
            'value'        => array(
                              'mongo' => 'MongoDB',
                              'mysql' => 'MySQL'
                           )
        ),
        'database_name' => array (
            'datatype'    => 'VARCHAR',
@@ -174,4 +177,4 @@
);
?>
?>
interface/web/sites/form/database_user.tform.php
@@ -29,7 +29,7 @@
    Hint:
    The ID field of the database table is not part of the datafield definition.
    The ID field must be always auto incement (int or bigint).
    Search:
    - searchable = 1 or searchable = 2 include the field in the search
    - searchable = 1: this field will be the title of the search result
@@ -108,6 +108,14 @@
            'width'        => '30',
            'maxlength'    => '255'
        ),
        'database_password_mongo' => array (
            'datatype'    => 'VARCHAR',
            'formtype'    => 'PASSWORD',
            'default'    => '',
            'value'        => '',
            'width'        => '30',
            'maxlength'    => '255'
        ),
    ##################################
    # ENDE Datatable fields
    ##################################
interface/web/sites/lib/lang/de_database_admin_list.lng
@@ -2,6 +2,7 @@
$wb['list_head_txt'] = 'Datenbank';
$wb['active_txt'] = 'Aktiv';
$wb['remote_access_txt'] = 'Remotezugriff';
$wb['type_txt'] = 'Typ';
$wb['server_id_txt'] = 'Server';
$wb['database_user_txt'] = 'Datenbank Benutzer';
$wb['database_name_txt'] = 'Datenbankname';
interface/web/sites/lib/lang/de_database_list.lng
@@ -2,6 +2,7 @@
$wb['list_head_txt'] = 'Datenbank';
$wb['active_txt'] = 'Aktiv';
$wb['remote_access_txt'] = 'Remotezugriff';
$wb['type_txt'] = 'Typ';
$wb['server_id_txt'] = 'Server';
$wb['database_name_txt'] = 'Datenbankname';
$wb['add_new_record_txt'] = 'Neue Datenbank hinzufügen';
interface/web/sites/lib/lang/de_web_backup_list.lng
@@ -10,6 +10,7 @@
$wb['restore_confirm_txt'] = 'Die Wiederherstellung wird existierende Dateien in Ihrer Website Ã¼berschreiben. Möchten Sie dieses Backup wirklich zurückspielen?';
$wb['download_pending_txt'] = 'Es liegt bereits ein Backup Download Job an.';
$wb['restore_pending_txt'] = 'Es liegt bereits ein Backup Wiederherstellungs Job an.';
$wb['backup_type_mongodb'] = 'MongoDB Datenbank';
$wb['backup_type_mysql'] = 'MySQL Datenbank';
$wb['backup_type_web'] = 'Webseiten Dateien';
?>
interface/web/sites/lib/lang/en_database_admin_list.lng
@@ -2,9 +2,10 @@
$wb["list_head_txt"] = 'Database';
$wb["active_txt"] = 'Active';
$wb["remote_access_txt"] = 'Remote Access';
$wb['type_txt'] = 'Type';
$wb["server_id_txt"] = 'Server';
$wb["database_user_txt"] = 'Database user';
$wb["database_name_txt"] = 'Database name';
$wb["add_new_record_txt"] = 'Add new Database';
$wb["sys_groupid_txt"] = 'Client';
?>
?>
interface/web/sites/lib/lang/en_database_list.lng
@@ -2,8 +2,9 @@
$wb["list_head_txt"] = 'Database';
$wb["active_txt"] = 'Active';
$wb["remote_access_txt"] = 'Remote Access';
$wb['type_txt'] = 'Type';
$wb["server_id_txt"] = 'Server';
$wb["database_user_txt"] = 'Database user';
$wb["database_name_txt"] = 'Database name';
$wb["add_new_record_txt"] = 'Add new Database';
?>
?>
interface/web/sites/lib/lang/en_web_backup_list.lng
@@ -11,7 +11,8 @@
$wb['restore_confirm_txt'] = 'Restoring will overwrite existing files in your website. Do you really want to restore this backup?';
$wb['download_pending_txt'] = 'There is already a pending backup download job.';
$wb['restore_pending_txt'] = 'There is already a pending backup restore job.';
$wb['backup_type_mysql'] = 'MySQL Database';
$wb['backup_type_web'] = 'Website files';
?>
$wb['backup_type_mongodb'] = 'MongoDB Database';
$wb['backup_type_mysql'] = 'MySQL Database';
$wb['backup_type_web'] = 'Website files';
?>
interface/web/sites/list/database.list.php
@@ -70,6 +70,19 @@
                            'width'        => "",
                            'value'        => array('y' => "<div id=\"ir-Yes\" class=\"swap\"><span>Yes</span></div>",'n' => "<div class=\"swap\" id=\"ir-No\"><span>No</span></div>"));
$liste["item"][] = array(    'field'        => "type",
                            'datatype'    => "VARCHAR",
                            'formtype'    => "SELECT",
                            'op'        => "=",
                            'prefix'    => "",
                            'suffix'    => "",
                            'width'        => "",
                            'value'        => array(
                                              'mongo' => "MongoDB",
                                              'mysql' => "MySQL"
                                           )
                        );
if($_SESSION['s']['user']['typ'] == 'admin') {
$liste["item"][] = array(    'field'        => "sys_groupid",
                            'datatype'    => "INTEGER",
@@ -123,4 +136,4 @@
                            'width'        => "",
                            'value'        => "");
?>
?>
interface/web/sites/templates/database_admin_list.htm
@@ -19,6 +19,7 @@
                    <tr class="caption">
                        <th class="tbl_col_active" scope="col"><tmpl_var name="active_txt"></th>
                        <th class="tbl_col_remote_access" scope="col"><tmpl_var name="remote_access_txt"></th>
                        <th class="tbl_col_type" scope="col"><tmpl_var name="type_txt"></th>
                        <th class="tbl_col_sys_groupid" scope="col"><tmpl_var name="sys_groupid_txt"></th>
                        <th class="tbl_col_server_id" scope="col"><tmpl_var name="server_id_txt"></th>
                        <th class="tbl_col_database_user_id" scope="col"><tmpl_var name="database_user_txt"></th>
@@ -28,6 +29,7 @@
                    <tr class="filter">
                        <td class="tbl_col_active"><select name="search_active">{tmpl_var name='search_active'}</select></td>
                        <td class="tbl_col_remote_access"><select name="search_remote_access">{tmpl_var name='search_remote_access'}</select></td>
                        <td class="tbl_col_type"><select name="search_type">{tmpl_var name='search_type'}</select></td>
                        <td class="tbl_col_sys_groupid"><select name="search_sys_groupid">{tmpl_var name='search_sys_groupid'}</select></td>
                        <td class="tbl_col_server_id"><select name="search_server_id">{tmpl_var name='search_server_id'}</select></td>
                        <td class="tbl_col_database_user"><select name="search_database_user_id">{tmpl_var name='search_database_user_id'}</select></td>
@@ -42,6 +44,7 @@
                        <tr class="tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>">
                            <td class="tbl_col_active"><a href="#" onclick="loadContent('sites/database_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="active"}</a></td>
                            <td class="tbl_col_remote_access"><a href="#" onclick="loadContent('sites/database_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="remote_access"}</a></td>
                            <td class="tbl_col_type"><a href="#" onclick="loadContent('sites/database_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="type"}</a></td>
                            <td class="tbl_col_sys_groupid"><a href="#" onclick="loadContent('sites/database_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="sys_groupid"}</a></td>
                            <td class="tbl_col_server_id"><a href="#" onclick="loadContent('sites/database_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="server_id"}</a></td>
                            <td class="tbl_col_database_user"><a href="#" onclick="loadContent('sites/database_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="database_user_id"}</a></td>
@@ -51,23 +54,23 @@
                                    <a class="button icons16 icoDbAdmin" href="sites/database_phpmyadmin.php?id={tmpl_var name='id'}" target="phpmyadmin"><span>{tmpl_var name='admin_txt'}</span></a>
                                </tmpl_if>
                                <a class="button icons16 icoEdit" href="javascript: loadContent('sites/database_edit.php?id={tmpl_var name='id'}');"><span>{tmpl_var name='edit_txt'}</span></a>
                                <a class="button icons16 icoDelete" href="javascript: del_record('sites/database_del.php?id={tmpl_var name='id'}&phpsessid={tmpl_var name='phpsessid'}','{tmpl_var name='delete_confirmation'}');"><span>{tmpl_var name='delete_txt'}</span></a>
                                <a class="button icons16 icoDelete" href="javascript: del_record('sites/database_del.php?id={tmpl_var name='id'}&amp;phpsessid={tmpl_var name='phpsessid'}','{tmpl_var name='delete_confirmation'}');"><span>{tmpl_var name='delete_txt'}</span></a>
                            </td>
                        </tr>
                    </tmpl_loop>
                    <tmpl_unless name="records">
                        <tr class="tbl_row_noresults tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>">
                            <td colspan="7">{tmpl_var name='globalsearch_noresults_text_txt'}</td>
                            <td colspan="8">{tmpl_var name='globalsearch_noresults_text_txt'}</td>
                        </tr>
                    </tmpl_unless>
                </tbody>
                <tfoot>
                    <tr>
                        <td class="tbl_footer tbl_paging" colspan="7"><tmpl_var name="paging"></td>
                        <td class="tbl_footer tbl_paging" colspan="8"><tmpl_var name="paging"></td>
                    </tr>
                </tfoot>
            </table>
        </fieldset>
    </div>
</div>
</div>
interface/web/sites/templates/database_list.htm
@@ -36,6 +36,7 @@
                    <tr class="caption">
                        <th class="tbl_col_active" scope="col"><tmpl_var name="active_txt"></th>
                        <th class="tbl_col_remote_access" scope="col"><tmpl_var name="remote_access_txt"></th>
                        <th class="tbl_col_type" scope="col"><tmpl_var name="type_txt"></th>
                        <th class="tbl_col_server_id" scope="col"><tmpl_var name="server_id_txt"></th>
                        <th class="tbl_col_database_user_id" scope="col"><tmpl_var name="database_user_txt"></th>
                        <th class="tbl_col_database_name" scope="col"><tmpl_var name="database_name_txt"></th>
@@ -44,6 +45,7 @@
                    <tr class="filter">
                        <td class="tbl_col_active"><select name="search_active">{tmpl_var name='search_active'}</select></td>
                        <td class="tbl_col_remote_access"><select name="search_remote_access">{tmpl_var name='search_remote_access'}</select></td>
                        <td class="tbl_col_type"><select name="search_type">{tmpl_var name='search_type'}</select></td>
                        <td class="tbl_col_server_id"><select name="search_server_id">{tmpl_var name='search_server_id'}</select></td>
                        <td class="tbl_col_database_user_id"><select name="search_database_user_id">{tmpl_var name='search_database_user_id'}</select></td>
                        <td class="tbl_col_database_name"><input type="text" name="search_database_name" value="{tmpl_var name='search_database_name'}"/></td>
@@ -57,6 +59,7 @@
                        <tr class="tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>">
                            <td class="tbl_col_active"><a href="#" onclick="loadContent('sites/database_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="active"}</a></td>
                            <td class="tbl_col_remote_access"><a href="#" onclick="loadContent('sites/database_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="remote_access"}</a></td>
                            <td class="tbl_col_type"><a href="#" onclick="loadContent('sites/database_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="type"}</a></td>
                            <td class="tbl_col_server_id"><a href="#" onclick="loadContent('sites/database_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="server_id"}</a></td>
                            <td class="tbl_col_database_user"><a href="#" onclick="loadContent('sites/database_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="database_user_id"}</a></td>
                            <td class="tbl_col_database_name"><a href="#" onclick="loadContent('sites/database_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="database_name"}</a></td>
@@ -65,23 +68,23 @@
                                    <a class="button icons16 icoDbAdmin" href="sites/database_phpmyadmin.php?id={tmpl_var name='id'}" target="phpmyadmin"><span>{tmpl_var name='admin_txt'}</span></a>
                                </tmpl_if>
                                <a class="button icons16 icoEdit" href="javascript: loadContent('sites/database_edit.php?id={tmpl_var name='id'}');"><span>{tmpl_var name='edit_txt'}</span></a>
                                <a class="button icons16 icoDelete" href="javascript: del_record('sites/database_del.php?id={tmpl_var name='id'}&phpsessid={tmpl_var name='phpsessid'}','{tmpl_var name='delete_confirmation'}');"><span>{tmpl_var name='delete_txt'}</span></a>
                                <a class="button icons16 icoDelete" href="javascript: del_record('sites/database_del.php?id={tmpl_var name='id'}&amp;phpsessid={tmpl_var name='phpsessid'}','{tmpl_var name='delete_confirmation'}');"><span>{tmpl_var name='delete_txt'}</span></a>
                            </td>
                        </tr>
                    </tmpl_loop>
                    <tmpl_unless name="records">
                        <tr class="tbl_row_noresults tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>">
                            <td colspan="6">{tmpl_var name='globalsearch_noresults_text_txt'}</td>
                            <td colspan="7">{tmpl_var name='globalsearch_noresults_text_txt'}</td>
                        </tr>
                    </tmpl_unless>
                </tbody>
                <tfoot>
                    <tr>
                        <td class="tbl_footer tbl_paging" colspan="6"><tmpl_var name="paging"></td>
                        <td class="tbl_footer tbl_paging" colspan="7"><tmpl_var name="paging"></td>
                    </tr>
                </tfoot>
            </table>
        </fieldset>
    </div>
</div>
</div>
server/cron_daily.php
@@ -54,7 +54,7 @@
foreach($records as $rec) {
    if(@is_file($rec['maildir'].'/ispconfig_mailsize')) {
        $parse_mail_log = false;
        // rename file
        rename($rec['maildir'].'/ispconfig_mailsize',$rec['maildir'].'/ispconfig_mailsize_save');
@@ -92,15 +92,15 @@
    $mailbox_traffic = array();
    $mail_boxes = array();
    $mail_rewrites = array(); // we need to read all mail aliases and forwards because the address in amavis is not always the mailbox address
    function parse_mail_log_line($line) {
        //Oct 31 17:35:48 mx01 amavis[32014]: (32014-05) Passed CLEAN, [IPv6:xxxxx] [IPv6:xxxxx] <xxx@yyyy> -> <aaaa@bbbb>, Message-ID: <xxxx@yyyyy>, mail_id: xxxxxx, Hits: -1.89, size: 1591, queued_as: xxxxxxx, 946 ms
        if(preg_match('/^(\w+\s+\d+\s+\d+:\d+:\d+)\s+[^ ]+\s+amavis.* <([^>]+)>\s+->\s+((<[^>]+>,)+) .*Message-ID:\s+<([^>]+)>.* size:\s+(\d+),.*$/', $line, $matches) == false) return false;
        $timestamp = strtotime($matches[1]);
        if(!$timestamp) return false;
        $to = array();
        $recipients = explode(',', $matches[3]);
        foreach($recipients as $recipient) {
@@ -108,15 +108,15 @@
            if(!$recipient || $recipient == $matches[2]) continue;
            $to[] = $recipient;
        }
        return array('line' => $line, 'timestamp' => $timestamp, 'size' => $matches[6], 'from' => $matches[2], 'to' => $to, 'message-id' => $matches[5]);
    }
    function add_mailbox_traffic(&$traffic_array, $address, $traffic) {
        global $mail_boxes, $mail_rewrites;
        $address = strtolower($address);
        if(in_array($address, $mail_boxes) == true) {
            if(!isset($traffic_array[$address])) $traffic_array[$address] = 0;
            $traffic_array[$address] += $traffic;
@@ -146,17 +146,17 @@
            }
        }
    }
    $state_file = dirname(__FILE__) . '/mail_log_parser.state';
    $prev_line = false;
    $last_line = false;
    $cur_line = false;
    if(file_exists($state_file)) {
        $prev_line = parse_mail_log_line(trim(file_get_contents($state_file)));
        //if($prev_line) echo "continuing from previous run, log position: " . $prev_line['message-id'] . " at " . strftime('%d.%m.%Y %H:%M:%S', $prev_line['timestamp']) . "\n";
    }
    if(file_exists('/var/log/mail.log')) {
        $fp = fopen('/var/log/mail.log', 'r');
        //echo "Parsing mail.log...\n";
@@ -166,7 +166,7 @@
            //if($l % 1000 == 0) echo "\rline $l";
            $cur_line = parse_mail_log_line($line);
            if(!$cur_line) continue;
            if($prev_line) {
                // check if this line has to be processed
                if($cur_line['timestamp'] < $prev_line['timestamp']) {
@@ -178,7 +178,7 @@
                    continue;
                }
            }
            add_mailbox_traffic($mailbox_traffic, $cur_line['from'], $cur_line['size']);
            foreach($cur_line['to'] as $to) {
                add_mailbox_traffic($mailbox_traffic, $to, $cur_line['size']);
@@ -188,7 +188,7 @@
        fclose($fp);
        //echo "\n";
    }
    if($parse_mail_log == true && file_exists('/var/log/mail.log.1')) {
        $fp = fopen('/var/log/mail.log.1', 'r');
        //echo "Parsing mail.log.1...\n";
@@ -198,7 +198,7 @@
            //if($l % 1000 == 0) echo "\rline $l";
            $cur_line = parse_mail_log_line($line);
            if(!$cur_line) continue;
            if($prev_line) {
                // check if this line has to be processed
                if($cur_line['timestamp'] < $prev_line['timestamp']) continue; // already processed
@@ -207,7 +207,7 @@
                    continue;
                }
            }
            add_mailbox_traffic($mailbox_traffic, $cur_line['from'], $cur_line['size']);
            foreach($cur_line['to'] as $to) {
                add_mailbox_traffic($mailbox_traffic, $to, $cur_line['size']);
@@ -218,7 +218,7 @@
    }
    unset($mail_rewrites);
    unset($mail_boxes);
    // Save the traffic stats in the sql database
    $tstamp = date('Y-m');
    $sql = "SELECT mailuser_id,email FROM mail_user WHERE server_id = ".$conf['server_id'];
@@ -238,7 +238,7 @@
            //echo $sql;
        }
    }
    unset($mailbox_traffic);
    if($last_line) file_put_contents($state_file, $last_line);
}
@@ -278,7 +278,7 @@
foreach($records as $rec) {
    //$yesterday = date('Ymd',time() - 86400);
    $yesterday = date('Ymd',strtotime("-1 day", time()));
    $log_folder = 'log';
    if($rec['type'] == 'vhostsubdomain') {
        $tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = '.intval($rec['parent_domain_id']));
@@ -330,7 +330,7 @@
foreach($records as $rec) {
    //$yesterday = date('Ymd',time() - 86400);
    $yesterday = date('Ymd',strtotime("-1 day", time()));
    $log_folder = 'log';
    if($rec['type'] == 'vhostsubdomain') {
        $tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = '.intval($rec['parent_domain_id']));
@@ -452,7 +452,7 @@
    //* create traffic statistics based on yesterdays access log file
    $yesterday = date('Ymd',time() - 86400);
    $log_folder = 'log';
    if($rec['type'] == 'vhostsubdomain') {
        $tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = '.intval($rec['parent_domain_id']));
@@ -461,7 +461,7 @@
        $log_folder .= '/' . $subdomain_host;
        unset($tmp);
    }
    $logfile = $rec['document_root'].'/' . $log_folder . '/'.$yesterday.'-access.log';
    $total_bytes = 0;
@@ -646,10 +646,10 @@
#########
function send_notification_email($template, $placeholders, $recipients) {
    global $conf;
    if(!is_array($recipients) || count($recipients) < 1) return false;
    if(!is_array($placeholders)) $placeholders = array();
    if(file_exists($conf['rootpath'].'/conf-custom/mail/' . $template . '_'.$conf['language'].'.txt')) {
        $lines = file($conf['rootpath'].'/conf-custom/mail/' . $template . '_'.$conf['language'].'.txt');
    } elseif(file_exists($conf['rootpath'].'/conf-custom/mail/' . $template . '_en.txt')) {
@@ -659,7 +659,7 @@
    } else {
        $lines = file($conf['rootpath'].'/conf/mail/' . $template . '_en.txt');
    }
    //* get mail headers, subject and body
    $mailHeaders = '';
    $mailBody = '';
@@ -680,12 +680,12 @@
        }
    }
    $mailBody = trim($mailBody);
    //* Replace placeholders
    $mailHeaders = strtr($mailHeaders, $placeholders);
    $mailSubject = strtr($mailSubject, $placeholders);
    $mailBody = strtr($mailBody, $placeholders);
    for($r = 0; $r < count($recipients); $r++) {
        mail($recipients[$r], $mailSubject, $mailBody, $mailHeaders);
    }
@@ -694,7 +694,7 @@
    unset($mailHeaders);
    unset($mailBody);
    unset($lines);
    return true;
}
@@ -706,7 +706,7 @@
if ($app->dbmaster == $app->db) {
    $global_config = $app->getconf->get_global_config('mail');
    $current_month = date('Y-m');
    //* Check website traffic quota
@@ -739,19 +739,19 @@
            if($web_traffic_quota > 0 && $web_traffic > $web_traffic_quota) {
                $app->dbmaster->datalogUpdate('web_domain', "traffic_quota_lock = 'y',active = 'n'", 'domain_id', $rec['domain_id']);
                $app->log('Traffic quota for '.$rec['domain'].' exceeded. Disabling website.',LOGLEVEL_DEBUG);
                //* Send traffic notifications
                if($rec['traffic_quota_lock'] != 'y' && ($web_config['overtraffic_notify_admin'] == 'y' || $web_config['overtraffic_notify_client'] == 'y')) {
                    $placeholders = array('{domain}' => $rec['domain'],
                                          '{admin_mail}' => $global_config['admin_mail']);
                    $placeholders = array('{domain}' => $rec['domain'],
                                          '{admin_mail}' => $global_config['admin_mail']);
                    $recipients = array();
                    //* send email to admin
                    //* send email to admin
                    if($global_config['admin_mail'] != '' && $web_config['overtraffic_notify_admin'] == 'y') {
                        $recipients[] = $global_config['admin_mail'];
                    }
                    //* Send email to client
                    if($web_config['overtraffic_notify_client'] == 'y') {
                        $client_group_id = $rec["sys_groupid"];
@@ -760,11 +760,10 @@
                            $recipients[] = $client['email'];
                        }
                    }
                    send_notification_email('web_traffic_notification', $placeholders, $recipients);
                    send_notification_email('web_traffic_notification', $placeholders, $recipients);
                }
            } else {
                //* unlock the website, if traffic is lower then quota
                if($rec['traffic_quota_lock'] == 'y') {
@@ -791,7 +790,7 @@
    $sql = "SELECT domain_id,sys_groupid,domain,system_user,last_quota_notification,DATEDIFF(CURDATE(), last_quota_notification) as `notified_before` FROM web_domain WHERE (type = 'vhost' OR type = 'vhostsubdomain')";
    $records = $app->db->queryAllRecords($sql);
    if(is_array($records) && !empty($records)) {
        $tmp_rec =  $app->db->queryAllRecords("SELECT data from monitor_data WHERE type = 'harddisk_quota' ORDER BY created DESC");
        $monitor_data = array();
        if(is_array($tmp_rec)) {
@@ -799,18 +798,18 @@
                $monitor_data = array_merge_recursive($monitor_data,unserialize($app->db->unquote($tmp_mon['data'])));
            }
        }
        foreach($records as $rec) {
            //$web_hd_quota = $rec['hd_quota'];
            $domain = $rec['domain'];
            $username = $rec['system_user'];
            $rec['used'] = $monitor_data['user'][$username]['used'];
            $rec['soft'] = $monitor_data['user'][$username]['soft'];
            $rec['hard'] = $monitor_data['user'][$username]['hard'];
            $rec['files'] = $monitor_data['user'][$username]['files'];
            if (!is_numeric($rec['used'])){
                if ($rec['used'][0] > $rec['used'][1]){
                    $rec['used'] = $rec['used'][0];
@@ -821,22 +820,22 @@
            if (!is_numeric($rec['soft'])) $rec['soft']=$rec['soft'][1];
            if (!is_numeric($rec['hard'])) $rec['hard']=$rec['hard'][1];
            if (!is_numeric($rec['files'])) $rec['files']=$rec['files'][1];
            // used space ratio
            if($rec['soft'] > 0){
                $used_ratio = $rec['used']/$rec['soft'];
            } else {
                $used_ratio = 0;
            }
            $rec['ratio'] = number_format($used_ratio * 100, 2, '.', '').'%';
            if($rec['used'] > 1024) {
                $rec['used'] = round($rec['used'] / 1024,2).' MB';
            } else {
                if ($rec['used'] != '') $rec['used'] .= ' KB';
            }
            if($rec['soft'] > 1024) {
                $rec['soft'] = round($rec['soft'] / 1024,2).' MB';
            } elseif($rec['soft'] == 0){
@@ -844,7 +843,7 @@
            } else {
                $rec['soft'] .= ' KB';
            }
            if($rec['hard'] > 1024) {
                $rec['hard'] = round($rec['hard'] / 1024,2).' MB';
            } elseif($rec['hard'] == 0){
@@ -852,12 +851,12 @@
            } else {
                $rec['hard'] .= ' KB';
            }
            // send notifications only if 90% or more of the quota are used
            if($used_ratio < 0.9) {
                // reset notification date
                if($rec['last_quota_notification']) $app->dbmaster->datalogUpdate('web_domain', "last_quota_notification = NULL", 'domain_id', $rec['domain_id']);
                // send notification - everything ok again
                if($rec['last_quota_notification'] && $web_config['overquota_notify_onok'] == 'y' && ($web_config['overquota_notify_admin'] == 'y' || $web_config['overquota_notify_client'] == 'y')) {
                    $placeholders = array('{domain}' => $rec['domain'],
@@ -868,12 +867,12 @@
                                          '{ratio}' => $rec['ratio']);
                    $recipients = array();
                    //* send email to admin
                    if($global_config['admin_mail'] != '' && $web_config['overquota_notify_admin'] == 'y') {
                        $recipients[] = $global_config['admin_mail'];
                    }
                    //* Send email to client
                    if($web_config['overquota_notify_client'] == 'y') {
                        $client_group_id = $rec["sys_groupid"];
@@ -884,19 +883,19 @@
                    }
                    send_notification_email('web_quota_ok_notification', $placeholders, $recipients);
                }
                continue;
            }
            // could a notification be sent?
            $send_notification = false;
            if(!$rec['last_quota_notification']) $send_notification = true; // not yet notified
            elseif($web_config['overquota_notify_freq'] > 0 && $rec['notified_before'] >= $web_config['overquota_notify_freq']) $send_notification = true;
            //* Send quota notifications
            if(($web_config['overquota_notify_admin'] == 'y' || $web_config['overquota_notify_client'] == 'y') && $send_notification == true) {
                $app->dbmaster->datalogUpdate('web_domain', "last_quota_notification = CURDATE()", 'domain_id', $rec['domain_id']);
                $placeholders = array('{domain}' => $rec['domain'],
                                      '{admin_mail}' => $global_config['admin_mail'],
                                      '{used}' => $rec['used'],
@@ -905,12 +904,12 @@
                                      '{ratio}' => $rec['ratio']);
                $recipients = array();
                //* send email to admin
                if($global_config['admin_mail'] != '' && $web_config['overquota_notify_admin'] == 'y') {
                    $recipients[] = $global_config['admin_mail'];
                }
                //* Send email to client
                if($web_config['overquota_notify_client'] == 'y') {
                    $client_group_id = $rec["sys_groupid"];
@@ -939,7 +938,7 @@
    $sql = "SELECT mailuser_id,sys_groupid,email,name,quota,last_quota_notification,DATEDIFF(CURDATE(), last_quota_notification) as `notified_before` FROM mail_user";
    $records = $app->db->queryAllRecords($sql);
    if(is_array($records) && !empty($records)) {
        $tmp_rec =  $app->db->queryAllRecords("SELECT data from monitor_data WHERE type = 'email_quota' ORDER BY created DESC");
        $monitor_data = array();
        if(is_array($tmp_rec)) {
@@ -953,24 +952,24 @@
                }
            }
        }
        foreach($records as $rec) {
            $email = $rec['email'];
            $rec['used'] = isset($monitor_data[$email]['used']) ? $monitor_data[$email]['used'] : array(1 => 0);
            if (!is_numeric($rec['used'])) $rec['used']=$rec['used'][1];
            // used space ratio
            if($rec['quota'] > 0){
                $used_ratio = $rec['used']/$rec['quota'];
            } else {
                $used_ratio = 0;
            }
            $rec['ratio'] = number_format($used_ratio * 100, 2, '.', '').'%';
            if($rec['quota'] > 0){
                $rec['quota'] = round($rec['quota'] / 1048576,4).' MB';
            } else {
@@ -981,8 +980,8 @@
                $rec['used'] = round($rec['used'] / 1024,4).' KB';
            } else {
                $rec['used'] = round($rec['used'] / 1048576,4).' MB';
            }
            }
            // send notifications only if 90% or more of the quota are used
            if($used_ratio < 0.9) {
                // reset notification date
@@ -996,13 +995,13 @@
                              '{name}' => $rec['name'],
                              '{quota}' => $rec['quota'],
                              '{ratio}' => $rec['ratio']);
                    $recipients = array();
                    //* send email to admin
                    if($global_config['admin_mail'] != '' && $mail_config['overquota_notify_admin'] == 'y') {
                        $recipients[] = $global_config['admin_mail'];
                    }
                    //* Send email to client
                    if($mail_config['overquota_notify_client'] == 'y') {
                        $client_group_id = $rec["sys_groupid"];
@@ -1011,35 +1010,35 @@
                            $recipients[] = $client['email'];
                        }
                    }
                    send_notification_email('mail_quota_ok_notification', $placeholders, $recipients);
                }
                continue;
            }
            //* Send quota notifications
            // could a notification be sent?
            $send_notification = false;
            if(!$rec['last_quota_notification']) $send_notification = true; // not yet notified
            elseif($mail_config['overquota_notify_freq'] > 0 && $rec['notified_before'] >= $mail_config['overquota_notify_freq']) $send_notification = true;
            if(($mail_config['overquota_notify_admin'] == 'y' || $mail_config['overquota_notify_client'] == 'y') && $send_notification == true) {
                $app->dbmaster->datalogUpdate('mail_user', "last_quota_notification = CURDATE()", 'mailuser_id', $rec['mailuser_id']);
                $placeholders = array('{email}' => $rec['email'],
                          '{admin_mail}' => $global_config['admin_mail'],
                          '{used}' => $rec['used'],
                          '{name}' => $rec['name'],
                          '{quota}' => $rec['quota'],
                          '{ratio}' => $rec['ratio']);
                $recipients = array();
                //* send email to admin
                if($global_config['admin_mail'] != '' && $mail_config['overquota_notify_admin'] == 'y') {
                    $recipients[] = $global_config['admin_mail'];
                }
                //* Send email to client
                if($mail_config['overquota_notify_client'] == 'y') {
                    $client_group_id = $rec["sys_groupid"];
@@ -1048,9 +1047,9 @@
                        $recipients[] = $client['email'];
                    }
                }
                send_notification_email('mail_quota_notification', $placeholders, $recipients);
            }
            }
        }
    }
}
@@ -1081,7 +1080,7 @@
#######################################################################################################
function formatBytes($size, $precision = 2) {
    $base=log($size)/log(1024);
    $suffixes=array('','k','M','G','T');
    $suffixes=array('','k','M','G','T');
        return round(pow(1024,$base-floor($base)),$precision).$suffixes[floor($base)];
}
@@ -1153,7 +1152,7 @@
                } else {
                    if(is_file($web_backup_dir.'/'.$web_backup_file)) unlink($web_backup_dir.'/'.$web_backup_file);
                }
                //* Remove old backups
                $backup_copies = intval($rec['backup_copies']);
@@ -1187,7 +1186,7 @@
                //* Remove backupdir symlink and create as directory instead
                $app->uses('system');
                $app->system->web_folder_protection($web_path,false);
                if(is_link($web_path.'/backup')) {
                    unlink($web_path.'/backup');
                }
@@ -1196,7 +1195,7 @@
                    chown($web_path.'/backup', $rec['system_user']);
                    chgrp($web_path.'/backup', $rec['system_group']);
                }
                $app->system->web_folder_protection($web_path,true);
            }
@@ -1232,33 +1231,72 @@
                chown($db_backup_dir, 'root');
                chgrp($db_backup_dir, 'root');
                //* Do the mysql database backup with mysqldump
                //* Do the mysql database backup with mysqldump or mongodump
                $db_id = $rec['database_id'];
                $db_name = $rec['database_name'];
                $db_backup_file = 'db_'.$db_name.'_'.date('Y-m-d_H-i').'.sql';
                $command = "mysqldump -h '".escapeshellcmd($clientdb_host)."' -u '".escapeshellcmd($clientdb_user)."' -p'".escapeshellcmd($clientdb_password)."' -c --add-drop-table --create-options --quick --result-file='".$db_backup_dir.'/'.$db_backup_file."' '".$db_name."'";
                exec($command, $tmp_output, $retval);
                //* Compress the backup with gzip
                if($retval == 0) exec("gzip -c '".escapeshellcmd($db_backup_dir.'/'.$db_backup_file)."' > '".escapeshellcmd($db_backup_dir.'/'.$db_backup_file).".gz'", $tmp_output, $retval);
                if($retval == 0){
                    chmod($db_backup_dir.'/'.$db_backup_file.'.gz', 0750);
                    chown($db_backup_dir.'/'.$db_backup_file.'.gz', fileowner($db_backup_dir));
                    chgrp($db_backup_dir.'/'.$db_backup_file.'.gz', filegroup($db_backup_dir));
                if ($rec['type'] == 'mysql') {
                    $db_backup_file = 'db_'.$db_name.'_'.date('Y-m-d_H-i').'.sql';
                    $command = "mysqldump -h '".escapeshellcmd($clientdb_host)."' -u '".escapeshellcmd($clientdb_user)."' -p'".escapeshellcmd($clientdb_password)."' -c --add-drop-table --create-options --quick --result-file='".$db_backup_dir.'/'.$db_backup_file."' '".$db_name."'";
                    exec($command, $tmp_output, $retval);
                    //* Insert web backup record in database
                    //$insert_data = "(server_id,parent_domain_id,backup_type,backup_mode,tstamp,filename) VALUES (".$conf['server_id'].",$web_id,'mysql','sqlgz',".time().",'".$app->db->quote($db_backup_file).".gz')";
                    //$app->dbmaster->datalogInsert('web_backup', $insert_data, 'backup_id');
                    $sql = "INSERT INTO web_backup (server_id,parent_domain_id,backup_type,backup_mode,tstamp,filename) VALUES (".$conf['server_id'].",$web_id,'mysql','sqlgz',".time().",'".$app->db->quote($db_backup_file).".gz')";
                    $app->db->query($sql);
                    if($app->db->dbHost != $app->dbmaster->dbHost) $app->dbmaster->query($sql);
                    //* Compress the backup with gzip
                    if($retval == 0) exec("gzip -c '".escapeshellcmd($db_backup_dir.'/'.$db_backup_file)."' > '".escapeshellcmd($db_backup_dir.'/'.$db_backup_file).".gz'", $tmp_output, $retval);
                } else {
                    if(is_file($db_backup_dir.'/'.$db_backup_file.'.gz')) unlink($db_backup_dir.'/'.$db_backup_file.'.gz');
                    if($retval == 0){
                        chmod($db_backup_dir.'/'.$db_backup_file.'.gz', 0750);
                        chown($db_backup_dir.'/'.$db_backup_file.'.gz', fileowner($db_backup_dir));
                        chgrp($db_backup_dir.'/'.$db_backup_file.'.gz', filegroup($db_backup_dir));
                        //* Insert web backup record in database
                        //$insert_data = "(server_id,parent_domain_id,backup_type,backup_mode,tstamp,filename) VALUES (".$conf['server_id'].",$web_id,'mysql','sqlgz',".time().",'".$app->db->quote($db_backup_file).".gz')";
                        //$app->dbmaster->datalogInsert('web_backup', $insert_data, 'backup_id');
                        $sql = "INSERT INTO web_backup (server_id,parent_domain_id,backup_type,backup_mode,tstamp,filename) VALUES (".$conf['server_id'].",$web_id,'mysql','sqlgz',".time().",'".$app->db->quote($db_backup_file).".gz')";
                        $app->db->query($sql);
                        if($app->db->dbHost != $app->dbmaster->dbHost) $app->dbmaster->query($sql);
                    } else {
                        if(is_file($db_backup_dir.'/'.$db_backup_file.'.gz')) unlink($db_backup_dir.'/'.$db_backup_file.'.gz');
                    }
                    //* Remove the uncompressed file
                    if(is_file($db_backup_dir.'/'.$db_backup_file)) unlink($db_backup_dir.'/'.$db_backup_file);
                } else if ($rec['type'] == 'mongo') {
                    $db_backup_file = 'db_'.$db_name.'_'.date('Y-m-d_H-i');
                    try {
                        $connection = new MongoClient("mongodb://root:123456@127.0.0.1:27017/admin");
                        $db = $connection->selectDB($db_name);
                        // exclude not supported by mongodump, only get user collections
                        $collections = $db->getCollectionNames(false);
                        foreach ($collections as $collection) {
                            // mongodump -h 127.0.0.1 --port 27017 -u root -p 123456 --authenticationDatabase admin -d <db> -c <table> -o /tmp/test
                            $command = "mongodump -h 127.0.0.1 --port 27017 -u root -p 123456 --authenticationDatabase admin -d ".escapeshellcmd($db_name)." -c ".escapeshellcmd($collection)." -o ".escapeshellcmd($db_backup_dir.'/'.$db_backup_file);
                            exec($command);
                        }
                        if (is_dir(escapeshellcmd($db_backup_dir.'/'.$db_backup_file))) {
                            //* Compress the backup with gzip
                            exec("cd ".escapeshellcmd($db_backup_dir)." && tar -pczf ".escapeshellcmd($db_backup_dir.'/'.$db_backup_file).".tar.gz ".escapeshellcmd($db_backup_file));
                            chmod($db_backup_dir.'/'.$db_backup_file.'.tar.gz', 0750);
                            chown($db_backup_dir.'/'.$db_backup_file.'.tar.gz', fileowner($db_backup_dir));
                            chgrp($db_backup_dir.'/'.$db_backup_file.'.tar.gz', filegroup($db_backup_dir));
                            //* Insert web backup record in database
                            $sql = "INSERT INTO web_backup (server_id,parent_domain_id,backup_type,backup_mode,tstamp,filename) VALUES (".$conf['server_id'].",$web_id,'mongodb','rootgz',".time().",'".$app->db->quote($db_backup_file).".tar.gz')";
                            $app->db->query($sql);
                            if ($app->db->dbHost != $app->dbmaster->dbHost) {
                                $app->dbmaster->query($sql);
                            }
                            //* Remove the uncompressed file
                            exec("rm -rf ".escapeshellcmd($db_backup_dir.'/'.$db_backup_file));
                        }
                    } catch (MongoConnnectionException $e) {
                        // connecting to MongoDB failed - cannot create backup
                    }
                }
                //* Remove the uncompressed file
                if(is_file($db_backup_dir.'/'.$db_backup_file)) unlink($db_backup_dir.'/'.$db_backup_file);
                //* Remove old backups
                $backup_copies = intval($rec['backup_copies']);
@@ -1266,13 +1304,13 @@
                $dir_handle = dir($db_backup_dir);
                $files = array();
                while (false !== ($entry = $dir_handle->read())) {
                    if($entry != '.' && $entry != '..' && preg_match('/^db_(.*?)_\d{4}-\d{2}-\d{2}_\d{2}-\d{2}\.sql.gz$/', $entry, $matches) && is_file($db_backup_dir.'/'.$entry)) {
                    if($entry != '.' && $entry != '..' && (preg_match('/^db_(.*?)_\d{4}-\d{2}-\d{2}_\d{2}-\d{2}\.sql.gz$/', $entry, $matches) || preg_match('/^db_(.*?)_\d{4}-\d{2}-\d{2}_\d{2}-\d{2}\.tar.gz$/', $entry, $matches)) && is_file($db_backup_dir.'/'.$entry)) {
                        if(array_key_exists($matches[1], $files) == false) $files[$matches[1]] = array();
                        $files[$matches[1]][] = $entry;
                    }
                }
                $dir_handle->close();
                reset($files);
                foreach($files as $db_name => $filelist) {
                    rsort($filelist);
server/lib/classes/monitor_tools.inc.php
@@ -755,6 +755,13 @@
                $data['mysqlserver'] = 0;
                $state = 'error'; // because service is down
            }
            if ($this->_checkTcp('localhost', 27017)) {
                $data['mongodbserver'] = 1;
            } else {
                $data['mongodbserver'] = 0;
                $state = 'error'; // because service is down
            }
        }
        /*
@@ -1299,6 +1306,51 @@
        return $res;
    }
    public function monitorMongoDB() {
        global $conf;
        /* the id of the server as int */
        $server_id = intval($conf['server_id']);
        /** The type of the data */
        $type = 'log_mongodb';
        /* This monitoring is only available if MongoDB is installed */
        system('which mongod', $retval); // Debian, Ubuntu, Fedora
        if ($retval !== 0)
            system('which mongod', $retval); // CentOS
        if ($retval === 0) {
            /*  Get the data of the log */
            $data = $this->_getLogData($type);
            /*
             * At this moment, there is no state (maybe later)
             */
            $state = 'no_state';
        } else {
            /*
             * MongoDB is not installed, so there is no data and no state
             *
             * no_state, NOT unknown, because "unknown" is shown as state
             * inside the GUI. no_state is hidden.
             *
             * We have to write NO DATA inside the DB, because the GUI
             * could not know, if there is any dat, or not...
             */
            $state = 'no_state';
            $data = '';
        }
        /*
         * Return the Result
         */
        $res['server_id'] = $server_id;
        $res['type'] = $type;
        $res['data'] = $data;
        $res['state'] = $state;
        return $res;
    }
    public function monitorIPTables() {
                global $conf;
@@ -1745,6 +1797,9 @@
                    $logfile = '/var/log/fail2ban.log';
                }
                break;
            case 'log_mongodb':
                    $logfile = '/var/log/mongodb/mongodb.log';
                break;
            case 'log_ispconfig':
                if ($dist == 'debian') {
                    $logfile = $conf['ispconfig_log_dir'] . '/ispconfig.log';
@@ -1926,4 +1981,4 @@
}
?>
?>
server/mods-available/monitor_core_module.inc.php
@@ -89,7 +89,7 @@
        $this->_tools = new monitor_tools();
        /*
         * Calls the single Monitoring steps
         * Calls the single Monitoring steps
         */
        $this->_monitorEmailQuota();
        $this->_monitorHDQuota();
@@ -117,6 +117,7 @@
        $this->_monitorRaid();
        $this->_monitorRkHunter();
        $this->_monitorFail2ban();
        $this->_monitorMongoDB();
        $this->_monitorIPTables();
        $this->_monitorSysLog();
    }
@@ -129,12 +130,12 @@
         */
        $min = @date('i', $this->_run_time);
        if ($min % 15 != 0) return;
        $app->uses('getconf');
        $mail_config = $app->getconf->get_server_config($conf['server_id'], 'mail');
        if($mail_config['mailbox_quota_stats'] == 'n') return;
        /*
         * First we get the Monitoring-data from the tools
         */
@@ -422,7 +423,7 @@
         * First we get the Monitoring-data from the tools
         */
        $res = $this->_tools->monitorSystemUpdate();
        //* Ensure that output is encoded so that it does not break the serialize
        //$res['data']['output'] = htmlentities($res['data']['output']);
        $res['data']['output'] = htmlentities($res['data']['output'],ENT_QUOTES,'UTF-8');
@@ -536,6 +537,31 @@
         * First we get the Monitoring-data from the tools
         */
        $res = $this->_tools->monitorFail2ban();
        /*
         * Insert the data into the database
         */
        $sql = 'REPLACE INTO monitor_data (server_id, type, created, data, state) ' .
                'VALUES (' .
                $res['server_id'] . ', ' .
                "'" . $app->dbmaster->quote($res['type']) . "', " .
                'UNIX_TIMESTAMP(), ' .
                "'" . $app->dbmaster->quote(serialize($res['data'])) . "', " .
                "'" . $res['state'] . "'" .
                ')';
        $app->dbmaster->query($sql);
        /* The new data is written, now we can delete the old one */
        $this->_delOldRecords($res['type'], $res['server_id']);
    }
    private function _monitorMongoDB() {
    global $app;
        /*
         * First we get the Monitoring-data from the tools
         */
        $res = $this->_tools->monitorMongoDB();
        /*
         * Insert the data into the database
@@ -712,7 +738,7 @@
         * First we get the Monitoring-data from the tools
         */
        $res = $this->_tools->monitorISPCCronLog();
        //* Ensure that output is encoded so that it does not break the serialize
        if(is_array($res) && isset($res['data'])) $res['data'] = htmlentities($res['data']);
@@ -820,10 +846,10 @@
        // $now = time();
        // $old = $now - (4 * 60); // 4 minutes
        $old = 'UNIX_TIMESTAMP() - 240';
        /*
         * ATTENTION if i do NOT pay attention of the server id, i delete all data (of the type)
         * of ALL servers. This means, if i have a multiserver-environment and a server has a
         * of ALL servers. This means, if i have a multiserver-environment and a server has a
         * time not synced with the others (for example, all server has 11:00 and ONE server has
         * 10:45) then the actual data of this server (with the time-stamp 10:45) get lost
         * even though it is the NEWEST data of this server. To avoid this i HAVE to include
@@ -841,4 +867,4 @@
}
?>
?>
server/mods-available/rescue_core_module.inc.php
@@ -35,7 +35,7 @@
    /* No actions at this time. maybe later... */
    var $actions_available = array();
    /**
     * The monitoring-Data of this module.
     * The monitoring-Data of this module.
     * [0] are the actual data, [1] are the data 1 minnute ago [2] are teh data 2 minuntes...
     */
    private $_monitoringData = array();
@@ -73,7 +73,7 @@
         * do nothing, if the rescue-system is not enabled
         */
        global $conf;
        if ((!isset($conf['serverconfig']['rescue']['try_rescue'])) ||
        if ((!isset($conf['serverconfig']['rescue']['try_rescue'])) ||
                ((isset($conf['serverconfig']['rescue']['try_rescue'])) && ($conf['serverconfig']['rescue']['try_rescue'] !='y'))){
            return;
        }
@@ -87,17 +87,22 @@
         * Next we get the rescue data needed for rescuing the system
         */
        $this->_rescueData = $this->_getRescueData();
        /*
         * rescue MongoDB if needed
         */
        $this->_rescueMongoDB();
        /*
         * rescue mysql if needed (maybe httpd depends on mysql, so try this first!)
         */
        $this->_rescueMySql();
        /*
         * rescue httpd if needed
         */
        $this->_rescueHttpd();
        /*
         * The last step is to save the rescue-data
         */
@@ -112,12 +117,12 @@
     */
    private function _getMonitoringData() {
        global $app;
        $dataFilename = dirname(__FILE__) . "/../temp/rescue_module_monitoringdata.ser.txt";
        /*
         * If the file containing the data is too old (older than 5 minutes) it is better to
         * delete it, because it could be, that the server was down for some times and so the data
         * delete it, because it could be, that the server was down for some times and so the data
         * are outdated
         */
        if (file_exists($dataFilename) && (filemtime($dataFilename) < (time() - 5 * 60))) {
@@ -132,7 +137,7 @@
        } else {
            $data = array();
        }
        /*
         * $temp[0] was the data of the last monitoring (means 1 minute ago), $temp[1] is the data
         * 2 minutes ago and so on. Now we have make place for the newest data...
@@ -144,32 +149,32 @@
        for ($i = $max; $i > 0; $i--){
            $data[$i] = $data[$i -1];
        }
        /*
         * we need the monitoring tools
         */
        $app->load('monitor_tools');
        $tools = new monitor_tools();
        /*
         * Call the needed Monitoring-step and get the data
         */
        $tmp[0] = $tools->monitorServices();
        /* Add the data at the FIRST position of the history */
        $data[0] = $tmp;
        /*
         * We have the newest monitoring data. Save it!
         * (and protect it, because there may be sensible data in it)
         */
        file_put_contents($dataFilename, serialize($data));
        chmod($dataFilename, 0600);
        /* Thats it */
        return $data;
    }
    /**
     * This gets the rescue-Data, needed for rescuing the system.
     * Because we can not be 100% sure, that the mysql-DB is up and running, so we use the
@@ -181,7 +186,7 @@
        /*
         * If the file containing the data is too old (older than 5 minutes) it is better to
         * delete it, because it could be, that the server was down for some times and so the data
         * delete it, because it could be, that the server was down for some times and so the data
         * are outdated
         */
        if (file_exists($dataFilename) && (filemtime($dataFilename) < (time() - 5 * 60))) {
@@ -196,7 +201,7 @@
        } else {
            $data = array();
        }
        /* Thats it */
        return $data;
    }
@@ -222,14 +227,14 @@
     */
    private function _rescueHttpd(){
        global $app, $conf;
        /*
         * do nothing, if it is not allowed to rescue httpd
         */
        if ((isset($conf['serverconfig']['rescue']['do_not_try_rescue_httpd']) && ($conf['serverconfig']['rescue']['do_not_try_rescue_httpd']) == 'y')){
            return;
        }
        /*
         * if the service is up and running, or the service is not installed there is nothing to do...
         */
@@ -238,42 +243,42 @@
            $this->_rescueData['webserver']['try_counter'] = 0;
            return;
        }
        /*
         * OK, the service is installed and down.
         * Maybe this is because of a restart of the service by the admin.
         * This means, we check the data 1 minute ago
         */
        if ((!isset($this->_monitoringData[1][0]['data']['webserver'])) ||
        if ((!isset($this->_monitoringData[1][0]['data']['webserver'])) ||
                ((isset($this->_monitoringData[1][0]['data']['webserver'])) && ($this->_monitoringData[1][0]['data']['webserver'] != 0))){
            /*
             * We do NOT have this data or we have this data, but the webserver was not down 1 minute ago.
             * This means, it could be, that the admin is restarting the server.
            /*
             * We do NOT have this data or we have this data, but the webserver was not down 1 minute ago.
             * This means, it could be, that the admin is restarting the server.
             * We wait one more minute...
             */
            return;
        }
        /*#####
         * The service is down and it was down 1 minute ago.
         * We try to rescue it
         *#####*/
        /* Get the try counter */
        $tryCount = (!isset($this->_rescueData['webserver']['try_counter']))? 1 : $this->_rescueData['webserver']['try_counter'] + 1;
        /* Set the new try counter */
        $this->_rescueData['webserver']['try_counter'] = $tryCount;
        /* if 5 times will not work, we have to give up... */
        if ($tryCount > 5){
            $app->log('httpd is down! Rescue will not help!', LOGLEVEL_ERROR);
            return;
        }
        $app->log('httpd is down! Try rescue httpd (try:' . $tryCount . ')...', LOGLEVEL_WARN);
        if($conf['serverconfig']['web']['server_type'] == 'nginx'){
            $daemon = 'nginx';
        } else {
@@ -285,23 +290,89 @@
                $daemon = 'apache2';
            }
        }
        $this->_rescueDaemon($daemon);
    }
    /**
     * restarts MongoDB, if needed
     */
    private function _rescueMongoDB(){
        global $app, $conf;
        /*
         * do nothing, if it is not allowed to rescue mysql
         */
        if ((isset($conf['serverconfig']['rescue']['do_not_try_rescue_mongodb']) && ($conf['serverconfig']['rescue']['do_not_try_rescue_mongodb']) == 'y')){
            return;
        }
        /*
         * if the service is up and running, or the service is not installed there is nothing to do...
         */
        if ($this->_monitoringData[0][0]['data']['mongodbserver'] != 0){
            /* Clear the try counter, because we do not have to try to rescue the service */
            $this->_rescueData['mongodbserver']['try_counter'] = 0;
            return;
        }
        /*
         * OK, the service is installed and down.
         * Maybe this is because of a restart of the service by the admin.
         * This means, we check the data 1 minute ago
         */
        if ((!isset($this->_monitoringData[1][0]['data']['mongodbserver'])) ||
                ((isset($this->_monitoringData[1][0]['data']['mongodbserver'])) && ($this->_monitoringData[1][0]['data']['mongodbserver'] != 0))){
            /*
             * We do NOT have this data or we have this data, but the webserver was not down 1 minute ago.
             * This means, it could be, that the admin is restarting the server.
             * We wait one more minute...
             */
            return;
        }
        /*#####
         * The service is down and it was down 1 minute ago.
         * We try to rescue it
         *#####*/
        /* Get the try counter */
        $tryCount = (!isset($this->_rescueData['mongodbserver']['try_counter']))? 1 : $this->_rescueData['mongodbserver']['try_counter'] + 1;
        /* Set the new try counter */
        $this->_rescueData['mongodbserver']['try_counter'] = $tryCount;
        /* if 5 times will not work, we have to give up... */
        if ($tryCount > 5){
            $app->log('MongoDB is down! Rescue will not help!', LOGLEVEL_ERROR);
            return;
        }
        $app->log('MongoDB is down! Try rescue MongoDB (try:' . $tryCount . ')...', LOGLEVEL_WARN);
        if(is_file($conf['init_scripts'] . '/' . 'mongodb')) {
            $daemon = 'mongodb';
        } else {
            $daemon = 'mongodb';
        }
        $this->_rescueDaemon($daemon);
    }
    /**
     * restarts mysql, if needed
     */
    private function _rescueMySql(){
        global $app, $conf;
        /*
         * do nothing, if it is not allowed to rescue mysql
         */
        if ((isset($conf['serverconfig']['rescue']['do_not_try_rescue_mysql']) && ($conf['serverconfig']['rescue']['do_not_try_rescue_mysql']) == 'y')){
            return;
        }
        /*
         * if the service is up and running, or the service is not installed there is nothing to do...
         */
@@ -310,40 +381,40 @@
            $this->_rescueData['mysqlserver']['try_counter'] = 0;
            return;
        }
        /*
         * OK, the service is installed and down.
         * Maybe this is because of a restart of the service by the admin.
         * This means, we check the data 1 minute ago
         */
        if ((!isset($this->_monitoringData[1][0]['data']['mysqlserver'])) ||
        if ((!isset($this->_monitoringData[1][0]['data']['mysqlserver'])) ||
                ((isset($this->_monitoringData[1][0]['data']['mysqlserver'])) && ($this->_monitoringData[1][0]['data']['mysqlserver'] != 0))){
            /*
             * We do NOT have this data or we have this data, but the webserver was not down 1 minute ago.
             * This means, it could be, that the admin is restarting the server.
            /*
             * We do NOT have this data or we have this data, but the webserver was not down 1 minute ago.
             * This means, it could be, that the admin is restarting the server.
             * We wait one more minute...
             */
            return;
        }
        /*#####
         * The service is down and it was down 1 minute ago.
         * We try to rescue it
         *#####*/
        /* Get the try counter */
        $tryCount = (!isset($this->_rescueData['mysqlserver']['try_counter']))? 1 : $this->_rescueData['mysqlserver']['try_counter'] + 1;
        /* Set the new try counter */
        $this->_rescueData['mysqlserver']['try_counter'] = $tryCount;
        /* if 5 times will not work, we have to give up... */
        if ($tryCount > 5){
            $app->log('MySQL is down! Rescue will not help!', LOGLEVEL_ERROR);
            return;
        }
        $app->log('MySQL is down! Try rescue mysql (try:' . $tryCount . ')...', LOGLEVEL_WARN);
        if(is_file($conf['init_scripts'] . '/' . 'mysqld')) {
@@ -351,23 +422,23 @@
        } else {
            $daemon = 'mysql';
        }
        $this->_rescueDaemon($daemon);
    }
    /**
     * Tries to stop and then restart the daemon
     *
     *
     * @param type $daemon the name of the daemon
     */
    private function _rescueDaemon($daemon){
        global $conf;
        // if you need to find all restarts search for "['init_scripts']"
        /*
         * First we stop the running service "normally"
         */
        /*
         * ATTENTION!
         * The service hangs. this means it could be, that "stop" will hang also.
@@ -375,13 +446,13 @@
         * of the service
         */
        exec($conf['init_scripts'] . '/' . $daemon . ' stop && (sleep 3; kill $!; sleep 2; kill -9 $!) &> /dev/null');
        /*
         * OK, we tryed to stop it normally, maybe this worked maybe not. So we have to look
         * if the service is already running or not. If so, we have to kill them hard
         */
        exec("kill -9 `ps -A | grep " . $daemon . "| grep -v grep | awk '{print $1}'` &> /dev/null");
        /*
         * There are no more zombies left. Lets start the service..
         */
server/plugins-available/backup_plugin.inc.php
@@ -29,48 +29,48 @@
*/
class backup_plugin {
    var $plugin_name = 'backup_plugin';
    var $class_name  = 'backup_plugin';
    //* This function is called during ispconfig installation to determine
    //  if a symlink shall be created for this plugin.
    public function onInstall() {
        global $conf;
        return true;
    }
    /*
         This function is called when the plugin is loaded
    */
    public function onLoad() {
        global $app;
        //* Register for actions
        $app->plugins->registerAction('backup_download',$this->plugin_name,'backup_action');
        $app->plugins->registerAction('backup_restore',$this->plugin_name,'backup_action');
    }
    //* Do a backup action
    public function backup_action($action_name,$data) {
        global $app,$conf;
        $backup_id = intval($data);
        $backup = $app->dbmaster->queryOneRecord("SELECT * FROM web_backup WHERE backup_id = $backup_id");
        if(is_array($backup)) {
            $app->uses('ini_parser,file,getconf');
            $web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".$backup['parent_domain_id']);
            $server_config = $app->getconf->get_server_config($conf['server_id'], 'server');
            $backup_dir = $server_config['backup_dir'].'/web'.$web['domain_id'];
            //* Make backup available for download
            if($action_name == 'backup_download') {
                //* Copy the backup file to the backup folder of the website
@@ -80,12 +80,38 @@
                    $app->log('cp '.$backup_dir.'/'.$backup['filename'].' '.$web['document_root'].'/backup/'.$backup['filename'],LOGLEVEL_DEBUG);
                }
            }
            //* Restore a MongoDB backup
            if($action_name == 'backup_restore' && $backup['backup_type'] == 'mongodb') {
                if(file_exists($backup_dir.'/'.$backup['filename'])) {
                    //$parts = explode('_',$backup['filename']);
                    //$db_name = $parts[1];
                    preg_match('@^db_(.+)_\d{4}-\d{2}-\d{2}_\d{2}-\d{2}\.tar\.gz$@', $backup['filename'], $matches);
                    $db_name = $matches[1];
                    // extract tar.gz archive
                    $dump_directory = str_replace(".tar.gz", "", $backup['filename']);
                    $extracted = "/usr/local/ispconfig/server/temp";
                    exec("tar -xzvf ".escapeshellarg($backup_dir.'/'.$backup['filename'])." --directory=".escapeshellarg($extracted));
                    $restore_directory = $extracted."/".$dump_directory."/".$db_name;
                    // mongorestore -h 127.0.0.1 -u root -p 123456 --authenticationDatabase admin -d c1debug --drop ./toRestore
                    $command = "mongorestore -h 127.0.0.1 --port 27017 -u root -p 123456 --authenticationDatabase admin -d ".$db_name." --drop ".escapeshellarg($restore_directory);
                    exec($command);
                    exec("rm -rf ".escapeshellarg($extracted."/".$dump_directory));
                }
                unset($clientdb_host);
                unset($clientdb_user);
                unset($clientdb_password);
                $app->log('Restored MongoDB backup '.$backup_dir.'/'.$backup['filename'],LOGLEVEL_DEBUG);
            }
            //* Restore a mysql backup
            if($action_name == 'backup_restore' && $backup['backup_type'] == 'mysql') {
                //* Load sql dump into db
                include('lib/mysql_clientdb.conf');
                if(file_exists($backup_dir.'/'.$backup['filename'])) {
                    //$parts = explode('_',$backup['filename']);
                    //$db_name = $parts[1];
@@ -99,7 +125,7 @@
                unset($clientdb_password);
                $app->log('Restored MySQL backup '.$backup_dir.'/'.$backup['filename'],LOGLEVEL_DEBUG);
            }
            //* Restore a web backup
            if($action_name == 'backup_restore' && $backup['backup_type'] == 'web') {
                if($backup['backup_mode'] == 'userzip') {
@@ -123,11 +149,11 @@
                    }
                }
            }
        } else {
            $app->log('No backup with ID '.$backup_id.' found.',LOGLEVEL_DEBUG);
        }
        return 'ok';
    }
server/plugins-available/mongo_clientdb_plugin.inc.php
New file
@@ -0,0 +1,820 @@
<?php
/*
Copyright (c) 2007, Till Brehm, projektfarm Gmbh
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright notice,
      this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
    * Neither the name of ISPConfig nor the names of its contributors
      may be used to endorse or promote products derived from this software without
      specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
 * The MongoDB client plugin is used by ISPConfig to control the management of MongoDB.
 * If handles everything from creating DBs/Users, update them or delete them.
 */
class mongo_clientdb_plugin {
    /**
     * ISPConfig internal identifiers.
     */
    var $plugin_name = 'mongo_clientdb_plugin';
    var $class_name  = 'mongo_clientdb_plugin';
    /**
     * This function is called during ISPConfig installation.
     * It determines if a symlink shall be created for this plugin.
     *
     * @return bool true if symlink should be created
     */
    function onInstall() {
        global $conf;
        return (bool) $conf['services']['db'];
    }
    /**
     * This function is called when the plugin is loaded.
     * Each plugin/module needs to register itself to ISPConfig events from which
     * it want to receive changes/get notified.
     *
     * Since this is a MongoDB plugin we are interested in DB changes and everything related
     * to it, like users.
     */
    function onLoad() {
        global $app;
        //* Databases
        $app->plugins->registerEvent('database_insert',$this->plugin_name,'db_insert');
        $app->plugins->registerEvent('database_update',$this->plugin_name,'db_update');
        $app->plugins->registerEvent('database_delete',$this->plugin_name,'db_delete');
        //* Database users
        $app->plugins->registerEvent('database_user_insert',$this->plugin_name,'db_user_insert');
        $app->plugins->registerEvent('database_user_update',$this->plugin_name,'db_user_update');
        $app->plugins->registerEvent('database_user_delete',$this->plugin_name,'db_user_delete');
    }
    /**
     * MongoDB
     * ------------------------------------------------------------------------
     * The following needs to be done before using this plugin:
     * - 1. install MongoDB server from 10gen sources (or another one with >= 2.4)
     * - 2. install php5-dev package (apt-get install php5-dev)
     * - 3. install mongo PECL extension (pecl install mongo)
     * - 4. enable mongo (echo "extension=mongo.so" > /etc/php5/mods-available/mongo.ini && php5enmod mongo)
     * - 5. create administrative user manager in Mongo (mongo -> use admin -> db.addUser({user: "root", pwd: "123456", roles: [ "userAdminAnyDatabase", "readWriteAnyDatabase", "dbAdminAnyDatabase", "clusterAdmin" ]}))
     * - 6. enable auth for Mongo (nano /etc/mongodb.conf -> auth = true)
     * - 7. restart MongoDB (service mongodb restart)
     *
     * Unlike MySQL, MongoDB manages users per database.
     * Therefor we cannot use one user for multiple databases. Instead, we have to add him each time via the admin user.
     */
    /**
     * Stores the MongoDB connection.
     * @var object
     */
    private $_connection = null;
    /**
     * Stores the MongoDB admin user.
     * @var string
     */
    const USER = "root";
    /**
     * Stores the MongoDB admin password.
     * @var string
     */
    const PW = "123456";
    /**
     * Stores the MongoDB host address.
     * @var string
     */
    const HOST = "127.0.0.1";
    /**
     * Stores the MongoDB port.
     * @var int
     */
    const PORT = 27017;
    /**
     * Adds the user to given database.
     * If no connection exists, the user already exists or the database doesn't exist,
     * null is returned.
     *
     * @param string $db the database to use
     * @param array $user the user to add
     * @return bool true if user added
     */
    private function addUser($db, $user) {
        if ($this->isConnected() && !$this->userExists($db, $user)) {
            $roles = "";
            foreach ($user['roles'] as $index => $role) {
                $roles .= "\"".$role."\"";
                if ($index !== count($user['roles']) - 1) {
                    $roles .= ", ";
                }
            }
            return $this->exec($db, "db.system.users.insert({ user: \"".$user['username']."\", pwd: \"".$user['password']."\", roles: [ ".$roles." ] })");
            //return $this->exec($db, "db.addUser({ user: \"".$user['username']."\", pwd: \"".$user['password']."\", roles: [ ".$roles." ] })");
        }
        return null;
    }
    /**
     * Changes the users password in given DB.
     * If no connection exists, the user doesn't exist or the DB doesn't exist,
     * null is returned.
     *
     * @param string $db the database name
     * @param string $user the user to change
     * @param string $password the new password
     * @return bool true if password changes
     */
    private function changePassword($db, $user, $password) {
        if ($this->isConnected() && $this->dbExists($db) && $this->userExists($db, $user)) {
            $old_user = $this->getUser($db, $user);
            if ($this->dropUser($user, $db)) {
                return $this->addUser($db, array(
                    'username' => $user,
                    'password' => $password,
                    'roles' => $old_user['roles']
                ));
            }
            return false;
        }
        return null;
    }
    /**
     * Connects to the server and authentificates.
     * If the authentificaten goes wrong or another error encounters,
     * false is returned.
     * If we already have an open connection we try to disconnect and connect again.
     * If this fails, false is returned.
     *
     * @return object $connection the MongoDB connection
     */
    private function connect() {
        try {
            if ($this->isConnected() && !$this->disconnect()) {
                return false;
            }
            $this->_connection = new MongoClient("mongodb://".self::USER.":".self::PW."@".self::HOST.":".self::PORT."/admin");
            return $this->_connection;
        } catch (MongoConnnectionException $e) {
            $app->log('Unable to connect to MongoDB: '.$e, LOGLEVEL_ERROR);
            $this->_connection = null;
            return false;
        }
    }
    /**
     * Checks if the database exists.
     * If no connection exists,
     * null is returned.
     *
     * @param string $db the database name
     * @return bool true if exists
     */
    private function dbExists($db) {
        if ($this->isConnected()) {
            return in_array($db, $this->getDBs());
        }
        return null;
    }
    /**
     * Closes the MongoDB connection.
     * If no connection exists and nothing is done,
     * null is returned.
     *
     * @return bool true if closed
     */
    private function disconnect() {
        if ($this->isConnected()) {
            $status = $this->_connection->close();
            if ($status) {
                $this->_connection = null;
            }
            return $status;
        }
        return null;
    }
    /**
     * Drops the given database.
     * If no connection exists or the database doesn't exist,
     * null is returned.
     *
     * @param string $db the database's to drop name
     */
    private function dropDB($db) {
        if ($this->isConnected() && $this->dbExists($db)) {
            return (bool) $this->_connection->dropDB($db)['ok'];
        }
        return null;
    }
    /**
     * Drops the given user from database.
     * If no DB is defined, the user is dropped from all databases.
     * If there's an error when dropping the user from all DBs, an array containing the
     * names of the failed DBs is returned.
     * If no connection exists, the database doesn't exist or the user is not in DB,
     * null is returned.
     *
     * @param string $user the user to drop
     * @param string $db the database name
     * @return bool true if dropped
     */
    private function dropUser($user, $db = null) {
        if ($this->isConnected()) {
            if ($db !== null && $this->dbExists($db) && $this->userExists($db, $user)) {
                return $this->exec($db, "db.removeUser(\"".$user."\")");
            } else {
                $dbs = $this->getDBs();
                if ((bool) $dbs) {
                    $failures = array();
                    foreach ($dbs as $db) {
                        $exists = $this->userExists($db, $user);
                        if ($exists) {
                            if (!$this->dropUser($user, $db)) {
                                $failures[] = $db;
                            }
                        }
                    }
                }
                return (bool) $failures ? $failures : true;
            }
        }
        return null;
    }
    /**
     * Executed the command on the MongoDB server.
     * If no connection exists and thus nothing can be done,
     * null is returned.
     *
     * @param string $db the database to query
     * @param string $query the command to execute
     * @return array the result of the query
     */
    private function exec($db, $query) {
        if ($this->isConnected()) {
            $db = $this->selectDB($db);
            $result = $db->execute($query);
            if ((bool) $result['ok']) {
                return $result;
            }
            return false;
        }
        return null;
    }
    /**
     * Checks if the connection exists.
     *
     * @return true if connected
     */
    private function isConnected() {
        return $this->_connection !== null;
    }
    /**
     * Generates a MongoDB compatible password.
     *
     * @param string $user the username
     * @param string $password the user password
     * @return string the MD5 string
     */
    private function generatePassword($user, $password) {
        return md5($user.":mongo:".$password);
    }
    /**
     * Returns the databases found on connection.
     * If no connection exists and therefor no DBs can be found,
     * null is returned.
     *
     * @return array $names the databases's name
     */
    private function getDBs() {
        if ($this->isConnected()) {
            $dbs = $this->_connection->listDBs();
            if ((bool) $dbs && isset($dbs['databases'])) {
                $names = array();
                foreach ($dbs['databases'] as $db) {
                    $names[] = $db['name'];
                }
                return $names;
            }
        }
        return null;
    }
    /**
     * Returns the user entry for given database.
     * If no connection exists, the database doesn't exist or the user doesn't exist
     * null is returned.
     *
     * @param string $db the database name
     * @param string $user the user to return
     * @return array $user the user in DB
     */
    private function getUser($db, $user) {
        if ($this->isConnected() && $this->dbExists($db) && $this->userExists($db, $user)) {
            $result = $this->selectDB($db)->selectCollection("system.users")->find(array( 'user' => $user ));
            // ugly fix to return user
            foreach ($result as $user) {
                return $user;
            }
        }
        return null;
    }
    /**
     * Returns the users for given database.
     * If no connection exists or the database doesn't exist,
     * null is returned.
     *
     * @param string $db the database name
     * @return array $users the users in DB
     */
    private function getUsers($db) {
        if ($this->isConnected() && $this->dbExists($db)) {
            $result = $this->selectDB($db)->selectCollection("system.users")->find();
            $users = array();
            foreach ($result as $record) {
                $users[] = $record['user'];
            }
            return $users;
        }
        return null;
    }
    /**
     * Checks if the given user exists in given database.
     * If no connection exists or the given database doesn't exist
     * null is returned.
     *
     * @param string $db the database name
     * @param string $user the user to check
     * @return bool true if user exists
     */
    private function userExists($db, $user) {
        if ($this->isConnected() && $this->dbExists($db)) {
            $users = $this->getUsers($db);
            return in_array($user, $users);
        }
        return null;
    }
    /**
     * Renames the MongoDB database to provided name.
     * If no connection exists, the source DB doesn't exist or the target DB already exists,
     * null is returned.
     *
     * @param string $old_name the old database name
     * @param string $new_name the new database name
     * @return bool true if renamed
     */
    private function renameDB($old_name, $new_name) {
        if ($this->isConnected() && $this->dbExists($old_name) && !$this->dbExists($new_name)) {
            if ($this->exec($old_name, "db.copyDatabase(\"".$old_name."\", \"".$new_name."\", \"".self::HOST."\", \"".self::USER."\", \"".self::PW."\")")) {
                $this->dropDB($old_name);
                return true;
            }
            return false;
        }
        return null;
    }
    /**
     * Switched the selected database.
     * MongoDB acts on a per-DB level (user management) and we always need to
     * ensure we have the right DB selected.
     * If no connection exists and thus nothing is done,
     * null is returned.
     *
     * @param string $db the database to use
     * @return object the MongoDB database object
     */
    private function selectDB($db) {
        if ($this->isConnected()) {
            return $this->_connection->selectDB($db);
        }
        return null;
    }
    /**
     * This function is called when a DB is created from within the ISPConfig3 interface.
     * We need to create the DB and allow all users to connect to it that are choosen.
     * Since MongoDB doesn't create a DB before any data is stored in it, it's important
     * to store the users so it contains data -> is created.
     *
     * @param string $event_name the name of the event (insert, update, delete)
     * @param array $data the event data (old and new)
     * @return only if something is wrong
     */
    function db_insert($event_name, $data) {
        global $app, $conf;
        // beside checking for MongoDB we also check if the DB is active because only then we add users
        // -> MongoDB needs users to create the DB
        if ($data['new']['type'] == 'mongo' && $data['new']['active'] == 'y') {
            if ($this->connect() === false) {
                $app->log("Unable to connect to MongoDB: Connecting using connect() failed.", LOGLEVEL_ERROR);
                return;
            }
            $db_user = $app->db->queryOneRecord("SELECT `database_user`, `database_password_mongo` FROM `web_database_user` WHERE `database_user_id` = '" . intval($data['new']['database_user_id']) . "'");
            $db_ro_user = $app->db->queryOneRecord("SELECT `database_user`, `database_password_mongo` FROM `web_database_user` WHERE `database_user_id` = '" . intval($data['new']['database_ro_user_id']) . "'");
            $user = $db_user['database_user'];
            $password = $db_user['database_password_mongo'];
            $ro_user = $db_ro_user['database_user'];
            $ro_password = $db_ro_user['database_password_mongo'];
            $db = $data['new']['database_name'];
            if ((bool) $db_user) {
                if ($user == 'root') {
                $app->log("User root not allowed for client databases", LOGLEVEL_WARNING);
                } else {
                if (!$this->addUser($db, array(
                    'username' => $user,
                    'password' => $password,
                    'roles' => array(
                        "readWrite",
                        "dbAdmin"
                    )
                ))) {
                    $app->log("Error while adding user: ".$user." to DB: ".$db, LOGLEVEL_WARNING);
                }
                }
            }
            if ($db_ro_user && $data['new']['database_user_id'] != $data['new']['database_ro_user_id']) {
                if ($user == 'root') {
                $app->log("User root not allowed for client databases", LOGLEVEL_WARNING);
                } else {
                if (!$this->addUser($db, array(
                    'username' => $ro_user,
                    'password' => $ro_password,
                    'roles' => array(
                        "read"
                    )
                ))) {
                    $app->log("Error while adding read-only user: ".$user." to DB: ".$db, LOGLEVEL_WARNING);
                }
                }
            }
            $this->disconnect();
        }
    }
    /**
     * This function is called when a DB is updated from within the ISPConfig interface.
     * Updating the DB needs a lot of changes. First, we need to recheck all users that
     * have permissions to access the DB. Maybe we also need to rename the DB and change
     * it's type (MySQL, MongoDB etc.)...hard work here :)
     *
     * @param string $event_name the name of the event (insert, update, delete)
     * @param array $data the event data (old and new)
     * @return only if something is wrong
     */
    function db_update($event_name,$data) {
        global $app, $conf;
        if ($data['old']['active'] == 'n' && $data['new']['active'] == 'n') {
            return;
        }
        // currently switching from MongoDB <-> MySQL isn't supported
        if ($data['old']['type'] == 'mongo' && $data['new']['type'] == 'mongo') {
            if ($this->connect() === false) {
                $app->log("Unable to connect to MongoDB: Connecting using connect() failed.", LOGLEVEL_ERROR);
                return;
            }
            $db_user = $app->db->queryOneRecord("SELECT `database_user`, `database_password_mongo` FROM `web_database_user` WHERE `database_user_id` = '" . intval($data['new']['database_user_id']) . "'");
            $db_ro_user = $app->db->queryOneRecord("SELECT `database_user`, `database_password_mongo` FROM `web_database_user` WHERE `database_user_id` = '" . intval($data['new']['database_ro_user_id']) . "'");
            $user = $db_user['database_user'];
            $password = $db_user['database_password_mongo'];
            $ro_user = $db_ro_user['database_user'];
            $ro_password = $db_ro_user['database_password_mongo'];
            $db = $data['new']['database_name'];
            // create the database user if database was disabled before
            if ($data['new']['active'] == 'y' && $data['old']['active'] == 'n') {
                // since MongoDB creates DBs on-the-fly we can use the db_insert method which takes care of adding
                // users to a given DB
                $this->db_insert($event_name, $data);
            } else if ($data['new']['active'] == 'n' && $data['old']['active'] == 'y') {
                $users = $this->getUsers($db);
                if ((bool) $users) {
                    foreach ($users as $user) {
                        $this->dropUser($user, $db);
                    }
                }
            } else {
                // selected user has changed -> drop old one
                if ($data['new']['database_user_id'] != $data['old']['database_user_id']) {
                    $old_db_user = $app->db->queryOneRecord("SELECT `database_user`, `database_password_mongo` FROM `web_database_user` WHERE `database_user_id` = '" . intval($data['old']['database_user_id']) . "'");
                    if ((bool) $old_db_user) {
                        if ($old_db_user['database_user'] == 'root') {
                            $app->log("User root not allowed for client databases", LOGLEVEL_WARNING);
                        } else {
                            $this->dropUser($old_db_user['database_user'], $db);
                        }
                    }
                }
                // selected read-only user has changed -> drop old one
                if ($data['new']['database_ro_user_id'] != $data['old']['database_ro_user_id']) {
                    $old_db_user = $app->db->queryOneRecord("SELECT `database_user`, `database_password_mongo` FROM `web_database_user` WHERE `database_user_id` = '" . intval($data['old']['database_ro_user_id']) . "'");
                    if ((bool) $old_db_user) {
                        if ($old_db_user['database_user'] == 'root') {
                            $app->log("User root not allowed for client databases",LOGLEVEL_WARNING);
                        } else {
                            $this->dropUser($old_db_user['database_user'], $db);
                        }
                    }
                }
                // selected user has changed -> add new one
                if ($data['new']['database_user_id'] != $data['old']['database_user_id']) {
                    if ((bool) $db_user) {
                        if ($user == 'root') {
                            $app->log("User root not allowed for client databases", LOGLEVEL_WARNING);
                        } else {
                            $this->addUser($db, array(
                                'username' => $user,
                                'password' => $password,
                                'roles' => array(
                                    "readWrite",
                                    "dbAdmin"
                                )
                            ));
                        }
                    }
                }
                // selected read-only user has changed -> add new one
                if ($data['new']['database_ro_user_id'] != $data['old']['database_ro_user_iduser_id']) {
                    if ((bool) $db_ro_user && $data['new']['database_user_id'] != $data['new']['database_ro_user_id']) {
                        if ($ro_user == 'root') {
                            $app->log("User root not allowed for client databases", LOGLEVEL_WARNING);
                        } else {
                            $this->addUser($db, array(
                                'username' => $ro_user,
                                'password' => $ro_password,
                                'roles' => array(
                                    "read"
                                )
                            ));
                        }
                    }
                }
                // renamed?
                /*
                if ($data['old']['database_name'] != $data['new']['database_name']) {
                    $old_name = $data['old']['database_name'];
                    $new_name = $data['new']['database_name'];
                    if ($this->renameDB($oldName, $newName)) {
                        $app->log("Renamed MongoDB database: ".$old_name." -> ".$new_name, LOGLEVEL_DEBUG);
                    } else {
                        $app->log("Renaming MongoDB database failed: ".$old_name." -> ".$new_name, LOGLEVEL_WARNING);
                    }
                }
                */
            }
            // switching from MySQL <-> Mongo isn't supported
            // no idea what we should do here...would be best to permit in interface?
            // remote access isn't supported by MongoDB (limiting to IP),
            // we therefor don't listen for it's changes
        }
        $this->disconnect();
    }
    /**
     * This function is called when a DB is deleted from within the ISPConfig interface.
     * All we need to do is to delete the database.
     *
     * @param string $event_name the name of the event (insert, update, delete)
     * @param array $data the event data (old and new)
     * @return only if something is wrong
     */
    function db_delete($event_name,$data) {
        global $app, $conf;
        if ($data['old']['type'] == 'mongo') {
            if ($this->connect() === false) {
                $app->log("Unable to connect to MongoDB: Connecting using connect() failed.", LOGLEVEL_ERROR);
                return;
            }
            $db_to_drop = $data['old']['database_name'];
            if ($this->dropDB($db_to_drop)) {
                $app->log("Dropping MongoDB database: ".$db_to_drop, LOGLEVEL_DEBUG);
            } else {
                $app->log("Error while dropping MongoDB database: ".$db_to_drop, LOGLEVEL_WARNING);
            }
            $this->disconnect();
        }
    }
    /**
     * This function is called when a user is inserted from within the ISPConfig interface.
     * Since users are separated from databases we don't do anything here.
     * As soon as an user is associated to a DB, we add him there.
     *
     * @param string $event_name the name of the event (insert, update, delete)
     * @param array $data the event data (old and new)
     */
    function db_user_insert($event_name,$data) {}
    /**
     * This function is called when a user is updated from within the ISPConfig interface.
     * The only thing we need to listen for here are password changes.
     * We than need to change those in all databases the user uses.
     *
     * @param string $event_name the name of the event (insert, update, delete)
     * @param array $data the event data (old and new)
     * @return only if something is wrong
     */
    function db_user_update($event_name,$data) {
        global $app, $conf;
        if ($data['old']['database_user'] == $data['new']['database_user']
            && ($data['old']['database_password'] == $data['new']['database_password']
            || $data['new']['database_password'] == '')) {
            return;
        }
        if ($this->connect() === false) {
            $app->log("Unable to connect to MongoDB: Connecting using connect() failed.", LOGLEVEL_ERROR);
            return;
        }
        if ($data['old']['database_user'] != $data['new']['database_user']) {
            // username has changed
            $dbs = $this->getDBs();
            if ((bool) $dbs) {
                foreach ($dbs as $db) {
                    if ($this->userExists($db, $data['old']['database_user'])) {
                        if (!$this->userExists($db, $data['new']['database_user'])) {
                            $user = $this->getUser($db, $data['old']['database_user']);
                            if ($this->dropUser($data['old']['database_user'], $db)) {
                                if ($this->addUser($db, array(
                                    'username' => $data['new']['database_user'],
                                    'password' => md5($data['new']['database_password_mongo']),
                                    'roles' => $user['roles']
                                ))) {
                                    $app->log("Created user: ".$data['new']['database_user']." in DB: ".$db, LOGLEVEL_DEBUG);
                                } else {
                                    $app->log("Couldn't create user: ".$data['new']['database_user']." in DB: ".$db, LOGLEVEL_WARNING);
                                }
                            } else {
                                $app->log("Couldn't drop user: ".$data['old']['database_user']." in DB: ".$db, LOGLEVEL_WARNING);
                            }
                        } else {
                            $app->log("User: ".$data['new']['database_user']." already exists in DB: ".$db, LOGLEVEL_WARNING);
                        }
                    }
                }
            }
        }
        if ($data['old']['database_password'] != $data['new']['database_password']
            || $data['old']['database_user'] != $data['new']['database_user']) {
            // password only has changed
            $dbs = $this->getDBs();
            if ((bool) $dbs) {
                foreach ($dbs as $db) {
                    if ($this->userExists($db, $data['new']['database_user'])) {
                        if ($this->changePassword($db, $data['new']['database_user'], md5($data['new']['database_password_mongo']))) {
                            $app->log("Changed user's: ".$data['new']['database_user']." password in DB: ".$db, LOGLEVEL_DEBUG);
                        } else {
                            $app->log("Couldn't change user's: ".$data['new']['database_user']." password in DB: ".$db, LOGLEVEL_WARNING);
                        }
                    }
                }
            }
        }
        $this->disconnect();
    }
    /**
     * This function is called when a user is deleted from within the ISPConfig interface.
     * Since MongoDB uses per-DB user management, we have to find every database where the user is
     * activated and delete him there.
     *
     * @param string $event_name the name of the event (insert, update, delete)
     * @param array $data the event data (old and new)
     * @return only if something is wrong
     */
    function db_user_delete($event_name, $data) {
        global $app, $conf;
        if ($this->connect() === false) {
            $app->log("Unable to connect to MongoDB: Connecting using connect() failed.", LOGLEVEL_ERROR);
            return;
        }
        if ($this->dropUser($data['old']['database_user']) === true) {
            $app->log("Dropped MongoDB user: ".$data['old']['database_user'], LOGLEVEL_DEBUG);
        } else {
            $app->log("Error while dropping MongoDB user: ".$data['old']['database_user'], LOGLEVEL_WARNING);
        }
        $this->disconnect();
    }
}