From dd0130670fe3cab4c7e2c1ab4f3bf0d2b2d512b0 Mon Sep 17 00:00:00 2001
From: Denny Bortfeldt <denny@bortfeldt.net>
Date: Mon, 27 Jun 2016 18:02:16 -0400
Subject: [PATCH] When uploading a logo which is smaller than the current ispconfig one, then the logo will be on the left side of the header. In my opinion it will look better when it's centered. You could vote about it ;)

---
 server/plugins-available/apache2_plugin.inc.php |  836 +++++++++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 631 insertions(+), 205 deletions(-)

diff --git a/server/plugins-available/apache2_plugin.inc.php b/server/plugins-available/apache2_plugin.inc.php
index 499f23e..6763399 100644
--- a/server/plugins-available/apache2_plugin.inc.php
+++ b/server/plugins-available/apache2_plugin.inc.php
@@ -91,8 +91,52 @@
 		$app->plugins->registerAction('php_ini_changed', $this->plugin_name, 'php_ini_changed');
 	}
 
-	// check for php.ini changes
-
+	private function get_master_php_ini_content($web_data) {
+		global $app, $conf;
+		
+		$app->uses('getconf');
+		$web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
+		$fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi');
+		
+		$php_ini_content = '';
+		$master_php_ini_path = '';
+		
+		if($web_data['php'] == 'mod') {
+			$master_php_ini_path = $web_config['php_ini_path_apache'];
+		} else {
+			// check for custom php
+			if($web_data['fastcgi_php_version'] != '') {
+				$tmp = explode(':', $web_data['fastcgi_php_version']);
+				if(isset($tmp[2])) {
+					$tmppath = $tmp[2];
+					if(substr($tmppath, -7) != 'php.ini') {
+						if(substr($tmppath, -1) != '/') $tmppath .= '/';
+						$tmppath .= 'php.ini';
+					}
+					if(file_exists($tmppath)) {
+						$master_php_ini_path = $tmppath;
+					}
+					unset($tmppath);
+				}
+				unset($tmp);
+			}
+			
+			if(!$master_php_ini_path) {
+				if($web_data['php'] == 'fast-cgi' && file_exists($fastcgi_config["fastcgi_phpini_path"])) {
+					$master_php_ini_path = $fastcgi_config["fastcgi_phpini_path"];
+				} elseif($web_data['php'] == 'php-fpm' && file_exists($web_config['php_fpm_ini_path'])) {
+					$master_php_ini_path = $fastcgi_config["fastcgi_phpini_path"];
+				} else {
+					$master_php_ini_path = $web_config['php_ini_path_cgi'];
+				}
+			}
+		}
+		if($master_php_ini_path != '' && substr($master_php_ini_path, -7) == 'php.ini' && is_file($master_php_ini_path)) {
+			$php_ini_content .= $app->system->file_get_contents($master_php_ini_path)."\n";
+		}
+		
+		return $php_ini_content;
+	}
 
 	// Handle php.ini changes
 	function php_ini_changed($event_name, $data) {
@@ -104,22 +148,31 @@
 
 		/* $data contains an array with these keys:
          * file -> full path of changed php_ini
-         * mode -> web_domain php modes to change (mod, fast-cgi, php-fpm or '' for all except 'mod')
+         * mode -> web_domain php modes to change (mod, fast-cgi, php-fpm, hhvm or '' for all except 'mod')
          * php_version -> php ini path that changed (additional php versions)
          */
 
+		$param = '';
 		$qrystr = "SELECT * FROM web_domain WHERE custom_php_ini != ''";
 		if($data['mode'] == 'mod') {
 			$qrystr .= " AND php = 'mod'";
 		} elseif($data['mode'] == 'fast-cgi') {
 			$qrystr .= " AND php = 'fast-cgi'";
 			if($data['php_version']) {
-				$qrystr .= " AND fastcgi_php_version LIKE '%:" . $app->db->quote($data['php_version']) . "'";
+				$qrystr .= " AND fastcgi_php_version LIKE ?";
+				$param = '%:' . $data['php_version'];
 			}
 		} elseif($data['mode'] == 'php-fpm') {
 			$qrystr .= " AND php = 'php-fpm'";
 			if($data['php_version']) {
-				$qrystr .= " AND fastcgi_php_version LIKE '%:" . $app->db->quote($data['php_version']) . ":%'";
+				$qrystr .= " AND fastcgi_php_version LIKE ?";
+				$param = '%:' . $data['php_version'] . ':%';
+			}
+		} elseif($data['mode'] == 'hhvm') {
+			$qrystr .= " AND php = 'hhvm'";
+			if($data['php_version']) {
+				$qrystr .= " AND fastcgi_php_version LIKE ?";
+				$param = '%:' . $data['php_version'] . ':%';
 			}
 		} else {
 			$qrystr .= " AND php != 'mod' AND php != 'fast-cgi'";
@@ -127,31 +180,39 @@
 
 
 		//** Get all the webs
-		$web_domains = $app->db->queryAllRecords($qrystr);
+		$web_domains = $app->db->queryAllRecords($qrystr, $param);
 		foreach($web_domains as $web_data) {
 			$custom_php_ini_dir = $web_config['website_basedir'].'/conf/'.$web_data['system_user'];
 			$web_folder = 'web';
-			if($web_data['type'] == 'vhostsubdomain') {
+			if($web_data['type'] == 'vhostsubdomain' || $web_data['type'] == 'vhostalias') {
 				$web_folder = $web_data['web_folder'];
 				$custom_php_ini_dir .= '_' . $web_folder;
 			}
 			if(!is_dir($web_config['website_basedir'].'/conf')) $app->system->mkdir($web_config['website_basedir'].'/conf');
-
-
+			
 			if(!is_dir($custom_php_ini_dir)) $app->system->mkdir($custom_php_ini_dir);
-			$php_ini_content = '';
-			if($web_data['php'] == 'mod') {
-				$master_php_ini_path = $web_config['php_ini_path_apache'];
-			} else {
-				if($web_data['php'] == 'fast-cgi' && file_exists($fastcgi_config["fastcgi_phpini_path"])) {
-					$master_php_ini_path = $fastcgi_config["fastcgi_phpini_path"];
-				} else {
-					$master_php_ini_path = $web_config['php_ini_path_cgi'];
+			
+			$php_ini_content = $this->get_master_php_ini_content($web_data);
+			
+			if(intval($web_data['directive_snippets_id']) > 0){
+				$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)){
+						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['snippet'] = trim($php_snippet['snippet']);
+								if($php_snippet['snippet'] != ''){
+									$web_data['custom_php_ini'] .= "\n".$php_snippet['snippet'];
+								}
+							}
+						}
+					}
 				}
 			}
-			if($master_php_ini_path != '' && substr($master_php_ini_path, -7) == 'php.ini' && is_file($master_php_ini_path)) {
-				$php_ini_content .= $app->system->file_get_contents($master_php_ini_path)."\n";
-			}
+		
 			$php_ini_content .= str_replace("\r", '', trim($web_data['custom_php_ini']));
 			$app->system->file_put_contents($custom_php_ini_dir.'/php.ini', $php_ini_content);
 			$app->log('Info: rewrote custom php.ini for web ' . $web_data['domain_id'] . ' (' . $web_data['domain'] . ').', LOGLEVEL_DEBUG);
@@ -192,7 +253,7 @@
 			$app->log("CA path error, file does not exist:".$web_config['CA_path'].'/openssl.cnf', LOGLEVEL_ERROR);
 
 		//* Only vhosts can have a ssl cert
-		if($data["new"]["type"] != "vhost" && $data["new"]["type"] != "vhostsubdomain") return;
+		if($data["new"]["type"] != "vhost" && $data["new"]["type"] != "vhostsubdomain" && $data["new"]["type"] != "vhostalias") return;
 
 		// if(!is_dir($data['new']['document_root'].'/ssl')) exec('mkdir -p '.$data['new']['document_root'].'/ssl');
 		if(!is_dir($data['new']['document_root'].'/ssl')) $app->system->mkdirpath($data['new']['document_root'].'/ssl');
@@ -237,6 +298,7 @@
 
         [ req ]
         default_bits           = 2048
+		default_md             = sha256
         default_keyfile        = keyfile.pem
         distinguished_name     = req_distinguished_name
         attributes             = req_attributes
@@ -245,45 +307,49 @@
 
         [ req_distinguished_name ]
         C                      = ".trim($data['new']['ssl_country'])."
-        ST                     = ".trim($data['new']['ssl_state'])."
-        L                      = ".trim($data['new']['ssl_locality'])."
-        O                      = ".trim($data['new']['ssl_organisation'])."
-        OU                     = ".trim($data['new']['ssl_organisation_unit'])."
+        " . (trim($data['new']['ssl_state']) == '' ? '' : "ST                     = ".trim($data['new']['ssl_state'])) . "
+        " . (trim($data['new']['ssl_locality']) == '' ? '' : "L                      = ".trim($data['new']['ssl_locality']))."
+        " . (trim($data['new']['ssl_organisation']) == '' ? '' : "O                      = ".trim($data['new']['ssl_organisation']))."
+        " . (trim($data['new']['ssl_organisation_unit']) == '' ? '' : "OU                     = ".trim($data['new']['ssl_organisation_unit']))."
         CN                     = $domain
         emailAddress           = webmaster@".$data['new']['domain']."
 
         [ req_attributes ]
-        challengePassword              = A challenge password";
+        ";//challengePassword              = A challenge password";
 
 			$ssl_cnf_file = $ssl_dir.'/openssl.conf';
 			$app->system->file_put_contents($ssl_cnf_file, $ssl_cnf);
 
 			$rand_file = escapeshellcmd($rand_file);
 			$key_file = escapeshellcmd($key_file);
+			$openssl_cmd_key_file = $key_file;
 			if(substr($domain, 0, 2) == '*.' && strpos($key_file, '/ssl/\*.') !== false) $key_file = str_replace('/ssl/\*.', '/ssl/*.', $key_file); // wildcard certificate
 			$key_file2 = escapeshellcmd($key_file2);
+			$openssl_cmd_key_file2 = $key_file2;
 			if(substr($domain, 0, 2) == '*.' && strpos($key_file2, '/ssl/\*.') !== false) $key_file2 = str_replace('/ssl/\*.', '/ssl/*.', $key_file2); // wildcard certificate
 			$ssl_days = 3650;
 			$csr_file = escapeshellcmd($csr_file);
+			$openssl_cmd_csr_file = $csr_file;
 			if(substr($domain, 0, 2) == '*.' && strpos($csr_file, '/ssl/\*.') !== false) $csr_file = str_replace('/ssl/\*.', '/ssl/*.', $csr_file); // wildcard certificate
 			$config_file = escapeshellcmd($ssl_cnf_file);
 			$crt_file = escapeshellcmd($crt_file);
+			$openssl_cmd_crt_file = $crt_file;
 			if(substr($domain, 0, 2) == '*.' && strpos($crt_file, '/ssl/\*.') !== false) $crt_file = str_replace('/ssl/\*.', '/ssl/*.', $crt_file); // wildcard certificate
 
 			if(is_file($ssl_cnf_file) && !is_link($ssl_cnf_file)) {
 
-				exec("openssl genrsa -des3 -rand $rand_file -passout pass:$ssl_password -out $key_file 2048");
-				exec("openssl req -new -passin pass:$ssl_password -passout pass:$ssl_password -key $key_file -out $csr_file -days $ssl_days -config $config_file");
-				exec("openssl rsa -passin pass:$ssl_password -in $key_file -out $key_file2");
+				exec("openssl genrsa -des3 -rand $rand_file -passout pass:$ssl_password -out $openssl_cmd_key_file 2048");
+				exec("openssl req -new -sha256 -passin pass:$ssl_password -passout pass:$ssl_password -key $openssl_cmd_key_file -out $openssl_cmd_csr_file -days $ssl_days -config $config_file");
+				exec("openssl rsa -passin pass:$ssl_password -in $openssl_cmd_key_file -out $openssl_cmd_key_file2");
 
 				if(file_exists($web_config['CA_path'].'/openssl.cnf'))
 				{
-					exec("openssl ca -batch -out $crt_file -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -in $csr_file");
+					exec("openssl ca -batch -out $openssl_cmd_crt_file -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -in $openssl_cmd_csr_file");
 					$app->log("Creating CA-signed SSL Cert for: $domain", LOGLEVEL_DEBUG);
-					if (filesize($crt_file)==0 || !file_exists($crt_file)) $app->log("CA-Certificate signing failed.  openssl ca -out $crt_file -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -in $csr_file", LOGLEVEL_ERROR);
+					if (filesize($crt_file)==0 || !file_exists($crt_file)) $app->log("CA-Certificate signing failed.  openssl ca -out $openssl_cmd_crt_file -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -in $openssl_cmd_csr_file", LOGLEVEL_ERROR);
 				};
 				if (@filesize($crt_file)==0 || !file_exists($crt_file)){
-					exec("openssl req -x509 -passin pass:$ssl_password -passout pass:$ssl_password -key $key_file -in $csr_file -out $crt_file -days $ssl_days -config $config_file ");
+					exec("openssl req -x509 -passin pass:$ssl_password -passout pass:$ssl_password -key $openssl_cmd_key_file -in $openssl_cmd_csr_file -out $openssl_cmd_crt_file -days $ssl_days -config $config_file ");
 					$app->log("Creating self-signed SSL Cert for: $domain", LOGLEVEL_DEBUG);
 				};
 
@@ -293,15 +359,31 @@
 			$app->system->chmod($key_file2, 0400);
 			@$app->system->unlink($config_file);
 			@$app->system->unlink($rand_file);
-			$ssl_request = $app->db->quote($app->system->file_get_contents($csr_file));
-			$ssl_cert = $app->db->quote($app->system->file_get_contents($crt_file));
-			$ssl_key2 = $app->db->quote($app->system->file_get_contents($key_file2));
+			$ssl_request = $app->system->file_get_contents($csr_file);
+			$ssl_cert = $app->system->file_get_contents($crt_file);
+			$ssl_key2 = $app->system->file_get_contents($key_file2);
 			/* Update the DB of the (local) Server */
-			$app->db->query("UPDATE web_domain SET ssl_request = '$ssl_request', ssl_cert = '$ssl_cert', ssl_key = '$ssl_key2' WHERE domain = '".$data['new']['domain']."'");
-			$app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
+			$app->db->query("UPDATE web_domain SET ssl_request = ?, ssl_cert = ?, ssl_key = ? WHERE domain = ?", $ssl_request, $ssl_cert, $ssl_key2, $data['new']['domain']);
+			$app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
 			/* Update also the master-DB of the Server-Farm */
-			$app->dbmaster->query("UPDATE web_domain SET ssl_request = '$ssl_request', ssl_cert = '$ssl_cert', ssl_key = '$ssl_key2' WHERE domain = '".$data['new']['domain']."'");
-			$app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
+			$app->dbmaster->query("UPDATE web_domain SET ssl_request = ?, ssl_cert = ?, ssl_key = ? WHERE domain = ?", $ssl_request, $ssl_cert, $ssl_key2, $data['new']['domain']);
+			$app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
+		}
+		
+		//* Check that the SSL key is not password protected
+		if($data["new"]["ssl_action"] == 'save') {
+			if(stristr($data["new"]["ssl_key"],'Proc-Type: 4,ENCRYPTED')) {
+				$data["new"]["ssl_action"] = '';
+			
+				$app->log('SSL Certificate not saved. The SSL key is encrypted.', LOGLEVEL_WARN);
+				$app->dbmaster->datalogError('SSL Certificate not saved. The SSL key is encrypted.');
+			
+				/* Update the DB of the (local) Server */
+				$app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
+
+				/* Update also the master-DB of the Server-Farm */
+				$app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
+			}
 		}
 
 		//* Save a SSL certificate to disk
@@ -330,26 +412,33 @@
 
 			//* Write new ssl files
 			if(trim($data["new"]["ssl_request"]) != '') $app->system->file_put_contents($csr_file, $data["new"]["ssl_request"]);
-			if(trim($data["new"]["ssl_cert"]) != '') $app->system->file_put_contents($crt_file, $data["new"]["ssl_cert"]);
-			if(trim($data["new"]["ssl_bundle"]) != '') $app->system->file_put_contents($bundle_file, $data["new"]["ssl_bundle"]);
+			if(version_compare($app->system->getapacheversion(true), '2.4.8', '>=')) {
+				$tmp_data = '';
+				if(trim($data["new"]["ssl_cert"]) != '') $tmp_data .= $data["new"]["ssl_cert"] . "\n";
+				if(trim($data["new"]["ssl_bundle"]) != '') $tmp_data .= $data["new"]["ssl_bundle"];
+				if(trim($tmp_data) != '') $app->system->file_put_contents($crt_file, $tmp_data);
+			} else {
+				if(trim($data["new"]["ssl_cert"]) != '') $app->system->file_put_contents($crt_file, $data["new"]["ssl_cert"]);
+				if(trim($data["new"]["ssl_bundle"]) != '') $app->system->file_put_contents($bundle_file, $data["new"]["ssl_bundle"]);
+			}
 
 			//* Write the key file, if field is empty then import the key into the db
 			if(trim($data["new"]["ssl_key"]) != '') {
 				$app->system->file_put_contents($key_file2, $data["new"]["ssl_key"]);
 				$app->system->chmod($key_file2, 0400);
 			} else {
-				$ssl_key2 = $app->db->quote($app->system->file_get_contents($key_file2));
+				$ssl_key2 = $app->system->file_get_contents($key_file2);
 				/* Update the DB of the (local) Server */
-				$app->db->query("UPDATE web_domain SET ssl_key = '$ssl_key2' WHERE domain = '".$data['new']['domain']."'");
+				$app->db->query("UPDATE web_domain SET ssl_key = ? WHERE domain = ?", $ssl_key2, $data['new']['domain']);
 				/* Update also the master-DB of the Server-Farm */
-				$app->dbmaster->query("UPDATE web_domain SET ssl_key = '$ssl_key2' WHERE domain = '".$data['new']['domain']."'");
+				$app->dbmaster->query("UPDATE web_domain SET ssl_key = ? WHERE domain = ?", $ssl_key2, $data['new']['domain']);
 			}
 
 			/* Update the DB of the (local) Server */
-			$app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
+			$app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
 
 			/* Update also the master-DB of the Server-Farm */
-			$app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
+			$app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
 			$app->log('Saving SSL Cert for: '.$domain, LOGLEVEL_DEBUG);
 		}
 
@@ -362,18 +451,18 @@
 			$bundle_file = $ssl_dir.'/'.$domain.'.bundle';
 			if(file_exists($web_config['CA_path'].'/openssl.cnf') && !is_link($web_config['CA_path'].'/openssl.cnf'))
 			{
-				exec("openssl ca -batch -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -revoke $crt_file");
+				exec("openssl ca -batch -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -revoke ".escapeshellcmd($crt_file));
 				$app->log("Revoking CA-signed SSL Cert for: $domain", LOGLEVEL_DEBUG);
 			};
 			$app->system->unlink($csr_file);
 			$app->system->unlink($crt_file);
 			$app->system->unlink($bundle_file);
 			/* Update the DB of the (local) Server */
-			$app->db->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = '".$data['new']['domain']."'");
-			$app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
+			$app->db->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = ?", $data['new']['domain']);
+			$app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
 			/* Update also the master-DB of the Server-Farm */
-			$app->dbmaster->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = '".$data['new']['domain']."'");
-			$app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
+			$app->dbmaster->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = ?", $data['new']['domain']);
+			$app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
 			$app->log('Deleting SSL Cert for: '.$domain, LOGLEVEL_DEBUG);
 		}
 
@@ -396,14 +485,14 @@
 
 		if($this->action != 'insert') $this->action = 'update';
 
-		if($data['new']['type'] != 'vhost' && $data['new']['type'] != 'vhostsubdomain' && $data['new']['parent_domain_id'] > 0) {
+		if($data['new']['type'] != 'vhost' && $data['new']['type'] != 'vhostsubdomain' && $data['new']['type'] != 'vhostalias' && $data['new']['parent_domain_id'] > 0) {
 
 			$old_parent_domain_id = intval($data['old']['parent_domain_id']);
 			$new_parent_domain_id = intval($data['new']['parent_domain_id']);
 
 			// If the parent_domain_id has been changed, we will have to update the old site as well.
 			if($this->action == 'update' && $data['new']['parent_domain_id'] != $data['old']['parent_domain_id']) {
-				$tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = '.$old_parent_domain_id." AND active = 'y'");
+				$tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = ? AND active = ?', $old_parent_domain_id, 'y');
 				$data['new'] = $tmp;
 				$data['old'] = $tmp;
 				$this->action = 'update';
@@ -411,7 +500,7 @@
 			}
 
 			// This is not a vhost, so we need to update the parent record instead.
-			$tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = '.$new_parent_domain_id." AND active = 'y'");
+			$tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = ? AND active = ?', $new_parent_domain_id, 'y');
 			$data['new'] = $tmp;
 			$data['old'] = $tmp;
 			$this->action = 'update';
@@ -430,11 +519,12 @@
 		}
 
 		if($data['new']['document_root'] == '') {
-			if($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain') $app->log('document_root not set', LOGLEVEL_WARN);
+			if($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') $app->log('document_root not set', LOGLEVEL_WARN);
 			return 0;
 		}
-		if($data['new']['system_user'] == 'root' or $data['new']['system_group'] == 'root') {
-			$app->log('Websites cannot be owned by the root user or group.', LOGLEVEL_WARN);
+		if($app->system->is_allowed_user($data['new']['system_user'], $app->system->is_user($data['new']['system_user']), true) == false
+			|| $app->system->is_allowed_group($data['new']['system_group'], $app->system->is_group($data['new']['system_group']), true) == false) {
+			$app->log('Websites cannot be owned by the root user or group. User: '.$data['new']['system_user'].' Group: '.$data['new']['system_group'], LOGLEVEL_WARN);
 			return 0;
 		}
 		if(trim($data['new']['domain']) == '') {
@@ -444,13 +534,26 @@
 
 		$web_folder = 'web';
 		$log_folder = 'log';
-		if($data['new']['type'] == 'vhostsubdomain') {
-			$tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = '.intval($data['new']['parent_domain_id']));
+		$old_web_folder = 'web';
+		$old_log_folder = 'log';
+		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']);
 			$subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['new']['domain']);
 			if($subdomain_host == '') $subdomain_host = 'web'.$data['new']['domain_id'];
 			$web_folder = $data['new']['web_folder'];
 			$log_folder .= '/' . $subdomain_host;
 			unset($tmp);
+			
+			if(isset($data['old']['parent_domain_id'])) {
+				// old one
+				$tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = ?', $data['old']['parent_domain_id']);
+				$subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['old']['domain']);
+				if($subdomain_host == '') $subdomain_host = 'web'.$data['old']['domain_id'];
+				$old_web_folder = $data['old']['web_folder'];
+				$old_log_folder .= '/' . $subdomain_host;
+				unset($tmp);
+			}
 		}
 
 		// Create group and user, if not exist
@@ -498,7 +601,7 @@
 		if($this->action == 'update' && $data['new']['document_root'] != $data['old']['document_root']) {
 
 			//* Get the old client ID
-			$old_client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = '.intval($data['old']['sys_groupid']));
+			$old_client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['old']['sys_groupid']);
 			$old_client_id = intval($old_client['client_id']);
 			unset($old_client);
 
@@ -521,7 +624,7 @@
 			//* Remove protection of old folders
 			$app->system->web_folder_protection($data['old']['document_root'], false);
 
-			if($data["new"]["type"] != "vhostsubdomain") {
+			if($data["new"]["type"] != "vhostsubdomain" && $data["new"]["type"] != "vhostalias") {
 				//* Move the site data
 				$tmp_docroot = explode('/', $data['new']['document_root']);
 				unset($tmp_docroot[count($tmp_docroot)-1]);
@@ -537,6 +640,10 @@
 					$app->system->rename($data['new']['document_root'], $data['new']['document_root'].'_bak_'.date('Y_m_d_H_i_s'));
 					$app->log('Renaming existing directory in new docroot location. mv '.$data['new']['document_root'].' '.$data['new']['document_root'].'_bak_'.date('Y_m_d_H_i_s'), LOGLEVEL_DEBUG);
 				}
+				
+				//* 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'));
 
 				//* Create new base directory, if it does not exist yet
 				if(!is_dir($new_dir)) $app->system->mkdirpath($new_dir);
@@ -562,11 +669,27 @@
 			if($apache_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command);
 
 			//* Change the log mount
-			$fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.'    none    bind';
+			/*
+			$fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.'    none    bind';
 			$app->system->removeLine('/etc/fstab', $fstab_line);
-			$fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.'    none    bind,nobootwait    0 0';
-			$app->system->replaceLine('/etc/fstab', $fstab_line, $fstab_line, 1, 1);
-
+			$fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.'    none    bind,nobootwait';
+			$app->system->removeLine('/etc/fstab', $fstab_line);
+			$fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.'    none    bind,nobootwait';
+			$app->system->removeLine('/etc/fstab', $fstab_line);
+			*/
+			
+			$fstab_line_old = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.'    none    bind';
+			
+			if($web_config['network_filesystem'] == 'y') {
+				$fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.'    none    bind,nobootwait,_netdev    0 0';
+				$app->system->replaceLine('/etc/fstab', $fstab_line_old, $fstab_line, 0, 1);
+			} else {
+				$fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.'    none    bind,nobootwait    0 0';
+				$app->system->replaceLine('/etc/fstab', $fstab_line_old, $fstab_line, 0, 1);
+			}
+			
+			exec('mount --bind '.escapeshellarg('/var/log/ispconfig/httpd/'.$data['new']['domain']).' '.escapeshellarg($data['new']['document_root'].'/'.$log_folder));
+			
 		}
 
 		//print_r($data);
@@ -576,6 +699,7 @@
 
 		if(!is_dir($data['new']['document_root'].'/' . $web_folder)) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder);
 		if(!is_dir($data['new']['document_root'].'/' . $web_folder . '/error') and $data['new']['errordocs']) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder . '/error');
+		if(!is_dir($data['new']['document_root'].'/' . $web_folder . '/stats')) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder . '/stats');
 		//if(!is_dir($data['new']['document_root'].'/'.$log_folder)) exec('mkdir -p '.$data['new']['document_root'].'/'.$log_folder);
 		if(!is_dir($data['new']['document_root'].'/ssl')) $app->system->mkdirpath($data['new']['document_root'].'/ssl');
 		if(!is_dir($data['new']['document_root'].'/cgi-bin')) $app->system->mkdirpath($data['new']['document_root'].'/cgi-bin');
@@ -594,14 +718,15 @@
 		// Remove the symlink for the site, if site is renamed
 		if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) {
 			if(is_dir('/var/log/ispconfig/httpd/'.$data['old']['domain'])) exec('rm -rf /var/log/ispconfig/httpd/'.$data['old']['domain']);
-			if(is_link($data['old']['document_root'].'/'.$log_folder)) $app->system->unlink($data['old']['document_root'].'/'.$log_folder);
+			if(is_link($data['old']['document_root'].'/'.$old_log_folder)) $app->system->unlink($data['old']['document_root'].'/'.$old_log_folder);
 
 			//* remove old log mount
-			$fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.'    none    bind';
+			$fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.'    none    bind';
 			$app->system->removeLine('/etc/fstab', $fstab_line);
 
 			//* Unmount log directory
-			exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder));
+			//exec('fuser -km '.escapeshellarg($data['old']['document_root'].'/'.$old_log_folder));
+			exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$old_log_folder));
 		}
 
 		//* Create the log dir if nescessary and mount it
@@ -614,14 +739,15 @@
 			$app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755);
 			exec('mount --bind '.escapeshellarg('/var/log/ispconfig/httpd/'.$data['new']['domain']).' '.escapeshellarg($data['new']['document_root'].'/'.$log_folder));
 			//* add mountpoint to fstab
-			$fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.'    none    bind,nobootwait    0 0';
+			$fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.'    none    bind,nobootwait';
+			$fstab_line .= @($web_config['network_filesystem'] == 'y')?',_netdev    0 0':'    0 0';
 			$app->system->replaceLine('/etc/fstab', $fstab_line, $fstab_line, 1, 1);
 		}
 
 		$app->system->web_folder_protection($data['new']['document_root'], true);
 
 		// Get the client ID
-		$client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = '.intval($data['new']['sys_groupid']));
+		$client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['new']['sys_groupid']);
 		$client_id = intval($client['client_id']);
 		unset($client);
 
@@ -677,7 +803,7 @@
 		// setting a local var here
 
 		// normally $conf['templates'] = "/usr/local/ispconfig/server/conf";
-		if($this->action == 'insert' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain')) {
+		if($this->action == 'insert' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias')) {
 
 			// Copy the error pages
 			if($data['new']['errordocs']) {
@@ -697,33 +823,37 @@
 			}
 
 			if (file_exists($conf['rootpath'] . '/conf-custom/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2))) {
-				exec('cp ' . $conf['rootpath'] . '/conf-custom/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2).' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html');
+				if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2).' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html');
 
 				if(is_file($conf['rootpath'] . '/conf-custom/index/favicon.ico')) {
-					exec('cp ' . $conf['rootpath'] . '/conf-custom/index/favicon.ico '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
+					if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/favicon.ico')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/favicon.ico '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
 				}
 				if(is_file($conf['rootpath'] . '/conf-custom/index/robots.txt')) {
-					exec('cp ' . $conf['rootpath'] . '/conf-custom/index/robots.txt '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
+					if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/robots.txt')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/robots.txt '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
 				}
 				if(is_file($conf['rootpath'] . '/conf-custom/index/.htaccess')) {
-					exec('cp ' . $conf['rootpath'] . '/conf-custom/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
+					if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/.htaccess')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
 				}
-			}
-			else {
+			} else {
 				if (file_exists($conf['rootpath'] . '/conf-custom/index/standard_index.html')) {
-					exec('cp ' . $conf['rootpath'] . '/conf-custom/index/standard_index.html '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html');
-				}
-				else {
-					exec('cp ' . $conf['rootpath'] . '/conf/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2).' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html');
-					if(is_file($conf['rootpath'] . '/conf/index/favicon.ico')) exec('cp ' . $conf['rootpath'] . '/conf/index/favicon.ico '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
-					if(is_file($conf['rootpath'] . '/conf/index/robots.txt')) exec('cp ' . $conf['rootpath'] . '/conf/index/robots.txt '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
-					if(is_file($conf['rootpath'] . '/conf/index/.htaccess')) exec('cp ' . $conf['rootpath'] . '/conf/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
+					if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/standard_index.html '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html');
+				} else {
+					if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html')) exec('cp ' . $conf['rootpath'] . '/conf/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2).' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html');
+					if(is_file($conf['rootpath'] . '/conf/index/favicon.ico')){
+						if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/favicon.ico')) exec('cp ' . $conf['rootpath'] . '/conf/index/favicon.ico '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
+					}
+					if(is_file($conf['rootpath'] . '/conf/index/robots.txt')){
+						if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/robots.txt')) exec('cp ' . $conf['rootpath'] . '/conf/index/robots.txt '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
+					}
+					if(is_file($conf['rootpath'] . '/conf/index/.htaccess')){
+						if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/.htaccess')) exec('cp ' . $conf['rootpath'] . '/conf/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
+					}
 				}
 			}
 			exec('chmod -R a+r '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
 
 			//** Copy the error documents on update when the error document checkbox has been activated and was deactivated before
-		} elseif ($this->action == 'update' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain') && $data['old']['errordocs'] == 0 && $data['new']['errordocs'] == 1) {
+		} elseif ($this->action == 'update' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') && $data['old']['errordocs'] == 0 && $data['new']['errordocs'] == 1) {
 
 			$error_page_path = escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/error/';
 			if (file_exists($conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2))) {
@@ -741,16 +871,34 @@
 			exec('chown -R '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.$error_page_path);
 		}  // end copy error docs
 
-		// Set the quota for the user, but only for vhosts, not vhostsubdomains
+		// Set the quota for the user, but only for vhosts, not vhostsubdomains or vhostalias
 		if($username != '' && $app->system->is_user($username) && $data['new']['type'] == 'vhost') {
 			if($data['new']['hd_quota'] > 0) {
 				$blocks_soft = $data['new']['hd_quota'] * 1024;
 				$blocks_hard = $blocks_soft + 1024;
+                $mb_hard = $mb_soft + 1;
 			} else {
-				$blocks_soft = $blocks_hard = 0;
+				$mb_soft = $mb_hard = $blocks_soft = $blocks_hard = 0;
 			}
-			exec("setquota -u $username $blocks_soft $blocks_hard 0 0 -a &> /dev/null");
-			exec('setquota -T -u '.$username.' 604800 604800 -a &> /dev/null');
+            
+          // get the primitive folder for document_root and the filesystem, will need it later.
+          $df_output=explode(" ", exec("df -T $document_root|awk 'END{print \$2,\$NF}'"));
+          $file_system = $df_output[0];
+          $primitive_root = $df_output[1];
+
+		  if ( in_array($file_system , array('ext2','ext3','ext4'), true) ) {
+            exec('setquota -u '. $username . ' ' . $blocks_soft . ' ' . $blocks_hard . ' 0 0 -a &> /dev/null');
+            exec('setquota -T -u '.$username.' 604800 604800 -a &> /dev/null');
+          } elseif ($file_system == 'xfs') {
+
+            exec("xfs_quota -x -c 'limit -g bsoft=$mb_soft" . 'm'. " bhard=$mb_hard" . 'm'. " $username' $primitive_root");
+
+            // xfs only supports timers globally, not per user.
+            exec("xfs_quota -x -c 'timer -bir -i 604800'");
+
+            unset($project_uid, $username_position, $xfs_projects);
+            unset($primitive_root, $df_output, $mb_hard, $mb_soft);
+          }
 		}
 
 		if($this->action == 'insert' || $data["new"]["system_user"] != $data["old"]["system_user"]) {
@@ -778,13 +926,13 @@
 			if($web_config['security_level'] == 20) {
 
 				$app->system->chmod($data['new']['document_root'], 0755);
-				$app->system->chmod($data['new']['document_root'].'/web', 0710);
+				$app->system->chmod($data['new']['document_root'].'/web', 0711);
 				$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);
 
 				// make tmp directory writable for Apache and the website users
-				$app->system->chmod($data['new']['document_root'].'/tmp', 0777);
+				$app->system->chmod($data['new']['document_root'].'/tmp', 0770);
 
 				// Set Log directory to 755 to make the logs accessible by the FTP user
 				if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') {
@@ -844,7 +992,7 @@
 				$app->system->chmod($data['new']['document_root'].'/cgi-bin', 0755);
 
 				// make temp directory writable for Apache and the website users
-				$app->system->chmod($data['new']['document_root'].'/tmp', 0777);
+				$app->system->chmod($data['new']['document_root'].'/tmp', 0770);
 
 				// Set Log directory to 755 to make the logs accessible by the FTP user
 				if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') {
@@ -873,7 +1021,9 @@
 				$app->system->chown($data['new']['document_root'].'/webdav', $username);
 				$app->system->chgrp($data['new']['document_root'].'/webdav', $groupname);
 			}
-		} elseif(($this->action == 'insert' && $data['new']['type'] == 'vhostsubdomain') or ($web_config['set_folder_permissions_on_update'] == 'y' && $data['new']['type'] == 'vhostsubdomain')) {
+		} elseif((($data['new']['type'] == 'vhostsubdomain') || ($data['new']['type'] == 'vhostalias')) &&
+				 (($this->action == 'insert') || ($web_config['set_folder_permissions_on_update'] == 'y'))) {
+
 			if($web_config['security_level'] == 20) {
 				$app->system->chmod($data['new']['document_root'].'/' . $web_folder, 0710);
 				$app->system->chown($data['new']['document_root'].'/' . $web_folder, $username);
@@ -905,7 +1055,7 @@
 
 		//* Write the custom php.ini file, if custom_php_ini fieled is not empty
 		$custom_php_ini_dir = $web_config['website_basedir'].'/conf/'.$data['new']['system_user'];
-		if($data['new']['type'] == 'vhostsubdomain') $custom_php_ini_dir .= '_' . $web_folder;
+		if($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') $custom_php_ini_dir .= '_' . $web_folder;
 		if(!is_dir($web_config['website_basedir'].'/conf')) $app->system->mkdir($web_config['website_basedir'].'/conf');
 
 		//* add open_basedir restriction to custom php.ini content, required for suphp only
@@ -925,33 +1075,33 @@
 		if(trim($data['new']['custom_php_ini']) != '') {
 			$has_custom_php_ini = true;
 			if(!is_dir($custom_php_ini_dir)) $app->system->mkdirpath($custom_php_ini_dir);
-			$php_ini_content = '';
-			if($data['new']['php'] == 'mod') {
-				$master_php_ini_path = $web_config['php_ini_path_apache'];
-			} else {
-				if($data["new"]['php'] == 'fast-cgi') {
-					if(trim($data['new']['fastcgi_php_version']) != '' && file_exists($custom_fastcgi_php_ini_dir)){
-						$master_php_ini_path = $custom_fastcgi_php_ini_dir;
-					} elseif(file_exists($fastcgi_config["fastcgi_phpini_path"])){
-						$master_php_ini_path = $fastcgi_config["fastcgi_phpini_path"];
-					} else {
-						$master_php_ini_path = $web_config['php_ini_path_cgi'];
+			
+			$php_ini_content = $this->get_master_php_ini_content($data['new']);
+			$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 = '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['snippet'] = trim($php_snippet['snippet']);
+								if($php_snippet['snippet'] != ''){
+									$php_ini_content .= "\n".$php_snippet['snippet'];
+								}
+							}
+						}
+
+						foreach($sub_prefixes as $s) {
+							$temp_domains[] = $s . $aliasdomain['domain'];
+						}
 					}
-				} else {
-					$master_php_ini_path = $web_config['php_ini_path_cgi'];
 				}
 			}
-
-			//* Add php.ini to the path in case that the master_php_ini_path is a directory
-			if($master_php_ini_path != '' && is_dir($master_php_ini_path) && is_file($master_php_ini_path.'/php.ini')) {
-				if(substr($master_php_ini_path, -1) == '/') $master_php_ini_path = substr($master_php_ini_path, 0, -1);
-				$master_php_ini_path .= '/php.ini';
-			}
-
-			if($master_php_ini_path != '' && substr($master_php_ini_path, -7) == 'php.ini' && is_file($master_php_ini_path)) {
-				$php_ini_content .= $app->system->file_get_contents($master_php_ini_path)."\n";
-			}
-			$php_ini_content .= str_replace("\r", '', trim($data['new']['custom_php_ini']));
+		
 			$app->system->file_put_contents($custom_php_ini_dir.'/php.ini', $php_ini_content);
 		} else {
 			$has_custom_php_ini = false;
@@ -978,13 +1128,25 @@
 		$vhost_data['custom_php_ini_dir'] = escapeshellcmd($custom_php_ini_dir);
 
 		// Custom Apache directives
+		if(intval($data['new']['directive_snippets_id']) > 0){
+			$snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'apache' AND active = 'y' AND customer_viewable = 'y'", $data['new']['directive_snippets_id']);
+			if(isset($snippet['snippet'])){
+				$vhost_data['apache_directives'] = $snippet['snippet'];
+			}
+		}
 		// Make sure we only have Unix linebreaks
 		$vhost_data['apache_directives'] = str_replace("\r\n", "\n", $vhost_data['apache_directives']);
 		$vhost_data['apache_directives'] = str_replace("\r", "\n", $vhost_data['apache_directives']);
+		$trans = array(
+			'{DOCROOT}' => $vhost_data['web_document_root_www'],
+			'{DOCROOT_CLIENT}' => $vhost_data['web_document_root']
+		);
+		$vhost_data['apache_directives'] = strtr($vhost_data['apache_directives'], $trans);
 
 		// Check if a SSL cert exists
 		$ssl_dir = $data['new']['document_root'].'/ssl';
 		$domain = $data['new']['ssl_domain'];
+		if(!$domain) $domain = $data['new']['domain'];
 		$key_file = $ssl_dir.'/'.$domain.'.key';
 		$crt_file = $ssl_dir.'/'.$domain.'.crt';
 		$bundle_file = $ssl_dir.'/'.$domain.'.bundle';
@@ -998,6 +1160,144 @@
 			$app->log('SSL Disabled. '.$domain,LOGLEVEL_DEBUG);
 		}
 		*/
+
+		if($data['new']['ssl'] == 'y' && $data['new']['ssl_letsencrypt'] == 'y') {
+			if(substr($domain, 0, 2) === '*.') {
+				// wildcard domain not yet supported by letsencrypt!
+				$app->log('Wildcard domains not yet supported by letsencrypt, so changing ' . $domain . ' to ' . substr($domain, 2), LOGLEVEL_WARN);
+				$domain = substr($domain, 2);
+			}
+			
+			$data['new']['ssl_domain'] = $domain;
+			$vhost_data['ssl_domain'] = $domain;
+		}
+
+		//* Generate Let's Encrypt SSL certificat
+		if($data['new']['ssl'] == 'y' && $data['new']['ssl_letsencrypt'] == 'y' && ( // ssl and let's encrypt is active
+			($data['old']['ssl'] == 'n' || $data['old']['ssl_letsencrypt'] == 'n') // we have new let's encrypt configuration
+			|| ($data['old']['domain'] != $data['new']['domain']) // we have domain update
+			|| ($data['old']['subdomain'] != $data['new']['subdomain']) // we have new or update on "auto" subdomain
+			|| ($data['new']['type'] == 'subdomain') // we have new or update on subdomain
+			|| ($data['old']['type'] == 'alias' || $data['new']['type'] == 'alias') // we have new or update on aliasdomain
+		)) {
+			// default values
+			$temp_domains = array();
+			$lddomain = $domain;
+			$subdomains = null;
+			$aliasdomains = null;
+			$sub_prefixes = array();
+
+			//* be sure to have good domain
+			if($data['new']['subdomain'] == "www" OR $data['new']['subdomain'] == "*") {
+				$temp_domains[] = "www." . $domain;
+			}
+
+			//* then, add subdomain if we have
+			$subdomains = $app->db->queryAllRecords('SELECT domain FROM web_domain WHERE parent_domain_id = '.intval($data['new']['domain_id'])." AND active = 'y' AND type = 'subdomain'");
+			if(is_array($subdomains)) {
+				foreach($subdomains as $subdomain) {
+					$temp_domains[] = $subdomain['domain'];
+					$sub_prefixes[] = str_replace($domain, "", $subdomain['domain']);
+				}
+			}
+			
+			//* then, add alias domain if we have
+			$aliasdomains = $app->db->queryAllRecords('SELECT domain,subdomain FROM web_domain WHERE parent_domain_id = '.intval($data['new']['domain_id'])." AND active = 'y' AND type = 'alias'");
+			if(is_array($aliasdomains)) {
+				foreach($aliasdomains as $aliasdomain) {
+					$temp_domains[] = $aliasdomain['domain'];
+					if(isset($aliasdomain['subdomain']) && ! empty($aliasdomain['subdomain'])) {
+						$temp_domains[] = $aliasdomain['subdomain'] . "." . $aliasdomain['domain'];
+					}
+				}
+			}
+
+			// prevent duplicate
+			$temp_domains = array_unique($temp_domains);
+
+			// generate cli format
+			foreach($temp_domains as $temp_domain) {
+				$lddomain .= (string) " --domains " . $temp_domain;
+			}
+
+			// useless data
+			unset($subdomains);
+			unset($temp_domains);
+
+			$crt_tmp_file = "/etc/letsencrypt/live/".$domain."/cert.pem";
+			$key_tmp_file = "/etc/letsencrypt/live/".$domain."/privkey.pem";
+			$bundle_tmp_file = "/etc/letsencrypt/live/".$domain."/chain.pem";
+			$webroot = $data['new']['document_root']."/web";
+
+			//* check if we have already a Let's Encrypt cert
+			if(!file_exists($crt_tmp_file) && !file_exists($key_tmp_file)) {
+				$app->log("Create Let's Encrypt SSL Cert for: $domain", LOGLEVEL_DEBUG);
+				
+				$success = false;
+				$letsencrypt = array_shift( explode("\n", shell_exec('which letsencrypt certbot /root/.local/share/letsencrypt/bin/letsencrypt')) );
+				if(is_executable($letsencrypt)) {
+					$success = $this->_exec($letsencrypt . " certonly --text --agree-tos --authenticator webroot --server https://acme-v01.api.letsencrypt.org/directory --rsa-key-size 4096 --email postmaster@$domain --domains $lddomain --webroot-path /usr/local/ispconfig/interface/acme");
+				}
+				if(!$success) {
+					// error issuing cert
+					$app->log('Let\'s Encrypt SSL Cert for: ' . $domain . ' could not be issued.', LOGLEVEL_WARN);
+					$data['new']['ssl_letsencrypt'] = 'n';
+					if($data['old']['ssl'] == 'n') $data['new']['ssl'] = 'n';
+					/* Update the DB of the (local) Server */
+					$app->db->query("UPDATE web_domain SET `ssl` = ?, `ssl_letsencrypt` = ? WHERE `domain` = ?", $data['new']['ssl'], 'n', $data['new']['domain']);
+					/* Update also the master-DB of the Server-Farm */
+					$app->dbmaster->query("UPDATE web_domain SET `ssl` = ?, `ssl_letsencrypt` = ? WHERE `domain` = ?", $data['new']['ssl'], 'n', $data['new']['domain']);
+				}
+			}
+
+			//* check is been correctly created
+			if(file_exists($crt_tmp_file) OR file_exists($key_tmp_file)) {
+				$date = date("YmdHis");
+				if(is_file($key_file)) {
+					$app->system->copy($key_file, $key_file.'.old'.$date);
+					$app->system->chmod($key_file.'.old.'.$date, 0400);
+					$app->system->unlink($key_file);
+				}
+
+				if ($web_config["website_symlinks_rel"] == 'y') {
+					$this->create_relative_link(escapeshellcmd($key_tmp_file), escapeshellcmd($key_file));
+				} else {
+					exec("ln -s ".escapeshellcmd($key_tmp_file)." ".escapeshellcmd($key_file));
+				}
+
+				if(is_file($crt_file)) {
+					$app->system->copy($crt_file, $crt_file.'.old.'.$date);
+					$app->system->chmod($crt_file.'.old.'.$date, 0400);
+					$app->system->unlink($crt_file);
+				}
+
+				if($web_config["website_symlinks_rel"] == 'y') {
+					$this->create_relative_link(escapeshellcmd($crt_tmp_file), escapeshellcmd($crt_file));
+				} else {
+					exec("ln -s ".escapeshellcmd($crt_tmp_file)." ".escapeshellcmd($crt_file));
+				}
+
+				if(is_file($bundle_file)) {
+					$app->system->copy($bundle_file, $bundle_file.'.old.'.$date);
+					$app->system->chmod($bundle_file.'.old.'.$date, 0400);
+					$app->system->unlink($bundle_file);
+				}
+
+				if($web_config["website_symlinks_rel"] == 'y') {
+					$this->create_relative_link(escapeshellcmd($bundle_tmp_file), escapeshellcmd($bundle_file));
+				} else {
+					exec("ln -s ".escapeshellcmd($bundle_tmp_file)." ".escapeshellcmd($bundle_file));
+				}
+
+				/* we don't need to store it.
+				/* Update the DB of the (local) Server */
+				$app->db->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '', ssl_key = '' WHERE domain = ?", $data['new']['domain']);
+				$app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
+				/* Update also the master-DB of the Server-Farm */
+				$app->dbmaster->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '', ssl_key = '' WHERE domain = ?", $data['new']['domain']);
+				$app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
+			}
+		}
 
 		if(@is_file($bundle_file)) $vhost_data['has_bundle_cert'] = 1;
 
@@ -1019,9 +1319,11 @@
 		}
 
 		$tpl->setVar($vhost_data);
+		$tpl->setVar('apache_version', $app->system->getapacheversion());
 
 		// Rewrite rules
 		$rewrite_rules = array();
+		$rewrite_wildcard_rules = array();
 		if($data['new']['redirect_type'] != '' && $data['new']['redirect_path'] != '') {
 			if(substr($data['new']['redirect_path'], -1) != '/' && !preg_match('/^(https?|\[scheme\]):\/\//', $data['new']['redirect_path'])) $data['new']['redirect_path'] .= '/';
 			if(substr($data['new']['redirect_path'], 0, 8) == '[scheme]'){
@@ -1053,7 +1355,7 @@
 					'rewrite_add_path' => (substr($rewrite_target, -1) == '/' ? 'y' : 'n'));
 				break;
 			case '*':
-				$rewrite_rules[] = array( 'rewrite_domain'  => '(^|\.)'.$this->_rewrite_quote($data['new']['domain']),
+				$rewrite_wildcard_rules[] = array( 'rewrite_domain'  => '(^|\.)'.$this->_rewrite_quote($data['new']['domain']),
 					'rewrite_type'   => ($data['new']['redirect_type'] == 'no')?'':'['.$data['new']['redirect_type'].']',
 					'rewrite_target'  => $rewrite_target,
 					'rewrite_target_ssl' => $rewrite_target_ssl,
@@ -1076,7 +1378,7 @@
 		$auto_alias = $web_config['website_autoalias'];
 		if($auto_alias != '') {
 			// get the client username
-			$client = $app->db->queryOneRecord("SELECT `username` FROM `client` WHERE `client_id` = '" . intval($client_id) . "'");
+			$client = $app->db->queryOneRecord("SELECT `username` FROM `client` WHERE `client_id` = ?", $client_id);
 			$aa_search = array('[client_id]', '[website_id]', '[client_username]', '[website_domain]');
 			$aa_replace = array($client_id, $data['new']['domain_id'], $client['username'], $data['new']['domain']);
 			$auto_alias = str_replace($aa_search, $aa_replace, $auto_alias);
@@ -1087,7 +1389,7 @@
 		}
 
 		// get alias domains (co-domains and subdomains)
-		$aliases = $app->db->queryAllRecords('SELECT * FROM web_domain WHERE parent_domain_id = '.$data['new']['domain_id']." AND active = 'y' AND type != 'vhostsubdomain'");
+		$aliases = $app->db->queryAllRecords("SELECT * FROM web_domain WHERE parent_domain_id = ? AND active = 'y' AND (type != 'vhostsubdomain' AND type != 'vhostalias')", $data['new']['domain_id']);
 		$alias_seo_redirects = array();
 		switch($data['new']['subdomain']) {
 		case 'www':
@@ -1152,7 +1454,7 @@
 							'rewrite_add_path' => (substr($rewrite_target, -1) == '/' ? 'y' : 'n'));
 						break;
 					case '*':
-						$rewrite_rules[] = array( 'rewrite_domain'  => '(^|\.)'.$this->_rewrite_quote($alias['domain']),
+						$rewrite_wildcard_rules[] = array( 'rewrite_domain'  => '(^|\.)'.$this->_rewrite_quote($alias['domain']),
 							'rewrite_type'   => ($alias['redirect_type'] == 'no')?'':'['.$alias['redirect_type'].']',
 							'rewrite_target'  => $rewrite_target,
 							'rewrite_target_ssl' => $rewrite_target_ssl,
@@ -1189,6 +1491,8 @@
 		} else {
 			$tpl->setVar('alias', '');
 		}
+		
+		if (count($rewrite_wildcard_rules) > 0) $rewrite_rules = array_merge($rewrite_rules, $rewrite_wildcard_rules); // Append wildcard rules to the end of rules
 
 		if(count($rewrite_rules) > 0 || $vhost_data['seo_redirect_enabled'] > 0 || count($alias_seo_redirects) > 0) {
 			$tpl->setVar('rewrite_enabled', 1);
@@ -1225,6 +1529,7 @@
 
 			$fcgi_tpl = new tpl();
 			$fcgi_tpl->newTemplate('php-fcgi-starter.master');
+			$fcgi_tpl->setVar('apache_version', $app->system->getapacheversion());
 
 			// Support for multiple PHP versions (FastCGI)
 			if(trim($data['new']['fastcgi_php_version']) != ''){
@@ -1252,11 +1557,12 @@
 				$fcgi_tpl->setVar('php_fcgi_bin', escapeshellcmd($custom_fastcgi_php_executable));
 			}
 			$fcgi_tpl->setVar('security_level', intval($web_config['security_level']));
+			$fcgi_tpl->setVar('domain', escapeshellcmd($data['new']['domain']));
 
 			$php_open_basedir = ($data['new']['php_open_basedir'] == '')?$data['new']['document_root']:$data['new']['php_open_basedir'];
 			$fcgi_tpl->setVar('open_basedir', escapeshellcmd($php_open_basedir));
 
-			$fcgi_starter_script = escapeshellcmd($fastcgi_starter_path.$fastcgi_config['fastcgi_starter_script'].($data['new']['type'] == 'vhostsubdomain' ? '_web' . $data['new']['domain_id'] : ''));
+			$fcgi_starter_script = escapeshellcmd($fastcgi_starter_path.$fastcgi_config['fastcgi_starter_script'].(($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') ? '_web' . $data['new']['domain_id'] : ''));
 			$app->system->file_put_contents($fcgi_starter_script, $fcgi_tpl->grab());
 			unset($fcgi_tpl);
 
@@ -1268,24 +1574,21 @@
 
 			$tpl->setVar('fastcgi_alias', $fastcgi_config['fastcgi_alias']);
 			$tpl->setVar('fastcgi_starter_path', $fastcgi_starter_path);
-			$tpl->setVar('fastcgi_starter_script', $fastcgi_config['fastcgi_starter_script'].($data['new']['type'] == 'vhostsubdomain' ? '_web' . $data['new']['domain_id'] : ''));
+			$tpl->setVar('fastcgi_starter_script', $fastcgi_config['fastcgi_starter_script'].(($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') ? '_web' . $data['new']['domain_id'] : ''));
 			$tpl->setVar('fastcgi_config_syntax', $fastcgi_config['fastcgi_config_syntax']);
 			$tpl->setVar('fastcgi_max_requests', $fastcgi_config['fastcgi_max_requests']);
 
 		} else {
 			//remove the php fastgi starter script if available
+			$fastcgi_starter_script = $fastcgi_config['fastcgi_starter_script'].($data['old']['type'] == 'vhostsubdomain' ? '_web' . $data['old']['domain_id'] : '');
 			if ($data['old']['php'] == 'fast-cgi') {
 				$fastcgi_starter_path = str_replace('[system_user]', $data['old']['system_user'], $fastcgi_config['fastcgi_starter_path']);
 				$fastcgi_starter_path = str_replace('[client_id]', $client_id, $fastcgi_starter_path);
 				if($data['old']['type'] == 'vhost') {
-					if (is_dir($fastcgi_starter_path)) {
-						exec('rm -rf '.$fastcgi_starter_path);
-					}
+					if(is_file($fastcgi_starter_script)) @unlink($fastcgi_starter_script);
+					if (is_dir($fastcgi_starter_path)) @rmdir($fastcgi_starter_path);
 				} else {
-					$fcgi_starter_script = $fastcgi_starter_path.$fastcgi_config['fastcgi_starter_script'].'_web' . $data['old']['domain_id'];
-					if (file_exists($fcgi_starter_script)) {
-						exec('rm -f '.$fcgi_starter_script);
-					}
+					if(is_file($fastcgi_starter_script)) @unlink($fastcgi_starter_script);
 				}
 			}
 		}
@@ -1305,7 +1608,7 @@
 				$default_php_fpm = true;
 			}
 		} else {
-			if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){
+			if(trim($data['old']['fastcgi_php_version']) != '' && ($data['old']['php'] == 'php-fpm' || $data['old']['php'] == 'hhvm')){
 				$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['old']['fastcgi_php_version']));
 				if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/';
@@ -1319,12 +1622,16 @@
 		} else {
 			$pool_dir = $custom_php_fpm_pool_dir;
 		}
+		$pool_dir = trim($pool_dir);
 		if(substr($pool_dir, -1) != '/') $pool_dir .= '/';
 		$pool_name = 'web'.$data['new']['domain_id'];
 		$socket_dir = escapeshellcmd($web_config['php_fpm_socket_dir']);
 		if(substr($socket_dir, -1) != '/') $socket_dir .= '/';
-
-		if($data['new']['php_fpm_use_socket'] == 'y'){
+		
+		$apache_modules = $app->system->getapachemodules();
+		
+		// Use sockets, but not with apache 2.4 on centos (mod_proxy_fcgi) as socket support is buggy in that version
+		if($data['new']['php_fpm_use_socket'] == 'y' && in_array('fastcgi_module',$apache_modules)){
 			$use_tcp = 0;
 			$use_socket = 1;
 		} else {
@@ -1347,7 +1654,7 @@
 			//$cgi_config = $app->getconf->get_server_config($conf['server_id'], 'cgi');
 
 			$cgi_config['cgi_starter_path'] = $web_config['website_basedir'].'/php-cgi-scripts/[system_user]/';
-			$cgi_config['cgi_starter_script'] = 'php-cgi-starter'.($data['new']['type'] == 'vhostsubdomain' ? '_web' . $data['new']['domain_id'] : '');
+			$cgi_config['cgi_starter_script'] = 'php-cgi-starter'.(($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') ? '_web' . $data['new']['domain_id'] : '');
 			$cgi_config['cgi_bin'] = '/usr/bin/php-cgi';
 
 			$cgi_starter_path = str_replace('[system_user]', $data['new']['system_user'], $cgi_config['cgi_starter_path']);
@@ -1364,6 +1671,7 @@
 
 			$cgi_tpl = new tpl();
 			$cgi_tpl->newTemplate('php-cgi-starter.master');
+			$cgi_tpl->setVar('apache_version', $app->system->getapacheversion());
 
 			// This works because PHP "rewrites" a symlink to the physical path
 			$php_open_basedir = ($data['new']['php_open_basedir'] == '')?$data['new']['document_root']:$data['new']['php_open_basedir'];
@@ -1382,7 +1690,7 @@
 				$cgi_tpl->setVar('php_ini_path', escapeshellcmd($fastcgi_config['fastcgi_phpini_path']));
 			}
 
-			$cgi_starter_script = escapeshellcmd($cgi_starter_path.$cgi_config['cgi_starter_script'].($data['new']['type'] == 'vhostsubdomain' ? '_web' . $data['new']['domain_id'] : ''));
+			$cgi_starter_script = escapeshellcmd($cgi_starter_path.$cgi_config['cgi_starter_script'].(($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') ? '_web' . $data['new']['domain_id'] : ''));
 			$app->system->file_put_contents($cgi_starter_script, $cgi_tpl->grab());
 			unset($cgi_tpl);
 
@@ -1394,7 +1702,7 @@
 			$app->system->chgrp($cgi_starter_script, $data['new']['system_group']);
 
 			$tpl->setVar('cgi_starter_path', $cgi_starter_path);
-			$tpl->setVar('cgi_starter_script', $cgi_config['cgi_starter_script'].($data['new']['type'] == 'vhostsubdomain' ? '_web' . $data['new']['domain_id'] : ''));
+			$tpl->setVar('cgi_starter_script', $cgi_config['cgi_starter_script'].(($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') ? '_web' . $data['new']['domain_id'] : ''));
 
 		}
 
@@ -1406,6 +1714,15 @@
 		$vhosts = array();
 
 		//* Add vhost for ipv4 IP
+
+		//* use ip-mapping for web-mirror
+		if($data['new']['ip_address'] != '*' && $conf['mirror_server_id'] > 0) {
+			$sql = "SELECT destination_ip FROM server_ip_map WHERE server_id = ? AND source_ip = ?";
+			$newip = $app->db->queryOneRecord($sql, $conf['server_id'], $data['new']['ip_address']);
+			$data['new']['ip_address'] = $newip['destination_ip'];
+			unset($newip);
+		}
+
 		$tmp_vhost_arr = array('ip_address' => $data['new']['ip_address'], 'ssl_enabled' => 0, 'port' => 80);
 		if(count($rewrite_rules) > 0)  $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $rewrite_rules);
 		if(count($alias_seo_redirects) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $alias_seo_redirects);
@@ -1448,7 +1765,7 @@
 					$data['new']['ipv6_address'] = implode(':', $explode_v6);
 				}
 			}
-
+			if($data['new']['ipv6_address'] == '*') $data['new']['ipv6_address'] = '::';
 			$tmp_vhost_arr = array('ip_address' => '['.$data['new']['ipv6_address'].']', 'ssl_enabled' => 0, 'port' => 80);
 			if(count($rewrite_rules) > 0)  $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $rewrite_rules);
 			if(count($alias_seo_redirects) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $alias_seo_redirects);
@@ -1558,11 +1875,12 @@
 		}
 
 		//* Create awstats configuration
-		if($data['new']['stats_type'] == 'awstats' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain')) {
+		if($data['new']['stats_type'] == 'awstats' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias')) {
 			$this->awstats_update($data, $web_config);
 		}
 
 		$this->php_fpm_pool_update($data, $web_config, $pool_dir, $pool_name, $socket_dir);
+		$this->hhvm_update($data, $web_config);
 
 		if($web_config['check_apache_config'] == 'y') {
 			//* Test if apache starts with the new configuration file
@@ -1703,7 +2021,6 @@
 
 		//* Unset action to clean it for next processed vhost.
 		$this->action = '';
-
 	}
 
 	function delete($event_name, $data) {
@@ -1715,7 +2032,7 @@
 		$web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
 		$fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi');
 
-		if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain') $app->system->web_folder_protection($data['old']['document_root'], false);
+		if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') $app->system->web_folder_protection($data['old']['document_root'], false);
 
 		//* Check if this is a chrooted setup
 		if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) {
@@ -1727,8 +2044,8 @@
 		//* Remove the mounts
 		$log_folder = 'log';
 		$web_folder = '';
-		if($data['old']['type'] == 'vhostsubdomain') {
-			$tmp = $app->db->queryOneRecord('SELECT `domain`,`document_root` FROM web_domain WHERE domain_id = '.intval($data['old']['parent_domain_id']));
+		if($data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') {
+			$tmp = $app->db->queryOneRecord('SELECT `domain`,`document_root` FROM web_domain WHERE domain_id = ?', $data['old']['parent_domain_id']);
 			if($tmp['domain'] != ''){
 				$subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['old']['domain']);
 			} else {
@@ -1773,14 +2090,16 @@
 			unset($subdomain_hosts);
 		}
 
-		if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain'){
+		if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias'){
 			if(is_array($log_folders) && !empty($log_folders)){
 				foreach($log_folders as $log_folder){
 					//if($app->system->is_mounted($data['old']['document_root'].'/'.$log_folder)) exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder));
+					//exec('fuser -km '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null');
 					exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null');
 				}
 			} else {
 				//if($app->system->is_mounted($data['old']['document_root'].'/'.$log_folder)) exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder));
+				//exec('fuser -km '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null');
 				exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null');
 			}
 		}
@@ -1797,10 +2116,10 @@
 		}
 		unset($log_folders);
 
-		if($data['old']['type'] != 'vhost' && $data['old']['type'] != 'vhostsubdomain' && $data['old']['parent_domain_id'] > 0) {
+		if($data['old']['type'] != 'vhost' && $data['old']['type'] != 'vhostsubdomain' && $data['old']['type'] != 'vhostalias' && $data['old']['parent_domain_id'] > 0) {
 			//* This is a alias domain or subdomain, so we have to update the website instead
 			$parent_domain_id = intval($data['old']['parent_domain_id']);
-			$tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = '.$parent_domain_id." AND active = 'y'");
+			$tmp = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ? AND active = 'y'", $parent_domain_id);
 			$data['new'] = $tmp;
 			$data['old'] = $tmp;
 			$this->action = 'update';
@@ -1831,7 +2150,7 @@
 			$app->system->unlink($vhost_file);
 			$app->log('Removing vhost file: '.$vhost_file, LOGLEVEL_DEBUG);
 
-			if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain') {
+			if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') {
 				$docroot = escapeshellcmd($data['old']['document_root']);
 				if($docroot != '' && !stristr($docroot, '..')) {
 					if($data['old']['type'] == 'vhost') {
@@ -1852,9 +2171,9 @@
 							// we use strict check as otherwise directories named '0' may not be deleted
 							$do_delete = false;
 						} else {
-							// read all vhost subdomains with same parent domain
+							// read all vhost subdomains and alias with same parent domain
 							$used_paths = array();
-							$tmp = $app->db->queryAllRecords("SELECT `web_folder` FROM web_domain WHERE type = 'vhostsubdomain' AND parent_domain_id = ".intval($data['old']['parent_domain_id'])." AND domain_id != ".intval($data['old']['domain_id']));
+							$tmp = $app->db->queryAllRecords("SELECT `web_folder` FROM web_domain WHERE (type = 'vhostsubdomain' OR type = 'vhostalias') AND parent_domain_id = ? AND domain_id != ?", $data['old']['parent_domain_id'], $data['old']['domain_id']);
 							foreach($tmp as $tmprec) {
 								// we normalize the folder entries because we need to compare them
 								$tmp_folder = preg_replace('/[\/]{2,}/', '/', $tmprec['web_folder']); // replace / occuring multiple times
@@ -1911,6 +2230,8 @@
 				// remove PHP-FPM pool
 				if ($data['old']['php'] == 'php-fpm') {
 					$this->php_fpm_pool_delete($data, $web_config);
+				} elseif($data['old']['php'] == 'hhvm') {
+					$this->hhvm_update($data, $web_config);
 				}
 
 				//remove the php cgi starter script if available
@@ -1934,7 +2255,7 @@
 				$app->log('Removing website: '.$docroot, LOGLEVEL_DEBUG);
 
 				// Delete the symlinks for the sites
-				$client = $app->db->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = '.intval($data['old']['sys_groupid']));
+				$client = $app->db->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['old']['sys_groupid']);
 				$client_id = intval($client['client_id']);
 				unset($client);
 				$tmp_symlinks_array = explode(':', $web_config['website_symlinks']);
@@ -1973,7 +2294,7 @@
 				$this->awstats_delete($data, $web_config);
 			}
 
-			if($data['old']['type'] == 'vhostsubdomain') {
+			if($data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') {
 				$app->system->web_folder_protection($parent_web_document_root, true);
 			}
 
@@ -1988,25 +2309,19 @@
 			if($data['old']['type'] == 'vhost') {
 				$server_config = $app->getconf->get_server_config($conf['server_id'], 'server');
 				$backup_dir = $server_config['backup_dir'];
-				//* mount backup directory, if necessary
 				$mount_backup = true;
-				$server_config['backup_dir_mount_cmd'] = trim($server_config['backup_dir_mount_cmd']);
-				if($server_config['backup_dir'] != '') {
-					if($server_config['backup_dir_is_mount'] == 'y' && $server_config['backup_dir_mount_cmd'] != ''){
-						if(!$app->system->is_mounted($backup_dir)){
-							exec(escapeshellcmd($server_config['backup_dir_mount_cmd']));
-							sleep(1);
-							if(!$app->system->is_mounted($backup_dir)) $mount_backup = false;
-						}
-					}
+				if($server_config['backup_dir'] != '' && $server_config['backup_delete'] == 'y') {
+					//* mount backup directory, if necessary
+					if( $server_config['backup_dir_is_mount'] == 'y' && !$app->system->mount_backup_dir($backup_dir) ) $mount_backup = false;
+
 					if($mount_backup){
 						$web_backup_dir = $backup_dir.'/web'.$data_old['domain_id'];
 						//** do not use rm -rf $web_backup_dir because database(s) may exits
 						exec(escapeshellcmd('rm -f '.$web_backup_dir.'/web'.$data_old['domain_id'].'_').'*');
 						//* cleanup database
-						$sql = "DELETE FROM web_backup WHERE server_id = ".$conf['server_id']." AND parent_domain_id = ".$data_old['domain_id']." AND filename LIKE 'web".$data_old['domain_id']."_%'";
-						$app->db->query($sql);
-						if($app->db->dbHost != $app->dbmaster->dbHost) $app->dbmaster->query($sql);
+						$sql = "DELETE FROM web_backup WHERE server_id = ? AND parent_domain_id = ? AND filename LIKE ?";
+						$app->db->query($sql, $conf['server_id'], $data_old['domain_id'], "web".$data_old['domain_id']."_%");
+						if($app->db->dbHost != $app->dbmaster->dbHost) $app->dbmaster->query($sql, $conf['server_id'], $data_old['domain_id'], "web".$data_old['domain_id']."_%");
 
 						$app->log('Deleted the web backup files', LOGLEVEL_DEBUG);
 					}
@@ -2028,7 +2343,8 @@
 
 		$tpl = new tpl();
 		$tpl->newTemplate('apache_ispconfig.conf.master');
-		$records = $app->db->queryAllRecords('SELECT * FROM server_ip WHERE server_id = '.$conf['server_id']." AND virtualhost = 'y'");
+		$tpl->setVar('apache_version', $app->system->getapacheversion());
+		$records = $app->db->queryAllRecords("SELECT * FROM server_ip WHERE server_id = ? AND virtualhost = 'y'", $conf['server_id']);
 
 		$records_out= array();
 		if(is_array($records)) {
@@ -2074,8 +2390,8 @@
 			$folder_id = $data['new']['web_folder_id'];
 		}
 
-		$folder = $app->db->queryOneRecord("SELECT * FROM web_folder WHERE web_folder_id = ".intval($folder_id));
-		$website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($folder['parent_domain_id']));
+		$folder = $app->db->queryOneRecord("SELECT * FROM web_folder WHERE web_folder_id = ?", $folder_id);
+		$website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $folder['parent_domain_id']);
 
 		if(!is_array($folder) or !is_array($website)) {
 			$app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG);
@@ -2083,7 +2399,7 @@
 		}
 
 		$web_folder = 'web';
-		if($website['type'] == 'vhostsubdomain') $web_folder = $website['web_folder'];
+		if($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') $web_folder = $website['web_folder'];
 
 		//* Get the folder path.
 		if(substr($folder['path'], 0, 1) == '/') $folder['path'] = substr($folder['path'], 1);
@@ -2099,32 +2415,17 @@
 
 		//* Create the folder path, if it does not exist
 		if(!is_dir($folder_path)) {
-			$app->system->mkdirpath($folder_path);
-			$app->system->chown($folder_path, $website['system_user']);
-			$app->system->chgrp($folder_path, $website['system_group']);
+			$app->system->mkdirpath($folder_path, 0755, $website['system_user'], $website['system_group']);
 		}
 
 		//* Create empty .htpasswd file, if it does not exist
 		if(!is_file($folder_path.'.htpasswd')) {
 			$app->system->touch($folder_path.'.htpasswd');
-			$app->system->chmod($folder_path.'.htpasswd', 0750);
+			$app->system->chmod($folder_path.'.htpasswd', 0751);
 			$app->system->chown($folder_path.'.htpasswd', $website['system_user']);
 			$app->system->chgrp($folder_path.'.htpasswd', $website['system_group']);
 			$app->log('Created file '.$folder_path.'.htpasswd', LOGLEVEL_DEBUG);
 		}
-
-		/*
-		$auth_users = $app->db->queryAllRecords("SELECT * FROM web_folder_user WHERE active = 'y' AND web_folder_id = ".intval($folder_id));
-		$htpasswd_content = '';
-		if(is_array($auth_users) && !empty($auth_users)){
-			foreach($auth_users as $auth_user){
-				$htpasswd_content .= $auth_user['username'].':'.$auth_user['password']."\n";
-			}
-		}
-		$htpasswd_content = trim($htpasswd_content);
-		@file_put_contents($folder_path.'.htpasswd', $htpasswd_content);
-		$app->log('Changed .htpasswd file: '.$folder_path.'.htpasswd',LOGLEVEL_DEBUG);
-		*/
 
 		if(($data['new']['username'] != $data['old']['username'] || $data['new']['active'] == 'n') && $data['old']['username'] != '') {
 			$app->system->removeLine($folder_path.'.htpasswd', $data['old']['username'].':');
@@ -2161,7 +2462,7 @@
 		unset($old_content);
 
 		$app->system->file_put_contents($folder_path.'.htaccess', $ht_file);
-		$app->system->chmod($folder_path.'.htaccess', 0750);
+		$app->system->chmod($folder_path.'.htaccess', 0751);
 		$app->system->chown($folder_path.'.htaccess', $website['system_user']);
 		$app->system->chgrp($folder_path.'.htaccess', $website['system_group']);
 		$app->log('Created/modified file '.$folder_path.'.htaccess', LOGLEVEL_DEBUG);
@@ -2176,7 +2477,7 @@
 		$folder_id = $data['old']['web_folder_id'];
 
 		$folder = $data['old'];
-		$website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($folder['parent_domain_id']));
+		$website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $folder['parent_domain_id']);
 
 		if(!is_array($folder) or !is_array($website)) {
 			$app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG);
@@ -2184,7 +2485,7 @@
 		}
 
 		$web_folder = 'web';
-		if($website['type'] == 'vhostsubdomain') $web_folder = $website['web_folder'];
+		if($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') $web_folder = $website['web_folder'];
 
 		//* Get the folder path.
 		if(substr($folder['path'], 0, 1) == '/') $folder['path'] = substr($folder['path'], 1);
@@ -2231,7 +2532,7 @@
 	function web_folder_update($event_name, $data) {
 		global $app, $conf;
 
-		$website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($data['new']['parent_domain_id']));
+		$website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $data['new']['parent_domain_id']);
 
 		if(!is_array($website)) {
 			$app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG);
@@ -2239,7 +2540,7 @@
 		}
 
 		$web_folder = 'web';
-		if($website['type'] == 'vhostsubdomain') $web_folder = $website['web_folder'];
+		if($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') $web_folder = $website['web_folder'];
 
 		//* Get the folder path.
 		if(substr($data['old']['path'], 0, 1) == '/') $data['old']['path'] = substr($data['old']['path'], 1);
@@ -2323,10 +2624,19 @@
 			}
 
 			$app->system->file_put_contents($new_folder_path.'.htaccess', $ht_file);
-			$app->system->chmod($new_folder_path.'.htaccess', 0750);
+			$app->system->chmod($new_folder_path.'.htaccess', 0751);
 			$app->system->chown($new_folder_path.'.htaccess', $website['system_user']);
 			$app->system->chgrp($new_folder_path.'.htaccess', $website['system_group']);
 			$app->log('Created/modified file '.$new_folder_path.'.htaccess', LOGLEVEL_DEBUG);
+			
+			//* Create empty .htpasswd file, if it does not exist
+			if(!is_file($folder_path.'.htpasswd')) {
+				$app->system->touch($new_folder_path.'.htpasswd');
+				$app->system->chmod($new_folder_path.'.htpasswd', 0751);
+				$app->system->chown($new_folder_path.'.htpasswd', $website['system_user']);
+				$app->system->chgrp($new_folder_path.'.htpasswd', $website['system_group']);
+				$app->log('Created file '.$new_folder_path.'.htpasswd', LOGLEVEL_DEBUG);
+			}
 		}
 
 		//* Remove .htaccess file
@@ -2382,7 +2692,7 @@
 			/*
 			 * Get additional informations
 			*/
-			$sitedata = $app->db->queryOneRecord('SELECT document_root, domain, system_user, system_group FROM web_domain WHERE domain_id = ' . $data['new']['parent_domain_id']);
+			$sitedata = $app->db->queryOneRecord('SELECT document_root, domain, system_user, system_group FROM web_domain WHERE domain_id = ?', $data['new']['parent_domain_id']);
 			$documentRoot = $sitedata['document_root'];
 			$domain = $sitedata['domain'];
 			$user = $sitedata['system_user'];
@@ -2470,7 +2780,7 @@
 			/*
 			 * Get additional informations
 			*/
-			$sitedata = $app->db->queryOneRecord('SELECT document_root, domain FROM web_domain WHERE domain_id = ' . $data['old']['parent_domain_id']);
+			$sitedata = $app->db->queryOneRecord('SELECT document_root, domain FROM web_domain WHERE domain_id = ?', $data['old']['parent_domain_id']);
 			$documentRoot = $sitedata['document_root'];
 			$domain = $sitedata['domain'];
 
@@ -2692,9 +3002,88 @@
 		}
 	}
 
+	private function hhvm_update($data, $web_config) {
+		global $app, $conf;
+		
+		if(file_exists($conf['rootpath'] . '/conf-custom/hhvm_starter.master')) {
+			$content = file_get_contents($conf['rootpath'] . '/conf-custom/hhvm_starter.master');
+		} else {
+			$content = file_get_contents($conf['rootpath'] . '/conf/hhvm_starter.master');
+		}
+		if(file_exists($conf['rootpath'] . '/conf-custom/hhvm_monit.master')) {
+			$monit_content = file_get_contents($conf['rootpath'] . '/conf-custom/hhvm_monit.master');
+		} else {
+			$monit_content = file_get_contents($conf['rootpath'] . '/conf/hhvm_monit.master');
+		}
+		
+		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 = '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 ".($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'];
+								}
+							}
+						}
+					}
+				}
+			}
+			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($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);
+			file_put_contents('/etc/init.d/hhvm_' . $data['new']['system_user'], $content);
+			exec('chmod +x /etc/init.d/hhvm_' . $data['new']['system_user'] . ' >/dev/null 2>&1');
+			exec('/usr/sbin/update-rc.d hhvm_' . $data['new']['system_user'] . ' defaults >/dev/null 2>&1');
+			exec('/etc/init.d/hhvm_' . $data['new']['system_user'] . ' restart >/dev/null 2>&1');
+			
+			if(is_dir('/etc/monit/conf.d')){
+				$monit_content = str_replace('{SYSTEM_USER}', $data['new']['system_user'], $monit_content);
+				file_put_contents('/etc/monit/conf.d/00-hhvm_' . $data['new']['system_user'], $monit_content);
+				if(is_file('/etc/monit/conf.d/hhvm_' . $data['new']['system_user'])) unlink('/etc/monit/conf.d/hhvm_' . $data['new']['system_user']);
+				exec('/etc/init.d/monit restart >/dev/null 2>&1');
+			}
+			
+ 		} elseif($data['new']['php'] != 'hhvm' && $data['old']['php'] == 'hhvm') {
+			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/00-hhvm_' . $data['new']['system_user'])){
+					unlink('/etc/monit/conf.d/00-hhvm_' . $data['new']['system_user']);
+				}
+				exec('/etc/init.d/monit restart >/dev/null 2>&1');
+			}
+		}
+	}
+
 	//* Update the PHP-FPM pool configuration file
 	private function php_fpm_pool_update ($data, $web_config, $pool_dir, $pool_name, $socket_dir) {
 		global $app, $conf;
+		$pool_dir = trim($pool_dir);
 		//$reload = false;
 
 		if($data['new']['php'] == 'php-fpm'){
@@ -2737,8 +3126,12 @@
 		$app->load('tpl');
 		$tpl = new tpl();
 		$tpl->newTemplate('php_fpm_pool.conf.master');
-
-		if($data['new']['php_fpm_use_socket'] == 'y'){
+		$tpl->setVar('apache_version', $app->system->getapacheversion());
+		
+		$apache_modules = $app->system->getapachemodules();
+		
+		// Use sockets, but not with apache 2.4 on centos (mod_proxy_fcgi) as socket support is buggy in that version
+		if($data['new']['php_fpm_use_socket'] == 'y' && in_array('fastcgi_module',$apache_modules)){
 			$use_tcp = 0;
 			$use_socket = 1;
 			if(!is_dir($socket_dir)) $app->system->mkdirpath($socket_dir);
@@ -2751,11 +3144,12 @@
 
 		$fpm_socket = $socket_dir.$pool_name.'.sock';
 		$tpl->setVar('fpm_socket', $fpm_socket);
+		$tpl->setVar('fpm_listen_mode', '0660');
 
 		$tpl->setVar('fpm_pool', $pool_name);
 		$tpl->setVar('fpm_port', $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1);
 		$tpl->setVar('fpm_user', $data['new']['system_user']);
-		$tpl->setVar('fpm_group', $data['new']['system_group']);
+		$tpl->setVar('fpm_group', $web_config['group']);
 		$tpl->setVar('fpm_domain', $data['new']['domain']);
 		$tpl->setVar('pm', $data['new']['pm']);
 		$tpl->setVar('pm_max_children', $data['new']['pm_max_children']);
@@ -2766,6 +3160,7 @@
 		$tpl->setVar('pm_max_requests', $data['new']['pm_max_requests']);
 		$tpl->setVar('document_root', $data['new']['document_root']);
 		$tpl->setVar('security_level', $web_config['security_level']);
+		$tpl->setVar('domain', $data['new']['domain']);
 		$php_open_basedir = ($data['new']['php_open_basedir'] == '')?escapeshellcmd($data['new']['document_root']):escapeshellcmd($data['new']['php_open_basedir']);
 		$tpl->setVar('php_open_basedir', $php_open_basedir);
 		if($php_open_basedir != ''){
@@ -2777,6 +3172,27 @@
 		// Custom php.ini settings
 		$final_php_ini_settings = array();
 		$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 = '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 ".($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'];
+							}
+						}
+					}
+				}
+			}
+		}
+		
+		$custom_session_save_path = false;
 		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);
@@ -2788,10 +3204,11 @@
 					if(substr($ini_setting, 0, 1) == ';') continue;
 					if(substr($ini_setting, 0, 1) == '#') continue;
 					if(substr($ini_setting, 0, 2) == '//') continue;
-					list($key, $value) = explode('=', $ini_setting);
-					if($value){
-						$value = trim($value);
+					list($key, $value) = explode('=', $ini_setting, 2);
+					$value = trim($value);
+					if($value != ''){
 						$key = trim($key);
+						if($key == 'session.save_path') $custom_session_save_path = true;
 						switch (strtolower($value)) {
 						case '0':
 							// PHP-FPM might complain about invalid boolean value if you use 0
@@ -2812,7 +3229,9 @@
 				}
 			}
 		}
-
+		
+		$tpl->setVar('custom_session_save_path', ($custom_session_save_path ? 'y' : 'n'));
+		
 		$tpl->setLoop('custom_php_ini_settings', $final_php_ini_settings);
 
 		$app->system->file_put_contents($pool_dir.$pool_name.'.conf', $tpl->grab());
@@ -2820,7 +3239,7 @@
 		unset($tpl);
 
 		// delete pool in all other PHP versions
-		$default_pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']);
+		$default_pool_dir = trim(escapeshellcmd($web_config['php_fpm_pool_dir']));
 		if(substr($default_pool_dir, -1) != '/') $default_pool_dir .= '/';
 		if($default_pool_dir != $pool_dir){
 			if ( @is_file($default_pool_dir.$pool_name.'.conf') ) {
@@ -2829,9 +3248,10 @@
 				$app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
 			}
 		}
-		$php_versions = $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 = ".$conf["server_id"]);
+		$php_versions = $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 = ?", $conf["server_id"]);
 		if(is_array($php_versions) && !empty($php_versions)){
 			foreach($php_versions as $php_version){
+				$php_version['php_fpm_pool_dir'] = trim($php_version['php_fpm_pool_dir']);
 				if(substr($php_version['php_fpm_pool_dir'], -1) != '/') $php_version['php_fpm_pool_dir'] .= '/';
 				if($php_version['php_fpm_pool_dir'] != $pool_dir){
 					if ( @is_file($php_version['php_fpm_pool_dir'].$pool_name.'.conf') ) {
@@ -2872,6 +3292,7 @@
 		} else {
 			$pool_dir = $custom_php_fpm_pool_dir;
 		}
+		$pool_dir = trim($pool_dir);
 
 		if(substr($pool_dir, -1) != '/') $pool_dir .= '/';
 		$pool_name = 'web'.$data['old']['domain_id'];
@@ -2884,7 +3305,7 @@
 		}
 
 		// delete pool in all other PHP versions
-		$default_pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']);
+		$default_pool_dir = trim(escapeshellcmd($web_config['php_fpm_pool_dir']));
 		if(substr($default_pool_dir, -1) != '/') $default_pool_dir .= '/';
 		if($default_pool_dir != $pool_dir){
 			if ( @is_file($default_pool_dir.$pool_name.'.conf') ) {
@@ -2893,9 +3314,10 @@
 				$app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
 			}
 		}
-		$php_versions = $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 = ".$data['old']['server_id']);
+		$php_versions = $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 = ?", $data['old']['server_id']);
 		if(is_array($php_versions) && !empty($php_versions)){
 			foreach($php_versions as $php_version){
+				$php_version['php_fpm_pool_dir'] = trim($php_version['php_fpm_pool_dir']);
 				if(substr($php_version['php_fpm_pool_dir'], -1) != '/') $php_version['php_fpm_pool_dir'] .= '/';
 				if($php_version['php_fpm_pool_dir'] != $pool_dir){
 					if ( @is_file($php_version['php_fpm_pool_dir'].$pool_name.'.conf') ) {
@@ -2953,8 +3375,12 @@
 	//* Wrapper for exec function for easier debugging
 	private function _exec($command) {
 		global $app;
+		$out = array();
+		$ret = 0;
 		$app->log('exec: '.$command, LOGLEVEL_DEBUG);
-		exec($command);
+		exec($command, $out, $ret);
+		if($ret != 0) return false;
+		else return true;
 	}
 
 	private function _checkTcp ($host, $port) {

--
Gitblit v1.9.1