From 3b23ef916b969e579684938146772bdcbdf60ce6 Mon Sep 17 00:00:00 2001 From: JackieDo Date: Sat, 28 Dec 2019 12:12:39 +0700 Subject: [PATCH] Upgrade core - Cleanup source code. - Refactoring the source code. - Add more features. - Extend the installation method. --- README.md | 57 +++++++- apppath_register.vbs | 18 --- cacert_generate.bat | 1 - composer.json | 29 ++++ help.hlp | 26 ++-- support/Application.php | 145 +++++++++++++++++++ support/Console.php | 18 +-- support/Installer.php | 277 ++++++++++++++++++----------------- support/Manager.php | 304 +++++++++++++++++++++++++-------------- support/PathRegister.vbs | 78 ++++++++++ support/PowerExec.vbs | 236 ++++++++++++++++-------------- support/Setting.php | 13 +- vhostcert_generate.bat | 1 - xvhosts.bat | 203 ++++++++------------------ xvhosts.php | 37 +++-- 15 files changed, 878 insertions(+), 565 deletions(-) delete mode 100644 apppath_register.vbs create mode 100644 composer.json create mode 100644 support/Application.php create mode 100644 support/PathRegister.vbs diff --git a/README.md b/README.md index 0c3eb8d..2270d36 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,8 @@ Therefore, this project was born, in order to strengthen Xampp, helping users ta * List all existing virtual hosts. * Add SSL certificate to an existing virtual host. * Remove SSL certificate of an existing virtual host. +* Stop Xampp Apache Httpd +* Start Xampp Apache Httpd * Restart Xampp Apache Httpd. # Overview @@ -30,6 +32,8 @@ Look at one of the following topics to learn more about Xampp vHosts Manager * [Compatibility](#compatibility) * [Requirement](#requirement) * [Installation](#installation) + - [Via Composer Create-Project](#via-composer-create-project) + - [Via Manual Download](#via-manual-download) * [Usage](#usage) - [Display the help message](#display-the-help-message) - [Create new virtual host](#create-new-virtual-host) @@ -38,7 +42,10 @@ Look at one of the following topics to learn more about Xampp vHosts Manager - [Remove an existing virtual host](#remove-an-existing-virtual-host) - [Add SSL certificate to an existing virtual host](#add-ssl-certificate-to-an-existing-virtual-host) - [Remove SSL certificate of an existing virtual host](#remove-ssl-certificate-of-an-existing-virtual-host) + - [Stop Apache Httpd](#stop-apache-httpd) + - [Start Apache Httpd](#start-apache-httpd) - [Restart Apache Httpd](#restart-apache-httpd) + - [Register path of application](#register-path-of-application) * [Configuration](#configuration) * [License](#license) * [Thanks from author](#thanks-for-use) @@ -47,18 +54,30 @@ Look at one of the following topics to learn more about Xampp vHosts Manager Xampp vHosts Manager is compatible with all Xampp versions using PHP 5.4 or higher. ## Requirement -Xampp vHosts Manager takes full advantage of what's included in Xampp, nothing more needed. So, you just need two following things: +Xampp vHosts Manager takes full advantage of what's included in Xampp, nothing more needed. So, you just need following things: -* Xampp installed (of course). -* Added the path to PHP directory of Xampp to system environment variables. +* Installed Xampp (of course). +* Added the path to PHP directory of Xampp into Windows Path Environment Variable. +* (Optional) Installed Composer. -> _Note: See [here](https://helpdeskgeek.com/windows-10/add-windows-path-environment-variable/) to know how to add Windows path environment variable._ +> _Note: See [here](https://helpdeskgeek.com/windows-10/add-windows-path-environment-variable/) to know how to add Windows Path Environment Variable._ ## Installation +There are two installation methods, via Composer or manual download. It is recommended to use the method via Composer if you already have it installed. + +#### Via Composer Create-Project +* Open a terminal. +* Navigate to the directory you want to install Xampp vHosts Manager into. +* Run composer create-project command: +``` +$ composer create-project jackiedo/xampp-vhosts-manager xvhm "1.*" +``` + +#### Via Manual Download * Download the [latest release](https://github.com/JackieDo/Xampp-vHosts-Manager/releases/latest) -* Extract the archive to a shared location `(example: D:\vhostsManager)`. Note: Should not place in `C:\Program Files` or anywhere else that would require Administrator access for modifying configuration files. +* Extract the archive to a shared location `(example: D:\xvhm)`. Note: Should not place in `C:\Program Files` or anywhere else that would require Administrator access for modifying configuration files. * Open a terminal in Administrator mode `(run as Administrator)`. -* Navigate to the directory you have placed Xampp vHosts Manager `(example: cd /D D:\vhostsManager)`. +* Navigate to the directory you have placed Xampp vHosts Manager `(example: cd /D D:\xvhm)`. * Execute the command `xvhosts install` and follow the required steps. * Exit terminal. @@ -143,6 +162,20 @@ Example: $ xvhosts remove_ssl demo.local ``` +#### Stop Apache Httpd + +Syntax: +``` +$ xvhosts stop_apache +``` + +#### Start Apache Httpd + +Syntax: +``` +$ xvhosts start_apache +``` + #### Restart Apache Httpd Syntax: @@ -150,6 +183,18 @@ Syntax: $ xvhosts restart_apache ``` +#### Register path of application +This feature allows you to register the path to the application directory of Xampp vHosts Manager into the Windows Path Environment Variable. Usually, you rarely need this. It is only useful when you need to change the application directory name of Xampp vHosts Manager or move it to another location. + +To do this, after you have changed the directory, navigate to the new location of application directory in the command prompt and run the following command: + +Syntax: +``` +$ xvhosts register_path +``` + +> Note: You need to accept this feature to be implemented in Administrator mode. + ## Configuration All onfiguration are put in an ini file with name `settings.ini` located in Xampp vHosts Manager application directory. The structure of this file looks like this: diff --git a/apppath_register.vbs b/apppath_register.vbs deleted file mode 100644 index 9e3bc77..0000000 --- a/apppath_register.vbs +++ /dev/null @@ -1,18 +0,0 @@ -Set objShell = CreateObject("WScript.Shell") -Set objSystemEnv = objShell.Environment("SYSTEM") -appStarted = objShell.ExpandEnvironmentStrings("%XVHM_APP_STARTED%") -appDir = objShell.ExpandEnvironmentStrings("%XVHM_APP_DIR%") - -If ((appStarted = "true") and (not appDir = "%XVHM_APP_DIR%")) Then - currentSystemPath = objSystemEnv("PATH") - - If (InStr(currentSystemPath, appDir & ";") = 0) and (InStr(currentSystemPath, ";" & appDir) = 0) Then - objSystemEnv("PATH") = appDir & ";" & currentSystemPath - End If -Else - WScript.Echo "This script does not accept running as a standalone application." & _ - vbNewLine & "Please run application from command ""xvhosts""" -End If - -Set objSystemEnv = Nothing -Set objShell = Nothing \ No newline at end of file diff --git a/cacert_generate.bat b/cacert_generate.bat index 739de9a..8840feb 100644 --- a/cacert_generate.bat +++ b/cacert_generate.bat @@ -3,7 +3,6 @@ cls setlocal EnableExtensions :: Check necessary data -if not "%XVHM_APP_STARTED%"=="true" goto missing if "%XVHM_APP_DIR%"=="" goto missing if "%XVHM_TMP_DIR%"=="" goto missing if "%XVHM_CACERT_DIR%"=="" goto missing diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..fb9935b --- /dev/null +++ b/composer.json @@ -0,0 +1,29 @@ +{ + "name": "jackiedo/xampp-vhosts-manager", + "description": "Virtual hosts (SSL) management system (in console mode) for Xampp on Windows OS.", + "keywords": [ + "xampp", + "virtual-hosts", + "vhosts", + "ssl-certificates", + "ssl-cert", + "ssl", + "domain", + "manager", + "console" + ], + "license": "MIT", + "type": "project", + "require": { + "php": ">=5.4" + }, + "scripts": { + "post-create-project-cmd": [ + "xvhosts.bat install" + ] + }, + "config": { + "sort-packages": true, + "optimize-autoloader": true + } +} \ No newline at end of file diff --git a/help.hlp b/help.hlp index 18c73b0..04139c3 100644 --- a/help.hlp +++ b/help.hlp @@ -4,19 +4,21 @@ Virtual hosts manager for Xampp on Windows OS Usage: xvhosts [HOST_NAME] - Available commands: - install Intergrate Xampp vHosts Manager into Xampp - (require running in Administrator mode). - new Create a new virtual host. - show Display information of specific virtual host. - remove Remove specific virtual host. - add_ssl Add SSL certificate to specific virtual host. - remove_ssl Remove SSL certificate of specific virtual host. - list List all existing virtual hosts. - restart_apache Restart Apache httpd. - help Display the help message. - + install Intergrate Xampp vHosts Manager into Xampp + (require running in Administrator mode). + new Create a new virtual host. + show Display information of specific virtual host. + remove Remove specific virtual host. + add_ssl Add SSL certificate to specific virtual host. + remove_ssl Remove SSL certificate of specific virtual host. + list List all existing virtual hosts. + stop_apache Stop Apache httpd. + start_apache Start Apache httpd. + restart_apache Stop Apache httpd and start it again. + register_path Register path to Xampp vHosts Manager directory + into Windows Path Environment Variable. + help Display the help message. Examples: xvhosts new demo.local diff --git a/support/Application.php b/support/Application.php new file mode 100644 index 0000000..3daf9e0 --- /dev/null +++ b/support/Application.php @@ -0,0 +1,145 @@ + 'Xampp vHosts Manager is terminating...')); + + $this->setting = new Setting; + + $this->loadAppPaths(); + + if ($detectXamppPaths) { + $this->detectXamppPaths(); + } + } + + private function loadAppPaths() + { + $appDir = realpath(getenv('XVHM_APP_DIR')); + + $this->paths['appDir'] = $appDir; + $this->paths['phpDir'] = dirname(PHP_BINARY); + $this->paths['tmpDir'] = $appDir . '\tmp'; + $this->paths['caCertDir'] = $appDir . '\cacert'; + $this->paths['caCertGenScript'] = $appDir . '\cacert_generate.bat'; + $this->paths['caCertGenConfig'] = $appDir . '\cacert_generate.cnf'; + $this->paths['vhostConfigTemplate'] = $appDir . '\templates\vhost_config\vhost.conf.tpl'; + $this->paths['vhostSSLConfigTemplate'] = $appDir . '\templates\vhost_config\vhost_ssl.conf.tpl'; + $this->paths['vhostCertGenScript'] = $appDir . '\vhostcert_generate.bat'; + $this->paths['vhostCertGenConfig'] = $appDir . '\vhostcert_generate.cnf'; + $this->paths['pathRegister'] = $appDir . '\support\PathRegister.vbs'; + $this->paths['powerExecutor'] = $appDir . '\support\PowerExec.vbs'; + $this->paths['winHostsFile'] = realpath($_SERVER['SystemRoot'] . '\System32\drivers\etc\hosts'); + + // Set environment variables + putenv('XVHM_TMP_DIR=' . $this->paths['tmpDir']); + putenv('XVHM_CACERT_DIR=' . $this->paths['caCertDir']); + putenv('XVHM_CACERT_GENERATE_CONFIG=' . $this->paths['caCertGenConfig']); + putenv('XVHM_VHOST_CERT_GENERATE_CONFIG=' . $this->paths['vhostCertGenConfig']); + } + + protected function detectXamppPaths() + { + // Force reload settings + $this->setting->reloadSettings(); + + $xamppDir = realpath($this->setting->get('DirectoryPaths', 'Xampp')); + $apacheDir = $this->setting->get('DirectoryPaths', 'Apache'); + + if (! $xamppDir || ! is_file($xamppDir . '\xampp-control.exe')) { + Console::breakline(); + + $message = 'Cannot find Xampp directory.' . PHP_EOL; + $message .= 'Please check the configuration path to the Xampp directory in file "' . $this->paths['appDir'] . '\settings.ini".'; + + Console::terminate($message, 1); + } + + $this->paths['xamppDir'] = $xamppDir; + + if (! $apacheDir) { + $apacheDir = $xamppDir . '\apache'; + } + + if (! is_file($apacheDir . '\bin\httpd.exe')) { + Console::breakline(); + + $message = 'Cannot find Apache directory.' . PHP_EOL; + $message .= 'Please check the configuration path to the Apache directory in file "' . $this->paths['appDir'] . '\settings.ini".'; + + Console::terminate($message, 1); + } + + $this->paths['apacheDir'] = $apacheDir; + + return $this->loadAdditionalPaths(); + } + + protected function loadAdditionalPaths() + { + if (! array_key_exists('apacheDir', $this->paths)) { + Console::breakline(); + Console::terminate('The identification of the path to Apache directory has not yet been conducted', 1); + } + + $this->paths['vhostCertDir'] = $this->paths['apacheDir'] . '\conf\extra\certs'; + $this->paths['vhostCertKeyDir'] = $this->paths['apacheDir'] . '\conf\extra\keys'; + $this->paths['vhostConfigDir'] = $this->paths['apacheDir'] . '\conf\extra\vhosts'; + $this->paths['vhostSSLConfigDir'] = $this->paths['apacheDir'] . '\conf\extra\vhosts_ssl'; + $this->paths['opensslBin'] = $this->paths['apacheDir'] . '\bin\openssl.exe'; + + // Set environment variables + putenv('XVHM_VHOST_CERT_DIR=' . $this->paths['vhostCertDir']); + putenv('XVHM_VHOST_CERT_KEY_DIR=' . $this->paths['vhostCertKeyDir']); + + putenv('XVHM_OPENSSL_BIN=' . $this->paths['opensslBin']); + putenv('XVHM_OPENSSL_SUBJECT_CN=Xampp Certificate Authority'); + putenv('XVHM_OPENSSL_SUBJECT_O=OpenSSL Software Foundation'); + putenv('XVHM_OPENSSL_SUBJECT_OU=Server Certificate Provider'); + + return $this; + } + + protected function reduceApachePath($path, $directorySeparator = DS) + { + $apachePath = str_replace('/', DS, $this->paths['apacheDir']); + $path = str_replace('/', DS, $path); + + if (substr($path, 0, strlen($apachePath)) == $apachePath) { + $path = substr($path, strlen($apachePath . DS)); + } + + return str_replace(DS, $directorySeparator, $path); + } + + protected function powerExec($command, $arguments = null, &$outputValue = null, &$returnCode = null) + { + if (is_file($this->paths['powerExecutor'])) { + if (is_array($arguments)) { + $arguments = '"' . trim(implode('" "', $arguments)) . '"'; + } elseif (is_string($arguments)) { + $arguments = trim($arguments); + } else { + $arguments = trim(strval($arguments)); + } + + return exec('cscript //NoLogo "' . $this->paths['powerExecutor'] . '" ' . $arguments . ' ' . $command, $outputValue, $returnCode); + } + + $message = 'Cannot find the "' . $this->paths['powerExecutor'] . '" implementer.'; + $outputValue = array($message); + $returnCode = 1; + + return $message; + } +} diff --git a/support/Console.php b/support/Console.php index e0a75d8..b400a54 100644 --- a/support/Console.php +++ b/support/Console.php @@ -20,9 +20,9 @@ public static function ask($message, $defaultValue = null) return self::getSimpleConsole()->askInput($message, $defaultValue); } - public static function line($message = null, $breakLine = true) + public static function line($message = null, $breakLine = true, $beginAtColumn = 0) { - self::getSimpleConsole()->showMessage($message, $breakLine); + self::getSimpleConsole()->showMessage($message, $breakLine, $beginAtColumn); } public static function breakline($multiplier = 1) @@ -35,9 +35,9 @@ public static function hrline($width = 83, $symbol = '-') self::getSimpleConsole()->showMessage(str_repeat($symbol, $width)); } - public static function terminate($message = null) + public static function terminate($message = null, $exitStatus = 0) { - self::getSimpleConsole()->terminate($message); + self::getSimpleConsole()->terminate($message, $exitStatus); } private static function getSimpleConsole() @@ -97,23 +97,25 @@ public function askInput($message, $defaultValue = null) return $answer; } - public function showMessage($message = null, $breakLine = true) + public function showMessage($message = null, $breakLine = true, $beginAtColumn = 0) { - echo $message; + $spaceBefore = ($beginAtColumn > 0) ? str_repeat(' ', $beginAtColumn) : ''; + + echo $spaceBefore . $message; if ($breakLine) { echo PHP_EOL; } } - public function terminate($message = null) + public function terminate($message = null, $exitStatus = 0) { if (! is_null($message)) { $message .= PHP_EOL; } $this->showMessage($message . $this->defaultMessages['terminate']); - exit; + exit($exitStatus); } private function getInputFromKeyboard($defaultValue = null) diff --git a/support/Installer.php b/support/Installer.php index a5c6d49..bbcfe6a 100644 --- a/support/Installer.php +++ b/support/Installer.php @@ -2,27 +2,24 @@ define('DS', DIRECTORY_SEPARATOR); -require_once __DIR__.'/Console.php'; -require_once __DIR__.'/Setting.php'; +require_once __DIR__.'/Application.php'; -class Installer +class Installer extends Application { - protected $settings = null; - public function __construct() { - Console::setDefaultMessages(array('terminate' => 'The installation is cancelling...')); - $this->settings = new Setting; - } + parent::__construct(false); - public function startInstall() - { - if (is_file($_ENV['XVHM_APP_DIR'] . '\settings.ini')) { + if (is_file($this->paths['appDir'] . '\settings.ini') && is_file($this->paths['caCertDir'] . '\cacert.crt')) { + Console::breakline(); Console::line('Xampp vHosts Manager is already integrated into Xampp.'); Console::line('No need to do it again.'); - return; + exit; } + } + public function install() + { Console::line('Welcome to Xampp vHosts Manager installer.'); Console::line('This installer will perform following tasks:'); Console::breakline(); @@ -31,126 +28,126 @@ public function startInstall() Console::line('2. Grant the necessary permissions to Windows hosts file so it can be edited from this utility.'); Console::line('3. Improve Apache\'s "httpd-vhosts.conf" file to include vhost config files later.'); Console::line('4. Improve Apache\'s "httpd-ssl.conf" file to include vhost SSL config files later.'); - Console::line('5. Register application\'s path to system environment, so you can call it anywhere later.'); + Console::line('5. Register path into Windows Path Environment Variable, so you can call it anywhere later.'); Console::breakline(); $continue = Console::confirm('Do you agree to continue?'); if (! $continue) { - Console::terminate(); + Console::terminate(null, 1); } Console::breakline(); + $this->askInstallConfig(); + + Console::hrline(); + Console::line('Start intergrating Xampp vHosts Manager into your Xampp.'); + Console::breakline(); + + $this->registerCA(); + $this->grantPermsToWinHostsFile(); + $this->improveHttpdVhostsConfFile(); + $this->improveHttpdSslConfFile(); + $this->registerPath(); + + Console::breakline(); + Console::hrline(); + Console::line('Configure some more settings (option step).'); + + $this->askMoreConfig(); + + Console::breakline(); + Console::hrline(); + Console::line('XAMPP VHOSTS MANAGER WAS INSTALLED SUCCESSFULLY.'); + Console::line('TO START USING IT, PLEASE EXIT YOUR TERMINAL TO'); + Console::line('DELETE TEMPORARY PROCESS ENVIRONMENT VARIABLES.'); } private function askInstallConfig() { - $phpDir = $_ENV['XVHM_PHP_DIR']; + $phpDir = $this->paths['phpDir']; Console::line('First, provide the path to your Xampp directory for Xampp vHosts Manager.'); if (is_file($phpDir . '\..\xampp-control.exe')) { $detectedXamppDir = realpath($phpDir . '\..\\'); - Console::line('Xampp vHosts Manager has detected that directory "' . $detectedXamppDir . '" could be your Xampp directory.'); + Console::line('Xampp vHosts Manager has detected that directory "' . strtoupper($detectedXamppDir) . '" could be your Xampp directory.'); Console::breakline(); - $confirmXamppDir = Console::confirm('>>> Is that the actual path to your Xampp directory?'); + $confirmXamppDir = Console::confirm('Is that the actual path to your Xampp directory?'); Console::breakline(); } $xamppDir = (isset($detectedXamppDir) && $confirmXamppDir) ? $detectedXamppDir : $this->tryGetXamppDir(); - $this->settings->set('DirectoryPaths', 'Xampp', $xamppDir); + $this->setting->set('DirectoryPaths', 'Xampp', $xamppDir); + $this->paths['xamppDir'] = $xamppDir; - if (! is_file($xamppDir . '\apache\bin\httpd.exe')) { + if (is_file($xamppDir . '\apache\bin\httpd.exe')) { + $this->paths['apacheDir'] = $xamppDir . '\apache'; + } else { Console::line('Next, because Xampp vHosts Manager does not detect the path to the Apache directory, you need to provide it manually.'); Console::breakline(); $apacheDir = $this->tryGetApacheDir(); - $this->settings->set('DirectoryPaths', 'Apache', $apacheDir); - + $this->setting->set('DirectoryPaths', 'Apache', $apacheDir); + $this->paths['apacheDir'] = $apacheDir; } - if (! $this->settings->save()) { + if (! $this->setting->save()) { Console::breakline(); - $this->terminate('The installation process was interrupted.'); + Console::line('Installation settings cannot be saved.'); + Console::terminate('Cancel the installation.', 1); } - @file_put_contents($_ENV['XVHM_TMP_DIR'] . '\.installing', ''); - } - - public function continueInstall() - { - if (! is_file($_ENV['XVHM_TMP_DIR'] . '\.installing')) { - Console::breakline(); - Console::line('The installation process was interrupted.'); - Console::line('Please delete file "settings.ini" and try from the beginning.'); - Console::terminate(); - } - - Console::hrline(); - Console::line('Start intergrating Xampp vHosts Manager into your Xampp.'); - Console::breakline(); - - $this->registerCA(); - $this->grantPermsToWinHostsFile(); - $this->improveHttpdVhostsConfFile(); - $this->improveHttpdSslConfFile(); - $this->registerPath(); - @unlink($_ENV['XVHM_TMP_DIR'] . '\.installing'); - - Console::breakline(); - Console::hrline(); - Console::line('Configure some more settings (option step).'); - $this->askMoreConfig(); - - Console::breakline(); - Console::hrline(); - Console::line('Finish installing.'); + $this->setting->reloadSettings(); + $this->loadAdditionalPaths(); } private function registerCA() { - $message = 'Registering Trusted CA with name "' .$_ENV['XVHM_OPENSSL_SUBJECT_CN']. '"...'; + $message = 'Registering Trusted CA with name "' . getenv('XVHM_OPENSSL_SUBJECT_CN') . '"...'; Console::line($message, false); - $callPowerExec = 'cscript //NoLogo "' . $_ENV['XVHM_POWER_EXECUTOR'] . '"'; - exec($callPowerExec . ' -w -i "' . $_ENV['XVHM_CACERT_GENERATE_SCRIPT'] . '"'); - - if (is_file($_ENV['XVHM_CACERT_DIR'] . '\cacert.crt')) { - $installCacertLogFile = $_ENV['XVHM_TMP_DIR'] . '\install-cacert.log'; - exec($callPowerExec . ' -w -e -i CERTUTIL -addstore -enterprise -f -v Root "' . $_ENV['XVHM_CACERT_DIR'] . '\cacert.crt" ">' . $installCacertLogFile . '"'); + $this->powerExec('"' . $this->paths['caCertGenScript'] . '"', '-w -i -n'); - $logContent = trim(file_get_contents($installCacertLogFile)); - $logRows = explode(PHP_EOL, $logContent); - @unlink($installCacertLogFile); + if (is_file($this->paths['caCertDir'] . '\cacert.crt')) { + $this->powerExec('CERTUTIL -addstore -enterprise -f -v Root "' . $this->paths['caCertDir'] . '\cacert.crt"', '-w -e -i -n', $outputVal, $exitCode); - if (end($logRows) == 'CertUtil: -addstore command completed successfully.') { - Console::line(str_repeat(' ', max(73 - strlen($message), 1)) . 'Successful'); + if ($exitCode == 0) { + Console::line('Successful', true, max(73 - strlen($message), 1)); return true; } } // If generating failed - Console::line(str_repeat(' ', max(77 - strlen($message), 1)) . 'Failed'); + Console::line('Failed', true, max(77 - strlen($message), 1)); - $files = glob($_ENV['XVHM_CACERT_DIR'] .DS. '*'); // get all file names + $files = glob($this->paths['caCertDir'] .DS. '*'); // get all file names foreach ($files as $file) { if (is_file($file)) { @unlink($file); } } - Console::terminate(); + Console::terminate('Cancel the installation.', 1); } private function grantPermsToWinHostsFile() { - $message = 'Granting permissions to Windows host file...'; + $message = 'Granting necessary permissions to Windows host file...'; Console::line($message, false); - $winHostsFile = realpath($_SERVER['SystemRoot'] . '\System32\drivers\etc\hosts'); - exec('cscript //NoLogo "' .$_ENV['XVHM_POWER_EXECUTOR']. '" -w -i -e icacls "' . $winHostsFile . '" /grant Users:MRXRW'); + $this->powerExec('icacls "' . $this->paths['winHostsFile'] . '" /grant Users:MRXRW', '-w -i -e -n', $outputVal, $exitCode); + + if ($exitCode == 0) { + Console::line('Successful', true, max(73 - strlen($message), 1)); + return true; + } - Console::line(str_repeat(' ', max(73 - strlen($message), 1)) . 'Successful'); + Console::line('Failed', true, max(77 - strlen($message), 1)); + Console::breakline(); + Console::line('You need set the Modify and Write permissions for group Users...'); + Console::line('to Windows hosts file manually after installation.'); + return false; } private function improveHttpdVhostsConfFile() @@ -158,30 +155,32 @@ private function improveHttpdVhostsConfFile() $message = 'Backing up and improve Apache\'s "httpd-vhosts.conf" file...'; Console::line($message, false); - $backupDir = $_ENV['XVHM_APACHE_DIR'] . '\conf\extra\backup'; + $backupDir = $this->paths['apacheDir'] . '\conf\extra\backup'; if (! is_dir($backupDir)) { mkdir($backupDir, 0755, true); } // Backup httpd-vhosts.conf - $httpd_vhosts_conf = $_ENV['XVHM_APACHE_DIR'] . '\conf\extra\httpd-vhosts.conf'; + $httpd_vhosts_conf = $this->paths['apacheDir'] . '\conf\extra\httpd-vhosts.conf'; copy($httpd_vhosts_conf, $backupDir . '\httpd-vhosts.conf'); // Improve httpd-vhosts.conf - $configLine = 'IncludeOptional "' . $this->reduceApachePath($_ENV['XVHM_VHOST_CONFIG_DIR'], '/') . '/*.conf"'; + $configLine = 'IncludeOptional "' . $this->reduceApachePath($this->paths['vhostConfigDir'], '/') . '/*.conf"'; $httpd_vhosts_append = PHP_EOL . '# Include all virtual host config files'; $httpd_vhosts_append .= PHP_EOL . $configLine . PHP_EOL; $httpd_vhosts_updated = file_put_contents($httpd_vhosts_conf, $httpd_vhosts_append, FILE_APPEND); if ($httpd_vhosts_updated) { - Console::line(str_repeat(' ', max(73 - strlen($message), 1)) . 'Successful'); - } else { - Console::line(str_repeat(' ', max(77 - strlen($message), 1)) . 'Failed'); - Console::breakline(); - Console::line('You need to add the following line to the "' .$httpd_vhosts_conf. '" file manually:'); - Console::line($configLine); - Console::breakline(); + Console::line('Successful', true, max(73 - strlen($message), 1)); + return true; } + + Console::line('Failed', true, max(77 - strlen($message), 1)); + Console::breakline(); + Console::line('You need to add the following lines to the "' .$httpd_vhosts_conf. '" file manually after installation:'); + Console::line($configLine); + Console::breakline(); + return false; } private function improveHttpdSslConfFile() @@ -189,83 +188,103 @@ private function improveHttpdSslConfFile() $message = 'Backing up and improve Apache\'s "httpd-ssl.conf" file...'; Console::line($message, false); - $backupDir = $_ENV['XVHM_APACHE_DIR'] . '\conf\extra\backup'; + $backupDir = $this->paths['apacheDir'] . '\conf\extra\backup'; if (! is_dir($backupDir)) { mkdir($backupDir, 0755, true); } // Backup httpd-ssl.conf - $httpd_ssl_conf = $_ENV['XVHM_APACHE_DIR'] . '\conf\extra\httpd-ssl.conf'; + $httpd_ssl_conf = $this->paths['apacheDir'] . '\conf\extra\httpd-ssl.conf'; copy($httpd_ssl_conf, $backupDir . '\httpd-ssl.conf'); // Improve httpd-ssl.conf - $configLine = 'IncludeOptional "' . $this->reduceApachePath($_ENV['XVHM_VHOST_SSL_CONFIG_DIR'], '/') . '/*.conf"'; + $configLine = 'IncludeOptional "' . $this->reduceApachePath($this->paths['vhostSSLConfigDir'], '/') . '/*.conf"'; $httpd_ssl_append = PHP_EOL . '# Include all virtual host ssl config files'; $httpd_ssl_append .= PHP_EOL . $configLine . PHP_EOL; $httpd_ssl_updated = file_put_contents($httpd_ssl_conf, $httpd_ssl_append, FILE_APPEND); if ($httpd_ssl_updated) { - Console::line(str_repeat(' ', max(73 - strlen($message), 1)) . 'Successful'); - } else { - Console::line(str_repeat(' ', max(77 - strlen($message), 1)) . 'Failed'); - Console::breakline(); - Console::line('You need to add the following line to the "' .$httpd_ssl_conf. '" file manually:'); - Console::line($configLine); - Console::breakline(); + Console::line('Successful', true, max(73 - strlen($message), 1)); + return true; } + + Console::line('Failed', true, max(77 - strlen($message), 1)); + Console::breakline(); + Console::line('You need to add the following lines to the "' .$httpd_ssl_conf. '" file manually after installation:'); + Console::line($configLine); + Console::breakline(); + return false; } private function registerPath() { - $message = 'Registering application\'s path to system environment...'; + $message = 'Registering application\'s path into Windows Path Environment Variable...'; Console::line($message, false); - exec('cscript //NoLogo "' . $_ENV['XVHM_APPPATH_REGISTER'] . '"'); - Console::line(str_repeat(' ', max(73 - strlen($message), 1)) . 'Successful'); + + $this->powerExec('cscript "' . $this->paths['pathRegister'] . '" "' .$this->paths['appDir']. '"', '-w -i -e -n', $outputVal, $exitCode); + + if ($exitCode == 0) { + Console::line('Successful', true, max(73 - strlen($message), 1)); + return true; + } else { + Console::line('Failed', true, max(77 - strlen($message), 1)); + Console::breakline(); + Console::line('Don\'t worry. This does not affect the installation process.'); + Console::line('You can register the path manually...'); + Console::line('or use the "xvhosts register_path" command after installation.'); + return false; + } } private function askMoreConfig() { Console::breakline(); Console::line('At this point, the installation process is complete.'); - Console::line('However, for Xampp vHosts Manager to work more perfectly, you should configure some more settings.'); - Console::line('You can skip this step and configure the following via the "settings.ini" file.'); + Console::line('However, for Xampp vHosts Manager to work more perfectly'); + Console::line('you should configure some more settings. You can skip this'); + Console::line('step and configure the following via the "settings.ini" file.'); Console::breakline(); - $configNow = Console::confirm('>>> Would you like to do that now?'); + $configNow = Console::confirm('Would you like to do that now?'); if ($configNow) { Console::breakline(); - Console::line('The first setting ---'); + Console::line('[+] The first setting ---'); Console::line('Provide the path to directory used to propose as Document Root each vhost creation process.'); Console::line('Note*: You can use the string {{host_name}} as the virtual host name placeholder.'); Console::breakline(); - $docRootSuggestion = Console::ask('>>> Enter document root path suggestion', $_ENV['XVHM_XAMPP_DIR'] . '\htdocs\{{host_name}}'); - $this->settings->set('Suggestions', 'DocumentRoot', str_replace('/', DS, $docRootSuggestion)); + + $docRootSuggestion = Console::ask('Enter document root path suggestion', $this->paths['xamppDir'] . '\htdocs\{{host_name}}'); + $this->setting->set('Suggestions', 'DocumentRoot', str_replace('/', DS, $docRootSuggestion)); Console::breakline(); - Console::line('The second setting ---'); + Console::line('[+] The second setting ---'); Console::line('Provide the email used to propose as Admin Email each vhost creation process.'); Console::breakline(); - $adminEmailSuggestion = Console::ask('>>> Enter admin email suggestion', 'webmaster@example.com'); - $this->settings->set('Suggestions', 'AdminEmail', $adminEmailSuggestion); + + $adminEmailSuggestion = Console::ask('Enter admin email suggestion', 'webmaster@example.com'); + $this->setting->set('Suggestions', 'AdminEmail', $adminEmailSuggestion); Console::breakline(); - Console::line('The third setting ---'); - Console::line('You want to show how many records per page when listing the existing virtual hosts.'); + Console::line('[+] The third setting ---'); + Console::line('Provide the number of records per page when listing the existing virtual hosts.'); Console::breakline(); - $recordPerPage = Console::ask('>>> Enter the virtual hosts record per page', 2); - $this->settings->set('ListViewMode', 'RecordPerPage', $recordPerPage); + + $recordPerPage = Console::ask('Enter the virtual hosts record per page', 2); + $this->setting->set('ListViewMode', 'RecordPerPage', $recordPerPage); Console::breakline(); $message = 'Saving settings to the "settings.ini" file...'; Console::line($message, false); - if ($this->settings->save()) { - Console::line(str_repeat(' ', max(73 - strlen($message), 1)) . 'Successful'); - } else { - Console::line(str_repeat(' ', max(77 - strlen($message), 1)) . 'Failed'); - Console::breakline(); - Console::line('You have to set settings through the "settings.ini" file manually.'); + if ($this->setting->save()) { + Console::line('Successful', true, max(73 - strlen($message), 1)); + return true; } + + Console::line('Failed', true, max(77 - strlen($message), 1)); + Console::breakline(); + Console::line('You have to set settings through the "settings.ini" file manually.'); + return false; } } @@ -274,16 +293,17 @@ private function tryGetXamppDir() $xamppDir = ''; $repeat = 0; - while (! is_file(rtrim($xamppDir, '\\') . '\xampp-control.exe')) { + while (! is_file(rtrim($xamppDir, '\\/') . '\xampp-control.exe')) { if ($repeat == 4) { - Console::terminate('You have not provided correct information multiple times.'); + Console::line('You have not provided correct information multiple times.'); + Console::terminate('Cancel the installation.', 1); } if ($repeat == 0) { - $xamppDir = Console::ask('>>> Enter the path to your Xampp directory'); + $xamppDir = Console::ask('Enter the path to your Xampp directory'); } else { Console::line('The path provided is not the path to the actual Xampp directory.'); - $xamppDir = Console::ask('>>> Please provide it again'); + $xamppDir = Console::ask('Please provide it again'); } Console::breakline(); @@ -301,14 +321,15 @@ private function tryGetApacheDir() $repeat = 0; while (! is_file(rtrim($apacheDir, '\\') . '\bin\httpd.exe')) { if ($repeat == 4) { - Console::terminate('You have not provided correct information multiple times.'); + Console::line('You have not provided correct information multiple times.'); + Console::terminate('Cancel the installation.', 1); } if ($repeat == 0) { - $apacheDir = Console::ask('>>> Enter the path to your Apache directory'); + $apacheDir = Console::ask('Enter the path to your Apache directory'); } else { Console::line('The path provided is not the path to the actual Apache directory.'); - $apacheDir = Console::ask('>>> Please provide it again'); + $apacheDir = Console::ask('Please provide it again'); } Console::breakline(); @@ -318,16 +339,4 @@ private function tryGetApacheDir() return $apacheDir; } - - private function reduceApachePath($path, $directorySeparator = DS) - { - $apachePath = str_replace('/', DS, $_ENV['XVHM_APACHE_DIR']); - $path = str_replace('/', DS, $path); - - if (substr($path, 0, strlen($apachePath)) == $apachePath) { - $path = substr($path, strlen($apachePath . DS)); - } - - return str_replace(DS, $directorySeparator, $path); - } } diff --git a/support/Manager.php b/support/Manager.php index 55484d3..a349234 100644 --- a/support/Manager.php +++ b/support/Manager.php @@ -2,41 +2,27 @@ define('DS', DIRECTORY_SEPARATOR); -require_once __DIR__.'/Console.php'; -require_once __DIR__.'/Setting.php'; +require_once __DIR__.'/Application.php'; -class Manager +class Manager extends Application { - protected $settings = null; - protected $paths = array(); - protected $vhosts = array(); + protected $vhosts = array(); public function __construct() { - Console::setDefaultMessages(array('terminate' => 'Xampp vHosts Manager is terminating...')); + if (! is_file(getenv('XVHM_APP_DIR') . '\settings.ini')) { + $this->requireInstall(); + } - $this->loadPaths(); - $this->loadSettings(); - $this->loadAllHosts(); - } + parent::__construct(); - private function loadPaths() - { - // Dir paths - $this->paths['appDir'] = realpath($_ENV['XVHM_APP_DIR']); - $this->paths['xamppDir'] = realpath($_ENV['XVHM_XAMPP_DIR']); - $this->paths['apacheDir'] = realpath($_ENV['XVHM_APACHE_DIR']); - $this->paths['vhostConfigDir'] = $this->prepareVhostConfigDir(); - $this->paths['vhostSSLConfigDir'] = $this->prepareVhostSSLConfigDir(); - $this->paths['vhostCertDir'] = $this->prepareVhostCertDir(); - $this->paths['vhostCertKeyDir'] = $this->prepareVhostCertKeyDir(); - - // File paths - $this->paths['winHostsFile'] = realpath($_SERVER['SystemRoot'] . '\System32\drivers\etc\hosts'); - $this->paths['vhostConfigTemplate'] = $_ENV['XVHM_VHOST_CONFIG_TEMPLATE']; - $this->paths['vhostSSLConfigTemplate'] = $_ENV['XVHM_VHOST_SSL_CONFIG_TEMPLATE']; - $this->paths['vhostCertGenerateScript'] = $_ENV['XVHM_VHOST_CERT_GENERATE_SCRIPT']; - $this->paths['powerExecutor'] = $_ENV['XVHM_POWER_EXECUTOR']; + if (! is_file($this->paths['caCertDir'] . '\cacert.crt')) { + $this->requireInstall(); + } + + $this->prepareDirectories(); + $this->loadApacheSettings(); + $this->loadAllHosts(); } public function showHostInfo($hostName = null, $processStandalone = true, $indentSpaces = 2) @@ -71,6 +57,20 @@ public function showHostInfo($hostName = null, $processStandalone = true, $inden Console::line($indentString . '- SSL certificate file : ' . $hostInfo['certFile']); Console::line($indentString . '- SSL private key file : ' . $hostInfo['certKeyFile']); } + + if ($processStandalone) { + Console::breakline(); + Console::hrline(); + $showMore = Console::confirm('Do you want to show information of another virtual host?'); + + if ($showMore) { + Console::breakline(); + $this->showHostInfo(); + } + + Console::breakline(); + Console::terminate('All jobs are completed.'); + } } public function listHosts() @@ -107,6 +107,10 @@ public function listHosts() } } } + + Console::breakline(); + Console::hrline(); + Console::terminate('Your request is completed.'); } public function removeHost($hostName = null) @@ -153,10 +157,21 @@ public function removeHost($hostName = null) unset($this->vhosts[$hostName]); - // Ask restart Apache + // Ask to remove another Console::breakline(); Console::hrline(); + $removeMore = Console::confirm('Do you want to remove another virtual host?'); + + if ($removeMore) { + Console::breakline(); + $this->removeHost(); + } + + // Ask restart Apache $this->askRestartApache(); + + Console::breakline(); + Console::terminate('All jobs are completed.'); } public function addSSLtoHost($hostName = null, $processStandalone = true) @@ -188,7 +203,7 @@ public function addSSLtoHost($hostName = null, $processStandalone = true) if (! $createdCertAndKey) { if ($processStandalone) { Console::breakline(); - Console::terminate('Error while create SSL certificate files'); + Console::terminate('Error while create SSL certificate files', 1); } else { Console::line('Cancelling adding SSL for this host...'); return; @@ -201,7 +216,7 @@ public function addSSLtoHost($hostName = null, $processStandalone = true) if (is_null($sslConfigFile)) { if ($processStandalone) { Console::breakline(); - Console::terminate('Error while create SSL config file'); + Console::terminate('Error while create SSL config file', 1); } else { Console::line('Cancelling adding SSL for this host...'); return; @@ -217,19 +232,29 @@ public function addSSLtoHost($hostName = null, $processStandalone = true) if ($processStandalone) { // Show recent host info Console::breakline(); - Console::hrline(); Console::line('The following is information about the virtual host that just updated:'); Console::breakline(); $this->showHostInfo($hostName, false); - // Ask restart Apache + // Ask to add SSL for another Console::breakline(); Console::hrline(); + $addMore = Console::confirm('Do you want to add SSL for another virtual host?'); + + if ($addMore) { + Console::breakline(); + $this->addSSLtoHost(); + } + + // Ask restart Apache $this->askRestartApache(); + + Console::breakline(); + Console::terminate('All jobs are completed.'); } } - public function removeSSLOfHost($hostName) + public function removeSSLOfHost($hostName = null) { $hostName = $this->tryGetHostName($hostName); @@ -272,15 +297,25 @@ public function removeSSLOfHost($hostName) // Show recent host info Console::breakline(); - Console::hrline(); Console::line('The following is information about the virtual host that just updated:'); Console::breakline(); $this->showHostInfo($hostName, false); - // Ask restart Apache + // Ask to remove SSL for another Console::breakline(); Console::hrline(); + $removeMore = Console::confirm('Do you want to remove SSL for another virtual host?'); + + if ($removeMore) { + Console::breakline(); + $this->removeSSLOfHost(); + } + + // Ask restart Apache $this->askRestartApache(); + + Console::breakline(); + Console::terminate('All jobs are completed.'); } public function newHost($hostName = null) @@ -314,7 +349,7 @@ public function newHost($hostName = null) if (! $createdDocumentRoot) { Console::breakline(); - Console::terminate('Error while creating document root.'); + Console::terminate('Error while creating document root.', 1); } } @@ -323,7 +358,7 @@ public function newHost($hostName = null) if (is_null($vhostConfigFile)) { Console::breakline(); - Console::terminate('Error while create host config file'); + Console::terminate('Error while create host config file', 1); } // Update vhosts info @@ -348,108 +383,155 @@ public function newHost($hostName = null) // Show recent host info Console::breakline(); - Console::hrline(); Console::line('The following is information about the virtual host that just created:'); Console::breakline(); $this->showHostInfo($serverName, false); - // Ask restart Apache + // Ask to create more Console::breakline(); Console::hrline(); + $createMore = Console::confirm('Do you want to create another virtual host?'); + + if ($createMore) { + Console::breakline(); + $this->newHost(); + } + + // Ask restart Apache $this->askRestartApache(); + + Console::breakline(); + Console::terminate('All jobs are completed.'); } public function askRestartApache($question = null) { - $question = $question ?: 'Do you want to restart Apache?'; - $restartApache = Console::confirm($question); + $question = $question ?: 'Do you want to restart Apache?'; + $confirm = Console::confirm($question); - if ($restartApache) { + if ($confirm) { Console::breakline(); - Console::line('Stopping Apache Httpd...'); - exec('cscript //NoLogo "' . $this->paths['powerExecutor'] . '" -w -i -n "' . $this->paths['xamppDir'] . '\apache_stop.bat"'); - - Console::line('Starting Apache Httpd...'); - exec('cscript //NoLogo "' . $this->paths['powerExecutor'] . '" -i -n "' . $this->paths['xamppDir'] . '\apache_start.bat"'); + $this->stopApache(false); + $this->startApache(false); } } - private function prepareVhostConfigDir() + public function stopApache($askConfirm = true) { - $vhostsConfigDir = $_ENV['XVHM_VHOST_CONFIG_DIR']; - - if (! is_dir($vhostsConfigDir)) { - mkdir($vhostsConfigDir, 0755, true); + if ($askConfirm) { + $confirm = Console::confirm('Are you sure you want to stop Apache?'); + } else { + $confirm = true; } - return realpath($vhostsConfigDir); + if ($confirm) { + if ($askConfirm) { + Console::breakline(); + } + + Console::line('Stopping Apache Httpd...'); + $this->powerExec('"' . $this->paths['xamppDir'] . '\apache_stop.bat"', '-w -i -n'); + } } - private function prepareVhostSSLConfigDir() + public function startApache($askConfirm = true) { - $vhostsSSLConfigDir = $_ENV['XVHM_VHOST_SSL_CONFIG_DIR']; - - if (! is_dir($vhostsSSLConfigDir)) { - mkdir($vhostsSSLConfigDir, 0755, true); + if ($askConfirm) { + $confirm = Console::confirm('Are you sure you want to start Apache?'); + } else { + $confirm = true; } - return realpath($vhostsSSLConfigDir); + if ($confirm) { + if ($askConfirm) { + Console::breakline(); + } + + Console::line('Starting Apache Httpd...'); + $this->powerExec('"' . $this->paths['xamppDir'] . '\apache_start.bat"', '-i -n'); + } } - private function prepareVhostCertDir() + public function registerPath() { - $vhostsCertDir = $_ENV['XVHM_VHOST_CERT_DIR']; + $question = 'Do you want to change the path of XVHM to "' . $this->paths['appDir'] . '"?'; + $confirm = Console::confirm($question); + + if ($confirm) { + $message = 'Registering new path into Windows Path Environment Variable...'; + Console::breakline(); + Console::line($message, false); + + $this->powerExec('cscript "' . $this->paths['pathRegister'] . '" "' .$this->paths['appDir']. '"', '-w -i -e -n', $outputVal, $exitCode); + + if ($exitCode == 0) { + Console::line('Successful', true, max(73 - strlen($message), 1)); + Console::terminate(); + } - if (! is_dir($vhostsCertDir)) { - mkdir($vhostsCertDir, 0755, true); + Console::line('Failed', true, max(77 - strlen($message), 1)); + Console::terminate(null, 1); } + } - return realpath($vhostsCertDir); + private function requireInstall() + { + Console::breakline(); + Console::line('Xampp vHosts Manager has not been integrated into Xampp.'); + Console::line('Run command "xvhosts install" in Administartor mode to integrate it.'); + Console::terminate(null, 1); } - private function prepareVhostCertKeyDir() + private function prepareDirectories() { - $vhostsCertKeyDir = $_ENV['XVHM_VHOST_CERT_KEY_DIR']; + if (! is_dir($this->paths['vhostConfigDir'])) { + mkdir($this->paths['vhostConfigDir'], 0755, true); + } - if (! is_dir($vhostsCertKeyDir)) { - mkdir($vhostsCertKeyDir, 0755, true); + if (! is_dir($this->paths['vhostSSLConfigDir'])) { + mkdir($this->paths['vhostSSLConfigDir'], 0755, true); } - return realpath($vhostsCertKeyDir); + if (! is_dir($this->paths['vhostCertDir'])) { + mkdir($this->paths['vhostCertDir'], 0755, true); + } + + if (! is_dir($this->paths['vhostCertKeyDir'])) { + mkdir($this->paths['vhostCertKeyDir'], 0755, true); + } } - private function reduceApachePath($path, $directorySeparator = DS) + private function normalizeDocumentRoot($documentRoot) { - $apachePath = str_replace('/', DS, $this->paths['apacheDir']); - $path = str_replace('/', DS, $path); + $documentRoot = trim($documentRoot, './\\'); + $documentRoot = str_replace('/', DS, $documentRoot); - if (substr($path, 0, strlen($apachePath)) == $apachePath) { - $path = substr($path, strlen($apachePath . DS)); + if (strpos($documentRoot, ':') !== false) { + return $documentRoot; } - return str_replace(DS, $directorySeparator, $path); + return $this->paths['xamppDir'] .DS. $documentRoot; } private function normalizeHostName($hostName) { $hostName = trim($hostName); $hostName = str_replace(' ', '', $hostName); - $hostName = str_replace('www.', '', $hostName); - return $hostName; - } + if (stripos($hostName, 'http://') === 0) { + $hostName = substr($hostName, 7); + } - private function normalizeDocumentRoot($documentRoot) - { - $documentRoot = trim($documentRoot, './\\'); - $documentRoot = str_replace('/', DS, $documentRoot); + if (stripos($hostName, 'https://') === 0) { + $hostName = substr($hostName, 8); + } - if (strpos($documentRoot, ':') !== false) { - return $documentRoot; + if (stripos($hostName, 'www.') === 0) { + $hostName = substr($hostName, 4); } - return $this->paths['xamppDir'] .DS. $documentRoot; + return $hostName; } private function tryGetHostName($hostName = null, $message = null) @@ -458,15 +540,15 @@ private function tryGetHostName($hostName = null, $message = null) $message = $message ?: 'Enter virtual host name'; $repeat = 0; - while (! $hostName) { + while (! $hostName || ! filter_var('http://' . $hostName, FILTER_VALIDATE_URL)) { if ($repeat == 4) { - Console::terminate('You have not provided enough information many times.'); + Console::terminate('You have entered an incorrect format many times.', 1); } if ($repeat == 0) { $hostName = Console::ask($message); } else { - Console::line('You have not provided enough information.'); + Console::line('You have entered an incorrect format.'); $hostName = Console::ask($message . ' again'); } @@ -630,7 +712,7 @@ private function loadAllHosts() closedir($handle); } - private function loadSettings() + private function loadApacheSettings() { $xampp_settings = parse_ini_file($this->paths['xamppDir'] . '\xampp-control.ini', true); @@ -646,16 +728,18 @@ private function loadSettings() $default_ssl_port = 443; } - $settings = new Setting; - $settings->set('Suggestions', 'HostPort', $default_port); - $settings->set('Suggestions', 'HostSSLPort', $default_ssl_port); + // $settingsContainer = new Setting; + // $settingsContainer->set('Suggestions', 'HostPort', $default_port); + // $settingsContainer->set('Suggestions', 'HostSSLPort', $default_ssl_port); - $this->settings = $settings; + // $this->setting = $settingsContainer; + $this->setting->set('Suggestions', 'HostPort', $default_port); + $this->setting->set('Suggestions', 'HostSSLPort', $default_ssl_port); } private function getSetting($sectionName, $settingName, $defaultValue = null) { - return $this->settings->get($sectionName, $settingName, $defaultValue); + return $this->setting->get($sectionName, $settingName, $defaultValue); } private function createDocumentRoot($dirPath) @@ -667,11 +751,11 @@ private function createDocumentRoot($dirPath) mkdir($dirPath, 0755, true); if (is_dir($dirPath)) { - Console::line(str_repeat(' ', max(73 - strlen($message), 1)) . 'Successful'); + Console::line('Successful', true, max(73 - strlen($message), 1)); return true; } - Console::line(str_repeat(' ', max(77 - strlen($message), 1)) . 'Failed'); + Console::line('Failed', true, max(77 - strlen($message), 1)); return false; } @@ -697,11 +781,11 @@ private function createHostConfigFile($hostName, $hostPort, $adminEmail, $docume $content = str_replace($search, $replace, file_get_contents($template)); if (file_put_contents($configFile, $content)) { - Console::line(str_repeat(' ', max(73 - strlen($message), 1)) . 'Successful'); + Console::line('Successful', true, max(73 - strlen($message), 1)); return realpath($configFile); } - Console::line(str_repeat(' ', max(77 - strlen($message), 1)) . 'Failed'); + Console::line('Failed', true, max(77 - strlen($message), 1)); return null; } @@ -731,11 +815,11 @@ private function createSSLConfigFile($hostName, $sslPort, $adminEmail, $document $content = str_replace($search, $replace, file_get_contents($template)); if (file_put_contents($configFile, $content)) { - Console::line(str_repeat(' ', max(73 - strlen($message), 1)) . 'Successful'); + Console::line('Successful', true, max(73 - strlen($message), 1)); return realpath($configFile); } - Console::line(str_repeat(' ', max(77 - strlen($message), 1)) . 'Failed'); + Console::line('Failed', true, max(77 - strlen($message), 1)); return null; } @@ -744,14 +828,14 @@ private function createCertKeyFile($hostName) $message = 'Generating the cert and private key files...'; Console::line($message, false); - exec('cscript //NoLogo "' . $this->paths['powerExecutor'] . '" -w -i "' . $this->paths['vhostCertGenerateScript'] . '" "' . $hostName . '"'); + $this->powerExec('"' . $this->paths['vhostCertGenScript'] . '" "' . $hostName . '"', '-w -i -n'); if (is_file($this->paths['vhostCertDir'] .DS. $hostName . '.cert') && is_file($this->paths['vhostCertKeyDir'] .DS. $hostName . '.key')) { - Console::line(str_repeat(' ', max(73 - strlen($message), 1)) . 'Successful'); + Console::line('Successful', true, max(73 - strlen($message), 1)); return true; } - Console::line(str_repeat(' ', max(77 - strlen($message), 1)) . 'Failed'); + Console::line('Failed', true, max(77 - strlen($message), 1)); return false; } @@ -782,13 +866,13 @@ private function addHostToWindowsHost($hostNames) $result = @file_put_contents($this->paths['winHostsFile'], $content, FILE_APPEND); if (! $result) { - Console::line(str_repeat(' ', max(77 - strlen($message), 1)) . 'Failed'); + Console::line('Failed', true, max(77 - strlen($message), 1)); return false; } } } - Console::line(str_repeat(' ', max(73 - strlen($message), 1)) . 'Successful'); + Console::line('Successful', true, max(73 - strlen($message), 1)); return true; } @@ -830,12 +914,12 @@ private function removeHostInWindowsHost($hostNames) $updated = @file_put_contents($this->paths['winHostsFile'], $content); if (! $updated) { - Console::line(str_repeat(' ', max(77 - strlen($message), 1)) . 'Failed'); + Console::line('Failed', true, max(73 - strlen($message), 1)); return false; } } - Console::line(str_repeat(' ', max(73 - strlen($message), 1)) . 'Successful'); + Console::line('Successful', true, max(73 - strlen($message), 1)); return true; } @@ -846,9 +930,9 @@ private function removeFile($filePath, $message = null) $removed = @unlink($filePath); if ($removed) { - Console::line(str_repeat(' ', max(73 - strlen($message), 1)) . 'Successful'); + Console::line('Successful', true, max(73 - strlen($message), 1)); } else { - Console::line(str_repeat(' ', max(77 - strlen($message), 1)) . 'Failed'); + Console::line('Failed', true, max(77 - strlen($message), 1)); } return $removed; diff --git a/support/PathRegister.vbs b/support/PathRegister.vbs new file mode 100644 index 0000000..bb59e54 --- /dev/null +++ b/support/PathRegister.vbs @@ -0,0 +1,78 @@ +Option Explicit + +' Define global variables +Dim objArgs: Set objArgs = WScript.Arguments +Dim objShell: Set objShell = CreateObject("WScript.Shell") +Dim objSystemEnv: Set objSystemEnv = objShell.Environment("SYSTEM") + +' Define subroutines +Private Sub ClearVars() + Set objSystemEnv = Nothing + Set objShell = Nothing + Set objArgs = Nothing +End Sub + +Private Sub WriteMsg(ByVal message, ByVal writeAs) + If (DetectScriptMode = "Window") Then + MsgBox message + Else + Select Case writeAs + Case "output" + WScript.StdOut.WriteLine message + Case "error" + WScript.StdErr.WriteLine message + Case "echo" + WScript.Echo message + End Select + End If +End Sub + +Private Sub Quit(errorCode) + ClearVars + WScript.Quit errorCode +End Sub + +' Define functions +Private Function DetectScriptMode() + Dim scriptMode + + If InStr(1, WScript.FullName, "cscript", vbTextCompare) Then + scriptMode = "Console" + ElseIf InStr(1, WScript.FullName, "wscript", vbTextCompare) Then + scriptMode = "Window" + Else + scriptMode = "Unknown" + End If + + DetectScriptMode = scriptMode +End Function + +' Check Elevated permission +Dim objExec: Set objExec = objShell.Exec("cmd /C ""FSUTIL dirty query %SystemDrive%>nul""") +Do While (objExec.Status = 0) + WScript.Sleep 50 +Loop +If (objExec.ExitCode = 1) Then + WriteMsg "This process can only be run with elevated permission.", "error" + WriteMsg "Please run this process in Administartor mode.", "error" + Set objExec = Nothing + Quit 1 +End If +Set objExec = Nothing + +' The path argument is missing +If (objArgs.Count <= 0) Then + WriteMsg "The ""path"" argument is missing.", "error" + Quit 1 +End If + +' Start process +Dim currentPaths: currentPaths = objSystemEnv("PATH") +Dim path: path = Trim(objArgs.item(0)) + +If (InStr(currentPaths, path & ";") = 0) and (InStr(currentPaths, ";" & path) = 0) Then + objSystemEnv("PATH") = path & ";" & currentPaths +End If + +WriteMsg "The path has been added into Windows Path Environment Variable", "output" +Quit 0 \ No newline at end of file diff --git a/support/PowerExec.vbs b/support/PowerExec.vbs index 83ae23a..bc07166 100644 --- a/support/PowerExec.vbs +++ b/support/PowerExec.vbs @@ -6,9 +6,14 @@ Dim objShell: Set objShell = CreateObject("WScript.Shell") Dim objFSO: Set objFSO = CreateObject("Scripting.FileSystemObject") Dim scriptBaseName: scriptBaseName = objFSO.GetBaseName(WScript.ScriptName) Dim scriptExt: scriptExt = LCase(objFSO.GetExtensionName(WScript.ScriptName)) -Dim noOutput: noOutput = false ' Define subroutines +Private Sub ClearVars() + Set objFSO = Nothing + Set objShell = Nothing + Set objArgs = Nothing +End Sub + Private Sub ShowHelp() Dim callMethod @@ -22,7 +27,7 @@ Private Sub ShowHelp() helpMsg = "" & _ vbNewLine & "Usage:" & _ - vbNewLine & " " & callMethod & " [-k] [-p] [-w] [-e] [(-m | -a)] [-i] [-n] [-h] " & _ + vbNewLine & " " & callMethod & " [-k] [-p] [-w] [-e] [(-m | -x)] [-i] [-n] [-h] " & _ vbNewLine & _ vbNewLine & "Options:" & _ vbNewLine & " -k Keep the command prompt window after execution; equivalent to ""cmd /k command""." & _ @@ -30,7 +35,7 @@ Private Sub ShowHelp() vbNewLine & " -w Wait until the execution is terminated and the execution window is closed." & _ vbNewLine & " -e Execute command with elevated permission (run as Administrator)." & _ vbNewLine & " -m Minimize command execution window (visible mode)." & _ - vbNewLine & " -a Maximize command execution window (visible mode)." & _ + vbNewLine & " -x Maximize command execution window (visible mode)." & _ vbNewLine & " -i Hide command execution window (invisible mode)." & _ vbNewLine & " -n Do not present " & scriptBaseName & "'s messages (error or success) except the help." & _ vbNewLine & " -h Display " & scriptBaseName & "'s help message." & _ @@ -47,21 +52,34 @@ Private Sub ShowHelp() WScript.Echo helpMsg End Sub -Private Sub ShowHelpWithMessage(ByVal message) +Private Sub ShowHelpWithMessage(ByVal message, ByVal showAs) If ((Not message = vbNullString) and (Not message = vbNull)) Then - WScript.Echo message + WriteMsg message, showAs End If ShowHelp End Sub Private Sub Quit(errorCode) - Set objFSO = Nothing - Set objShell = Nothing - Set objArgs = Nothing + ClearVars WScript.Quit errorCode End Sub +Private Sub WriteMsg(ByVal message, ByVal writeAs) + If (DetectScriptMode = "Window") Then + MsgBox message + Else + Select Case writeAs + Case "output" + WScript.StdOut.WriteLine message + Case "error" + WScript.StdErr.WriteLine message + Case "echo" + WScript.Echo message + End Select + End If +End Sub + ' Define functions Private Function ParseArguments(ByVal arguments) Dim isElevateOption: isElevateOption = true @@ -90,7 +108,7 @@ Private Function ParseArguments(ByVal arguments) If (isElevateOption) Then If (lcaseCurrArg = "/?" or lcaseCurrArg = "/h" or lcaseCurrArg = "/help" or lcaseCurrArg = "-h" or lcaseCurrArg = "--help") Then - ShowHelpWithMessage "Execute commands with more advanced controls." + ShowHelpWithMessage "Execute commands with more advanced controls.", "success" Quit 0 End If @@ -105,14 +123,14 @@ Private Function ParseArguments(ByVal arguments) objParams("Elevated") = true Case "m" If (Not objParams("WindowSize") = "Normal") Then - ShowHelpWithMessage scriptBaseName & " error: Cannot use the [-m] and [-a] parameters at the same time. Cancel the operation." + ShowHelpWithMessage scriptBaseName & " error: Cannot use the [-m] and [-a] parameters at the same time. Cancel the operation.", "error" Quit 1 End If objParams("WindowSize") = "Minimized" - Case "a" + Case "x" If (Not objParams("WindowSize") = "Normal") Then - ShowHelpWithMessage scriptBaseName & " error: Cannot use the [-m] and [-a] parameters at the same time. Cancel the operation." + ShowHelpWithMessage scriptBaseName & " error: Cannot use the [-m] and [-a] parameters at the same time. Cancel the operation.", "error" Quit 1 End If @@ -122,7 +140,7 @@ Private Function ParseArguments(ByVal arguments) Case "n" objParams("NoOutput") = true Case Else - ShowHelpWithMessage scriptBaseName & " error: Unknown argument """ & currentArg & """. Cancel the operation." + ShowHelpWithMessage scriptBaseName & " error: Unknown argument """ & currentArg & """. Cancel the operation.", "error" Quit 1 End Select Else @@ -192,123 +210,125 @@ Private Function RandomString() RandomString = TempCopy End Function -' Main program +'''''''''''''''' START MAIN PROGRAM '''''''''''''''' + +' Notice if runnig in Window mode If (DetectScriptMode() = "Window") Then - WScript.Echo "Sorry! This application only runs in console mode." & vbNewLine & _ + MsgBox "Sorry! This application only runs in console mode." & vbNewLine & _ "Please run this application with the ""cscript"" command." Quit 1 End If -If (objArgs.Count > 0) Then - Dim objParams: Set objParams = ParseArguments(objArgs) - - If (Not objParams("Command") = "") Then - noOutput = objParams("NoOutput") - - If (objParams("PushdCurrDir")) Then - objParams("Command") = "pushd """ & objShell.CurrentDirectory & """" & " & " & objParams("Command") - End If - - Dim tempFolder: tempFolder = objShell.ExpandEnvironmentStrings("%TEMP%") - Dim commandErrorLog: commandErrorLog = tempFolder & "\" & LCase(scriptBaseName) & "-command-error-" & RandomString() & ".log" - - objParams("Command") = objParams("Command") & " 2>""" & commandErrorLog & """" - objParams("Command") = Replace(objParams("Command"), """", "\""") - - Dim powerShellWait - If (objParams("WaitForFinish")) Then - powerShellWait = " -Wait" - Else - powerShellWait = "" - End If - - Dim powerShellWindow - If (objParams("ShowWindow")) Then - powerShellWindow = " -WindowStyle " & objParams("WindowSize") - Else - powerShellWindow = " -WindowStyle Hidden" - End If - - Dim powerShellRunAs - If (objParams("Elevated")) Then - powerShellRunAs = " -Verb RunAs" - Else - powerShellRunAs = "" - End If +' Arguments is missing +If (objArgs.Count <= 0) Then + ShowHelpWithMessage scriptBaseName & " error: Missing input arguments.", "error" + Quit 1 +End If - Dim powerShellCommand - powerShellCommand = "powershell -Command ""Start-Process cmd -ArgumentList {""" & objParams("CmdOptions") & " \""" & objParams("Command") & "\""""}" & _ - powerShellRunAs & powerShellWait & powerShellWindow & """" +' Parse arguments +Dim objParams: Set objParams = ParseArguments(objArgs) - Set objParams = Nothing +' The command argument is missing +If (Trim(objParams("Command")) = "") Then + ShowHelpWithMessage scriptBaseName & " error: The ""command"" argument is missing.", "error" + Set objParams = Nothing + Quit 1 +End If - ' Method 1: Use Run function if we do not need to store the process ID - Dim exitCode: exitCode = objShell.Run(powerShellCommand, 0, true) +' Push current dir before execute command +If (objParams("PushdCurrDir")) Then + objParams("Command") = "pushd """ & objShell.CurrentDirectory & """" & " & " & objParams("Command") +End If - If (exitCode = 1) Then - If (Not noOutput) Then - WScript.Echo "The operation was canceled by the user." - End If +' Prepare error lof file if the execution of command occurred error +Dim tempFolder: tempFolder = objShell.ExpandEnvironmentStrings("%TEMP%") +Dim errorLogPath: errorLogPath = tempFolder & "\" & LCase(scriptBaseName) & "-error-" & RandomString() & ".log" +objParams("Command") = objParams("Command") & " || type nul>""" & errorLogPath & """" - Quit 1 - End If +' Build powershell command +objParams("Command") = Replace(objParams("Command"), """", "\""") - ' Method 2: Use Exec function if want to store process ID - ' Dim objExec: Set objExec = objShell.Exec(powerShellCommand) - ' Dim processID: processID = objExec.ProcessID +Dim powerShellWait +If (objParams("WaitForFinish")) Then + powerShellWait = " -Wait" +Else + powerShellWait = "" +End If - ' While (objExec.Status = 0) - ' WScript.Sleep 50 +Dim powerShellWindow +If (objParams("ShowWindow")) Then + powerShellWindow = " -WindowStyle " & objParams("WindowSize") +Else + powerShellWindow = " -WindowStyle Hidden" +End If - ' If (objExec.ExitCode = 1) Then - ' If (Not noOutput) Then - ' WScript.Echo "The operation was canceled by the user." - ' End If +Dim powerShellRunAs +If (objParams("Elevated")) Then + powerShellRunAs = " -Verb RunAs" +Else + powerShellRunAs = "" +End If - ' Set objExec = Nothing - ' Quit 1 - ' End If - ' Wend +Dim powerShellCommand +powerShellCommand = "powershell -Command ""Start-Process cmd -ArgumentList {""" & objParams("CmdOptions") & " \""" & objParams("Command") & "\""""}" & _ + powerShellRunAs & powerShellWait & powerShellWindow & """" - ' Set objExec = Nothing +' Run powershell command +' Method 1: Use Run function if we do not need to store the process ID +Dim exitCode: exitCode = objShell.Run(powerShellCommand, 0, true) - ' Check the command execution - Dim openFile: Set openFile = objFSO.OpenTextFile(commandErrorLog, 1, true) - Dim errorContent +If (exitCode = 1) Then + If (Not objParams("NoOutput")) Then + WriteMsg "The operation was canceled by user.", "error" + End If - If Not openFile.AtEndOfStream Then - ' errorContent = openFile.ReadAll() - errorContent = errorContent & openFile.ReadAll() - Else - errorContent = "" - End If + Set objParams = Nothing + Quit 1 +End If - Set openFile = Nothing - objFSO.DeleteFile(commandErrorLog) +' Method 2: Use Exec function if want to store process ID +' Dim objExec: Set objExec = objShell.Exec(powerShellCommand) +' Dim processID: processID = objExec.ProcessID +' While (objExec.Status = 0) +' WScript.Sleep 50 +' If (objExec.ExitCode = 1) Then +' If (Not objParams("NoOutput")) Then +' WriteMsg "The operation was canceled by the user.", "error" +' End If +' Set objExec = Nothing +' Quit 1 +' End If +' Wend +' Set objExec = Nothing + +' If do not wait for finish +If (Not objParams("WaitForFinish")) Then + If (Not objParams("NoOutput")) Then + WriteMsg "The operation has been executed.", "output" + End If - If (Not errorContent = "") Then - If (Not noOutput) Then - WScript.Echo "The execution of the command occurred an error:" - WScript.Echo errorContent - End If + Set objParams = Nothing + Quit 0 +End If - Quit 1 - End If +' If the execution of command occurred error +If (objFSO.FileExists(errorLogPath)) Then + objFSO.DeleteFile(errorLogPath) - ' Finish command excution - If (Not noOutput) Then - WScript.Echo "The execution of the command has been completed successfully." - End If - Else - ShowHelpWithMessage scriptBaseName & " error: Missing arguments." - Quit 1 + If (Not objParams("NoOutput")) Then + WriteMsg "The execution of the operation occurred error.", "error" End If -Else - ShowHelpWithMessage scriptBaseName & " error: Missing arguments." + + Set objParams = Nothing Quit 1 End If -' Clear global objects -Set objFSO = Nothing -Set objShell = Nothing -Set objArgs = Nothing \ No newline at end of file +' Finish command excution +If (Not objParams("NoOutput")) Then + WriteMsg "The execution of the operation has been successfully completed.", "output" +End If + +Set objParams = Nothing +Quit 0 + +'''''''''''''''' END MAIN PROGRAM '''''''''''''''' \ No newline at end of file diff --git a/support/Setting.php b/support/Setting.php index 3f9aad0..1a9be32 100644 --- a/support/Setting.php +++ b/support/Setting.php @@ -6,9 +6,16 @@ class Setting public function __construct() { - if (is_file($_ENV['XVHM_APP_DIR'] . '\settings.ini')) { - $this->settings = @parse_ini_file($_ENV['XVHM_APP_DIR'] . '\settings.ini', true); + $this->reloadSettings(); + } + + public function reloadSettings() + { + if (is_file(getenv('XVHM_APP_DIR') . '\settings.ini')) { + $this->settings = @parse_ini_file(getenv('XVHM_APP_DIR') . '\settings.ini', true); } + + return $this; } public function all() @@ -59,6 +66,6 @@ public function save() } } - return file_put_contents($_ENV['XVHM_APP_DIR'] . '\settings.ini', ltrim($content)); + return @file_put_contents(getenv('XVHM_APP_DIR') . '\settings.ini', ltrim($content)); } } diff --git a/vhostcert_generate.bat b/vhostcert_generate.bat index 59cea03..4e275bd 100644 --- a/vhostcert_generate.bat +++ b/vhostcert_generate.bat @@ -3,7 +3,6 @@ cls setlocal EnableExtensions :: Check necessary data -if not "%XVHM_APP_STARTED%"=="true" goto missing if "%XVHM_APP_DIR%"=="" goto missing if "%XVHM_TMP_DIR%"=="" goto missing if "%XVHM_CACERT_DIR%"=="" goto missing diff --git a/xvhosts.bat b/xvhosts.bat index ab53ba2..d1ae820 100644 --- a/xvhosts.bat +++ b/xvhosts.bat @@ -5,142 +5,63 @@ setlocal EnableExtensions EnableDelayedExpansion :: DETECT PHP =================================== for /F "tokens=* USEBACKQ" %%v in (`where php`) do ( if not exist "%%v" goto phpBinNotFound - set XVHM_PHP_DIR=%%~dpv - if "!XVHM_PHP_DIR:~-1!"=="\" set XVHM_PHP_DIR=!XVHM_PHP_DIR:~0,-1! ) -:: TURN ON STARTED FLAG ========================= -set XVHM_APP_STARTED=true - -:: DEFINE APP DIRS ============================== +:: DEFINE APP PATHS ============================= set XVHM_APP_DIR=%~dp0 if not "%XVHM_APP_DIR:~-2%"==":\" set XVHM_APP_DIR=%XVHM_APP_DIR:~0,-1% -set XVHM_TMP_DIR=%XVHM_APP_DIR%\tmp -set XVHM_CACERT_DIR=%XVHM_APP_DIR%\cacert -set XVHM_CACERT_GENERATE_SCRIPT=%XVHM_APP_DIR%\cacert_generate.bat -set XVHM_CACERT_GENERATE_CONFIG=%XVHM_APP_DIR%\cacert_generate.cnf -set XVHM_VHOST_CONFIG_TEMPLATE=%XVHM_APP_DIR%\templates\vhost_config\vhost.conf.tpl -set XVHM_VHOST_SSL_CONFIG_TEMPLATE=%XVHM_APP_DIR%\templates\vhost_config\vhost_ssl.conf.tpl -set XVHM_VHOST_CERT_GENERATE_SCRIPT=%XVHM_APP_DIR%\vhostcert_generate.bat -set XVHM_VHOST_CERT_GENERATE_CONFIG=%XVHM_APP_DIR%\vhostcert_generate.cnf -set XVHM_APPPATH_REGISTER=%XVHM_APP_DIR%\apppath_register.vbs -set XVHM_POWER_EXECUTOR=%XVHM_APP_DIR%\support\PowerExec.vbs - -:: INSTALL VHOSTS MANAGER AS REQUIRED =========== -if "%~1"=="install" ( - cls - goto install -) -if not exist "%XVHM_APP_DIR%\settings.ini" goto needToInstall - -:: DEFINE XAMPP DIRS ============================ -:defineXamppDirs -:: Xampp dir -for /F "tokens=* USEBACKQ" %%v in ( - `php -n "%XVHM_APP_DIR%\xvhosts.php" "getSetting" "DirectoryPaths" "Xampp" " "` -) do ( - set XVHM_XAMPP_DIR=%%v - set XVHM_XAMPP_DIR=!XVHM_XAMPP_DIR:/=\! - if "!XVHM_XAMPP_DIR:~-1!"=="\" set XVHM_XAMPP_DIR=!XVHM_XAMPP_DIR:~0,-1! - if not exist "!XVHM_XAMPP_DIR!\xampp-control.exe" goto xamppDirNotFound -) -:: Apache dir -for /F "tokens=* USEBACKQ" %%v in ( - `php -n "%XVHM_APP_DIR%\xvhosts.php" "getSetting" "DirectoryPaths" "Apache" " "` -) do ( - if "%%v"=="" ( - set XVHM_APACHE_DIR=!XVHM_XAMPP_DIR!\apache - ) else ( - set XVHM_APACHE_DIR=%%v - ) - set XVHM_APACHE_DIR=!XVHM_APACHE_DIR:/=\! - if "!XVHM_APACHE_DIR:~-1!"=="\" set XVHM_APACHE_DIR=!XVHM_APACHE_DIR:~0,-1! - if not exist "!XVHM_APACHE_DIR!\bin\httpd.exe" goto apacheDirNotFound -) - -:: Related dirs -set XVHM_VHOST_CERT_DIR=%XVHM_APACHE_DIR%\conf\extra\certs -set XVHM_VHOST_CERT_KEY_DIR=%XVHM_APACHE_DIR%\conf\extra\keys -set XVHM_VHOST_CONFIG_DIR=%XVHM_APACHE_DIR%\conf\extra\vhosts -set XVHM_VHOST_SSL_CONFIG_DIR=%XVHM_APACHE_DIR%\conf\extra\vhosts_ssl - -set XVHM_OPENSSL_BIN=%XVHM_APACHE_DIR%\bin\openssl.exe -set XVHM_OPENSSL_SUBJECT_CN=Xampp Certificate Authority -set XVHM_OPENSSL_SUBJECT_O=OpenSSL Software Foundation -set XVHM_OPENSSL_SUBJECT_OU=Server Certificate Provider -if exist "%XVHM_TMP_DIR%\.installing" goto install +set XVHM_POWER_EXECUTOR=%XVHM_APP_DIR%\support\PowerExec.vbs +set XVHM_PHP_CONTROLLER=%XVHM_APP_DIR%\xvhosts.php goto startCommand -:: ERROR NOTATION =============================== +:: ERROR NOTATIONS ============================== :phpBinNotFound echo. echo Cannot find PHP cli. -echo Make sure you have set the path to your PHP directory in system environment variables. +echo Make sure you have add the path to your PHP directory into Windows Path Environment Variable. call :clearEnvVars exit /B 1 -:xamppDirNotFound +:installationFailed echo. -echo Cannot find Xampp directory. -echo Please check the configuration path to the Xampp directory in file "%XVHM_APP_DIR%\settings.ini". -call :clearEnvVars -exit /B 1 - -:apacheDirNotFound +echo Installation Xampp vHosts Manager failed. +echo Please review the instructions carefully before installation. echo. -echo Cannot find Apache directory. -echo Please check the configuration path to the Apache directory in file "%XVHM_APP_DIR%\settings.ini". +pause>nul|set/p =Press any key to exit terminal... call :clearEnvVars -exit /B 1 +exit 1 :missingArgs echo. -echo Xampp vHosts Manager Error: Missing the command argument. +echo Xampp vHosts Manager error: The "command" argument is missing. echo. goto help call :clearEnvVars exit /B 1 -:needToInstall -echo. -echo Xampp vHosts Manager has not been integrated into Xampp. -echo Run command "xvhosts install" in Administartor mode to integrate it. -call :clearEnvVars -exit /B 1 - :: INSTALL APP ================================== :install -FSUTIL dirty query %SystemDrive% >nul +FSUTIL dirty query %SystemDrive%>nul if %errorLevel% NEQ 0 ( echo. - echo Sorry! This script can only be run with elevated permission. - pause>nul|set/p =Press any key to start the process in Administrator mode... + echo This process can only be run with elevated permission. + pause>nul|set/p =Press any key to start this process in Administrator mode... echo. - cscript //NoLogo "%XVHM_POWER_EXECUTOR%" -e "%XVHM_APP_DIR%\xvhosts.bat" install - exit /B -) -if not exist "%XVHM_TMP_DIR%\.installing" ( - php -n -d output_buffering=0 "%XVHM_APP_DIR%\xvhosts.php" "install" "start" - if not exist "%XVHM_TMP_DIR%\.installing" ( - call :clearEnvVars + cscript //NoLogo "%XVHM_POWER_EXECUTOR%" -e -x -n "%~fx0" "install" + if errorLevel 1 ( + echo The installation was canceled by user. exit /B 1 + ) else ( + echo The installation started in new window with Elevated permission. + exit /B ) - goto defineXamppDirs ) -php -n -d output_buffering=0 "%XVHM_APP_DIR%\xvhosts.php" "install" "continue" -echo. -if not exist "%XVHM_CACERT_DIR%\cacert.crt" ( - echo Installation Xampp vHosts Manager failed. - echo Please review the instructions carefully before installation. - echo. - call :clearEnvVars - exit /B 1 -) -echo XAMPP VHOSTS MANAGER WAS INSTALLED SUCCESSFULLY. -echo TO START USING IT, PLEASE EXIT YOUR TERMINAL TO DELETE TEMPORARY PROCESS ENVIRONMENT VARIABLES. +php -n -d output_buffering=0 "%XVHM_PHP_CONTROLLER%" "install" +if errorLevel 1 goto installationFailed echo. pause>nul|set/p =Press any key to exit terminal... +call :clearEnvVars exit :: APP FEATURES ================================= @@ -150,88 +71,82 @@ call :clearEnvVars exit /B :newHost -php -n -d output_buffering=0 "%XVHM_APP_DIR%\xvhosts.php" "newHost" "%~2" +php -n -d output_buffering=0 "%XVHM_PHP_CONTROLLER%" "newHost" "%~2" call :clearEnvVars -exit /B +exit /B %errorLevel% :showHostInfo -php -n -d output_buffering=0 "%XVHM_APP_DIR%\xvhosts.php" "showHostInfo" "%~2" +php -n -d output_buffering=0 "%XVHM_PHP_CONTROLLER%" "showHostInfo" "%~2" call :clearEnvVars -exit /B +exit /B %errorLevel% :listHosts -php -n -d output_buffering=0 "%XVHM_APP_DIR%\xvhosts.php" "listHosts" +php -n -d output_buffering=0 "%XVHM_PHP_CONTROLLER%" "listHosts" call :clearEnvVars -exit /B +exit /B %errorLevel% :removeHost -php -n -d output_buffering=0 "%XVHM_APP_DIR%\xvhosts.php" "removeHost" "%~2" +php -n -d output_buffering=0 "%XVHM_PHP_CONTROLLER%" "removeHost" "%~2" call :clearEnvVars -exit /B +exit /B %errorLevel% :addSSL -php -n -d output_buffering=0 "%XVHM_APP_DIR%\xvhosts.php" "addSSL" "%~2" +php -n -d output_buffering=0 "%XVHM_PHP_CONTROLLER%" "addSSL" "%~2" call :clearEnvVars -exit /B +exit /B %errorLevel% :removeSSL -php -n -d output_buffering=0 "%XVHM_APP_DIR%\xvhosts.php" "removeSSL" "%~2" +php -n -d output_buffering=0 "%XVHM_PHP_CONTROLLER%" "removeSSL" "%~2" call :clearEnvVars -exit /B +exit /B %errorLevel% + +:registerPath +php -n -d output_buffering=0 "%XVHM_PHP_CONTROLLER%" "registerPath" +call :clearEnvVars +exit /B %errorLevel% + +:stopApache +php -n -d output_buffering=0 "%XVHM_PHP_CONTROLLER%" "stopApache" +call :clearEnvVars +exit /B %errorLevel% + +:startApache +php -n -d output_buffering=0 "%XVHM_PHP_CONTROLLER%" "startApache" +call :clearEnvVars +exit /B %errorLevel% :restartApache -php -n -d output_buffering=0 "%XVHM_APP_DIR%\xvhosts.php" "restartApache" +php -n -d output_buffering=0 "%XVHM_PHP_CONTROLLER%" "restartApache" call :clearEnvVars -exit /B +exit /B %errorLevel% :startCommand cls - -:: integrated check -if not exist "%XVHM_CACERT_DIR%\cacert.crt" goto needToInstall - -:: check special input param if "%~1"=="" goto missingArgs if "%~1"=="help" goto help +if "%~1"=="install" goto install if "%~1"=="new" goto newHost if "%~1"=="show" goto showHostInfo if "%~1"=="list" goto listHosts if "%~1"=="remove" goto removeHost if "%~1"=="add_ssl" goto addSSL if "%~1"=="remove_ssl" goto removeSSL +if "%~1"=="register_path" goto registerPath +if "%~1"=="stop_apache" goto stopApache +if "%~1"=="start_apache" goto startApache if "%~1"=="restart_apache" goto restartApache -:: call the xvhosts script without param +:: call the xvhosts script with unknown param echo. -echo Xampp vHosts Manager Error: "%~1" is invalid xvhosts command. +echo Xampp vHosts Manager error: "%~1" is invalid xvhosts command. echo. goto help :: END APP ====================================== :clearEnvVars -set XVHM_APP_STARTED= set XVHM_APP_DIR= -set XVHM_TMP_DIR= -set XVHM_CACERT_DIR= -set XVHM_CACERT_GENERATE_SCRIPT= -set XVHM_CACERT_GENERATE_CONFIG= -set XVHM_VHOST_CONFIG_TEMPLATE= -set XVHM_VHOST_SSL_CONFIG_TEMPLATE= -set XVHM_VHOST_CERT_GENERATE_SCRIPT= -set XVHM_VHOST_CERT_GENERATE_CONFIG= -set XVHM_APPPATH_REGISTER= set XVHM_POWER_EXECUTOR= -set XVHM_XAMPP_DIR= -set XVHM_PHP_DIR= -set XVHM_APACHE_DIR= -set XVHM_VHOST_CERT_DIR= -set XVHM_VHOST_CERT_KEY_DIR= -set XVHM_VHOST_CONFIG_DIR= -set XVHM_VHOST_SSL_CONFIG_DIR= -set XVHM_OPENSSL_BIN= -set XVHM_OPENSSL_SUBJECT_CN= -set XVHM_OPENSSL_SUBJECT_O= -set XVHM_OPENSSL_SUBJECT_OU= +set XVHM_PHP_CONTROLLER= exit /B endlocal \ No newline at end of file diff --git a/xvhosts.php b/xvhosts.php index e28ce99..a8aa41d 100644 --- a/xvhosts.php +++ b/xvhosts.php @@ -1,17 +1,16 @@ get($_SERVER['argv'][2], $_SERVER['argv'][3], $_SERVER['argv'][4]); - exit; - } + echo $banner; if ($_SERVER['argv'][1] == 'install') { $installer = new Installer; - - if ($_SERVER['argv'][2] == 'start') { - echo $banner; - $installer->startInstall(); - exit; - } - - $installer->continueInstall(); + $installer->install(); exit; } - echo $banner; - $manager = new Manager; switch ($_SERVER['argv'][1]) { @@ -73,6 +58,18 @@ $manager->removeSSLOfHost($_SERVER['argv'][2]); break; + case 'registerPath': + $manager->registerPath(); + break; + + case 'stopApache': + $manager->stopApache(); + break; + + case 'startApache': + $manager->startApache(); + break; + case 'restartApache': $manager->askRestartApache('Are you sure you want to restart Apache?'); break;