From 2332b2279d8a8599b4f041370315edc9544b1560 Mon Sep 17 00:00:00 2001 From: tbrehm Date: Fri, 2 Aug 2013 14:48:38 +0000 Subject: [PATCH] Added support for mongodb. Many thanks to MaddinXx for the patch. http://www.howtoforge.com/forums/showthread.php?t=62691 --- install/sql/incremental/upd_0055.sql | 2 + install/sql/ispconfig3.sql | 213 +- interface/lib/classes/tform.inc.php | 1990 ++++++++--------- interface/lib/classes/tools_monitor.inc.php | 34 + interface/lib/shelluser_blacklist | 3 +- .../web/admin/form/server_config.tform.php | 72 +- .../web/admin/lib/lang/de_server_config.lng | 1 + .../web/admin/lib/lang/en_server_config.lng | 3 +- .../templates/server_config_rescue_edit.htm | 16 +- interface/web/monitor/lib/lang/de.lng | 3 + interface/web/monitor/lib/lang/en.lng | 3 + interface/web/monitor/lib/module.conf.php | 7 +- interface/web/monitor/show_data.php | 7 + interface/web/sites/database_user_edit.php | 62 +- interface/web/sites/form/database.tform.php | 9 +- .../web/sites/form/database_user.tform.php | 10 +- .../sites/lib/lang/de_database_admin_list.lng | 1 + .../web/sites/lib/lang/de_database_list.lng | 1 + .../web/sites/lib/lang/de_web_backup_list.lng | 1 + .../sites/lib/lang/en_database_admin_list.lng | 3 +- .../web/sites/lib/lang/en_database_list.lng | 3 +- .../web/sites/lib/lang/en_web_backup_list.lng | 9 +- interface/web/sites/list/database.list.php | 15 +- .../sites/templates/database_admin_list.htm | 11 +- .../web/sites/templates/database_list.htm | 11 +- server/cron_daily.php | 248 +- server/lib/classes/monitor_tools.inc.php | 57 +- .../monitor_core_module.inc.php | 44 +- .../mods-available/rescue_core_module.inc.php | 175 +- .../plugins-available/backup_plugin.inc.php | 66 +- .../mongo_clientdb_plugin.inc.php | 820 +++++++ 31 files changed, 2525 insertions(+), 1375 deletions(-) create mode 100644 install/sql/incremental/upd_0055.sql create mode 100644 server/plugins-available/mongo_clientdb_plugin.inc.php diff --git a/install/sql/incremental/upd_0055.sql b/install/sql/incremental/upd_0055.sql new file mode 100644 index 0000000000..7bcfa71f3f --- /dev/null +++ b/install/sql/incremental/upd_0055.sql @@ -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`; diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql index cb2033dfc6..e9bdf95317 100644 --- a/install/sql/ispconfig3.sql +++ b/install/sql/ispconfig3.sql @@ -26,24 +26,24 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 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 --- +-- --- +-- -- ISPConfig 3 -- DB-Version: 3.0.0.9 --- +-- SET FOREIGN_KEY_CHECKS = 0; @@ -252,9 +252,9 @@ CREATE TABLE `client_circle` ( -- -------------------------------------------------------- --- +-- -- Table structure for table `client_template` --- +-- CREATE TABLE `client_template` ( `template_id` int(11) unsigned NOT NULL auto_increment, @@ -262,7 +262,7 @@ CREATE TABLE `client_template` ( `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 @@ CREATE TABLE `country` ( -- -------------------------------------------------------- --- +-- -- 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 @@ CREATE TABLE `cron` ( -- -------------------------------------------------------- --- +-- -- 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 @@ CREATE TABLE IF NOT EXISTS `directive_snippets` ( -- -------------------------------------------------------- --- +-- -- Table structure for table `dns_rr` --- +-- CREATE TABLE `dns_rr` ( `id` int(11) unsigned NOT NULL auto_increment, @@ -425,9 +425,9 @@ CREATE TABLE `dns_slave` ( -- -------------------------------------------------------- --- +-- -- Table structure for table `dns_soa` --- +-- CREATE TABLE `dns_soa` ( `id` int(10) unsigned NOT NULL auto_increment, @@ -457,9 +457,9 @@ CREATE TABLE `dns_soa` ( -- -------------------------------------------------------- --- +-- -- Table structure for table `dns_template` --- +-- CREATE TABLE `dns_template` ( `template_id` int(11) unsigned NOT NULL auto_increment, @@ -493,9 +493,9 @@ CREATE TABLE `domain` ( -- -------------------------------------------------------- --- +-- -- Table structure for table `firewall` --- +-- CREATE TABLE `firewall` ( `firewall_id` int(11) unsigned NOT NULL auto_increment, @@ -513,9 +513,9 @@ CREATE TABLE `firewall` ( -- -------------------------------------------------------- --- +-- -- Table structure for table `ftp_user` --- +-- CREATE TABLE `ftp_user` ( `ftp_user_id` int(11) unsigned NOT NULL auto_increment, @@ -607,9 +607,9 @@ CREATE TABLE `iptables` ( -- -------------------------------------------------------- --- +-- -- Table structure for table `mail_access` --- +-- CREATE TABLE `mail_access` ( `access_id` int(11) unsigned NOT NULL auto_increment, @@ -629,9 +629,9 @@ CREATE TABLE `mail_access` ( -- -------------------------------------------------------- --- +-- -- 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 @@ CREATE TABLE `mail_content_filter` ( -- -------------------------------------------------------- --- +-- -- Table structure for table `mail_domain` --- +-- CREATE TABLE `mail_domain` ( `domain_id` int(11) unsigned NOT NULL auto_increment, @@ -675,9 +675,9 @@ CREATE TABLE `mail_domain` ( -- -------------------------------------------------------- --- +-- -- Table structure for table `mail_forwarding` --- +-- CREATE TABLE `mail_forwarding` ( `forwarding_id` int(11) unsigned NOT NULL auto_increment, @@ -698,9 +698,9 @@ CREATE TABLE `mail_forwarding` ( -- -------------------------------------------------------- --- +-- -- Table structure for table `mail_get` --- +-- CREATE TABLE `mail_get` ( `mailget_id` int(11) unsigned NOT NULL auto_increment, @@ -764,9 +764,9 @@ CREATE TABLE IF NOT EXISTS `mail_relay_recipient` ( -- -------------------------------------------------------- --- +-- -- Table structure for table `mail_traffic` --- +-- CREATE TABLE `mail_traffic` ( `traffic_id` int(11) unsigned NOT NULL auto_increment, @@ -779,9 +779,9 @@ CREATE TABLE `mail_traffic` ( -- -------------------------------------------------------- --- +-- -- Table structure for table `mail_transport` --- +-- CREATE TABLE `mail_transport` ( `transport_id` int(11) unsigned NOT NULL auto_increment, @@ -802,9 +802,9 @@ CREATE TABLE `mail_transport` ( -- -------------------------------------------------------- --- +-- -- Table structure for table `mail_user` --- +-- CREATE TABLE `mail_user` ( `mailuser_id` int(11) unsigned NOT NULL auto_increment, @@ -848,9 +848,9 @@ CREATE TABLE `mail_user` ( -- -------------------------------------------------------- --- +-- -- 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 @@ CREATE TABLE IF NOT EXISTS `openvz_vm` ( -- -------------------------------------------------------- --- +-- -- Table structure for table `remote_session` --- +-- CREATE TABLE `remote_session` ( `remote_session` varchar(64) NOT NULL, @@ -1075,9 +1075,9 @@ CREATE TABLE `remote_session` ( -- -------------------------------------------------------- --- +-- -- Table structure for table `remote_user` --- +-- CREATE TABLE `remote_user` ( `remote_userid` int(11) unsigned NOT NULL auto_increment, @@ -1094,9 +1094,9 @@ CREATE TABLE `remote_user` ( -- -------------------------------------------------------- --- +-- -- Table structure for table `server` --- +-- CREATE TABLE `server` ( `server_id` int(11) unsigned NOT NULL auto_increment, @@ -1124,9 +1124,9 @@ CREATE TABLE `server` ( -- -------------------------------------------------------- --- +-- -- Table structure for table `server_ip` --- +-- CREATE TABLE `server_ip` ( `server_ip_id` int(11) unsigned NOT NULL auto_increment, @@ -1200,9 +1200,9 @@ CREATE TABLE `shell_user` ( -- -------------------------------------------------------- --- +-- -- Table structure for table `software_package` --- +-- CREATE TABLE `software_package` ( `package_id` int(11) unsigned NOT NULL auto_increment, @@ -1223,9 +1223,9 @@ CREATE TABLE `software_package` ( -- -------------------------------------------------------- --- +-- -- Table structure for table `software_repo` --- +-- CREATE TABLE `software_repo` ( `software_repo_id` int(11) unsigned NOT NULL auto_increment, @@ -1244,9 +1244,9 @@ CREATE TABLE `software_repo` ( -- -------------------------------------------------------- --- +-- -- Table structure for table `software_update` --- +-- CREATE TABLE `software_update` ( `software_update_id` int(11) unsigned NOT NULL auto_increment, @@ -1266,9 +1266,9 @@ CREATE TABLE `software_update` ( -- -------------------------------------------------------- --- +-- -- 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 @@ CREATE TABLE `software_update_inst` ( -- -------------------------------------------------------- --- +-- -- Table structure for table `spamfilter_policy` --- +-- CREATE TABLE `spamfilter_policy` ( `id` int(11) unsigned NOT NULL auto_increment, @@ -1335,9 +1335,9 @@ CREATE TABLE `spamfilter_policy` ( -- -------------------------------------------------------- --- +-- -- Table structure for table `spamfilter_users` --- +-- CREATE TABLE `spamfilter_users` ( `id` int(11) unsigned NOT NULL auto_increment, @@ -1358,9 +1358,9 @@ CREATE TABLE `spamfilter_users` ( -- -------------------------------------------------------- --- +-- -- Table structure for table `spamfilter_wblist` --- +-- CREATE TABLE `spamfilter_wblist` ( `wblist_id` int(11) unsigned NOT NULL auto_increment, @@ -1380,9 +1380,9 @@ CREATE TABLE `spamfilter_wblist` ( -- -------------------------------------------------------- --- +-- -- Table structure for table `support_message` --- +-- CREATE TABLE `support_message` ( `support_message_id` int(11) unsigned NOT NULL auto_increment, @@ -1414,9 +1414,9 @@ CREATE TABLE `sys_config` ( -- -------------------------------------------------------- --- +-- -- Table structure for table `sys_datalog` --- +-- CREATE TABLE `sys_datalog` ( `datalog_id` int(11) unsigned NOT NULL auto_increment, @@ -1434,9 +1434,9 @@ CREATE TABLE `sys_datalog` ( -- -------------------------------------------------------- --- +-- -- Table structure for table `sys_dbsync` --- +-- CREATE TABLE `sys_dbsync` ( `id` int(11) unsigned NOT NULL auto_increment, @@ -1458,9 +1458,9 @@ CREATE TABLE `sys_dbsync` ( -- -------------------------------------------------------- --- +-- -- Table structure for table `sys_filesync` --- +-- CREATE TABLE `sys_filesync` ( `id` int(11) unsigned NOT NULL auto_increment, @@ -1478,9 +1478,9 @@ CREATE TABLE `sys_filesync` ( -- -------------------------------------------------------- --- +-- -- Table structure for table `sys_group` --- +-- CREATE TABLE `sys_group` ( `groupid` int(11) unsigned NOT NULL auto_increment, @@ -1492,9 +1492,9 @@ CREATE TABLE `sys_group` ( -- -------------------------------------------------------- --- +-- -- Table structure for table `sys_ini` --- +-- CREATE TABLE `sys_ini` ( `sysini_id` int(11) unsigned NOT NULL auto_increment, @@ -1504,9 +1504,9 @@ CREATE TABLE `sys_ini` ( -- -------------------------------------------------------- --- +-- -- Table structure for table `sys_log` --- +-- CREATE TABLE `sys_log` ( `syslog_id` int(11) unsigned NOT NULL auto_increment, @@ -1572,9 +1572,9 @@ CREATE TABLE IF NOT EXISTS `sys_theme` ( -- -------------------------------------------------------- --- +-- -- Table structure for table `sys_user` --- +-- CREATE TABLE `sys_user` ( `userid` int(11) unsigned NOT NULL auto_increment, @@ -1595,7 +1595,7 @@ CREATE TABLE `sys_user` ( `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 @@ CREATE TABLE `web_backup` ( `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 @@ CREATE TABLE IF NOT EXISTS `web_database_user` ( `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 @@ INSERT INTO `country` (`iso`, `name`, `printable_name`, `iso3`, `numcode`) VALUE -- -------------------------------------------------------- --- +-- -- 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 @@ INSERT INTO `spamfilter_policy` (`id`, `sys_userid`, `sys_groupid`, `sys_perm_us -- -------------------------------------------------------- --- +-- -- 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_user` (`userid`, `sys_userid`, `sys_groupid`, `sys_perm_user`, -- INSERT INTO sys_config VALUES ('1','db','db_version','3.0.5.2'); - + SET FOREIGN_KEY_CHECKS = 1; diff --git a/interface/lib/classes/tform.inc.php b/interface/lib/classes/tform.inc.php index 23b05ce2fa..d1fd373c5c 100644 --- a/interface/lib/classes/tform.inc.php +++ b/interface/lib/classes/tform.inc.php @@ -7,14 +7,14 @@ 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. + * 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 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. class tform { - /** - * Definition of the database table (array) - * @var tableDef - */ - var $tableDef; - - /** - * Private - * @var action - */ - var $action; - - /** - * Table name (String) - * @var table_name - */ - var $table_name; - - /** - * Debug Variable - * @var debug - */ - var $debug = 0; - - /** - * name of the primary field of the database table (string) - * @var table_index - */ - var $table_index; - - /** - * contains the error messages - * @var errorMessage - */ - var $errorMessage = ''; - - var $dateformat = "d.m.Y"; - var $formDef = array(); - var $wordbook; - var $module; - var $primary_id; + /** + * Definition of the database table (array) + * @var tableDef + */ + var $tableDef; + + /** + * Private + * @var action + */ + var $action; + + /** + * Table name (String) + * @var table_name + */ + var $table_name; + + /** + * Debug Variable + * @var debug + */ + var $debug = 0; + + /** + * name of the primary field of the database table (string) + * @var table_index + */ + var $table_index; + + /** + * contains the error messages + * @var errorMessage + */ + var $errorMessage = ''; + + 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; - - include_once($file); - $this->tableDef = $table; - $this->table_name = $table_name; - $this->table_index = $table_index; - return true; - } - */ - - function loadFormDef($file,$module = '') { - global $app,$conf; - - include($file); - $this->formDef = $form; - - $this->module = $module; + /** + * 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; + } + */ + + function loadFormDef($file,$module = '') { + global $app,$conf; + + include($file); + $this->formDef = $form; + + $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 'TEXT': - $new_record[$key] = $record[$key]; - break; - - case 'DATETSTAMP': - if($record[$key] > 0) { - $new_record[$key] = date($this->dateformat,$record[$key]); - } - break; - + case 'VARCHAR': + $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 '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; - - case 'INTEGER': - $new_record[$key] = $app->functions->intval($record[$key]); - break; - - case 'DOUBLE': - $new_record[$key] = $record[$key]; - break; - - case 'CURRENCY': - $new_record[$key] = $app->functions->currency_format($record[$key]); - break; - - 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 - */ - - function getDatasourceData($field, $record) { - global $app; - - $values = array(); - - if($field["datasource"]["type"] == 'SQL') { - - // Preparing SQL string. We will replace some - // common placeholders - $querystring = $field["datasource"]["querystring"]; - $querystring = str_replace("{USERID}",$_SESSION["s"]["user"]["userid"],$querystring); - $querystring = str_replace("{GROUPID}",$_SESSION["s"]["user"]["default_group"],$querystring); - $querystring = str_replace("{GROUPS}",$_SESSION["s"]["user"]["groups"],$querystring); - $table_idx = $this->formDef['db_table_idx']; - + $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 'DOUBLE': + $new_record[$key] = $record[$key]; + break; + + case 'CURRENCY': + $new_record[$key] = $app->functions->currency_format($record[$key]); + break; + + 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 + */ + + function getDatasourceData($field, $record) { + global $app; + + $values = array(); + + if($field["datasource"]["type"] == 'SQL') { + + // Preparing SQL string. We will replace some + // common placeholders + $querystring = $field["datasource"]["querystring"]; + $querystring = str_replace("{USERID}",$_SESSION["s"]["user"]["userid"],$querystring); + $querystring = str_replace("{GROUPID}",$_SESSION["s"]["user"]["default_group"],$querystring); + $querystring = str_replace("{GROUPS}",$_SESSION["s"]["user"]["groups"],$querystring); + $table_idx = $this->formDef['db_table_idx']; + $tmp_recordid = (isset($record[$table_idx]))?$record[$table_idx]:0; - $querystring = str_replace("{RECORDID}",$tmp_recordid,$querystring); + $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
\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; - - } - + + $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
\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 @@ class tform { $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 @@ class tform { //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 @@ class tform { } } // 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 @@ class tform { $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) { - $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])) { + 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 .= "\r\n"; - } - } - $new_record[$key] = $out; - break; - case 'MULTIPLE': - if(is_array($field['value'])) { - - // Split - $vals = explode($field['separator'],$val); - - // write HTML - $out = ''; - foreach($field['value'] as $k => $v) { - - $selected = ''; - foreach($vals as $tvl) { - if(trim($tvl) == trim($k)) $selected = ' SELECTED'; - } - - $out .= "\r\n"; - } - } - $new_record[$key] = $out; - break; - - case 'PASSWORD': - $new_record[$key] = ''; - break; - - case 'CHECKBOX': - $checked = ($val == $field['value'][1])?' CHECKED':''; - $new_record[$key] = "\r\n"; - break; - - case 'CHECKBOXARRAY': - if(is_array($field['value'])) { - - // aufsplitten ergebnisse - $vals = explode($field['separator'],$val); - - // HTML schreiben - $out = ''; - $elementNo = 0; - foreach($field['value'] as $k => $v) { - - $checked = ''; - foreach($vals as $tvl) { - if(trim($tvl) == trim($k)) $checked = ' CHECKED'; - } - // $out .= "\r\n"; + $out .= "\r\n"; + } + } + $new_record[$key] = $out; + break; + case 'MULTIPLE': + if(is_array($field['value'])) { + + // Split + $vals = explode($field['separator'],$val); + + // write HTML + $out = ''; + foreach($field['value'] as $k => $v) { + + $selected = ''; + foreach($vals as $tvl) { + if(trim($tvl) == trim($k)) $selected = ' SELECTED'; + } + + $out .= "\r\n"; + } + } + $new_record[$key] = $out; + break; + + case 'PASSWORD': + $new_record[$key] = ''; + break; + + case 'CHECKBOX': + $checked = ($val == $field['value'][1])?' CHECKED':''; + $new_record[$key] = "\r\n"; + break; + + case 'CHECKBOXARRAY': + if(is_array($field['value'])) { + + // aufsplitten ergebnisse + $vals = explode($field['separator'],$val); + + // HTML schreiben + $out = ''; + $elementNo = 0; + foreach($field['value'] as $k => $v) { + + $checked = ''; + foreach($vals as $tvl) { + if(trim($tvl) == trim($k)) $checked = ' CHECKED'; + } + // $out .= "\r\n"; $out .= "
\r\n"; - $elementNo++; - } - } - $new_record[$key] = $out; - break; - - case 'RADIO': - if(is_array($field['value'])) { - - // HTML schreiben - $out = ''; - $elementNo = 0; - foreach($field['value'] as $k => $v) { - $checked = ($k == $val)?' CHECKED':''; - //$out .= "\r\n"; + $elementNo++; + } + } + $new_record[$key] = $out; + break; + + case 'RADIO': + if(is_array($field['value'])) { + + // HTML schreiben + $out = ''; + $elementNo = 0; + foreach($field['value'] as $k => $v) { + $checked = ($k == $val)?' CHECKED':''; + //$out .= "\r\n"; $out .= "\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; - - default: + $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; + + 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) { - - // If Datasource is set, get the data from there - if(@is_array($field['datasource'])) { - if(is_array($field["value"])) { + } + } + } + } 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"])) { $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 .= "\r\n"; - } - } - if(isset($out)) $new_record[$key] = $out; - break; - case 'MULTIPLE': - if(is_array($field['value'])) { - - // aufsplitten ergebnisse - $vals = explode($field['separator'],$val); - - // HTML schreiben - $out = ''; - foreach($field['value'] as $k => $v) { - - $out .= "\r\n"; - } - } - $new_record[$key] = $out; - break; - - case 'PASSWORD': - $new_record[$key] = ''; - break; - - case 'CHECKBOX': - // $checked = (empty($field["default"]))?'':' CHECKED'; - $checked = ($field["default"] == $field['value'][1])?' CHECKED':''; - $new_record[$key] = "\r\n"; - break; - - case 'CHECKBOXARRAY': - if(is_array($field['value'])) { - - // aufsplitten ergebnisse - $vals = explode($field['separator'],$field["default"]); - - // HTML schreiben - $out = ''; - $elementNo = 0; - foreach($field['value'] as $k => $v) { - - $checked = ''; - foreach($vals as $tvl) { - if(trim($tvl) == trim($k)) $checked = ' CHECKED'; - } - // $out .= "\r\n"; + switch ($field['formtype']) { + case 'SELECT': + if(is_array($field['value'])) { + $out = ''; + foreach($field['value'] as $k => $v) { + $selected = ($k == $field["default"])?' SELECTED':''; + $out .= "\r\n"; + } + } + if(isset($out)) $new_record[$key] = $out; + break; + case 'MULTIPLE': + if(is_array($field['value'])) { + + // aufsplitten ergebnisse + $vals = explode($field['separator'],$val); + + // HTML schreiben + $out = ''; + foreach($field['value'] as $k => $v) { + + $out .= "\r\n"; + } + } + $new_record[$key] = $out; + break; + + case 'PASSWORD': + $new_record[$key] = ''; + break; + + case 'CHECKBOX': + // $checked = (empty($field["default"]))?'':' CHECKED'; + $checked = ($field["default"] == $field['value'][1])?' CHECKED':''; + $new_record[$key] = "\r\n"; + break; + + case 'CHECKBOXARRAY': + if(is_array($field['value'])) { + + // aufsplitten ergebnisse + $vals = explode($field['separator'],$field["default"]); + + // HTML schreiben + $out = ''; + $elementNo = 0; + foreach($field['value'] as $k => $v) { + + $checked = ''; + foreach($vals as $tvl) { + if(trim($tvl) == trim($k)) $checked = ' CHECKED'; + } + // $out .= "\r\n"; $out .= "  \r\n"; - $elementNo++; - } - } - $new_record[$key] = $out; - break; - - case 'RADIO': - if(is_array($field['value'])) { - - // HTML schreiben - $out = ''; - $elementNo = 0; - foreach($field['value'] as $k => $v) { - $checked = ($k == $field["default"])?' CHECKED':''; - //$out .= "\r\n"; + $elementNo++; + } + } + $new_record[$key] = $out; + break; + + case 'RADIO': + if(is_array($field['value'])) { + + // HTML schreiben + $out = ''; + $elementNo = 0; + foreach($field['value'] as $k => $v) { + $checked = ($k == $field["default"])?' CHECKED':''; + //$out .= "\r\n"; $out .= "\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; - - default: - $new_record[$key] = htmlspecialchars($field['default']); - } - } - - } - - 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) { + $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; + + default: + $new_record[$key] = htmlspecialchars($field['default']); + } + } + + } + + 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 @@ class tform { $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 @@ class tform { $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; - } - - // 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]."
\r\n"; - } - } - + //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; + } + + // 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]."
\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; - } - + } + } + 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 + * 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 record + */ - function filterField($field_name, $field_value, $filters, $filter_event) { + 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 @@ class tform { } } } - 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 - */ - - function validateField($field_name, $field_value, $validators) { - - global $app; - + 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 + */ + + function validateField($field_name, $field_value, $validators) { + + global $app; + $escape = '`'; - - // loop trough the validators - foreach($validators as $validator) { - - switch ($validator['type']) { - case 'REGEX': - $validator['regex'] .= 's'; - if(!preg_match($validator['regex'], $field_value)) { - $errmsg = $validator['errmsg']; - if(isset($this->wordbook[$errmsg])) { - $this->errorMessage .= $this->wordbook[$errmsg]."
\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]."
\r\n"; } else { $this->errorMessage .= $errmsg."
\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]."
\r\n"; + $this->errorMessage .= $this->wordbook[$errmsg]."
\r\n"; } else { $this->errorMessage .= $errmsg."
\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]."
\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]."
\r\n"; } else { $this->errorMessage .= $errmsg."
\r\n"; } - } + } } } - break; - case 'NOTEMPTY': - if(empty($field_value)) { - $errmsg = $validator['errmsg']; - if(isset($this->wordbook[$errmsg])) { - $this->errorMessage .= $this->wordbook[$errmsg]."
\r\n"; + break; + case 'NOTEMPTY': + if(empty($field_value)) { + $errmsg = $validator['errmsg']; + if(isset($this->wordbook[$errmsg])) { + $this->errorMessage .= $this->wordbook[$errmsg]."
\r\n"; } else { $this->errorMessage .= $errmsg."
\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]."
\r\n"; + if(isset($this->wordbook[$errmsg])) { + $this->errorMessage .= $this->wordbook[$errmsg]."
\r\n"; } else { $this->errorMessage .= $errmsg."
\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]."
\r\n"; + $errmsg = $validator['errmsg']; + if(isset($this->wordbook[$errmsg])) { + $this->errorMessage .= $this->wordbook[$errmsg]."
\r\n"; } else { $this->errorMessage .= $errmsg."
\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]."
\r\n"; + $this->errorMessage .= $this->wordbook[$errmsg]."
\r\n"; } else { $this->errorMessage .= $errmsg."
\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]."
\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]."
\r\n"; } else { $this->errorMessage .= $errmsg."
\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]."
\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]."
\r\n"; } else { $this->errorMessage .= $errmsg."
\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."
\r\n"; + $this->errorMessage .= $errmsg."
\r\n"; } break; case 'ISIPV4': @@ -927,15 +927,15 @@ class tform { $vip=0; } }else{$vip=0;} - if($vip==0) { + if($vip==0) { $errmsg = $validator['errmsg']; - if(isset($this->wordbook[$errmsg])) { - $this->errorMessage .= $this->wordbook[$errmsg]."
\r\n"; + if(isset($this->wordbook[$errmsg])) { + $this->errorMessage .= $this->wordbook[$errmsg]."
\r\n"; } else { $this->errorMessage .= $errmsg."
\r\n"; } } - break; + break; case 'ISIP': if($validator['allowempty'] != 'y') $validator['allowempty'] = 'n'; if($validator['allowempty'] == 'y' && $field_value == '') { @@ -979,13 +979,13 @@ class tform { } } } - 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 @@ class tform { } else { $this->errorMessage .= $errmsg."
\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
\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
\r\n"; + } + break; default: $this->errorMessage .= "Unknown Validator: ".$validator['type']; break; - } - - - } - - 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 = '') { - - global $app; - - // If there are no data records on the tab, return empty sql string - if(count($this->formDef['tabs'][$tab]['fields']) == 0) return ''; - - // checking permissions - if($this->formDef['auth'] == 'yes' && $_SESSION["s"]["user"]["typ"] != 'admin') { - if($action == "INSERT") { - if(!$this->checkPerm($primary_id,'i')) $this->errorMessage .= "Insert denied.
\r\n"; - } else { - if(!$this->checkPerm($primary_id,'u')) $this->errorMessage .= "Update denied.
\r\n"; - } - } - - $this->action = $action; - $this->primary_id = $primary_id; - - $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)."); - - // 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') { + } + + + } + + 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 = '') { + + global $app; + + // If there are no data records on the tab, return empty sql string + if(count($this->formDef['tabs'][$tab]['fields']) == 0) return ''; + + // checking permissions + if($this->formDef['auth'] == 'yes' && $_SESSION["s"]["user"]["typ"] != 'admin') { + if($action == "INSERT") { + if(!$this->checkPerm($primary_id,'i')) $this->errorMessage .= "Insert denied.
\r\n"; + } else { + if(!$this->checkPerm($primary_id,'u')) $this->errorMessage .= "Update denied.
\r\n"; + } + } + + $this->action = $action; + $this->primary_id = $primary_id; + + $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)."); + + // 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 @@ class tform { $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 @@ class tform { } 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 @@ class tform { $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 @@ class tform { } 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 = '`'; - } - - - 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 { + } + } + + + // 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($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 "
";
-                print_r($array_data);
-                echo "
"; + echo "
";
+				print_r($array_data);
+				echo "
"; - } + } - 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"]; - - // 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; - } - - // Unset unused variables. - unset($tab["fields"]); - unset($tab["plugins"]); - - $frmTab[] = $tab; - } - - // setting form tabs - $app->tpl->setLoop("formTab", $frmTab); - - // Set form action - $app->tpl->setVar('form_action',$this->formDef["action"]); - $app->tpl->setVar('form_active_tab',$active_tab); - - // Set form title - $form_hint = $this->lng($this->formDef["title"]); - if($this->formDef["description"] != '') $form_hint .= '
'.$this->lng($this->formDef["description"]).'
'; - $app->tpl->setVar('form_hint',$form_hint); - - // Set Wordbook for this form - - $app->tpl->setVar($this->wordbook); - } + + 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"]; + + // 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; + } + + // Unset unused variables. + unset($tab["fields"]); + unset($tab["plugins"]); + + $frmTab[] = $tab; + } + + // setting form tabs + $app->tpl->setLoop("formTab", $frmTab); + + // Set form action + $app->tpl->setVar('form_action',$this->formDef["action"]); + $app->tpl->setVar('form_active_tab',$active_tab); + + // Set form title + $form_hint = $this->lng($this->formDef["title"]); + if($this->formDef["description"] != '') $form_hint .= '
'.$this->lng($this->formDef["description"]).'
'; + $app->tpl->setVar('form_hint',$form_hint); + + // Set Wordbook for this form + + $app->tpl->setVar($this->wordbook); + } function getDataRecord($primary_id) { global $app; $escape = '`'; $sql = "SELECT * FROM ".$escape.$this->formDef['db_table'].$escape." WHERE ".$this->formDef['db_table_idx']." = ".$primary_id; - return $app->db->queryOneRecord($sql); + 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; + } + } + + /* + 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 = '`'; + } - return $sql; + $sql = "SELECT ".$this->formDef['db_table_idx']." FROM ".$escape.$this->formDef['db_table'].$escape." WHERE ".$this->formDef['db_table_idx']." = ".$record_id." AND ".$this->getAuthSQL($perm); + if($record = $app->db->queryOneRecord($sql)) { + return true; + } else { + return false; + } + } else { + $result = false; + if(@$this->formDef["auth_preset"]["userid"] == $_SESSION["s"]["user"]["userid"] && stristr($perm,$this->formDef["auth_preset"]["perm_user"])) $result = true; + if(@$this->formDef["auth_preset"]["groupid"] == $_SESSION["s"]["user"]["groupid"] && stristr($perm,$this->formDef["auth_preset"]["perm_group"])) $result = true; + if(@stristr($this->formDef["auth_preset"]["perm_other"],$perm)) $result = true; + + // if preset == 0, everyone can insert a record of this type + if($this->formDef["auth_preset"]["userid"] == 0 AND $this->formDef["auth_preset"]["groupid"] == 0 AND (@stristr($this->formDef["auth_preset"]["perm_user"],$perm) OR @stristr($this->formDef["auth_preset"]["perm_group"],$perm))) $result = true; + + return $result; + + } + + } + + function getNextTab() { + // 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"]; } - } - - /* - 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 = '`'; - } - - $sql = "SELECT ".$this->formDef['db_table_idx']." FROM ".$escape.$this->formDef['db_table'].$escape." WHERE ".$this->formDef['db_table_idx']." = ".$record_id." AND ".$this->getAuthSQL($perm); - if($record = $app->db->queryOneRecord($sql)) { - return true; - } else { - return false; - } - } else { - $result = false; - if(@$this->formDef["auth_preset"]["userid"] == $_SESSION["s"]["user"]["userid"] && stristr($perm,$this->formDef["auth_preset"]["perm_user"])) $result = true; - if(@$this->formDef["auth_preset"]["groupid"] == $_SESSION["s"]["user"]["groupid"] && stristr($perm,$this->formDef["auth_preset"]["perm_group"])) $result = true; - if(@stristr($this->formDef["auth_preset"]["perm_other"],$perm)) $result = true; - - // if preset == 0, everyone can insert a record of this type - if($this->formDef["auth_preset"]["userid"] == 0 AND $this->formDef["auth_preset"]["groupid"] == 0 AND (@stristr($this->formDef["auth_preset"]["perm_user"],$perm) OR @stristr($this->formDef["auth_preset"]["perm_group"],$perm))) $result = true; - - return $result; - - } - - } - - function getNextTab() { - // 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; - } - - function getCurrentTab() { - return $_SESSION["s"]["form"]["tab"]; - } - + + return $active_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 @@ class tform { $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 @@ class tform { 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 @@ class tform { } } 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 @@ class tform { $_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 @@ class tform { } $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 .= "' . str_repeat(' ', $dt_space); } - + return $out; } } diff --git a/interface/lib/classes/tools_monitor.inc.php b/interface/lib/classes/tools_monitor.inc.php index 121ab931f4..42defa07e4 100644 --- a/interface/lib/classes/tools_monitor.inc.php +++ b/interface/lib/classes/tools_monitor.inc.php @@ -453,6 +453,40 @@ class tools_monitor { 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 = + '
+
'; + + /* + * 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 .= '

'. + 'MongoDB is not installed at this server.
' . + 'See more (for debian) here...'. + '

'; + } + else { + $html .= nl2br($data); + } + $html .= '
'; + + } else { + $html = '

There is no data available at the moment.

'; + } + + 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"); diff --git a/interface/lib/shelluser_blacklist b/interface/lib/shelluser_blacklist index c49d825517..4913b64272 100644 --- a/interface/lib/shelluser_blacklist +++ b/interface/lib/shelluser_blacklist @@ -31,4 +31,5 @@ vmail getmail ispconfig courier -dovecot \ No newline at end of file +dovecot +mongodb diff --git a/interface/web/admin/form/server_config.tform.php b/interface/web/admin/form/server_config.tform.php index c83075f825..0bc490f765 100644 --- a/interface/web/admin/form/server_config.tform.php +++ b/interface/web/admin/form/server_config.tform.php @@ -89,9 +89,9 @@ $form["tabs"]['server'] = array( '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 @@ $form["tabs"]['server'] = array( '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 @@ $form["tabs"]['server'] = array( '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 @@ $form["tabs"]['server'] = array( '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 @@ $form["tabs"]['mail'] = array( '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 @@ $form["tabs"]['mail'] = array( 'formtype' => 'TEXT', 'default' => '7', 'value' => '', - 'width' => '20', - 'maxlength' => '255' + 'width' => '20', + 'maxlength' => '255' ), 'overquota_notify_onok' => array( 'datatype' => 'VARCHAR', @@ -659,8 +659,8 @@ $form["tabs"]['web'] = array( 'formtype' => 'TEXT', 'default' => '7', 'value' => '', - 'width' => '20', - 'maxlength' => '255' + 'width' => '20', + 'maxlength' => '255' ), 'overquota_notify_onok' => array( 'datatype' => 'VARCHAR', @@ -1306,6 +1306,12 @@ $form["tabs"]['rescue'] = array( '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', diff --git a/interface/web/admin/lib/lang/de_server_config.lng b/interface/web/admin/lib/lang/de_server_config.lng index b6f105163d..acb6b3dd8a 100644 --- a/interface/web/admin/lib/lang/de_server_config.lng +++ b/interface/web/admin/lib/lang/de_server_config.lng @@ -146,6 +146,7 @@ $wb['php_fpm_socket_dir_error_empty'] = 'PHP-FPM Socket Verzeichnis ist leer.'; $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'] = 'Information: 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.'; diff --git a/interface/web/admin/lib/lang/en_server_config.lng b/interface/web/admin/lib/lang/en_server_config.lng index c4abee856e..1f1ad0db78 100644 --- a/interface/web/admin/lib/lang/en_server_config.lng +++ b/interface/web/admin/lib/lang/en_server_config.lng @@ -151,6 +151,7 @@ $wb["php_fpm_socket_dir_txt"] = 'PHP-FPM socket directory'; $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"] = 'Information: If you want to shut down mysql you have to select the "Disable MySQL monitor" checkbox and then wait 2-3 minutes.
If you do not wait 2-3 minutes, rescue will try to restart mysql!'; @@ -190,4 +191,4 @@ $wb['munin_user_txt'] = 'Munin User'; $wb['munin_password_txt'] = 'Munin Password'; $wb['munin_url_error_regex'] = 'Invalid Munin URL'; $wb['munin_url_note_txt'] = 'Placeholder:'; -?> +?> diff --git a/interface/web/admin/templates/server_config_rescue_edit.htm b/interface/web/admin/templates/server_config_rescue_edit.htm index 778225b3e6..28b5cb4bd5 100644 --- a/interface/web/admin/templates/server_config_rescue_edit.htm +++ b/interface/web/admin/templates/server_config_rescue_edit.htm @@ -17,6 +17,12 @@ {tmpl_var name='do_not_try_rescue_httpd'} +
+

{tmpl_var name='do_not_try_rescue_mongodb_txt'}

+
+ {tmpl_var name='do_not_try_rescue_mongodb'} +
+

{tmpl_var name='do_not_try_rescue_mysql_txt'}

@@ -30,15 +36,15 @@
- + - + - +
- - \ No newline at end of file + + diff --git a/interface/web/monitor/lib/lang/de.lng b/interface/web/monitor/lib/lang/de.lng index cf9621f57e..a46050ee49 100644 --- a/interface/web/monitor/lib/lang/de.lng +++ b/interface/web/monitor/lib/lang/de.lng @@ -122,6 +122,7 @@ $wb['monitor_services_smtp_txt'] = 'SMTP Server:'; $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_raidstate_txt'] = 'RAID Status'; $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.
We cant find any of them at your server.

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_title_beancounter_txt'] = 'OpenVz VE BeanCounter'; $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'; diff --git a/interface/web/monitor/lib/lang/en.lng b/interface/web/monitor/lib/lang/en.lng index 20cf1fbb3b..ec5ca7325f 100644 --- a/interface/web/monitor/lib/lang/en.lng +++ b/interface/web/monitor/lib/lang/en.lng @@ -46,6 +46,7 @@ $wb['Show ISPConfig-Log'] = 'Show ISPConfig-Log'; $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_smtp_txt'] = 'SMTP-Server:'; $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_mailq_txt'] = 'Mail Queue'; $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'; diff --git a/interface/web/monitor/lib/module.conf.php b/interface/web/monitor/lib/module.conf.php index 1d4e5e1c34..c019b84e46 100644 --- a/interface/web/monitor/lib/module.conf.php +++ b/interface/web/monitor/lib/module.conf.php @@ -190,6 +190,11 @@ $items[] = array( 'title' => "Show fail2ban-Log", '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 @@ $items[] = array( 'title' => "Show IPTables", $module["nav"][] = array( 'title' => 'Logfiles', 'open' => 1, 'items' => $items); -?> \ No newline at end of file +?> diff --git a/interface/web/monitor/show_data.php b/interface/web/monitor/show_data.php index 1cd4baf525..92c66a486b 100644 --- a/interface/web/monitor/show_data.php +++ b/interface/web/monitor/show_data.php @@ -124,6 +124,13 @@ switch($dataType) { $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(); diff --git a/interface/web/sites/database_user_edit.php b/interface/web/sites/database_user_edit.php index 1b71196f69..4f6979fc4e 100644 --- a/interface/web/sites/database_user_edit.php +++ b/interface/web/sites/database_user_edit.php @@ -57,17 +57,17 @@ class page_action extends tform_actions { * 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 @@ class page_action extends tform_actions { } $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 @@ class page_action extends tform_actions { $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"].'
'; 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"]).'
'; - + //* 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.').'
'; } - + 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"].'
'; @@ -162,11 +167,11 @@ class page_action extends tform_actions { $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"]).'
'; - + //* 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 @@ class page_action extends tform_actions { 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 @@ class page_action extends tform_actions { $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; diff --git a/interface/web/sites/form/database.tform.php b/interface/web/sites/form/database.tform.php index e390f7276c..4cbfa12fef 100644 --- a/interface/web/sites/form/database.tform.php +++ b/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 @@ $form["tabs"]['database'] = array ( '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 @@ $form["tabs"]['database'] = array ( ); -?> \ No newline at end of file +?> diff --git a/interface/web/sites/form/database_user.tform.php b/interface/web/sites/form/database_user.tform.php index fa2b2d3a32..d2a2defe7b 100644 --- a/interface/web/sites/form/database_user.tform.php +++ b/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 @@ $form["tabs"]['database_user'] = array ( 'width' => '30', 'maxlength' => '255' ), + 'database_password_mongo' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'PASSWORD', + 'default' => '', + 'value' => '', + 'width' => '30', + 'maxlength' => '255' + ), ################################## # ENDE Datatable fields ################################## diff --git a/interface/web/sites/lib/lang/de_database_admin_list.lng b/interface/web/sites/lib/lang/de_database_admin_list.lng index 3f7542a303..3b11b2c415 100644 --- a/interface/web/sites/lib/lang/de_database_admin_list.lng +++ b/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'; diff --git a/interface/web/sites/lib/lang/de_database_list.lng b/interface/web/sites/lib/lang/de_database_list.lng index bae444c42b..89caea3e99 100644 --- a/interface/web/sites/lib/lang/de_database_list.lng +++ b/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'; diff --git a/interface/web/sites/lib/lang/de_web_backup_list.lng b/interface/web/sites/lib/lang/de_web_backup_list.lng index 4cc06d82e7..499fb4f754 100644 --- a/interface/web/sites/lib/lang/de_web_backup_list.lng +++ b/interface/web/sites/lib/lang/de_web_backup_list.lng @@ -10,6 +10,7 @@ $wb['restore_info_txt'] = 'Die Wiederherstellung des Backups hat begonnen. Diese $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'; ?> diff --git a/interface/web/sites/lib/lang/en_database_admin_list.lng b/interface/web/sites/lib/lang/en_database_admin_list.lng index a49adcdadd..5d0ad7a83a 100644 --- a/interface/web/sites/lib/lang/en_database_admin_list.lng +++ b/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'; -?> \ No newline at end of file +?> diff --git a/interface/web/sites/lib/lang/en_database_list.lng b/interface/web/sites/lib/lang/en_database_list.lng index ff599d270a..0a8d6ff87e 100644 --- a/interface/web/sites/lib/lang/en_database_list.lng +++ b/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'; -?> \ No newline at end of file +?> diff --git a/interface/web/sites/lib/lang/en_web_backup_list.lng b/interface/web/sites/lib/lang/en_web_backup_list.lng index 2b65944682..aea21f8046 100644 --- a/interface/web/sites/lib/lang/en_web_backup_list.lng +++ b/interface/web/sites/lib/lang/en_web_backup_list.lng @@ -11,7 +11,8 @@ $wb['restore_info_txt'] = 'Restore of the backup has been started. This action t $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'; + +?> diff --git a/interface/web/sites/list/database.list.php b/interface/web/sites/list/database.list.php index cbb51a81bb..f512bef31d 100644 --- a/interface/web/sites/list/database.list.php +++ b/interface/web/sites/list/database.list.php @@ -70,6 +70,19 @@ $liste["item"][] = array( 'field' => "remote_access", 'width' => "", 'value' => array('y' => "
Yes
",'n' => "
No
")); +$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 @@ $liste["item"][] = array( 'field' => "database_name", 'width' => "", 'value' => ""); -?> \ No newline at end of file +?> diff --git a/interface/web/sites/templates/database_admin_list.htm b/interface/web/sites/templates/database_admin_list.htm index e44616c135..2f967384fd 100644 --- a/interface/web/sites/templates/database_admin_list.htm +++ b/interface/web/sites/templates/database_admin_list.htm @@ -19,6 +19,7 @@ + @@ -28,6 +29,7 @@ + @@ -42,6 +44,7 @@ {tmpl_var name="active"} {tmpl_var name="remote_access"} + {tmpl_var name="type"} {tmpl_var name="sys_groupid"} {tmpl_var name="server_id"} {tmpl_var name="database_user_id"} @@ -51,23 +54,23 @@ {tmpl_var name='admin_txt'} {tmpl_var name='edit_txt'} - {tmpl_var name='delete_txt'} + {tmpl_var name='delete_txt'} - {tmpl_var name='globalsearch_noresults_text_txt'} + {tmpl_var name='globalsearch_noresults_text_txt'} - + - \ No newline at end of file + diff --git a/interface/web/sites/templates/database_list.htm b/interface/web/sites/templates/database_list.htm index 0e80212c9d..888f3ba13e 100644 --- a/interface/web/sites/templates/database_list.htm +++ b/interface/web/sites/templates/database_list.htm @@ -36,6 +36,7 @@ + @@ -44,6 +45,7 @@ + @@ -57,6 +59,7 @@ {tmpl_var name="active"} {tmpl_var name="remote_access"} + {tmpl_var name="type"} {tmpl_var name="server_id"} {tmpl_var name="database_user_id"} {tmpl_var name="database_name"} @@ -65,23 +68,23 @@ {tmpl_var name='admin_txt'} {tmpl_var name='edit_txt'} - {tmpl_var name='delete_txt'} + {tmpl_var name='delete_txt'} - {tmpl_var name='globalsearch_noresults_text_txt'} + {tmpl_var name='globalsearch_noresults_text_txt'} - + - \ No newline at end of file + diff --git a/server/cron_daily.php b/server/cron_daily.php index 9d7ca00d24..21d8f84f0b 100644 --- a/server/cron_daily.php +++ b/server/cron_daily.php @@ -54,7 +54,7 @@ if(count($records) > 0) $parse_mail_log = true; 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 @@ if($parse_mail_log == true) { $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] -> , Message-ID: , 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($parse_mail_log == true) { 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 @@ if($parse_mail_log == true) { } } } - + $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($parse_mail_log == true) { //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 @@ if($parse_mail_log == true) { 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 @@ if($parse_mail_log == true) { 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($parse_mail_log == true) { //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 @@ if($parse_mail_log == true) { 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 @@ if($parse_mail_log == true) { } 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 @@ if($parse_mail_log == true) { //echo $sql; } } - + unset($mailbox_traffic); if($last_line) file_put_contents($state_file, $last_line); } @@ -278,7 +278,7 @@ $records = $app->db->queryAllRecords($sql); 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 @@ $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); 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 @@ foreach($records as $rec) { //* 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 @@ foreach($records as $rec) { $log_folder .= '/' . $subdomain_host; unset($tmp); } - + $logfile = $rec['document_root'].'/' . $log_folder . '/'.$yesterday.'-access.log'; $total_bytes = 0; @@ -646,10 +646,10 @@ if ($app->dbmaster == $app->db) { ######### 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 @@ function send_notification_email($template, $placeholders, $recipients) { } else { $lines = file($conf['rootpath'].'/conf/mail/' . $template . '_en.txt'); } - + //* get mail headers, subject and body $mailHeaders = ''; $mailBody = ''; @@ -680,12 +680,12 @@ function send_notification_email($template, $placeholders, $recipients) { } } $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 @@ function send_notification_email($template, $placeholders, $recipients) { unset($mailHeaders); unset($mailBody); unset($lines); - + return true; } @@ -706,7 +706,7 @@ function send_notification_email($template, $placeholders, $recipients) { 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 ($app->dbmaster == $app->db) { 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 @@ if ($app->dbmaster == $app->db) { $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 @@ if ($app->dbmaster == $app->db) { $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 @@ if ($app->dbmaster == $app->db) { $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 ($app->dbmaster == $app->db) { 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 @@ if ($app->dbmaster == $app->db) { } else { $rec['soft'] .= ' KB'; } - + if($rec['hard'] > 1024) { $rec['hard'] = round($rec['hard'] / 1024,2).' MB'; } elseif($rec['hard'] == 0){ @@ -852,12 +851,12 @@ if ($app->dbmaster == $app->db) { } 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 @@ if ($app->dbmaster == $app->db) { '{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 @@ if ($app->dbmaster == $app->db) { } 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 @@ if ($app->dbmaster == $app->db) { '{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 @@ if ($app->dbmaster == $app->db) { $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 @@ if ($app->dbmaster == $app->db) { } } } - + 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 @@ if ($app->dbmaster == $app->db) { $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 @@ if ($app->dbmaster == $app->db) { '{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 @@ if ($app->dbmaster == $app->db) { $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 @@ if ($app->dbmaster == $app->db) { $recipients[] = $client['email']; } } - + send_notification_email('mail_quota_notification', $placeholders, $recipients); - } + } } } } @@ -1081,7 +1080,7 @@ if ($app->dbmaster == $app->db) { ####################################################################################################### 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 @@ if($backup_dir != '') { } 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 @@ if($backup_dir != '') { //* 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 @@ if($backup_dir != '') { 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 @@ if($backup_dir != '') { 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 -c -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 @@ if($backup_dir != '') { $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); diff --git a/server/lib/classes/monitor_tools.inc.php b/server/lib/classes/monitor_tools.inc.php index 9ce95567a2..6b93e1e6ae 100644 --- a/server/lib/classes/monitor_tools.inc.php +++ b/server/lib/classes/monitor_tools.inc.php @@ -755,6 +755,13 @@ class monitor_tools { $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 @@ class monitor_tools { 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 @@ class monitor_tools { $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 @@ class monitor_tools { } -?> \ No newline at end of file +?> diff --git a/server/mods-available/monitor_core_module.inc.php b/server/mods-available/monitor_core_module.inc.php index 2e66d64938..88e994dccf 100644 --- a/server/mods-available/monitor_core_module.inc.php +++ b/server/mods-available/monitor_core_module.inc.php @@ -89,7 +89,7 @@ class monitor_core_module { $this->_tools = new monitor_tools(); /* - * Calls the single Monitoring steps + * Calls the single Monitoring steps */ $this->_monitorEmailQuota(); $this->_monitorHDQuota(); @@ -117,6 +117,7 @@ class monitor_core_module { $this->_monitorRaid(); $this->_monitorRkHunter(); $this->_monitorFail2ban(); + $this->_monitorMongoDB(); $this->_monitorIPTables(); $this->_monitorSysLog(); } @@ -129,12 +130,12 @@ class monitor_core_module { */ $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 @@ class monitor_core_module { * 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'); @@ -554,6 +555,31 @@ class monitor_core_module { $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 + */ + $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 _monitorIPTables() { global $app; @@ -712,7 +738,7 @@ class monitor_core_module { * 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 @@ class monitor_core_module { // $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 @@ class monitor_core_module { } -?> \ No newline at end of file +?> diff --git a/server/mods-available/rescue_core_module.inc.php b/server/mods-available/rescue_core_module.inc.php index 49012d50a0..050d32fd3b 100644 --- a/server/mods-available/rescue_core_module.inc.php +++ b/server/mods-available/rescue_core_module.inc.php @@ -35,7 +35,7 @@ class rescue_core_module { /* 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 @@ class rescue_core_module { * 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 @@ class rescue_core_module { * 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 @@ class rescue_core_module { */ 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 @@ class rescue_core_module { } 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 @@ class rescue_core_module { 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 @@ class rescue_core_module { /* * 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 @@ class rescue_core_module { } else { $data = array(); } - + /* Thats it */ return $data; } @@ -222,14 +227,14 @@ class rescue_core_module { */ 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 @@ class rescue_core_module { $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 @@ class rescue_core_module { $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 @@ class rescue_core_module { $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 @@ class rescue_core_module { } 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 @@ class rescue_core_module { * 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.. */ diff --git a/server/plugins-available/backup_plugin.inc.php b/server/plugins-available/backup_plugin.inc.php index 78be959e6d..bc91a9186d 100644 --- a/server/plugins-available/backup_plugin.inc.php +++ b/server/plugins-available/backup_plugin.inc.php @@ -29,48 +29,48 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 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 @@ class backup_plugin { $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 @@ class backup_plugin { 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 @@ class backup_plugin { } } } - + } else { $app->log('No backup with ID '.$backup_id.' found.',LOGLEVEL_DEBUG); } - + return 'ok'; } diff --git a/server/plugins-available/mongo_clientdb_plugin.inc.php b/server/plugins-available/mongo_clientdb_plugin.inc.php new file mode 100644 index 0000000000..545fe9e4bd --- /dev/null +++ b/server/plugins-available/mongo_clientdb_plugin.inc.php @@ -0,0 +1,820 @@ +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(); + } + +} -- GitLab