From d22277878254cf33fd63ca1bf12b215f4e030a27 Mon Sep 17 00:00:00 2001
From: Marius Burkard <m.burkard@pixcept.de>
Date: Mon, 04 Jan 2016 05:12:49 -0500
Subject: [PATCH] - merged different fixes and updates from foreign branches

---
 server/conf/nginx_vhost.conf.master                           |   24 
 interface/web/admin/directive_snippets_list.php               |   45 +
 server/lib/classes/cronjob.inc.php                            |   31 +
 interface/web/themes/default/templates/sidenav.tpl.htm        |   11 
 install/tpl/server.ini.master                                 |    6 
 interface/web/admin/form/server_config.tform.php              |  104 ++++
 interface/web/admin/templates/server_config_server_edit.htm   |    6 
 server/conf/vhost.conf.master                                 |    1 
 interface/web/sites/templates/web_vhost_domain_edit.htm       |   69 ++
 install/lib/installer_base.lib.php                            |   78 +++
 install/sql/ispconfig3.sql                                    |    5 
 interface/web/sites/templates/web_vhost_domain_admin_list.htm |   10 
 server/plugins-available/apache2_plugin.inc.php               |   24 
 interface/web/admin/form/directive_snippets.tform.php         |    2 
 interface/web/admin/templates/directive_snippets_list.htm     |    9 
 interface/web/client/client_list.php                          |   20 
 interface/web/sites/form/database.tform.php                   |    2 
 server/plugins-available/nginx_plugin.inc.php                 |  132 ++++
 interface/lib/classes/listform.inc.php                        |   33 +
 interface/web/sites/form/web_vhost_domain.tform.php           |   18 
 interface/web/admin/directive_snippets_edit.php               |   53 +
 interface/web/sites/web_vhost_domain_edit.php                 |  268 +++++++++-
 server/conf/hhvm_starter.master                               |    2 
 interface/web/client/client_del.php                           |    4 
 interface/web/client/list/client.list.php                     |   11 
 server/plugins-available/shelluser_jailkit_plugin.inc.php     |   22 
 interface/web/sites/templates/web_vhost_domain_advanced.htm   |   10 
 interface/web/client/form/client.tform.php                    |   12 
 interface/web/admin/list/directive_snippets.list.php          |    9 
 interface/web/sites/ajax_get_json.php                         |   13 
 interface/web/client/templates/clients_list.htm               |   17 
 interface/web/sites/database_quota_stats.php                  |   67 +-
 interface/web/mail/templates/mail_domain_edit.htm             |    2 
 install/install.php                                           |   11 
 interface/web/admin/templates/directive_snippets_edit.htm     |   12 
 interface/lib/classes/remote.d/client.inc.php                 |   42 +
 interface/lib/classes/validate_password.inc.php               |    3 
 interface/lib/classes/tform_base.inc.php                      |    3 
 server/mods-available/web_module.inc.php                      |   24 
 interface/web/client/form/reseller.tform.php                  |   16 
 interface/lib/classes/functions.inc.php                       |  328 ++++++++++++
 41 files changed, 1,390 insertions(+), 169 deletions(-)

diff --git a/install/install.php b/install/install.php
index 0236820..cab7069 100644
--- a/install/install.php
+++ b/install/install.php
@@ -246,6 +246,8 @@
 
 if($install_mode == 'standard') {
 
+	$inst->dbmaster = $inst->db;
+	
 	//* Create the MySQL database
 	$inst->configure_database();
 
@@ -500,6 +502,9 @@
 		$inst->install_crontab();
 	} else swriteln('[ERROR] Cron not found');
 
+	swriteln('Detect IP addresses');
+	$inst->detect_ips();
+
 	swriteln('Restarting services ...');
 	if($conf['mysql']['installed'] == true && $conf['mysql']['init_script'] != '') system($inst->getinitcommand($conf['mysql']['init_script'], 'restart').' >/dev/null 2>&1');
 	if($conf['postfix']['installed'] == true && $conf['postfix']['init_script'] != '') system($inst->getinitcommand($conf['postfix']['init_script'], 'restart'));
@@ -696,6 +701,9 @@
 		swriteln('Configuring Pureftpd');
 		$inst->configure_pureftpd();
 	}
+	
+	swriteln('Detect IP addresses');
+	$inst->detect_ips();
 
 	//** Configure DNS
 	if(strtolower($inst->simple_query('Configure DNS Server', array('y', 'n'), 'y','configure_dns')) == 'y') {
@@ -866,6 +874,9 @@
 		if($conf['nginx']['php_fpm_init_script'] != '') system($inst->getinitcommand($conf['nginx']['php_fpm_init_script'], 'reload'));
 		if($conf['nginx']['init_script'] != '') system($inst->getinitcommand($conf['nginx']['init_script'], 'reload'));
 	}
+	
+	swriteln('Detect IP addresses');
+	$inst->detect_ips();
 
 
 
diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php
index db83e05..be878c1 100644
--- a/install/lib/installer_base.lib.php
+++ b/install/lib/installer_base.lib.php
@@ -371,6 +371,84 @@
 
 
 	}
+	
+	public function detect_ips(){
+		global $conf;
+
+		exec("ip addr show | awk '/global/ { print $2 }' | cut -d '/' -f 1", $output, $retval);
+		
+		if($retval == 0){
+			if(is_array($output) && !empty($output)){
+				foreach($output as $line){
+					$line = trim($line);
+					$ip_type = '';
+					if (filter_var($line, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
+						$ip_type = 'IPv4';
+					}
+					if (filter_var($line, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
+						$ip_type = 'IPv6';
+					}
+					if($ip_type == '') continue;
+					if($this->db->dbHost != $this->dbmaster->dbHost){
+						$this->dbmaster->query('INSERT INTO server_ip (
+							sys_userid, sys_groupid, sys_perm_user, sys_perm_group,
+							sys_perm_other, server_id, client_id, ip_type, ip_address,
+							virtualhost, virtualhost_port
+						) VALUES (
+							1,
+							1,
+							"riud",
+							"riud",
+							"",
+							' . $conf['server_id'] . ',
+							0,
+							"'.$ip_type.'",
+							"'.$line.'",
+							"y",
+							"80,443"
+						)');
+						$server_ip_id = $this->dbmaster->insertID();
+						$this->db->query('INSERT INTO server_ip (
+							server_php_id, sys_userid, sys_groupid, sys_perm_user, sys_perm_group,
+							sys_perm_other, server_id, client_id, ip_type, ip_address,
+							virtualhost, virtualhost_port
+						) VALUES (
+							'.$server_ip_id.',
+							1,
+							1,
+							"riud",
+							"riud",
+							"",
+							' . $conf['server_id'] . ',
+							0,
+							"'.$ip_type.'",
+							"'.$line.'",
+							"y",
+							"80,443"
+						)');
+					} else {
+						$this->db->query('INSERT INTO server_ip (
+							sys_userid, sys_groupid, sys_perm_user, sys_perm_group,
+							sys_perm_other, server_id, client_id, ip_type, ip_address,
+							virtualhost, virtualhost_port
+						) VALUES (
+							1,
+							1,
+							"riud",
+							"riud",
+							"",
+							' . $conf['server_id'] . ',
+							0,
+							"'.$ip_type.'",
+							"'.$line.'",
+							"y",
+							"80,443"
+						)');
+					}
+				}
+			}
+		}
+	}
 
 	public function grant_master_database_rights($verbose = false) {
 		global $conf;
diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql
index 1c56118..672f94b 100644
--- a/install/sql/ispconfig3.sql
+++ b/install/sql/ispconfig3.sql
@@ -257,6 +257,9 @@
   `customer_no_counter` int(11) NOT NULL DEFAULT '0',
   `added_date` date NOT NULL DEFAULT '0000-00-00',
   `added_by` varchar(255) DEFAULT NULL,
+  `validation_status` enum('accept','review','reject') NOT NULL DEFAULT 'accept',
+  `risk_score` int(10) unsigned NOT NULL DEFAULT '0',
+  `activation_code` varchar(10) NOT NULL DEFAULT '',
   PRIMARY KEY (`client_id`)
 ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
 
@@ -455,6 +458,7 @@
   `customer_viewable` ENUM('n','y') NOT NULL DEFAULT 'n',
   `required_php_snippets` varchar(255) NOT NULL DEFAULT '',
   `active` enum('n','y') NOT NULL DEFAULT 'y',
+  `master_directive_snippets_id` int(11) unsigned NOT NULL DEFAULT '0',
   PRIMARY KEY (`directive_snippets_id`)
 ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
 
@@ -1946,6 +1950,7 @@
   `enable_pagespeed` ENUM('y','n') NOT NULL DEFAULT 'n',
   `http_port` int(11) unsigned NOT NULL DEFAULT '80',
   `https_port` int(11) unsigned NOT NULL DEFAULT '443',
+  `folder_directive_snippets` text NOT NULL,
   PRIMARY KEY  (`domain_id`),
   UNIQUE KEY `serverdomain` (  `server_id` , `ip_address`,  `domain` )
 ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
diff --git a/install/tpl/server.ini.master b/install/tpl/server.ini.master
index 286dc07..1f7df52 100644
--- a/install/tpl/server.ini.master
+++ b/install/tpl/server.ini.master
@@ -18,6 +18,7 @@
 backup_dir=/var/backup
 backup_dir_is_mount=n
 backup_mode=rootgz
+backup_time=0:00
 backup_delete=n
 monit_url=
 monit_user=
@@ -46,7 +47,7 @@
 mailbox_size_limit=0
 message_size_limit=0
 mailbox_quota_stats=y
-realtime_blackhole_list=
+realtime_blackhole_list=zen.spamhaus.org
 overquota_notify_admin=y
 overquota_notify_client=y
 overquota_notify_freq=7
@@ -78,7 +79,6 @@
 apps_vhost_servername=
 php_open_basedir=[website_path]/web:[website_path]/private:[website_path]/tmp:/var/www/[website_domain]/web:/srv/www/[website_domain]/web:/usr/share/php5:/usr/share/php:/tmp:/usr/share/phpmyadmin:/etc/phpmyadmin:/var/lib/phpmyadmin
 htaccess_allow_override=All
-enable_spdy=y
 awstats_conf_dir=/etc/awstats
 awstats_data_dir=/var/lib/awstats
 awstats_pl=/usr/lib/cgi-bin/awstats.pl
@@ -131,7 +131,7 @@
 [jailkit]
 jailkit_chroot_home=/home/[username]
 jailkit_chroot_app_sections=basicshell editors extendedshell netutils ssh sftp scp groups jk_lsh
-jailkit_chroot_app_programs=/usr/bin/groups /usr/bin/id /usr/bin/dircolors /usr/bin/lesspipe /usr/bin/basename /usr/bin/dirname /usr/bin/nano /usr/bin/pico /usr/bin/mysql /usr/bin/mysqldump /usr/bin/git /usr/bin/git-receive-pack /usr/bin/git-upload-pack /usr/bin/unzip /usr/bin/zip /bin/tar /bin/rm /usr/bin/patch
+jailkit_chroot_app_programs=/usr/bin/groups /usr/bin/id /usr/bin/dircolors /usr/bin/lesspipe /usr/bin/basename /usr/bin/dirname /usr/bin/nano /usr/bin/pico /usr/bin/mysql /usr/bin/mysqldump /usr/bin/git /usr/bin/git-receive-pack /usr/bin/git-upload-pack /usr/bin/unzip /usr/bin/zip /bin/tar /bin/rm /usr/bin/patch /usr/bin/which /usr/lib/x86_64-linux-gnu/libmemcached.so.11 /usr/lib/x86_64-linux-gnu/libmemcachedutil.so.2 /usr/lib/x86_64-linux-gnu/libMagickWand-6.Q16.so.2 /opt/php-5.6.8/bin/php /opt/php-5.6.8/include /opt/php-5.6.8/lib
 jailkit_chroot_cron_programs=/usr/bin/php /usr/bin/perl /usr/share/perl /usr/share/php
 
 [vlogger]
diff --git a/interface/lib/classes/functions.inc.php b/interface/lib/classes/functions.inc.php
index 8ec4496..92f6f17 100644
--- a/interface/lib/classes/functions.inc.php
+++ b/interface/lib/classes/functions.inc.php
@@ -390,6 +390,334 @@
 			return getimagesizefromstring($string);
 		}		
 	}
+	
+	public function password($minLength = 10, $special = false){
+		global $app;
+	
+		$iteration = 0;
+		$password = "";
+		$maxLength = $minLength + 5;
+		$length = $this->getRandomInt($minLength, $maxLength);
+
+		while($iteration < $length){
+			$randomNumber = (floor(((mt_rand() / mt_getrandmax()) * 100)) % 94) + 33;
+			if(!$special){
+				if (($randomNumber >=33) && ($randomNumber <=47)) { continue; }
+				if (($randomNumber >=58) && ($randomNumber <=64)) { continue; }
+				if (($randomNumber >=91) && ($randomNumber <=96)) { continue; }
+				if (($randomNumber >=123) && ($randomNumber <=126)) { continue; }
+			}
+			$iteration++;
+			$password .= chr($randomNumber);
+		}
+		$app->uses('validate_password');
+		if($app->validate_password->password_check('', $password, '') !== false) $password = $this->password($minLength, $special);
+		return $password;
+	}
+
+	public function getRandomInt($min, $max){
+		return floor((mt_rand() / mt_getrandmax()) * ($max - $min + 1)) + $min;
+	}
+	
+	public function generate_customer_no(){
+		global $app;
+		// generate customer no.
+		$customer_no = mt_rand(100000, 999999);
+		while($app->db->queryOneRecord("SELECT client_id FROM client WHERE customer_no = '".$customer_no."'")){
+			$customer_no = mt_rand(100000, 999999);
+		}
+		
+		return $customer_no;
+	}
+	
+	public function generate_activation_code(){
+		
+		$activation_code = str_pad(mt_rand(0, 99999999), 8, '0', STR_PAD_LEFT);
+		
+		return $activation_code;
+	}
+	
+	public function client_activate($client_id){
+		global $app, $conf;
+		
+		if(!is_file(ISPC_WEB_PATH.'/robot/lib/robot_config.inc.php')) return false;
+		include(ISPC_WEB_PATH.'/robot/lib/robot_config.inc.php');
+		
+		$context = stream_context_create(array(
+			'ssl' => array(
+				'verify_peer'       => false,
+				'verify_peer_name'  => false,
+			)
+		));
+
+		$soap_client = new SoapClient(null, array('location' => $robot_conf['soap']['soap_location'],
+									'uri'      => $robot_conf['soap']['soap_uri'],
+									'trace' => 1,
+									'exceptions' => 1,
+									'stream_context' => $context));
+	
+	
+		try {
+			if($session_id = $soap_client->login($robot_conf['soap']['username'] , $robot_conf['soap']['password'])) {
+				//echo 'Logged successfull. Session ID:'.$session_id.'<br />';
+			}
+			$error = '';
+			$client_record = $soap_client->client_get($session_id, $client_id);
+					
+			$client_record['password'] = $this->password();
+			if(trim($client_record['customer_no']) == '') $client_record['customer_no'] = $this->generate_customer_no();
+			$client_record['username'] = 'c'.$client_record['customer_no'];
+			//die($client_record['customer_no']);
+			//$client_record['locked'] = 'n';
+			$client_record['canceled'] = 'n';
+			$soap_client->client_update($session_id, $client_id, 0, $client_record);
+		
+			$app->db->query("UPDATE client SET validation_status = 'accept', activation_code = '' WHERE client_id = ".$client_id);
+			
+			$activation_letter_filename = ISPC_ROOT_PATH.'/pdf/activation_letters/c'.$client_id.'-'.$client_record['activation_code'].'.pdf';
+			if(is_file($activation_letter_filename)) unlink($activation_letter_filename);
+		
+			$webdetails['ispconfiguser'] = $client_record['username'];
+			$webdetails['ispconfigpassword'] = $client_record['password'];
+			$webdetails['customer_no'] = $client_record['customer_no'];
+			$webdetails['contact'] = ($client_record['contact_firstname'] != ''? $client_record['contact_firstname'].' ' : '').$client_record['contact_name'];
+			$webdetails['salutation_de'] = ($client_record['gender'] == 'f'? 'Frau' : 'Herr');
+			$webdetails['salutation_en'] = ($client_record['gender'] == 'f'? 'Mrs.' : 'Mr.');
+			$webdetails['ispconfigurl'] = 'http'.($_SERVER['HTTPS'] == 'on'? 's' : '').'://'.$_SERVER['HTTP_HOST'];
+			$webdetails['signature_de'] = $robot_conf['textbaustein']['emailfooter'];
+			$webdetails['signature_en'] = $robot_conf['textbaustein_en']['emailfooter'];
+		
+			if($error == ''){
+				// send email with login details
+				$invoice_client_settings = $app->db->queryOneRecord("SELECT * FROM invoice_client_settings WHERE client_id = ".intval($client_id));
+				$company = $app->db->queryOneRecord("SELECT * FROM invoice_company WHERE invoice_company_id = ".$invoice_client_settings['invoice_company_id']);
+				
+				$subject = '['.$company['company_name_short'].'] Zugangsdaten zu unserem Kundeninterface / Login details for our customer interface';
+			
+				$app->uses('tpl');
+				$tpl = new tpl;
+				$tpl->newTemplate(ISPC_WEB_PATH."/client/templates/ispconfig_login.master");
+				$tpl->setVar($webdetails);
+				$message = $tpl->grab();
+			
+				if($robot_conf['production_mode']){
+					$app->functions->mail(trim($client_record['email']), $subject, $message, 'support@timmehosting.de', '', 'application/pdf', '', '', 'f.timme@timmehosting.de,hetzner@timmehosting.de', 'TimmeHosting.de Support');
+				
+					$app->db->query("INSERT INTO `th_robot_message` (`sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `client_id`, `subject`, `message`, `message_sent_date`, `message_sent_tstamp`, `email_from`, `email_to`, `email_to_bcc`) VALUES(1, 1, 'riud', 'riud', '', ".intval($client_id).", '".$app->db->quote($subject)."', '".$app->db->quote($message)."', '".date('Y-m-d')."', ".time().", 'support@timmehosting.de', '".trim($client_record['email'])."', 'f.timme@timmehosting.de,hetzner@timmehosting.de')");
+				}
+			}
+		
+			if($soap_client->logout($session_id)) {
+				//echo 'Logged out.<br />';
+			}
+
+		} catch (SoapFault $e) {
+			//$error .= $client->__getLastResponse();
+			$error .= 'SOAP Error: '.$e->getMessage();
+		}
+	}
+	
+	public function client_activation_failed($client){
+		global $app, $conf;
+		
+		if(!is_file(ISPC_WEB_PATH.'/robot/lib/robot_config.inc.php')) return false;
+		include(ISPC_WEB_PATH.'/robot/lib/robot_config.inc.php');
+		
+		$client_id = intval($client['client_id']);
+		$webdetails['contact'] = ($client['contact_firstname'] != ''? $client['contact_firstname'].' ' : '').$client['contact_name'];
+		$webdetails['salutation_de'] = ($client['gender'] == 'f'? 'Frau' : 'Herr');
+		$webdetails['salutation_en'] = ($client['gender'] == 'f'? 'Mrs.' : 'Mr.');
+		$webdetails['signature_de'] = $robot_conf['textbaustein']['emailfooter'];
+		$webdetails['signature_en'] = $robot_conf['textbaustein_en']['emailfooter'];
+		
+		
+		// send email with login details
+		$invoice_client_settings = $app->db->queryOneRecord("SELECT * FROM invoice_client_settings WHERE client_id = ".intval($client_id));
+		$company = $app->db->queryOneRecord("SELECT * FROM invoice_company WHERE invoice_company_id = ".$invoice_client_settings['invoice_company_id']);
+		$subject = '['.$company['company_name_short'].'] Aktivierung Ihres Kundenaccounts fehlgeschlagen / Activation of your customer account failed';
+			
+		$app->uses('tpl');
+		$tpl = new tpl;
+		$tpl->newTemplate(ISPC_WEB_PATH."/client/templates/ispconfig_client_activation_failed.master");
+		$tpl->setVar($webdetails);
+		$message = $tpl->grab();
+			
+		if($robot_conf['production_mode']){
+			$app->functions->mail(trim($client['email']), $subject, $message, 'support@timmehosting.de', '', 'application/pdf', '', '', 'f.timme@timmehosting.de,hetzner@timmehosting.de', 'TimmeHosting.de Support');
+				
+			$app->db->query("INSERT INTO `th_robot_message` (`sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `client_id`, `subject`, `message`, `message_sent_date`, `message_sent_tstamp`, `email_from`, `email_to`, `email_to_bcc`) VALUES(1, 1, 'riud', 'riud', '', ".intval($client_id).", '".$app->db->quote($subject)."', '".$app->db->quote($message)."', '".date('Y-m-d')."', ".time().", 'support@timmehosting.de', '".trim($client['email'])."', 'f.timme@timmehosting.de,hetzner@timmehosting.de')");
+		}
+	}
+	
+	public function client_review($client_id){
+		global $app, $conf;
+		
+		if(!is_file(ISPC_WEB_PATH.'/robot/lib/robot_config.inc.php')) return false;
+		include(ISPC_WEB_PATH.'/robot/lib/robot_config.inc.php');
+		
+		$context = stream_context_create(array(
+			'ssl' => array(
+				'verify_peer'       => false,
+				'verify_peer_name'  => false,
+			)
+		));
+
+		$soap_client = new SoapClient(null, array('location' => $robot_conf['soap']['soap_location'],
+									'uri'      => $robot_conf['soap']['soap_uri'],
+									'trace' => 1,
+									'exceptions' => 1,
+									'stream_context' => $context));
+									
+		try {
+			if($session_id = $soap_client->login($robot_conf['soap']['username'] , $robot_conf['soap']['password'])) {
+				//echo 'Logged successfull. Session ID:'.$session_id.'<br />';
+			}
+			$error = '';
+			$client_record = $soap_client->client_get($session_id, $client_id);
+					
+			if(trim($client_record['customer_no']) == ''){
+				$client_record['customer_no'] = $this->generate_customer_no();
+				$soap_client->client_update($session_id, $client_id, 0, $client_record);
+			}
+		
+			$activation_code = $this->generate_activation_code();
+			$app->db->query("UPDATE client SET activation_code = '".$activation_code."'".($client_record['validation_status'] != 'review'? ", validation_status = 'review'" : "")." WHERE client_id = ".$client_id);
+		
+			$webdetails['customer_no'] = $client_record['customer_no'];
+			$webdetails['contact'] = ($client_record['contact_firstname'] != ''? $client_record['contact_firstname'].' ' : '').$client_record['contact_name'];
+			$webdetails['salutation_de'] = ($client_record['gender'] == 'f'? 'Frau' : 'Herr');
+			$webdetails['salutation_en'] = ($client_record['gender'] == 'f'? 'Mrs.' : 'Mr.');
+			$webdetails['signature_de'] = $robot_conf['textbaustein']['emailfooter'];
+			$webdetails['signature_en'] = $robot_conf['textbaustein_en']['emailfooter'];
+			$webdetails['email'] = $client_record['email'];
+			include ISPC_LIB_PATH.'/lang/'.strtolower($client_record['language']).'.lng';
+			$webdetails['latest_activation_date'] = date($wb['conf_format_dateshort'], $client_record['created_at'] + 14 * 86400);
+		
+			if($error == ''){
+				// send email with login details
+				$invoice_client_settings = $app->db->queryOneRecord("SELECT * FROM invoice_client_settings WHERE client_id = ".intval($client_id));
+				$company = $app->db->queryOneRecord("SELECT * FROM invoice_company WHERE invoice_company_id = ".$invoice_client_settings['invoice_company_id']);
+				
+				$subject = '['.$company['company_name_short'].'] Aktivierung Ihres Kundenkontos / Activation of your customer account';
+				$webdetails['company_name_short'] = $company['company_name_short'];
+			
+				$app->uses('tpl');
+				$tpl = new tpl;
+				$tpl->newTemplate(ISPC_WEB_PATH."/client/templates/ispconfig_client_activation_email.master");
+				$tpl->setVar($webdetails);
+				$message = $tpl->grab();
+			
+				if($robot_conf['production_mode']){
+					$app->functions->mail(trim($client_record['email']), $subject, $message, 'support@timmehosting.de', '', 'application/pdf', '', '', 'f.timme@timmehosting.de,hetzner@timmehosting.de', 'TimmeHosting.de Support');
+				
+					$app->db->query("INSERT INTO `th_robot_message` (`sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `client_id`, `subject`, `message`, `message_sent_date`, `message_sent_tstamp`, `email_from`, `email_to`, `email_to_bcc`) VALUES(1, 1, 'riud', 'riud', '', ".intval($client_id).", '".$app->db->quote($subject)."', '".$app->db->quote($message)."', '".date('Y-m-d')."', ".time().", 'support@timmehosting.de', '".trim($client_record['email'])."', 'f.timme@timmehosting.de,hetzner@timmehosting.de')");
+				}
+			}
+		
+			// create activation letter pdf
+			$app->uses('pdf');
+			$app->pdf->AliasNbPages();
+			$app->pdf->createActivationLetter($client_id);
+
+			$pdf_content = $app->pdf->Output('doc.pdf', 'S');
+
+			$activation_letter_filename = ISPC_ROOT_PATH.'/pdf/activation_letters/c'.$client_id.'-'.$activation_code.'.pdf';
+			file_put_contents($activation_letter_filename, $pdf_content);
+		
+			if(is_file($activation_letter_filename)){
+				include(ISPC_WEB_PATH.'/billing/lib/onlinebrief24/Net/SFTP.php');
+				$sftp = new Net_SFTP('api.letterei-onlinebrief.de');
+				if (!$sftp->login($company['onlinebrief24_user'], $company['onlinebrief24_password'])) {
+					$error_msg = $app->lng('onlinebrief24_login_failed_txt');
+					$app->error($error_msg);
+				}
+				$upload_filename = ($company['onlinebrief24_print'] == 'coloured'? '1' : '0').'00'.($client_record['country'] == 'DE'? '1' : '0').'000000000-c'.$client_id.'-'.$activation_code.'.pdf';
+				//die($upload_filename);
+				$sftp->chdir('upload/api');
+				$sftp->put($upload_filename, $activation_letter_filename, NET_SFTP_LOCAL_FILE);
+			}
+		
+			if($soap_client->logout($session_id)) {
+				//echo 'Logged out.<br />';
+			}
+
+		} catch (SoapFault $e) {
+			//$error .= $client->__getLastResponse();
+			$error .= 'SOAP Error: '.$e->getMessage();
+		}
+	}
+	
+	public function client_reject($client_id){
+		global $app, $conf;
+		
+		if(!is_file(ISPC_WEB_PATH.'/robot/lib/robot_config.inc.php')) return false;
+		include(ISPC_WEB_PATH.'/robot/lib/robot_config.inc.php');
+		
+		$context = stream_context_create(array(
+			'ssl' => array(
+				'verify_peer'       => false,
+				'verify_peer_name'  => false,
+			)
+		));
+
+		$soap_client = new SoapClient(null, array('location' => $robot_conf['soap']['soap_location'],
+									'uri'      => $robot_conf['soap']['soap_uri'],
+									'trace' => 1,
+									'exceptions' => 1,
+									'stream_context' => $context));
+		
+		try {
+			if($session_id = $soap_client->login($robot_conf['soap']['username'] , $robot_conf['soap']['password'])) {
+				//echo 'Logged successfull. Session ID:'.$session_id.'<br />';
+			}
+			$error = '';
+			$client_record = $soap_client->client_get($session_id, $client_id);
+					
+			$client_record['locked'] = 'y';
+			$client_record['canceled'] = 'y';
+			$soap_client->client_update($session_id, $client_id, 0, $client_record);
+		
+			$app->db->query("UPDATE client SET validation_status = 'reject', activation_code = '' WHERE client_id = ".$client_id);
+			$app->db->query("DELETE FROM th_order WHERE client_id = ".$client_id);
+			
+			$activation_letter_filename = ISPC_ROOT_PATH.'/pdf/activation_letters/c'.$client_id.'-'.$client_record['activation_code'].'.pdf';
+			if(is_file($activation_letter_filename)) unlink($activation_letter_filename);
+		
+			$webdetails['contact'] = ($client_record['contact_firstname'] != ''? $client_record['contact_firstname'].' ' : '').$client_record['contact_name'];
+			$webdetails['salutation_de'] = ($client_record['gender'] == 'f'? 'Frau' : 'Herr');
+			$webdetails['salutation_en'] = ($client_record['gender'] == 'f'? 'Mrs.' : 'Mr.');
+			$webdetails['signature_de'] = $robot_conf['textbaustein']['emailfooter'];
+			$webdetails['signature_en'] = $robot_conf['textbaustein_en']['emailfooter'];
+		
+			if($error == ''){
+				// send email with login details
+				$invoice_client_settings = $app->db->queryOneRecord("SELECT * FROM invoice_client_settings WHERE client_id = ".intval($client_id));
+				$company = $app->db->queryOneRecord("SELECT * FROM invoice_company WHERE invoice_company_id = ".$invoice_client_settings['invoice_company_id']);
+				
+				$subject = '['.$company['company_name_short'].'] Sperrung Ihres Kundenaccounts / Suspension of your customer account';
+			
+				$app->uses('tpl');
+				$tpl = new tpl;
+				$tpl->newTemplate(ISPC_WEB_PATH."/client/templates/ispconfig_client_rejection.master");
+				$tpl->setVar($webdetails);
+				$message = $tpl->grab();
+			
+				if($robot_conf['production_mode']){
+					$app->functions->mail(trim($client_record['email']), $subject, $message, 'support@timmehosting.de', '', 'application/pdf', '', '', 'f.timme@timmehosting.de,hetzner@timmehosting.de', 'TimmeHosting.de Support');
+				
+					$app->db->query("INSERT INTO `th_robot_message` (`sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `client_id`, `subject`, `message`, `message_sent_date`, `message_sent_tstamp`, `email_from`, `email_to`, `email_to_bcc`) VALUES(1, 1, 'riud', 'riud', '', ".intval($client_id).", '".$app->db->quote($subject)."', '".$app->db->quote($message)."', '".date('Y-m-d')."', ".time().", 'support@timmehosting.de', '".trim($client_record['email'])."', 'f.timme@timmehosting.de,hetzner@timmehosting.de')");
+				}
+			}
+		
+			if($soap_client->logout($session_id)) {
+				//echo 'Logged out.<br />';
+			}
+
+		} catch (SoapFault $e) {
+			//$error .= $client->__getLastResponse();
+			$error .= 'SOAP Error: '.$e->getMessage();
+		}
+	}
 
 }
 
diff --git a/interface/lib/classes/listform.inc.php b/interface/lib/classes/listform.inc.php
index d4ed752..120e652 100644
--- a/interface/lib/classes/listform.inc.php
+++ b/interface/lib/classes/listform.inc.php
@@ -257,10 +257,23 @@
 						$searchval = $year.'-'.$month.'-'.$day;
 					}
 				}
+				
+				if($i['datatype'] == 'BOOLEAN' && $searchval != ''){
+					if (!function_exists('boolval')) {
+						$searchval = (bool) $searchval;
+						if($searchval === true){
+							$searchval = 'TRUE';
+						} else {
+							$searchval = 'FALSE';
+						}
+					} else {
+						$searchval = boolval($searchval)? 'TRUE' : 'FALSE';
+					}
+				}
 
 				// if($_REQUEST[$search_prefix.$field] != '') $sql_where .= " $field ".$i["op"]." '".$i["prefix"].$_REQUEST[$search_prefix.$field].$i["suffix"]."' and";
 				if(isset($searchval) && $searchval != ''){
-					$sql_where .= " ".($table != ''? $table.'.' : $this->listDef['table'].'.')."$field ".$i['op']." '".$app->db->quote($i['prefix'].$searchval.$i['suffix'])."' and";
+					$sql_where .= " ".($table != ''? $table.'.' : $this->listDef['table'].'.')."$field ".$i['op']." ".($i['datatype'] == 'BOOLEAN'? "" : "'").$app->db->quote($i['prefix'].$searchval.$i['suffix']).($i['datatype'] == 'BOOLEAN'? "" : "'")." and";
 				}
 			}
 		}
@@ -384,7 +397,7 @@
 		if(isset($vars['show_page_back']) && $vars['show_page_back'] == 1){
 			$content .= '<li><a href="#" data-load-content="'.$vars['list_file'].'?page=0'.$vars['page_params'].'" aria-label="First">
 			<span aria-hidden="true">&laquo;</span></a></li>';
-			$content .= '<li><a href="#" data-load-content='.$vars['list_file'].'?page='.$vars['last_page'].$vars['page_params'].'" aria-label="Previous">
+			$content .= '<li><a href="#" data-load-content="'.$vars['list_file'].'?page='.$vars['last_page'].$vars['page_params'].'" aria-label="Previous">
 			<span aria-hidden="true">&lsaquo;</span></a></li>';
 		}
 		$prev = -1;
@@ -501,6 +514,14 @@
 					case 'CURRENCY':
 						$record[$key] = $app->functions->currency_format($record[$key]);
 						break;
+						
+					case 'BOOLEAN':
+						if (!function_exists('boolval')) {
+							$record[$key] = (bool) $record[$key];
+						} else {
+							$record[$key] = boolval($record[$key]);
+						}
+						break;
 
 					default:
 						$record[$key] = htmlentities(stripslashes($record[$key]), ENT_QUOTES, $conf["html_content_encoding"]);
@@ -564,6 +585,14 @@
 				case 'CURRENCY':
 					$record[$key] = str_replace(',', '.', $record[$key]);
 					break;
+				
+				case 'BOOLEAN':
+					if (!function_exists('boolval')) {
+						$record[$key] = (bool) $record[$key];
+					} else {
+						$record[$key] = boolval($record[$key]);
+					}
+					break;
 				}
 			}
 		}
diff --git a/interface/lib/classes/remote.d/client.inc.php b/interface/lib/classes/remote.d/client.inc.php
index cccc04f..e44fd82 100644
--- a/interface/lib/classes/remote.d/client.inc.php
+++ b/interface/lib/classes/remote.d/client.inc.php
@@ -526,22 +526,24 @@
 	 * @param int  client id
 	 * @param string new password
 	 * @return bool true if success
-	 * @author Julio Montoya <gugli100@gmail.com> BeezNest 2010
 	 *
 	 */
 	public function client_change_password($session_id, $client_id, $new_password) {
 		global $app;
 
+		$app->uses('auth');
+
 		if(!$this->checkPerm($session_id, 'client_change_password')) {
 			throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.');
 			return false;
 		}
-		$client_id = $app->functions->intval($client_id);
+
 		$client = $app->db->queryOneRecord("SELECT client_id FROM client WHERE client_id = ?", $client_id);
 		if($client['client_id'] > 0) {
-			$sql = "UPDATE client SET password = md5(?) 	WHERE client_id = ?";
+			$new_password = $app->auth->crypt_password($new_password);
+			$sql = "UPDATE client SET password = ? 	WHERE client_id = ?";
 			$app->db->query($sql, $new_password, $client_id);
-			$sql = "UPDATE sys_user SET passwort = md5(?) 	WHERE client_id = ?";
+			$sql = "UPDATE sys_user SET passwort = ? 	WHERE client_id = ?";
 			$app->db->query($sql, $new_password, $client_id);
 			return true;
 		} else {
@@ -681,6 +683,38 @@
 		
 		return $returnval;
 	}
+	
+	public function client_activate($session_id, $params){
+		global $app;
+		/*
+		if (!$this->checkPerm($session_id, 'client_update')){
+			throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.');
+			return false;
+		}
+		*/
+		
+		if(!is_file(ISPC_WEB_PATH.'/robot/lib/robot_config.inc.php')){
+			throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.');
+			return false;
+		}
+		
+		$client = $app->db->queryOneRecord("SELECT * FROM client WHERE customer_no = '".$app->db->quote($params['customer_no'])."' AND email = '".$app->db->quote($params['email'])."' AND activation_code = '".$app->db->quote($params['activation_code'])."' AND validation_status = 'review'");
+		//file_put_contents('/tmp/test.txt', "SELECT * FROM client WHERE customer_no = '".$app->db->quote($params['customer_no'])."' AND email = '".$app->db->quote($params['email'])."' AND activation_code = '".$app->db->quote($params['activation_code'])."' AND validation_status = 'review'");
+		
+		if(is_array($client) && !empty($client)){
+			$client_id = intval($client['client_id']);
+			
+			$app->functions->client_activate($client_id);
+	
+			return true;
+		} else {
+			$client = $app->db->queryOneRecord("SELECT * FROM client WHERE email = '".$app->db->quote($params['email'])."' AND validation_status = 'review'");
+			if(is_array($client) && !empty($client)){
+				$app->functions->client_activation_failed($client);
+			}
+			return false;
+		}
+	}
 
 }
 
diff --git a/interface/lib/classes/tform_base.inc.php b/interface/lib/classes/tform_base.inc.php
index 2e53d27..87e7a68 100644
--- a/interface/lib/classes/tform_base.inc.php
+++ b/interface/lib/classes/tform_base.inc.php
@@ -878,6 +878,9 @@
 				case 'TRIM':
 					$returnval = trim($returnval);
 					break;
+				case 'NOWHITESPACE':
+					$returnval = preg_replace('/\s+/', '', $returnval);
+					break;
 				default:
 					$this->errorMessage .= "Unknown Filter: ".$filter['type'];
 					break;
diff --git a/interface/lib/classes/validate_password.inc.php b/interface/lib/classes/validate_password.inc.php
index da044c6..f36f162 100644
--- a/interface/lib/classes/validate_password.inc.php
+++ b/interface/lib/classes/validate_password.inc.php
@@ -33,6 +33,7 @@
 	
 	private function _get_password_strength($password) {
 		$length = strlen($password);
+		
 		$points = 0;
 		if ($length < 5) {
 			return 1;
@@ -53,7 +54,7 @@
 			$different += 1;
 		}
 
-		if (preg_match('/[`~!@#$%^&*()_+|\\=-\[\]}{\';:\/?.>,<" ]/', $password)) {
+		if (preg_match('/[`~!@#$%^&*()_+|\\=\-\[\]}{\';:\/?.>,<" ]/', $password)) {
 			$points += 1;
 			$different += 1;
 		}
diff --git a/interface/web/admin/directive_snippets_edit.php b/interface/web/admin/directive_snippets_edit.php
index 06cea79..f5c48af 100644
--- a/interface/web/admin/directive_snippets_edit.php
+++ b/interface/web/admin/directive_snippets_edit.php
@@ -47,7 +47,56 @@
 // Loading classes
 $app->uses('tpl,tform,tform_actions');
 
-// let tform_actions handle the page
-$app->tform_actions->onLoad();
+class page_action extends tform_actions {
+
+	function onShow() {
+		global $app, $conf;
+		
+		if($this->id > 0){
+			$record = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ".intval($this->id));
+			if($record['master_directive_snippets_id'] > 0){
+				unset($app->tform->formDef["tabs"]['directive_snippets']['fields']['name'], $app->tform->formDef["tabs"]['directive_snippets']['fields']['type'], $app->tform->formDef["tabs"]['directive_snippets']['fields']['snippet'], $app->tform->formDef["tabs"]['directive_snippets']['fields']['required_php_snippets']);
+			}
+			unset($record);
+		}
+		
+		parent::onShow();
+	}
+	
+	function onShowEnd() {
+		global $app, $conf;
+		
+		$is_master = false;
+		if($this->id > 0){
+			if($this->dataRecord['master_directive_snippets_id'] > 0){
+				$is_master = true;
+				$app->tpl->setVar("name", $this->dataRecord['name']);
+				$app->tpl->setVar("type", $this->dataRecord['type']);
+				$app->tpl->setVar("snippet", $this->dataRecord['snippet']);
+			}
+		}
+		$app->tpl->setVar("is_master", $is_master);
+		
+		parent::onShowEnd();
+	}
+	
+	function onSubmit() {
+		global $app, $conf;
+		
+		if($this->id > 0){
+			$record = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ".intval($this->id));
+			if($record['master_directive_snippets_id'] > 0){
+				unset($app->tform->formDef["tabs"]['directive_snippets']['fields']['name'], $app->tform->formDef["tabs"]['directive_snippets']['fields']['type'], $app->tform->formDef["tabs"]['directive_snippets']['fields']['snippet'], $app->tform->formDef["tabs"]['directive_snippets']['fields']['required_php_snippets']);
+			}
+			unset($record);
+		}
+		
+		parent::onSubmit();
+	}
+	
+}
+
+$page = new page_action;
+$page->onLoad();
 
 ?>
diff --git a/interface/web/admin/directive_snippets_list.php b/interface/web/admin/directive_snippets_list.php
index 5fb75c7..1376ef0 100644
--- a/interface/web/admin/directive_snippets_list.php
+++ b/interface/web/admin/directive_snippets_list.php
@@ -46,7 +46,48 @@
 
 $app->uses('listform_actions');
 
+class list_action extends listform_actions {
+
+	public function prepareDataRow($rec)
+	{
+		global $app;
+
+		$rec = $app->listform->decode($rec);
+
+		//* Alternating datarow colors
+		$this->DataRowColor = ($this->DataRowColor == '#FFFFFF') ? '#EEEEEE' : '#FFFFFF';
+		$rec['bgcolor'] = $this->DataRowColor;
+		
+		$rec['is_master'] = $rec['master_directive_snippets_id'];
+
+		//* substitute value for select fields
+		if(is_array($app->listform->listDef['item']) && count($app->listform->listDef['item']) > 0) {
+			foreach($app->listform->listDef['item'] as $field) {
+				$key = $field['field'];
+				if(isset($field['formtype']) && $field['formtype'] == 'SELECT') {
+					if(strtolower($rec[$key]) == 'y' or strtolower($rec[$key]) == 'n') {
+						// Set a additional image variable for bolean fields
+						$rec['_'.$key.'_'] = (strtolower($rec[$key]) == 'y')?'x16/tick_circle.png':'x16/cross_circle.png';
+					}
+					//* substitute value for select field
+					$rec[$key] = @$field['value'][$rec[$key]];
+				}
+			}
+		}
+
+		//* The variable "id" contains always the index variable
+		$rec['id'] = $rec[$this->idx_key];
+		return $rec;
+	}
+	
+}
+$list = new list_action;
+$list->SQLOrderBy = 'ORDER BY directive_snippets.name';
+$list->onLoad();
+
+//$app->listform_actions->SQLExtWhere = 'master_directive_snippets_id = 0';
+/*
+$app->listform_actions->SQLOrderBy = 'ORDER BY directive_snippets.name';
 $app->listform_actions->onLoad();
-
-
+*/
 ?>
diff --git a/interface/web/admin/form/directive_snippets.tform.php b/interface/web/admin/form/directive_snippets.tform.php
index 0c2502c..4d34fef 100644
--- a/interface/web/admin/form/directive_snippets.tform.php
+++ b/interface/web/admin/form/directive_snippets.tform.php
@@ -110,7 +110,7 @@
 			'formtype' => 'CHECKBOXARRAY',
 			'default' => '',
 			'datasource' => array (  'type' => 'SQL',
-				'querystring' => "SELECT directive_snippets_id,name FROM directive_snippets WHERE type = 'php' AND active = 'y'ORDER BY name",
+				'querystring' => "SELECT directive_snippets_id,name FROM directive_snippets WHERE type = 'php' AND active = 'y' AND master_directive_snippets_id = 0 ORDER BY name",
 				'keyfield' => 'directive_snippets_id',
 				'valuefield' => 'name'
 			),
diff --git a/interface/web/admin/form/server_config.tform.php b/interface/web/admin/form/server_config.tform.php
index adc55b1..7e37550 100644
--- a/interface/web/admin/form/server_config.tform.php
+++ b/interface/web/admin/form/server_config.tform.php
@@ -191,6 +191,110 @@
 			'width' => '40',
 			'maxlength' => '255'
 		),
+		'backup_time' => array(
+			'datatype' => 'VARCHAR',
+			'formtype' => 'SELECT',
+			'default' => '0:00',
+			'value' => array(	'0:00' => '0:00h',
+								'0:15' => '0:15h',
+								'0:30' => '0:30h',
+								'0:45' => '0:45h',
+								'1:00' => '1:00h',
+								'1:15' => '1:15h',
+								'1:30' => '1:30h',
+								'1:45' => '1:45h',
+								'2:00' => '2:00h',
+								'2:15' => '2:15h',
+								'2:30' => '2:30h',
+								'2:45' => '2:45h',
+								'3:00' => '3:00h',
+								'3:15' => '3:15h',
+								'3:30' => '3:30h',
+								'3:45' => '3:45h',
+								'4:00' => '4:00h',
+								'4:15' => '4:15h',
+								'4:30' => '4:30h',
+								'4:45' => '4:45h',
+								'5:00' => '5:00h',
+								'5:15' => '5:15h',
+								'5:30' => '5:30h',
+								'5:45' => '5:45h',
+								'6:00' => '6:00h',
+								'6:15' => '6:15h',
+								'6:30' => '6:30h',
+								'6:45' => '6:45h',
+								'7:00' => '7:00h',
+								'7:15' => '7:15h',
+								'7:30' => '7:30h',
+								'7:45' => '7:45h',
+								'8:00' => '8:00h',
+								'8:15' => '8:15h',
+								'8:30' => '8:30h',
+								'8:45' => '8:45h',
+								'9:00' => '9:00h',
+								'9:15' => '9:15h',
+								'9:30' => '9:30h',
+								'9:45' => '9:45h',
+								'10:00' => '10:00h',
+								'10:15' => '10:15h',
+								'10:30' => '10:30h',
+								'10:45' => '10:45h',
+								'11:00' => '11:00h',
+								'11:15' => '11:15h',
+								'11:30' => '11:30h',
+								'11:45' => '11:45h',
+								'12:00' => '12:00h',
+								'12:15' => '12:15h',
+								'12:30' => '12:30h',
+								'12:45' => '12:45h',
+								'13:00' => '13:00h',
+								'13:15' => '13:15h',
+								'13:30' => '13:30h',
+								'13:45' => '13:45h',
+								'14:00' => '14:00h',
+								'14:15' => '14:15h',
+								'14:30' => '14:30h',
+								'14:45' => '14:45h',
+								'15:00' => '15:00h',
+								'15:15' => '15:15h',
+								'15:30' => '15:30h',
+								'15:45' => '15:45h',
+								'16:00' => '16:00h',
+								'16:15' => '16:15h',
+								'16:30' => '16:30h',
+								'16:45' => '16:45h',
+								'17:00' => '17:00h',
+								'17:15' => '17:15h',
+								'17:30' => '17:30h',
+								'17:45' => '17:45h',
+								'18:00' => '18:00h',
+								'18:15' => '18:15h',
+								'18:30' => '18:30h',
+								'18:45' => '18:45h',
+								'19:00' => '19:00h',
+								'19:15' => '19:15h',
+								'19:30' => '19:30h',
+								'19:45' => '19:45h',
+								'20:00' => '20:00h',
+								'20:15' => '20:15h',
+								'20:30' => '20:30h',
+								'20:45' => '20:45h',
+								'21:00' => '21:00h',
+								'21:15' => '21:15h',
+								'21:30' => '21:30h',
+								'21:45' => '21:45h',
+								'22:00' => '22:00h',
+								'22:15' => '22:15h',
+								'22:30' => '22:30h',
+								'22:45' => '22:45h',
+								'23:00' => '23:00h',
+								'23:15' => '23:15h',
+								'23:30' => '23:30h',
+								'23:45' => '23:45h',
+								),
+			'width' => '40',
+			'maxlength' => '255'
+		),
 		'backup_delete' => array(
 			'datatype' => 'VARCHAR',
 			'formtype' => 'CHECKBOX',
diff --git a/interface/web/admin/list/directive_snippets.list.php b/interface/web/admin/list/directive_snippets.list.php
index 078cebf..c41bcd5 100644
--- a/interface/web/admin/list/directive_snippets.list.php
+++ b/interface/web/admin/list/directive_snippets.list.php
@@ -83,5 +83,14 @@
 	'suffix' => "",
 	'width'  => "",
 	'value'  => array('y' => "<div id=\"ir-Yes\" class=\"swap\"><span>".$app->lng('yes_txt')."</span></div>", 'n' => "<div class=\"swap\" id=\"ir-No\"><span>".$app->lng('no_txt')."</span></div>"));
+	
+$liste["item"][] = array( 'field'  => "master_directive_snippets_id",
+	'datatype' => "BOOLEAN",
+	'formtype' => "SELECT",
+	'op'  => "IS",
+	'prefix' => "",
+	'suffix' => "",
+	'width'  => "",
+	'value'  => array(0 => $app->lng('select_directive_snippet_txt'), 1 => $app->lng('select_master_directive_snippet_txt')));
 
 ?>
diff --git a/interface/web/admin/templates/directive_snippets_edit.htm b/interface/web/admin/templates/directive_snippets_edit.htm
index 054c5bc..b5adc58 100644
--- a/interface/web/admin/templates/directive_snippets_edit.htm
+++ b/interface/web/admin/templates/directive_snippets_edit.htm
@@ -7,23 +7,27 @@
         
             <div class="form-group">
                 <label for="name" class="col-sm-3 control-label">{tmpl_var name='name_txt'}</label>
-                <div class="col-sm-9"><input type="text" name="name" id="name" value="{tmpl_var name='name'}" class="form-control" /></div></div>
+                <tmpl_if name='is_master'><div class="col-sm-9 col-text">{tmpl_var name='name'}</div></tmpl_else><div class="col-sm-9"><input type="text" name="name" id="name" value="{tmpl_var name='name'}" class="form-control" /></div></tmpl_if>
+            </div>
 			<div class="form-group">
                 <label for="type" class="col-sm-3 control-label">{tmpl_var name='type_txt'}</label>
-                <div class="col-sm-9"><select name="type" id="type" class="form-control">
+                <tmpl_if name='is_master'><div class="col-sm-9 col-text">{tmpl_var name='type'}</div></tmpl_else><div class="col-sm-9"><select name="type" id="type" class="form-control">
                     {tmpl_var name='type'}
-                </select></div>
+                </select></div></tmpl_if>
             </div>
 			<div class="form-group">
                 <label for="snippet" class="col-sm-3 control-label">{tmpl_var name='snippet_txt'}</label>
-                <div class="col-sm-9"><textarea class="form-control" name="snippet" id="snippet" rows='10' cols='50'>{tmpl_var name='snippet'}</textarea></div><span> &nbsp; {tmpl_var name='variables_txt'}: </span><a href="javascript:void(0);" class="addPlaceholder">{DOCROOT}</a>, <a href="javascript:void(0);" class="addPlaceholder">{DOCROOT_CLIENT}</a><span class="nginx">, </span><a href="javascript:void(0);" class="addPlaceholder nginx">{FASTCGIPASS}</a>
+                <tmpl_if name='is_master'><div class="col-sm-9 col-text"><pre>{tmpl_var name='snippet'}</pre></div></tmpl_else><div class="col-sm-9"><textarea class="form-control" name="snippet" id="snippet" rows='10' cols='50'>{tmpl_var name='snippet'}</textarea></div>
+                <div class="col-sm-3 col-text nginx"></div><div class="col-sm-9 col-text nginx"> &nbsp;{tmpl_var name='variables_txt'}: <a href="javascript:void(0);" class="addPlaceholder">{DOCROOT}</a>, <a href="javascript:void(0);" class="addPlaceholder">{FASTCGIPASS}</a>, <a href="javascript:void(0);" class="addPlaceholder">{PHPFALLBACKFASTCGIPASS}</a></div></tmpl_if>
             </div>
+            <tmpl_if name='is_master'></tmpl_else>
 			<div class="form-group php">
                 <label class="col-sm-3 control-label">{tmpl_var name='required_php_snippets_txt'}</label>
                 <div class="col-sm-9">
                     {tmpl_var name='required_php_snippets'}
                 </div>
             </div>
+            </tmpl_if>
 			<div class="form-group">
                 <label class="col-sm-3 control-label">{tmpl_var name='customer_viewable_txt'}</label>
                 <div class="col-sm-9">
diff --git a/interface/web/admin/templates/directive_snippets_list.htm b/interface/web/admin/templates/directive_snippets_list.htm
index bf43d42..602c71a 100644
--- a/interface/web/admin/templates/directive_snippets_list.htm
+++ b/interface/web/admin/templates/directive_snippets_list.htm
@@ -17,6 +17,7 @@
                         <th data-column="name"><tmpl_var name="name_txt"></th>
                         <th data-column="type"><tmpl_var name="type_txt"></th>
 						<th data-column="customer_viewable"><tmpl_var name="customer_viewable_txt"></th>
+						<th data-column="master_directive_snippets_id"><tmpl_var name="master_directive_snippets_id_txt"></th>
                         <th class="small-col text-right">{tmpl_var name='search_limit'}</th>
                     </tr>
                     <tr>
@@ -24,6 +25,7 @@
                         <td><input class="form-control" type="text" name="search_name" value="{tmpl_var name='search_name'}" /></td>
                         <td><select class="form-control" name="search_type">{tmpl_var name='search_type'}</select></td>
 						<td><select class="form-control" name="search_customer_viewable">{tmpl_var name='search_customer_viewable'}</select></td>
+						<td><select class="form-control" name="search_master_directive_snippets_id">{tmpl_var name='search_master_directive_snippets_id'}</select></td>
                         <td class="text-right">
                             <button type="button" class="btn btn-default formbutton-default formbutton-narrow" name="Filter" id="Filter" value="{tmpl_var name="filter_txt"}" data-submit-form="pageForm" data-form-action="admin/directive_snippets_list.php"><span class="icon icon-filter"></span></button>
                         </td>
@@ -36,21 +38,22 @@
                             <td><a href="#" data-load-content="admin/directive_snippets_edit.php?id={tmpl_var name='id'}">{tmpl_var name="name"}</a></td>
                             <td><a href="#" data-load-content="admin/directive_snippets_edit.php?id={tmpl_var name='id'}">{tmpl_var name="type"}</a></td>
 							<td><a href="#" data-load-content="admin/directive_snippets_edit.php?id={tmpl_var name='id'}">{tmpl_var name="customer_viewable"}</a></td>
+							<td><a href="#" data-load-content="admin/directive_snippets_edit.php?id={tmpl_var name='id'}">{tmpl_var name="master_directive_snippets_id"}</a></td>
                             <td class="text-right">
-                                <a class="btn btn-default formbutton-danger formbutton-narrow" href="javascript: ISPConfig.confirm_action('admin/directive_snippets_del.php?id={tmpl_var name='id'}&phpsessid={tmpl_var name='phpsessid'}','{tmpl_var name='delete_confirmation'}');"><span class="icon icon-delete"></span></a>
+                                <tmpl_if name='is_master'></tmpl_else><a class="btn btn-default formbutton-danger formbutton-narrow" href="javascript: ISPConfig.confirm_action('admin/directive_snippets_del.php?id={tmpl_var name='id'}&phpsessid={tmpl_var name='phpsessid'}','{tmpl_var name='delete_confirmation'}');"><span class="icon icon-delete"></span></a></tmpl_if>
                             </td>
                         </tr>
                     </tmpl_loop>
                     <tmpl_unless name="records">
                         <tr class="tbl_row_noresults tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>">
-                            <td colspan="5">{tmpl_var name='globalsearch_noresults_text_txt'}</td>
+                            <td colspan="6">{tmpl_var name='globalsearch_noresults_text_txt'}</td>
                         </tr>
                     </tmpl_unless>
                 </tbody>
 
                 <tfoot>
                     <tr>
-                    <td colspan="5"><tmpl_var name="paging"></td>
+                    <td colspan="6"><tmpl_var name="paging"></td>
                     </tr>
                 </tfoot>
             </table>
diff --git a/interface/web/admin/templates/server_config_server_edit.htm b/interface/web/admin/templates/server_config_server_edit.htm
index 5de8154..d8724fc 100644
--- a/interface/web/admin/templates/server_config_server_edit.htm
+++ b/interface/web/admin/templates/server_config_server_edit.htm
@@ -63,6 +63,12 @@
                     {tmpl_var name='backup_mode'}
                 </select></div>
             </div>
+			<div class="form-group">
+                <label for="backup_time" class="col-sm-3 control-label">{tmpl_var name='backup_time_txt'}</label>
+                <div class="col-sm-3"><select name="backup_time" id="backup_time" class="form-control">
+                    {tmpl_var name='backup_time'}
+                </select></div>
+            </div>
             <div class="form-group">
                 <label class="col-sm-3 control-label">{tmpl_var name='backup_delete_txt'}</label>
                 <div class="col-sm-9">
diff --git a/interface/web/client/client_del.php b/interface/web/client/client_del.php
index 3e0d6bc..4344118 100644
--- a/interface/web/client/client_del.php
+++ b/interface/web/client/client_del.php
@@ -162,8 +162,8 @@
 				}
 			}
 
-
-
+			$activation_letter_filename = ISPC_ROOT_PATH.'/pdf/activation_letters/c'.$client_id.'-'.$this->dataRecord['activation_code'].'.pdf';
+			if(is_file($activation_letter_filename)) unlink($activation_letter_filename);
 		}
 
 	}
diff --git a/interface/web/client/client_list.php b/interface/web/client/client_list.php
index 43cc028..b5f2ed0 100644
--- a/interface/web/client/client_list.php
+++ b/interface/web/client/client_list.php
@@ -17,10 +17,22 @@
 
 $app->uses('listform_actions');
 
-$app->listform_actions->SQLOrderBy = 'ORDER BY client.company_name, client.contact_name, client.client_id';
-$app->listform_actions->SQLExtWhere = "client.limit_client = 0";
-$app->listform_actions->SQLExtSelect = ', LOWER(client.country) as countryiso';
-$app->listform_actions->onLoad();
+class list_action extends listform_actions {
+	function onShow() {
+		global $app;
+		
+		if(is_file(ISPC_WEB_PATH.'/robot/lib/robot_config.inc.php')){
+			$app->tpl->setVar('has_robot', true);
+		}
+		
+		parent::onShow();
+	}
 
+}
 
+$list = new list_action;
+$list->SQLOrderBy = 'ORDER BY client.company_name, client.contact_name, client.client_id';
+$list->SQLExtWhere = "client.limit_client = 0";
+$list->SQLExtSelect = ', LOWER(client.country) as countryiso';
+$list->onLoad();
 ?>
diff --git a/interface/web/client/form/client.tform.php b/interface/web/client/form/client.tform.php
index eab4e02..88d6872 100644
--- a/interface/web/client/form/client.tform.php
+++ b/interface/web/client/form/client.tform.php
@@ -385,7 +385,9 @@
 			'filters'   => array( 0 => array( 	'event' => 'SAVE',
 												'type' => 'TRIM'),
 								1 => array( 	'event' => 'SAVE',
-												'type' => 'TOUPPER')
+												'type' => 'TOUPPER'),
+								2 => array( 	'event' => 'SAVE',
+												'type' => 'NOWHITESPACE')
 			),
 		),
 		'company_id' => array (
@@ -456,7 +458,9 @@
 			'filters'   => array( 0 => array( 	'event' => 'SAVE',
 												'type' => 'TRIM'),
 								1 => array( 	'event' => 'SAVE',
-												'type' => 'TOUPPER')
+												'type' => 'TOUPPER'),
+								2 => array( 	'event' => 'SAVE',
+												'type' => 'NOWHITESPACE')
 			),
 		),
 		'bank_account_swift' => array (
@@ -472,7 +476,9 @@
 			'filters'   => array( 0 => array( 	'event' => 'SAVE',
 												'type' => 'TRIM'),
 								1 => array( 	'event' => 'SAVE',
-												'type' => 'TOUPPER')
+												'type' => 'TOUPPER'),
+								2 => array( 	'event' => 'SAVE',
+												'type' => 'NOWHITESPACE')
 			),
 		),
 		'notes' => array (
diff --git a/interface/web/client/form/reseller.tform.php b/interface/web/client/form/reseller.tform.php
index a858643..1a8b303 100644
--- a/interface/web/client/form/reseller.tform.php
+++ b/interface/web/client/form/reseller.tform.php
@@ -334,6 +334,10 @@
 				1 => array ( 'type' => 'NOTEMPTY',
 					'errmsg'=> 'email_error_empty'),
 			),
+			'validators' => array (  0 => array ( 'type' => 'REGEX',
+					'regex' => '/^\w+[\w\.\-\+]*\w{0,}@\w+[\w.-]*\.[a-z\-]{2,10}$/i',
+					'errmsg'=> 'email_error_isemail'),
+			),
 			'default' => '',
 			'value'  => '',
 			'separator' => '',
@@ -384,7 +388,9 @@
 			'filters'   => array( 0 => array( 	'event' => 'SAVE',
 												'type' => 'TRIM'),
 								1 => array( 	'event' => 'SAVE',
-												'type' => 'TOUPPER')
+												'type' => 'TOUPPER'),
+								2 => array( 	'event' => 'SAVE',
+												'type' => 'NOWHITESPACE')
 			),
 		),
 		'company_id' => array (
@@ -455,7 +461,9 @@
 			'filters'   => array( 0 => array( 	'event' => 'SAVE',
 												'type' => 'TRIM'),
 								1 => array( 	'event' => 'SAVE',
-												'type' => 'TOUPPER')
+												'type' => 'TOUPPER'),
+								2 => array( 	'event' => 'SAVE',
+												'type' => 'NOWHITESPACE')
 			),
 		),
 		'bank_account_swift' => array (
@@ -471,7 +479,9 @@
 			'filters'   => array( 0 => array( 	'event' => 'SAVE',
 												'type' => 'TRIM'),
 								1 => array( 	'event' => 'SAVE',
-												'type' => 'TOUPPER')
+												'type' => 'TOUPPER'),
+								2 => array( 	'event' => 'SAVE',
+												'type' => 'NOWHITESPACE')
 			),
 		),
 		'notes' => array (
diff --git a/interface/web/client/list/client.list.php b/interface/web/client/list/client.list.php
index 40af2a7..ae41bef 100644
--- a/interface/web/client/list/client.list.php
+++ b/interface/web/client/list/client.list.php
@@ -114,5 +114,16 @@
 	),
 	'width' => "",
 	'value' => "");
+	
+if(is_file(ISPC_WEB_PATH.'/robot/lib/robot_config.inc.php')){
+	$liste["item"][] = array( 'field'  => "validation_status",
+	'datatype' => "VARCHAR",
+	'formtype' => "SELECT",
+	'op'  => "=",
+	'prefix' => "",
+	'suffix' => "",
+	'width'  => "",
+	'value'  => array('accept' => 'accept', 'review' => 'review', 'reject' => 'reject'));
+}
 
 ?>
diff --git a/interface/web/client/templates/clients_list.htm b/interface/web/client/templates/clients_list.htm
index 27d4b7d..67bc598 100644
--- a/interface/web/client/templates/clients_list.htm
+++ b/interface/web/client/templates/clients_list.htm
@@ -23,6 +23,7 @@
                         <th data-column="username"><tmpl_var name="username_txt"></th>
                         <th data-column="city"><tmpl_var name="city_txt"></th>
                         <th data-column="country"><tmpl_var name="country_txt"></th>
+						<tmpl_if name="has_robot"><th data-column="validation_status"><tmpl_var name="validation_status_txt"></th></tmpl_if>
                         <th class="small-col text-right">{tmpl_var name='search_limit'}</th>
                     </tr>
                     <tr>
@@ -33,6 +34,7 @@
                         <td><input class="form-control" type="text" name="search_username" value="{tmpl_var name='search_username'}" /></td>
                         <td><input class="form-control" type="text" name="search_city" value="{tmpl_var name='search_city'}" /></td>
                         <td><select class="form-control" name="search_country">{tmpl_var name='search_country'}</select></td>
+						<tmpl_if name="has_robot"><td><select class="form-control" name="search_validation_status">{tmpl_var name='search_validation_status'}</select></td></tmpl_if>
                         <td class="text-right">
                             <button type="button" class="btn btn-default formbutton-default formbutton-narrow" name="Filter" id="Filter" value="{tmpl_var name="filter_txt"}" data-submit-form="pageForm" data-form-action="client/client_list.php"><span class="icon icon-filter"></span></button>
                         </td>
@@ -48,7 +50,16 @@
                             <td><a href="#" data-load-content="client/client_edit.php?id={tmpl_var name='id'}">{tmpl_var name="username"}</a></td>
                             <td><a href="#" data-load-content="client/client_edit.php?id={tmpl_var name='id'}">{tmpl_var name="city"}</a></td>
                             <td><a href="#" data-load-content="client/client_edit.php?id={tmpl_var name='id'}"><span class="flags flag-{tmpl_var name="countryiso"}">{tmpl_var name="country"}</span></a></td>
+							<tmpl_if name="has_robot"><td><a href="#" data-load-content="client/client_edit.php?id={tmpl_var name='id'}">{tmpl_var name="validation_status"}</a></td></tmpl_if>
                             <td class="text-right">
+								<tmpl_if name="has_robot">
+									<a class="btn btn-default formbutton-default formbutton-narrow" href="#" data-load-content="client/client_action.php?id={tmpl_var name='id'}" title="{tmpl_var name='client_actions_txt'}" style="background: no-repeat center url('themes/default/assets/images/arrow.png');"><span class="icon">&nbsp;&nbsp;</span></a>
+									<tmpl_if name='activation_code' op='!=' value=''>
+										<tmpl_if name='validation_status' op='==' value='review'>
+											<a class="btn btn-default formbutton-default formbutton-narrow" href="client/client_get_activation_pdf.php?id={tmpl_var name='id'}" style="background: no-repeat center url('billing/lib/icon/pdficon_small.gif');" title="{tmpl_var name='show_pdf_txt'}"><span class="icon">&nbsp;&nbsp;</span></a>
+										</tmpl_if>
+									</tmpl_if>
+								</tmpl_if>
                                 <tmpl_if name="is_admin">
                                     <a class="btn btn-default formbutton-success formbutton-narrow" data-load-content="login/login_as.php?cid={tmpl_var name='id'}"><span class="icon icon-loginas"></span></a>
                                 <tmpl_elseif name="is_reseller">
@@ -59,14 +70,14 @@
                         </tr>
                     </tmpl_loop>
                     <tmpl_unless name="records">
-                        <tr class="tbl_row_noresults tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>">
-                            <td colspan="8">{tmpl_var name='globalsearch_noresults_text_txt'}</td>
+                        <tr class="tbl_row_noresults tbl_row_{tmpl_if name='__EVEN__'}even{tmpl_else}uneven{/tmpl_if}">
+                            <td colspan="{tmpl_if name="has_robot"}9{tmpl_else}8{/tmpl_if}">{tmpl_var name='globalsearch_noresults_text_txt'}</td>
                         </tr>
                     </tmpl_unless>
                 </tbody>
                 <tfoot>
                     <tr>
-                        <td colspan="8"><tmpl_var name="paging"></td>
+                        <td colspan="{tmpl_if name="has_robot"}9{tmpl_else}8{/tmpl_if}"><tmpl_var name="paging"></td>
                     </tr>
                 </tfoot>
             </table>
diff --git a/interface/web/mail/templates/mail_domain_edit.htm b/interface/web/mail/templates/mail_domain_edit.htm
index 307b0d1..960f446 100644
--- a/interface/web/mail/templates/mail_domain_edit.htm
+++ b/interface/web/mail/templates/mail_domain_edit.htm
@@ -86,7 +86,7 @@
 			<tmpl_else>
 				<input type="hidden" name="domain_module" value="0" id="domain_module" />
 			</tmpl_if>
-            <div class="col-sm-12"><button class="btn btn-default formbutton-default" type="button" data-toggle="collapse" data-target="#toggle-dkim" aria-expanded="false" aria-controls="toggle-dkim">{tmpl_var name='dkim_settings_txt'}</button></div>
+            <div class="col-sm-12" style="padding:0"><button class="btn btn-default formbutton-default" type="button" data-toggle="collapse" data-target="#toggle-dkim" aria-expanded="false" aria-controls="toggle-dkim">{tmpl_var name='dkim_settings_txt'}</button></div>
             <div id="toggle-dkim" class="collapse">
               <div class="form-group">
                 <label class="col-sm-3 control-label">{tmpl_var name='dkim_txt'}</label>
diff --git a/interface/web/sites/ajax_get_json.php b/interface/web/sites/ajax_get_json.php
index b9b9b03..c115b17 100644
--- a/interface/web/sites/ajax_get_json.php
+++ b/interface/web/sites/ajax_get_json.php
@@ -92,7 +92,7 @@
 		$sql_where .= ")";
 	}
 
-	if($php_type == 'php-fpm'){
+	if($php_type == 'php-fpm' || ($php_type == 'hhvm' && $server_type == 'nginx')){
 		$php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fpm_init_script != '' AND php_fpm_ini_dir != '' AND php_fpm_pool_dir != '' AND server_id = ?".$sql_where, $server_id);
 	} elseif($php_type == 'fast-cgi'){
 		$php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fastcgi_binary != '' AND php_fastcgi_ini_dir != '' AND server_id = ?".$sql_where, $server_id);
@@ -100,7 +100,7 @@
 	$php_select = "";
 	if(is_array($php_records) && !empty($php_records)) {
 		foreach( $php_records as $php_record) {
-			if($php_type == 'php-fpm'){
+			if($php_type == 'php-fpm' || ($php_type == 'hhvm' && $server_type == 'nginx')){
 				$php_version = $php_record['name'].':'.$php_record['php_fpm_init_script'].':'.$php_record['php_fpm_ini_dir'].':'.$php_record['php_fpm_pool_dir'];
 			} else {
 				$php_version = $php_record['name'].':'.$php_record['php_fastcgi_binary'].':'.$php_record['php_fastcgi_ini_dir'];
@@ -192,12 +192,13 @@
 if ($type == 'getdirectivesnippet') {
 	$server_type = 'apache';
 	$web_config = $app->getconf->get_server_config($server_id, 'web');
-	if (!empty($web_config['server_type']))
-		$server_type = $web_config['server_type'];
+	if (!empty($web_config['server_type'])) $server_type = $web_config['server_type'];
 
-	$snippets = $app->db->queryAllRecords("SELECT directive_snippets_id, name FROM directive_snippets WHERE customer_viewable = 'y' AND type = ? ORDER BY name ASC", $server_type);
+	$m_snippets = $app->db->queryAllRecords("SELECT directive_snippets_id, name FROM directive_snippets WHERE customer_viewable = 'y' AND active = 'y' AND master_directive_snippets_id > 0 AND type = ? ORDER BY name ASC", $server_type);
+	
+	$snippets = $app->db->queryAllRecords("SELECT directive_snippets_id, name FROM directive_snippets WHERE customer_viewable = 'y' AND active = 'y' AND master_directive_snippets_id = 0 AND type = ? ORDER BY name ASC", $server_type);
 
-	$json = json_encode($snippets);
+	$json = json_encode(array('m_snippets' => $m_snippets, 'snippets' => $snippets));
 }
 
 if($type == 'getclientssldata'){
diff --git a/interface/web/sites/database_quota_stats.php b/interface/web/sites/database_quota_stats.php
index 7815faa..54fd4fe 100644
--- a/interface/web/sites/database_quota_stats.php
+++ b/interface/web/sites/database_quota_stats.php
@@ -19,21 +19,26 @@
 
 $app->load('listform_actions');
 
-$tmp_rec =  $app->db->queryOneRecord("SELECT data from monitor_data WHERE type = 'database_size' ORDER BY created DESC");
+$tmp_rec =  $app->db->queryAllRecords("SELECT server_id, data from monitor_data WHERE type = 'database_size' ORDER BY created DESC");
 $monitor_data = array();
-$tmp_array = unserialize($tmp_rec['data']);
+if(is_array($tmp_rec)) {
+	for($i = 0; $i < count($tmp_rec); $i++) {
+		$tmp_array = unserialize($tmp_rec[$i]['data']);
+		$server_id = $tmp_rec[$i]['server_id'];
 
-foreach($tmp_array as $database_name => $data) {
-	$db_name = $data['database_name'];
+		foreach($tmp_array as $database_name => $data) {
+			$db_name = $data['database_name'];
 
-	$temp = $app->db->queryOneRecord("SELECT client.username, web_database.database_quota FROM web_database, sys_group, client WHERE web_database.sys_groupid = sys_group.groupid AND sys_group.client_id = client.client_id AND web_database.database_name = ?", $db_name);
-
-	$monitor_data[$db_name]['database_name'] = $data['database_name'];
-	$monitor_data[$db_name]['client'] = isset($temp['username']) ? $temp['username'] : '';
-	$monitor_data[$db_name]['used'] = isset($data['size']) ? $data['size'] : 0;
-	$monitor_data[$db_name]['quota'] = isset($temp['database_quota']) ? $temp['database_quota'] : 0;
-
-	unset($temp);
+			$temp = $app->db->queryOneRecord("SELECT client.username, web_database.database_quota FROM web_database, sys_group, client WHERE web_database.sys_groupid = sys_group.groupid AND sys_group.client_id = client.client_id AND web_database.database_name = ?", $db_name);
+			if(is_array($temp) && !empty($temp)) {
+				$monitor_data[$server_id.'.'.$db_name]['database_name'] = $data['database_name'];
+				$monitor_data[$server_id.'.'.$db_name]['client'] = isset($temp['username']) ? $temp['username'] : '';
+				$monitor_data[$server_id.'.'.$db_name]['used'] = isset($data['size']) ? $data['size'] : 0;
+				$monitor_data[$server_id.'.'.$db_name]['quota'] = isset($temp['database_quota']) ? $temp['database_quota'] : 0;
+			}
+			unset($temp);
+		}
+	}
 }
 
 class list_action extends listform_actions {
@@ -48,26 +53,36 @@
 		$rec['bgcolor'] = $this->DataRowColor;
 
 		$database_name = $rec['database_name'];
+		
+		if(!empty($monitor_data[$rec['server_id'].'.'.$database_name])){
+			$rec['database'] = $monitor_data[$rec['server_id'].'.'.$database_name]['database_name'];
+			$rec['client'] = $monitor_data[$rec['server_id'].'.'.$database_name]['client'];
+			$rec['server_name'] = $app->db->queryOneRecord("SELECT server_name FROM server WHERE server_id = ?", $rec['server_id'])['server_name'];
+			$rec['used'] = $monitor_data[$rec['server_id'].'.'.$database_name]['used'];
+			$rec['quota'] = $monitor_data[$rec['server_id'].'.'.$database_name]['quota'];
 
-		$rec['database'] = $monitor_data[$database_name]['database_name'];
-		$rec['client'] = $monitor_data[$database_name]['client'];
-		$rec['server_name'] = $app->db->queryOneRecord("SELECT server_name FROM server WHERE server_id = ?", $rec['server_id'])['server_name'];
-		$rec['used'] = $monitor_data[$database_name]['used'];
-		$rec['quota'] = $monitor_data[$database_name]['quota'];
+			if($rec['quota'] == 0){
+				$rec['quota'] = $app->lng('unlimited');
+				$rec['percentage'] = '';
+			} else {
+				if ($rec['used'] > 0 ) $rec['percentage'] = round(100 * intval($rec['used']) / ( intval($rec['quota'])*1024*1024) ).'%';
+				$rec['quota'] .= ' MB';
+			}
 
-		if($rec['quota'] == 0){
-			$rec['quota'] = $app->lng('unlimited');
-			$rec['percentage'] = '';
+			if ($rec['used'] > 0) $rec['used'] = $app->functions->formatBytes($rec['used']);
 		} else {
-			if ($rec['used'] > 0 ) $rec['percentage'] = round(100 * intval($rec['used']) / ( intval($rec['quota'])*1024*1024) ).'%';
-			$rec['quota'] .= ' MB';
+			$web_database = $app->db->queryOneRecord("SELECT * FROM web_database WHERE database_id = ".$rec[$this->idx_key]);
+			$rec['database'] = $rec['database_name'];
+			$rec['server_name'] = $app->db->queryOneRecord("SELECT server_name FROM server WHERE server_id = ?", $web_database['server_id'])['server_name'];
+			$sys_group = $app->db->queryOneRecord("SELECT * FROM sys_group WHERE groupid = ".$web_database['sys_groupid']);
+			$client = $app->db->queryOneRecord("SELECT * FROM client WHERE client_id = ".$sys_group['client_id']);
+			$rec['client'] = $client['username'];
+			$rec['used'] = 'n/a';
+			$rec['quota'] = 'n/a';
 		}
-
-		if ($rec['used'] > 0) $rec['used'] = $app->functions->formatBytes($rec['used']);
-
 		$rec['id'] = $rec[$this->idx_key];
-		return $rec;
 
+		return $rec;
 	}
 
 }
diff --git a/interface/web/sites/form/database.tform.php b/interface/web/sites/form/database.tform.php
index da3bf9c..aef56f5 100644
--- a/interface/web/sites/form/database.tform.php
+++ b/interface/web/sites/form/database.tform.php
@@ -90,7 +90,7 @@
 			'formtype' => 'SELECT',
 			'default' => 'mysql',
 			'value'  => array(
-				'mongo' => 'MongoDB',
+				/*'mongo' => 'MongoDB',*/
 				'mysql' => 'MySQL'
 			)
 		),
diff --git a/interface/web/sites/form/web_vhost_domain.tform.php b/interface/web/sites/form/web_vhost_domain.tform.php
index e0b3a03..c447b1e 100644
--- a/interface/web/sites/form/web_vhost_domain.tform.php
+++ b/interface/web/sites/form/web_vhost_domain.tform.php
@@ -48,12 +48,12 @@
 		$vhostdomain_type = 'subdomain';
 		$form_title = "Subdomain";
 		$validator_function = 'sub_domain';
-		$first_tab_title = "Subomain";
+		$first_tab_title = "Subdomain";
 	} elseif($_SESSION['s']['var']['vhostdomain_type'] == 'aliasdomain') {
 		$vhostdomain_type = 'aliasdomain';
 		$form_title = "Aliasdomain";
 		$validator_function = 'alias_domain';
-		$first_tab_title = "Aliasomain";
+		$first_tab_title = "Aliasdomain";
 	}
 }
 
@@ -342,6 +342,18 @@
 			'errmsg'=> 'domain_error_autosub'
 		),
 	);
+	$form['tabs']['domain']['fields']['web_folder'] = array (
+		'datatype' => 'VARCHAR',
+		'validators' => array (  0 => array ( 'type' => 'REGEX',
+				'regex' => '@^((?!(.*\.\.)|(.*\./)|(.*//))[^/][\w/_\.\-]{1,100})?$@',
+				'errmsg'=> 'web_folder_error_regex'),
+		),
+		'formtype' => 'TEXT',
+		'default' => '',
+		'value'  => '',
+		'width'  => '30',
+		'maxlength' => '255'
+	);
 } else {
 	$form['tabs']['domain']['fields']['parent_domain_id']['datasource'] = array (
 		'type' => 'SQL',
@@ -352,7 +364,7 @@
 	$form['tabs']['domain']['fields']['web_folder'] = array (
 		'datatype' => 'VARCHAR',
 		'validators' => array (  0 => array ( 'type' => 'REGEX',
-				'regex' => '@^((?!.*\.\.)[\w/_\.\-]{1,100})$@',
+				'regex' => '@^((?!(.*\.\.)|(.*\./)|(.*//))[^/][\w/_\.\-]{1,100})?$@',
 				'errmsg'=> 'web_folder_error_regex'),
 		),
 		'formtype' => 'TEXT',
diff --git a/interface/web/sites/templates/web_vhost_domain_admin_list.htm b/interface/web/sites/templates/web_vhost_domain_admin_list.htm
index ccd16e2..9e12930 100644
--- a/interface/web/sites/templates/web_vhost_domain_admin_list.htm
+++ b/interface/web/sites/templates/web_vhost_domain_admin_list.htm
@@ -17,7 +17,7 @@
                 <tr>
                     <tmpl_if name="vhostdomain_type" value="domain"><th class="small-col" data-column="domain_id"><tmpl_var name="domain_id_txt"></th></tmpl_if>
                     <th class="tiny-col" data-column="active"><tmpl_var name="active_txt"></th>
-                    <th data-column="sys_groupid"><tmpl_var name="sys_groupid_txt"></th>
+                    <tmpl_if name="vhostdomain_type" value="domain"><th data-column="sys_groupid"><tmpl_var name="sys_groupid_txt"></th></tmpl_if>
                     <th data-column="server_id"><tmpl_var name="server_id_txt"></th>
 					<tmpl_if name="vhostdomain_type" op="!=" value="domain"><th data-column="parent_domain_id"><tmpl_var name="parent_domain_id_txt"></th></tmpl_if>
                     <th data-column="domain"><tmpl_if name='vhostdomain_type' op='==' value='domain'>{tmpl_var name="domain_txt"}</tmpl_if><tmpl_if name='vhostdomain_type' op='==' value='subdomain'>{tmpl_var name="subdomain_txt"}</tmpl_if><tmpl_if name='vhostdomain_type' op='==' value='aliasdomain'>{tmpl_var name="aliasdomain_txt"}</tmpl_if></th>
@@ -26,7 +26,7 @@
                 <tr>
                     <tmpl_if name="vhostdomain_type" value="domain"><td><input class="form-control" type="text" name="search_domain_id" value="{tmpl_var name='search_domain_id'}" /></td></tmpl_if>
                     <td><select class="form-control" name="search_active">{tmpl_var name='search_active'}</select></td>
-                    <td><select class="form-control" name="search_sys_groupid">{tmpl_var name='search_sys_groupid'}</select></td>
+                    <tmpl_if name="vhostdomain_type" value="domain"><td><select class="form-control" name="search_sys_groupid">{tmpl_var name='search_sys_groupid'}</select></td></tmpl_if>
                     <td><select class="form-control" name="search_server_id">{tmpl_var name='search_server_id'}</select></td>
 					<tmpl_if name="vhostdomain_type" op="!=" value="domain"><td><select class="form-control" name="search_parent_domain_id">{tmpl_var name='search_parent_domain_id'}</select></td></tmpl_if>
                     <td><input class="form-control" type="text" name="search_domain" value="{tmpl_var name='search_domain'}" /></td>
@@ -40,7 +40,7 @@
                     <tr>
                     	<tmpl_if name="vhostdomain_type" value="domain"><td><a href="#" data-load-content="sites/web_vhost_domain_edit.php?id={tmpl_var name='id'}&type={tmpl_var name='vhostdomain_type'}">{tmpl_var name="domain_id"}</a></td></tmpl_if>
                         <td><a href="#" data-load-content="sites/web_vhost_domain_edit.php?id={tmpl_var name='id'}&type={tmpl_var name='vhostdomain_type'}">{tmpl_var name="active"}</a></td>
-                        <td><a href="#" data-load-content="sites/web_vhost_domain_edit.php?id={tmpl_var name='id'}&type={tmpl_var name='vhostdomain_type'}">{tmpl_var name="sys_groupid"}</a></td>
+                        <tmpl_if name="vhostdomain_type" value="domain"><td><a href="#" data-load-content="sites/web_vhost_domain_edit.php?id={tmpl_var name='id'}&type={tmpl_var name='vhostdomain_type'}">{tmpl_var name="sys_groupid"}</a></td></tmpl_if>
                         <td><a href="#" data-load-content="sites/web_vhost_domain_edit.php?id={tmpl_var name='id'}&type={tmpl_var name='vhostdomain_type'}">{tmpl_var name="server_id"}</a></td>
 						<tmpl_if name="vhostdomain_type" op="!=" value="domain"><td><a href="#" data-load-content="sites/web_vhost_aliasdomain_edit.php?id={tmpl_var name='id'}">{tmpl_var name="parent_domain_id"}</a></td></tmpl_if>
                         <td><a href="#" data-load-content="sites/web_vhost_domain_edit.php?id={tmpl_var name='id'}&type={tmpl_var name='vhostdomain_type'}">{tmpl_var name="domain"}</a></td>
@@ -52,13 +52,13 @@
                 </tmpl_loop>
                 <tmpl_unless name="records">
                     <tr class="tbl_row_noresults tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>">
-                        <td colspan="6">{tmpl_var name='globalsearch_noresults_text_txt'}</td>
+                        <td colspan="{tmpl_if name="vhostdomain_type" value="domain"}6{/tmpl_else}5{/tmpl_if}">{tmpl_var name='globalsearch_noresults_text_txt'}</td>
                     </tr>
                 </tmpl_unless>
                 </tbody>
                 <tfoot>
                     <tr>
-                        <td colspan="6"><tmpl_var name="paging"></td>
+                        <td colspan="{tmpl_if name="vhostdomain_type" value="domain"}6{/tmpl_else}5{/tmpl_if}"><tmpl_var name="paging"></td>
                     </tr>
                 </tfoot>
             </table>
diff --git a/interface/web/sites/templates/web_vhost_domain_advanced.htm b/interface/web/sites/templates/web_vhost_domain_advanced.htm
index 3060caf..04825cb 100644
--- a/interface/web/sites/templates/web_vhost_domain_advanced.htm
+++ b/interface/web/sites/templates/web_vhost_domain_advanced.htm
@@ -34,6 +34,14 @@
             <div class="form-group apache">
                 <label for="allow_override" class="col-sm-3 control-label">{tmpl_var name='allow_override_txt'}</label>
                 <div class="col-sm-9"><input type="text" name="allow_override" id="allow_override" value="{tmpl_var name='allow_override'}" class="form-control" /></div></div>
+			<div class="form-group nginx">
+                <label for="http_port" class="col-sm-3 control-label">{tmpl_var name='http_port_txt'}</label>
+                <div class="col-sm-9"><input name="http_port" id="http_port" value="{tmpl_var name='http_port'}" type="text" class="form-control" /></div>
+            </div>
+			<div class="form-group nginx">
+                <label for="https_port" class="col-sm-3 control-label">{tmpl_var name='https_port_txt'}</label>
+                <div class="col-sm-9"><input name="https_port" id="https_port" value="{tmpl_var name='https_port'}" type="text" class="form-control" /></div>
+            </div>	
             <div class="phpfpm">
                 <div class="form-group">
                     <label class="col-sm-3 control-label">{tmpl_var name='php_fpm_use_socket_txt'}</label>
@@ -88,7 +96,7 @@
             <div class="form-group nginx">
                 <label for="nginx_directives" class="col-sm-3 control-label">{tmpl_var name='nginx_directives_txt'}</label>
                 <div class="col-sm-9"><textarea class="form-control" name="nginx_directives" id="nginx_directives" rows='10' cols='50'>{tmpl_var name='nginx_directives'}</textarea>
-				<b>{tmpl_var name="available_nginx_directive_snippets_txt"}</b><br><br>&nbsp;{tmpl_var name="nginx_directive_snippets_txt"}<br>----<br><b>&nbsp;{tmpl_var name='variables_txt'}:</b> <a href="javascript:void(0);" class="addPlaceholder">{DOCROOT}</a>, <a href="javascript:void(0);" class="addPlaceholder">{FASTCGIPASS}</a>
+				<b>{tmpl_var name="available_nginx_directive_snippets_txt"}</b><br><br>&nbsp;{tmpl_var name="nginx_directive_snippets_txt"}<br>----<br><b>&nbsp;{tmpl_var name='variables_txt'}:</b> <a href="javascript:void(0);" class="addPlaceholder">{DOCROOT}</a>, <a href="javascript:void(0);" class="addPlaceholder">{FASTCGIPASS}</a>, <a href="javascript:void(0);" class="addPlaceholder">{PHPFALLBACKFASTCGIPASS}</a>
 				</div>
 			</div>
 			<div class="form-group proxy">
diff --git a/interface/web/sites/templates/web_vhost_domain_edit.htm b/interface/web/sites/templates/web_vhost_domain_edit.htm
index 28d398b..8ba2825 100644
--- a/interface/web/sites/templates/web_vhost_domain_edit.htm
+++ b/interface/web/sites/templates/web_vhost_domain_edit.htm
@@ -74,7 +74,7 @@
                     {tmpl_var name='ip_address'}
                 </select></div>
             </div>
-            <div class="form-group">
+            <div class="form-group" style="display:none">
                 <label for="ipv6_address" class="col-sm-3 control-label">{tmpl_var name='ipv6_address_txt'}</label>
                 <div class="col-sm-9"><select name="ipv6_address" id="ipv6_address" class="form-control">
                     {tmpl_var name='ipv6_address'}
@@ -229,7 +229,12 @@
                     {tmpl_var name='fastcgi_php_version'}
                 </select></div>
             </div>
-            {tmpl_var name="directive_snippets_id"}
+			<div class="form-group">
+				<label for="directive_snippets_id" class="col-sm-3 control-label">{tmpl_var name='directive_snippets_id_txt'}</label>
+				<div class="col-sm-9"><select name="directive_snippets_id" id="directive_snippets_id" class="form-control">
+					{tmpl_var name='directive_snippets_id'}
+				</select></div>
+			</div>
 			{tmpl_hook name="field_enable_pagespeed"}
 			<div class="form-group nginx pagespeed">
 				<label class="col-sm-3 control-label">{tmpl_var name='enable_pagespeed_txt'}</label>
@@ -256,6 +261,7 @@
     var serverId;
     var clientGroupId = jQuery('#client_group_id').val();
     var serverIdDisabled = jQuery('#server_id_disabled').val();
+	var serverType;
     if(serverIdDisabled > 0){
         serverId = serverIdDisabled;
     } else {
@@ -270,15 +276,22 @@
     }
     adjustForm(true);
     reloadFastcgiPHPVersions(true);
-		
+	
     jQuery('#client_group_id').change(function(){
         clientGroupId = $(this).val();
         reloadWebIP();
 		reloadFastcgiPHPVersions();
     });
 		
-    if(jQuery('#php').val() == 'fast-cgi' || jQuery('#php').val() == 'php-fpm'){
+    if(jQuery('#php').val() == 'fast-cgi' || jQuery('#php').val() == 'php-fpm' || (jQuery('#php').val() == 'hhvm' && serverType == 'nginx')){
         jQuery('.fastcgi_php_version:hidden').show();
+		if(jQuery('#php').val() == 'hhvm'){
+			jQuery('#fastcgi_php_version_txt').hide();
+			jQuery('#fastcgi_php_fallback_version_txt').show();
+		} else {
+			jQuery('#fastcgi_php_version_txt').show();
+			jQuery('#fastcgi_php_fallback_version_txt').hide();
+		}
     } else {
         jQuery('.fastcgi_php_version:visible').hide();
     }
@@ -286,8 +299,15 @@
     
     jQuery('#php').change(function(){
         reloadFastcgiPHPVersions();
-        if(jQuery(this).val() == 'fast-cgi' || jQuery(this).val() == 'php-fpm'){
+        if(jQuery(this).val() == 'fast-cgi' || jQuery(this).val() == 'php-fpm' || (jQuery(this).val() == 'hhvm' && serverType == 'nginx')){	
             jQuery('.fastcgi_php_version:hidden').show();
+			if(jQuery(this).val() == 'hhvm'){
+				jQuery('#fastcgi_php_version_txt').hide();
+				jQuery('#fastcgi_php_fallback_version_txt').show();
+			} else {
+				jQuery('#fastcgi_php_version_txt').show();
+				jQuery('#fastcgi_php_fallback_version_txt').hide();
+			}
         } else {
             jQuery('.fastcgi_php_version:visible').hide();
         }
@@ -323,6 +343,7 @@
     function adjustForm(noFormChange){
         jQuery.getJSON('sites/ajax_get_json.php'+ '?' + Math.round(new Date().getTime()), {server_id : serverId, type : "getservertype"}, function(data) {
             if(data.servertype == "nginx"){
+				serverType = 'nginx';
                 var selected = jQuery('#php').val();
                 jQuery('.apache').hide();
 				jQuery('.nginx').show();
@@ -346,6 +367,7 @@
                 jQuery('#php option[value="mod"]').hide();
                 jQuery('#php option[value="suphp"]').hide();
             } else {
+				serverType = 'apache';
 				jQuery('.nginx').hide();
                 jQuery('.apache').show();
                 jQuery('#php option[value="fast-cgi"]').show();
@@ -365,16 +387,30 @@
 	
 	function reloadDirectiveSnippets() {
         jQuery.getJSON('sites/ajax_get_json.php'+ '?' + Math.round(new Date().getTime()), {server_id : serverId, type : "getdirectivesnippet"}, function(data) {
-            var options = '<option value="0"></option>';
-			for (var i = 0, len = data.length; i < len; i++) {
+            var options = '<option value="0">-</option>';
+			options += "<optgroup label=\"{tmpl_var name='select_master_directive_snippet_txt'}\">";
+			for (var i = 0, len = data['m_snippets'].length; i < len; i++) {
 				var isSelected = '';
 
 				 if ($('#directive_snippets_id').val() == i + 1) {
 					 isSelected = 'selected="selected"';
 				 }
 
-				 options += '<option ' + isSelected + ' value="' + data[i]['directive_snippets_id'] + '">' + data[i]['name'] + '</option>';
+				 options += '<option ' + isSelected + ' value="' + data['m_snippets'][i]['directive_snippets_id'] + '">' + data['m_snippets'][i]['name'] + '</option>';
 			}
+			options += '</optgroup>';
+			
+			options += "<optgroup label=\"{tmpl_var name='select_directive_snippet_txt'}\">";
+			for (var i = 0, len = data['snippets'].length; i < len; i++) {
+				var isSelected = '';
+
+				 if ($('#directive_snippets_id').val() == i + 1) {
+					 isSelected = 'selected="selected"';
+				 }
+
+				 options += '<option ' + isSelected + ' value="' + data['snippets'][i]['directive_snippets_id'] + '">' + data['snippets'][i]['name'] + '</option>';
+			}
+			options += '</optgroup>';
 
 			$('#directive_snippets_id').html(options).change();
 		});
@@ -434,5 +470,22 @@
             ISPConfig.submitForm('pageForm','sites/web_vhost_domain_edit.php');
         });
     </tmpl_if>
+	
+	if($('#domain').val() == ''){
+		$('#web_folder_domain').text('[DOMAIN]');
+	} else {
+		$('#web_folder_domain').text($('#domain').val());
+	}
+	$('#domain').bind('change keyup', function(){
+		if($(this).val() == ''){
+			$('#web_folder_domain').text('[DOMAIN]');
+		} else {
+			$('#web_folder_domain').text($('#domain').val());
+		}
+	});
+	
+	$('#more_folder_directive_snippets').click(function(){
+		$('.folder_directive_snippets:hidden:first').removeClass('hidden');
+	});
 			
 </script>
diff --git a/interface/web/sites/web_vhost_domain_edit.php b/interface/web/sites/web_vhost_domain_edit.php
index 6dcd7a3..86cc522 100644
--- a/interface/web/sites/web_vhost_domain_edit.php
+++ b/interface/web/sites/web_vhost_domain_edit.php
@@ -236,14 +236,14 @@
 			if($server_type == 'nginx' && $this->dataRecord['php'] == 'fast-cgi') $this->dataRecord['php'] = 'php-fpm';
 
 			if($this->_vhostdomain_type == 'domain') {
-				if($this->dataRecord['php'] == 'php-fpm'){
+				if($this->dataRecord['php'] == 'php-fpm' || ($this->dataRecord['php'] == 'hhvm' && $server_type == 'nginx')){
 					$php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fpm_init_script != '' AND php_fpm_ini_dir != '' AND php_fpm_pool_dir != '' AND server_id = ? AND (client_id = 0 OR client_id=?)", ($this->id > 0 ? $this->dataRecord['server_id'] : $client['default_webserver']), $_SESSION['s']['user']['client_id']);
 				}
 				if($this->dataRecord['php'] == 'fast-cgi'){
 					$php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fastcgi_binary != '' AND php_fastcgi_ini_dir != '' AND server_id = ? AND (client_id = 0 OR client_id=?)", ($this->id > 0 ? $this->dataRecord['server_id'] : $client['default_webserver']), $_SESSION['s']['user']['client_id']);
 				}
 			} else {
-				if($this->dataRecord['php'] == 'php-fpm'){
+				if($this->dataRecord['php'] == 'php-fpm' || ($this->dataRecord['php'] == 'hhvm' && $server_type == 'nginx')){
 					$php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fpm_init_script != '' AND php_fpm_ini_dir != '' AND php_fpm_pool_dir != '' AND server_id = ? AND (client_id = 0 OR client_id=?)", $parent_domain['server_id'], $_SESSION['s']['user']['client_id']);
 				}
 				if($this->dataRecord['php'] == 'fast-cgi'){
@@ -253,7 +253,7 @@
 			$php_select = "<option value=''>Default</option>";
 			if(is_array($php_records) && !empty($php_records)) {
 				foreach( $php_records as $php_record) {
-					if($this->dataRecord['php'] == 'php-fpm'){
+					if($this->dataRecord['php'] == 'php-fpm' || ($this->dataRecord['php'] == 'hhvm' && $server_type == 'nginx')){
 						$php_version = $php_record['name'].':'.$php_record['php_fpm_init_script'].':'.$php_record['php_fpm_ini_dir'].':'.$php_record['php_fpm_pool_dir'];
 					} else {
 						$php_version = $php_record['name'].':'.$php_record['php_fastcgi_binary'].':'.$php_record['php_fastcgi_ini_dir'];
@@ -370,14 +370,14 @@
 			$selected_client = $app->db->queryOneRecord("SELECT client_id FROM sys_group WHERE groupid = ?", $selected_client_group_id);
 			$sql_where = " AND (client_id = 0 OR client_id = ?)";
 			if($this->_vhostdomain_type == 'domain') {
-				if($this->dataRecord['php'] == 'php-fpm'){
+				if($this->dataRecord['php'] == 'php-fpm' || ($this->dataRecord['php'] == 'hhvm' && $server_type == 'nginx')){
 					$php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fpm_init_script != '' AND php_fpm_ini_dir != '' AND php_fpm_pool_dir != '' AND server_id = ?".$sql_where, ($this->id > 0 ? $this->dataRecord['server_id'] : $client['default_webserver']), $selected_client['client_id']);
 				}
 				if($this->dataRecord['php'] == 'fast-cgi') {
 					$php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fastcgi_binary != '' AND php_fastcgi_ini_dir != '' AND server_id = ?".$sql_where, ($this->id > 0 ? $this->dataRecord['server_id'] : $client['default_webserver']), $selected_client['client_id']);
 				}
 			} else {
-				if($this->dataRecord['php'] == 'php-fpm'){
+				if($this->dataRecord['php'] == 'php-fpm' || ($this->dataRecord['php'] == 'hhvm' && $server_type == 'nginx')){
 					$php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fpm_init_script != '' AND php_fpm_ini_dir != '' AND php_fpm_pool_dir != '' AND server_id = ? AND (client_id = 0 OR client_id=?)", $parent_domain['server_id'], $_SESSION['s']['user']['client_id']);
 				}
 				if($this->dataRecord['php'] == 'fast-cgi') {
@@ -387,7 +387,7 @@
 			$php_select = "<option value=''>Default</option>";
 			if(is_array($php_records) && !empty($php_records)) {
 				foreach( $php_records as $php_record) {
-					if($this->dataRecord['php'] == 'php-fpm'){
+					if($this->dataRecord['php'] == 'php-fpm' || ($this->dataRecord['php'] == 'hhvm' && $server_type == 'nginx')){
 						$php_version = $php_record['name'].':'.$php_record['php_fpm_init_script'].':'.$php_record['php_fpm_ini_dir'].':'.$php_record['php_fpm_pool_dir'];
 					} else {
 						$php_version = $php_record['name'].':'.$php_record['php_fastcgi_binary'].':'.$php_record['php_fastcgi_ini_dir'];
@@ -405,24 +405,46 @@
 			$sites_config = $app->getconf->get_global_config('sites');
 			if($sites_config['reseller_can_use_options']) {
 				// Directive Snippets
-				$php_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'php' AND active = 'y'");
 				$php_directive_snippets_txt = '';
+				$php_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'php' AND active = 'y' AND master_directive_snippets_id > 0 ORDER BY name");
 				if(is_array($php_directive_snippets) && !empty($php_directive_snippets)){
+					$php_directive_snippets_txt .= $app->tform->wordbook["select_master_directive_snippet_txt"].'<br>';
 					foreach($php_directive_snippets as $php_directive_snippet){
 						$php_directive_snippet['snippet'] = PHP_EOL . PHP_EOL . $php_directive_snippet['snippet'] . PHP_EOL;
-						$php_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$php_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.htmlentities($php_directive_snippet['snippet']).'</pre></a> ';
+						$php_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$php_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.htmlentities($php_directive_snippet['snippet']).'</pre></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
+					}
+					$php_directive_snippets_txt .= '<br><br>';
+				}
+				
+				$php_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'php' AND active = 'y' AND master_directive_snippets_id = 0 ORDER BY name");
+				if(is_array($php_directive_snippets) && !empty($php_directive_snippets)){
+					$php_directive_snippets_txt .= $app->tform->wordbook["select_directive_snippet_txt"].'<br>';
+					foreach($php_directive_snippets as $php_directive_snippet){
+						$php_directive_snippet['snippet'] = PHP_EOL . PHP_EOL . $php_directive_snippet['snippet'] . PHP_EOL;
+						$php_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$php_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.htmlentities($php_directive_snippet['snippet']).'</pre></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
 					}
 				}
 				if($php_directive_snippets_txt == '') $php_directive_snippets_txt = '------';
 				$app->tpl->setVar("php_directive_snippets_txt", $php_directive_snippets_txt);
 
 				if($server_type == 'apache'){
-					$apache_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'apache' AND active = 'y'");
 					$apache_directive_snippets_txt = '';
+					$apache_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'apache' AND active = 'y' AND master_directive_snippets_id > 0 ORDER BY name");
 					if(is_array($apache_directive_snippets) && !empty($apache_directive_snippets)){
+						$apache_directive_snippets_txt .= $app->tform->wordbook["select_master_directive_snippet_txt"].'<br>';
 						foreach($apache_directive_snippets as $apache_directive_snippet){
 							$apache_directive_snippet['snippet'] = PHP_EOL . PHP_EOL . $apache_directive_snippet['snippet'] . PHP_EOL;
-							$apache_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$apache_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.htmlentities($apache_directive_snippet['snippet']).'</pre></a> ';
+							$apache_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$apache_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.htmlentities($apache_directive_snippet['snippet']).'</pre></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
+						}
+						$apache_directive_snippets_txt .= '<br><br>';
+					}
+					
+					$apache_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'apache' AND active = 'y' AND master_directive_snippets_id = 0 ORDER BY name");
+					if(is_array($apache_directive_snippets) && !empty($apache_directive_snippets)){
+						$apache_directive_snippets_txt .= $app->tform->wordbook["select_directive_snippet_txt"].'<br>';
+						foreach($apache_directive_snippets as $apache_directive_snippet){
+							$apache_directive_snippet['snippet'] = PHP_EOL . PHP_EOL . $apache_directive_snippet['snippet'] . PHP_EOL;
+							$apache_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$apache_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.htmlentities($apache_directive_snippet['snippet']).'</pre></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
 						}
 					}
 					if($apache_directive_snippets_txt == '') $apache_directive_snippets_txt = '------';
@@ -430,24 +452,46 @@
 				}
 
 				if($server_type == 'nginx'){
-					$nginx_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'nginx' AND active = 'y'");
 					$nginx_directive_snippets_txt = '';
+					$nginx_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'nginx' AND active = 'y' AND master_directive_snippets_id > 0 ORDER BY name");
 					if(is_array($nginx_directive_snippets) && !empty($nginx_directive_snippets)){
+						$nginx_directive_snippets_txt .= $app->tform->wordbook["select_master_directive_snippet_txt"].'<br>';
 						foreach($nginx_directive_snippets as $nginx_directive_snippet){
 							$nginx_directive_snippet['snippet'] = PHP_EOL . PHP_EOL . $nginx_directive_snippet['snippet'] . PHP_EOL;
-							$nginx_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$nginx_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.htmlentities($nginx_directive_snippet['snippet']).'</pre></a> ';
+							$nginx_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$nginx_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.htmlentities($nginx_directive_snippet['snippet']).'</pre></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
+						}
+						$nginx_directive_snippets_txt .= '<br><br>';
+					}
+					
+					$nginx_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'nginx' AND active = 'y' AND master_directive_snippets_id = 0 ORDER BY name");
+					if(is_array($nginx_directive_snippets) && !empty($nginx_directive_snippets)){
+						$nginx_directive_snippets_txt .= $app->tform->wordbook["select_directive_snippet_txt"].'<br>';
+						foreach($nginx_directive_snippets as $nginx_directive_snippet){
+							$nginx_directive_snippet['snippet'] = PHP_EOL . PHP_EOL . $nginx_directive_snippet['snippet'] . PHP_EOL;
+							$nginx_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$nginx_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.htmlentities($nginx_directive_snippet['snippet']).'</pre></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
 						}
 					}
 					if($nginx_directive_snippets_txt == '') $nginx_directive_snippets_txt = '------';
 					$app->tpl->setVar("nginx_directive_snippets_txt", $nginx_directive_snippets_txt);
 				}
 
-				$proxy_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'proxy' AND active = 'y'");
 				$proxy_directive_snippets_txt = '';
+				$proxy_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'proxy' AND active = 'y' AND master_directive_snippets_id > 0 ORDER BY name");
 				if(is_array($proxy_directive_snippets) && !empty($proxy_directive_snippets)){
+					$proxy_directive_snippets_txt .= $app->tform->wordbook["select_master_directive_snippet_txt"].'<br>';
 					foreach($proxy_directive_snippets as $proxy_directive_snippet){
 						$proxy_directive_snippet['snippet'] = PHP_EOL . PHP_EOL . $proxy_directive_snippet['snippet'] . PHP_EOL;
-						$proxy_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$proxy_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.htmlentities($proxy_directive_snippet['snippet']).'</pre></a> ';
+						$proxy_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$proxy_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.htmlentities($proxy_directive_snippet['snippet']).'</pre></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
+					}
+					$proxy_directive_snippets_txt .= '<br><br>';
+				}
+				
+				$proxy_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'proxy' AND active = 'y' AND master_directive_snippets_id = 0 ORDER BY name");
+				if(is_array($proxy_directive_snippets) && !empty($proxy_directive_snippets)){
+					$proxy_directive_snippets_txt .= $app->tform->wordbook["select_directive_snippet_txt"].'<br>';
+					foreach($proxy_directive_snippets as $proxy_directive_snippet){
+						$proxy_directive_snippet['snippet'] = PHP_EOL . PHP_EOL . $proxy_directive_snippet['snippet'] . PHP_EOL;
+						$proxy_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$proxy_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.htmlentities($proxy_directive_snippet['snippet']).'</pre></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
 					}
 				}
 				if($proxy_directive_snippets_txt == '') $proxy_directive_snippets_txt = '------';
@@ -516,6 +560,10 @@
 			unset($ips);
 
 			if ($settings['use_domain_module'] != 'y') {
+				if(!isset($this->dataRecord["sys_groupid"])){
+					$tmp = $app->db->queryOneRecord("SELECT sys_groupid FROM web_domain WHERE domain_id = ".$app->functions->intval($this->id));
+					$this->dataRecord["sys_groupid"] = $tmp["sys_groupid"];
+				}
 				// 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 sys_group.client_id > 0 ORDER BY client.company_name, client.contact_name, sys_group.name";
 				$clients = $app->db->queryAllRecords($sql);
@@ -541,14 +589,14 @@
 			$selected_client = $app->db->queryOneRecord("SELECT client_id FROM sys_group WHERE groupid = ?", $selected_client_group_id);
 			$sql_where = " AND (client_id = 0 OR client_id = ?)";
 			if($this->_vhostdomain_type == 'domain') {
-				if($this->dataRecord['php'] == 'php-fpm'){
+				if($this->dataRecord['php'] == 'php-fpm' || ($this->dataRecord['php'] == 'hhvm' && $server_type == 'nginx')){
 					$php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fpm_init_script != '' AND php_fpm_ini_dir != '' AND php_fpm_pool_dir != '' AND server_id = ?".$sql_where, $server_id, $selected_client['client_id']);
 				}
 				if($this->dataRecord['php'] == 'fast-cgi') {
 					$php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fastcgi_binary != '' AND php_fastcgi_ini_dir != '' AND server_id = ?".$sql_where, $server_id, $selected_client['client_id']);
 				}
 			} else {
-				if($this->dataRecord['php'] == 'php-fpm'){
+				if($this->dataRecord['php'] == 'php-fpm' || ($this->dataRecord['php'] == 'hhvm' && $server_type == 'nginx')){
 					$php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fpm_init_script != '' AND php_fpm_ini_dir != '' AND php_fpm_pool_dir != '' AND server_id = ?", $parent_domain['server_id']);
 				}
 				if($this->dataRecord['php'] == 'fast-cgi') {
@@ -558,7 +606,7 @@
 			$php_select = "<option value=''>Default</option>";
 			if(is_array($php_records) && !empty($php_records)) {
 				foreach( $php_records as $php_record) {
-					if($this->dataRecord['php'] == 'php-fpm'){
+					if($this->dataRecord['php'] == 'php-fpm' || ($this->dataRecord['php'] == 'hhvm' && $server_type == 'nginx')){
 						$php_version = $php_record['name'].':'.$php_record['php_fpm_init_script'].':'.$php_record['php_fpm_ini_dir'].':'.$php_record['php_fpm_pool_dir'];
 					} else {
 						$php_version = $php_record['name'].':'.$php_record['php_fastcgi_binary'].':'.$php_record['php_fastcgi_ini_dir'];
@@ -573,24 +621,46 @@
 			foreach($read_limits as $limit) $app->tpl->setVar($limit, ($limit == 'force_suexec' ? 'n' : 'y'));
 
 			// Directive Snippets
-			$php_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'php' AND active = 'y'");
 			$php_directive_snippets_txt = '';
+			$php_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'php' AND active = 'y' AND master_directive_snippets_id > 0 ORDER BY name");
 			if(is_array($php_directive_snippets) && !empty($php_directive_snippets)){
+				$php_directive_snippets_txt .= $app->tform->wordbook["select_master_directive_snippet_txt"].'<br>';
 				foreach($php_directive_snippets as $php_directive_snippet){
 					$php_directive_snippet['snippet'] = PHP_EOL . PHP_EOL . $php_directive_snippet['snippet'] . PHP_EOL;
-					$php_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$php_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.htmlentities($php_directive_snippet['snippet']).'</pre></a> ';
+					$php_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$php_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.htmlentities($php_directive_snippet['snippet']).'</pre></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
+				}
+				$php_directive_snippets_txt .= '<br><br>';
+			}
+			
+			$php_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'php' AND active = 'y' AND master_directive_snippets_id = 0 ORDER BY name");
+			if(is_array($php_directive_snippets) && !empty($php_directive_snippets)){
+				$php_directive_snippets_txt .= $app->tform->wordbook["select_directive_snippet_txt"].'<br>';
+				foreach($php_directive_snippets as $php_directive_snippet){
+					$php_directive_snippet['snippet'] = PHP_EOL . PHP_EOL . $php_directive_snippet['snippet'] . PHP_EOL;
+					$php_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$php_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.htmlentities($php_directive_snippet['snippet']).'</pre></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
 				}
 			}
 			if($php_directive_snippets_txt == '') $php_directive_snippets_txt = '------';
 			$app->tpl->setVar("php_directive_snippets_txt", $php_directive_snippets_txt);
 
 			if($server_type == 'apache'){
-				$apache_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'apache' AND active = 'y'");
 				$apache_directive_snippets_txt = '';
+				$apache_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'apache' AND active = 'y' AND master_directive_snippets_id > 0 ORDER BY name");
 				if(is_array($apache_directive_snippets) && !empty($apache_directive_snippets)){
+					$apache_directive_snippets_txt .= $app->tform->wordbook["select_master_directive_snippet_txt"].'<br>';
 					foreach($apache_directive_snippets as $apache_directive_snippet){
 						$apache_directive_snippet['snippet'] = PHP_EOL . PHP_EOL . $apache_directive_snippet['snippet'] . PHP_EOL;
-						$apache_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$apache_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.htmlentities($apache_directive_snippet['snippet']).'</pre></a> ';
+						$apache_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$apache_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.htmlentities($apache_directive_snippet['snippet']).'</pre></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
+					}
+					$apache_directive_snippets_txt .= '<br><br>';
+				}
+				
+				$apache_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'apache' AND active = 'y' AND master_directive_snippets_id = 0 ORDER BY name");
+				if(is_array($apache_directive_snippets) && !empty($apache_directive_snippets)){
+					$apache_directive_snippets_txt .= $app->tform->wordbook["select_directive_snippet_txt"].'<br>';
+					foreach($apache_directive_snippets as $apache_directive_snippet){
+						$apache_directive_snippet['snippet'] = PHP_EOL . PHP_EOL . $apache_directive_snippet['snippet'] . PHP_EOL;
+						$apache_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$apache_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.htmlentities($apache_directive_snippet['snippet']).'</pre></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
 					}
 				}
 				if($apache_directive_snippets_txt == '') $apache_directive_snippets_txt = '------';
@@ -598,24 +668,46 @@
 			}
 
 			if($server_type == 'nginx'){
-				$nginx_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'nginx' AND active = 'y'");
 				$nginx_directive_snippets_txt = '';
+				$nginx_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'nginx' AND active = 'y' AND master_directive_snippets_id > 0 ORDER BY name");
 				if(is_array($nginx_directive_snippets) && !empty($nginx_directive_snippets)){
+					$nginx_directive_snippets_txt .= $app->tform->wordbook["select_master_directive_snippet_txt"].'<br>';
 					foreach($nginx_directive_snippets as $nginx_directive_snippet){
 						$nginx_directive_snippet['snippet'] = PHP_EOL . PHP_EOL . $nginx_directive_snippet['snippet'] . PHP_EOL;
-						$nginx_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$nginx_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.htmlentities($nginx_directive_snippet['snippet']).'</pre></a> ';
+						$nginx_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$nginx_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.htmlentities($nginx_directive_snippet['snippet']).'</pre></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
+					}
+					$nginx_directive_snippets_txt .= '<br><br>';
+				}
+				
+				$nginx_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'nginx' AND active = 'y' AND master_directive_snippets_id = 0 ORDER BY name");
+				if(is_array($nginx_directive_snippets) && !empty($nginx_directive_snippets)){
+					$nginx_directive_snippets_txt .= $app->tform->wordbook["select_directive_snippet_txt"].'<br>';
+					foreach($nginx_directive_snippets as $nginx_directive_snippet){
+						$nginx_directive_snippet['snippet'] = PHP_EOL . PHP_EOL . $nginx_directive_snippet['snippet'] . PHP_EOL;
+						$nginx_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$nginx_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.htmlentities($nginx_directive_snippet['snippet']).'</pre></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
 					}
 				}
 				if($nginx_directive_snippets_txt == '') $nginx_directive_snippets_txt = '------';
 				$app->tpl->setVar("nginx_directive_snippets_txt", $nginx_directive_snippets_txt);
 			}
 
-			$proxy_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'proxy' AND active = 'y'");
 			$proxy_directive_snippets_txt = '';
+			$proxy_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'proxy' AND active = 'y' AND master_directive_snippets_id > 0 ORDER BY name");
 			if(is_array($proxy_directive_snippets) && !empty($proxy_directive_snippets)){
+				$proxy_directive_snippets_txt .= $app->tform->wordbook["select_master_directive_snippet_txt"].'<br>';
 				foreach($proxy_directive_snippets as $proxy_directive_snippet){
 					$proxy_directive_snippet['snippet'] = PHP_EOL . PHP_EOL . $proxy_directive_snippet['snippet'] . PHP_EOL;
-					$proxy_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$proxy_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.htmlentities($proxy_directive_snippet['snippet']).'</pre></a> ';
+					$proxy_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$proxy_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.htmlentities($proxy_directive_snippet['snippet']).'</pre></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
+				}
+				$proxy_directive_snippets_txt .= '<br><br>';
+			}
+			
+			$proxy_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'proxy' AND active = 'y' AND master_directive_snippets_id = 0 ORDER BY name");
+			if(is_array($proxy_directive_snippets) && !empty($proxy_directive_snippets)){
+				$proxy_directive_snippets_txt .= $app->tform->wordbook["select_directive_snippet_txt"].'<br>';
+				foreach($proxy_directive_snippets as $proxy_directive_snippet){
+					$proxy_directive_snippet['snippet'] = PHP_EOL . PHP_EOL . $proxy_directive_snippet['snippet'] . PHP_EOL;
+					$proxy_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$proxy_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.htmlentities($proxy_directive_snippet['snippet']).'</pre></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
 				}
 			}
 			if($proxy_directive_snippets_txt == '') $proxy_directive_snippets_txt = '------';
@@ -730,6 +822,96 @@
 		if($sys_config['use_combobox'] == 'y') {
 			$app->tpl->setVar('use_combobox', 'y');
 		}
+		
+		$directive_snippets_id_select = '<option value="0"'.($this->dataRecord['directive_snippets_id'] == 0? ' selected="selected"' : '').'>-</option>';
+		$server_type = $app->getconf->get_server_config($server_id, 'web');
+		$server_type = $server_type['server_type'];
+		
+		$m_directive_snippets = $app->db->queryAllRecords("SELECT directive_snippets_id, name FROM directive_snippets WHERE customer_viewable = 'y' AND active = 'y' AND master_directive_snippets_id > 0 AND type = ? ORDER BY name ASC", $server_type);
+		if(is_array($m_directive_snippets) && !empty($m_directive_snippets)){
+			$directive_snippets_id_select .= '<optgroup label="'.$app->tform->wordbook["select_master_directive_snippet_txt"].'">';
+			foreach($m_directive_snippets as $m_directive_snippet){
+				$directive_snippets_id_select .= '<option value="'.$m_directive_snippet['directive_snippets_id'].'"'.($this->dataRecord['directive_snippets_id'] == $m_directive_snippet['directive_snippets_id']? ' selected="selected"' : '').'>'.$m_directive_snippet['name'].'</option>';
+			}
+			$directive_snippets_id_select .= '</optgroup>';
+		}
+		
+		$directive_snippets = $app->db->queryAllRecords("SELECT directive_snippets_id, name FROM directive_snippets WHERE customer_viewable = 'y' AND active = 'y' AND master_directive_snippets_id = 0 AND type = ? ORDER BY name ASC", $server_type);
+		if(is_array($directive_snippets) && !empty($directive_snippets)){
+			$directive_snippets_id_select .= '<optgroup label="'.$app->tform->wordbook["select_directive_snippet_txt"].'">';
+			foreach($directive_snippets as $directive_snippet){
+				$directive_snippets_id_select .= '<option value="'.$directive_snippet['directive_snippets_id'].'"'.($this->dataRecord['directive_snippets_id'] == $directive_snippet['directive_snippets_id']? ' selected="selected"' : '').'>'.$directive_snippet['name'].'</option>';
+			}
+			$directive_snippets_id_select .= '</optgroup>';
+		}
+		$app->tpl->setVar("directive_snippets_id", $directive_snippets_id_select);
+		
+		// folder_directive_snippets
+		if(isset($_POST['folder_directive_snippets']) && !isset($this->dataRecord['folder_directive_snippets'])){
+			$this->dataRecord['folder_directive_snippets'] = '';
+			if(is_array($_POST['folder_directive_snippets']) && !empty($_POST['folder_directive_snippets'])){
+				foreach($_POST['folder_directive_snippets'] as $folder_directive_snippet){
+					if(trim($folder_directive_snippet['folder']) != '' && intval($folder_directive_snippet['snippets_id']) > 0) $this->dataRecord['folder_directive_snippets'] .= trim($folder_directive_snippet['folder']).':'.intval($folder_directive_snippet['snippets_id'])."\n";
+				}
+			}
+			$this->dataRecord['folder_directive_snippets'] = trim($this->dataRecord['folder_directive_snippets']);
+		}
+		
+		$master_directive_snippets = $app->db->queryAllRecords("SELECT directive_snippets_id, name FROM directive_snippets WHERE customer_viewable = 'y' AND active = 'y' AND snippet LIKE '%{FOLDER}%' AND master_directive_snippets_id > 0 AND type = ? ORDER BY name ASC", $server_type);
+		$c_directive_snippets = $app->db->queryAllRecords("SELECT directive_snippets_id, name FROM directive_snippets WHERE customer_viewable = 'y' AND active = 'y' AND snippet LIKE '%{FOLDER}%' AND master_directive_snippets_id = 0 AND type = ? ORDER BY name ASC", $server_type);
+		
+		$folder_directive_snippets = array();
+		$this->dataRecord['folder_directive_snippets'] = str_replace("\r\n", "\n", $this->dataRecord['folder_directive_snippets']);
+		$this->dataRecord['folder_directive_snippets'] = str_replace("\r", "\n", $this->dataRecord['folder_directive_snippets']);
+		$folder_directive_snippets_lines = explode("\n", trim($this->dataRecord['folder_directive_snippets']));
+		for($i=0;$i<sizeof($folder_directive_snippets_lines)+50;$i++){
+			$folder_directive_snippets[$i]['folder_directive_snippets_index'] = $i;
+			$folder_directive_snippets[$i]['folder_directive_snippets_index_plus_1'] = $i + 1;
+			if($i > sizeof($folder_directive_snippets_lines)){
+				$folder_directive_snippets[$i]['folder_directive_snippets_css'] = 'hidden';
+			} else {
+				$folder_directive_snippets[$i]['folder_directive_snippets_css'] = '';
+			}
+			if(trim($folder_directive_snippets_lines[$i]) != ''){
+				list($folder_directive_snippets[$i]['folder_directive_snippets_folder'], $selected_snippet) = explode(':', trim($folder_directive_snippets_lines[$i]));
+				$folder_directive_snippets[$i]['folder_directive_snippets_id'] = '<option value="0">-</option>';
+				if(is_array($master_directive_snippets) && !empty($master_directive_snippets)){
+					$folder_directive_snippets[$i]['folder_directive_snippets_id'] .= '<optgroup label="'.$app->tform->wordbook["select_master_directive_snippet_txt"].'">';
+					foreach($master_directive_snippets as $master_directive_snippet){
+						$folder_directive_snippets[$i]['folder_directive_snippets_id'] .= '<option value="'.$master_directive_snippet['directive_snippets_id'].'"'.($master_directive_snippet['directive_snippets_id'] == $selected_snippet ? ' selected="selected"' : '').'>'.$master_directive_snippet['name'].'</option>';
+					}
+					$folder_directive_snippets[$i]['folder_directive_snippets_id'] .= '</optgroup>';
+				}
+				
+				if(is_array($c_directive_snippets) && !empty($c_directive_snippets)){
+					$folder_directive_snippets[$i]['folder_directive_snippets_id'] .= '<optgroup label="'.$app->tform->wordbook["select_directive_snippet_txt"].'">';
+					foreach($c_directive_snippets as $c_directive_snippet){
+						$folder_directive_snippets[$i]['folder_directive_snippets_id'] .= '<option value="'.$c_directive_snippet['directive_snippets_id'].'"'.($c_directive_snippet['directive_snippets_id'] == $selected_snippet? ' selected="selected"' : '').'>'.$c_directive_snippet['name'].'</option>';
+					}
+					$folder_directive_snippets[$i]['folder_directive_snippets_id'] .= '</optgroup>';
+				}
+			} else {
+				$folder_directive_snippets[$i]['folder_directive_snippets_folder'] = '';
+				$folder_directive_snippets[$i]['folder_directive_snippets_id'] = '<option value="0">-</option>';
+				if(is_array($master_directive_snippets) && !empty($master_directive_snippets)){
+					$folder_directive_snippets[$i]['folder_directive_snippets_id'] .= '<optgroup label="'.$app->tform->wordbook["select_master_directive_snippet_txt"].'">';
+					foreach($master_directive_snippets as $master_directive_snippet){
+						$folder_directive_snippets[$i]['folder_directive_snippets_id'] .= '<option value="'.$master_directive_snippet['directive_snippets_id'].'">'.$master_directive_snippet['name'].'</option>';
+					}
+					$folder_directive_snippets[$i]['folder_directive_snippets_id'] .= '</optgroup>';
+				}
+				
+				if(is_array($c_directive_snippets) && !empty($c_directive_snippets)){
+					$folder_directive_snippets[$i]['folder_directive_snippets_id'] .= '<optgroup label="'.$app->tform->wordbook["select_directive_snippet_txt"].'">';
+					foreach($c_directive_snippets as $c_directive_snippet){
+						$folder_directive_snippets[$i]['folder_directive_snippets_id'] .= '<option value="'.$c_directive_snippet['directive_snippets_id'].'">'.$c_directive_snippet['name'].'</option>';
+					}
+					$folder_directive_snippets[$i]['folder_directive_snippets_id'] .= '</optgroup>';
+				}
+			}
+		}
+		$app->tpl->setLoop('folder_directive_snippets', $folder_directive_snippets);
+
 		parent::onShowEnd();
 	}
 
@@ -925,7 +1107,7 @@
 				// restore the server ID if the user is not admin and record is edited
 				$tmp = $app->db->queryOneRecord("SELECT server_id, `system_user`, `system_group`, `web_folder`, `cgi`, `ssi`, `perl`, `ruby`, `python`, `suexec`, `errordocs`, `subdomain`, `ssl` FROM web_domain WHERE domain_id = ?", $this->id);
 				$this->dataRecord["server_id"] = $tmp["server_id"];
-				$this->dataRecord['web_folder'] = $tmp['web_folder']; // cannot be changed!
+				if($this->_vhostdomain_type != 'domain') $this->dataRecord['web_folder'] = $tmp['web_folder']; // cannot be changed!
 				$this->dataRecord['system_user'] = $tmp['system_user'];
 				$this->dataRecord['system_group'] = $tmp['system_group'];
 
@@ -1095,7 +1277,31 @@
 			unset($app->tform->formDef["tabs"]['ssl']['fields']['enable_spdy']);
 		}
 		if($this->dataRecord["directive_snippets_id"] < 1) $this->dataRecord["enable_pagespeed"] = 'n';
-
+		
+		//print_r($_POST['folder_directive_snippets']);
+		//print_r($_POST['folder_directive_snippets_id']);
+		if(isset($_POST['folder_directive_snippets'])){
+			$this->dataRecord['folder_directive_snippets'] = '';
+			if(is_array($_POST['folder_directive_snippets']) && !empty($_POST['folder_directive_snippets'])){
+				$existing_directive_snippets_folders = array();
+				foreach($_POST['folder_directive_snippets'] as $folder_directive_snippet){
+					$folder_directive_snippet['folder'] = trim($folder_directive_snippet['folder']);
+					if($folder_directive_snippet['folder'] != '' && intval($folder_directive_snippet['snippets_id']) > 0){
+						if(substr($folder_directive_snippet['folder'], -1) != '/') $folder_directive_snippet['folder'] .= '/';
+						if(substr($folder_directive_snippet['folder'], 0, 1) == '/') $folder_directive_snippet['folder'] = substr($folder_directive_snippet['folder'], 1);
+						if(in_array($folder_directive_snippet['folder'], $existing_directive_snippets_folders)){
+							$app->tform->errorMessage .= $app->tform->lng("config_for_folder_exists_already_txt").'<br>';
+						} else {
+							$existing_directive_snippets_folders[] = $folder_directive_snippet['folder'];
+						}
+						$this->dataRecord['folder_directive_snippets'] .= $folder_directive_snippet['folder'].':'.intval($folder_directive_snippet['snippets_id'])."\n";
+					}
+					if(!preg_match('@^((?!(.*\.\.)|(.*\./)|(.*//))[^/][\w/_\.\-]{1,100})?$@', $folder_directive_snippet['folder'])) $app->tform->errorMessage .= $app->tform->lng("web_folder_error_regex").'<br>';
+				}
+			}
+			$this->dataRecord['folder_directive_snippets'] = trim($this->dataRecord['folder_directive_snippets']);
+		}
+		
 		parent::onSubmit();
 	}
 
@@ -1169,7 +1375,7 @@
 			$sql = "UPDATE web_domain SET sys_groupid = ?, system_user = ?, system_group = ?, document_root = ?, allow_override = ?, php_open_basedir = ?, added_date = ?, added_by = ?  WHERE domain_id = ?";
 			$app->db->query($sql, $this->parent_domain_record['sys_groupid'], $system_user, $system_group, $document_root, $htaccess_allow_override, $php_open_basedir, $added_date, $added_by, $this->id);
 		}
-
+		if(isset($this->dataRecord['folder_directive_snippets'])) $app->db->query("UPDATE web_domain SET folder_directive_snippets = ? WHERE domain_id = ?", $this->dataRecord['folder_directive_snippets'], $this->id);
 	}
 
 	function onBeforeUpdate () {
@@ -1221,6 +1427,12 @@
 		}
 
 	}
+	
+	function onAfterUpdate() {
+		global $app, $conf;
+
+		if(isset($this->dataRecord['folder_directive_snippets'])) $app->db->query("UPDATE web_domain SET folder_directive_snippets = ? WHERE domain_id = ?", $this->dataRecord['folder_directive_snippets'], $this->id);
+	}
 }
 
 $page = new page_action;
diff --git a/interface/web/themes/default/templates/sidenav.tpl.htm b/interface/web/themes/default/templates/sidenav.tpl.htm
index 6064966..be82bc9 100644
--- a/interface/web/themes/default/templates/sidenav.tpl.htm
+++ b/interface/web/themes/default/templates/sidenav.tpl.htm
@@ -1,17 +1,20 @@
 <tmpl_loop name="nav_left">
-	<tmpl_if name="title"><header><tmpl_if name="startpage"><a href="#" class="subnav-header" data-load-content="<tmpl_var name='startpage'>"></tmpl_if><tmpl_var name="title"><tmpl_if name="startpage"></a></tmpl_if></header></tmpl_if>
+	<tmpl_if name="title"><header><tmpl_if name="is_link" op="!=" value="no"><tmpl_if name="startpage"><a href="#" onclick="return false;" class="subnav-header" data-load-content="<tmpl_var name='startpage'>"></tmpl_if></tmpl_if><tmpl_var name="title"><tmpl_if name="is_link" op="!=" value="no"><tmpl_if name="startpage"></a></tmpl_if></tmpl_if></header></tmpl_if>
 	<ul id="sub-navigation">
 	  <tmpl_loop name="items">
 	  <li<tmpl_if name="html_id"> id='<tmpl_var name="html_id">' </tmpl_if>>
 		<tmpl_if name="link">
 			<tmpl_if name="target" op="==" value="_blank">
 				<a href="<tmpl_var name='link'>" target="_blank">
+			<tmpl_elseif name="target" op="==" value="_top">
+				<a href="<tmpl_var name='link'>" target="_top">
 			<tmpl_else>
-				<a href="#" data-load-content="<tmpl_var name='link'>">
+				<a href="#" onclick="return false;" data-load-content="<tmpl_var name='link'>">
 			</tmpl_if>
 		</tmpl_if>
-		  <div>
-			<strong><tmpl_var name="title"></strong>
+		  <div{tmpl_if name="css"} style="{tmpl_var name='css'}"{/tmpl_if}>
+			<tmpl_if name="title"><strong><tmpl_var name="title"></strong></tmpl_if>
+			<tmpl_if name="image"><div align="center"><tmpl_var name="image"></div></tmpl_if>
 		  </div>
 		<tmpl_if name="link">
 		</a>
diff --git a/server/conf/hhvm_starter.master b/server/conf/hhvm_starter.master
index a4cac46..318c3b3 100644
--- a/server/conf/hhvm_starter.master
+++ b/server/conf/hhvm_starter.master
@@ -35,7 +35,7 @@
 		ln -s /var/run/mysqld/mysqld.sock /tmp/mysql.sock ;
 	fi
 	
-	umask 017
+	umask 022
 	sudo -u {SYSTEM_USER} touch /var/run/hhvm/hhvm_{SYSTEM_USER}.pid
 	
 	BASEINIFILE=""
diff --git a/server/conf/nginx_vhost.conf.master b/server/conf/nginx_vhost.conf.master
index 4a775ce..807eeb1 100644
--- a/server/conf/nginx_vhost.conf.master
+++ b/server/conf/nginx_vhost.conf.master
@@ -1,14 +1,14 @@
 server {
-        listen <tmpl_var name='ip_address'>:80;
+        listen <tmpl_var name='ip_address'>:<tmpl_var name='http_port'>;
 <tmpl_if name='ipv6_enabled'>
-        listen [<tmpl_var name='ipv6_address'>]:80;
+        listen [<tmpl_var name='ipv6_address'>]:<tmpl_var name='http_port'>;
 </tmpl_if>
 		
 <tmpl_if name='ssl_enabled'>
-        listen <tmpl_var name='ip_address'>:443 ssl{tmpl_if name='enable_spdy' op='==' value='y'} spdy{/tmpl_if};
+        listen <tmpl_var name='ip_address'>:<tmpl_var name='https_port'> ssl{tmpl_if name='enable_http2' op='==' value='y'} http2{/tmpl_if}{tmpl_if name='enable_spdy' op='==' value='y'} spdy{/tmpl_if};
 		ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
 <tmpl_if name='ipv6_enabled'>
-        listen [<tmpl_var name='ipv6_address'>]:443 ssl{tmpl_if name='enable_spdy' op='==' value='y'} spdy{/tmpl_if};
+        listen [<tmpl_var name='ipv6_address'>]:<tmpl_var name='https_port'> ssl{tmpl_if name='enable_http2' op='==' value='y'} http2{/tmpl_if}{tmpl_if name='enable_spdy' op='==' value='y'} spdy{/tmpl_if};
 </tmpl_if>
         ssl_certificate <tmpl_var name='document_root'>/ssl/<tmpl_var name='ssl_domain'>.crt;
         ssl_certificate_key <tmpl_var name='document_root'>/ssl/<tmpl_var name='ssl_domain'>.key;
@@ -169,6 +169,22 @@
 				fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
 				#fastcgi_param PATH_INFO $fastcgi_script_name;
 				fastcgi_intercept_errors on;
+				error_page 500 501 502 503 = @phpfallback;
+			}
+			
+			location @phpfallback {
+				try_files $uri =404;
+				include /etc/nginx/fastcgi_params;
+<tmpl_if name='use_tcp'>
+				fastcgi_pass 127.0.0.1:<tmpl_var name='fpm_port'>;
+</tmpl_if>
+<tmpl_if name='use_socket'>
+				fastcgi_pass unix:<tmpl_var name='fpm_socket'>;
+</tmpl_if>
+				fastcgi_index index.php;
+				fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+				#fastcgi_param PATH_INFO $fastcgi_script_name;
+				fastcgi_intercept_errors on;
 			}
 	</tmpl_else>
 
diff --git a/server/conf/vhost.conf.master b/server/conf/vhost.conf.master
index 03b1ed0..104d531 100644
--- a/server/conf/vhost.conf.master
+++ b/server/conf/vhost.conf.master
@@ -415,6 +415,7 @@
 	
 </tmpl_loop>
 <tmpl_if name='ssl_enabled'>
+<tmpl_else>
 <tmpl_if name='rewrite_to_https' op='==' value='y'>
         RewriteCond %{HTTPS} off
         RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
diff --git a/server/lib/classes/cronjob.inc.php b/server/lib/classes/cronjob.inc.php
index 03e36e7..02f4f46 100644
--- a/server/lib/classes/cronjob.inc.php
+++ b/server/lib/classes/cronjob.inc.php
@@ -47,7 +47,30 @@
 
 
 	public function getSchedule() {
-		return $this->_schedule;
+		global $app, $conf;
+		
+		$class = get_class($this);
+		
+		switch ($class) {
+			case 'cronjob_backup':
+				$app->uses('ini_parser,getconf');
+				$server_id = $conf['server_id'];
+				$server_conf = $app->getconf->get_server_config($server_id, 'server');
+				if(isset($server_conf['backup_time']) && $server_conf['backup_time'] != ''){
+					list($hour, $minute) = explode(':', $server_conf['backup_time']);
+					$schedule = $minute.' '.$hour.' * * *';
+				} else {
+					$schedule = '0 0 * * *';
+				}
+				break;
+			/*case 'cronjob_backup_mail':
+				$schedule = '1 0 * * *';
+				break;*/
+			default:
+				$schedule = $this->_schedule;
+		}
+		
+		return $schedule;
 	}
 
 
@@ -56,7 +79,7 @@
 	public function run() {
 
 		print "Called run() for class " . get_class($this) . "\n";
-		print "Job has schedule: " . $this->_schedule . "\n";
+		print "Job has schedule: " . $this->getSchedule() . "\n";
 		$this->onPrepare();
 		$run_it = $this->onBeforeRun();
 		if($run_it == true) {
@@ -86,7 +109,7 @@
 			if($this->_run_at_new == true) {
 				$this->_next_run = ISPConfigDateTime::dbtime(); // run now.
 			} else {
-				$app->cron->parseCronLine($this->_schedule);
+				$app->cron->parseCronLine($this->getSchedule());
 				$next_run = $app->cron->getNextRun(ISPConfigDateTime::dbtime());
 				$this->_next_run = $next_run;
 
@@ -116,7 +139,7 @@
 		// next_run time reached (reached === 0 or -1)
 
 		// calculare next run time based on last_run or current time
-		$app->cron->parseCronLine($this->_schedule);
+		$app->cron->parseCronLine($this->getSchedule());
 		if($this->_no_skip == true) {
 			// we need to calculare the next run based on the previous next_run, as we may not skip one.
 			$next_run = $app->cron->getNextRun($this->_next_run);
diff --git a/server/mods-available/web_module.inc.php b/server/mods-available/web_module.inc.php
index 42eaab6..36e1391 100644
--- a/server/mods-available/web_module.inc.php
+++ b/server/mods-available/web_module.inc.php
@@ -216,13 +216,31 @@
 		} else {
 			$cmd = $app->system->getinitcommand($daemon, 'reload');
 		}
+		
+		if($web_config['server_type'] == 'nginx'){
+			$app->log("Checking nginx configuration...", LOGLEVEL_DEBUG);
+			exec('nginx -t 2>&1', $retval['output'], $retval['retval']);
+			if($retval['retval'] == 0){
+				$app->log("nginx configuration ok!", LOGLEVEL_DEBUG);
+			} else {
+				$app->log("nginx config test failed!", LOGLEVEL_DEBUG);
+				return $retval;
+			}
+		}
+		
 		exec($cmd.' 2>&1', $retval['output'], $retval['retval']);
+		
+		// if restart failed despite successful syntax check => try again
+		if($web_config['server_type'] == 'nginx' && $retval['retval'] > 0){
+			sleep(2);
+			exec($cmd.' 2>&1', $retval['output'], $retval['retval']);
+		}
 		$app->log("Restarting httpd: $cmd", LOGLEVEL_DEBUG);
 		
 		// nginx: do a syntax check because on some distributions, the init script always returns 0 - even if the syntax is not ok (how stupid is that?)
-		if($web_config['server_type'] == 'nginx' && $retval['retval'] == 0){
-			exec('nginx -t 2>&1', $retval['output'], $retval['retval']);
-		}
+		//if($web_config['server_type'] == 'nginx' && $retval['retval'] == 0){
+			//exec('nginx -t 2>&1', $retval['output'], $retval['retval']);
+		//}
 		return $retval;
 	}
 
diff --git a/server/plugins-available/apache2_plugin.inc.php b/server/plugins-available/apache2_plugin.inc.php
index d5406b5..605d17d 100644
--- a/server/plugins-available/apache2_plugin.inc.php
+++ b/server/plugins-available/apache2_plugin.inc.php
@@ -163,7 +163,7 @@
 			}
 			
 			if(intval($web_data['directive_snippets_id']) > 0){
-				$snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'nginx' AND active = 'y' AND customer_viewable = 'y'", intval($web_data['directive_snippets_id']));
+				$snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'apache' AND active = 'y' AND customer_viewable = 'y'", intval($web_data['directive_snippets_id']));
 				if(isset($snippet['required_php_snippets']) && trim($snippet['required_php_snippets']) != ''){
 					$required_php_snippets = explode(',', trim($snippet['required_php_snippets']));
 					if(is_array($required_php_snippets) && !empty($required_php_snippets)){
@@ -1038,7 +1038,7 @@
 			$php_ini_content .= str_replace("\r", '', trim($data['new']['custom_php_ini']));
 			
 			if(intval($data['new']['directive_snippets_id']) > 0){
-				$snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'nginx' AND active = 'y' AND customer_viewable = 'y'", intval($data['new']['directive_snippets_id']));
+				$snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'apache' AND active = 'y' AND customer_viewable = 'y'", intval($data['new']['directive_snippets_id']));
 				if(isset($snippet['required_php_snippets']) && trim($snippet['required_php_snippets']) != ''){
 					$required_php_snippets = explode(',', trim($snippet['required_php_snippets']));
 					if(is_array($required_php_snippets) && !empty($required_php_snippets)){
@@ -2926,19 +2926,19 @@
 			$monit_content = file_get_contents($conf['rootpath'] . '/conf/hhvm_monit.master');
 		}
 		
-		if($data['new']['php'] == 'hhvm' && $data['old']['php'] != 'hhvm' || $data['new']['custom_php_ini'] != $data['old']['custom_php_ini']) {
+		if($data['new']['php'] == 'hhvm' && $data['old']['php'] != 'hhvm' || (isset($data['old']['custom_php_ini']) && $data['new']['custom_php_ini'] != $data['old']['custom_php_ini'])) {
 		
 			// Custom php.ini settings
 			$custom_php_ini_settings = trim($data['new']['custom_php_ini']);
 			if(intval($data['new']['directive_snippets_id']) > 0){
-				$snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'nginx' AND active = 'y' AND customer_viewable = 'y'", intval($data['new']['directive_snippets_id']));
+				$snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'apache' AND active = 'y' AND customer_viewable = 'y'", intval($data['new']['directive_snippets_id']));
 				if(isset($snippet['required_php_snippets']) && trim($snippet['required_php_snippets']) != ''){
 					$required_php_snippets = explode(',', trim($snippet['required_php_snippets']));
 					if(is_array($required_php_snippets) && !empty($required_php_snippets)){
 						foreach($required_php_snippets as $required_php_snippet){
 							$required_php_snippet = intval($required_php_snippet);
 							if($required_php_snippet > 0){
-								$php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet);
+								$php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE ".($snippet['master_directive_snippets_id'] > 0 ? 'master_' : '')."directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet);
 								$php_snippet['snippet'] = trim($php_snippet['snippet']);
 								if($php_snippet['snippet'] != ''){
 									$custom_php_ini_settings .= "\n".$php_snippet['snippet'];
@@ -2954,7 +2954,7 @@
 				$custom_php_ini_settings = str_replace("\r", "\n", $custom_php_ini_settings);
 				file_put_contents('/etc/hhvm/'.$data['new']['system_user'].'.ini', $custom_php_ini_settings);
 			} else {
-				if(is_file('/etc/hhvm/'.$data['old']['system_user'].'.ini')) unlink('/etc/hhvm/'.$data['old']['system_user'].'.ini');
+				if($data['old']['system_user'] != '' && is_file('/etc/hhvm/'.$data['old']['system_user'].'.ini')) unlink('/etc/hhvm/'.$data['old']['system_user'].'.ini');
 			}
 			
 			$content = str_replace('{SYSTEM_USER}', $data['new']['system_user'], $content);
@@ -2971,10 +2971,12 @@
 			}
 			
  		} elseif($data['new']['php'] != 'hhvm' && $data['old']['php'] == 'hhvm') {
-			exec('/etc/init.d/hhvm_' . $data['old']['system_user'] . ' stop >/dev/null 2>&1');
-			exec('/usr/sbin/update-rc.d hhvm_' . $data['old']['system_user'] . ' remove >/dev/null 2>&1');
-			unlink('/etc/init.d/hhvm_' . $data['old']['system_user']);
-			if(is_file('/etc/hhvm/'.$data['old']['system_user'].'.ini')) unlink('/etc/hhvm/'.$data['old']['system_user'].'.ini');
+			if($data['old']['system_user'] != ''){
+				exec('/etc/init.d/hhvm_' . $data['old']['system_user'] . ' stop >/dev/null 2>&1');
+				exec('/usr/sbin/update-rc.d hhvm_' . $data['old']['system_user'] . ' remove >/dev/null 2>&1');
+				unlink('/etc/init.d/hhvm_' . $data['old']['system_user']);
+				if(is_file('/etc/hhvm/'.$data['old']['system_user'].'.ini')) unlink('/etc/hhvm/'.$data['old']['system_user'].'.ini');
+			}
 			
 			if(is_file('/etc/monit/conf.d/hhvm_' . $data['new']['system_user']) || is_file('/etc/monit/conf.d/00-hhvm_' . $data['new']['system_user'])){
 				if(is_file('/etc/monit/conf.d/hhvm_' . $data['new']['system_user'])){
@@ -3089,7 +3091,7 @@
 					foreach($required_php_snippets as $required_php_snippet){
 						$required_php_snippet = intval($required_php_snippet);
 						if($required_php_snippet > 0){
-							$php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet);
+							$php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE ".($snippet['master_directive_snippets_id'] > 0 ? 'master_' : '')."directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet);
 							$php_snippet['snippet'] = trim($php_snippet['snippet']);
 							if($php_snippet['snippet'] != ''){
 								$custom_php_ini_settings .= "\n".$php_snippet['snippet'];
diff --git a/server/plugins-available/nginx_plugin.inc.php b/server/plugins-available/nginx_plugin.inc.php
index aaab39b..3437b55 100644
--- a/server/plugins-available/nginx_plugin.inc.php
+++ b/server/plugins-available/nginx_plugin.inc.php
@@ -372,6 +372,19 @@
 		$log_folder = 'log';
 		$old_web_folder = 'web';
 		$old_log_folder = 'log';
+		if($data['new']['type'] == 'vhost'){
+			if($data['new']['web_folder'] != ''){
+				if(substr($data['new']['web_folder'],0,1) == '/') $data['new']['web_folder'] = substr($data['new']['web_folder'],1);
+				if(substr($data['new']['web_folder'],-1) == '/') $data['new']['web_folder'] = substr($data['new']['web_folder'],0,-1);
+			}
+			$web_folder .= '/'.$data['new']['web_folder'];
+			
+			if($data['old']['web_folder'] != ''){
+				if(substr($data['old']['web_folder'],0,1) == '/') $data['old']['web_folder'] = substr($data['old']['web_folder'],1);
+				if(substr($data['old']['web_folder'],-1) == '/') $data['old']['web_folder'] = substr($data['old']['web_folder'],0,-1);
+			}
+			$old_web_folder .= '/'.$data['old']['web_folder'];
+		}
 		if($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') {
 			// new one
 			$tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = ?', $data['new']['parent_domain_id']);
@@ -475,8 +488,7 @@
 				}
 				
 				//* Unmount the old log directory bfore we move the log dir
-				//exec('fuser -km '.escapeshellcmd($old_dir.'/log'));
-				exec('umount '.escapeshellcmd($data['old']['document_root'].'/log'));
+				exec('umount '.escapeshellcmd($old_dir.'/log'));
 
 				//* Create new base directory, if it does not exist yet
 				if(!is_dir($new_dir)) $app->system->mkdirpath($new_dir);
@@ -729,7 +741,7 @@
 		if($data['new']['type'] == 'vhost' && $web_config['security_level'] == 20) $app->system->add_user_to_group($groupname, escapeshellcmd($web_config['nginx_user']));
 
 		//* If the security level is set to high
-		if(($this->action == 'insert' && $data['new']['type'] == 'vhost') or ($web_config['set_folder_permissions_on_update'] == 'y' && $data['new']['type'] == 'vhost')) {
+		if(($this->action == 'insert' && $data['new']['type'] == 'vhost') or ($web_config['set_folder_permissions_on_update'] == 'y' && $data['new']['type'] == 'vhost') or ($web_folder != $old_web_folder && $data['new']['type'] == 'vhost')) {
 
 			$app->system->web_folder_protection($data['new']['document_root'], false);
 
@@ -743,6 +755,7 @@
 				//$app->system->chmod($data['new']['document_root'].'/webdav',0710);
 				$app->system->chmod($data['new']['document_root'].'/private', 0710);
 				$app->system->chmod($data['new']['document_root'].'/ssl', 0755);
+				if($web_folder != 'web') $app->system->chmod($data['new']['document_root'].'/'.$web_folder, 0751);
 
 				// make tmp directory writable for nginx and the website users
 				$app->system->chmod($data['new']['document_root'].'/tmp', 0770);
@@ -794,6 +807,11 @@
 				//$app->system->chgrp($data['new']['document_root'].'/webdav',$groupname);
 				$app->system->chown($data['new']['document_root'].'/private', $username);
 				$app->system->chgrp($data['new']['document_root'].'/private', $groupname);
+				
+				if($web_folder != 'web'){
+					$app->system->chown($data['new']['document_root'].'/'.$web_folder, $username);
+					$app->system->chgrp($data['new']['document_root'].'/'.$web_folder, $groupname);
+				}
 
 				// If the security Level is set to medium
 			} else {
@@ -803,6 +821,7 @@
 				//$app->system->chmod($data['new']['document_root'].'/webdav',0755);
 				$app->system->chmod($data['new']['document_root'].'/ssl', 0755);
 				$app->system->chmod($data['new']['document_root'].'/cgi-bin', 0755);
+				if($web_folder != 'web') $app->system->chmod($data['new']['document_root'].'/'.$web_folder, 0755);
 
 				// make temp directory writable for nginx and the website users
 				$app->system->chmod($data['new']['document_root'].'/tmp', 0770);
@@ -833,6 +852,11 @@
 				$app->system->chgrp($data['new']['document_root'].'/web/stats', $groupname);
 				//$app->system->chown($data['new']['document_root'].'/webdav',$username);
 				//$app->system->chgrp($data['new']['document_root'].'/webdav',$groupname);
+				
+				if($web_folder != 'web'){
+					$app->system->chown($data['new']['document_root'].'/'.$web_folder, $username);
+					$app->system->chgrp($data['new']['document_root'].'/'.$web_folder, $groupname);
+				}
 			}
 		} elseif((($data['new']['type'] == 'vhostsubdomain') || ($data['new']['type'] == 'vhostalias')) &&
 				 (($this->action == 'insert') || ($web_config['set_folder_permissions_on_update'] == 'y'))) {
@@ -953,7 +977,7 @@
 			$default_php_fpm = true;
 		}
 		*/
-		if($data['new']['php'] == 'php-fpm'){
+		if($data['new']['php'] == 'php-fpm' || $data['new']['php'] == 'hhvm'){
 			if(trim($data['new']['fastcgi_php_version']) != ''){
 				$default_php_fpm = false;
 				list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version']));
@@ -1128,6 +1152,58 @@
 			$nginx_directives = $data['new']['nginx_directives'];
 			$vhost_data['enable_pagespeed'] = false;
 		}
+		
+		// folder_directive_snippets
+		if(trim($data['new']['folder_directive_snippets']) != ''){
+			$data['new']['folder_directive_snippets'] = trim($data['new']['folder_directive_snippets']);
+			$data['new']['folder_directive_snippets'] = str_replace("\r\n", "\n", $data['new']['folder_directive_snippets']);
+			$data['new']['folder_directive_snippets'] = str_replace("\r", "\n", $data['new']['folder_directive_snippets']);
+			$folder_directive_snippets_lines = explode("\n", $data['new']['folder_directive_snippets']);
+			
+			if(is_array($folder_directive_snippets_lines) && !empty($folder_directive_snippets_lines)){
+				foreach($folder_directive_snippets_lines as $folder_directive_snippets_line){
+					list($folder_directive_snippets_folder, $folder_directive_snippets_snippets_id) = explode(':', $folder_directive_snippets_line);
+					
+					$folder_directive_snippets_folder = trim($folder_directive_snippets_folder);
+					$folder_directive_snippets_snippets_id = trim($folder_directive_snippets_snippets_id);
+					
+					if($folder_directive_snippets_folder  != '' && intval($folder_directive_snippets_snippets_id) > 0 && preg_match('@^((?!(.*\.\.)|(.*\./)|(.*//))[^/][\w/_\.\-]{1,100})?$@', $folder_directive_snippets_folder)){
+						if(substr($folder_directive_snippets_folder, -1) != '/') $folder_directive_snippets_folder .= '/';
+						if(substr($folder_directive_snippets_folder, 0, 1) == '/') $folder_directive_snippets_folder = substr($folder_directive_snippets_folder, 1);
+						
+						$master_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'nginx' AND active = 'y' AND customer_viewable = 'y'", intval($folder_directive_snippets_snippets_id));
+						if(isset($master_snippet['snippet'])){
+							$folder_directive_snippets_trans = array('{FOLDER}' => $folder_directive_snippets_folder, '{FOLDERMD5}' => md5($folder_directive_snippets_folder));
+							$master_snippet['snippet'] = strtr($master_snippet['snippet'], $folder_directive_snippets_trans);
+							$nginx_directives .= "\n\n".$master_snippet['snippet'];
+							
+							// create folder it it does not exist
+							if(!is_dir($data['new']['document_root'].'/' . $web_folder.$folder_directive_snippets_folder)){
+								$app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder.$folder_directive_snippets_folder);
+								$app->system->chown($data['new']['document_root'].'/' . $web_folder.$folder_directive_snippets_folder, $username);
+								$app->system->chgrp($data['new']['document_root'].'/' . $web_folder.$folder_directive_snippets_folder, $groupname);
+							}
+						}
+					}
+				}
+			}
+		}
+		
+		// use vLib for template logic
+		$nginx_directives_new = '';
+		$ngx_conf_tpl = new tpl();
+		$ngx_conf_tpl_tmp_file = tempnam($conf['temppath'], "ngx");
+		file_put_contents($ngx_conf_tpl_tmp_file, $nginx_directives);
+		$ngx_conf_tpl->newTemplate($ngx_conf_tpl_tmp_file);
+		$ngx_conf_tpl->setVar('use_tcp', $use_tcp);
+		$ngx_conf_tpl->setVar('use_socket', $use_socket);
+		$ngx_conf_tpl->setVar('fpm_socket', $fpm_socket);
+		$ngx_conf_tpl->setVar($vhost_data);
+		$nginx_directives_new = $ngx_conf_tpl->grab();
+		if(is_file($ngx_conf_tpl_tmp_file)) unlink($ngx_conf_tpl_tmp_file);
+		if($nginx_directives_new != '') $nginx_directives = $nginx_directives_new;
+		unset($nginx_directives_new);
+		
 		// Make sure we only have Unix linebreaks
 		$nginx_directives = str_replace("\r\n", "\n", $nginx_directives);
 		$nginx_directives = str_replace("\r", "\n", $nginx_directives);
@@ -1448,6 +1524,18 @@
 					'use_rewrite' => ($data['new']['redirect_type'] == 'proxy' ? false:true),
 					'use_proxy' => ($data['new']['redirect_type'] == 'proxy' ? true:false));
 			}
+		}
+		
+		// http2 or spdy?
+		$vhost_data['enable_http2']  = 'n';
+		if($vhost_data['enable_spdy'] == 'y'){
+			// check if nginx support http_v2; if so, use that instead of spdy
+			exec("2>&1 nginx -V | tr -- - '\n' | grep http_v2_module", $tmp_output, $tmp_retval);
+			if($tmp_retval == 0){
+				$vhost_data['enable_http2']  = 'y';
+				$vhost_data['enable_spdy'] = 'n';
+			}
+			unset($tmp_output, $tmp_retval);
 		}
 
 		$tpl->setVar($vhost_data);
@@ -2115,6 +2203,7 @@
 					$this->php_fpm_pool_delete($data, $web_config);
 				} elseif($data['old']['php'] == 'hhvm') {
 					$this->hhvm_update($data, $web_config);
+					$this->php_fpm_pool_delete($data, $web_config);
 				}
 
 				//remove the php cgi starter script if available
@@ -2485,7 +2574,7 @@
 			$monit_content = file_get_contents($conf['rootpath'] . '/conf/hhvm_monit.master');
 		}
 		
-		if($data['new']['php'] == 'hhvm' && $data['old']['php'] != 'hhvm' || $data['new']['custom_php_ini'] != $data['old']['custom_php_ini']) {
+		if($data['new']['php'] == 'hhvm' && $data['old']['php'] != 'hhvm' || (isset($data['old']['custom_php_ini']) && isset($data['new']['custom_php_ini']) && $data['new']['custom_php_ini'] != $data['old']['custom_php_ini'])) {
 
 			// Custom php.ini settings
 			$custom_php_ini_settings = trim($data['new']['custom_php_ini']);
@@ -2497,7 +2586,7 @@
 						foreach($required_php_snippets as $required_php_snippet){
 							$required_php_snippet = intval($required_php_snippet);
 							if($required_php_snippet > 0){
-								$php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet);
+								$php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE ".($snippet['master_directive_snippets_id'] > 0 ? 'master_' : '')."directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet);
 								$php_snippet['snippet'] = trim($php_snippet['snippet']);
 								if($php_snippet['snippet'] != ''){
 									$custom_php_ini_settings .= "\n".$php_snippet['snippet'];
@@ -2507,13 +2596,14 @@
 					}
 				}
 			}
+			
 			if($custom_php_ini_settings != ''){
 				// Make sure we only have Unix linebreaks
 				$custom_php_ini_settings = str_replace("\r\n", "\n", $custom_php_ini_settings);
 				$custom_php_ini_settings = str_replace("\r", "\n", $custom_php_ini_settings);
 				file_put_contents('/etc/hhvm/'.$data['new']['system_user'].'.ini', $custom_php_ini_settings);
 			} else {
-				if(is_file('/etc/hhvm/'.$data['old']['system_user'].'.ini')) unlink('/etc/hhvm/'.$data['old']['system_user'].'.ini');
+				if($data['old']['system_user'] != '' && is_file('/etc/hhvm/'.$data['old']['system_user'].'.ini')) unlink('/etc/hhvm/'.$data['old']['system_user'].'.ini');
 			}
 		
 			$content = str_replace('{SYSTEM_USER}', $data['new']['system_user'], $content);
@@ -2530,17 +2620,19 @@
 			}
 			
  		} elseif($data['new']['php'] != 'hhvm' && $data['old']['php'] == 'hhvm') {
-			exec('/etc/init.d/hhvm_' . $data['old']['system_user'] . ' stop >/dev/null 2>&1');
-			exec('/usr/sbin/update-rc.d hhvm_' . $data['old']['system_user'] . ' remove >/dev/null 2>&1');
-			unlink('/etc/init.d/hhvm_' . $data['old']['system_user']);
-			if(is_file('/etc/hhvm/'.$data['old']['system_user'].'.ini')) unlink('/etc/hhvm/'.$data['old']['system_user'].'.ini');
+			if($data['old']['system_user'] != ''){
+				exec('/etc/init.d/hhvm_' . $data['old']['system_user'] . ' stop >/dev/null 2>&1');
+				exec('/usr/sbin/update-rc.d hhvm_' . $data['old']['system_user'] . ' remove >/dev/null 2>&1');
+				unlink('/etc/init.d/hhvm_' . $data['old']['system_user']);
+				if(is_file('/etc/hhvm/'.$data['old']['system_user'].'.ini')) unlink('/etc/hhvm/'.$data['old']['system_user'].'.ini');
+			}
 			
-			if(is_file('/etc/monit/conf.d/hhvm_' . $data['new']['system_user']) || is_file('/etc/monit/conf.d/00-hhvm_' . $data['new']['system_user'])){
-				if(is_file('/etc/monit/conf.d/hhvm_' . $data['new']['system_user'])){
-					unlink('/etc/monit/conf.d/hhvm_' . $data['new']['system_user']);
+			if(is_file('/etc/monit/conf.d/hhvm_' . $data['old']['system_user']) || is_file('/etc/monit/conf.d/00-hhvm_' . $data['old']['system_user'])){
+				if(is_file('/etc/monit/conf.d/hhvm_' . $data['old']['system_user'])){
+					unlink('/etc/monit/conf.d/hhvm_' . $data['old']['system_user']);
 				}
-				if(is_file('/etc/monit/conf.d/00-hhvm_' . $data['new']['system_user'])){
-					unlink('/etc/monit/conf.d/00-hhvm_' . $data['new']['system_user']);
+				if(is_file('/etc/monit/conf.d/00-hhvm_' . $data['old']['system_user'])){
+					unlink('/etc/monit/conf.d/00-hhvm_' . $data['old']['system_user']);
 				}
 				exec('/etc/init.d/monit restart >/dev/null 2>&1');
 			}
@@ -2560,7 +2652,8 @@
 			$default_php_fpm = true;
 		}
 		*/
-		if($data['new']['php'] == 'php-fpm'){
+		// HHVM => PHP-FPM-Fallback
+		if($data['new']['php'] == 'php-fpm' || $data['new']['php'] == 'hhvm'){
 			if(trim($data['new']['fastcgi_php_version']) != ''){
 				$default_php_fpm = false;
 				list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version']));
@@ -2581,7 +2674,8 @@
 		$app->uses("getconf");
 		$web_config = $app->getconf->get_server_config($conf["server_id"], 'web');
 
-		if($data['new']['php'] != 'php-fpm'){
+		// HHVM => PHP-FPM-Fallback
+		if($data['new']['php'] != 'php-fpm' && $data['new']['php'] != 'hhvm'){
 			if(@is_file($pool_dir.$pool_name.'.conf')){
 				$app->system->unlink($pool_dir.$pool_name.'.conf');
 				//$reload = true;
@@ -2649,7 +2743,7 @@
 					foreach($required_php_snippets as $required_php_snippet){
 						$required_php_snippet = intval($required_php_snippet);
 						if($required_php_snippet > 0){
-							$php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet);
+							$php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE ".($snippet['master_directive_snippets_id'] > 0 ? 'master_' : '')."directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet);
 							$php_snippet['snippet'] = trim($php_snippet['snippet']);
 							if($php_snippet['snippet'] != ''){
 								$custom_php_ini_settings .= "\n".$php_snippet['snippet'];
diff --git a/server/plugins-available/shelluser_jailkit_plugin.inc.php b/server/plugins-available/shelluser_jailkit_plugin.inc.php
index aabbcde..4c400c7 100755
--- a/server/plugins-available/shelluser_jailkit_plugin.inc.php
+++ b/server/plugins-available/shelluser_jailkit_plugin.inc.php
@@ -301,7 +301,7 @@
 			file_put_contents($bashrc, $tpl->grab());
 			unset($tpl);
 
-			$this->app->log("Added bashrc script : ".$bashrc, LOGLEVEL_DEBUG);
+			$this->app->log("Added bashrc script: ".$bashrc, LOGLEVEL_DEBUG);
 
 			$tpl = new tpl();
 			$tpl->newTemplate("motd.master");
@@ -318,13 +318,21 @@
 
 	function _add_jailkit_programs()
 	{
-		//copy over further programs and its libraries
-		$command = '/usr/local/ispconfig/server/scripts/create_jailkit_programs.sh';
-		$command .= ' '.escapeshellcmd($this->data['new']['dir']);
-		$command .= ' \''.$this->jailkit_config['jailkit_chroot_app_programs'].'\'';
-		exec($command.' 2>/dev/null');
+		$jailkit_chroot_app_programs = preg_split("/[\s,]+/", $this->jailkit_config['jailkit_chroot_app_programs']);
+		if(is_array($jailkit_chroot_app_programs) && !empty($jailkit_chroot_app_programs)){
+			foreach($jailkit_chroot_app_programs as $jailkit_chroot_app_program){
+				$jailkit_chroot_app_program = trim($jailkit_chroot_app_program);
+				if(is_file($jailkit_chroot_app_program) || is_dir($jailkit_chroot_app_program)){			
+					//copy over further programs and its libraries
+					$command = '/usr/local/ispconfig/server/scripts/create_jailkit_programs.sh';
+					$command .= ' '.escapeshellcmd($this->data['new']['dir']);
+					$command .= ' '.$jailkit_chroot_app_program;
+					exec($command.' 2>/dev/null');
 
-		$this->app->log("Added programs to jailkit chroot with command: ".$command, LOGLEVEL_DEBUG);
+					$this->app->log("Added programs to jailkit chroot with command: ".$command, LOGLEVEL_DEBUG);
+				}
+			}
+		}
 	}
 
 	function _get_home_dir($username)

--
Gitblit v1.9.1