Przeglądaj źródła

Merge branch 'staging/features' into staging/sync

Kristan Kenney 5 lat temu
rodzic
commit
08dd2b05e4

+ 1 - 0
CHANGELOG.md

@@ -63,6 +63,7 @@ All notable changes to this project will be documented in this file.
 - Improved German translations (thanks **@ronald-at**)
 - Improved Russian translations (thanks **@Pleskan**)
 
+
 ## [1.2.0] - Major Release (Feature / Quality Update)
 ### Features
 - **NOTE:** Debian 8 is no longer supported as it has reached EOL (end-of-life) status.

+ 1 - 1
bin/v-add-web-domain

@@ -169,7 +169,7 @@ time=$(echo "$time_n_date" |cut -f 1 -d \ )
 date=$(echo "$time_n_date" |cut -f 2 -d \ )
 
 # Adding domain in web.conf
-echo "DOMAIN='$domain' IP='$ip' IP6='' ALIAS='$ALIAS' TPL='$WEB_TEMPLATE'\
+echo "DOMAIN='$domain' IP='$ip' IP6='' CUSTOM_DOCROOT='' ALIAS='$ALIAS' TPL='$WEB_TEMPLATE'\
  SSL='no' SSL_FORCE='no' SSL_HOME='same' LETSENCRYPT='no' FTP_USER='' FTP_MD5=''\
  BACKEND='$BACKEND_TEMPLATE' PROXY='$PROXY_TEMPLATE' PROXY_EXT='$PROXY_EXT'\
  STATS='' STATS_USER='' STATS_CRYPT='' U_DISK='0' U_BANDWIDTH='0'\

+ 11 - 3
bin/v-add-web-domain-backend

@@ -41,11 +41,12 @@ check_hestia_demo_mode
 
 # Defining pool directory
 prepare_web_backend
+get_domain_values 'web'
 
 # Checking backend configuration
-if [ -e "$pool/$backend_type.conf" ]; then
-    exit
-fi
+#if [ -e "$pool/$backend_type.conf" ]; then
+#    exit
+#fi
 
 # Allocating backend port
 backend_port=9000
@@ -65,6 +66,13 @@ cat $WEBTPL/$WEB_BACKEND/$template.tpl |\
         -e "s|%backend%|$backend_type|g"\
         -e "s|%backend_version%|$backend_version|g" > $pool/$backend_type.conf
 
+# Set correct document root path
+if [ ! -z "$CUSTOM_DOCROOT" ]; then
+    docroot="$CUSTOM_DOCROOT"
+    sed -i "s|/home\/$user\/web\/$domain\/public_html|$docroot|g"  $pool/$backend_type.conf
+else
+    docroot="$HOMEDIR/$user/web/$domain/public_html/"
+fi
 
 #----------------------------------------------------------#
 #                       Hestia                             #

+ 11 - 3
bin/v-change-web-domain-backend-tpl

@@ -39,6 +39,7 @@ is_object_unsuspended 'user' 'USER' "$user"
 is_object_valid 'web' 'DOMAIN' "$domain"
 is_object_unsuspended 'web' 'DOMAIN' "$domain"
 is_backend_template_valid $template
+get_domain_values 'web'
 
 # Perform verification if read-only mode is enabled
 check_hestia_demo_mode
@@ -48,11 +49,12 @@ check_hestia_demo_mode
 #                       Action                             #
 #----------------------------------------------------------#
 
-prepare_web_backend
-
-# Deleting backend
+# Deleting current backend
 delete_web_backend
 
+# Prepare new backend configuration
+prepare_web_backend
+
 # Allocating backend port
 backend_port=9000
 ports=$(grep -v '^;' $pool/* 2>/dev/null |grep listen |grep -o :[0-9].*)
@@ -72,6 +74,12 @@ cat $WEBTPL/$WEB_BACKEND/$template.tpl |\
         -e "s|%backend%|$backend_type|g"\
         -e "s|%backend_version%|$backend_version|g" > $pool/$backend_type.conf
 
+# Set correct document root path
+if [ ! -z "$CUSTOM_DOCROOT" ]; then
+    docroot="$CUSTOM_DOCROOT"
+    sed -i "s|/home\/$user\/web\/$domain\/public_html|$docroot|g"  $pool/$backend_type.conf
+fi
+
 # Checking backend pool configuration
 if [ "$backend_type" = "$user" ]; then
     conf=$USER_DATA/web.conf

+ 112 - 0
bin/v-change-web-domain-docroot

@@ -0,0 +1,112 @@
+#!/bin/bash
+# info: Changes the document root for an existing web domain
+
+# options: USER DOMAIN TARGET_DOMAIN [DIRECTORY]
+# example usage:
+# add custom docroot:    v-change-web-domain-docroot admin domain.tld otherdomain.tld
+#                        points domain.tld to otherdomain.tld's document root.
+#
+# remove custom docroot: v-change-web-domain-docroot admin test.local default
+#                        returns document root to default value for domain.
+
+# This call changes the document root of a chosen web domain
+# to another available domain under the user context.
+
+
+#----------------------------------------------------------#
+#                    Variable&Function                     #
+#----------------------------------------------------------#
+
+# Argument definition
+user=$1
+domain=$2
+
+# Export target domain and directory
+# so they are correctly passed through to domain.sh
+export target_domain=$3
+export target_directory=$4
+
+# Includes
+source $HESTIA/func/main.sh
+source $HESTIA/func/domain.sh
+source $HESTIA/conf/hestia.conf
+
+# Additional argument formatting
+format_domain
+
+#----------------------------------------------------------#
+#                    Verifications                         #
+#----------------------------------------------------------#
+
+check_args '2' "$#" 'USER DOMAIN TARGET_DOMAIN [DIRECTORY]'
+is_system_enabled "$WEB_SYSTEM" 'WEB_SYSTEM'
+# Check to ensure that target domain is valid if we're
+# not setting the docroot value back to defaults
+if [ "$target_domain" != "default" ]; then
+    is_format_valid 'user' 'domain' 'target_domain'
+    is_object_valid 'web' 'DOMAIN' "$target_domain"
+else
+    is_format_valid 'user' 'domain'
+fi
+is_object_valid 'user' 'USER' "$user" "$user"
+is_object_unsuspended 'user' 'USER' "$user"
+is_object_valid 'web' 'DOMAIN' "$domain"
+is_object_unsuspended 'web' 'DOMAIN' "$domain"
+is_object_value_empty 'web' 'DOMAIN' "$domain" '$docroot'
+is_dir_symlink "$HOMEDIR/$user/web"
+is_dir_symlink "$HOMEDIR/$user/web/$target_domain"
+
+# Perform verification if read-only mode is enabled
+check_hestia_demo_mode
+
+#----------------------------------------------------------#
+#                       Action                             #
+#----------------------------------------------------------#
+
+# Unset existing custom document root path
+if [ ! -z "$CUSTOM_DOCROOT" ]; then
+    update_object_value 'web' 'DOMAIN' "$domain" '$CUSTOM_DOCROOT' ""
+fi
+
+# If target domain value is 'default', remove the custom document root
+# value and rebuild web domain to restore default configuration.
+# Otherwise, set target document root path accordingly based on passed values.
+if [ "$target_domain" = "default" ]; then
+    update_object_value 'web' 'DOMAIN' "$domain" '$CUSTOM_DOCROOT' ""
+else
+    # Check for existence of specified directory under target domain's public_html folder
+    if [ ! -z "$target_directory" ]; then
+        if [ ! -e "$HOMEDIR/$user/web/$target_domain/public_html/$target_directory" ]; then
+            echo "ERROR: Directory $target_directory does not exist under $HOMEDIR/$user/$target_domain/public_html/."
+            exit 1
+        else
+            CUSTOM_DOCROOT="$HOMEDIR/$user/web/$target_domain/public_html/$target_directory/"
+        fi
+    else
+        CUSTOM_DOCROOT="$HOMEDIR/$user/web/$target_domain/public_html/"
+    fi
+    add_object_key 'web' 'DOMAIN' "$domain" 'CUSTOM_DOCROOT' 'IP6'
+    update_object_value 'web' 'DOMAIN' "$domain" '$CUSTOM_DOCROOT' "$CUSTOM_DOCROOT"
+fi
+
+#----------------------------------------------------------#
+#                       Hestia                             #
+#----------------------------------------------------------#
+
+# Rebuild domain configuration
+$BIN/v-rebuild-web-domain $user $domain
+
+# Logging
+if [ "$target_domain" = "default" ]; then
+    log_history "set web domain $domain to use default document root."
+else
+    log_history "set web domain $domain to use document root from $target_domain."
+fi
+
+log_event "$OK" "$ARGUMENTS"
+
+# Unset variables
+unset target_domain
+unset target_directory
+
+exit

+ 12 - 6
bin/v-list-web-domain

@@ -23,6 +23,7 @@ json_list() {
     echo '    "'$DOMAIN'": {
         "IP": "'$IP'",
         "IP6": "'$IP6'",
+        "DOCUMENT_ROOT": "'$DOCROOT'",
         "U_DISK": "'$U_DISK'",
         "U_BANDWIDTH": "'$U_BANDWIDTH'",
         "TPL": "'$TPL'",
@@ -40,7 +41,7 @@ json_list() {
         "BACKEND": "'$BACKEND'",
         "PROXY": "'$PROXY'",
         "PROXY_EXT": "'$PROXY_EXT'",
-        "DOCUMENT_ROOT": "'$HOMEDIR/$user/web/$domain/public_html'",
+        "CUSTOM_DOCROOT": "'$CUSTOM_DOCROOT'",
         "SUSPENDED": "'$SUSPENDED'",
         "TIME": "'$TIME'",
         "DATE": "'$DATE'"
@@ -50,10 +51,10 @@ json_list() {
 
 # SHELL list function
 shell_list() {
-    source $HESTIA/conf/hestia.conf
     echo "DOMAIN:         $DOMAIN"
     echo "ALIAS:          ${ALIAS//,/ }"
     echo "IP:             $IP"
+    echo "DOCUMENT_ROOT:  $DOCROOT"
     if [ ! -z "$IP6" ]; then
         echo "IP6:            $IP6"
     fi
@@ -95,7 +96,7 @@ shell_list() {
 
 # PLAIN list function
 plain_list() {
-    echo -ne "$DOMAIN\t$IP\t$IP6\t$U_DISK\t$U_BANDWIDTH\t$TPL\t"
+    echo -ne "$DOMAIN\t$IP\t$IP6\t$DOCROOT\t$U_DISK\t$U_BANDWIDTH\t$TPL\t"
     echo -ne "$ALIAS\t$STATS\t$STATS_USER\t$SSL\t$SSL_FORCE\t$SSL_HSTS\t$SSL_HOME\t,$LETSENCRYPT"
     echo -ne "$FTP_USER\t$FTP_PATH\t$AUTH_USER\t$BACKEND\t$PROXY\t"
     echo -e "$PROXY_EXT\t$SUSPENDED\t$TIME\t$DATE"
@@ -103,10 +104,10 @@ plain_list() {
 
 # CSV list function
 csv_list() {
-    echo -n "DOMAIN,IP,IP6,U_DISK,U_BANDWIDTH,TPL,ALIAS,STATS,STATS_USER,SSL,"
+    echo -n "DOMAIN,IP,IP6,DOCROOT,U_DISK,U_BANDWIDTH,TPL,ALIAS,STATS,STATS_USER,SSL,"
     echo -n "SSL_FORCE,SSL_HSTS,SSL_HOME,LETSENCRYPT,FTP_USER,FTP_PATH,AUTH_USER,BACKEND,PROXY,PROXY_EXT,"
     echo "SUSPENDED,TIME,DATE"
-    echo -n "$DOMAIN,$IP,$IP6,$U_DISK,$U_BANDWIDTH,$TPL,\"$ALIAS\",$STATS"
+    echo -n "$DOMAIN,$IP,$IP6,$DOCROOT,$U_DISK,$U_BANDWIDTH,$TPL,\"$ALIAS\",$STATS"
     echo -n "\"$STATS_USER\",$SSL,$SSL_FORCE,$SSL_HSTS,$SSL_HOME,$LETSENCRYPT,\"$FTP_USER\",\"$FTP_PATH\","
     echo -n "\"$AUTH_USER\",$BACKEND,$PROXY,\"$PROXY_EXT\",$SUSPENDED,$TIME,"
     echo  "$DATE"
@@ -130,6 +131,12 @@ is_object_valid 'web' 'DOMAIN' "$domain"
 # Parsing domain
 parse_object_kv_list $(grep "DOMAIN='$domain'" $USER_DATA/web.conf)
 
+if [ ! -z "$CUSTOM_DOCROOT" ]; then
+    DOCROOT="$CUSTOM_DOCROOT"
+else
+    DOCROOT="$HOMEDIR/$user/web/$DOMAIN/public_html/"
+fi
+
 # Listing data
 case $format in
     json)   json_list ;;
@@ -138,7 +145,6 @@ case $format in
     shell)  shell_list ;;
 esac
 
-
 #----------------------------------------------------------#
 #                       Hestia                             #
 #----------------------------------------------------------#

+ 25 - 4
bin/v-list-web-domains

@@ -24,9 +24,16 @@ json_list() {
     echo "{"
     while read str; do
         parse_object_kv_list "$str"
+        # Set correct document root path
+        if [ ! -z "$CUSTOM_DOCROOT" ]; then
+            DOCROOT="$CUSTOM_DOCROOT"
+        else
+            DOCROOT="$HOMEDIR/$user/web/$DOMAIN/public_html/"
+        fi
         echo -n '    "'$DOMAIN'": {
         "IP": "'$IP'",
         "IP6": "'$IP6'",
+        "DOCUMENT_ROOT": "'$DOCROOT'",
         "U_DISK": "'$U_DISK'",
         "U_BANDWIDTH": "'$U_BANDWIDTH'",
         "TPL": "'$TPL'",
@@ -72,7 +79,13 @@ plain_list() {
     IFS=$'\n'
     while read str; do
         parse_object_kv_list "$str"
-        echo -ne "$DOMAIN\t$IP\t$IP6\t$U_DISK\t$U_BANDWIDTH\t$TPL\t"
+        # Set correct document root path
+        if [ ! -z "$CUSTOM_DOCROOT" ]; then
+            DOCROOT="$CUSTOM_DOCROOT"
+        else
+            DOCROOT="$HOMEDIR/$user/web/$DOMAIN/public_html/"
+        fi
+        echo -ne "$DOMAIN\t$IP\t$IP6\t$DOCROOT\t$U_DISK\t$U_BANDWIDTH\t$TPL\t"
         echo -ne "$ALIAS\t$STATS\t$STATS_USER\t$SSL\t$SSL_HOME\t$LETSENCRYPT\t"
         echo -ne "$FTP_USER\t$FTP_PATH\t$AUTH_USER\t$BACKEND\t$PROXY\t"
         echo -e "$PROXY_EXT\t$SUSPENDED\t$TIME\t$DATE"
@@ -82,12 +95,18 @@ plain_list() {
 # CSV list function
 csv_list() {
     IFS=$'\n'
-    echo -n "DOMAIN,IP,IP6,U_DISK,U_BANDWIDTH,TPL,ALIAS,STATS,STATS_USER,"
+    echo -n "DOMAIN,IP,IP6,DOCROOT,U_DISK,U_BANDWIDTH,TPL,ALIAS,STATS,STATS_USER,"
     echo -n "SSL,SSL_HOME,LETSENCRYPT,FTP_USER,FTP_PATH,AUTH_USER,BACKEND,PROXY,"
     echo "PROXY_EXT,SUSPENDED,TIME,DATE"
     while read str; do
         parse_object_kv_list "$str"
-        echo -n "$DOMAIN,$IP,$IP6,$U_DISK,$U_BANDWIDTH,$TPL,"
+        # Set correct document root path
+        if [ ! -z "$CUSTOM_DOCROOT" ]; then
+            DOCROOT="$CUSTOM_DOCROOT"
+        else
+            DOCROOT="$HOMEDIR/$user/web/$DOMAIN/public_html/"
+        fi
+        echo -n "$DOMAIN,$IP,$IP6,$DOCROOT,$U_DISK,$U_BANDWIDTH,$TPL,"
         echo -n "\"$ALIAS\",$STATS,\"$STATS_USER\",$SSL,$SSL_HOME,$LETSENCRYPT,"
         echo -n "\"$FTP_USER\",\"$FTP_PATH\",\"$AUTH_USER\",$BACKEND,$PROXY,"
         echo "\"$PROXY_EXT\",$SUSPENDED,$TIME,$DATE"
@@ -113,9 +132,11 @@ case $format in
     json)   json_list ;;
     plain)  plain_list ;;
     csv)    csv_list ;;
-    shell)  shell_list |column -t ;;
+    shell)  shell_list ;;
 esac
 
+unset docroot
+
 
 #----------------------------------------------------------#
 #                       Hestia                             #

+ 26 - 1
func/domain.sh

@@ -159,7 +159,7 @@ prepare_web_domain_values() {
     docroot="$HOMEDIR/$user/web/$domain/public_html"
     sdocroot="$docroot"
     if [ "$SSL_HOME" = 'single' ]; then
-        sdocroot="$HOMEDIR/$user/web/$domain/public_shtml" ;
+        sdocroot="$HOMEDIR/$user/web/$domain/public_shtml"
     fi
 
     if [ ! -z "$WEB_BACKEND" ]; then
@@ -179,6 +179,31 @@ prepare_web_domain_values() {
     if [ ! -e "$USER_DATA/ssl/$domain.ca" ]; then
         ssl_ca_str='#'
     fi
+
+    # Set correct document root
+    if [ ! -z "$CUSTOM_DOCROOT" ]; then
+        # Custom document root has been set by the user, import from configuration
+        custom_docroot="$CUSTOM_DOCROOT"
+        docroot="$custom_docroot"
+        sdocroot="$docroot"
+    elif [ ! -z "$CUSTOM_DOCROOT" ] && [ ! -z "$target_directory" ]; then
+        # Custom document root has been specified with a different target than public_html
+        if [ -d "$HOMEDIR/$user/web/$target_domain/public_html/$target_directory/" ]; then
+            custom_docroot="$HOMEDIR/$user/web/$target_domain/public_html/$target_directory"
+            docroot="$custom_docroot"
+            sdocroot="$docroot"
+        fi
+    elif [ ! -z "$CUSTOM_DOCROOT" ] && [ -z "$target_directory" ]; then
+        # Set custom document root to target domain's public_html folder
+        custom_docroot="$HOMEDIR/$user/web/$target_domain/public_html"
+        docroot="$custom_docroot"
+        sdocroot="$docroot"
+    else
+        # No custom document root specified, use default
+        docroot="$HOMEDIR/$user/web/$domain/public_html"
+        sdocroot="$docroot"
+    fi
+
     if [ "$SUSPENDED" = 'yes' ]; then
         docroot="$HESTIA/data/templates/web/suspend"
         sdocroot="$HESTIA/data/templates/web/suspend"

+ 31 - 1
web/add/web/index.php

@@ -94,6 +94,10 @@ if (!empty($_POST['ok'])) {
     $v_stats = escapeshellarg($_POST['v_stats']);
     $v_stats_user = $data[$v_domain]['STATS_USER'];
     $v_stats_password = $data[$v_domain]['STATS_PASSWORD'];
+    $v_custom_doc_domain = $_POST['v-custom-doc-domain'];
+    $v_custom_doc_folder = $_POST['v-custom-doc-folder'];
+    $v_custom_doc_root_prepath = '/home/'.$user.'/web/';
+    
     $v_ftp = $_POST['v_ftp'];
     $v_ftp_user = $_POST['v_ftp_user'];
     $v_ftp_password = $_POST['v_ftp_password'];
@@ -109,7 +113,8 @@ if (!empty($_POST['ok'])) {
     if ((!empty($_POST['v_ssl_crt'])) || (!empty($_POST['v_ssl_key']))) $v_adv = 'yes';
     if ((!empty($_POST['v_ssl_ca'])) || ($_POST['v_stats'] != 'none')) $v_adv = 'yes';
     if ((!empty($_POST['v_letsencrypt']))) $v_adv = 'yes';
-
+    if (!empty($_POST['v_custom_doc_root_check'])){$v_adv = 'yes'; $v_custom_doc_root = 1; }
+    
     // Check advanced features
     if (empty($_POST['v_dns'])) $v_dns = 'off';
     if (empty($_POST['v_mail'])) $v_mail = 'off';
@@ -227,6 +232,24 @@ if (!empty($_POST['ok'])) {
         unlink($v_stats_password);
         $v_stats_password = escapeshellarg($_POST['v_stats_password']);
     }
+    
+    if ( !empty($_POST['v-custom-doc-domain']) && !empty($_POST['v_custom_doc_root_check']) && $v_custom_doc_root_prepath.$v_custom_doc_domain.'/public_html'.$v_custom_doc_folder != $v_custom_doc_root){
+        if($_POST['v-custom-doc-domain'] == $v_domain && empty($_POST['v-custom-doc-folder'])){
+
+        }else{
+            $v_custom_doc_domain = escapeshellarg($_POST['v-custom-doc-domain']);
+            $v_custom_doc_folder = escapeshellarg($_POST['v-custom-doc-folder']);
+            $v_domain = escapeshellarg(trim($_POST['v_domain']));
+            
+            exec(HESTIA_CMD."v-change-web-domain-docroot ".$user." ".$v_domain." ".$v_custom_doc_domain." ".$v_custom_doc_folder,  $output, $return_var);
+            check_return_code($return_var,$output);
+            unset($output);  
+            $v_custom_doc_root = 1; 
+        }
+    }else{
+        unset($v_custom_doc_root);
+    }   
+    
 
     // Restart DNS server
     if (($_POST['v_dns'] == 'on') && (empty($_SESSION['error_msg']))) {
@@ -354,6 +377,7 @@ if (!empty($_POST['ok'])) {
 // Define user variables
 $v_ftp_user_prepath = $panel[$user]['HOME'] . "/web";
 $v_ftp_email = $panel[$user]['CONTACT'];
+$v_custom_doc_root_prepath = '/home/'.$user.'/web/';
 
 // List IP addresses
 exec (HESTIA_CMD."v-list-user-ips ".$user." json", $output, $return_var);
@@ -365,6 +389,12 @@ exec (HESTIA_CMD."v-list-web-stats json", $output, $return_var);
 $stats = json_decode(implode('', $output), true);
 unset($output);
 
+// Get all user domains 
+exec (HESTIA_CMD."v-list-web-domains ".escapeshellarg($user)." json", $output, $return_var);
+$user_domains = json_decode(implode('', $output), true);
+$user_domains = array_keys($user_domains);
+unset($output);
+
 // Render page
 render_page($user, $TAB, 'add_web');
 

+ 40 - 2
web/edit/web/index.php

@@ -73,11 +73,24 @@ $v_proxy_ext = str_replace(',', ', ', $data[$v_domain]['PROXY_EXT']);
 $v_stats = $data[$v_domain]['STATS'];
 $v_stats_user = $data[$v_domain]['STATS_USER'];
 if (!empty($v_stats_user)) $v_stats_password = "";
+$v_custom_doc_root_prepath = '/home/'.$v_username.'/web/';
+$v_custom_doc_root = $data[$v_domain]['CUSTOM_DOCROOT'];
+
+$m = preg_match('/\/home\/'.$v_username.'\/web\/([A-Za-z0-9.-].*)\/([A-Za-z0-9.-\/].*)/', $v_custom_doc_root, $matches);
+$v_custom_doc_domain = $matches[1];
+$v_custom_doc_folder = str_replace('public_html/','',$matches[2]);
+
 $v_ftp_user = $data[$v_domain]['FTP_USER'];
 $v_ftp_path = $data[$v_domain]['FTP_PATH'];
 if (!empty($v_ftp_user)) $v_ftp_password = "";
-$v_ftp_user_prepath = $data[$v_domain]['DOCUMENT_ROOT'];
-$v_ftp_user_prepath = str_replace('/public_html', '', $v_ftp_user_prepath, $occurance = 1);
+
+if($v_custom_doc_domain != ''){
+    $v_ftp_user_prepath = '/home/'.$v_username.'/web/'.$v_custom_doc_domain;
+}else{
+    $v_ftp_user_prepath = '/home/'.$v_username.'/web/'.$v_domain;
+}
+
+
 $v_ftp_email = $panel[$user]['CONTACT'];
 $v_suspended = $data[$v_domain]['SUSPENDED'];
 if ( $v_suspended == 'yes' ) {
@@ -736,6 +749,31 @@ if (!empty($_POST['save'])) {
             }
         }
     }
+    //custom docoot with check box disabled      
+    if( !empty($v_custom_doc_root) && empty($_POST['v_custom_doc_root_check']) ){
+        exec(HESTIA_CMD."v-change-web-domain-docroot ".$v_username." ".escapeshellarg($v_domain)." default",  $output, $return_var);
+        check_return_code($return_var,$output);
+        unset($output);    
+        unset($_POST['v-custom-doc-domain'], $_POST['v-custom-doc-folder']);    
+    }
+
+    if ( !empty($_POST['v-custom-doc-domain']) && !empty($_POST['v_custom_doc_root_check']) && $v_custom_doc_root_prepath.$v_custom_doc_domain.'/public_html'.$v_custom_doc_folder != $v_custom_doc_root){
+        if($_POST['v-custom-doc-domain'] == $v_domain && empty($_POST['v-custom-doc-folder'])){
+            exec(HESTIA_CMD."v-change-web-domain-docroot ".$v_username." ".escapeshellarg($v_domain)." default",  $output, $return_var);
+            check_return_code($return_var,$output);
+            unset($output);     
+        }else{
+            $v_custom_doc_domain = escapeshellarg($_POST['v-custom-doc-domain']);
+            $v_custom_doc_folder = escapeshellarg($_POST['v-custom-doc-folder']);
+        
+            exec(HESTIA_CMD."v-change-web-domain-docroot ".$v_username." ".escapeshellarg($v_domain)." ".$v_custom_doc_domain." ".$v_custom_doc_folder,  $output, $return_var);
+            check_return_code($return_var,$output);
+            unset($output);  
+            $v_custom_doc_root = 1; 
+        }
+    }else{
+        unset($v_custom_doc_root);
+    }   
 
     // Restart web server
     if (!empty($restart_web) && (empty($_SESSION['error_msg']))) {

+ 44 - 0
web/js/pages/add_web.js

@@ -1,3 +1,43 @@
+ App.Actions.WEB.update_custom_doc_root = function(elm, hint) {
+    var prepath = $('input[name="v-custom-doc-root_prepath"]').val();
+    var domain = $('select[name="v-custom-doc-domain"]').val();
+    var folder = $('input[name="v-custom-doc-folder"]').val();
+    console.log(domain, folder);
+    $('.custom_docroot_hint').html(prepath+domain+'/public_html/'+folder);
+}
+App.Listeners.DB.keypress_custom_folder = function() {
+    var ref = $('input[name="v-custom-doc-folder"]');
+    var current_rec = ref.val();
+    App.Actions.WEB.update_custom_doc_root(ref, current_rec);
+    
+    ref.bind('keypress input', function(evt) {
+        clearTimeout(window.frp_usr_tmt);
+        window.frp_usr_tmt = setTimeout(function() {
+            var elm = $(evt.target);
+            App.Actions.WEB.update_custom_doc_root(elm, $(elm).val());
+        });
+    });
+}
+
+App.Listeners.DB.change_custom_doc = function() {
+    var ref = $('select[name="v-custom-doc-domain"]');
+    var current_rec = ref.val();
+    ref.bind('change select', function(evt) {
+        clearTimeout(window.frp_usr_tmt);
+        window.frp_usr_tmt = setTimeout(function() {
+            var elm = $(evt.target);
+            App.Actions.WEB.update_custom_doc_root(elm, $(elm).val());
+            var domain = $('.ftp-path-prefix').text(GLOBAL.FTP_USER_PREPATH + '/' + $(evt.target));
+
+        });
+    });
+}
+
+// Page entry point
+// Trigger listeners
+App.Listeners.DB.keypress_custom_folder();
+App.Listeners.DB.change_custom_doc();
+
 App.Actions.WEB.update_ftp_username_hint = function(elm, hint) {
     if (hint.trim() == '') {
         $(elm).parent().find('.hint').html('');
@@ -38,6 +78,10 @@ App.Listeners.WEB.keypress_domain_name = function() {
             //var elm = $(evt.target);
             //App.Actions.WEB.update_ftp_username_hint(elm, $(elm).val());
             var domain = $('.ftp-path-prefix').text(GLOBAL.FTP_USER_PREPATH + '/' + $('#v_domain').val());
+            $('#v-custom-doc-domain-main').text($('#v_domain').val());
+            $('#v-custom-doc-domain-main').val($('#v_domain').val());
+            App.Actions.WEB.update_custom_doc_root(13, 12);
+            
         }, 100);
     });
 }

+ 39 - 0
web/js/pages/edit_web.js

@@ -1,3 +1,42 @@
+App.Actions.WEB.update_custom_doc_root = function(elm, hint) {
+    var prepath = $('input[name="v-custom-doc-root_prepath"]').val();
+    var domain = $('select[name="v-custom-doc-domain"]').val();
+    var folder = $('input[name="v-custom-doc-folder"]').val();
+    console.log(domain, folder);
+    $('.custom_docroot_hint').html(prepath+domain+'/public_html/'+folder);
+}
+App.Listeners.DB.keypress_custom_folder = function() {
+    var ref = $('input[name="v-custom-doc-folder"]');
+    var current_rec = ref.val();
+    App.Actions.WEB.update_custom_doc_root(ref, current_rec);
+
+
+    ref.bind('keypress input', function(evt) {
+        clearTimeout(window.frp_usr_tmt);
+        window.frp_usr_tmt = setTimeout(function() {
+            var elm = $(evt.target);
+            App.Actions.WEB.update_custom_doc_root(elm, $(elm).val());
+        });
+    });
+}
+
+App.Listeners.DB.change_custom_doc = function() {
+    var ref = $('select[name="v-custom-doc-domain"]');
+    var current_rec = ref.val();
+    ref.bind('change select', function(evt) {
+        clearTimeout(window.frp_usr_tmt);
+        window.frp_usr_tmt = setTimeout(function() {
+            var elm = $(evt.target);
+            App.Actions.WEB.update_custom_doc_root(elm, $(elm).val());
+        });
+    });
+}
+
+// Page entry point
+// Trigger listeners
+App.Listeners.DB.keypress_custom_folder();
+App.Listeners.DB.change_custom_doc();
+
 App.Actions.WEB.update_ftp_username_hint = function(elm, hint) {
     if (hint.trim() == '') {
         $(elm).parent().find('.hint').html('');

+ 57 - 1
web/templates/admin/add_web.html

@@ -195,7 +195,63 @@
                                     </table>
                                 </td>
                             </tr>
-
+                             <tr>
+                                <td class="vst-text step-top">
+                                    <label><input type="checkbox" size="20" class="vst-checkbox" name="v_custom_doc_root_check" <?php if (!empty($v_custom_doc_root)) echo "checked=yes" ?> onclick="javascript:elementHideShow('v_custom_doc_root');"> <?php print __('Custom document root');?></label>
+                                </td>
+                            </tr>
+                            <tr>
+                                <td class="step-left">
+                                    <table style="display:<?php if (empty($v_custom_doc_root)) { echo 'none';} else {echo 'block';}?> ;" id="v_custom_doc_root">
+                                        <tr>
+                                            <td class="vst-text input-label">
+                                                <?php print __('Point to');?>
+                                            </td>
+                                        </tr>
+                                        <tr>
+                                            <td>
+                                                <input type="hidden" name="v-custom-doc-root_prepath" value="<?php echo $v_custom_doc_root_prepath;?>">
+                                                <select class="vst-list" name="v-custom-doc-domain">
+                                                    <option value="<?=htmlentities(trim($v_domain, "'"))?>" id="v-custom-doc-domain-main"><?=htmlentities(trim($v_domain, "'"))?></option>
+                                                    <?php
+                                                    foreach ($user_domains  as $domain) {
+                                                        if($domain != $v_domain ){
+                                                        if($v_custom_doc_domain == $domain){
+                                                    ?>
+                                                            <option value="<?php echo $domain;?>" selected="selected"><?php echo $domain;?></option> 
+                                                    <?php
+                                                        }else{
+                                                     ?>
+                                                            <option value="<?php echo $domain;?>"><?php echo $domain;?></option> 
+                                                    <?php                                                           
+                                                        }
+                                                        }
+                                                    }
+                                                    ?>
+                                                </select>
+                                            </td>
+                                        </tr>
+                                        <tr>
+                                            <td class="vst-text input-label">
+                                                <?php print( __('Folder'));?> <span class="optional">(<?php print __('optional');?>)</span>
+                                            </td>
+                                        </tr>
+                                        <tr>
+                                            <td>
+                                                <input type="text" size="20" class="vst-input"
+                                                name="v-custom-doc-folder" value="<?=htmlentities(trim($v_custom_doc_folder, "'"))?>">
+                                            </td>
+                                        </tr>
+                                        <tr>
+                                            <td>
+                                                <small class="custom_docroot_hint"></small>
+                                            </td>
+                                        </tr>
+                                        
+                                    </table>
+                                </td>
+                            </tr>
+                                                    
                         <tr>
                             <td class="step-top vst-text">
                                 <label><input type="checkbox" size="20" class="vst-checkbox" name="v_ssl" <?php if($v_ssl == 'yes' || $v_ssl == 'on') echo "checked=yes" ?> onclick="javascript:elementHideShow('ssltable');"> <?php print __('SSL Support');?></label>

+ 57 - 0
web/templates/admin/edit_web.html

@@ -243,6 +243,63 @@
                                 </td>
                             </tr>
                             <?php } ?>
+                            <tr>
+                                <td class="vst-text step-top">
+                                    <label><input type="checkbox" size="20" class="vst-checkbox" name="v_custom_doc_root_check" <?php if (!empty($v_custom_doc_root)) echo "checked=yes" ?> onclick="javascript:elementHideShow('v_custom_doc_root');"> <?php print __('Custom document root');?></label>
+                                </td>
+                            </tr>
+                            <tr>
+                                <td class="step-left">
+                                    <table style="display:<?php if (empty($v_custom_doc_root)) { echo 'none';} else {echo 'block';}?> ;" id="v_custom_doc_root">
+                                        <tr>
+                                            <td class="vst-text input-label">
+                                                <?php print __('Point to');?>
+                                            </td>
+                                        </tr>
+                                        <tr>
+                                            <td>
+                                                <input type="hidden" name="v-custom-doc-root_prepath"" value="<?php echo $v_custom_doc_root_prepath;?>">
+                                                <select class="vst-list" name="v-custom-doc-domain">
+                                                    <option value="<?php echo $v_domain;?>"><?php echo $v_domain;?></option>
+                                                    <?php
+                                                    foreach ($user_domains as $domain) {
+                                                        if($domain != $v_domain ){
+                                                        if($v_custom_doc_domain == $domain){
+                                                    ?>
+                                                            <option value="<?php echo $domain;?>" selected="selected"><?php echo $domain;?></option> 
+                                                    <?php
+                                                        }else{
+                                                     ?>
+                                                            <option value="<?php echo $domain;?>"><?php echo $domain;?></option> 
+                                                    <?php                                                           
+                                                        }
+                                                        }
+                                                    }
+                                                    ?>
+                                                </select>
+                                            </td>
+                                        </tr>
+                                        <tr>
+                                            <td class="vst-text input-label">
+                                                <?php print( __('Folder'));?> <span class="optional">(<?php print __('optional');?>)</span>
+                                            </td>
+                                        </tr>
+                                        <tr>
+                                            <td>
+                                                <input type="text" size="20" class="vst-input"
+                                                name="v-custom-doc-folder" value="<?=htmlentities(trim($v_custom_doc_folder, "'"))?>">
+                                            </td>
+                                        </tr>
+                                        <tr>
+                                            <td>
+                                                <small class="custom_docroot_hint"></small>
+                                            </td>
+                                        </tr>
+                                        
+                                    </table>
+                                </td>
+                            </tr>
+                          
                             <tr>
                                 <td class="vst-text step-top">
                                     <label><input type="checkbox" size="20" class="vst-checkbox" name="v_ssl" <?php if ($v_ssl == 'yes') echo "checked=yes" ?> onclick="javascript:elementHideShow('ssltable');"> <?php print __('SSL Support');?></label>

+ 57 - 0
web/templates/user/edit_web.html

@@ -256,6 +256,63 @@
                                 </td>
                             </tr>
                             <?php } ?>
+                            <tr>
+                                <td class="vst-text step-top">
+                                    <label><input type="checkbox" size="20" class="vst-checkbox" name="v_custom_doc_root_check" <?php if (!empty($v_custom_doc_root)) echo "checked=yes" ?> onclick="javascript:elementHideShow('v_custom_doc_root');"> <?php print __('Custom document root');?></label>
+                                </td>
+                            </tr>
+                            <tr>
+                                <td class="step-left">
+                                    <table style="display:<?php if (empty($v_custom_doc_root)) { echo 'none';} else {echo 'block';}?> ;" id="v_custom_doc_root">
+                                        <tr>
+                                            <td class="vst-text input-label">
+                                                <?php print __('Point to');?>
+                                            </td>
+                                        </tr>
+                                        <tr>
+                                            <td>
+                                                <input type="hidden" name="v-custom-doc-root_prepath"" value="<?php echo $v_custom_doc_root_prepath;?>">
+                                                <select class="vst-list" name="v-custom-doc-domain">
+                                                    <option value="<?php echo $v_domain;?>"><?php echo $v_domain;?></option>
+                                                    <?php
+                                                    foreach ($user_domains  as $domain) {
+                                                        if($domain != $v_domain ){
+                                                        if($v_custom_doc_domain == $domain){
+                                                    ?>
+                                                            <option value="<?php echo $domain;?>" selected="selected"><?php echo $domain;?></option> 
+                                                    <?php
+                                                        }else{
+                                                     ?>
+                                                            <option value="<?php echo $domain;?>"><?php echo $domain;?></option> 
+                                                    <?php                                                           
+                                                        }
+                                                        }
+                                                    }
+                                                    ?>
+                                                </select>
+                                            </td>
+                                        </tr>
+                                        <tr>
+                                            <td class="vst-text input-label">
+                                                <?php print( __('Folder'));?> <span class="optional">(<?php print __('optional');?>)</span>
+                                            </td>
+                                        </tr>
+                                        <tr>
+                                            <td>
+                                                <input type="text" size="20" class="vst-input"
+                                                name="v-custom-doc-folder" value="<?=htmlentities(trim($v_custom_doc_folder, "'"))?>">
+                                            </td>
+                                        </tr>
+                                        <tr>
+                                            <td>
+                                                <small class="custom_docroot_hint"></small>
+                                            </td>
+                                        </tr>
+                                        
+                                    </table>
+                                </td>
+                            </tr>
+
                             <tr>
                                 <td class="vst-text step-top">
                                     <label><input type="checkbox" size="20" class="vst-checkbox" name="v_ssl" <?php if ($v_ssl == 'yes') echo "checked=yes" ?> onclick="javascript:elementHideShow('ssltable');"> <?php print __('SSL Support');?></label>