diff --git a/install/tpl/server.ini.master b/install/tpl/server.ini.master index b822131ceef500fd155af6d76d2d3bfe8db00682..f2966c2cc2b82117e7f933415495644f68d1f8fc 100644 --- a/install/tpl/server.ini.master +++ b/install/tpl/server.ini.master @@ -5,12 +5,12 @@ dnsserver=mydns [server] -auto_network_configuration=n -ip_address=0.0.0.0 -netmask=255.255.255.0 -gateway=0.0.0.0 -hostname=server1.domain.tld -nameservers=8.8.8.8,8.8.4.4 +auto_network_configuration=n +ip_address=0.0.0.0 +netmask=255.255.255.0 +gateway=0.0.0.0 +hostname=server1.domain.tld +nameservers=8.8.8.8,8.8.4.4 firewall=bastille loglevel=2 admin_notify_events=1 @@ -51,12 +51,12 @@ getmail_config_dir=/etc/getmail [web] server_type=apache website_basedir=/var/www -website_path=/var/www/clients/client[client_id]/web[website_id] -website_symlinks=/var/www/[website_domain]/:/var/www/clients/client[client_id]/[website_domain]/ -website_symlinks_rel=n -vhost_conf_dir=/etc/apache2/sites-available -vhost_conf_enabled_dir=/etc/apache2/sites-enabled -nginx_vhost_conf_dir=/etc/nginx/sites-available +website_path=/var/www/clients/client[client_id]/web[website_id] +website_symlinks=/var/www/[website_domain]/:/var/www/clients/client[client_id]/[website_domain]/ +website_symlinks_rel=n +vhost_conf_dir=/etc/apache2/sites-available +vhost_conf_enabled_dir=/etc/apache2/sites-enabled +nginx_vhost_conf_dir=/etc/nginx/sites-available nginx_vhost_conf_enabled_dir=/etc/nginx/sites-enabled security_level=20 user=www-data diff --git a/interface/lib/classes/aps_base.inc.php b/interface/lib/classes/aps_base.inc.php index b8f6ad9232275d3ec5135002307c8e4629f82b13..4c1512ba2a018e45f9aee6ef758be1c65e767b70 100644 --- a/interface/lib/classes/aps_base.inc.php +++ b/interface/lib/classes/aps_base.inc.php @@ -1,103 +1,103 @@ -<?php -/* -Copyright (c) 2012, ISPConfig UG -Contributors: web wack creations, http://www.web-wack.at -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of ISPConfig nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -// Constants describing instances -define('INSTANCE_PENDING', 0); -define('INSTANCE_INSTALL', 1); -define('INSTANCE_ERROR', 2); -define('INSTANCE_SUCCESS', 3); -define('INSTANCE_REMOVE', 4); - -// Constants describing packages -define('PACKAGE_LOCKED', 1); -define('PACKAGE_ENABLED', 2); -define('PACKAGE_OUTDATED', 3); -define('PACKAGE_ERROR_NOMETA', 4); - -class ApsBase -{ - protected $log_prefix = ''; - protected $fetch_url = ''; - protected $aps_version = ''; - protected $packages_dir = ''; - protected $temp_pkg_dir = ''; - protected $interface_pkg_dir = ''; - protected $interface_mode = false; // server mode by default - - /** - * Constructor - * - * @param $app the application instance (db handle + log method) - * @param $interface_mode act in interface (true) or server mode (false) - * @param $log_prefix a prefix to set before all log entries - */ - public function __construct($app, $log_prefix = 'APS: ', $interface_mode = false) - { - $this->log_prefix = $log_prefix; - $this->interface_mode = $interface_mode; - $this->fetch_url = 'apscatalog.com'; - $this->aps_version = '1'; - $this->packages_dir = ISPC_ROOT_PATH.'/aps_packages'; - $this->interface_pkg_dir = ISPC_ROOT_PATH.'/web/sites/aps_meta_packages'; - } - - /** - * Converts a given value to it's native representation in 1024 units - * - * @param $value the size to convert - * @return integer and string - */ - public function convertSize($value) - { - $unit = array('Bytes', 'KB', 'MB', 'GB', 'TB'); - return @round($value/pow(1024, ($i = floor(log($value, 1024)))), 2).' '.$unit[$i]; - } - - /** - * Determine a specific xpath from a given SimpleXMLElement handle. If the - * element is found, it's string representation is returned. If not, - * the return value will stay empty - * - * @param $xml_handle the SimpleXMLElement handle - * @param $query the XPath query - * @param $array define whether to return an array or a string - * @return $ret the return string - */ - protected function getXPathValue($xml_handle, $query, $array = false) - { - $ret = ''; - - $xp_result = @($xml_handle->xpath($query)) ? $xml_handle->xpath($query) : false; - if($xp_result !== false) $ret = (($array === false) ? (string)$xp_result[0] : $xp_result); - - return $ret; - } -} +<?php +/* +Copyright (c) 2012, ISPConfig UG +Contributors: web wack creations, http://www.web-wack.at +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of ISPConfig nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +// Constants describing instances +define('INSTANCE_PENDING', 0); +define('INSTANCE_INSTALL', 1); +define('INSTANCE_ERROR', 2); +define('INSTANCE_SUCCESS', 3); +define('INSTANCE_REMOVE', 4); + +// Constants describing packages +define('PACKAGE_LOCKED', 1); +define('PACKAGE_ENABLED', 2); +define('PACKAGE_OUTDATED', 3); +define('PACKAGE_ERROR_NOMETA', 4); + +class ApsBase +{ + protected $log_prefix = ''; + protected $fetch_url = ''; + protected $aps_version = ''; + protected $packages_dir = ''; + protected $temp_pkg_dir = ''; + protected $interface_pkg_dir = ''; + protected $interface_mode = false; // server mode by default + + /** + * Constructor + * + * @param $app the application instance (db handle + log method) + * @param $interface_mode act in interface (true) or server mode (false) + * @param $log_prefix a prefix to set before all log entries + */ + public function __construct($app, $log_prefix = 'APS: ', $interface_mode = false) + { + $this->log_prefix = $log_prefix; + $this->interface_mode = $interface_mode; + $this->fetch_url = 'apscatalog.com'; + $this->aps_version = '1'; + $this->packages_dir = ISPC_ROOT_PATH.'/aps_packages'; + $this->interface_pkg_dir = ISPC_ROOT_PATH.'/web/sites/aps_meta_packages'; + } + + /** + * Converts a given value to it's native representation in 1024 units + * + * @param $value the size to convert + * @return integer and string + */ + public function convertSize($value) + { + $unit = array('Bytes', 'KB', 'MB', 'GB', 'TB'); + return @round($value/pow(1024, ($i = floor(log($value, 1024)))), 2).' '.$unit[$i]; + } + + /** + * Determine a specific xpath from a given SimpleXMLElement handle. If the + * element is found, it's string representation is returned. If not, + * the return value will stay empty + * + * @param $xml_handle the SimpleXMLElement handle + * @param $query the XPath query + * @param $array define whether to return an array or a string + * @return $ret the return string + */ + protected function getXPathValue($xml_handle, $query, $array = false) + { + $ret = ''; + + $xp_result = @($xml_handle->xpath($query)) ? $xml_handle->xpath($query) : false; + if($xp_result !== false) $ret = (($array === false) ? (string)$xp_result[0] : $xp_result); + + return $ret; + } +} ?> \ No newline at end of file diff --git a/interface/lib/classes/aps_crawler.inc.php b/interface/lib/classes/aps_crawler.inc.php index 00b1d7632729ea57fd7e5771d68f28459fcda874..2c6906efda50d4716a66c664dc3ab04ef78cc4d4 100644 --- a/interface/lib/classes/aps_crawler.inc.php +++ b/interface/lib/classes/aps_crawler.inc.php @@ -1,592 +1,592 @@ -<?php -/* -Copyright (c) 2012, ISPConfig UG -Contributors: web wack creations, http://www.web-wack.at -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of ISPConfig nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -require_once('aps_base.inc.php'); - -@set_time_limit(0); -@ignore_user_abort(1); - -class ApsCrawler extends ApsBase -{ - - //public $app_download_url_list = array(); - - /** - * Constructor - * - * @param $app the application instance (db handle + log method) - * @param $interface_mode act in interface (true) or server mode (false) - */ - public function __construct($app, $interface_mode = false) - { - parent::__construct($app, 'APS crawler: ', $interface_mode); - } - - /** - * Before the cron is executed, make sure all necessary options are set - * and all functions (i.e. cURL) are available - */ - private function checkRequirements() - { - global $app; - - try - { - // Check if allow_url_fopen is enabled - if(!@ini_get('allow_url_fopen')) throw new Exception('allow_url_fopen is not enabled'); - // Check if the cURL module is available - if(!function_exists('curl_version')) throw new Exception('cURL is not available'); - - // Check if used folders are writable - if($this->interface_mode) - { - if(!is_writable($this->interface_pkg_dir)) - throw new Exception('the folder '.basename($this->interface_pkg_dir).' is not writable'); - } - else - { - if(!is_writable($this->packages_dir)) - throw new Exception('the folder '.basename($this->packages_dir).' is not writable'); - } - - return true; - } - catch(Exception $e) - { - $app->log($this->log_prefix.'Aborting execution because '.$e->getMessage(), LOGLEVEL_ERROR); - return false; - } - } - - /** - * Remove a directory recursively - * In case of error be silent - * - * @param $dir the directory to remove - */ - private function removeDirectory($dir) - { - if(is_dir($dir)) - { - $files = scandir($dir); - foreach($files as $file) - { - if($file != '.' && $file != '..') - if(filetype($dir.'/'.$file) == 'dir') $this->removeDirectory($dir.'/'.$file); - else @unlink($dir.'/'.$file); - } - reset($files); - @rmdir($dir); - } - } - - - /** - * Fetch HTML data from one or more given URLs - * If a string is given, a string is returned, if an array of URLs should - * be fetched, the responses of the parallel queries are returned as array - * - * @param $input the string or array to fetch - * @return $ret a query response string or array - */ - private function fetchPage($input) - { - $ret = array(); - $url = array(); - $conn = array(); - - // Make sure we are working with an array, further on - if(!is_array($input)) $url[] = $input; - else $url = $input; - - // Build the single cURL handles and add them to a multi handle - $mh = curl_multi_init(); - for($i = 0; $i < count($url); $i++) - { - $conn[$i] = curl_init('http://'.$this->fetch_url.$url[$i]); - curl_setopt($conn[$i], CURLOPT_RETURNTRANSFER, true); - curl_multi_add_handle($mh, $conn[$i]); - } - - $active = 0; - do curl_multi_exec($mh, $active); - while($active > 0); - - // Get the response(s) - for($i = 0; $i < count($url); $i++) - { - $ret[$i] = curl_multi_getcontent($conn[$i]); - curl_multi_remove_handle($mh, $conn[$i]); - curl_close($conn[$i]); - } - curl_multi_close($mh); - - if(count($url) == 1) $ret = $ret[0]; - - return $ret; - } - - /** - * Fetch binary data from a given array - * The data is retrieved in binary mode and - * then directly written to an output file - * - * @param $input a specially structed array - * @see $this->startUpdate() - */ - private function fetchFiles($input) - { - $fh = array(); - $url = array(); - $conn = array(); - - // Build the single cURL handles and add them to a multi handle - $mh = curl_multi_init(); - - // Process each app - for($i = 0; $i < count($input); $i++) - { - $conn[$i] = curl_init($input[$i]['url']); - $fh[$i] = fopen($input[$i]['localtarget'], 'wb'); - - curl_setopt($conn[$i], CURLOPT_BINARYTRANSFER, true); - curl_setopt($conn[$i], CURLOPT_FILE, $fh[$i]); - curl_setopt($conn[$i], CURLOPT_TIMEOUT, 0); - curl_setopt($conn[$i], CURLOPT_FAILONERROR, 1); - curl_setopt($conn[$i], CURLOPT_FOLLOWLOCATION, 1); - - curl_multi_add_handle($mh, $conn[$i]); - } - - $active = 0; - do curl_multi_exec($mh, $active); - while($active > 0); - - // Close the handles - for($i = 0; $i < count($input); $i++) - { - fclose($fh[$i]); - curl_multi_remove_handle($mh, $conn[$i]); - curl_close($conn[$i]); - } - curl_multi_close($mh); - } - - /** - * A method to build query URLs out of a list of vendors - * - */ - private function formatVendorCallback($array_item) - { - $array_item = str_replace(' ', '%20', $array_item); - $array_item = str_replace('http://', '', $array_item); - $array_item = '/'.$this->aps_version.'.atom?vendor='.$array_item.'&pageSize=100'; - return($array_item); - } - - /** - * The main method which performs the actual crawling - */ - public function startCrawler() - { - global $app; - - try - { - // Make sure the requirements are given so that this script can execute - $req_ret = $this->checkRequirements(); - if(!$req_ret) return false; - - // Execute the open task and first fetch all vendors (APS catalog API 1.1, p. 12) - $app->log($this->log_prefix.'Fetching data from '.$this->fetch_url); - - $vendor_page = $this->fetchPage('/all-app/'); //$vendor_page = $this->fetchPage('/'.$this->aps_version.'/'); - preg_match_all("/\<a href=\"(.+)\/\" class=\"vendor\"/i", $vendor_page, $matches); - $vendors = array_map('urldecode', $matches[1]); - if(!$vendors) throw new Exception('Unable to fetch vendors. Aborting'); - - // Format all vendors for further processing (i.e. typo3.org -> /1.atom?vendor=typo3.org&pageSize=100 - //array_walk($vendors, array($this, 'formatVendorCallback')); - if(is_array($vendors)) { - foreach($vendors as $key => $array_item) { - $vendors[$key] = $this->formatVendorCallback($array_item); - } - } - - // Process all vendors in chunks of 50 entries - $vendor_chunks = array_chunk($vendors, 50); - //var_dump($vendor_chunks); - - // Get all known apps from the database and the highest known version - // Note: A dirty hack is used for numerical sorting of the VARCHAR field Version: +0 -> cast - // A longer but typesafe way would be: ORDER BY CAST(REPLACE(Version, '.', '') AS UNSIGNED) DESC - $existing_apps = $app->db->queryAllRecords("SELECT * FROM ( - SELECT name AS Name, CONCAT(version, '-', CAST(`release` AS CHAR)) AS CurrentVersion - FROM aps_packages ORDER BY REPLACE(version, '.', '')+0 DESC, `release` DESC - ) as Versions GROUP BY name"); - //var_dump($existing_apps); - - // Used for statistics later - $apps_in_repo = 0; - $apps_updated = 0; - $apps_downloaded = 0; - - $apps_to_dl = array(); - - for($i = 0; $i < count($vendor_chunks); $i++) - { - // Fetch all apps for the current chunk of vendors - $apps = $this->fetchPage($vendor_chunks[$i]); - - for($j = 0; $j < count($apps); $j++) - { - // Before parsing, make sure it's worth the work by checking if at least one app exists - $apps_count = substr_count($apps[$j], '<opensearch:totalResults>0</opensearch:totalResults>'); - if($apps_count == 0) // obviously this vendor provides one or more apps - { - // Rename namespaces and register them - $xml = str_replace("xmlns=", "ns=", $apps[$j]); - $sxe = new SimpleXMLElement($xml); - $namespaces = $sxe->getDocNamespaces(true); - foreach($namespaces as $ns => $url) $sxe->registerXPathNamespace($ns, $url); - - // Fetching values of interest - $app_name = parent::getXPathValue($sxe, 'entry[position()=1]/a:name'); - $app_version = parent::getXPathValue($sxe, 'entry[position()=1]/a:version'); - $app_release = parent::getXPathValue($sxe, 'entry[position()=1]/a:release'); - - // Find out a (possibly) existing package version - $ex_ver = ''; - /* - array_walk($existing_apps, - create_function('$v, $k, $ex_ver', 'if($v["Name"] == "'.$app_name.'") $ex_ver = $v["CurrentVersion"];'), &$ex_ver); - */ - if(is_array($existing_apps)) { - foreach($existing_apps as $k => $v) { - if($v["Name"] == $app_name) $ex_ver = $v["CurrentVersion"]; - } - } - - $new_ver = $app_version.'-'.$app_release; - $local_intf_folder = $this->interface_pkg_dir.'/'.$app_name.'-'.$new_ver.'.app.zip/'; - - // Proceed if a newer or at least equal version has been found with server mode or - // interface mode is activated and there are no valid APP-META.xml and PKG_URL existing yet - if((!$this->interface_mode && version_compare($new_ver, $ex_ver) >= 0) || ($this->interface_mode && (!file_exists($local_intf_folder.'APP-META.xml') || filesize($local_intf_folder.'APP-META.xml') == 0 || !file_exists($local_intf_folder.'PKG_URL') || filesize($local_intf_folder.'PKG_URL') == 0))){ - // Check if we already have an old version of this app - if(!empty($ex_ver) && version_compare($new_ver, $ex_ver) == 1) $apps_updated++; - - $app_dl = parent::getXPathValue($sxe, "entry[position()=1]/link[@a:type='aps']/@href"); - $app_filesize = parent::getXPathValue($sxe, "entry[position()=1]/link[@a:type='aps']/@length"); - $app_metafile = parent::getXPathValue($sxe, "entry[position()=1]/link[@a:type='meta']/@href"); - - //$this->app_download_url_list[$app_name.'-'.$new_ver.'.app.zip'] = $app_dl; - // Skip ASP.net packages because they can't be used at all - $asp_handler = parent::getXPathValue($sxe, '//aspnet:handler'); - $asp_permissions = parent::getXPathValue($sxe, '//aspnet:permissions'); - $asp_version = parent::getXPathValue($sxe, '//aspnet:version'); - if(!empty($asp_handler) || !empty($asp_permissions) || !empty($asp_version)) continue; - - // Interface mode (download only parts) - if($this->interface_mode) - { - // Delete an obviously out-dated version from the system and DB - if(!empty($ex_ver) && version_compare($new_ver, $ex_ver) == 1) - { - $old_folder = $this->interface_pkg_dir.'/'.$app_name.'-'.$ex_ver.'.app.zip'; - if(file_exists($old_folder)) $this->removeDirectory($old_folder); - - /* - $app->db->query("UPDATE aps_packages SET package_status = '".PACKAGE_OUTDATED."' WHERE name = '". - $app->db->quote($app_name)."' AND CONCAT(version, '-', CAST(`release` AS CHAR)) = '". - $app->db->quote($ex_ver)."';"); - */ - $tmp = $app->db->queryOneRecord("SELECT id FROM aps_packages WHERE name = '". - $app->db->quote($app_name)."' AND CONCAT(version, '-', CAST(`release` AS CHAR)) = '". - $app->db->quote($ex_ver)."';"); - $app->db->datalogUpdate('aps_packages', "package_status = ".PACKAGE_OUTDATED, 'id', $tmp['id']); - unset($tmp); - } - - // Create the local folder if not yet existing - if(!file_exists($local_intf_folder)) @mkdir($local_intf_folder, 0777, true); - - // Save the package URL in an extra file because it's not part of the APP-META.xml file - @file_put_contents($local_intf_folder.'PKG_URL', $app_dl); - - // Download the meta file - $local_metafile = $local_intf_folder.'APP-META.xml'; - if(!file_exists($local_metafile) || filesize($local_metafile) == 0) - { - $apps_to_dl[] = array('name' => 'APP-META.xml', - 'url' => $app_metafile, - 'filesize' => 0, - 'localtarget' => $local_metafile); - $apps_downloaded++; - } - - // Download package license - $license = parent::getXPathValue($sxe, "entry[position()=1]/link[@a:type='eula']/@href"); - if($license != '') - { - $local_license = $local_intf_folder.'LICENSE'; - if(!file_exists($local_license) || filesize($local_license) == 0) - { - $apps_to_dl[] = array('name' => basename($license), - 'url' => $license, - 'filesize' => 0, - 'localtarget' => $local_license); - } - } - - // Download package icon - $icon = parent::getXPathValue($sxe, "entry[position()=1]/link[@a:type='icon']/@href"); - if($icon != '') - { - $local_icon = $local_intf_folder.basename($icon); - if(!file_exists($local_icon) || filesize($local_icon) == 0) - { - $apps_to_dl[] = array('name' => basename($icon), - 'url' => $icon, - 'filesize' => 0, - 'localtarget' => $local_icon); - } - } - - // Download available screenshots - $screenshots = parent::getXPathValue($sxe, "entry[position()=1]/link[@a:type='screenshot']", true); - if(!empty($screenshots)) - { - foreach($screenshots as $screen) - { - $local_screen = $local_intf_folder.basename($screen['href']); - if(!file_exists($local_screen) || filesize($local_screen) == 0) - { - $apps_to_dl[] = array('name' => basename($screen['href']), - 'url' => $screen['href'], - 'filesize' => 0, - 'localtarget' => $local_screen); - } - } - } - } - else // Server mode (download whole ZIP archive) - { - // Delete an obviously out-dated version from the system - if(!empty($ex_ver) && version_compare($new_ver, $ex_ver) == 1) - { - $old_file = $this->packages_dir.'/'.$app_name.'-'.$ex_ver.'.app.zip'; - if(file_exists($old_file)) $this->removeDirectory($old_file); - } - - // Attention: $new_ver can also be == $ex_ver (according to version_compare >= 0) - $local_zip = $this->packages_dir.'/'.$app_name.'-'.$new_ver.'.app.zip'; - - // Before re-downloading a file, make sure it's not yet existing on HDD (due to DB inconsistency) - if((file_exists($local_zip) && (filesize($local_zip) == $app_filesize)) === false) - { - $apps_to_dl[] = array('name' => $app_name, - 'url' => $app_dl, - 'filesize' => $app_filesize, - 'localtarget' => $local_zip); - $apps_downloaded++; - } - } - } - - unset($sxe); - $apps_in_repo++; - } - } - //var_dump($apps); - - // For memory reasons, unset the current vendor and his apps - unset($apps); - } - - // Shuffle the download array (in order to compensate unexpected php aborts) - shuffle($apps_to_dl); - - // After collecting all provisioned apps, download them - $apps_to_dl_chunks = array_chunk($apps_to_dl, 10); - - for($i = 0; $i < count($apps_to_dl_chunks); $i++) - { - $this->fetchFiles($apps_to_dl_chunks[$i]); - - // Check the integrity of all downloaded files - // but exclude cases where no filesize is available (i.e. screenshot or metafile download) - for($j = 0; $j < count($apps_to_dl_chunks[$i]); $j++) - { - if($apps_to_dl_chunks[$i][$j]['filesize'] != 0 && - $apps_to_dl_chunks[$i][$j]['filesize'] != filesize($apps_to_dl_chunks[$i][$j]['localtarget'])) - { - $app->log($this->log_prefix.' The filesize of the package "'. - $apps_to_dl_chunks[$i][$j]['name'].'" is wrong. Download failure?', LOGLEVEL_WARN); - } - } - } - - $app->log($this->log_prefix.'Processed '.$apps_in_repo. - ' apps from the repo. Downloaded '.$apps_updated. - ' updates, '.$apps_downloaded.' new apps'); - } - catch(Exception $e) - { - $app->log($this->log_prefix.$e->getMessage(), LOGLEVEL_ERROR); - return false; - } - } - - /** - * Read in all possible packages from the interface packages folder and - * check if they are not ASP.net code (as this can't be processed). - * - * Note: There's no need to check if the packages to register are newer - * than those in the database because this already happended in startCrawler() - */ - public function parseFolderToDB() - { - global $app; - - try - { - // This method must be used in interface mode - if(!$this->interface_mode) return false; - - $pkg_list = array(); - - // Read in every package having a correct filename - $temp_handle = @dir($this->interface_pkg_dir); - if(!$temp_handle) throw new Exception('The temp directory is not accessible'); - while($folder = $temp_handle->read()) - if(substr($folder, -8) == '.app.zip') $pkg_list[] = $folder; - $temp_handle->close(); - - // If no packages are available -> exception (because at this point there should exist packages) - if(empty($pkg_list)) throw new Exception('No packages to read in'); - - // Get registered packages and mark non-existant packages with an error code to omit the install - $existing_packages = array(); - $path_query = $app->db->queryAllRecords('SELECT path AS Path FROM aps_packages;'); - foreach($path_query as $path) $existing_packages[] = $path['Path']; - $diff = array_diff($existing_packages, $pkg_list); - foreach($diff as $todelete) { - /*$app->db->query("UPDATE aps_packages SET package_status = '".PACKAGE_ERROR_NOMETA."' - WHERE path = '".$app->db->quote($todelete)."';");*/ - $tmp = $app->db->queryOneRecord("SELECT id FROM aps_packages WHERE path = '".$app->db->quote($todelete)."';"); - $app->db->datalogUpdate('aps_packages', "package_status = ".PACKAGE_ERROR_NOMETA, 'id', $tmp['id']); - unset($tmp); - } - - // Register all new packages - $new_packages = array_diff($pkg_list, $existing_packages); - foreach($new_packages as $pkg) - { - // Load in meta file if existing and register its namespaces - $metafile = $this->interface_pkg_dir.'/'.$pkg.'/APP-META.xml'; - if(!file_exists($metafile)) - { - $app->log($this->log_prefix.'Cannot read metadata from '.$pkg, LOGLEVEL_ERROR); - continue; - } - - $metadata = file_get_contents($metafile); - $metadata = str_replace("xmlns=", "ns=", $metadata); - $sxe = new SimpleXMLElement($metadata); - $namespaces = $sxe->getDocNamespaces(true); - foreach($namespaces as $ns => $url) $sxe->registerXPathNamespace($ns, $url); - - // Insert the new package - $pkg_name = parent::getXPathValue($sxe, 'name'); - $pkg_category = parent::getXPathValue($sxe, '//category'); - $pkg_version = parent::getXPathValue($sxe, 'version'); - $pkg_release = parent::getXPathValue($sxe, 'release'); - //$pkg_url = $this->app_download_url_list[$pkg]; - $pkg_url = @file_get_contents($this->interface_pkg_dir.'/'.$pkg.'/PKG_URL'); - - /* - $app->db->query("INSERT INTO `aps_packages` - (`path`, `name`, `category`, `version`, `release`, `package_status`) VALUES - ('".$app->db->quote($pkg)."', '".$app->db->quote($pkg_name)."', - '".$app->db->quote($pkg_category)."', '".$app->db->quote($pkg_version)."', - ".$app->db->quote($pkg_release).", ".PACKAGE_ENABLED.");"); - */ - // Insert only if data is complete - if($pkg != '' && $pkg_name != '' && $pkg_category != '' && $pkg_version != '' && $pkg_release != '' && $pkg_url){ - $insert_data = "(`path`, `name`, `category`, `version`, `release`, `package_url`, `package_status`) VALUES - ('".$app->db->quote($pkg)."', '".$app->db->quote($pkg_name)."', - '".$app->db->quote($pkg_category)."', '".$app->db->quote($pkg_version)."', - ".$app->db->quote($pkg_release).", '".$app->db->quote($pkg_url)."', ".PACKAGE_ENABLED.");"; - - $app->db->datalogInsert('aps_packages', $insert_data, 'id'); - } else { - if(file_exists($this->interface_pkg_dir.'/'.$pkg)) $this->removeDirectory($this->interface_pkg_dir.'/'.$pkg); - } - } - } - catch(Exception $e) - { - $app->log($this->log_prefix.$e->getMessage(), LOGLEVEL_ERROR); - $app->error($e->getMessage()); - return false; - } - } - - /** - * Add missing package URLs to database - */ - public function fixURLs() - { - global $app; - - try - { - // This method must be used in interface mode - if(!$this->interface_mode) return false; - - $incomplete_pkgs = $app->db->queryAllRecords("SELECT * FROM aps_packages WHERE package_url = ''"); - if(is_array($incomplete_pkgs) && !empty($incomplete_pkgs)){ - foreach($incomplete_pkgs as $incomplete_pkg){ - $pkg_url = @file_get_contents($this->interface_pkg_dir.'/'.$incomplete_pkg['path'].'/PKG_URL'); - if($pkg_url != ''){ - $app->db->datalogUpdate('aps_packages', "package_url = '".$pkg_url."'", 'id', $incomplete_pkg['id']); - } - } - } - } - catch(Exception $e) - { - $app->log($this->log_prefix.$e->getMessage(), LOGLEVEL_ERROR); - $app->error($e->getMessage()); - return false; - } - } -} +<?php +/* +Copyright (c) 2012, ISPConfig UG +Contributors: web wack creations, http://www.web-wack.at +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of ISPConfig nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +require_once('aps_base.inc.php'); + +@set_time_limit(0); +@ignore_user_abort(1); + +class ApsCrawler extends ApsBase +{ + + //public $app_download_url_list = array(); + + /** + * Constructor + * + * @param $app the application instance (db handle + log method) + * @param $interface_mode act in interface (true) or server mode (false) + */ + public function __construct($app, $interface_mode = false) + { + parent::__construct($app, 'APS crawler: ', $interface_mode); + } + + /** + * Before the cron is executed, make sure all necessary options are set + * and all functions (i.e. cURL) are available + */ + private function checkRequirements() + { + global $app; + + try + { + // Check if allow_url_fopen is enabled + if(!@ini_get('allow_url_fopen')) throw new Exception('allow_url_fopen is not enabled'); + // Check if the cURL module is available + if(!function_exists('curl_version')) throw new Exception('cURL is not available'); + + // Check if used folders are writable + if($this->interface_mode) + { + if(!is_writable($this->interface_pkg_dir)) + throw new Exception('the folder '.basename($this->interface_pkg_dir).' is not writable'); + } + else + { + if(!is_writable($this->packages_dir)) + throw new Exception('the folder '.basename($this->packages_dir).' is not writable'); + } + + return true; + } + catch(Exception $e) + { + $app->log($this->log_prefix.'Aborting execution because '.$e->getMessage(), LOGLEVEL_ERROR); + return false; + } + } + + /** + * Remove a directory recursively + * In case of error be silent + * + * @param $dir the directory to remove + */ + private function removeDirectory($dir) + { + if(is_dir($dir)) + { + $files = scandir($dir); + foreach($files as $file) + { + if($file != '.' && $file != '..') + if(filetype($dir.'/'.$file) == 'dir') $this->removeDirectory($dir.'/'.$file); + else @unlink($dir.'/'.$file); + } + reset($files); + @rmdir($dir); + } + } + + + /** + * Fetch HTML data from one or more given URLs + * If a string is given, a string is returned, if an array of URLs should + * be fetched, the responses of the parallel queries are returned as array + * + * @param $input the string or array to fetch + * @return $ret a query response string or array + */ + private function fetchPage($input) + { + $ret = array(); + $url = array(); + $conn = array(); + + // Make sure we are working with an array, further on + if(!is_array($input)) $url[] = $input; + else $url = $input; + + // Build the single cURL handles and add them to a multi handle + $mh = curl_multi_init(); + for($i = 0; $i < count($url); $i++) + { + $conn[$i] = curl_init('http://'.$this->fetch_url.$url[$i]); + curl_setopt($conn[$i], CURLOPT_RETURNTRANSFER, true); + curl_multi_add_handle($mh, $conn[$i]); + } + + $active = 0; + do curl_multi_exec($mh, $active); + while($active > 0); + + // Get the response(s) + for($i = 0; $i < count($url); $i++) + { + $ret[$i] = curl_multi_getcontent($conn[$i]); + curl_multi_remove_handle($mh, $conn[$i]); + curl_close($conn[$i]); + } + curl_multi_close($mh); + + if(count($url) == 1) $ret = $ret[0]; + + return $ret; + } + + /** + * Fetch binary data from a given array + * The data is retrieved in binary mode and + * then directly written to an output file + * + * @param $input a specially structed array + * @see $this->startUpdate() + */ + private function fetchFiles($input) + { + $fh = array(); + $url = array(); + $conn = array(); + + // Build the single cURL handles and add them to a multi handle + $mh = curl_multi_init(); + + // Process each app + for($i = 0; $i < count($input); $i++) + { + $conn[$i] = curl_init($input[$i]['url']); + $fh[$i] = fopen($input[$i]['localtarget'], 'wb'); + + curl_setopt($conn[$i], CURLOPT_BINARYTRANSFER, true); + curl_setopt($conn[$i], CURLOPT_FILE, $fh[$i]); + curl_setopt($conn[$i], CURLOPT_TIMEOUT, 0); + curl_setopt($conn[$i], CURLOPT_FAILONERROR, 1); + curl_setopt($conn[$i], CURLOPT_FOLLOWLOCATION, 1); + + curl_multi_add_handle($mh, $conn[$i]); + } + + $active = 0; + do curl_multi_exec($mh, $active); + while($active > 0); + + // Close the handles + for($i = 0; $i < count($input); $i++) + { + fclose($fh[$i]); + curl_multi_remove_handle($mh, $conn[$i]); + curl_close($conn[$i]); + } + curl_multi_close($mh); + } + + /** + * A method to build query URLs out of a list of vendors + * + */ + private function formatVendorCallback($array_item) + { + $array_item = str_replace(' ', '%20', $array_item); + $array_item = str_replace('http://', '', $array_item); + $array_item = '/'.$this->aps_version.'.atom?vendor='.$array_item.'&pageSize=100'; + return($array_item); + } + + /** + * The main method which performs the actual crawling + */ + public function startCrawler() + { + global $app; + + try + { + // Make sure the requirements are given so that this script can execute + $req_ret = $this->checkRequirements(); + if(!$req_ret) return false; + + // Execute the open task and first fetch all vendors (APS catalog API 1.1, p. 12) + $app->log($this->log_prefix.'Fetching data from '.$this->fetch_url); + + $vendor_page = $this->fetchPage('/all-app/'); //$vendor_page = $this->fetchPage('/'.$this->aps_version.'/'); + preg_match_all("/\<a href=\"(.+)\/\" class=\"vendor\"/i", $vendor_page, $matches); + $vendors = array_map('urldecode', $matches[1]); + if(!$vendors) throw new Exception('Unable to fetch vendors. Aborting'); + + // Format all vendors for further processing (i.e. typo3.org -> /1.atom?vendor=typo3.org&pageSize=100 + //array_walk($vendors, array($this, 'formatVendorCallback')); + if(is_array($vendors)) { + foreach($vendors as $key => $array_item) { + $vendors[$key] = $this->formatVendorCallback($array_item); + } + } + + // Process all vendors in chunks of 50 entries + $vendor_chunks = array_chunk($vendors, 50); + //var_dump($vendor_chunks); + + // Get all known apps from the database and the highest known version + // Note: A dirty hack is used for numerical sorting of the VARCHAR field Version: +0 -> cast + // A longer but typesafe way would be: ORDER BY CAST(REPLACE(Version, '.', '') AS UNSIGNED) DESC + $existing_apps = $app->db->queryAllRecords("SELECT * FROM ( + SELECT name AS Name, CONCAT(version, '-', CAST(`release` AS CHAR)) AS CurrentVersion + FROM aps_packages ORDER BY REPLACE(version, '.', '')+0 DESC, `release` DESC + ) as Versions GROUP BY name"); + //var_dump($existing_apps); + + // Used for statistics later + $apps_in_repo = 0; + $apps_updated = 0; + $apps_downloaded = 0; + + $apps_to_dl = array(); + + for($i = 0; $i < count($vendor_chunks); $i++) + { + // Fetch all apps for the current chunk of vendors + $apps = $this->fetchPage($vendor_chunks[$i]); + + for($j = 0; $j < count($apps); $j++) + { + // Before parsing, make sure it's worth the work by checking if at least one app exists + $apps_count = substr_count($apps[$j], '<opensearch:totalResults>0</opensearch:totalResults>'); + if($apps_count == 0) // obviously this vendor provides one or more apps + { + // Rename namespaces and register them + $xml = str_replace("xmlns=", "ns=", $apps[$j]); + $sxe = new SimpleXMLElement($xml); + $namespaces = $sxe->getDocNamespaces(true); + foreach($namespaces as $ns => $url) $sxe->registerXPathNamespace($ns, $url); + + // Fetching values of interest + $app_name = parent::getXPathValue($sxe, 'entry[position()=1]/a:name'); + $app_version = parent::getXPathValue($sxe, 'entry[position()=1]/a:version'); + $app_release = parent::getXPathValue($sxe, 'entry[position()=1]/a:release'); + + // Find out a (possibly) existing package version + $ex_ver = ''; + /* + array_walk($existing_apps, + create_function('$v, $k, $ex_ver', 'if($v["Name"] == "'.$app_name.'") $ex_ver = $v["CurrentVersion"];'), &$ex_ver); + */ + if(is_array($existing_apps)) { + foreach($existing_apps as $k => $v) { + if($v["Name"] == $app_name) $ex_ver = $v["CurrentVersion"]; + } + } + + $new_ver = $app_version.'-'.$app_release; + $local_intf_folder = $this->interface_pkg_dir.'/'.$app_name.'-'.$new_ver.'.app.zip/'; + + // Proceed if a newer or at least equal version has been found with server mode or + // interface mode is activated and there are no valid APP-META.xml and PKG_URL existing yet + if((!$this->interface_mode && version_compare($new_ver, $ex_ver) >= 0) || ($this->interface_mode && (!file_exists($local_intf_folder.'APP-META.xml') || filesize($local_intf_folder.'APP-META.xml') == 0 || !file_exists($local_intf_folder.'PKG_URL') || filesize($local_intf_folder.'PKG_URL') == 0))){ + // Check if we already have an old version of this app + if(!empty($ex_ver) && version_compare($new_ver, $ex_ver) == 1) $apps_updated++; + + $app_dl = parent::getXPathValue($sxe, "entry[position()=1]/link[@a:type='aps']/@href"); + $app_filesize = parent::getXPathValue($sxe, "entry[position()=1]/link[@a:type='aps']/@length"); + $app_metafile = parent::getXPathValue($sxe, "entry[position()=1]/link[@a:type='meta']/@href"); + + //$this->app_download_url_list[$app_name.'-'.$new_ver.'.app.zip'] = $app_dl; + // Skip ASP.net packages because they can't be used at all + $asp_handler = parent::getXPathValue($sxe, '//aspnet:handler'); + $asp_permissions = parent::getXPathValue($sxe, '//aspnet:permissions'); + $asp_version = parent::getXPathValue($sxe, '//aspnet:version'); + if(!empty($asp_handler) || !empty($asp_permissions) || !empty($asp_version)) continue; + + // Interface mode (download only parts) + if($this->interface_mode) + { + // Delete an obviously out-dated version from the system and DB + if(!empty($ex_ver) && version_compare($new_ver, $ex_ver) == 1) + { + $old_folder = $this->interface_pkg_dir.'/'.$app_name.'-'.$ex_ver.'.app.zip'; + if(file_exists($old_folder)) $this->removeDirectory($old_folder); + + /* + $app->db->query("UPDATE aps_packages SET package_status = '".PACKAGE_OUTDATED."' WHERE name = '". + $app->db->quote($app_name)."' AND CONCAT(version, '-', CAST(`release` AS CHAR)) = '". + $app->db->quote($ex_ver)."';"); + */ + $tmp = $app->db->queryOneRecord("SELECT id FROM aps_packages WHERE name = '". + $app->db->quote($app_name)."' AND CONCAT(version, '-', CAST(`release` AS CHAR)) = '". + $app->db->quote($ex_ver)."';"); + $app->db->datalogUpdate('aps_packages', "package_status = ".PACKAGE_OUTDATED, 'id', $tmp['id']); + unset($tmp); + } + + // Create the local folder if not yet existing + if(!file_exists($local_intf_folder)) @mkdir($local_intf_folder, 0777, true); + + // Save the package URL in an extra file because it's not part of the APP-META.xml file + @file_put_contents($local_intf_folder.'PKG_URL', $app_dl); + + // Download the meta file + $local_metafile = $local_intf_folder.'APP-META.xml'; + if(!file_exists($local_metafile) || filesize($local_metafile) == 0) + { + $apps_to_dl[] = array('name' => 'APP-META.xml', + 'url' => $app_metafile, + 'filesize' => 0, + 'localtarget' => $local_metafile); + $apps_downloaded++; + } + + // Download package license + $license = parent::getXPathValue($sxe, "entry[position()=1]/link[@a:type='eula']/@href"); + if($license != '') + { + $local_license = $local_intf_folder.'LICENSE'; + if(!file_exists($local_license) || filesize($local_license) == 0) + { + $apps_to_dl[] = array('name' => basename($license), + 'url' => $license, + 'filesize' => 0, + 'localtarget' => $local_license); + } + } + + // Download package icon + $icon = parent::getXPathValue($sxe, "entry[position()=1]/link[@a:type='icon']/@href"); + if($icon != '') + { + $local_icon = $local_intf_folder.basename($icon); + if(!file_exists($local_icon) || filesize($local_icon) == 0) + { + $apps_to_dl[] = array('name' => basename($icon), + 'url' => $icon, + 'filesize' => 0, + 'localtarget' => $local_icon); + } + } + + // Download available screenshots + $screenshots = parent::getXPathValue($sxe, "entry[position()=1]/link[@a:type='screenshot']", true); + if(!empty($screenshots)) + { + foreach($screenshots as $screen) + { + $local_screen = $local_intf_folder.basename($screen['href']); + if(!file_exists($local_screen) || filesize($local_screen) == 0) + { + $apps_to_dl[] = array('name' => basename($screen['href']), + 'url' => $screen['href'], + 'filesize' => 0, + 'localtarget' => $local_screen); + } + } + } + } + else // Server mode (download whole ZIP archive) + { + // Delete an obviously out-dated version from the system + if(!empty($ex_ver) && version_compare($new_ver, $ex_ver) == 1) + { + $old_file = $this->packages_dir.'/'.$app_name.'-'.$ex_ver.'.app.zip'; + if(file_exists($old_file)) $this->removeDirectory($old_file); + } + + // Attention: $new_ver can also be == $ex_ver (according to version_compare >= 0) + $local_zip = $this->packages_dir.'/'.$app_name.'-'.$new_ver.'.app.zip'; + + // Before re-downloading a file, make sure it's not yet existing on HDD (due to DB inconsistency) + if((file_exists($local_zip) && (filesize($local_zip) == $app_filesize)) === false) + { + $apps_to_dl[] = array('name' => $app_name, + 'url' => $app_dl, + 'filesize' => $app_filesize, + 'localtarget' => $local_zip); + $apps_downloaded++; + } + } + } + + unset($sxe); + $apps_in_repo++; + } + } + //var_dump($apps); + + // For memory reasons, unset the current vendor and his apps + unset($apps); + } + + // Shuffle the download array (in order to compensate unexpected php aborts) + shuffle($apps_to_dl); + + // After collecting all provisioned apps, download them + $apps_to_dl_chunks = array_chunk($apps_to_dl, 10); + + for($i = 0; $i < count($apps_to_dl_chunks); $i++) + { + $this->fetchFiles($apps_to_dl_chunks[$i]); + + // Check the integrity of all downloaded files + // but exclude cases where no filesize is available (i.e. screenshot or metafile download) + for($j = 0; $j < count($apps_to_dl_chunks[$i]); $j++) + { + if($apps_to_dl_chunks[$i][$j]['filesize'] != 0 && + $apps_to_dl_chunks[$i][$j]['filesize'] != filesize($apps_to_dl_chunks[$i][$j]['localtarget'])) + { + $app->log($this->log_prefix.' The filesize of the package "'. + $apps_to_dl_chunks[$i][$j]['name'].'" is wrong. Download failure?', LOGLEVEL_WARN); + } + } + } + + $app->log($this->log_prefix.'Processed '.$apps_in_repo. + ' apps from the repo. Downloaded '.$apps_updated. + ' updates, '.$apps_downloaded.' new apps'); + } + catch(Exception $e) + { + $app->log($this->log_prefix.$e->getMessage(), LOGLEVEL_ERROR); + return false; + } + } + + /** + * Read in all possible packages from the interface packages folder and + * check if they are not ASP.net code (as this can't be processed). + * + * Note: There's no need to check if the packages to register are newer + * than those in the database because this already happended in startCrawler() + */ + public function parseFolderToDB() + { + global $app; + + try + { + // This method must be used in interface mode + if(!$this->interface_mode) return false; + + $pkg_list = array(); + + // Read in every package having a correct filename + $temp_handle = @dir($this->interface_pkg_dir); + if(!$temp_handle) throw new Exception('The temp directory is not accessible'); + while($folder = $temp_handle->read()) + if(substr($folder, -8) == '.app.zip') $pkg_list[] = $folder; + $temp_handle->close(); + + // If no packages are available -> exception (because at this point there should exist packages) + if(empty($pkg_list)) throw new Exception('No packages to read in'); + + // Get registered packages and mark non-existant packages with an error code to omit the install + $existing_packages = array(); + $path_query = $app->db->queryAllRecords('SELECT path AS Path FROM aps_packages;'); + foreach($path_query as $path) $existing_packages[] = $path['Path']; + $diff = array_diff($existing_packages, $pkg_list); + foreach($diff as $todelete) { + /*$app->db->query("UPDATE aps_packages SET package_status = '".PACKAGE_ERROR_NOMETA."' + WHERE path = '".$app->db->quote($todelete)."';");*/ + $tmp = $app->db->queryOneRecord("SELECT id FROM aps_packages WHERE path = '".$app->db->quote($todelete)."';"); + $app->db->datalogUpdate('aps_packages', "package_status = ".PACKAGE_ERROR_NOMETA, 'id', $tmp['id']); + unset($tmp); + } + + // Register all new packages + $new_packages = array_diff($pkg_list, $existing_packages); + foreach($new_packages as $pkg) + { + // Load in meta file if existing and register its namespaces + $metafile = $this->interface_pkg_dir.'/'.$pkg.'/APP-META.xml'; + if(!file_exists($metafile)) + { + $app->log($this->log_prefix.'Cannot read metadata from '.$pkg, LOGLEVEL_ERROR); + continue; + } + + $metadata = file_get_contents($metafile); + $metadata = str_replace("xmlns=", "ns=", $metadata); + $sxe = new SimpleXMLElement($metadata); + $namespaces = $sxe->getDocNamespaces(true); + foreach($namespaces as $ns => $url) $sxe->registerXPathNamespace($ns, $url); + + // Insert the new package + $pkg_name = parent::getXPathValue($sxe, 'name'); + $pkg_category = parent::getXPathValue($sxe, '//category'); + $pkg_version = parent::getXPathValue($sxe, 'version'); + $pkg_release = parent::getXPathValue($sxe, 'release'); + //$pkg_url = $this->app_download_url_list[$pkg]; + $pkg_url = @file_get_contents($this->interface_pkg_dir.'/'.$pkg.'/PKG_URL'); + + /* + $app->db->query("INSERT INTO `aps_packages` + (`path`, `name`, `category`, `version`, `release`, `package_status`) VALUES + ('".$app->db->quote($pkg)."', '".$app->db->quote($pkg_name)."', + '".$app->db->quote($pkg_category)."', '".$app->db->quote($pkg_version)."', + ".$app->db->quote($pkg_release).", ".PACKAGE_ENABLED.");"); + */ + // Insert only if data is complete + if($pkg != '' && $pkg_name != '' && $pkg_category != '' && $pkg_version != '' && $pkg_release != '' && $pkg_url){ + $insert_data = "(`path`, `name`, `category`, `version`, `release`, `package_url`, `package_status`) VALUES + ('".$app->db->quote($pkg)."', '".$app->db->quote($pkg_name)."', + '".$app->db->quote($pkg_category)."', '".$app->db->quote($pkg_version)."', + ".$app->db->quote($pkg_release).", '".$app->db->quote($pkg_url)."', ".PACKAGE_ENABLED.");"; + + $app->db->datalogInsert('aps_packages', $insert_data, 'id'); + } else { + if(file_exists($this->interface_pkg_dir.'/'.$pkg)) $this->removeDirectory($this->interface_pkg_dir.'/'.$pkg); + } + } + } + catch(Exception $e) + { + $app->log($this->log_prefix.$e->getMessage(), LOGLEVEL_ERROR); + $app->error($e->getMessage()); + return false; + } + } + + /** + * Add missing package URLs to database + */ + public function fixURLs() + { + global $app; + + try + { + // This method must be used in interface mode + if(!$this->interface_mode) return false; + + $incomplete_pkgs = $app->db->queryAllRecords("SELECT * FROM aps_packages WHERE package_url = ''"); + if(is_array($incomplete_pkgs) && !empty($incomplete_pkgs)){ + foreach($incomplete_pkgs as $incomplete_pkg){ + $pkg_url = @file_get_contents($this->interface_pkg_dir.'/'.$incomplete_pkg['path'].'/PKG_URL'); + if($pkg_url != ''){ + $app->db->datalogUpdate('aps_packages', "package_url = '".$pkg_url."'", 'id', $incomplete_pkg['id']); + } + } + } + } + catch(Exception $e) + { + $app->log($this->log_prefix.$e->getMessage(), LOGLEVEL_ERROR); + $app->error($e->getMessage()); + return false; + } + } +} ?> \ No newline at end of file diff --git a/interface/lib/classes/aps_guicontroller.inc.php b/interface/lib/classes/aps_guicontroller.inc.php index 5d1c79fc493d11cf8298897d447ec06e695a48ae..1e106a1e14ea2575532e0a9e7b12c02907205999 100644 --- a/interface/lib/classes/aps_guicontroller.inc.php +++ b/interface/lib/classes/aps_guicontroller.inc.php @@ -1,845 +1,845 @@ -<?php -/* -Copyright (c) 2012, ISPConfig UG -Contributors: web wack creations, http://www.web-wack.at -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of ISPConfig nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -require_once('aps_base.inc.php'); - -class ApsGUIController extends ApsBase -{ - /** - * Constructor - * - * @param $app the application instance (db handle) - */ - public function __construct($app) - { - parent::__construct($app); - } - - /** - * Reads in a package metadata file and registers it's namespaces - * - * @param $filename the file to read - * @return $sxe a SimpleXMLElement handle - */ - private function readInMetaFile($filename) - { - $metadata = file_get_contents($filename); - $metadata = str_replace("xmlns=", "ns=", $metadata); - $sxe = new SimpleXMLElement($metadata); - $namespaces = $sxe->getDocNamespaces(true); - foreach($namespaces as $ns => $url) $sxe->registerXPathNamespace($ns, $url); - - return $sxe; - } - - /** - * Applies a RegEx pattern onto a location path in order to secure it against - * code injections and invalid input - * - * @param $location_unfiltered the file path to secure - * @return $location - */ - private function secureLocation($location_unfiltered) - { - // Filter invalid slashes from string - $location = preg_replace(array('#/+#', '#\.+#', '#\0+#', '#\\\\+#'), - array('/', '', '', '/'), - $location_unfiltered); - - // Remove a beginning or trailing slash - if(substr($location, -1) == '/') $location = substr($location, 0, strlen($location) - 1); - if(substr($location, 0, 1) == '/') $location = substr($location, 1); - - return $location; - } - - /** - * Gets the CustomerID (ClientID) which belongs to a specific domain - * - * @param $domain the domain - * @return $customerid - */ - private function getCustomerIDFromDomain($domain) - { - global $app; - $customerid = 0; - - $customerdata = $app->db->queryOneRecord("SELECT client_id FROM sys_group, web_domain - WHERE web_domain.sys_groupid = sys_group.groupid - AND web_domain.domain = '".$app->db->quote($domain)."';"); - if(!empty($customerdata)) $customerid = $customerdata['client_id']; - - return $customerid; - } - - /** - * Returns the server_id for an already installed instance. Is actually - * just a little helper method to avoid redundant code - * - * @param $instanceid the instance to process - * @return $webserver_id the server_id - */ - private function getInstanceDataForDatalog($instanceid) - { - global $app; - $webserver_id = ''; - - $websrv = $app->db->queryOneRecord("SELECT server_id FROM web_domain - WHERE domain = (SELECT value FROM aps_instances_settings - WHERE name = 'main_domain' AND instance_id = ".$app->db->quote($instanceid).");"); - - // If $websrv is empty, an error has occured. Domain no longer existing? Settings table damaged? - // Anyhow, remove this instance record because it's not useful at all - if(empty($websrv)) - { - $app->db->query("DELETE FROM aps_instances WHERE id = ".$app->db->quote($instanceid).";"); - $app->db->query("DELETE FROM aps_instances_settings WHERE instance_id = ".$app->db->quote($instanceid).";"); - } - else $webserver_id = $websrv['server_id']; - - return $webserver_id; - } - - /** - * Finds out if there is a newer package version for - * a given (possibly valid) package ID - * - * @param $id the ID to check - * @return $newer_pkg_id the newer package ID - */ - public function getNewestPackageID($id) - { - global $app; - - if(preg_match('/^[0-9]+$/', $id) != 1) return 0; - - $result = $app->db->queryOneRecord("SELECT id, name, - CONCAT(version, '-', CAST(`release` AS CHAR)) AS current_version - FROM aps_packages - WHERE name = (SELECT name FROM aps_packages WHERE id = ".$app->db->quote($id).") - ORDER BY REPLACE(version, '.', '')+0 DESC, `release` DESC"); - - if(!empty($result) && ($id != $result['id'])) return $result['id']; - - return 0; - } - - /** - * Validates a given package ID - * - * @param $id the ID to check - * @param $is_admin a flag to allow locked IDs too (for admin calls) - * @return boolean - */ - public function isValidPackageID($id, $is_admin = false) - { - global $app; - - if(preg_match('/^[0-9]+$/', $id) != 1) return false; - - $sql_ext = (!$is_admin) ? - 'package_status = '.PACKAGE_ENABLED.' AND' : - '(package_status = '.PACKAGE_ENABLED.' OR package_status = '.PACKAGE_LOCKED.') AND'; - - $result = $app->db->queryOneRecord("SELECT id FROM aps_packages WHERE ".$sql_ext." id = ".$app->db->quote($id).";"); - if(!$result) return false; - - return true; - } - - /** - * Validates a given instance ID - * - * @param $id the ID to check - * @param $client_id the calling client ID - * @param $is_admin a flag to ignore the client ID check for admins - * @return boolean - */ - public function isValidInstanceID($id, $client_id, $is_admin = false) - { - global $app; - - if(preg_match('/^[0-9]+$/', $id) != 1) return false; - - // Only filter if not admin - $sql_ext = (!$is_admin) ? 'customer_id = '.$app->db->quote($client_id).' AND' : ''; - - $result = $app->db->queryOneRecord('SELECT id FROM aps_instances WHERE '.$sql_ext.' id = '.$app->db->quote($id).';'); - if(!$result) return false; - - return true; - } - - /** - * Creates a new database record for the package instance and - * an install task - * - * @param $settings the settings to enter into the DB - * @param $packageid the PackageID - */ - public function createPackageInstance($settings, $packageid) - { - global $app; - - $app->uses('tools_sites'); - - $webserver_id = 0; - $websrv = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain = '".$app->db->quote($settings['main_domain'])."';"); - if(!empty($websrv)) $webserver_id = $websrv['server_id']; - $customerid = $this->getCustomerIDFromDomain($settings['main_domain']); - - if(empty($settings) || empty($webserver_id)) return false; - - //* Get server config of the web server - $app->uses("getconf"); - $web_config = $app->getconf->get_server_config($app->functions->intval($websrv["server_id"]),'web'); - - //* Set PHP mode to php-fcgi and enable suexec in website on apache servers / set PHP mode to PHP-FPM on nginx servers - if($web_config['server_type'] == 'apache') { - if(($websrv['php'] != 'fast-cgi' || $websrv['suexec'] != 'y') && $websrv['php'] != 'php-fpm') { - $app->db->datalogUpdate('web_domain', "php = 'fast-cgi', suexec = 'y'", 'domain_id', $websrv['domain_id']); - } - } else { - // nginx - if($websrv['php'] != 'php-fpm' && $websrv['php'] != 'fast-cgi') { - $app->db->datalogUpdate('web_domain', "php = 'php-fpm'", 'domain_id', $websrv['domain_id']); - } - } - - - //* Create the MySQL database for the application - $pkg = $app->db->queryOneRecord('SELECT * FROM aps_packages WHERE id = '.$app->db->quote($packageid).';'); - $metafile = $this->interface_pkg_dir.'/'.$pkg['path'].'/APP-META.xml'; - $sxe = $this->readInMetaFile($metafile); - - $db_id = parent::getXPathValue($sxe, '//db:id'); - if (!empty($db_id)) { - $global_config = $app->getconf->get_global_config('sites'); - - $tmp = array(); - $tmp['parent_domain_id'] = $websrv['domain_id']; - $tmp['sys_groupid'] = $websrv['sys_groupid']; - $dbname_prefix = $app->tools_sites->replacePrefix($global_config['dbname_prefix'], $tmp); - $dbuser_prefix = $app->tools_sites->replacePrefix($global_config['dbuser_prefix'], $tmp); - unset($tmp); - - // get information if the webserver is a db server, too - $web_server = $app->db->queryOneRecord("SELECT server_id,server_name,db_server FROM server WHERE server_id = ".$websrv['server_id']); - if($web_server['db_server'] == 1) { - // create database on "localhost" (webserver) - $mysql_db_server_id = $websrv['server_id']; - $mysql_db_host = 'localhost'; - $mysql_db_remote_access = 'n'; - $mysql_db_remote_ips = ''; - } else { - //* get the default database server of the client - $client = $app->db->queryOneRecord("SELECT default_dbserver FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = ".$websrv['sys_groupid']); - if(is_array($client) && $client['default_dbserver'] > 0 && $client['default_dbserver'] != $websrv['server_id']) { - $mysql_db_server_id = $client['default_dbserver']; - $dbserver_config = $web_config = $app->getconf->get_server_config($app->functions->intval($mysql_db_server_id),'server'); - $mysql_db_host = $dbserver_config['ip_address']; - $mysql_db_remote_access = 'y'; - $webserver_config = $app->getconf->get_server_config($app->functions->intval($websrv['server_id']),'server'); - $mysql_db_remote_ips = $webserver_config['ip_address']; - } else { - /* I left this in place for a fallback that should NEVER! happen. - * if we reach this point it means that there is NO default db server for the client - * AND the webserver has NO db service enabled. - * We have to abort the aps installation here... so I added a return false - * although this does not present any error message to the user. - */ - return false; - - /*$mysql_db_server_id = $websrv['server_id']; - $mysql_db_host = 'localhost'; - $mysql_db_remote_access = 'n'; - $mysql_db_remote_ips = '';*/ - } - } - - //* Find a free db name for the app - for($n = 1; $n <= 1000; $n++) { - $mysql_db_name = ($dbname_prefix != '' ? $dbname_prefix.'aps'.$n : uniqid('aps')); - $tmp = $app->db->queryOneRecord("SELECT count(database_id) as number FROM web_database WHERE database_name = '".$app->db->quote($mysql_db_name)."'"); - if($tmp['number'] == 0) break; - } - //* Find a free db username for the app - for($n = 1; $n <= 1000; $n++) { - $mysql_db_user = ($dbuser_prefix != '' ? $dbuser_prefix.'aps'.$n : uniqid('aps')); - $tmp = $app->db->queryOneRecord("SELECT count(database_user_id) as number FROM web_database_user WHERE database_user = '".$app->db->quote($mysql_db_user)."'"); - if($tmp['number'] == 0) break; - } - - $mysql_db_password = $settings['main_database_password']; - - //* Create the mysql database user - $insert_data = "(`sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `server_id`, `database_user`, `database_user_prefix`, `database_password`) - VALUES( ".$websrv['sys_userid'].", ".$websrv['sys_groupid'].", 'riud', '".$websrv['sys_perm_group']."', '', 0, '$mysql_db_user', '".$app->db->quote($dbuser_prefix) . "', PASSWORD('$mysql_db_password'))"; - $mysql_db_user_id = $app->db->datalogInsert('web_database_user', $insert_data, 'database_user_id'); - - //* Create the mysql database - $insert_data = "(`sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `server_id`, `parent_domain_id`, `type`, `database_name`, `database_name_prefix`, `database_user_id`, `database_ro_user_id`, `database_charset`, `remote_access`, `remote_ips`, `backup_copies`, `active`, `backup_interval`) - VALUES( ".$websrv['sys_userid'].", ".$websrv['sys_groupid'].", 'riud', '".$websrv['sys_perm_group']."', '', $mysql_db_server_id, ".$websrv['domain_id'].", 'mysql', '$mysql_db_name', '" . $app->db->quote($dbname_prefix) . "', '$mysql_db_user_id', 0, '', '$mysql_db_remote_access', '$mysql_db_remote_ips', ".$websrv['backup_copies'].", 'y', '".$websrv['backup_interval']."')"; - $app->db->datalogInsert('web_database', $insert_data, 'database_id'); - - //* Add db details to package settings - $settings['main_database_host'] = $mysql_db_host; - $settings['main_database_name'] = $mysql_db_name; - $settings['main_database_login'] = $mysql_db_user; - - } - - //* Insert new package instance - $insert_data = "(`sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `server_id`, `customer_id`, `package_id`, `instance_status`) VALUES (".$websrv['sys_userid'].", ".$websrv['sys_groupid'].", 'riud', '".$websrv['sys_perm_group']."', '', ".$app->db->quote($webserver_id).",".$app->db->quote($customerid).", ".$app->db->quote($packageid).", ".INSTANCE_PENDING.")"; - $InstanceID = $app->db->datalogInsert('aps_instances', $insert_data, 'id'); - - //* Insert all package settings - if(is_array($settings)) { - foreach($settings as $key => $value) { - $insert_data = "(server_id, instance_id, name, value) VALUES (".$app->db->quote($webserver_id).",".$app->db->quote($InstanceID).", '".$app->db->quote($key)."', '".$app->db->quote($value)."')"; - $app->db->datalogInsert('aps_instances_settings', $insert_data, 'id'); - } - } - - //* Set package status to install afetr we inserted the settings - $app->db->datalogUpdate('aps_instances', "instance_status = ".INSTANCE_INSTALL, 'id', $InstanceID); - } - - /** - * Sets the status of an instance to "should be removed" and creates a - * datalog entry to give the ISPConfig server a real removal advice - * - * @param $instanceid the instance to delete - */ - public function deleteInstance($instanceid) - { - global $app; - /* - $app->db->query("UPDATE aps_instances SET instance_status = ".INSTANCE_REMOVE." WHERE id = ".$instanceid.";"); - - $webserver_id = $this->getInstanceDataForDatalog($instanceid); - if($webserver_id == '') return; - - // Create a sys_datalog entry for deletion - $datalog = array('Instance_id' => $instanceid, 'server_id' => $webserver_id); - $app->db->datalogSave('aps', 'DELETE', 'id', $instanceid, array(), $datalog); - */ - - $sql = "SELECT web_database.database_id as database_id, web_database.database_user_id as `database_user_id` FROM aps_instances_settings, web_database WHERE aps_instances_settings.value = web_database.database_name AND aps_instances_settings.name = 'main_database_name' AND aps_instances_settings.instance_id = ".$instanceid." LIMIT 0,1"; - $tmp = $app->db->queryOneRecord($sql); - if($tmp['database_id'] > 0) $app->db->datalogDelete('web_database', 'database_id', $tmp['database_id']); - - $database_user = $tmp['database_user_id']; - $tmp = $app->db->queryOneRecord("SELECT COUNT(*) as `cnt` FROM `web_database` WHERE `database_user_id` = '" . $app->functions->intval($database_user) . "' OR `database_ro_user_id` = '" . $app->functions->intval($database_user) . "'"); - if($tmp['cnt'] < 1) $app->db->datalogDelete('web_database_user', 'database_user_id', $database_user); - - $app->db->datalogUpdate('aps_instances', "instance_status = ".INSTANCE_REMOVE, 'id', $instanceid); - - } - - /** - * Sets the status of an instance to "installation planned" and creates a - * datalog entry to re-install the package. The existing package is simply overwritten. - * - * @param $instanceid the instance to delete - */ - public function reinstallInstance($instanceid) - { - global $app; - - /* - $app->db->query("UPDATE aps_instances SET instance_status = ".INSTANCE_INSTALL." WHERE id = ".$instanceid.";"); - - $webserver_id = $this->getInstanceDataForDatalog($instanceid); - if($webserver_id == '') return; - - // Create a sys_datalog entry for re-installation - $datalog = array('instance_id' => $instanceid, 'server_id' => $webserver_id); - $app->db->datalogSave('aps', 'INSERT', 'id', $instanceid, array(), $datalog); - */ - - $sql = "SELECT web_database.database_id as database_id FROM aps_instances_settings, web_database WHERE aps_instances_settings.value = web_database.database_name AND aps_instances_settings.value = aps_instances_settings.name = 'main_database_name' AND aps_instances_settings.instance_id = ".$instanceid." LIMIT 0,1"; - $tmp = $app->db->queryOneRecord($sql); - if($tmp['database_id'] > 0) $app->db->datalogDelete('web_database', 'database_id', $tmp['database_id']); - - $app->db->datalogUpdate('aps_instances', "instance_status = ".INSTANCE_INSTALL, 'id', $instanceid); - } - - /** - * Read the settings to be filled when installing - * - * @param $id the internal ID of the package - * @return array - */ - public function getPackageSettings($id) - { - global $app; - - $pkg = $app->db->queryOneRecord('SELECT * FROM aps_packages WHERE id = '.$app->db->quote($id).';'); - - // Load in meta file if existing and register its namespaces - $metafile = $this->interface_pkg_dir.'/'.$pkg['path'].'/APP-META.xml'; - if(!file_exists($metafile)) - return array('error' => 'The metafile for '.$settings['Name'].' couldn\'t be found'); - - $sxe = $this->readInMetaFile($metafile); - - $groupsettings = parent::getXPathValue($sxe, '//settings/group/setting', true); - if(empty($groupsettings)) return array(); - - $settings = array(); - foreach($groupsettings as $setting) - { - $setting_id = strval($setting['id']); - - if($setting['type'] == 'string' || $setting['type'] == 'email' || $setting['type'] == 'integer' - || $setting['type'] == 'float' || $setting['type'] == 'domain-name') - { - $settings[] = array('SettingID' => $setting_id, - 'SettingName' => $setting->name, - 'SettingDescription' => $setting->description, - 'SettingType' => $setting['type'], - 'SettingInputType' => 'string', - 'SettingDefaultValue' => strval($setting['default-value']), - 'SettingRegex' => $setting['regex'], - 'SettingMinLength' => $setting['min-length'], - 'SettingMaxLength' => $setting['max-length']); - } - else if($setting['type'] == 'password') - { - $settings[] = array('SettingID' => $setting_id, - 'SettingName' => $setting->name, - 'SettingDescription' => $setting->description, - 'SettingType' => 'password', - 'SettingInputType' => 'password', - 'SettingDefaultValue' => '', - 'SettingRegex' => $setting['regex'], - 'SettingMinLength' => $setting['min-length'], - 'SettingMaxLength' => $setting['max-length']); - } - else if($setting['type'] == 'boolean') - { - $settings[] = array('SettingID' => $setting_id, - 'SettingName' => $setting->name, - 'SettingDescription' => $setting->description, - 'SettingType' => 'boolean', - 'SettingInputType' => 'checkbox', - 'SettingDefaultValue' => strval($setting['default-value'])); - } - else if($setting['type'] == 'enum') - { - $choices = array(); - foreach($setting->choice as $choice) - { - $choices[] = array('EnumID' => strval($choice['id']), - 'EnumName' => $choice->name); - } - $settings[] = array('SettingID' => $setting_id, - 'SettingName' => $setting->name, - 'SettingDescription' => $setting->description, - 'SettingType' => 'enum', - 'SettingInputType' => 'select', - 'SettingDefaultValue' => strval($setting['default-value']), - 'SettingChoices' => $choices); - } - } - - return $settings; - } - - /** - * Validates the user input according to the settings array and - * delivers errors if occurring - * - * @param $input the user $_POST array - * @param $pkg_details the package details - * @param $settings the package settings array - * @return array in this structure: - * array(2) { - * ["input"]=> ... - * ["errors"]=> ... - * } - */ - public function validateInstallerInput($postinput, $pkg_details, $domains, $settings = array()) - { - global $app; - - $ret = array(); - $input = array(); - $error = array(); - - // Main domain (obligatory) - if(isset($postinput['main_domain'])) - { - if(!in_array($postinput['main_domain'], $domains)) $error[] = $app->lng('error_main_domain'); - else $input['main_domain'] = $postinput['main_domain']; - } - else $error[] = $app->lng('error_main_domain'); - - // Main location (not obligatory but must be supplied) - if(isset($postinput['main_location'])) - { - $temp_errstr = ''; - // It can be empty but if the user did write something, check it - $userinput = false; - if(strlen($postinput['main_location']) > 0) $userinput = true; - - // Filter invalid input slashes (twice!) - $main_location = $this->secureLocation($postinput['main_location']); - $main_location = $this->secureLocation($main_location); - // Only allow digits, words, / and - - $main_location = preg_replace("/[^\d\w\/\-]/i", "", $main_location); - if($userinput && (strlen($main_location) == 0)) $temp_errstr = $app->lng('error_inv_main_location'); - - // Find out document_root and make sure no apps are installed twice to one location - if(in_array($postinput['main_domain'], $domains)) - { - $docroot = $app->db->queryOneRecord("SELECT document_root FROM web_domain - WHERE domain = '".$app->db->quote($postinput['main_domain'])."';"); - $new_path = $docroot['document_root']; - if(substr($new_path, -1) != '/') $new_path .= '/'; - $new_path .= $main_location; - - // Get the $customerid which belongs to the selected domain - $customerid = $this->getCustomerIDFromDomain($postinput['main_domain']); - - // First get all domains used for an install, then their loop them - // and get the corresponding document roots as well as the defined - // locations. If an existing doc_root + location matches with the - // new one -> error - $instance_domains = $app->db->queryAllRecords("SELECT instance_id, s.value AS domain - FROM aps_instances AS i, aps_instances_settings AS s - WHERE i.id = s.instance_id AND s.name = 'main_domain' - AND i.customer_id = '".$app->db->quote($customerid)."';"); - for($i = 0; $i < count($instance_domains); $i++) - { - $used_path = ''; - - $doc_root = $app->db->queryOneRecord("SELECT document_root FROM web_domain - WHERE domain = '".$app->db->quote($instance_domains[$i]['domain'])."';"); - - // Probably the domain settings were changed later, so make sure the doc_root - // is not empty for further validation - if(!empty($doc_root)) - { - $used_path = $doc_root['document_root']; - if(substr($used_path, -1) != '/') $used_path .= '/'; - - $location_for_domain = $app->db->queryOneRecord("SELECT value - FROM aps_instances_settings WHERE name = 'main_location' - AND instance_id = '".$app->db->quote($instance_domains[$i]['instance_id'])."';"); - - // The location might be empty but the DB return must not be false! - if($location_for_domain) $used_path .= $location_for_domain['value']; - - if($new_path == $used_path) - { - $temp_errstr = $app->lng('error_used_location'); - break; - } - } - } - } - else $temp_errstr = $app->lng('error_main_domain'); - - if($temp_errstr == '') $input['main_location'] = htmlspecialchars($main_location); - else $error[] = $temp_errstr; - } - else $error[] = $app->lng('error_no_main_location'); - - // License (the checkbox must be set) - if(isset($pkg_details['License need agree']) - && $pkg_details['License need agree'] == 'true') - { - if(isset($postinput['license']) && $postinput['license'] == 'on') $input['license'] = 'true'; - else $error[] = $app->lng('error_license_agreement'); - } - - // Database - if(isset($pkg_details['Requirements Database']) - && $pkg_details['Requirements Database'] != '') - { - if(isset($postinput['main_database_password'])) - { - if($postinput['main_database_password'] == '') $error[] = $app->lng('error_no_database_pw'); - else if(strlen($postinput['main_database_password']) > 8) - $input['main_database_password'] = htmlspecialchars($postinput['main_database_password']); - else $error[] = $app->lng('error_short_database_pw'); - } - else $error[] = $app->lng('error_no_database_pw'); - } - - // Validate the package settings - foreach($settings as $setting) - { - $temp_errstr = ''; - $setting_id = strval($setting['SettingID']); - - // We assume that every setting must be set - if((isset($postinput[$setting_id]) && ($postinput[$setting_id] != '')) - || ($setting['SettingType'] == 'boolean')) - { - if($setting['SettingType'] == 'string' || $setting['SettingType'] == 'password') - { - if($app->functions->intval($setting['SettingMinLength'], true) != 0 - && strlen($postinput[$setting_id]) < $app->functions->intval($setting['SettingMinLength'], true)) - $temp_errstr = sprintf($app->lng('error_short_value_for'), $setting['setting_name']); - - if($app->functions->intval($setting['SettingMaxLength'], true) != 0 - && strlen($postinput[$setting_id]) > $app->functions->intval($setting['SettingMaxLength'], true)) - $temp_errstr = sprintf($app->lng('error_long_value_for'), $setting['setting_name']); - - if(isset($setting['SettingRegex']) - && !preg_match("/".$setting['SettingRegex']."/", $postinput[$setting_id])) - $temp_errstr = sprintf($app->lng('error_inv_value_for'), $setting['setting_name']); - } - else if($setting['SettingType'] == 'email') - { - if(filter_var(strtolower($postinput[$setting_id]), FILTER_VALIDATE_EMAIL) === false) - $temp_errstr = sprintf($app->lng('error_inv_email_for'), $setting['setting_name']); - } - else if($setting['SettingType'] == 'domain-name') - { - if(!preg_match("^(http|https)\://([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&%\$\-]+)*@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|localhost|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(\:[0-9]+)*(/($|[a-zA-Z0-9\.\,\?\'\\\+&%\$#\=~_\-]+))*$", - $postinput[$setting_id])) - $temp_errstr = sprintf($app->lng('error_inv_domain_for'), $setting['setting_name']); - } - else if($setting['SettingType'] == 'integer') - { - if(filter_var($postinput[$setting_id], FILTER_VALIDATE_INT) === false) - $temp_errstr = sprintf($app->lng('error_inv_integer_for'), $setting['setting_name']); - } - else if($setting['SettingType'] == 'float') - { - if(filter_var($postinput[$setting_id], FILTER_VALIDATE_FLOAT) === false) - $temp_errstr = sprintf($app->lng('error_inv_float_for'), $setting['setting_name']); - } - else if($setting['SettingType'] == 'boolean') - { - // If we have a boolean value set, it must be either true or false - if(!isset($postinput[$setting_id])) $postinput[$setting_id] = 'false'; - else if(isset($postinput[$setting_id]) && $postinput[$setting_id] != 'true') - $postinput[$setting_id] = 'true'; - } - else if($setting['SettingType'] == 'enum') - { - $found = false; - for($i = 0; $i < count($setting['SettingChoices']); $i++) - { - if($setting['SettingChoices'][$i]['EnumID'] == $postinput[$setting_id]) - $found = true; - } - if(!$found) $temp_errstr = sprintf($app->lng('error_inv_value_for'), $setting['SettingName']); - } - - if($temp_errstr == '') $input[$setting_id] = $postinput[$setting_id]; - else $error[] = $temp_errstr; - } - else $error[] = sprintf($app->lng('error_no_value_for'), $setting['SettingName']); - } - - $ret['input'] = $input; - $ret['error'] = array_unique($error); - - return $ret; - } - - /** - * Read the metadata of a package and returns some content - * - * @param $id the internal ID of the package - * @return array - */ - public function getPackageDetails($id) - { - global $app; - - $pkg = $app->db->queryOneRecord('SELECT * FROM aps_packages WHERE id = '.$app->db->quote($id).';'); - - // Load in meta file if existing and register its namespaces - $metafile = $this->interface_pkg_dir.'/'.$pkg['path'].'/APP-META.xml'; - if(!file_exists($metafile)) - return array('error' => 'The metafile for '.$pkg['name'].' couldn\'t be found'); - - $metadata = file_get_contents($metafile); - $metadata = str_replace("xmlns=", "ns=", $metadata); - $sxe = new SimpleXMLElement($metadata); - $namespaces = $sxe->getDocNamespaces(true); - foreach($namespaces as $ns => $url) $sxe->registerXPathNamespace($ns, $url); - - $pkg['Summary'] = htmlspecialchars(parent::getXPathValue($sxe, '//summary')); - $pkg['Homepage'] = parent::getXPathValue($sxe, '//homepage'); - $pkg['Description'] = nl2br(htmlspecialchars(trim(parent::getXPathValue($sxe, '//description')))); - $pkg['Config script'] = strtoupper(parent::getXPathValue($sxe, '//configuration-script-language')); - $installed_size = parent::getXPathValue($sxe, '//installed-size'); - $pkg['Installed Size'] = (!empty($installed_size)) ? parent::convertSize((int)$installed_size) : ''; - - // License - $pkg['License need agree'] = parent::getXPathValue($sxe, '//license/@must-accept'); - $pkg['License name'] = parent::getXPathValue($sxe, '//license/text/name'); // might be empty - $pkg['License type'] = 'file'; // default type - $pkg['License content'] = ''; // default license filename on local system - $license_url = parent::getXPathValue($sxe, '//license/text/url'); - if(!empty($license_url)) - { - $pkg['License type'] = 'url'; - $pkg['License content'] = htmlspecialchars($license_url); - } - else - { - $lic = @file_get_contents($this->interface_pkg_dir.'/'.$pkg['path'].'/LICENSE'); - $pkg['License content'] = htmlentities($lic, ENT_QUOTES, 'ISO-8859-1'); - } - - // Languages - $languages = parent::getXPathValue($sxe, '//languages/language', true); - $pkg['Languages'] = (is_array($languages)) ? implode(' ', $languages) : ''; - - // Icon - $icon = parent::getXPathValue($sxe, '//icon/@path'); - if(!empty($icon)) - { - // Using parse_url() to filter malformed URLs - $path = dirname(parse_url($_SERVER['PHP_SELF'], PHP_URL_PATH)).'/'. - basename($this->interface_pkg_dir).'/'.$pkg['path'].'/'.basename((string)$icon); - // nginx: if $_SERVER['PHP_SELF'] is doubled, remove /sites/aps_packagedetails_show.php from beginning of path - $path = preg_replace('@^/sites/aps_packagedetails_show.php(.*)@', '$1', $path); - $pkg['Icon'] = $path; - } - else $pkg['Icon'] = ''; - - // Screenshots - $screenshots = parent::getXPathValue($sxe, '//screenshot', true); - if(!empty($screenshots)) - { - foreach($screenshots as $screen) - { - // Using parse_url() to filter malformed URLs - $path = dirname(parse_url($_SERVER['PHP_SELF'], PHP_URL_PATH)).'/'. - basename($this->interface_pkg_dir).'/'.$pkg['path'].'/'.basename((string)$screen['path']); - // nginx: if $_SERVER['PHP_SELF'] is doubled, remove /sites/aps_packagedetails_show.php from beginning of path - $path = preg_replace('@^/sites/aps_packagedetails_show.php(.*)@', '$1', $path); - - $pkg['Screenshots'][] = array('ScreenPath' => $path, - 'ScreenDescription' => htmlspecialchars(trim((string)$screen->description))); - } - } - else $pkg['Screenshots'] = ''; // if no screenshots are available, set the variable though - - // Changelog - $changelog = parent::getXPathValue($sxe, '//changelog/version', true); - if(!empty($changelog)) - { - foreach($changelog as $change) - { - $entries = array(); - foreach($change->entry as $entry) $entries[] = htmlspecialchars(trim((string)$entry)); - - $pkg['Changelog'][] = array('ChangelogVersion' => (string)$change['version'], - 'ChangelogDescription' => implode('<br />', $entries)); - } - } - - else $pkg['Changelog'] = ''; - - // PHP extensions - $php_extensions = parent::getXPathValue($sxe, '//php:extension', true); - $php_ext = ''; - if(!empty($php_extensions)) - { - foreach($php_extensions as $extension) - { - if(strtolower($extension) == 'php') continue; - $php_ext .= $extension.' '; - } - } - $pkg['Requirements PHP extensions'] = trim($php_ext); - - // PHP bool options - $pkg['Requirements PHP settings'] = ''; - $php_bool_options = array('allow-url-fopen', 'file-uploads', 'magic-quotes-gpc', - 'register-globals', 'safe-mode', 'short-open-tag'); - foreach($php_bool_options as $option) - { - $value = parent::getXPathValue($sxe, '//php:'.$option); - if(!empty($value)) - { - $option = str_replace('-', '_', $option); - $value = str_replace(array('false', 'true'), array('off', 'on'), $value); - $pkg['Requirements PHP settings'][] = array('PHPSettingName' => $option, - 'PHPSettingValue' => $value); - } - } - - // PHP integer value settings - $memory_limit = parent::getXPathValue($sxe, '//php:memory-limit'); - if(!empty($memory_limit)) - $pkg['Requirements PHP settings'][] = array('PHPSettingName' => 'memory_limit', - 'PHPSettingValue' => parent::convertSize((int)$memory_limit)); - - $max_exec_time = parent::getXPathValue($sxe, '//php:max-execution-time'); - if(!empty($max_exec_time)) - $pkg['Requirements PHP settings'][] = array('PHPSettingName' => 'max-execution-time', - 'PHPSettingValue' => $max_exec_time); - - $post_max_size = parent::getXPathValue($sxe, '//php:post-max-size'); - if(!empty($post_max_size)) - $pkg['Requirements PHP settings'][] = array('PHPSettingName' => 'post_max_size', - 'PHPSettingValue' => parent::convertSize((int)$post_max_size)); - - // Get supported PHP versions - $pkg['Requirements Supported PHP versions'] = ''; - $php_min_version = parent::getXPathValue($sxe, '//php:version/@min'); - $php_max_not_including = parent::getXPathValue($sxe, '//php:version/@max-not-including'); - if(!empty($php_min_version) && !empty($php_max_not_including)) - $pkg['Requirements Supported PHP versions'] = $php_min_version.' - '.$php_max_not_including; - else if(!empty($php_min_version)) - $pkg['Requirements Supported PHP versions'] = '> '.$php_min_version; - else if(!empty($php_max_not_including)) - $pkg['Requirements Supported PHP versions'] = '< '.$php_min_version; - - // Database - $db_id = parent::getXPathValue($sxe, '//db:id'); - $db_server_type = parent::getXPathValue($sxe, '//db:server-type'); - $db_min_version = parent::getXPathValue($sxe, '//db:server-min-version'); - if(!empty($db_id)) - { - $db_server_type = str_replace('postgresql', 'PostgreSQL', $db_server_type); - $db_server_type = str_replace('microsoft:sqlserver', 'MSSQL', $db_server_type); - $db_server_type = str_replace('mysql', 'MySQL', $db_server_type); - - $pkg['Requirements Database'] = $db_server_type; - if(!empty($db_min_version)) $pkg['Requirements Database'] .= ' > '.$db_min_version; - } - else $pkg['Requirements Database'] = ''; - - return $pkg; - } -} +<?php +/* +Copyright (c) 2012, ISPConfig UG +Contributors: web wack creations, http://www.web-wack.at +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of ISPConfig nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +require_once('aps_base.inc.php'); + +class ApsGUIController extends ApsBase +{ + /** + * Constructor + * + * @param $app the application instance (db handle) + */ + public function __construct($app) + { + parent::__construct($app); + } + + /** + * Reads in a package metadata file and registers it's namespaces + * + * @param $filename the file to read + * @return $sxe a SimpleXMLElement handle + */ + private function readInMetaFile($filename) + { + $metadata = file_get_contents($filename); + $metadata = str_replace("xmlns=", "ns=", $metadata); + $sxe = new SimpleXMLElement($metadata); + $namespaces = $sxe->getDocNamespaces(true); + foreach($namespaces as $ns => $url) $sxe->registerXPathNamespace($ns, $url); + + return $sxe; + } + + /** + * Applies a RegEx pattern onto a location path in order to secure it against + * code injections and invalid input + * + * @param $location_unfiltered the file path to secure + * @return $location + */ + private function secureLocation($location_unfiltered) + { + // Filter invalid slashes from string + $location = preg_replace(array('#/+#', '#\.+#', '#\0+#', '#\\\\+#'), + array('/', '', '', '/'), + $location_unfiltered); + + // Remove a beginning or trailing slash + if(substr($location, -1) == '/') $location = substr($location, 0, strlen($location) - 1); + if(substr($location, 0, 1) == '/') $location = substr($location, 1); + + return $location; + } + + /** + * Gets the CustomerID (ClientID) which belongs to a specific domain + * + * @param $domain the domain + * @return $customerid + */ + private function getCustomerIDFromDomain($domain) + { + global $app; + $customerid = 0; + + $customerdata = $app->db->queryOneRecord("SELECT client_id FROM sys_group, web_domain + WHERE web_domain.sys_groupid = sys_group.groupid + AND web_domain.domain = '".$app->db->quote($domain)."';"); + if(!empty($customerdata)) $customerid = $customerdata['client_id']; + + return $customerid; + } + + /** + * Returns the server_id for an already installed instance. Is actually + * just a little helper method to avoid redundant code + * + * @param $instanceid the instance to process + * @return $webserver_id the server_id + */ + private function getInstanceDataForDatalog($instanceid) + { + global $app; + $webserver_id = ''; + + $websrv = $app->db->queryOneRecord("SELECT server_id FROM web_domain + WHERE domain = (SELECT value FROM aps_instances_settings + WHERE name = 'main_domain' AND instance_id = ".$app->db->quote($instanceid).");"); + + // If $websrv is empty, an error has occured. Domain no longer existing? Settings table damaged? + // Anyhow, remove this instance record because it's not useful at all + if(empty($websrv)) + { + $app->db->query("DELETE FROM aps_instances WHERE id = ".$app->db->quote($instanceid).";"); + $app->db->query("DELETE FROM aps_instances_settings WHERE instance_id = ".$app->db->quote($instanceid).";"); + } + else $webserver_id = $websrv['server_id']; + + return $webserver_id; + } + + /** + * Finds out if there is a newer package version for + * a given (possibly valid) package ID + * + * @param $id the ID to check + * @return $newer_pkg_id the newer package ID + */ + public function getNewestPackageID($id) + { + global $app; + + if(preg_match('/^[0-9]+$/', $id) != 1) return 0; + + $result = $app->db->queryOneRecord("SELECT id, name, + CONCAT(version, '-', CAST(`release` AS CHAR)) AS current_version + FROM aps_packages + WHERE name = (SELECT name FROM aps_packages WHERE id = ".$app->db->quote($id).") + ORDER BY REPLACE(version, '.', '')+0 DESC, `release` DESC"); + + if(!empty($result) && ($id != $result['id'])) return $result['id']; + + return 0; + } + + /** + * Validates a given package ID + * + * @param $id the ID to check + * @param $is_admin a flag to allow locked IDs too (for admin calls) + * @return boolean + */ + public function isValidPackageID($id, $is_admin = false) + { + global $app; + + if(preg_match('/^[0-9]+$/', $id) != 1) return false; + + $sql_ext = (!$is_admin) ? + 'package_status = '.PACKAGE_ENABLED.' AND' : + '(package_status = '.PACKAGE_ENABLED.' OR package_status = '.PACKAGE_LOCKED.') AND'; + + $result = $app->db->queryOneRecord("SELECT id FROM aps_packages WHERE ".$sql_ext." id = ".$app->db->quote($id).";"); + if(!$result) return false; + + return true; + } + + /** + * Validates a given instance ID + * + * @param $id the ID to check + * @param $client_id the calling client ID + * @param $is_admin a flag to ignore the client ID check for admins + * @return boolean + */ + public function isValidInstanceID($id, $client_id, $is_admin = false) + { + global $app; + + if(preg_match('/^[0-9]+$/', $id) != 1) return false; + + // Only filter if not admin + $sql_ext = (!$is_admin) ? 'customer_id = '.$app->db->quote($client_id).' AND' : ''; + + $result = $app->db->queryOneRecord('SELECT id FROM aps_instances WHERE '.$sql_ext.' id = '.$app->db->quote($id).';'); + if(!$result) return false; + + return true; + } + + /** + * Creates a new database record for the package instance and + * an install task + * + * @param $settings the settings to enter into the DB + * @param $packageid the PackageID + */ + public function createPackageInstance($settings, $packageid) + { + global $app; + + $app->uses('tools_sites'); + + $webserver_id = 0; + $websrv = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain = '".$app->db->quote($settings['main_domain'])."';"); + if(!empty($websrv)) $webserver_id = $websrv['server_id']; + $customerid = $this->getCustomerIDFromDomain($settings['main_domain']); + + if(empty($settings) || empty($webserver_id)) return false; + + //* Get server config of the web server + $app->uses("getconf"); + $web_config = $app->getconf->get_server_config($app->functions->intval($websrv["server_id"]),'web'); + + //* Set PHP mode to php-fcgi and enable suexec in website on apache servers / set PHP mode to PHP-FPM on nginx servers + if($web_config['server_type'] == 'apache') { + if(($websrv['php'] != 'fast-cgi' || $websrv['suexec'] != 'y') && $websrv['php'] != 'php-fpm') { + $app->db->datalogUpdate('web_domain', "php = 'fast-cgi', suexec = 'y'", 'domain_id', $websrv['domain_id']); + } + } else { + // nginx + if($websrv['php'] != 'php-fpm' && $websrv['php'] != 'fast-cgi') { + $app->db->datalogUpdate('web_domain', "php = 'php-fpm'", 'domain_id', $websrv['domain_id']); + } + } + + + //* Create the MySQL database for the application + $pkg = $app->db->queryOneRecord('SELECT * FROM aps_packages WHERE id = '.$app->db->quote($packageid).';'); + $metafile = $this->interface_pkg_dir.'/'.$pkg['path'].'/APP-META.xml'; + $sxe = $this->readInMetaFile($metafile); + + $db_id = parent::getXPathValue($sxe, '//db:id'); + if (!empty($db_id)) { + $global_config = $app->getconf->get_global_config('sites'); + + $tmp = array(); + $tmp['parent_domain_id'] = $websrv['domain_id']; + $tmp['sys_groupid'] = $websrv['sys_groupid']; + $dbname_prefix = $app->tools_sites->replacePrefix($global_config['dbname_prefix'], $tmp); + $dbuser_prefix = $app->tools_sites->replacePrefix($global_config['dbuser_prefix'], $tmp); + unset($tmp); + + // get information if the webserver is a db server, too + $web_server = $app->db->queryOneRecord("SELECT server_id,server_name,db_server FROM server WHERE server_id = ".$websrv['server_id']); + if($web_server['db_server'] == 1) { + // create database on "localhost" (webserver) + $mysql_db_server_id = $websrv['server_id']; + $mysql_db_host = 'localhost'; + $mysql_db_remote_access = 'n'; + $mysql_db_remote_ips = ''; + } else { + //* get the default database server of the client + $client = $app->db->queryOneRecord("SELECT default_dbserver FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = ".$websrv['sys_groupid']); + if(is_array($client) && $client['default_dbserver'] > 0 && $client['default_dbserver'] != $websrv['server_id']) { + $mysql_db_server_id = $client['default_dbserver']; + $dbserver_config = $web_config = $app->getconf->get_server_config($app->functions->intval($mysql_db_server_id),'server'); + $mysql_db_host = $dbserver_config['ip_address']; + $mysql_db_remote_access = 'y'; + $webserver_config = $app->getconf->get_server_config($app->functions->intval($websrv['server_id']),'server'); + $mysql_db_remote_ips = $webserver_config['ip_address']; + } else { + /* I left this in place for a fallback that should NEVER! happen. + * if we reach this point it means that there is NO default db server for the client + * AND the webserver has NO db service enabled. + * We have to abort the aps installation here... so I added a return false + * although this does not present any error message to the user. + */ + return false; + + /*$mysql_db_server_id = $websrv['server_id']; + $mysql_db_host = 'localhost'; + $mysql_db_remote_access = 'n'; + $mysql_db_remote_ips = '';*/ + } + } + + //* Find a free db name for the app + for($n = 1; $n <= 1000; $n++) { + $mysql_db_name = ($dbname_prefix != '' ? $dbname_prefix.'aps'.$n : uniqid('aps')); + $tmp = $app->db->queryOneRecord("SELECT count(database_id) as number FROM web_database WHERE database_name = '".$app->db->quote($mysql_db_name)."'"); + if($tmp['number'] == 0) break; + } + //* Find a free db username for the app + for($n = 1; $n <= 1000; $n++) { + $mysql_db_user = ($dbuser_prefix != '' ? $dbuser_prefix.'aps'.$n : uniqid('aps')); + $tmp = $app->db->queryOneRecord("SELECT count(database_user_id) as number FROM web_database_user WHERE database_user = '".$app->db->quote($mysql_db_user)."'"); + if($tmp['number'] == 0) break; + } + + $mysql_db_password = $settings['main_database_password']; + + //* Create the mysql database user + $insert_data = "(`sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `server_id`, `database_user`, `database_user_prefix`, `database_password`) + VALUES( ".$websrv['sys_userid'].", ".$websrv['sys_groupid'].", 'riud', '".$websrv['sys_perm_group']."', '', 0, '$mysql_db_user', '".$app->db->quote($dbuser_prefix) . "', PASSWORD('$mysql_db_password'))"; + $mysql_db_user_id = $app->db->datalogInsert('web_database_user', $insert_data, 'database_user_id'); + + //* Create the mysql database + $insert_data = "(`sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `server_id`, `parent_domain_id`, `type`, `database_name`, `database_name_prefix`, `database_user_id`, `database_ro_user_id`, `database_charset`, `remote_access`, `remote_ips`, `backup_copies`, `active`, `backup_interval`) + VALUES( ".$websrv['sys_userid'].", ".$websrv['sys_groupid'].", 'riud', '".$websrv['sys_perm_group']."', '', $mysql_db_server_id, ".$websrv['domain_id'].", 'mysql', '$mysql_db_name', '" . $app->db->quote($dbname_prefix) . "', '$mysql_db_user_id', 0, '', '$mysql_db_remote_access', '$mysql_db_remote_ips', ".$websrv['backup_copies'].", 'y', '".$websrv['backup_interval']."')"; + $app->db->datalogInsert('web_database', $insert_data, 'database_id'); + + //* Add db details to package settings + $settings['main_database_host'] = $mysql_db_host; + $settings['main_database_name'] = $mysql_db_name; + $settings['main_database_login'] = $mysql_db_user; + + } + + //* Insert new package instance + $insert_data = "(`sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `server_id`, `customer_id`, `package_id`, `instance_status`) VALUES (".$websrv['sys_userid'].", ".$websrv['sys_groupid'].", 'riud', '".$websrv['sys_perm_group']."', '', ".$app->db->quote($webserver_id).",".$app->db->quote($customerid).", ".$app->db->quote($packageid).", ".INSTANCE_PENDING.")"; + $InstanceID = $app->db->datalogInsert('aps_instances', $insert_data, 'id'); + + //* Insert all package settings + if(is_array($settings)) { + foreach($settings as $key => $value) { + $insert_data = "(server_id, instance_id, name, value) VALUES (".$app->db->quote($webserver_id).",".$app->db->quote($InstanceID).", '".$app->db->quote($key)."', '".$app->db->quote($value)."')"; + $app->db->datalogInsert('aps_instances_settings', $insert_data, 'id'); + } + } + + //* Set package status to install afetr we inserted the settings + $app->db->datalogUpdate('aps_instances', "instance_status = ".INSTANCE_INSTALL, 'id', $InstanceID); + } + + /** + * Sets the status of an instance to "should be removed" and creates a + * datalog entry to give the ISPConfig server a real removal advice + * + * @param $instanceid the instance to delete + */ + public function deleteInstance($instanceid) + { + global $app; + /* + $app->db->query("UPDATE aps_instances SET instance_status = ".INSTANCE_REMOVE." WHERE id = ".$instanceid.";"); + + $webserver_id = $this->getInstanceDataForDatalog($instanceid); + if($webserver_id == '') return; + + // Create a sys_datalog entry for deletion + $datalog = array('Instance_id' => $instanceid, 'server_id' => $webserver_id); + $app->db->datalogSave('aps', 'DELETE', 'id', $instanceid, array(), $datalog); + */ + + $sql = "SELECT web_database.database_id as database_id, web_database.database_user_id as `database_user_id` FROM aps_instances_settings, web_database WHERE aps_instances_settings.value = web_database.database_name AND aps_instances_settings.name = 'main_database_name' AND aps_instances_settings.instance_id = ".$instanceid." LIMIT 0,1"; + $tmp = $app->db->queryOneRecord($sql); + if($tmp['database_id'] > 0) $app->db->datalogDelete('web_database', 'database_id', $tmp['database_id']); + + $database_user = $tmp['database_user_id']; + $tmp = $app->db->queryOneRecord("SELECT COUNT(*) as `cnt` FROM `web_database` WHERE `database_user_id` = '" . $app->functions->intval($database_user) . "' OR `database_ro_user_id` = '" . $app->functions->intval($database_user) . "'"); + if($tmp['cnt'] < 1) $app->db->datalogDelete('web_database_user', 'database_user_id', $database_user); + + $app->db->datalogUpdate('aps_instances', "instance_status = ".INSTANCE_REMOVE, 'id', $instanceid); + + } + + /** + * Sets the status of an instance to "installation planned" and creates a + * datalog entry to re-install the package. The existing package is simply overwritten. + * + * @param $instanceid the instance to delete + */ + public function reinstallInstance($instanceid) + { + global $app; + + /* + $app->db->query("UPDATE aps_instances SET instance_status = ".INSTANCE_INSTALL." WHERE id = ".$instanceid.";"); + + $webserver_id = $this->getInstanceDataForDatalog($instanceid); + if($webserver_id == '') return; + + // Create a sys_datalog entry for re-installation + $datalog = array('instance_id' => $instanceid, 'server_id' => $webserver_id); + $app->db->datalogSave('aps', 'INSERT', 'id', $instanceid, array(), $datalog); + */ + + $sql = "SELECT web_database.database_id as database_id FROM aps_instances_settings, web_database WHERE aps_instances_settings.value = web_database.database_name AND aps_instances_settings.value = aps_instances_settings.name = 'main_database_name' AND aps_instances_settings.instance_id = ".$instanceid." LIMIT 0,1"; + $tmp = $app->db->queryOneRecord($sql); + if($tmp['database_id'] > 0) $app->db->datalogDelete('web_database', 'database_id', $tmp['database_id']); + + $app->db->datalogUpdate('aps_instances', "instance_status = ".INSTANCE_INSTALL, 'id', $instanceid); + } + + /** + * Read the settings to be filled when installing + * + * @param $id the internal ID of the package + * @return array + */ + public function getPackageSettings($id) + { + global $app; + + $pkg = $app->db->queryOneRecord('SELECT * FROM aps_packages WHERE id = '.$app->db->quote($id).';'); + + // Load in meta file if existing and register its namespaces + $metafile = $this->interface_pkg_dir.'/'.$pkg['path'].'/APP-META.xml'; + if(!file_exists($metafile)) + return array('error' => 'The metafile for '.$settings['Name'].' couldn\'t be found'); + + $sxe = $this->readInMetaFile($metafile); + + $groupsettings = parent::getXPathValue($sxe, '//settings/group/setting', true); + if(empty($groupsettings)) return array(); + + $settings = array(); + foreach($groupsettings as $setting) + { + $setting_id = strval($setting['id']); + + if($setting['type'] == 'string' || $setting['type'] == 'email' || $setting['type'] == 'integer' + || $setting['type'] == 'float' || $setting['type'] == 'domain-name') + { + $settings[] = array('SettingID' => $setting_id, + 'SettingName' => $setting->name, + 'SettingDescription' => $setting->description, + 'SettingType' => $setting['type'], + 'SettingInputType' => 'string', + 'SettingDefaultValue' => strval($setting['default-value']), + 'SettingRegex' => $setting['regex'], + 'SettingMinLength' => $setting['min-length'], + 'SettingMaxLength' => $setting['max-length']); + } + else if($setting['type'] == 'password') + { + $settings[] = array('SettingID' => $setting_id, + 'SettingName' => $setting->name, + 'SettingDescription' => $setting->description, + 'SettingType' => 'password', + 'SettingInputType' => 'password', + 'SettingDefaultValue' => '', + 'SettingRegex' => $setting['regex'], + 'SettingMinLength' => $setting['min-length'], + 'SettingMaxLength' => $setting['max-length']); + } + else if($setting['type'] == 'boolean') + { + $settings[] = array('SettingID' => $setting_id, + 'SettingName' => $setting->name, + 'SettingDescription' => $setting->description, + 'SettingType' => 'boolean', + 'SettingInputType' => 'checkbox', + 'SettingDefaultValue' => strval($setting['default-value'])); + } + else if($setting['type'] == 'enum') + { + $choices = array(); + foreach($setting->choice as $choice) + { + $choices[] = array('EnumID' => strval($choice['id']), + 'EnumName' => $choice->name); + } + $settings[] = array('SettingID' => $setting_id, + 'SettingName' => $setting->name, + 'SettingDescription' => $setting->description, + 'SettingType' => 'enum', + 'SettingInputType' => 'select', + 'SettingDefaultValue' => strval($setting['default-value']), + 'SettingChoices' => $choices); + } + } + + return $settings; + } + + /** + * Validates the user input according to the settings array and + * delivers errors if occurring + * + * @param $input the user $_POST array + * @param $pkg_details the package details + * @param $settings the package settings array + * @return array in this structure: + * array(2) { + * ["input"]=> ... + * ["errors"]=> ... + * } + */ + public function validateInstallerInput($postinput, $pkg_details, $domains, $settings = array()) + { + global $app; + + $ret = array(); + $input = array(); + $error = array(); + + // Main domain (obligatory) + if(isset($postinput['main_domain'])) + { + if(!in_array($postinput['main_domain'], $domains)) $error[] = $app->lng('error_main_domain'); + else $input['main_domain'] = $postinput['main_domain']; + } + else $error[] = $app->lng('error_main_domain'); + + // Main location (not obligatory but must be supplied) + if(isset($postinput['main_location'])) + { + $temp_errstr = ''; + // It can be empty but if the user did write something, check it + $userinput = false; + if(strlen($postinput['main_location']) > 0) $userinput = true; + + // Filter invalid input slashes (twice!) + $main_location = $this->secureLocation($postinput['main_location']); + $main_location = $this->secureLocation($main_location); + // Only allow digits, words, / and - + $main_location = preg_replace("/[^\d\w\/\-]/i", "", $main_location); + if($userinput && (strlen($main_location) == 0)) $temp_errstr = $app->lng('error_inv_main_location'); + + // Find out document_root and make sure no apps are installed twice to one location + if(in_array($postinput['main_domain'], $domains)) + { + $docroot = $app->db->queryOneRecord("SELECT document_root FROM web_domain + WHERE domain = '".$app->db->quote($postinput['main_domain'])."';"); + $new_path = $docroot['document_root']; + if(substr($new_path, -1) != '/') $new_path .= '/'; + $new_path .= $main_location; + + // Get the $customerid which belongs to the selected domain + $customerid = $this->getCustomerIDFromDomain($postinput['main_domain']); + + // First get all domains used for an install, then their loop them + // and get the corresponding document roots as well as the defined + // locations. If an existing doc_root + location matches with the + // new one -> error + $instance_domains = $app->db->queryAllRecords("SELECT instance_id, s.value AS domain + FROM aps_instances AS i, aps_instances_settings AS s + WHERE i.id = s.instance_id AND s.name = 'main_domain' + AND i.customer_id = '".$app->db->quote($customerid)."';"); + for($i = 0; $i < count($instance_domains); $i++) + { + $used_path = ''; + + $doc_root = $app->db->queryOneRecord("SELECT document_root FROM web_domain + WHERE domain = '".$app->db->quote($instance_domains[$i]['domain'])."';"); + + // Probably the domain settings were changed later, so make sure the doc_root + // is not empty for further validation + if(!empty($doc_root)) + { + $used_path = $doc_root['document_root']; + if(substr($used_path, -1) != '/') $used_path .= '/'; + + $location_for_domain = $app->db->queryOneRecord("SELECT value + FROM aps_instances_settings WHERE name = 'main_location' + AND instance_id = '".$app->db->quote($instance_domains[$i]['instance_id'])."';"); + + // The location might be empty but the DB return must not be false! + if($location_for_domain) $used_path .= $location_for_domain['value']; + + if($new_path == $used_path) + { + $temp_errstr = $app->lng('error_used_location'); + break; + } + } + } + } + else $temp_errstr = $app->lng('error_main_domain'); + + if($temp_errstr == '') $input['main_location'] = htmlspecialchars($main_location); + else $error[] = $temp_errstr; + } + else $error[] = $app->lng('error_no_main_location'); + + // License (the checkbox must be set) + if(isset($pkg_details['License need agree']) + && $pkg_details['License need agree'] == 'true') + { + if(isset($postinput['license']) && $postinput['license'] == 'on') $input['license'] = 'true'; + else $error[] = $app->lng('error_license_agreement'); + } + + // Database + if(isset($pkg_details['Requirements Database']) + && $pkg_details['Requirements Database'] != '') + { + if(isset($postinput['main_database_password'])) + { + if($postinput['main_database_password'] == '') $error[] = $app->lng('error_no_database_pw'); + else if(strlen($postinput['main_database_password']) > 8) + $input['main_database_password'] = htmlspecialchars($postinput['main_database_password']); + else $error[] = $app->lng('error_short_database_pw'); + } + else $error[] = $app->lng('error_no_database_pw'); + } + + // Validate the package settings + foreach($settings as $setting) + { + $temp_errstr = ''; + $setting_id = strval($setting['SettingID']); + + // We assume that every setting must be set + if((isset($postinput[$setting_id]) && ($postinput[$setting_id] != '')) + || ($setting['SettingType'] == 'boolean')) + { + if($setting['SettingType'] == 'string' || $setting['SettingType'] == 'password') + { + if($app->functions->intval($setting['SettingMinLength'], true) != 0 + && strlen($postinput[$setting_id]) < $app->functions->intval($setting['SettingMinLength'], true)) + $temp_errstr = sprintf($app->lng('error_short_value_for'), $setting['setting_name']); + + if($app->functions->intval($setting['SettingMaxLength'], true) != 0 + && strlen($postinput[$setting_id]) > $app->functions->intval($setting['SettingMaxLength'], true)) + $temp_errstr = sprintf($app->lng('error_long_value_for'), $setting['setting_name']); + + if(isset($setting['SettingRegex']) + && !preg_match("/".$setting['SettingRegex']."/", $postinput[$setting_id])) + $temp_errstr = sprintf($app->lng('error_inv_value_for'), $setting['setting_name']); + } + else if($setting['SettingType'] == 'email') + { + if(filter_var(strtolower($postinput[$setting_id]), FILTER_VALIDATE_EMAIL) === false) + $temp_errstr = sprintf($app->lng('error_inv_email_for'), $setting['setting_name']); + } + else if($setting['SettingType'] == 'domain-name') + { + if(!preg_match("^(http|https)\://([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&%\$\-]+)*@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|localhost|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(\:[0-9]+)*(/($|[a-zA-Z0-9\.\,\?\'\\\+&%\$#\=~_\-]+))*$", + $postinput[$setting_id])) + $temp_errstr = sprintf($app->lng('error_inv_domain_for'), $setting['setting_name']); + } + else if($setting['SettingType'] == 'integer') + { + if(filter_var($postinput[$setting_id], FILTER_VALIDATE_INT) === false) + $temp_errstr = sprintf($app->lng('error_inv_integer_for'), $setting['setting_name']); + } + else if($setting['SettingType'] == 'float') + { + if(filter_var($postinput[$setting_id], FILTER_VALIDATE_FLOAT) === false) + $temp_errstr = sprintf($app->lng('error_inv_float_for'), $setting['setting_name']); + } + else if($setting['SettingType'] == 'boolean') + { + // If we have a boolean value set, it must be either true or false + if(!isset($postinput[$setting_id])) $postinput[$setting_id] = 'false'; + else if(isset($postinput[$setting_id]) && $postinput[$setting_id] != 'true') + $postinput[$setting_id] = 'true'; + } + else if($setting['SettingType'] == 'enum') + { + $found = false; + for($i = 0; $i < count($setting['SettingChoices']); $i++) + { + if($setting['SettingChoices'][$i]['EnumID'] == $postinput[$setting_id]) + $found = true; + } + if(!$found) $temp_errstr = sprintf($app->lng('error_inv_value_for'), $setting['SettingName']); + } + + if($temp_errstr == '') $input[$setting_id] = $postinput[$setting_id]; + else $error[] = $temp_errstr; + } + else $error[] = sprintf($app->lng('error_no_value_for'), $setting['SettingName']); + } + + $ret['input'] = $input; + $ret['error'] = array_unique($error); + + return $ret; + } + + /** + * Read the metadata of a package and returns some content + * + * @param $id the internal ID of the package + * @return array + */ + public function getPackageDetails($id) + { + global $app; + + $pkg = $app->db->queryOneRecord('SELECT * FROM aps_packages WHERE id = '.$app->db->quote($id).';'); + + // Load in meta file if existing and register its namespaces + $metafile = $this->interface_pkg_dir.'/'.$pkg['path'].'/APP-META.xml'; + if(!file_exists($metafile)) + return array('error' => 'The metafile for '.$pkg['name'].' couldn\'t be found'); + + $metadata = file_get_contents($metafile); + $metadata = str_replace("xmlns=", "ns=", $metadata); + $sxe = new SimpleXMLElement($metadata); + $namespaces = $sxe->getDocNamespaces(true); + foreach($namespaces as $ns => $url) $sxe->registerXPathNamespace($ns, $url); + + $pkg['Summary'] = htmlspecialchars(parent::getXPathValue($sxe, '//summary')); + $pkg['Homepage'] = parent::getXPathValue($sxe, '//homepage'); + $pkg['Description'] = nl2br(htmlspecialchars(trim(parent::getXPathValue($sxe, '//description')))); + $pkg['Config script'] = strtoupper(parent::getXPathValue($sxe, '//configuration-script-language')); + $installed_size = parent::getXPathValue($sxe, '//installed-size'); + $pkg['Installed Size'] = (!empty($installed_size)) ? parent::convertSize((int)$installed_size) : ''; + + // License + $pkg['License need agree'] = parent::getXPathValue($sxe, '//license/@must-accept'); + $pkg['License name'] = parent::getXPathValue($sxe, '//license/text/name'); // might be empty + $pkg['License type'] = 'file'; // default type + $pkg['License content'] = ''; // default license filename on local system + $license_url = parent::getXPathValue($sxe, '//license/text/url'); + if(!empty($license_url)) + { + $pkg['License type'] = 'url'; + $pkg['License content'] = htmlspecialchars($license_url); + } + else + { + $lic = @file_get_contents($this->interface_pkg_dir.'/'.$pkg['path'].'/LICENSE'); + $pkg['License content'] = htmlentities($lic, ENT_QUOTES, 'ISO-8859-1'); + } + + // Languages + $languages = parent::getXPathValue($sxe, '//languages/language', true); + $pkg['Languages'] = (is_array($languages)) ? implode(' ', $languages) : ''; + + // Icon + $icon = parent::getXPathValue($sxe, '//icon/@path'); + if(!empty($icon)) + { + // Using parse_url() to filter malformed URLs + $path = dirname(parse_url($_SERVER['PHP_SELF'], PHP_URL_PATH)).'/'. + basename($this->interface_pkg_dir).'/'.$pkg['path'].'/'.basename((string)$icon); + // nginx: if $_SERVER['PHP_SELF'] is doubled, remove /sites/aps_packagedetails_show.php from beginning of path + $path = preg_replace('@^/sites/aps_packagedetails_show.php(.*)@', '$1', $path); + $pkg['Icon'] = $path; + } + else $pkg['Icon'] = ''; + + // Screenshots + $screenshots = parent::getXPathValue($sxe, '//screenshot', true); + if(!empty($screenshots)) + { + foreach($screenshots as $screen) + { + // Using parse_url() to filter malformed URLs + $path = dirname(parse_url($_SERVER['PHP_SELF'], PHP_URL_PATH)).'/'. + basename($this->interface_pkg_dir).'/'.$pkg['path'].'/'.basename((string)$screen['path']); + // nginx: if $_SERVER['PHP_SELF'] is doubled, remove /sites/aps_packagedetails_show.php from beginning of path + $path = preg_replace('@^/sites/aps_packagedetails_show.php(.*)@', '$1', $path); + + $pkg['Screenshots'][] = array('ScreenPath' => $path, + 'ScreenDescription' => htmlspecialchars(trim((string)$screen->description))); + } + } + else $pkg['Screenshots'] = ''; // if no screenshots are available, set the variable though + + // Changelog + $changelog = parent::getXPathValue($sxe, '//changelog/version', true); + if(!empty($changelog)) + { + foreach($changelog as $change) + { + $entries = array(); + foreach($change->entry as $entry) $entries[] = htmlspecialchars(trim((string)$entry)); + + $pkg['Changelog'][] = array('ChangelogVersion' => (string)$change['version'], + 'ChangelogDescription' => implode('<br />', $entries)); + } + } + + else $pkg['Changelog'] = ''; + + // PHP extensions + $php_extensions = parent::getXPathValue($sxe, '//php:extension', true); + $php_ext = ''; + if(!empty($php_extensions)) + { + foreach($php_extensions as $extension) + { + if(strtolower($extension) == 'php') continue; + $php_ext .= $extension.' '; + } + } + $pkg['Requirements PHP extensions'] = trim($php_ext); + + // PHP bool options + $pkg['Requirements PHP settings'] = ''; + $php_bool_options = array('allow-url-fopen', 'file-uploads', 'magic-quotes-gpc', + 'register-globals', 'safe-mode', 'short-open-tag'); + foreach($php_bool_options as $option) + { + $value = parent::getXPathValue($sxe, '//php:'.$option); + if(!empty($value)) + { + $option = str_replace('-', '_', $option); + $value = str_replace(array('false', 'true'), array('off', 'on'), $value); + $pkg['Requirements PHP settings'][] = array('PHPSettingName' => $option, + 'PHPSettingValue' => $value); + } + } + + // PHP integer value settings + $memory_limit = parent::getXPathValue($sxe, '//php:memory-limit'); + if(!empty($memory_limit)) + $pkg['Requirements PHP settings'][] = array('PHPSettingName' => 'memory_limit', + 'PHPSettingValue' => parent::convertSize((int)$memory_limit)); + + $max_exec_time = parent::getXPathValue($sxe, '//php:max-execution-time'); + if(!empty($max_exec_time)) + $pkg['Requirements PHP settings'][] = array('PHPSettingName' => 'max-execution-time', + 'PHPSettingValue' => $max_exec_time); + + $post_max_size = parent::getXPathValue($sxe, '//php:post-max-size'); + if(!empty($post_max_size)) + $pkg['Requirements PHP settings'][] = array('PHPSettingName' => 'post_max_size', + 'PHPSettingValue' => parent::convertSize((int)$post_max_size)); + + // Get supported PHP versions + $pkg['Requirements Supported PHP versions'] = ''; + $php_min_version = parent::getXPathValue($sxe, '//php:version/@min'); + $php_max_not_including = parent::getXPathValue($sxe, '//php:version/@max-not-including'); + if(!empty($php_min_version) && !empty($php_max_not_including)) + $pkg['Requirements Supported PHP versions'] = $php_min_version.' - '.$php_max_not_including; + else if(!empty($php_min_version)) + $pkg['Requirements Supported PHP versions'] = '> '.$php_min_version; + else if(!empty($php_max_not_including)) + $pkg['Requirements Supported PHP versions'] = '< '.$php_min_version; + + // Database + $db_id = parent::getXPathValue($sxe, '//db:id'); + $db_server_type = parent::getXPathValue($sxe, '//db:server-type'); + $db_min_version = parent::getXPathValue($sxe, '//db:server-min-version'); + if(!empty($db_id)) + { + $db_server_type = str_replace('postgresql', 'PostgreSQL', $db_server_type); + $db_server_type = str_replace('microsoft:sqlserver', 'MSSQL', $db_server_type); + $db_server_type = str_replace('mysql', 'MySQL', $db_server_type); + + $pkg['Requirements Database'] = $db_server_type; + if(!empty($db_min_version)) $pkg['Requirements Database'] .= ' > '.$db_min_version; + } + else $pkg['Requirements Database'] = ''; + + return $pkg; + } +} ?> \ No newline at end of file diff --git a/interface/lib/classes/tform.inc.php b/interface/lib/classes/tform.inc.php index 7cefb223c355e90a24ab4f30d600966be500bbe4..7138154533e9944b28517d99722224ae885e1518 100644 --- a/interface/lib/classes/tform.inc.php +++ b/interface/lib/classes/tform.inc.php @@ -885,45 +885,45 @@ class tform { $this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n"; } else { $this->errorMessage .= $errmsg."<br />\r\n"; - } - } - break; + } + } + break; /* - case 'ISV6PREFIX': - $v6_prefix_ok = 0; - $explode_field_value = explode(':',$field_value); - if ($explode_field_value[count($explode_field_value)-1]=='' && $explode_field_value[count($explode_field_value)-2]=='' ){ - if ( count($explode_field_value) <= 9 ) { - if(filter_var(substr($field_value,0,strlen($field_value)-2),FILTER_VALIDATE_IP,FILTER_FLAG_IPV6) or filter_var(substr($field_value,0,strlen($field_value)-2).'::0',FILTER_VALIDATE_IP,FILTER_FLAG_IPV6) or filter_var(substr($field_value,0,strlen($field_value)-2).':0',FILTER_VALIDATE_IP,FILTER_FLAG_IPV6) ) { - $v6_prefix_ok = 1; - } - } - } else { - $v6_prefix_ok = 2; - } - // check subnet against defined server-ipv6 - $sql_v6 = $app->db->queryOneRecord("SELECT ip_address FROM server_ip WHERE ip_type = 'IPv6' AND virtualhost = 'y' LIMIT 0,1"); - $sql_v6_explode=explode(':',$sql_v6['ip_address']); - if ( count($sql_v6_explode) < count($explode_field_value) && isset($sql_v6['ip_address']) ) { - $v6_prefix_ok = 3; - } - if($v6_prefix_ok == 0) { - $errmsg = $validator['errmsg']; - } - if($v6_prefix_ok == 2) { - $errmsg = 'IPv6 Prefix must end with ::'; - } - if($v6_prefix_ok == 3) { - $errmsg = 'IPv6 Prefix too long (according to Server IP Addresses)'; - } - if($v6_prefix_ok <> 1){ - $this->errorMessage .= $errmsg."<br />\r\n"; - } + case 'ISV6PREFIX': + $v6_prefix_ok = 0; + $explode_field_value = explode(':',$field_value); + if ($explode_field_value[count($explode_field_value)-1]=='' && $explode_field_value[count($explode_field_value)-2]=='' ){ + if ( count($explode_field_value) <= 9 ) { + if(filter_var(substr($field_value,0,strlen($field_value)-2),FILTER_VALIDATE_IP,FILTER_FLAG_IPV6) or filter_var(substr($field_value,0,strlen($field_value)-2).'::0',FILTER_VALIDATE_IP,FILTER_FLAG_IPV6) or filter_var(substr($field_value,0,strlen($field_value)-2).':0',FILTER_VALIDATE_IP,FILTER_FLAG_IPV6) ) { + $v6_prefix_ok = 1; + } + } + } else { + $v6_prefix_ok = 2; + } + // check subnet against defined server-ipv6 + $sql_v6 = $app->db->queryOneRecord("SELECT ip_address FROM server_ip WHERE ip_type = 'IPv6' AND virtualhost = 'y' LIMIT 0,1"); + $sql_v6_explode=explode(':',$sql_v6['ip_address']); + if ( count($sql_v6_explode) < count($explode_field_value) && isset($sql_v6['ip_address']) ) { + $v6_prefix_ok = 3; + } + if($v6_prefix_ok == 0) { + $errmsg = $validator['errmsg']; + } + if($v6_prefix_ok == 2) { + $errmsg = 'IPv6 Prefix must end with ::'; + } + if($v6_prefix_ok == 3) { + $errmsg = 'IPv6 Prefix too long (according to Server IP Addresses)'; + } + if($v6_prefix_ok <> 1){ + $this->errorMessage .= $errmsg."<br />\r\n"; + } break; - */ - case 'ISIPV4': - $vip=1; - if(preg_match("/^[0-9]{1,3}(\.)[0-9]{1,3}(\.)[0-9]{1,3}(\.)[0-9]{1,3}$/", $field_value)){ + */ + case 'ISIPV4': + $vip=1; + if(preg_match("/^[0-9]{1,3}(\.)[0-9]{1,3}(\.)[0-9]{1,3}(\.)[0-9]{1,3}$/", $field_value)){ $groups=explode(".",$field_value); foreach($groups as $group){ if($group<0 OR $group>255) diff --git a/interface/web/admin/form/server_config.tform.php b/interface/web/admin/form/server_config.tform.php index c2adbdcc955c5ccbb5194f7eb9a5055b5ea9f00b..7e0f63e3842462d4d331b7575c49c767cd362874 100644 --- a/interface/web/admin/form/server_config.tform.php +++ b/interface/web/admin/form/server_config.tform.php @@ -83,22 +83,22 @@ $form["tabs"]['server'] = array( 'errmsg' => 'netmask_error_wrong'), ), 'value' => '', - 'width' => '15', - 'maxlength' => '255' - ), - /* - 'v6_prefix' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'TEXT', - 'validators' => array(0 => array('type' => 'ISV6PREFIX', - 'errmsg' => 'v6_prefix_wrong'), - ), - 'default' => '' - ), - */ - 'gateway' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'TEXT', + 'width' => '15', + 'maxlength' => '255' + ), + /* + 'v6_prefix' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'validators' => array(0 => array('type' => 'ISV6PREFIX', + 'errmsg' => 'v6_prefix_wrong'), + ), + 'default' => '' + ), + */ + 'gateway' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', 'default' => '192.168.0.1', 'validators' => array(0 => array('type' => 'ISIPV4', 'errmsg' => 'gateway_error_wrong'), @@ -506,20 +506,20 @@ $form["tabs"]['web'] = array( 'formtype' => 'TEXT', 'default' => '', 'value' => '', - 'width' => '40', - 'maxlength' => '255' - ), -/* -'vhost_rewrite_v6' => array ( -'datatype' => 'VARCHAR', -'formtype' => 'CHECKBOX', -'default' => 'n', -'value' => array(0 => 'n',1 => 'y') -), -*/ - 'vhost_conf_dir' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'TEXT', + 'width' => '40', + 'maxlength' => '255' + ), +/* +'vhost_rewrite_v6' => array ( +'datatype' => 'VARCHAR', +'formtype' => 'CHECKBOX', +'default' => 'n', +'value' => array(0 => 'n',1 => 'y') +), +*/ + 'vhost_conf_dir' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', 'default' => '', 'validators' => array(0 => array('type' => 'NOTEMPTY', 'errmsg' => 'vhost_conf_dir_error_empty'), diff --git a/interface/web/admin/lib/lang/en_server_config.lng b/interface/web/admin/lib/lang/en_server_config.lng index 36a6791ad7d380f4a4715d2af7a443879d8f67fb..6b4c72848dc648d910c09708941ba1ca740e2311 100644 --- a/interface/web/admin/lib/lang/en_server_config.lng +++ b/interface/web/admin/lib/lang/en_server_config.lng @@ -167,8 +167,8 @@ $wb["awstats_settings_txt"] = 'AWStats Settings'; $wb["firewall_txt"] = 'Firewall'; $wb["mailbox_quota_stats_txt"] = 'Mailbox quota statistics'; $wb["enable_ip_wildcard_txt"] = 'Enable IP wildcard (*)'; -$wb["web_folder_protection_txt"] = 'Make web folders immutable (extended attributes)'; -$wb["overtraffic_notify_admin_txt"] = 'Send overtraffic notification to admin'; +$wb["web_folder_protection_txt"] = 'Make web folders immutable (extended attributes)'; +$wb["overtraffic_notify_admin_txt"] = 'Send overtraffic notification to admin'; $wb["overtraffic_notify_client_txt"] = 'Send overtraffic notification to client'; $wb["rbl_error_regex"] = 'Please specify valid RBL hostnames.'; $wb["overquota_notify_admin_txt"] = 'Send quota warnings to admin'; @@ -188,4 +188,4 @@ $wb['munin_user_txt'] = 'Munin User'; $wb['munin_password_txt'] = 'Munin Password'; $wb['munin_url_error_regex'] = 'Invalid Munin URL'; $wb['munin_url_note_txt'] = 'Placeholder:'; -?> +?> diff --git a/interface/web/admin/lib/menu.d/tpl_default.menu.php b/interface/web/admin/lib/menu.d/tpl_default.menu.php index 544400246eda49d6560a482bb7871b613ef0d065..d6d071a701996d45f9445d88a239cd74002d642d 100644 --- a/interface/web/admin/lib/menu.d/tpl_default.menu.php +++ b/interface/web/admin/lib/menu.d/tpl_default.menu.php @@ -1,15 +1,15 @@ -<?php -/* Removed because tpl_default.php does not work -for($m = 0; $m < count($module['nav']); $m++) { - if($module['nav'][$m]['title'] == 'Interface') { - - $module['nav'][$m]['items'][] = array( 'title' => 'Default Theme', - 'target' => 'content', - 'link' => 'admin/tpl_default.php', - 'html_id' => 'tpl_default'); - break; - } -} -*/ - -?> +<?php +/* Removed because tpl_default.php does not work +for($m = 0; $m < count($module['nav']); $m++) { + if($module['nav'][$m]['title'] == 'Interface') { + + $module['nav'][$m]['items'][] = array( 'title' => 'Default Theme', + 'target' => 'content', + 'link' => 'admin/tpl_default.php', + 'html_id' => 'tpl_default'); + break; + } +} +*/ + +?> diff --git a/interface/web/admin/templates/iptables_edit.htm b/interface/web/admin/templates/iptables_edit.htm index 283c5e78dbe169f1bca837b47109aa3f1439a127..23228d4563f9470925a79b123d1e54decf47d02e 100644 --- a/interface/web/admin/templates/iptables_edit.htm +++ b/interface/web/admin/templates/iptables_edit.htm @@ -1,67 +1,67 @@ -<h2><tmpl_var name="list_head_txt"></h2> -<p><tmpl_var name="list_desc_txt"></p> -<div class="panel panel_iptables"> - - <div class="pnl_formsarea"> - <fieldset class="inlineLabels"> - <div class="ctrlHolder"> - <label for="server_id">{tmpl_var name='server_id_txt'}</label> - <select name="server_id" id="server_id" class="selectInput"> - {tmpl_var name='server_id'} - </select> - </div> - <div class="ctrlHolder"> - <label for="table">{tmpl_var name='table_txt'}</label> - <select name="table" id="table" class="selectInput formLengthLimit"> - {tmpl_var name='table'} - </select> - </div> - <div class="ctrlHolder"> - <label for="protocol">{tmpl_var name='protocol_txt'}</label> - <select name="protocol" id="protocol" class="selectInput formLengthLimit"> - {tmpl_var name='protocol'} - </select> - </div> - <div class="ctrlHolder"> - <label for="singleport">{tmpl_var name='singleport_txt'}</label> - <input name="singleport" id="singleport" value="{tmpl_var name='singleport'}" size="10" maxlength="10" type="text" class="textInput formLengthLimit" /> - </div> - <div class="ctrlHolder"> - <label for="multiport">{tmpl_var name='multiport_txt'}</label> - <input name="multiport" id="multiport" value="{tmpl_var name='multiport'}" size="20" maxlength="40" type="text" class="textInput" /> - </div> - <div class="ctrlHolder"> - <label for="destination_ip">{tmpl_var name='destination_ip_txt'}</label> - <input name="destination_ip" id="destination_ip" value="{tmpl_var name='destination_ip'}" size="16" maxlength="20" type="text" class="textInput formLengthIPv4" /> - </div> - <div class="ctrlHolder"> - <label for="source_ip">{tmpl_var name='source_ip_txt'}</label> - <input name="source_ip" id="source_ip" value="{tmpl_var name='source_ip'}" size="16" maxlength="20" type="text" class="textInput formLengthIPv4" /> - </div> - <div class="ctrlHolder"> - <label for="state">{tmpl_var name='state_txt'}</label> - <input name="state" id="state" value="{tmpl_var name='state'}" size="16" maxlength="20" type="text" class="textInput" /> - </div> - <div class="ctrlHolder"> - <label for="target">{tmpl_var name='target_txt'}</label> - <select name="target" id="target" class="selectInput formLengthLimit"> - {tmpl_var name='target'} - </select> - </div> - <div class="ctrlHolder"> - <p class="label">{tmpl_var name='active_txt'}</p> - <div class="multiField"> - {tmpl_var name='active'} - </div> - </div> - </fieldset> - <input type="hidden" name="id" value="{tmpl_var name='id'}"> - <div class="buttonHolder buttons"> - <button class="positive iconstxt icoPositive" type="button" value="{tmpl_var name='btn_save_txt'}" onclick="submitForm('pageForm','admin/iptables_edit.php');"> - <span>{tmpl_var name='btn_save_txt'}</span></button> - <button class="negative iconstxt icoNegative" type="button" value="{tmpl_var name='btn_cancel_txt'}" onclick="loadContent('admin/iptables_list.php');"> - <span>{tmpl_var name='btn_cancel_txt'}</span></button> - </div> - </div> - +<h2><tmpl_var name="list_head_txt"></h2> +<p><tmpl_var name="list_desc_txt"></p> +<div class="panel panel_iptables"> + + <div class="pnl_formsarea"> + <fieldset class="inlineLabels"> + <div class="ctrlHolder"> + <label for="server_id">{tmpl_var name='server_id_txt'}</label> + <select name="server_id" id="server_id" class="selectInput"> + {tmpl_var name='server_id'} + </select> + </div> + <div class="ctrlHolder"> + <label for="table">{tmpl_var name='table_txt'}</label> + <select name="table" id="table" class="selectInput formLengthLimit"> + {tmpl_var name='table'} + </select> + </div> + <div class="ctrlHolder"> + <label for="protocol">{tmpl_var name='protocol_txt'}</label> + <select name="protocol" id="protocol" class="selectInput formLengthLimit"> + {tmpl_var name='protocol'} + </select> + </div> + <div class="ctrlHolder"> + <label for="singleport">{tmpl_var name='singleport_txt'}</label> + <input name="singleport" id="singleport" value="{tmpl_var name='singleport'}" size="10" maxlength="10" type="text" class="textInput formLengthLimit" /> + </div> + <div class="ctrlHolder"> + <label for="multiport">{tmpl_var name='multiport_txt'}</label> + <input name="multiport" id="multiport" value="{tmpl_var name='multiport'}" size="20" maxlength="40" type="text" class="textInput" /> + </div> + <div class="ctrlHolder"> + <label for="destination_ip">{tmpl_var name='destination_ip_txt'}</label> + <input name="destination_ip" id="destination_ip" value="{tmpl_var name='destination_ip'}" size="16" maxlength="20" type="text" class="textInput formLengthIPv4" /> + </div> + <div class="ctrlHolder"> + <label for="source_ip">{tmpl_var name='source_ip_txt'}</label> + <input name="source_ip" id="source_ip" value="{tmpl_var name='source_ip'}" size="16" maxlength="20" type="text" class="textInput formLengthIPv4" /> + </div> + <div class="ctrlHolder"> + <label for="state">{tmpl_var name='state_txt'}</label> + <input name="state" id="state" value="{tmpl_var name='state'}" size="16" maxlength="20" type="text" class="textInput" /> + </div> + <div class="ctrlHolder"> + <label for="target">{tmpl_var name='target_txt'}</label> + <select name="target" id="target" class="selectInput formLengthLimit"> + {tmpl_var name='target'} + </select> + </div> + <div class="ctrlHolder"> + <p class="label">{tmpl_var name='active_txt'}</p> + <div class="multiField"> + {tmpl_var name='active'} + </div> + </div> + </fieldset> + <input type="hidden" name="id" value="{tmpl_var name='id'}"> + <div class="buttonHolder buttons"> + <button class="positive iconstxt icoPositive" type="button" value="{tmpl_var name='btn_save_txt'}" onclick="submitForm('pageForm','admin/iptables_edit.php');"> + <span>{tmpl_var name='btn_save_txt'}</span></button> + <button class="negative iconstxt icoNegative" type="button" value="{tmpl_var name='btn_cancel_txt'}" onclick="loadContent('admin/iptables_list.php');"> + <span>{tmpl_var name='btn_cancel_txt'}</span></button> + </div> + </div> + </div> \ No newline at end of file diff --git a/interface/web/admin/templates/iptables_list.htm b/interface/web/admin/templates/iptables_list.htm index e3747054e3f5261af38a0ad2e267ef0b063e910e..523ec675de30bf704b31eb771e9d321f289ac328 100644 --- a/interface/web/admin/templates/iptables_list.htm +++ b/interface/web/admin/templates/iptables_list.htm @@ -1,74 +1,74 @@ -<h2><tmpl_var name="list_head_txt"></h2> - -<div class="panel panel_list_iptables"> - - <div class="pnl_toolsarea"> - <fieldset><legend>Tools</legend> - <div class="buttons"> - <button class="button iconstxt icoAdd" type="button" onclick="loadContent('admin/iptables_edit.php');"> - <span>{tmpl_var name="add_new_rule_txt"}</span> - </button> - </div> - </fieldset> - </div> - - <div class="pnl_listarea"> - <fieldset><legend><tmpl_var name="list_head_txt"></legend> - <table class="list"> - <thead> - <tr class="caption"> - <th class="tbl_col_active" scope="col"><tmpl_var name="active_txt"></th> - <th class="tbl_col_server_id" scope="col"><tmpl_var name="server_id_txt"></th> - <th class="tbl_col_table" scope="col"><tmpl_var name="table_txt"></th> - <th class="tbl_col_protocol" scope="col"><tmpl_var name="protocol_txt"></th> - <th class="tbl_col_port" scope="col"><tmpl_var name="singleport_txt"></th> - <th class="tbl_col_port" scope="col"><tmpl_var name="multiport_txt"></th> - <th class="tbl_col_state" scope="col"><tmpl_var name="state_txt"></th> - <th class="tbl_col_target" scope="col"><tmpl_var name="target_txt"></th> - <th class="tbl_col_buttons" scope="col"> </th> - </tr> - <tr class="filter"> - <td class="tbl_col_active"><select name="search_active">{tmpl_var name='search_active'}</select></td> - <td class="tbl_col_server_id"><select name="search_server_id">{tmpl_var name='search_server_id'}</select></td> - <td class="tbl_col_table"></td> - <td class="tbl_col_protocol"><select name="search_protocol">{tmpl_var name='search_protocol'}</select></td> - <td class="tbl_col_singleport"></td> - <td class="tbl_col_multiport"></td> - <td class="tbl_col_state"></td> - <td class="tbl_col_target"><select name="search_target">{tmpl_var name='search_target'}</select></td> - <td class="tbl_col_buttons"> - <button type="button" class="button icons16 icoFilter" name="Filter" id="Filter" value="{tmpl_var name="filter_txt"}" onclick="submitForm('pageForm','admin/iptables_list.php');"><span>{tmpl_var name="filter_txt"}filter_txt</span></button> - </td> - </tr> - </thead> - <tbody> - <tmpl_loop name="records"> - <tr class="tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>"> - <td class="tbl_col_active"><a href="#" onclick="loadContent('admin/iptables_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="active"}</a></td> - <td class="tbl_col_server_id"><a href="#" onclick="loadContent('admin/iptables_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="server_id"}</a></td> - <td class="tbl_col_table"><a href="#" onclick="loadContent('admin/iptables_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="table"}</a></td> - <td class="tbl_col_protocol"><a href="#" onclick="loadContent('admin/iptables_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="protocol"}</a></td> - <td class="tbl_col_singleport"><a href="#" onclick="loadContent('admin/iptables_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="singleport"}</a></td> - <td class="tbl_col_multiport"><a href="#" onclick="loadContent('admin/iptables_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="multiport"}</a></td> - <td class="tbl_col_state"><a href="#" onclick="loadContent('admin/iptables_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="state"}</a></td> - <td class="tbl_col_target"><a href="#" onclick="loadContent('admin/iptables_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="target"}</a></td> - <td class="tbl_col_buttons"> - <a class="button icons16 icoDelete" href="javascript: del_record('admin/iptables_del.php?id={tmpl_var name='id'}&phpsessid={tmpl_var name='phpsessid'}','{tmpl_var name='delete_confirmation'}');"><span>{tmpl_var name='delete_txt'}</span></a> - </td> - </tr> - </tmpl_loop> - <tmpl_unless name="records"> - <tr class="tbl_row_noresults tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>"> - <td colspan="9">{tmpl_var name='globalsearch_noresults_text_txt'}</td> - </tr> - </tmpl_unless> - </tbody> - <tfoot> - <tr> - <td class="tbl_footer tbl_paging" colspan="9"><tmpl_var name="paging"></td> - </tr> - </tfoot> - </table> - </fieldset> - </div> +<h2><tmpl_var name="list_head_txt"></h2> + +<div class="panel panel_list_iptables"> + + <div class="pnl_toolsarea"> + <fieldset><legend>Tools</legend> + <div class="buttons"> + <button class="button iconstxt icoAdd" type="button" onclick="loadContent('admin/iptables_edit.php');"> + <span>{tmpl_var name="add_new_rule_txt"}</span> + </button> + </div> + </fieldset> + </div> + + <div class="pnl_listarea"> + <fieldset><legend><tmpl_var name="list_head_txt"></legend> + <table class="list"> + <thead> + <tr class="caption"> + <th class="tbl_col_active" scope="col"><tmpl_var name="active_txt"></th> + <th class="tbl_col_server_id" scope="col"><tmpl_var name="server_id_txt"></th> + <th class="tbl_col_table" scope="col"><tmpl_var name="table_txt"></th> + <th class="tbl_col_protocol" scope="col"><tmpl_var name="protocol_txt"></th> + <th class="tbl_col_port" scope="col"><tmpl_var name="singleport_txt"></th> + <th class="tbl_col_port" scope="col"><tmpl_var name="multiport_txt"></th> + <th class="tbl_col_state" scope="col"><tmpl_var name="state_txt"></th> + <th class="tbl_col_target" scope="col"><tmpl_var name="target_txt"></th> + <th class="tbl_col_buttons" scope="col"> </th> + </tr> + <tr class="filter"> + <td class="tbl_col_active"><select name="search_active">{tmpl_var name='search_active'}</select></td> + <td class="tbl_col_server_id"><select name="search_server_id">{tmpl_var name='search_server_id'}</select></td> + <td class="tbl_col_table"></td> + <td class="tbl_col_protocol"><select name="search_protocol">{tmpl_var name='search_protocol'}</select></td> + <td class="tbl_col_singleport"></td> + <td class="tbl_col_multiport"></td> + <td class="tbl_col_state"></td> + <td class="tbl_col_target"><select name="search_target">{tmpl_var name='search_target'}</select></td> + <td class="tbl_col_buttons"> + <button type="button" class="button icons16 icoFilter" name="Filter" id="Filter" value="{tmpl_var name="filter_txt"}" onclick="submitForm('pageForm','admin/iptables_list.php');"><span>{tmpl_var name="filter_txt"}filter_txt</span></button> + </td> + </tr> + </thead> + <tbody> + <tmpl_loop name="records"> + <tr class="tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>"> + <td class="tbl_col_active"><a href="#" onclick="loadContent('admin/iptables_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="active"}</a></td> + <td class="tbl_col_server_id"><a href="#" onclick="loadContent('admin/iptables_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="server_id"}</a></td> + <td class="tbl_col_table"><a href="#" onclick="loadContent('admin/iptables_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="table"}</a></td> + <td class="tbl_col_protocol"><a href="#" onclick="loadContent('admin/iptables_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="protocol"}</a></td> + <td class="tbl_col_singleport"><a href="#" onclick="loadContent('admin/iptables_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="singleport"}</a></td> + <td class="tbl_col_multiport"><a href="#" onclick="loadContent('admin/iptables_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="multiport"}</a></td> + <td class="tbl_col_state"><a href="#" onclick="loadContent('admin/iptables_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="state"}</a></td> + <td class="tbl_col_target"><a href="#" onclick="loadContent('admin/iptables_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="target"}</a></td> + <td class="tbl_col_buttons"> + <a class="button icons16 icoDelete" href="javascript: del_record('admin/iptables_del.php?id={tmpl_var name='id'}&phpsessid={tmpl_var name='phpsessid'}','{tmpl_var name='delete_confirmation'}');"><span>{tmpl_var name='delete_txt'}</span></a> + </td> + </tr> + </tmpl_loop> + <tmpl_unless name="records"> + <tr class="tbl_row_noresults tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>"> + <td colspan="9">{tmpl_var name='globalsearch_noresults_text_txt'}</td> + </tr> + </tmpl_unless> + </tbody> + <tfoot> + <tr> + <td class="tbl_footer tbl_paging" colspan="9"><tmpl_var name="paging"></td> + </tr> + </tfoot> + </table> + </fieldset> + </div> </div> \ No newline at end of file diff --git a/interface/web/admin/templates/server_config_server_edit.htm b/interface/web/admin/templates/server_config_server_edit.htm index 93158d734b7a813e4347f205f9e9de96ac0b766a..53d0db7fbd5dd6ec694e04fc8184ca07c412b2a2 100644 --- a/interface/web/admin/templates/server_config_server_edit.htm +++ b/interface/web/admin/templates/server_config_server_edit.htm @@ -16,17 +16,17 @@ <input name="ip_address" id="ip_address" value="{tmpl_var name='ip_address'}" size="15" maxlength="255" type="text" class="textInput formLengthIPv4" /> </div> <div class="ctrlHolder"> - <label for="netmask">{tmpl_var name='netmask_txt'}</label> - <input name="netmask" id="netmask" value="{tmpl_var name='netmask'}" size="15" maxlength="255" type="text" class="textInput formLengthIPv4" /> - </div> - <!--<div class="ctrlHolder"> - <label for="v6_prefix">{tmpl_var name='v6_prefix_txt'}</label> - <input name="v6_prefix" id="v6_prefix" value="{tmpl_var name='v6_prefix'}" size="15" maxlength="255" type="text" class="textInput formLengthIPv4" /> + <label for="netmask">{tmpl_var name='netmask_txt'}</label> + <input name="netmask" id="netmask" value="{tmpl_var name='netmask'}" size="15" maxlength="255" type="text" class="textInput formLengthIPv4" /> + </div> + <!--<div class="ctrlHolder"> + <label for="v6_prefix">{tmpl_var name='v6_prefix_txt'}</label> + <input name="v6_prefix" id="v6_prefix" value="{tmpl_var name='v6_prefix'}" size="15" maxlength="255" type="text" class="textInput formLengthIPv4" /> </div> - --> - <div class="ctrlHolder"> - <label for="gateway">{tmpl_var name='gateway_txt'}</label> - <input name="gateway" id="gateway" value="{tmpl_var name='gateway'}" size="15" maxlength="255" type="text" class="textInput formLengthIPv4" /> + --> + <div class="ctrlHolder"> + <label for="gateway">{tmpl_var name='gateway_txt'}</label> + <input name="gateway" id="gateway" value="{tmpl_var name='gateway'}" size="15" maxlength="255" type="text" class="textInput formLengthIPv4" /> </div> <div class="ctrlHolder"> <label for="hostname">{tmpl_var name='hostname_txt'}</label> @@ -96,7 +96,7 @@ <div class="buttonHolder buttons"> <button class="positive iconstxt icoPositive" type="button" value="{tmpl_var name='btn_save_txt'}" onclick="submitForm('pageForm','admin/server_config_edit.php');"><span>{tmpl_var name='btn_save_txt'}</span></button> <button class="negative iconstxt icoNegative" type="button" value="{tmpl_var name='btn_cancel_txt'}" onclick="loadContent('admin/server_config_list.php');"><span>{tmpl_var name='btn_cancel_txt'}</span></button> - </div> - </div> - -</div> + </div> + </div> + +</div> diff --git a/interface/web/admin/templates/server_config_web_edit.htm b/interface/web/admin/templates/server_config_web_edit.htm index 7e75f5053267b5d786fd0c153666093840859b4e..dae9c2d57e9064ebee1cd04aa8be085d1f3ddd41 100644 --- a/interface/web/admin/templates/server_config_web_edit.htm +++ b/interface/web/admin/templates/server_config_web_edit.htm @@ -32,20 +32,20 @@ </div> </div> <div class="ctrlHolder"> - <label for="website_autoalias">{tmpl_var name='website_autoalias_txt'}</label> - <input name="website_autoalias" id="website_autoalias" value="{tmpl_var name='website_autoalias'}" size="40" maxlength="255" type="text" class="textInput" /> {tmpl_var name='website_autoalias_note_txt'} <a href="javascript:void(0);" class="addPlaceholder">[client_id]</a>, <a href="javascript:void(0);" class="addPlaceholder">[client_username]</a>, <a href="javascript:void(0);" class="addPlaceholder">[website_id]</a>, <a href="javascript:void(0);" class="addPlaceholder">[website_domain]</a> + <label for="website_autoalias">{tmpl_var name='website_autoalias_txt'}</label> + <input name="website_autoalias" id="website_autoalias" value="{tmpl_var name='website_autoalias'}" size="40" maxlength="255" type="text" class="textInput" /> {tmpl_var name='website_autoalias_note_txt'} <a href="javascript:void(0);" class="addPlaceholder">[client_id]</a>, <a href="javascript:void(0);" class="addPlaceholder">[client_username]</a>, <a href="javascript:void(0);" class="addPlaceholder">[website_id]</a>, <a href="javascript:void(0);" class="addPlaceholder">[website_domain]</a> </div> - <!-- - <div class="ctrlHolder apache"> - <label for="vhost_rewrite_v6">{tmpl_var name='vhost_rewrite_v6_txt'}</label> - <div class="multiField"> - {tmpl_var name='vhost_rewrite_v6'} - </div> + <!-- + <div class="ctrlHolder apache"> + <label for="vhost_rewrite_v6">{tmpl_var name='vhost_rewrite_v6_txt'}</label> + <div class="multiField"> + {tmpl_var name='vhost_rewrite_v6'} + </div> </div> - --> - <div class="ctrlHolder apache"> - <label for="vhost_conf_dir">{tmpl_var name='vhost_conf_dir_txt'}</label> - <input name="vhost_conf_dir" id="vhost_conf_dir" value="{tmpl_var name='vhost_conf_dir'}" size="40" maxlength="255" type="text" class="textInput" /> + --> + <div class="ctrlHolder apache"> + <label for="vhost_conf_dir">{tmpl_var name='vhost_conf_dir_txt'}</label> + <input name="vhost_conf_dir" id="vhost_conf_dir" value="{tmpl_var name='vhost_conf_dir'}" size="40" maxlength="255" type="text" class="textInput" /> </div> <div class="ctrlHolder apache"> <label for="vhost_conf_enabled_dir">{tmpl_var name='vhost_conf_enabled_dir_txt'}</label> @@ -280,7 +280,7 @@ jQuery('.apache').hide(); } else { jQuery('.nginx').hide(); - jQuery('.apache').show(); - } - } -</script> + jQuery('.apache').show(); + } + } +</script> diff --git a/interface/web/admin/templates/system_config_branding_edit.html b/interface/web/admin/templates/system_config_branding_edit.html index 80ab5a5da71dac6b7810034520183efa1eaad76b..2c4c2e1a628555bab74c64a53c78bf26b3edc683 100644 --- a/interface/web/admin/templates/system_config_branding_edit.html +++ b/interface/web/admin/templates/system_config_branding_edit.html @@ -1,22 +1,22 @@ -<h2><tmpl_var name="list_head_txt"></h2> -<p><tmpl_var name="list_desc_txt"></p> - -<div class="panel panel_system_config"> - - <div class="pnl_formsarea"> - <fieldset class="inlineLabels"><legend><tmpl_var name="branding_txt">Branding</legend> - <div class="ctrlHolder"> - <p class="label">{tmpl_var name='allow_themechange_txt'}Allow users to change theme</p> - <div class="multiField"> - {tmpl_var name='allow_themechange'} - </div> - </div> - </fieldset> - <input type="hidden" name="id" value="{tmpl_var name='id'}"> - <div class="buttonHolder buttons"> - <button class="positive iconstxt icoPositive" type="button" value="{tmpl_var name='btn_save_txt'}" onClick="submitForm('pageForm','admin/system_config_edit.php');"><span>{tmpl_var name='btn_save_txt'}</span></button> - <button class="negative iconstxt icoNegative" type="button" value="{tmpl_var name='btn_cancel_txt'}" onClick="loadContent('admin/server_list.php');"><span>{tmpl_var name='btn_cancel_txt'}</span></button> - </div> - </div> - +<h2><tmpl_var name="list_head_txt"></h2> +<p><tmpl_var name="list_desc_txt"></p> + +<div class="panel panel_system_config"> + + <div class="pnl_formsarea"> + <fieldset class="inlineLabels"><legend><tmpl_var name="branding_txt">Branding</legend> + <div class="ctrlHolder"> + <p class="label">{tmpl_var name='allow_themechange_txt'}Allow users to change theme</p> + <div class="multiField"> + {tmpl_var name='allow_themechange'} + </div> + </div> + </fieldset> + <input type="hidden" name="id" value="{tmpl_var name='id'}"> + <div class="buttonHolder buttons"> + <button class="positive iconstxt icoPositive" type="button" value="{tmpl_var name='btn_save_txt'}" onClick="submitForm('pageForm','admin/system_config_edit.php');"><span>{tmpl_var name='btn_save_txt'}</span></button> + <button class="negative iconstxt icoNegative" type="button" value="{tmpl_var name='btn_cancel_txt'}" onClick="loadContent('admin/server_list.php');"><span>{tmpl_var name='btn_cancel_txt'}</span></button> + </div> + </div> + </div> \ No newline at end of file diff --git a/interface/web/client/client_template_edit.php b/interface/web/client/client_template_edit.php index bb2fd944b48bdd1dabad744c729127698672de87..e14c7465ac431095c4a8477ae10a7d8aa7d86570 100644 --- a/interface/web/client/client_template_edit.php +++ b/interface/web/client/client_template_edit.php @@ -1,97 +1,97 @@ -<?php -/* -Copyright (c) 2007-2010, Till Brehm, projektfarm Gmbh and Oliver Vogel www.muv.com -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of ISPConfig nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -/****************************************** -* Begin Form configuration -******************************************/ - -$tform_def_file = "form/client_template.tform.php"; - -/****************************************** -* End Form configuration -******************************************/ - -require_once('../../lib/config.inc.php'); -require_once('../../lib/app.inc.php'); - -//* Check permissions for module -$app->auth->check_module_permissions('client'); -if(!$_SESSION["s"]["user"]["typ"] == 'admin') die('Client-Templates are only for Admins.'); - -// Loading classes -$app->uses('tpl,tform,tform_actions'); -$app->load('tform_actions'); - -class page_action extends tform_actions { - - function onBeforeUpdate() { - global $app; - - if(isset($this->dataRecord['template_type'])) { - //* Check if the template_type has been changed - $rec = $app->db->queryOneRecord("SELECT template_type from client_template WHERE template_id = ".$this->id); - if($rec['template_type'] != $this->dataRecord['template_type']) { - //* Add a error message and switch back to old server - $app->tform->errorMessage .= $app->lng('The template type can not be changed.'); - $this->dataRecord['template_type'] = $rec['template_type']; - } - unset($rec); - } - } - - - /* - This function is called automatically right after - the data was successful updated in the database. - */ - function onAfterUpdate() { - global $app; - - $app->uses('client_templates'); - /* - * the template has changed. apply the new data to all clients - */ - if ($this->dataRecord["template_type"] == 'm'){ - $sql = "SELECT client_id FROM client WHERE template_master = " . $this->id; - } else { - $sql = "SELECT client_id FROM client WHERE template_additional LIKE '%/" . $this->id . "/%' OR template_additional LIKE '" . $this->id . "/%' OR template_additional LIKE '%/" . $this->id . "' UNION SELECT client_id FROM client_template_assigned WHERE client_template_id = " . $this->id; - } - $clients = $app->db->queryAllRecords($sql); - if (is_array($clients)){ - foreach ($clients as $client){ - $app->client_templates->apply_client_templates($client['client_id']); - } - } - } -} - -$page = new page_action; -$page->onLoad(); -?> +<?php +/* +Copyright (c) 2007-2010, Till Brehm, projektfarm Gmbh and Oliver Vogel www.muv.com +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of ISPConfig nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +/****************************************** +* Begin Form configuration +******************************************/ + +$tform_def_file = "form/client_template.tform.php"; + +/****************************************** +* End Form configuration +******************************************/ + +require_once('../../lib/config.inc.php'); +require_once('../../lib/app.inc.php'); + +//* Check permissions for module +$app->auth->check_module_permissions('client'); +if(!$_SESSION["s"]["user"]["typ"] == 'admin') die('Client-Templates are only for Admins.'); + +// Loading classes +$app->uses('tpl,tform,tform_actions'); +$app->load('tform_actions'); + +class page_action extends tform_actions { + + function onBeforeUpdate() { + global $app; + + if(isset($this->dataRecord['template_type'])) { + //* Check if the template_type has been changed + $rec = $app->db->queryOneRecord("SELECT template_type from client_template WHERE template_id = ".$this->id); + if($rec['template_type'] != $this->dataRecord['template_type']) { + //* Add a error message and switch back to old server + $app->tform->errorMessage .= $app->lng('The template type can not be changed.'); + $this->dataRecord['template_type'] = $rec['template_type']; + } + unset($rec); + } + } + + + /* + This function is called automatically right after + the data was successful updated in the database. + */ + function onAfterUpdate() { + global $app; + + $app->uses('client_templates'); + /* + * the template has changed. apply the new data to all clients + */ + if ($this->dataRecord["template_type"] == 'm'){ + $sql = "SELECT client_id FROM client WHERE template_master = " . $this->id; + } else { + $sql = "SELECT client_id FROM client WHERE template_additional LIKE '%/" . $this->id . "/%' OR template_additional LIKE '" . $this->id . "/%' OR template_additional LIKE '%/" . $this->id . "' UNION SELECT client_id FROM client_template_assigned WHERE client_template_id = " . $this->id; + } + $clients = $app->db->queryAllRecords($sql); + if (is_array($clients)){ + foreach ($clients as $client){ + $app->client_templates->apply_client_templates($client['client_id']); + } + } + } +} + +$page = new page_action; +$page->onLoad(); +?> diff --git a/interface/web/dashboard/dashlets/mailquota.php b/interface/web/dashboard/dashlets/mailquota.php index a65b06ddaa9b44baa86498bb38c2a0234b3c4e23..dd8d72bbf451c84ba59d9d24841414839b7dd290 100644 --- a/interface/web/dashboard/dashlets/mailquota.php +++ b/interface/web/dashboard/dashlets/mailquota.php @@ -1,93 +1,93 @@ -<?php - -class dashlet_mailquota { - - function show() { - global $app, $conf; - - //* Loading Template - $app->uses('tpl'); - - $tpl = new tpl; - $tpl->newTemplate("dashlets/templates/mailquota.htm"); - - $wb = array(); - $lng_file = 'lib/lang/'.$_SESSION['s']['language'].'_dashlet_mailquota.lng'; - if(is_file($lng_file)) include($lng_file); - $tpl->setVar($wb); - - $tmp_rec = $app->db->queryAllRecords("SELECT data from monitor_data WHERE type = 'email_quota' ORDER BY created DESC"); - $monitor_data = array(); - if(is_array($tmp_rec)) { - foreach ($tmp_rec as $tmp_mon) { - //$monitor_data = array_merge_recursive($monitor_data,unserialize($app->db->unquote($tmp_mon['data']))); - $tmp_array = unserialize($app->db->unquote($tmp_mon['data'])); - if(is_array($tmp_array)) { - foreach($tmp_array as $username => $data) { - if(!$monitor_data[$username]['used']) $monitor_data[$username]['used'] = $data['used']; - } - } - } - } - //print_r($monitor_data); - if($_SESSION["s"]["user"]["typ"] != 'admin'){ - $sql_where = " AND sys_groupid = ".$_SESSION['s']['user']['default_group']; - } - - $has_mailquota = false; - // select email accounts belonging to client - $emails = $app->db->queryAllRecords("SELECT * FROM mail_user WHERE 1".$sql_where); - //print_r($emails); - if(is_array($emails) && !empty($emails)){ - for($i=0;$i<sizeof($emails);$i++){ - $email = $emails[$i]['email']; - - $emails[$i]['used'] = isset($monitor_data[$email]['used']) ? $monitor_data[$email]['used'] : array(1 => 0); - - if (!is_numeric($emails[$i]['used'])) $emails[$i]['used']=$emails[$i]['used'][1]; - - // colours - $emails[$i]['display_colour'] = '#000000'; - if($emails[$i]['quota'] > 0){ - $used_ratio = $emails[$i]['used']/$emails[$i]['quota']; - } else { - $used_ratio = 0; - } - if($used_ratio >= 0.8) $emails[$i]['display_colour'] = '#fd934f'; - if($used_ratio >= 1) $emails[$i]['display_colour'] = '#cc0000'; - - if($emails[$i]['quota'] == 0){ - $emails[$i]['quota'] = $app->lng('unlimited'); - } else { - $emails[$i]['quota'] = round($emails[$i]['quota'] / 1048576,4).' MB'; - } - - - if($emails[$i]['used'] < 1544000) { - $emails[$i]['used'] = round($emails[$i]['used'] / 1024,4).' KB'; - } else { - $emails[$i]['used'] = round($emails[$i]['used'] / 1048576,4).' MB'; - } - - } - $has_mailquota = true; - $tpl->setloop('mailquota', $emails); - } - //print_r($sites); - - $tpl->setVar('has_mailquota',$has_mailquota); - - return $tpl->grab(); - - - } -} - - - - - - - - +<?php + +class dashlet_mailquota { + + function show() { + global $app, $conf; + + //* Loading Template + $app->uses('tpl'); + + $tpl = new tpl; + $tpl->newTemplate("dashlets/templates/mailquota.htm"); + + $wb = array(); + $lng_file = 'lib/lang/'.$_SESSION['s']['language'].'_dashlet_mailquota.lng'; + if(is_file($lng_file)) include($lng_file); + $tpl->setVar($wb); + + $tmp_rec = $app->db->queryAllRecords("SELECT data from monitor_data WHERE type = 'email_quota' ORDER BY created DESC"); + $monitor_data = array(); + if(is_array($tmp_rec)) { + foreach ($tmp_rec as $tmp_mon) { + //$monitor_data = array_merge_recursive($monitor_data,unserialize($app->db->unquote($tmp_mon['data']))); + $tmp_array = unserialize($app->db->unquote($tmp_mon['data'])); + if(is_array($tmp_array)) { + foreach($tmp_array as $username => $data) { + if(!$monitor_data[$username]['used']) $monitor_data[$username]['used'] = $data['used']; + } + } + } + } + //print_r($monitor_data); + if($_SESSION["s"]["user"]["typ"] != 'admin'){ + $sql_where = " AND sys_groupid = ".$_SESSION['s']['user']['default_group']; + } + + $has_mailquota = false; + // select email accounts belonging to client + $emails = $app->db->queryAllRecords("SELECT * FROM mail_user WHERE 1".$sql_where); + //print_r($emails); + if(is_array($emails) && !empty($emails)){ + for($i=0;$i<sizeof($emails);$i++){ + $email = $emails[$i]['email']; + + $emails[$i]['used'] = isset($monitor_data[$email]['used']) ? $monitor_data[$email]['used'] : array(1 => 0); + + if (!is_numeric($emails[$i]['used'])) $emails[$i]['used']=$emails[$i]['used'][1]; + + // colours + $emails[$i]['display_colour'] = '#000000'; + if($emails[$i]['quota'] > 0){ + $used_ratio = $emails[$i]['used']/$emails[$i]['quota']; + } else { + $used_ratio = 0; + } + if($used_ratio >= 0.8) $emails[$i]['display_colour'] = '#fd934f'; + if($used_ratio >= 1) $emails[$i]['display_colour'] = '#cc0000'; + + if($emails[$i]['quota'] == 0){ + $emails[$i]['quota'] = $app->lng('unlimited'); + } else { + $emails[$i]['quota'] = round($emails[$i]['quota'] / 1048576,4).' MB'; + } + + + if($emails[$i]['used'] < 1544000) { + $emails[$i]['used'] = round($emails[$i]['used'] / 1024,4).' KB'; + } else { + $emails[$i]['used'] = round($emails[$i]['used'] / 1048576,4).' MB'; + } + + } + $has_mailquota = true; + $tpl->setloop('mailquota', $emails); + } + //print_r($sites); + + $tpl->setVar('has_mailquota',$has_mailquota); + + return $tpl->grab(); + + + } +} + + + + + + + + ?> \ No newline at end of file diff --git a/interface/web/dashboard/dashlets/quota.php b/interface/web/dashboard/dashlets/quota.php index bfbfe73fbac000e9be4beb6d0854dfcc794f8945..a46649ad242b897a3b1b22d5838e05dd85ac7887 100644 --- a/interface/web/dashboard/dashlets/quota.php +++ b/interface/web/dashboard/dashlets/quota.php @@ -1,116 +1,116 @@ -<?php - -class dashlet_quota { - - function show() { - global $app, $conf; - - //* Loading Template - $app->uses('tpl'); - - $tpl = new tpl; - $tpl->newTemplate("dashlets/templates/quota.htm"); - - $wb = array(); - $lng_file = 'lib/lang/'.$_SESSION['s']['language'].'_dashlet_quota.lng'; - if(is_file($lng_file)) include($lng_file); - $tpl->setVar($wb); - - $tmp_rec = $app->db->queryAllRecords("SELECT data from monitor_data WHERE type = 'harddisk_quota' ORDER BY created DESC"); - $monitor_data = array(); - if(is_array($tmp_rec)) { - foreach ($tmp_rec as $tmp_mon) { - $monitor_data = array_merge_recursive($monitor_data,unserialize($app->db->unquote($tmp_mon['data']))); - } - } - //print_r($monitor_data); - if($_SESSION["s"]["user"]["typ"] != 'admin'){ - $sql_where = " AND sys_groupid = ".$_SESSION['s']['user']['default_group']; - } - - $has_quota = false; - // select websites belonging to client - $sites = $app->db->queryAllRecords("SELECT * FROM web_domain WHERE active = 'y'".$sql_where); - //print_r($sites); - if(is_array($sites) && !empty($sites)){ - for($i=0;$i<sizeof($sites);$i++){ - $username = $sites[$i]['system_user']; - $sites[$i]['used'] = $monitor_data['user'][$username]['used']; - $sites[$i]['soft'] = $monitor_data['user'][$username]['soft']; - $sites[$i]['hard'] = $monitor_data['user'][$username]['hard']; - $sites[$i]['files'] = $monitor_data['user'][$username]['files']; - - if (!is_numeric($sites[$i]['used'])){ - if ($sites[$i]['used'][0] > $sites[$i]['used'][1]){ - $sites[$i]['used'] = $sites[$i]['used'][0]; - } else { - $sites[$i]['used'] = $sites[$i]['used'][1]; - } - } - if (!is_numeric($sites[$i]['soft'])) $sites[$i]['soft']=$sites[$i]['soft'][1]; - if (!is_numeric($sites[$i]['hard'])) $sites[$i]['hard']=$sites[$i]['hard'][1]; - if (!is_numeric($sites[$i]['files'])) $sites[$i]['files']=$sites[$i]['files'][1]; - - // colours - $sites[$i]['display_colour'] = '#000000'; - if($sites[$i]['soft'] > 0){ - $used_ratio = $sites[$i]['used']/$sites[$i]['soft']; - } else { - $used_ratio = 0; - } - if($used_ratio >= 0.8) $sites[$i]['display_colour'] = '#fd934f'; - if($used_ratio >= 1) $sites[$i]['display_colour'] = '#cc0000'; - - if($sites[$i]['used'] > 1024) { - $sites[$i]['used'] = round($sites[$i]['used'] / 1024,2).' MB'; - } else { - if ($sites[$i]['used'] != '') $sites[$i]['used'] .= ' KB'; - } - - if($sites[$i]['soft'] > 1024) { - $sites[$i]['soft'] = round($sites[$i]['soft'] / 1024,2).' MB'; - } else { - $sites[$i]['soft'] .= ' KB'; - } - - if($sites[$i]['hard'] > 1024) { - $sites[$i]['hard'] = round($sites[$i]['hard'] / 1024,2).' MB'; - } else { - $sites[$i]['hard'] .= ' KB'; - } - - if($sites[$i]['soft'] == " KB") $sites[$i]['soft'] = $app->lng('unlimited'); - if($sites[$i]['hard'] == " KB") $sites[$i]['hard'] = $app->lng('unlimited'); - - - /* - if(!strstr($sites[$i]['used'],'M') && !strstr($sites[$i]['used'],'K')) $sites[$i]['used'].= ' B'; - if(!strstr($sites[$i]['soft'],'M') && !strstr($sites[$i]['soft'],'K')) $sites[$i]['soft'].= ' B'; - if(!strstr($sites[$i]['hard'],'M') && !strstr($sites[$i]['hard'],'K')) $sites[$i]['hard'].= ' B'; - */ - - if($sites[$i]['soft'] == '0 B' || $sites[$i]['soft'] == '0 KB' || $sites[$i]['soft'] == '0') $sites[$i]['soft'] = $app->lng('unlimited'); - if($sites[$i]['hard'] == '0 B' || $sites[$i]['hard'] == '0 KB' || $sites[$i]['hard'] == '0') $sites[$i]['hard'] = $app->lng('unlimited'); - - } - $has_quota = true; - $tpl->setloop('quota', $sites); - } - //print_r($sites); - - $tpl->setVar('has_quota',$has_quota); - - return $tpl->grab(); - - - } -} - - - - - - - - +<?php + +class dashlet_quota { + + function show() { + global $app, $conf; + + //* Loading Template + $app->uses('tpl'); + + $tpl = new tpl; + $tpl->newTemplate("dashlets/templates/quota.htm"); + + $wb = array(); + $lng_file = 'lib/lang/'.$_SESSION['s']['language'].'_dashlet_quota.lng'; + if(is_file($lng_file)) include($lng_file); + $tpl->setVar($wb); + + $tmp_rec = $app->db->queryAllRecords("SELECT data from monitor_data WHERE type = 'harddisk_quota' ORDER BY created DESC"); + $monitor_data = array(); + if(is_array($tmp_rec)) { + foreach ($tmp_rec as $tmp_mon) { + $monitor_data = array_merge_recursive($monitor_data,unserialize($app->db->unquote($tmp_mon['data']))); + } + } + //print_r($monitor_data); + if($_SESSION["s"]["user"]["typ"] != 'admin'){ + $sql_where = " AND sys_groupid = ".$_SESSION['s']['user']['default_group']; + } + + $has_quota = false; + // select websites belonging to client + $sites = $app->db->queryAllRecords("SELECT * FROM web_domain WHERE active = 'y'".$sql_where); + //print_r($sites); + if(is_array($sites) && !empty($sites)){ + for($i=0;$i<sizeof($sites);$i++){ + $username = $sites[$i]['system_user']; + $sites[$i]['used'] = $monitor_data['user'][$username]['used']; + $sites[$i]['soft'] = $monitor_data['user'][$username]['soft']; + $sites[$i]['hard'] = $monitor_data['user'][$username]['hard']; + $sites[$i]['files'] = $monitor_data['user'][$username]['files']; + + if (!is_numeric($sites[$i]['used'])){ + if ($sites[$i]['used'][0] > $sites[$i]['used'][1]){ + $sites[$i]['used'] = $sites[$i]['used'][0]; + } else { + $sites[$i]['used'] = $sites[$i]['used'][1]; + } + } + if (!is_numeric($sites[$i]['soft'])) $sites[$i]['soft']=$sites[$i]['soft'][1]; + if (!is_numeric($sites[$i]['hard'])) $sites[$i]['hard']=$sites[$i]['hard'][1]; + if (!is_numeric($sites[$i]['files'])) $sites[$i]['files']=$sites[$i]['files'][1]; + + // colours + $sites[$i]['display_colour'] = '#000000'; + if($sites[$i]['soft'] > 0){ + $used_ratio = $sites[$i]['used']/$sites[$i]['soft']; + } else { + $used_ratio = 0; + } + if($used_ratio >= 0.8) $sites[$i]['display_colour'] = '#fd934f'; + if($used_ratio >= 1) $sites[$i]['display_colour'] = '#cc0000'; + + if($sites[$i]['used'] > 1024) { + $sites[$i]['used'] = round($sites[$i]['used'] / 1024,2).' MB'; + } else { + if ($sites[$i]['used'] != '') $sites[$i]['used'] .= ' KB'; + } + + if($sites[$i]['soft'] > 1024) { + $sites[$i]['soft'] = round($sites[$i]['soft'] / 1024,2).' MB'; + } else { + $sites[$i]['soft'] .= ' KB'; + } + + if($sites[$i]['hard'] > 1024) { + $sites[$i]['hard'] = round($sites[$i]['hard'] / 1024,2).' MB'; + } else { + $sites[$i]['hard'] .= ' KB'; + } + + if($sites[$i]['soft'] == " KB") $sites[$i]['soft'] = $app->lng('unlimited'); + if($sites[$i]['hard'] == " KB") $sites[$i]['hard'] = $app->lng('unlimited'); + + + /* + if(!strstr($sites[$i]['used'],'M') && !strstr($sites[$i]['used'],'K')) $sites[$i]['used'].= ' B'; + if(!strstr($sites[$i]['soft'],'M') && !strstr($sites[$i]['soft'],'K')) $sites[$i]['soft'].= ' B'; + if(!strstr($sites[$i]['hard'],'M') && !strstr($sites[$i]['hard'],'K')) $sites[$i]['hard'].= ' B'; + */ + + if($sites[$i]['soft'] == '0 B' || $sites[$i]['soft'] == '0 KB' || $sites[$i]['soft'] == '0') $sites[$i]['soft'] = $app->lng('unlimited'); + if($sites[$i]['hard'] == '0 B' || $sites[$i]['hard'] == '0 KB' || $sites[$i]['hard'] == '0') $sites[$i]['hard'] = $app->lng('unlimited'); + + } + $has_quota = true; + $tpl->setloop('quota', $sites); + } + //print_r($sites); + + $tpl->setVar('has_quota',$has_quota); + + return $tpl->grab(); + + + } +} + + + + + + + + ?> \ No newline at end of file diff --git a/interface/web/mail/templates/user_quota_stats_list.htm b/interface/web/mail/templates/user_quota_stats_list.htm index c2a539739977de00b24d41a61d577fbf2df530a9..e700557abcb911b5695122eab8185d351917ae3f 100644 --- a/interface/web/mail/templates/user_quota_stats_list.htm +++ b/interface/web/mail/templates/user_quota_stats_list.htm @@ -1,54 +1,54 @@ -<h2><tmpl_var name="list_head_txt"></h2> - -<div class="panel panel_list_user_quota_stats"> - - <div class="pnl_listarea"> - <fieldset><legend><tmpl_var name="list_head_txt"></legend> - <table class="list"> - <thead> - <tr class="caption"> - <th class="tbl_col_email" scope="col"><tmpl_var name="email_txt"></th> - <th class="tbl_col_name" scope="col"><tmpl_var name="name_txt"></th> - <th class="tbl_col_used_sort" scope="col"><tmpl_var name="used_txt"></th> - <th class="tbl_col_quota" scope="col"><tmpl_var name="quota_txt"></th> - <th class="tbl_col_percentage_sort" scope="col"><tmpl_var name="percentage_txt"></th> - <th class="tbl_col_limit" scope="col">{tmpl_var name='search_limit'}</th> - </tr> - <tr class="filter"> - <td class="tbl_col_email"><input type="text" name="search_email" value="{tmpl_var name='search_email'}" /></td> - <td class="tbl_col_name"><input type="text" name="search_system_user" value="{tmpl_var name='search_name'}" /></td> - <td class="tbl_col_used"> </td> - <td class="tbl_col_quota"> </td> - <td class="tbl_col_percentage"> </td> - <td class="tbl_col_buttons"> - <button type="button" class="button icons16 icoFilter" name="Filter" id="Filter" value="{tmpl_var name="filter_txt"}" onclick="submitForm('pageForm','mail/user_quota_stats.php');"><span>{tmpl_var name="filter_txt"}</span></button> - </td> - </tr> - </thead> - <tbody> - <tmpl_loop name="records"> - <tr class="tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>"> - <td class="tbl_col_email"><a href="#" onclick="loadContent('mail/mail_user_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="email"}</a></td> - <td class="tbl_col_name"><a href="#" onclick="loadContent('mail/mail_user_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="name"}</a></td> - <td class="tbl_col_used"><a href="#" onclick="loadContent('mail/mail_user_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="used"}</a></td> - <td class="tbl_col_quota"><a href="#" onclick="loadContent('mail/mail_user_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="quota"}</a></td> - <td class="tbl_col_percentage"><a href="#" onclick="loadContent('mail/mail_user_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="percentage"}</a></td> - <td class="tbl_col_buttons"></td> - </tr> - </tmpl_loop> - <tmpl_unless name="records"> - <tr class="tbl_row_noresults tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>"> - <td colspan="6">{tmpl_var name='globalsearch_noresults_text_txt'}</td> - </tr> - </tmpl_unless> - </tbody> - <tfoot> - <tr> - <td class="tbl_footer tbl_paging" colspan="6"><tmpl_var name="paging"></td> - </tr> - </tfoot> - </table> - </fieldset> - </div> - -</div> +<h2><tmpl_var name="list_head_txt"></h2> + +<div class="panel panel_list_user_quota_stats"> + + <div class="pnl_listarea"> + <fieldset><legend><tmpl_var name="list_head_txt"></legend> + <table class="list"> + <thead> + <tr class="caption"> + <th class="tbl_col_email" scope="col"><tmpl_var name="email_txt"></th> + <th class="tbl_col_name" scope="col"><tmpl_var name="name_txt"></th> + <th class="tbl_col_used_sort" scope="col"><tmpl_var name="used_txt"></th> + <th class="tbl_col_quota" scope="col"><tmpl_var name="quota_txt"></th> + <th class="tbl_col_percentage_sort" scope="col"><tmpl_var name="percentage_txt"></th> + <th class="tbl_col_limit" scope="col">{tmpl_var name='search_limit'}</th> + </tr> + <tr class="filter"> + <td class="tbl_col_email"><input type="text" name="search_email" value="{tmpl_var name='search_email'}" /></td> + <td class="tbl_col_name"><input type="text" name="search_system_user" value="{tmpl_var name='search_name'}" /></td> + <td class="tbl_col_used"> </td> + <td class="tbl_col_quota"> </td> + <td class="tbl_col_percentage"> </td> + <td class="tbl_col_buttons"> + <button type="button" class="button icons16 icoFilter" name="Filter" id="Filter" value="{tmpl_var name="filter_txt"}" onclick="submitForm('pageForm','mail/user_quota_stats.php');"><span>{tmpl_var name="filter_txt"}</span></button> + </td> + </tr> + </thead> + <tbody> + <tmpl_loop name="records"> + <tr class="tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>"> + <td class="tbl_col_email"><a href="#" onclick="loadContent('mail/mail_user_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="email"}</a></td> + <td class="tbl_col_name"><a href="#" onclick="loadContent('mail/mail_user_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="name"}</a></td> + <td class="tbl_col_used"><a href="#" onclick="loadContent('mail/mail_user_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="used"}</a></td> + <td class="tbl_col_quota"><a href="#" onclick="loadContent('mail/mail_user_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="quota"}</a></td> + <td class="tbl_col_percentage"><a href="#" onclick="loadContent('mail/mail_user_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="percentage"}</a></td> + <td class="tbl_col_buttons"></td> + </tr> + </tmpl_loop> + <tmpl_unless name="records"> + <tr class="tbl_row_noresults tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>"> + <td colspan="6">{tmpl_var name='globalsearch_noresults_text_txt'}</td> + </tr> + </tmpl_unless> + </tbody> + <tfoot> + <tr> + <td class="tbl_footer tbl_paging" colspan="6"><tmpl_var name="paging"></td> + </tr> + </tfoot> + </table> + </fieldset> + </div> + +</div> diff --git a/interface/web/monitor/templates/show_sys_state.htm b/interface/web/monitor/templates/show_sys_state.htm index 55aeeb28a248d3e003f777a557ce0acdb919f3a9..ceb419573db13061630c460b831f8bf6337de919 100644 --- a/interface/web/monitor/templates/show_sys_state.htm +++ b/interface/web/monitor/templates/show_sys_state.htm @@ -1,25 +1,25 @@ -<h2><tmpl_var name="list_head_txt"></h2> -<p><tmpl_var name="list_desc_txt"></p> - -<div class="panel panel_sys_state"> - - <div class="pnl_toolsarea"> - <fieldset class="inlineLabels"><legend><tmpl_var name="monTransRefreshsq"></legend> - <div class="buttons"> - <div class="ctrlHolder"> - <label for="refreshinterval"> </label> - <select name="refreshinterval" id="refreshinterval" class="selectInput withicons" onChange="loadContentRefresh('monitor/show_sys_state.php?state={tmpl_var name="state_type"}')"> - {tmpl_var name='refresh'} - </select> - </div> - </div> - </fieldset> - </div> - - <div class="pnl_formarea"> - <fieldset><legend></legend> - <div class="stateview"><tmpl_var name="state_data"></div> - </fieldset> - </div> - +<h2><tmpl_var name="list_head_txt"></h2> +<p><tmpl_var name="list_desc_txt"></p> + +<div class="panel panel_sys_state"> + + <div class="pnl_toolsarea"> + <fieldset class="inlineLabels"><legend><tmpl_var name="monTransRefreshsq"></legend> + <div class="buttons"> + <div class="ctrlHolder"> + <label for="refreshinterval"> </label> + <select name="refreshinterval" id="refreshinterval" class="selectInput withicons" onChange="loadContentRefresh('monitor/show_sys_state.php?state={tmpl_var name="state_type"}')"> + {tmpl_var name='refresh'} + </select> + </div> + </div> + </fieldset> + </div> + + <div class="pnl_formarea"> + <fieldset><legend></legend> + <div class="stateview"><tmpl_var name="state_data"></div> + </fieldset> + </div> + </div> \ No newline at end of file diff --git a/interface/web/sites/aps_cron_apscrawler_if.php b/interface/web/sites/aps_cron_apscrawler_if.php index d1e15cc963860d9e4911a1396d211cac407dedd2..caa9b02d75189eac40e74429894cd19f04ebebd7 100644 --- a/interface/web/sites/aps_cron_apscrawler_if.php +++ b/interface/web/sites/aps_cron_apscrawler_if.php @@ -1,63 +1,63 @@ -<?php -/* -Copyright (c) 2012, ISPConfig UG -Contributors: web wack creations, http://www.web-wack.at -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of ISPConfig nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -require_once('../../lib/config.inc.php'); -require_once('../../lib/app.inc.php'); - -//require_once('classes/class.crawler.php'); -$app->load('aps_crawler'); - -if(!@ini_get('allow_url_fopen')) $app->error('allow_url_fopen is not enabled.'); -if(!function_exists('curl_version')) $app->error('The PHP CURL extension is not available.'); - -$log_prefix = 'APS crawler cron: '; - -$aps = new ApsCrawler($app, true); // true = Interface mode, false = Server mode - -$app->log($log_prefix.'Used mem at begin: '.$aps->convertSize(memory_get_usage(true))); - -$time_start = microtime(true); -$aps->startCrawler(); -$aps->parseFolderToDB(); -$aps->fixURLs(); -$time = microtime(true) - $time_start; - -$app->log($log_prefix.'Used mem at end: '.$aps->convertSize(memory_get_usage(true))); -$app->log($log_prefix.'Mem peak during execution: '.$aps->convertSize(memory_get_peak_usage(true))); -$app->log($log_prefix.'Execution time: '.round($time, 3).' seconds'); - -// Load the language file -$lngfile = 'lib/lang/'.$_SESSION['s']['language'].'_aps.lng'; -$app->load_language_file('web/sites/'.$lngfile); - -echo '<div id="OKMsg"><p>'.$app->lng('packagelist_update_finished_txt').'</p></div>'; - - - +<?php +/* +Copyright (c) 2012, ISPConfig UG +Contributors: web wack creations, http://www.web-wack.at +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of ISPConfig nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +require_once('../../lib/config.inc.php'); +require_once('../../lib/app.inc.php'); + +//require_once('classes/class.crawler.php'); +$app->load('aps_crawler'); + +if(!@ini_get('allow_url_fopen')) $app->error('allow_url_fopen is not enabled.'); +if(!function_exists('curl_version')) $app->error('The PHP CURL extension is not available.'); + +$log_prefix = 'APS crawler cron: '; + +$aps = new ApsCrawler($app, true); // true = Interface mode, false = Server mode + +$app->log($log_prefix.'Used mem at begin: '.$aps->convertSize(memory_get_usage(true))); + +$time_start = microtime(true); +$aps->startCrawler(); +$aps->parseFolderToDB(); +$aps->fixURLs(); +$time = microtime(true) - $time_start; + +$app->log($log_prefix.'Used mem at end: '.$aps->convertSize(memory_get_usage(true))); +$app->log($log_prefix.'Mem peak during execution: '.$aps->convertSize(memory_get_peak_usage(true))); +$app->log($log_prefix.'Execution time: '.round($time, 3).' seconds'); + +// Load the language file +$lngfile = 'lib/lang/'.$_SESSION['s']['language'].'_aps.lng'; +$app->load_language_file('web/sites/'.$lngfile); + +echo '<div id="OKMsg"><p>'.$app->lng('packagelist_update_finished_txt').'</p></div>'; + + + ?> \ No newline at end of file diff --git a/interface/web/sites/aps_do_operation.php b/interface/web/sites/aps_do_operation.php index ad165f33bc44f4288b7df41f21fac85ae3d710c2..ada193c759cd5e7193ab4813999d93b9cd5fa20b 100644 --- a/interface/web/sites/aps_do_operation.php +++ b/interface/web/sites/aps_do_operation.php @@ -1,112 +1,112 @@ -<?php -/* -Copyright (c) 2012, ISPConfig UG -Contributors: web wack creations, http://www.web-wack.at -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of ISPConfig nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -require_once('../../lib/config.inc.php'); -require_once('../../lib/app.inc.php'); -$app->load('aps_guicontroller'); - -// Check the module permissions -$app->auth->check_module_permissions('sites'); - -$gui = new ApsGUIController($app); - -// An action and ID are required in any case -if(!isset($_GET['action'])) die('No action'); - -// List of operations which can be performed -if($_GET['action'] == 'change_status') -{ - // Only admins can perform this operation - if($_SESSION['s']['user']['typ'] != 'admin') die('For admin use only.'); - - // Make sure a valid package ID is given - if(!$gui->isValidPackageID($_GET['id'], true)) die($app->lng('Invalid ID')); - - // Change the existing status to the opposite - $get_status = $app->db->queryOneRecord("SELECT package_status FROM aps_packages WHERE id = '".$app->functions->intval($_GET['id'])."';"); - if($get_status['package_status'] == strval(PACKAGE_LOCKED)) - { - $app->db->query("UPDATE aps_packages SET package_status = ".PACKAGE_ENABLED." WHERE id = '".$app->functions->intval($_GET['id'])."';"); - echo '<div class="swap" id="ir-Yes"><span>'.$app->lng('Yes').'</span></div>'; - } - else - { - $app->db->query("UPDATE aps_packages SET Package_status = ".PACKAGE_LOCKED." WHERE id = '".$app->functions->intval($_GET['id'])."';"); - echo '<div class="swap" id="ir-No"><span>'.$app->lng('No').'</span></div>'; - } -} -else if($_GET['action'] == 'delete_instance') -{ - // Make sure a valid package ID is given (also corresponding to the calling user) - $client_id = 0; - $is_admin = ($_SESSION['s']['user']['typ'] == 'admin') ? true : false; - if(!$is_admin) - { - $cid = $app->db->queryOneRecord("SELECT client_id FROM client WHERE username = '".$app->db->quote($_SESSION['s']['user']['username'])."';"); - $client_id = $cid['client_id']; - } - - // Assume that the given instance belongs to the currently calling client_id. Unimportant if status is admin - if(!$gui->isValidInstanceID($_GET['id'], $client_id, $is_admin)) die($app->lng('Invalid ID')); - - // Only delete the instance if the status is "installed" or "flawed" - $check = $app->db->queryOneRecord("SELECT id FROM aps_instances - WHERE id = ".$app->db->quote($_GET['id'])." AND - (instance_status = ".INSTANCE_SUCCESS." OR instance_status = ".INSTANCE_ERROR.");"); - if($check['id'] > 0) $gui->deleteInstance($_GET['id']); - //echo $app->lng('Installation_remove'); - @header('Location:aps_installedpackages_list.php'); -} -else if($_GET['action'] == 'reinstall_instance') -{ - // Make sure a valid package ID is given (also corresponding to the calling user) - $client_id = 0; - $is_admin = ($_SESSION['s']['user']['typ'] == 'admin') ? true : false; - if(!$is_admin) - { - $cid = $app->db->queryOneRecord("SELECT client_id FROM client WHERE username = '".$app->db->quote($_SESSION['s']['user']['username'])."';"); - $client_id = $cid['client_id']; - } - // Assume that the given instance belongs to the currently calling client_id. Unimportant if status is admin - if(!$gui->isValidInstanceID($_GET['id'], $client_id, $is_admin)) die($app->lng('Invalid ID')); - - // We've an InstanceID, so make sure the package is not enabled and InstanceStatus is still "installed" - $check = $app->db->queryOneRecord("SELECT aps_instances.id FROM aps_instances, aps_packages - WHERE aps_instances.package_id = aps_packages.id - AND aps_instances.instance_status = ".INSTANCE_SUCCESS." - AND aps_packages.package_status = ".PACKAGE_ENABLED." - AND aps_instances.id = ".$app->db->quote($_GET['id']).";"); - if(!$check) die('Check failed'); // normally this might not happen at all, so just die - - $gui->reinstallInstance($_GET['id']); - //echo $app->lng('Installation_task'); - @header('Location:aps_installedpackages_list.php'); -} -?> +<?php +/* +Copyright (c) 2012, ISPConfig UG +Contributors: web wack creations, http://www.web-wack.at +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of ISPConfig nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +require_once('../../lib/config.inc.php'); +require_once('../../lib/app.inc.php'); +$app->load('aps_guicontroller'); + +// Check the module permissions +$app->auth->check_module_permissions('sites'); + +$gui = new ApsGUIController($app); + +// An action and ID are required in any case +if(!isset($_GET['action'])) die('No action'); + +// List of operations which can be performed +if($_GET['action'] == 'change_status') +{ + // Only admins can perform this operation + if($_SESSION['s']['user']['typ'] != 'admin') die('For admin use only.'); + + // Make sure a valid package ID is given + if(!$gui->isValidPackageID($_GET['id'], true)) die($app->lng('Invalid ID')); + + // Change the existing status to the opposite + $get_status = $app->db->queryOneRecord("SELECT package_status FROM aps_packages WHERE id = '".$app->functions->intval($_GET['id'])."';"); + if($get_status['package_status'] == strval(PACKAGE_LOCKED)) + { + $app->db->query("UPDATE aps_packages SET package_status = ".PACKAGE_ENABLED." WHERE id = '".$app->functions->intval($_GET['id'])."';"); + echo '<div class="swap" id="ir-Yes"><span>'.$app->lng('Yes').'</span></div>'; + } + else + { + $app->db->query("UPDATE aps_packages SET Package_status = ".PACKAGE_LOCKED." WHERE id = '".$app->functions->intval($_GET['id'])."';"); + echo '<div class="swap" id="ir-No"><span>'.$app->lng('No').'</span></div>'; + } +} +else if($_GET['action'] == 'delete_instance') +{ + // Make sure a valid package ID is given (also corresponding to the calling user) + $client_id = 0; + $is_admin = ($_SESSION['s']['user']['typ'] == 'admin') ? true : false; + if(!$is_admin) + { + $cid = $app->db->queryOneRecord("SELECT client_id FROM client WHERE username = '".$app->db->quote($_SESSION['s']['user']['username'])."';"); + $client_id = $cid['client_id']; + } + + // Assume that the given instance belongs to the currently calling client_id. Unimportant if status is admin + if(!$gui->isValidInstanceID($_GET['id'], $client_id, $is_admin)) die($app->lng('Invalid ID')); + + // Only delete the instance if the status is "installed" or "flawed" + $check = $app->db->queryOneRecord("SELECT id FROM aps_instances + WHERE id = ".$app->db->quote($_GET['id'])." AND + (instance_status = ".INSTANCE_SUCCESS." OR instance_status = ".INSTANCE_ERROR.");"); + if($check['id'] > 0) $gui->deleteInstance($_GET['id']); + //echo $app->lng('Installation_remove'); + @header('Location:aps_installedpackages_list.php'); +} +else if($_GET['action'] == 'reinstall_instance') +{ + // Make sure a valid package ID is given (also corresponding to the calling user) + $client_id = 0; + $is_admin = ($_SESSION['s']['user']['typ'] == 'admin') ? true : false; + if(!$is_admin) + { + $cid = $app->db->queryOneRecord("SELECT client_id FROM client WHERE username = '".$app->db->quote($_SESSION['s']['user']['username'])."';"); + $client_id = $cid['client_id']; + } + // Assume that the given instance belongs to the currently calling client_id. Unimportant if status is admin + if(!$gui->isValidInstanceID($_GET['id'], $client_id, $is_admin)) die($app->lng('Invalid ID')); + + // We've an InstanceID, so make sure the package is not enabled and InstanceStatus is still "installed" + $check = $app->db->queryOneRecord("SELECT aps_instances.id FROM aps_instances, aps_packages + WHERE aps_instances.package_id = aps_packages.id + AND aps_instances.instance_status = ".INSTANCE_SUCCESS." + AND aps_packages.package_status = ".PACKAGE_ENABLED." + AND aps_instances.id = ".$app->db->quote($_GET['id']).";"); + if(!$check) die('Check failed'); // normally this might not happen at all, so just die + + $gui->reinstallInstance($_GET['id']); + //echo $app->lng('Installation_task'); + @header('Location:aps_installedpackages_list.php'); +} +?> diff --git a/interface/web/sites/aps_install_package.php b/interface/web/sites/aps_install_package.php index b7bed71be3ae8ab3c49f01ee955b43572a4174f7..ccad334993d2770cc0998468e7943372f0373087 100644 --- a/interface/web/sites/aps_install_package.php +++ b/interface/web/sites/aps_install_package.php @@ -1,211 +1,211 @@ -<?php -/* -Copyright (c) 2012, ISPConfig UG -Contributors: web wack creations, http://www.web-wack.at -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of ISPConfig nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -require_once('../../lib/config.inc.php'); -require_once('../../lib/app.inc.php'); -//require_once('classes/class.guicontroller.php'); -$app->load('aps_guicontroller'); - -// Check the module permissions -$app->auth->check_module_permissions('sites'); - -// Load needed classes -$app->uses('tpl,tform'); -$app->tpl->newTemplate("form.tpl.htm"); -$app->tpl->setInclude('content_tpl', 'templates/aps_install_package.htm'); - -// Load the language file -$lngfile = 'lib/lang/'.$_SESSION['s']['language'].'_aps.lng'; -require_once($lngfile); -$app->tpl->setVar($wb); -$app->load_language_file('web/sites/'.$lngfile); - -// we will check only users, not admins -if($_SESSION["s"]["user"]["typ"] == 'user') { - $app->tform->formDef['db_table_idx'] = 'client_id'; - $app->tform->formDef['db_table'] = 'client'; - if(!$app->tform->checkClientLimit('limit_aps')) { - $app->error($app->lng("limit_aps_txt")); - } - if(!$app->tform->checkResellerLimit('limit_aps')) { - $app->error('Reseller: '.$wb["limit_aps_txt"]); - } -} - - -$adminflag = ($_SESSION['s']['user']['typ'] == 'admin') ? true : false; -$gui = new ApsGUIController($app); -$pkg_id = (isset($_GET['id'])) ? $app->db->quote($_GET['id']) : ''; - -// Check if a newer version is available for the current package -// Note: It's intended that here is no strict ID check (see below) -if(isset($pkg_id)) -{ - $newest_pkg_id = $gui->getNewestPackageID($pkg_id); - if($newest_pkg_id != 0) $pkg_id = $newest_pkg_id; -} - -// Make sure an integer ID is given -if(!isset($pkg_id) || !$gui->isValidPackageID($pkg_id, $adminflag)) - $app->error($app->lng('Invalid ID')); - -// Get package details -$details = $gui->getPackageDetails($pkg_id); -if(isset($details['error'])) $app->error($details['error']); -$settings = $gui->getPackageSettings($pkg_id); -if(isset($settings['error'])) $app->error($settings['error']); - -// Get domain list -$domains = array(); -$domain_for_user = ''; -if(!$adminflag) $domain_for_user = "AND (sys_userid = '".$app->db->quote($_SESSION['s']['user']['userid'])."' - OR sys_groupid = '".$app->db->quote($_SESSION['s']['user']['userid'])."' )"; -$domains_assoc = $app->db->queryAllRecords("SELECT domain FROM web_domain WHERE document_root != '' AND (type = 'vhost' OR type = 'vhostsubdomain') AND active = 'y' ".$domain_for_user." ORDER BY domain;"); -if(!empty($domains_assoc)) foreach($domains_assoc as $domain) $domains[] = $domain['domain']; - -// If data has been submitted, validate it -$result['input'] = array(); -if(count($_POST) > 1) -{ - $result = $gui->validateInstallerInput($_POST, $details, $domains, $settings); - if(empty($result['error'])) - { - $gui->createPackageInstance($result['input'], $pkg_id); - @header('Location:aps_installedpackages_list.php'); - } - else - { - $app->tpl->setVar('error', implode('<br />', $result['error'])); - - // Set memorized values (license, db password, install location) - if(!empty($result['input'])) - foreach($result['input'] as $key => $value) $app->tpl->setVar('inp_'.$key, $value); - } -} -else $app->tpl->setVar('inp_main_database_password', ucfirst(substr(md5(crypt(rand(0, 10))), 0, 16))); - -// Pass the package details to the template -foreach($details as $key => $value) -{ - if(!is_array($value)) $app->tpl->setVar('pkg_'.str_replace(' ', '_', strtolower($key)), $value); - else if($key == 'Requirements PHP settings') $app->tpl->setLoop('pkg_requirements_php_settings', $details['Requirements PHP settings']); -} - -// Parse the template as far as possible, then do the rest manually -$app->tpl_defaults(); -$parsed_tpl = $app->tpl->grab(); - - -// ISPConfig has a very old and functionally limited template engine. We have to style parts on our own... - -// Print the domain list -$domains_tpl = ''; -if(!empty($domains)) -{ - $set = array(); - $set[] = '<select name="main_domain" id="main_domain" class="selectInput">'; - foreach($domains as $domain) - { - $selected = ''; - if((count($_POST) > 1) - && (isset($result['input']['main_domain'])) - && ($result['input']['main_domain'] == $domain)) - $selected = ' selected '; - $set[] = '<option value="'.$domain.'" '.$selected.'>'.$domain.'</option>'; - } - $set[] = '</select>'; - - $domains_tpl = implode("\n", $set); -} -$parsed_tpl = str_replace('DOMAIN_LIST_SPACE', $domains_tpl, $parsed_tpl); - -// Print the packgae settings -$settings_tpl = ''; -if(!empty($settings)) -{ - $set = array(); - $set[] = '<legend>'.$app->lng('package_settings_txt').'</legend>'; - foreach($settings as $setting) - { - $set[] = '<div class="ctrlHolder">'; - $set[] = '<label for="'.$setting['SettingID'].'">'.$setting['SettingName'].'</label>'; - if($setting['SettingInputType'] == 'string' || $setting['SettingInputType'] == 'password') - { - $input_type = ($setting['SettingInputType'] == 'string') ? 'text' : 'password'; - - $input_value = ''; - if((count($_POST) > 1) - && (isset($result['input'][$setting['SettingID']]))) - $input_value = $result['input'][$setting['SettingID']]; - else $input_value = @$setting['SettingDefaultValue']; - - $set[] = '<input type="'.$input_type.'" class="textInput" name="'.$setting['SettingID'].'" maxlength="'.$setting['SettingMaxLength'].'" id="'.$setting['SettingID'].'" value="'.$input_value.'" /> - <p class="formHint">'.$setting['SettingDescription'].'</p>'; - } - else if($setting['SettingInputType'] == 'checkbox') - { - $checked = ''; - if((count($_POST) > 1) - && (isset($result['input'][$setting['SettingID']]) - && ($result['input'][$setting['SettingID']] == 'true'))) - $checked = 'checked '; - else if($setting['SettingDefaultValue'] == '1') $checked = 'checked '; - - $set[] = '<input type="checkbox" id="'.$setting['SettingID'].'" name="'.$setting['SettingID'].'" '.$checked.'/> - <p class="formHint">'.$setting['SettingDescription'].'</p>'; - } - else if($setting['SettingInputType'] == 'select') - { - $set[] = '<select size="1" class="selectInput" name="'.$setting['SettingID'].'">'; - foreach($setting['SettingChoices'] as $choice) - { - $selected = ''; - if((count($_POST) > 1) - && (isset($result['input'][$setting['SettingID']]))) - { - if($result['input'][$setting['SettingID']] == $choice['EnumID']) - $selected = 'selected '; - } - else if($setting['SettingDefaultValue'] == $choice['EnumID']) $selected = 'selected '; - - $set[] = '<option value="'.$choice['EnumID'].'" '.$selected.'>'.$choice['EnumName'].'</option>'; - } - $set[] = '</select> - <p class="formHint">'.$setting['SettingDescription'].'</p>'; - } - - $set[] = '</div>'; - } - $settings_tpl = implode("\n", $set); -} -$parsed_tpl = str_replace('PKG_SETTINGS_SPACE', $settings_tpl, $parsed_tpl); - -echo $parsed_tpl; +<?php +/* +Copyright (c) 2012, ISPConfig UG +Contributors: web wack creations, http://www.web-wack.at +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of ISPConfig nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +require_once('../../lib/config.inc.php'); +require_once('../../lib/app.inc.php'); +//require_once('classes/class.guicontroller.php'); +$app->load('aps_guicontroller'); + +// Check the module permissions +$app->auth->check_module_permissions('sites'); + +// Load needed classes +$app->uses('tpl,tform'); +$app->tpl->newTemplate("form.tpl.htm"); +$app->tpl->setInclude('content_tpl', 'templates/aps_install_package.htm'); + +// Load the language file +$lngfile = 'lib/lang/'.$_SESSION['s']['language'].'_aps.lng'; +require_once($lngfile); +$app->tpl->setVar($wb); +$app->load_language_file('web/sites/'.$lngfile); + +// we will check only users, not admins +if($_SESSION["s"]["user"]["typ"] == 'user') { + $app->tform->formDef['db_table_idx'] = 'client_id'; + $app->tform->formDef['db_table'] = 'client'; + if(!$app->tform->checkClientLimit('limit_aps')) { + $app->error($app->lng("limit_aps_txt")); + } + if(!$app->tform->checkResellerLimit('limit_aps')) { + $app->error('Reseller: '.$wb["limit_aps_txt"]); + } +} + + +$adminflag = ($_SESSION['s']['user']['typ'] == 'admin') ? true : false; +$gui = new ApsGUIController($app); +$pkg_id = (isset($_GET['id'])) ? $app->db->quote($_GET['id']) : ''; + +// Check if a newer version is available for the current package +// Note: It's intended that here is no strict ID check (see below) +if(isset($pkg_id)) +{ + $newest_pkg_id = $gui->getNewestPackageID($pkg_id); + if($newest_pkg_id != 0) $pkg_id = $newest_pkg_id; +} + +// Make sure an integer ID is given +if(!isset($pkg_id) || !$gui->isValidPackageID($pkg_id, $adminflag)) + $app->error($app->lng('Invalid ID')); + +// Get package details +$details = $gui->getPackageDetails($pkg_id); +if(isset($details['error'])) $app->error($details['error']); +$settings = $gui->getPackageSettings($pkg_id); +if(isset($settings['error'])) $app->error($settings['error']); + +// Get domain list +$domains = array(); +$domain_for_user = ''; +if(!$adminflag) $domain_for_user = "AND (sys_userid = '".$app->db->quote($_SESSION['s']['user']['userid'])."' + OR sys_groupid = '".$app->db->quote($_SESSION['s']['user']['userid'])."' )"; +$domains_assoc = $app->db->queryAllRecords("SELECT domain FROM web_domain WHERE document_root != '' AND (type = 'vhost' OR type = 'vhostsubdomain') AND active = 'y' ".$domain_for_user." ORDER BY domain;"); +if(!empty($domains_assoc)) foreach($domains_assoc as $domain) $domains[] = $domain['domain']; + +// If data has been submitted, validate it +$result['input'] = array(); +if(count($_POST) > 1) +{ + $result = $gui->validateInstallerInput($_POST, $details, $domains, $settings); + if(empty($result['error'])) + { + $gui->createPackageInstance($result['input'], $pkg_id); + @header('Location:aps_installedpackages_list.php'); + } + else + { + $app->tpl->setVar('error', implode('<br />', $result['error'])); + + // Set memorized values (license, db password, install location) + if(!empty($result['input'])) + foreach($result['input'] as $key => $value) $app->tpl->setVar('inp_'.$key, $value); + } +} +else $app->tpl->setVar('inp_main_database_password', ucfirst(substr(md5(crypt(rand(0, 10))), 0, 16))); + +// Pass the package details to the template +foreach($details as $key => $value) +{ + if(!is_array($value)) $app->tpl->setVar('pkg_'.str_replace(' ', '_', strtolower($key)), $value); + else if($key == 'Requirements PHP settings') $app->tpl->setLoop('pkg_requirements_php_settings', $details['Requirements PHP settings']); +} + +// Parse the template as far as possible, then do the rest manually +$app->tpl_defaults(); +$parsed_tpl = $app->tpl->grab(); + + +// ISPConfig has a very old and functionally limited template engine. We have to style parts on our own... + +// Print the domain list +$domains_tpl = ''; +if(!empty($domains)) +{ + $set = array(); + $set[] = '<select name="main_domain" id="main_domain" class="selectInput">'; + foreach($domains as $domain) + { + $selected = ''; + if((count($_POST) > 1) + && (isset($result['input']['main_domain'])) + && ($result['input']['main_domain'] == $domain)) + $selected = ' selected '; + $set[] = '<option value="'.$domain.'" '.$selected.'>'.$domain.'</option>'; + } + $set[] = '</select>'; + + $domains_tpl = implode("\n", $set); +} +$parsed_tpl = str_replace('DOMAIN_LIST_SPACE', $domains_tpl, $parsed_tpl); + +// Print the packgae settings +$settings_tpl = ''; +if(!empty($settings)) +{ + $set = array(); + $set[] = '<legend>'.$app->lng('package_settings_txt').'</legend>'; + foreach($settings as $setting) + { + $set[] = '<div class="ctrlHolder">'; + $set[] = '<label for="'.$setting['SettingID'].'">'.$setting['SettingName'].'</label>'; + if($setting['SettingInputType'] == 'string' || $setting['SettingInputType'] == 'password') + { + $input_type = ($setting['SettingInputType'] == 'string') ? 'text' : 'password'; + + $input_value = ''; + if((count($_POST) > 1) + && (isset($result['input'][$setting['SettingID']]))) + $input_value = $result['input'][$setting['SettingID']]; + else $input_value = @$setting['SettingDefaultValue']; + + $set[] = '<input type="'.$input_type.'" class="textInput" name="'.$setting['SettingID'].'" maxlength="'.$setting['SettingMaxLength'].'" id="'.$setting['SettingID'].'" value="'.$input_value.'" /> + <p class="formHint">'.$setting['SettingDescription'].'</p>'; + } + else if($setting['SettingInputType'] == 'checkbox') + { + $checked = ''; + if((count($_POST) > 1) + && (isset($result['input'][$setting['SettingID']]) + && ($result['input'][$setting['SettingID']] == 'true'))) + $checked = 'checked '; + else if($setting['SettingDefaultValue'] == '1') $checked = 'checked '; + + $set[] = '<input type="checkbox" id="'.$setting['SettingID'].'" name="'.$setting['SettingID'].'" '.$checked.'/> + <p class="formHint">'.$setting['SettingDescription'].'</p>'; + } + else if($setting['SettingInputType'] == 'select') + { + $set[] = '<select size="1" class="selectInput" name="'.$setting['SettingID'].'">'; + foreach($setting['SettingChoices'] as $choice) + { + $selected = ''; + if((count($_POST) > 1) + && (isset($result['input'][$setting['SettingID']]))) + { + if($result['input'][$setting['SettingID']] == $choice['EnumID']) + $selected = 'selected '; + } + else if($setting['SettingDefaultValue'] == $choice['EnumID']) $selected = 'selected '; + + $set[] = '<option value="'.$choice['EnumID'].'" '.$selected.'>'.$choice['EnumName'].'</option>'; + } + $set[] = '</select> + <p class="formHint">'.$setting['SettingDescription'].'</p>'; + } + + $set[] = '</div>'; + } + $settings_tpl = implode("\n", $set); +} +$parsed_tpl = str_replace('PKG_SETTINGS_SPACE', $settings_tpl, $parsed_tpl); + +echo $parsed_tpl; ?> \ No newline at end of file diff --git a/interface/web/sites/aps_installedpackages_list.php b/interface/web/sites/aps_installedpackages_list.php index 00d7b258b160e988804d67ddbda5fd02241a090a..4f3c76598df4c00a02e06525c9d416d06ce450dd 100644 --- a/interface/web/sites/aps_installedpackages_list.php +++ b/interface/web/sites/aps_installedpackages_list.php @@ -1,142 +1,142 @@ -<?php -/* -Copyright (c) 2012, ISPConfig UG -Contributors: web wack creations, http://www.web-wack.at -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of ISPConfig nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -require_once('../../lib/config.inc.php'); -require_once('../../lib/app.inc.php'); -//require_once('classes/class.base.php'); // for constants -$app->load('aps_base'); - -// Path to the list definition file -$list_def_file = "list/aps_installedpackages.list.php"; - -// Check the module permissions -$app->auth->check_module_permissions('sites'); - -// Load needed classes -$app->uses('tpl,tform,listform,listform_actions'); - -// Show further information only to admins or resellers -if($_SESSION['s']['user']['typ'] == 'admin' || $app->auth->has_clients($_SESSION['s']['user']['userid'])) - $app->tpl->setVar('is_noclient', 1); - -// Show each user the own packages (if not admin) -$client_ext = ''; -$is_admin = ($_SESSION['s']['user']['typ'] == 'admin') ? true : false; -if(!$is_admin) -{ - $cid = $app->db->queryOneRecord('SELECT client_id FROM client WHERE username = "'.$app->db->quote($_SESSION['s']['user']['username']).'";'); - //$client_ext = ' AND aps_instances.customer_id = '.$cid['client_id']; - $client_ext = ' AND '.$app->tform->getAuthSQL('r', 'aps_instances'); -} -$app->listform_actions->SQLExtWhere = 'aps_instances.package_id = aps_packages.id'.$client_ext; -$app->listform_actions->SQLOrderBy = 'ORDER BY package_name'; - -// We are using parts of listform_actions because ISPConfig doesn't allow -// queries over multiple tables so we construct them ourselves -$_SESSION['s']['form']['return_to'] = ''; - -// Load the list template -$app->listform->loadListDef($list_def_file); -if(!is_file('templates/'.$app->listform->listDef["name"].'_list.htm')) -{ -$app->uses('listform_tpl_generator'); -$app->listform_tpl_generator->buildHTML($app->listform->listDef); -} -$app->tpl->newTemplate("listpage.tpl.htm"); -$app->tpl->setInclude('content_tpl', 'templates/'.$app->listform->listDef["name"].'_list.htm'); - -// Build the WHERE query for search -$sql_where = ''; -if($app->listform_actions->SQLExtWhere != '') - $sql_where .= ' '.$app->listform_actions->SQLExtWhere.' and'; -$sql_where = $app->listform->getSearchSQL($sql_where); -$app->tpl->setVar($app->listform->searchValues); - -// Paging -$limit_sql = $app->listform->getPagingSQL($sql_where); -$app->tpl->setVar('paging', $app->listform->pagingHTML); - -if(!$is_admin) { -// Our query over multiple tables -$query = "SELECT aps_instances.id AS id, aps_instances.package_id AS package_id, - aps_instances.customer_id AS customer_id, client.username AS customer_name, - aps_instances.instance_status AS instance_status, aps_packages.name AS package_name, - aps_packages.version AS package_version, aps_packages.release AS package_release, - aps_packages.package_status AS package_status, - CONCAT((SELECT value FROM aps_instances_settings WHERE name='main_domain' AND instance_id = aps_instances.id), - '/', (SELECT value FROM aps_instances_settings WHERE name='main_location' AND instance_id = aps_instances.id)) - AS install_location - FROM aps_instances, aps_packages, client - WHERE client.client_id = aps_instances.customer_id AND ".$sql_where." ".$app->listform_actions->SQLOrderBy." ".$limit_sql; -} else { -$query = "SELECT aps_instances.id AS id, aps_instances.package_id AS package_id, - aps_instances.customer_id AS customer_id, sys_group.name AS customer_name, - aps_instances.instance_status AS instance_status, aps_packages.name AS package_name, - aps_packages.version AS package_version, aps_packages.release AS package_release, - aps_packages.package_status AS package_status, - CONCAT((SELECT value FROM aps_instances_settings WHERE name='main_domain' AND instance_id = aps_instances.id), - '/', (SELECT value FROM aps_instances_settings WHERE name='main_location' AND instance_id = aps_instances.id)) - AS install_location - FROM aps_instances, aps_packages, sys_group - WHERE sys_group.client_id = aps_instances.customer_id AND ".$sql_where." ".$app->listform_actions->SQLOrderBy." ".$limit_sql; - -} - -$records = $app->db->queryAllRecords($query); -$app->listform_actions->DataRowColor = '#FFFFFF'; - -// Re-form all result entries and add extra entries -$records_new = ''; -if(is_array($records)) -{ - $app->listform_actions->idx_key = $app->listform->listDef["table_idx"]; - foreach($records as $rec) - { - // Set an abbreviated install location to beware the page layout - $ils = ''; - if(strlen($rec['Install_location']) >= 38) $ils = substr($rec['Install_location'], 0, 35).'...'; - else $ils = $rec['install_location']; - $rec['install_location_short'] = $ils; - - // Also set a boolean-like variable for the reinstall button (vlibTemplate doesn't allow variable comparisons) - // For a reinstall, the package must be already installed successfully and (still be) enabled - if($rec['instance_status'] == INSTANCE_SUCCESS && $rec['package_status'] == PACKAGE_ENABLED) - $rec['reinstall_possible'] = 'true'; - // Of course an instance can only then be removed when it's not already tagged for removal - if($rec['instance_status'] != INSTANCE_REMOVE && $rec['instance_status'] != INSTANCE_INSTALL) - $rec['delete_possible'] = 'true'; - - $records_new[] = $app->listform_actions->prepareDataRow($rec); - } -} -$app->tpl->setLoop('records', $records_new); - -$app->listform_actions->onShow(); +<?php +/* +Copyright (c) 2012, ISPConfig UG +Contributors: web wack creations, http://www.web-wack.at +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of ISPConfig nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +require_once('../../lib/config.inc.php'); +require_once('../../lib/app.inc.php'); +//require_once('classes/class.base.php'); // for constants +$app->load('aps_base'); + +// Path to the list definition file +$list_def_file = "list/aps_installedpackages.list.php"; + +// Check the module permissions +$app->auth->check_module_permissions('sites'); + +// Load needed classes +$app->uses('tpl,tform,listform,listform_actions'); + +// Show further information only to admins or resellers +if($_SESSION['s']['user']['typ'] == 'admin' || $app->auth->has_clients($_SESSION['s']['user']['userid'])) + $app->tpl->setVar('is_noclient', 1); + +// Show each user the own packages (if not admin) +$client_ext = ''; +$is_admin = ($_SESSION['s']['user']['typ'] == 'admin') ? true : false; +if(!$is_admin) +{ + $cid = $app->db->queryOneRecord('SELECT client_id FROM client WHERE username = "'.$app->db->quote($_SESSION['s']['user']['username']).'";'); + //$client_ext = ' AND aps_instances.customer_id = '.$cid['client_id']; + $client_ext = ' AND '.$app->tform->getAuthSQL('r', 'aps_instances'); +} +$app->listform_actions->SQLExtWhere = 'aps_instances.package_id = aps_packages.id'.$client_ext; +$app->listform_actions->SQLOrderBy = 'ORDER BY package_name'; + +// We are using parts of listform_actions because ISPConfig doesn't allow +// queries over multiple tables so we construct them ourselves +$_SESSION['s']['form']['return_to'] = ''; + +// Load the list template +$app->listform->loadListDef($list_def_file); +if(!is_file('templates/'.$app->listform->listDef["name"].'_list.htm')) +{ +$app->uses('listform_tpl_generator'); +$app->listform_tpl_generator->buildHTML($app->listform->listDef); +} +$app->tpl->newTemplate("listpage.tpl.htm"); +$app->tpl->setInclude('content_tpl', 'templates/'.$app->listform->listDef["name"].'_list.htm'); + +// Build the WHERE query for search +$sql_where = ''; +if($app->listform_actions->SQLExtWhere != '') + $sql_where .= ' '.$app->listform_actions->SQLExtWhere.' and'; +$sql_where = $app->listform->getSearchSQL($sql_where); +$app->tpl->setVar($app->listform->searchValues); + +// Paging +$limit_sql = $app->listform->getPagingSQL($sql_where); +$app->tpl->setVar('paging', $app->listform->pagingHTML); + +if(!$is_admin) { +// Our query over multiple tables +$query = "SELECT aps_instances.id AS id, aps_instances.package_id AS package_id, + aps_instances.customer_id AS customer_id, client.username AS customer_name, + aps_instances.instance_status AS instance_status, aps_packages.name AS package_name, + aps_packages.version AS package_version, aps_packages.release AS package_release, + aps_packages.package_status AS package_status, + CONCAT((SELECT value FROM aps_instances_settings WHERE name='main_domain' AND instance_id = aps_instances.id), + '/', (SELECT value FROM aps_instances_settings WHERE name='main_location' AND instance_id = aps_instances.id)) + AS install_location + FROM aps_instances, aps_packages, client + WHERE client.client_id = aps_instances.customer_id AND ".$sql_where." ".$app->listform_actions->SQLOrderBy." ".$limit_sql; +} else { +$query = "SELECT aps_instances.id AS id, aps_instances.package_id AS package_id, + aps_instances.customer_id AS customer_id, sys_group.name AS customer_name, + aps_instances.instance_status AS instance_status, aps_packages.name AS package_name, + aps_packages.version AS package_version, aps_packages.release AS package_release, + aps_packages.package_status AS package_status, + CONCAT((SELECT value FROM aps_instances_settings WHERE name='main_domain' AND instance_id = aps_instances.id), + '/', (SELECT value FROM aps_instances_settings WHERE name='main_location' AND instance_id = aps_instances.id)) + AS install_location + FROM aps_instances, aps_packages, sys_group + WHERE sys_group.client_id = aps_instances.customer_id AND ".$sql_where." ".$app->listform_actions->SQLOrderBy." ".$limit_sql; + +} + +$records = $app->db->queryAllRecords($query); +$app->listform_actions->DataRowColor = '#FFFFFF'; + +// Re-form all result entries and add extra entries +$records_new = ''; +if(is_array($records)) +{ + $app->listform_actions->idx_key = $app->listform->listDef["table_idx"]; + foreach($records as $rec) + { + // Set an abbreviated install location to beware the page layout + $ils = ''; + if(strlen($rec['Install_location']) >= 38) $ils = substr($rec['Install_location'], 0, 35).'...'; + else $ils = $rec['install_location']; + $rec['install_location_short'] = $ils; + + // Also set a boolean-like variable for the reinstall button (vlibTemplate doesn't allow variable comparisons) + // For a reinstall, the package must be already installed successfully and (still be) enabled + if($rec['instance_status'] == INSTANCE_SUCCESS && $rec['package_status'] == PACKAGE_ENABLED) + $rec['reinstall_possible'] = 'true'; + // Of course an instance can only then be removed when it's not already tagged for removal + if($rec['instance_status'] != INSTANCE_REMOVE && $rec['instance_status'] != INSTANCE_INSTALL) + $rec['delete_possible'] = 'true'; + + $records_new[] = $app->listform_actions->prepareDataRow($rec); + } +} +$app->tpl->setLoop('records', $records_new); + +$app->listform_actions->onShow(); ?> \ No newline at end of file diff --git a/interface/web/sites/aps_packagedetails_show.php b/interface/web/sites/aps_packagedetails_show.php index 737bd54a9a82a29bce5644f5819f02f5485882ca..94f5eaa0ae1b91d149afe40da0b92e830f1448cf 100644 --- a/interface/web/sites/aps_packagedetails_show.php +++ b/interface/web/sites/aps_packagedetails_show.php @@ -1,100 +1,100 @@ -<?php -/* -Copyright (c) 2012, ISPConfig UG -Contributors: web wack creations, http://www.web-wack.at -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of ISPConfig nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -require_once('../../lib/config.inc.php'); -require_once('../../lib/app.inc.php'); -//require_once('classes/class.guicontroller.php'); -$app->load('aps_guicontroller'); - -// Check the module permissions -$app->auth->check_module_permissions('sites'); - -// Load needed classes -$app->uses('tpl'); -$app->tpl->newTemplate("listpage.tpl.htm"); -$app->tpl->setInclude('content_tpl', 'templates/aps_packagedetails_show.htm'); - -// Load the language file -$lngfile = 'lib/lang/'.$_SESSION['s']['language'].'_aps.lng'; -require_once($lngfile); -$app->tpl->setVar($wb); - -$gui = new ApsGUIController($app); -$pkg_id = (isset($_GET['id'])) ? $app->db->quote($_GET['id']) : ''; - -// Check if a newer version is available for the current package -// Note: It's intended that here is no strict ID check (see below) -if(isset($pkg_id)) -{ - $newest_pkg_id = $gui->getNewestPackageID($pkg_id); - if($newest_pkg_id != 0) $pkg_id = $newest_pkg_id; -} - -// Make sure an integer ID is given -$adminflag = ($_SESSION['s']['user']['typ'] == 'admin') ? true : false; -if(!isset($pkg_id) || !$gui->isValidPackageID($pkg_id, $adminflag)) - $app->error($app->lng('Invalid ID')); - -// Get package details -$details = $gui->getPackageDetails($pkg_id); -if(isset($details['error'])) $app->error($details['error']); - -// Set the active and default tab -$next_tab = 'details'; -if(isset($_POST['next_tab']) || isset($_GET['next_tab'])) -{ - $tab = (isset($_POST['next_tab']) ? $_POST['next_tab'] : $_GET['next_tab']); - switch($tab) - { - case 'details': $next_tab = 'details'; break; - case 'settings': $next_tab = 'settings'; break; - case 'changelog': $next_tab = 'changelog'; break; - case 'screenshots': $next_tab = 'screenshots'; break; - default: $next_tab = 'details'; - } -} -$app->tpl->setVar('next_tab', $next_tab); - -// Parse the package details to the template -foreach($details as $key => $value) -{ - if(!is_array($value)) $app->tpl->setVar('pkg_'.str_replace(' ', '_', strtolower($key)), $value); - else // Special cases - { - if($key == 'Changelog') $app->tpl->setLoop('pkg_changelog', $details['Changelog']); - elseif($key == 'Screenshots') $app->tpl->setLoop('pkg_screenshots', $details['Screenshots']); - elseif($key == 'Requirements PHP settings') $app->tpl->setLoop('pkg_requirements_php_settings', $details['Requirements PHP settings']); - } -} -//print_r($details['Requirements PHP settings']); - -$app->tpl_defaults(); -$app->tpl->pparse(); +<?php +/* +Copyright (c) 2012, ISPConfig UG +Contributors: web wack creations, http://www.web-wack.at +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of ISPConfig nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +require_once('../../lib/config.inc.php'); +require_once('../../lib/app.inc.php'); +//require_once('classes/class.guicontroller.php'); +$app->load('aps_guicontroller'); + +// Check the module permissions +$app->auth->check_module_permissions('sites'); + +// Load needed classes +$app->uses('tpl'); +$app->tpl->newTemplate("listpage.tpl.htm"); +$app->tpl->setInclude('content_tpl', 'templates/aps_packagedetails_show.htm'); + +// Load the language file +$lngfile = 'lib/lang/'.$_SESSION['s']['language'].'_aps.lng'; +require_once($lngfile); +$app->tpl->setVar($wb); + +$gui = new ApsGUIController($app); +$pkg_id = (isset($_GET['id'])) ? $app->db->quote($_GET['id']) : ''; + +// Check if a newer version is available for the current package +// Note: It's intended that here is no strict ID check (see below) +if(isset($pkg_id)) +{ + $newest_pkg_id = $gui->getNewestPackageID($pkg_id); + if($newest_pkg_id != 0) $pkg_id = $newest_pkg_id; +} + +// Make sure an integer ID is given +$adminflag = ($_SESSION['s']['user']['typ'] == 'admin') ? true : false; +if(!isset($pkg_id) || !$gui->isValidPackageID($pkg_id, $adminflag)) + $app->error($app->lng('Invalid ID')); + +// Get package details +$details = $gui->getPackageDetails($pkg_id); +if(isset($details['error'])) $app->error($details['error']); + +// Set the active and default tab +$next_tab = 'details'; +if(isset($_POST['next_tab']) || isset($_GET['next_tab'])) +{ + $tab = (isset($_POST['next_tab']) ? $_POST['next_tab'] : $_GET['next_tab']); + switch($tab) + { + case 'details': $next_tab = 'details'; break; + case 'settings': $next_tab = 'settings'; break; + case 'changelog': $next_tab = 'changelog'; break; + case 'screenshots': $next_tab = 'screenshots'; break; + default: $next_tab = 'details'; + } +} +$app->tpl->setVar('next_tab', $next_tab); + +// Parse the package details to the template +foreach($details as $key => $value) +{ + if(!is_array($value)) $app->tpl->setVar('pkg_'.str_replace(' ', '_', strtolower($key)), $value); + else // Special cases + { + if($key == 'Changelog') $app->tpl->setLoop('pkg_changelog', $details['Changelog']); + elseif($key == 'Screenshots') $app->tpl->setLoop('pkg_screenshots', $details['Screenshots']); + elseif($key == 'Requirements PHP settings') $app->tpl->setLoop('pkg_requirements_php_settings', $details['Requirements PHP settings']); + } +} +//print_r($details['Requirements PHP settings']); + +$app->tpl_defaults(); +$app->tpl->pparse(); ?> \ No newline at end of file diff --git a/interface/web/sites/lib/lang/en_aps.lng b/interface/web/sites/lib/lang/en_aps.lng index e240d57873dde680d9d16a239215ba72137e633f..bd33c1884ae848cf3b466433810528053a34e323 100644 --- a/interface/web/sites/lib/lang/en_aps.lng +++ b/interface/web/sites/lib/lang/en_aps.lng @@ -1,58 +1,58 @@ -<?php -$wb['overview_txt'] = 'Overview'; -$wb['administration_txt'] = 'Administration'; -$wb['available_packages_txt'] = 'Available packages'; -$wb['installed_packages_txt'] = 'Installed packages'; -$wb['yes_txt'] = 'Yes'; -$wb['no_txt'] = 'No'; -$wb['invalid_id_txt'] = 'No valid ID has been provided.'; -$wb['details_txt'] = 'Details'; -$wb['version_txt'] = 'Version'; -$wb['category_txt'] = 'Category'; -$wb['homepage_txt'] = 'Homepage'; -$wb['supported_languages_txt'] = 'Supported languages'; -$wb['description_txt'] = 'Description'; -$wb['config_script_txt'] = 'Configuration script'; -$wb['installed_size_txt'] = 'Size after installation'; -$wb['license_txt'] = 'License'; -$wb['screenshots_txt'] = 'Screenshots'; -$wb['changelog_txt'] = 'Changelog'; -$wb['server_requirements_txt'] = 'Server requirements'; -$wb['php_extensions_txt'] = 'PHP extensions'; -$wb['php_settings_txt'] = 'PHP settings'; -$wb['supported_php_versions_txt'] = 'Supported PHP versions'; -$wb['database_txt'] = 'Database'; -$wb['settings_txt'] = 'Settings'; -$wb['install_package_txt'] = 'Install this package'; -$wb['installation_txt'] = 'Installation'; -$wb['install_location_txt'] = 'Install location'; -$wb['btn_install_txt'] = 'Install'; -$wb['btn_cancel_txt'] = 'Cancel'; -$wb['acceptance_txt'] = 'Acceptance'; -$wb['acceptance_text_txt'] = 'Yes, i\'ve read the license and agree.'; -$wb['install_language_txt'] = 'Interface language'; -$wb['new_database_password_txt'] = 'New database password'; -$wb['basic_settings_txt'] = 'Basic settings'; -$wb['package_settings_txt'] = 'Package settings'; -$wb['error_main_domain'] = 'The domain of the installation path is invalid.'; -$wb['error_no_main_location'] = 'You have provided no valid installation path.'; -$wb['error_inv_main_location'] = 'The given install location folder is invalid.'; -$wb['error_license_agreement'] = 'In order to continue you have to accept the license agreement.'; -$wb['error_no_database_pw'] = 'You have provided no valid database password.'; -$wb['error_short_database_pw'] = 'Please choose a longer database password.'; -$wb['error_no_value_for'] = 'The field "%s" must not be empty.'; -$wb['error_short_value_for'] = 'The field "%s" requires a longer input value.'; -$wb['error_long_value_for'] = 'The field "%s" requires a shorter input value.'; -$wb['error_inv_value_for'] = 'You have entered an invalid value for the field "%s".'; -$wb['error_inv_email_for'] = 'You have entered an invalid mail address for the field "%s".'; -$wb['error_inv_domain_for'] = 'You have entered an invalid domain for the field "%s".'; -$wb['error_inv_integer_for'] = 'You have entered an invalid number for the field "%s".'; -$wb['error_inv_float_for'] = 'You have entered an invalid floating point number for the field "%s".'; -$wb['error_used_location'] = 'The installation path already contains a package installation.'; -$wb['installation_task_txt'] = 'Install planned'; -$wb['installation_error_txt'] = 'Install error'; -$wb['installation_success_txt'] = 'Installed'; -$wb['installation_remove_txt'] = 'Removal planned'; -$wb['packagelist_update_finished_txt'] = 'APS Packagelist update finished.'; -$wb["limit_aps_txt"] = 'The max. number of APS instances for your account is reached.'; +<?php +$wb['overview_txt'] = 'Overview'; +$wb['administration_txt'] = 'Administration'; +$wb['available_packages_txt'] = 'Available packages'; +$wb['installed_packages_txt'] = 'Installed packages'; +$wb['yes_txt'] = 'Yes'; +$wb['no_txt'] = 'No'; +$wb['invalid_id_txt'] = 'No valid ID has been provided.'; +$wb['details_txt'] = 'Details'; +$wb['version_txt'] = 'Version'; +$wb['category_txt'] = 'Category'; +$wb['homepage_txt'] = 'Homepage'; +$wb['supported_languages_txt'] = 'Supported languages'; +$wb['description_txt'] = 'Description'; +$wb['config_script_txt'] = 'Configuration script'; +$wb['installed_size_txt'] = 'Size after installation'; +$wb['license_txt'] = 'License'; +$wb['screenshots_txt'] = 'Screenshots'; +$wb['changelog_txt'] = 'Changelog'; +$wb['server_requirements_txt'] = 'Server requirements'; +$wb['php_extensions_txt'] = 'PHP extensions'; +$wb['php_settings_txt'] = 'PHP settings'; +$wb['supported_php_versions_txt'] = 'Supported PHP versions'; +$wb['database_txt'] = 'Database'; +$wb['settings_txt'] = 'Settings'; +$wb['install_package_txt'] = 'Install this package'; +$wb['installation_txt'] = 'Installation'; +$wb['install_location_txt'] = 'Install location'; +$wb['btn_install_txt'] = 'Install'; +$wb['btn_cancel_txt'] = 'Cancel'; +$wb['acceptance_txt'] = 'Acceptance'; +$wb['acceptance_text_txt'] = 'Yes, i\'ve read the license and agree.'; +$wb['install_language_txt'] = 'Interface language'; +$wb['new_database_password_txt'] = 'New database password'; +$wb['basic_settings_txt'] = 'Basic settings'; +$wb['package_settings_txt'] = 'Package settings'; +$wb['error_main_domain'] = 'The domain of the installation path is invalid.'; +$wb['error_no_main_location'] = 'You have provided no valid installation path.'; +$wb['error_inv_main_location'] = 'The given install location folder is invalid.'; +$wb['error_license_agreement'] = 'In order to continue you have to accept the license agreement.'; +$wb['error_no_database_pw'] = 'You have provided no valid database password.'; +$wb['error_short_database_pw'] = 'Please choose a longer database password.'; +$wb['error_no_value_for'] = 'The field "%s" must not be empty.'; +$wb['error_short_value_for'] = 'The field "%s" requires a longer input value.'; +$wb['error_long_value_for'] = 'The field "%s" requires a shorter input value.'; +$wb['error_inv_value_for'] = 'You have entered an invalid value for the field "%s".'; +$wb['error_inv_email_for'] = 'You have entered an invalid mail address for the field "%s".'; +$wb['error_inv_domain_for'] = 'You have entered an invalid domain for the field "%s".'; +$wb['error_inv_integer_for'] = 'You have entered an invalid number for the field "%s".'; +$wb['error_inv_float_for'] = 'You have entered an invalid floating point number for the field "%s".'; +$wb['error_used_location'] = 'The installation path already contains a package installation.'; +$wb['installation_task_txt'] = 'Install planned'; +$wb['installation_error_txt'] = 'Install error'; +$wb['installation_success_txt'] = 'Installed'; +$wb['installation_remove_txt'] = 'Removal planned'; +$wb['packagelist_update_finished_txt'] = 'APS Packagelist update finished.'; +$wb["limit_aps_txt"] = 'The max. number of APS instances for your account is reached.'; ?> \ No newline at end of file diff --git a/interface/web/sites/lib/lang/en_aps_instances_list.lng b/interface/web/sites/lib/lang/en_aps_instances_list.lng index 3b9c7e943ac237c34427c4e3bd1ee63e877bef8c..611c37efa63656420e4a25c5beb71d9b11c3047d 100644 --- a/interface/web/sites/lib/lang/en_aps_instances_list.lng +++ b/interface/web/sites/lib/lang/en_aps_instances_list.lng @@ -1,13 +1,13 @@ -<?php -$wb['list_head_txt'] = 'Installed packages'; -$wb['name_txt'] = 'Name'; -$wb['version_txt'] = 'Version'; -$wb['customer_txt'] = 'Client'; -$wb['status_txt'] = 'Status'; -$wb['install_location_txt'] = 'Install location'; -$wb['pkg_delete_confirmation'] = 'Do you really want to delete this installation?'; -$wb['pkg_reinstall_confirmation'] = 'Do you really want to reinstall this package with the same settings?'; -$wb['filter_txt'] = 'Search'; -$wb['delete_txt'] = 'Delete'; -$wb['reinstall_txt'] = 'Reinstall'; +<?php +$wb['list_head_txt'] = 'Installed packages'; +$wb['name_txt'] = 'Name'; +$wb['version_txt'] = 'Version'; +$wb['customer_txt'] = 'Client'; +$wb['status_txt'] = 'Status'; +$wb['install_location_txt'] = 'Install location'; +$wb['pkg_delete_confirmation'] = 'Do you really want to delete this installation?'; +$wb['pkg_reinstall_confirmation'] = 'Do you really want to reinstall this package with the same settings?'; +$wb['filter_txt'] = 'Search'; +$wb['delete_txt'] = 'Delete'; +$wb['reinstall_txt'] = 'Reinstall'; ?> \ No newline at end of file diff --git a/interface/web/sites/lib/lang/en_aps_packages_list.lng b/interface/web/sites/lib/lang/en_aps_packages_list.lng index 12cc30d023dddf9eee510f9c3545100fc158547a..ed6303a64e9176e80a8d2d6432a8cd783617682b 100644 --- a/interface/web/sites/lib/lang/en_aps_packages_list.lng +++ b/interface/web/sites/lib/lang/en_aps_packages_list.lng @@ -1,8 +1,8 @@ -<?php -$wb['list_head_txt'] = 'Available packages'; -$wb['name_txt'] = 'Name'; -$wb['version_txt'] = 'Version'; -$wb['category_txt'] = 'Category'; -$wb['status_txt'] = 'Unlocked'; -$wb['filter_txt'] = 'Search'; +<?php +$wb['list_head_txt'] = 'Available packages'; +$wb['name_txt'] = 'Name'; +$wb['version_txt'] = 'Version'; +$wb['category_txt'] = 'Category'; +$wb['status_txt'] = 'Unlocked'; +$wb['filter_txt'] = 'Search'; ?> \ No newline at end of file diff --git a/interface/web/sites/lib/lang/en_aps_update_packagelist.lng b/interface/web/sites/lib/lang/en_aps_update_packagelist.lng index 1a40a3394f2a049f00b2f5e3fef7764579281962..20a7360b64d81cd90a24c3e9ba3fa8ef9d32f28c 100644 --- a/interface/web/sites/lib/lang/en_aps_update_packagelist.lng +++ b/interface/web/sites/lib/lang/en_aps_update_packagelist.lng @@ -1,7 +1,7 @@ -<?php -$wb['head_txt'] = 'Update Packagelist'; -$wb['list_desc_txt'] = ''; -$wb['btn_start_txt'] = 'Update Packagelist'; -$wb['btn_cancel_txt'] = 'Cancel'; -$wb['legend_txt'] = 'Here you can update the list of available packages. Please note that this can take up to five minutes. You can leave this page if you like; the process will continue in the background.'; +<?php +$wb['head_txt'] = 'Update Packagelist'; +$wb['list_desc_txt'] = ''; +$wb['btn_start_txt'] = 'Update Packagelist'; +$wb['btn_cancel_txt'] = 'Cancel'; +$wb['legend_txt'] = 'Here you can update the list of available packages. Please note that this can take up to five minutes. You can leave this page if you like; the process will continue in the background.'; ?> \ No newline at end of file diff --git a/interface/web/sites/list/aps_availablepackages.list.php b/interface/web/sites/list/aps_availablepackages.list.php index d07b85a4fe1d4a50c290e92b539333e04159ab0d..b6f52cff8295b8c325106108f7048a5aff4337b1 100644 --- a/interface/web/sites/list/aps_availablepackages.list.php +++ b/interface/web/sites/list/aps_availablepackages.list.php @@ -1,86 +1,86 @@ -<?php -/* -Copyright (c) 2012, ISPConfig UG -Contributors: web wack creations, http://www.web-wack.at -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of ISPConfig nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -$liste['name'] = 'aps_packages'; // Name of the list -$liste['table'] = 'aps_packages'; // Database table -$liste['table_idx'] = 'id'; // Table index -$liste["search_prefix"] = 'search_'; // Search field prefix -$liste['records_per_page'] = 15; // Records per page -$liste['file'] = 'aps_availablepackages_list.php'; // Script file for this list -$liste['edit_file'] = ''; // Script file to edit -$liste['delete_file'] = ''; // Script file to delete -$liste['paging_tpl'] = 'templates/paging.tpl.htm'; // Paging template -$liste['auth'] = 'no'; // Handling it myself (check for admin) - -// Search fields -$liste["item"][] = array('field' => 'name', - 'datatype' => 'VARCHAR', - 'formtype' => 'TEXT', - 'op' => 'like', - 'prefix' => '%', - 'suffix' => '%', - 'width' => '', - 'value' => ''); - -$liste["item"][] = array('field' => 'version', - 'datatype' => 'VARCHAR', - 'formtype' => 'TEXT', - 'op' => 'like', - 'prefix' => '%', - 'suffix' => '%', - 'width' => '', - 'value' => ''); - -$liste["item"][] = array('field' => 'category', - 'datatype' => 'VARCHAR', - 'formtype' => 'SELECT', - 'op' => '=', - 'prefix' => '', - 'suffix' => '', - 'datasource' => array('type' => 'SQL', - 'querystring' => 'SELECT category FROM aps_packages ORDER BY category', - 'keyfield' => 'category', - 'valuefield' => 'category'), - 'width' => '', - 'value' => ''); - -if($_SESSION['s']['user']['typ'] == 'admin') -{ -$liste['item'][] = array('field' => 'package_status', - 'datatype' => 'VARCHAR', - 'formtype' => 'SELECT', - 'op' => '=', - 'prefix' => '', - 'suffix' => '', - 'width' => '', - 'value' => array(PACKAGE_ENABLED => '<div class="swap" id="ir-Yes"><span>'.$app->lng('Yes').'</span></div>', - PACKAGE_LOCKED => '<div class="swap" id="ir-No"><span>'.$app->lng('No').'</span></div>')); -} +<?php +/* +Copyright (c) 2012, ISPConfig UG +Contributors: web wack creations, http://www.web-wack.at +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of ISPConfig nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +$liste['name'] = 'aps_packages'; // Name of the list +$liste['table'] = 'aps_packages'; // Database table +$liste['table_idx'] = 'id'; // Table index +$liste["search_prefix"] = 'search_'; // Search field prefix +$liste['records_per_page'] = 15; // Records per page +$liste['file'] = 'aps_availablepackages_list.php'; // Script file for this list +$liste['edit_file'] = ''; // Script file to edit +$liste['delete_file'] = ''; // Script file to delete +$liste['paging_tpl'] = 'templates/paging.tpl.htm'; // Paging template +$liste['auth'] = 'no'; // Handling it myself (check for admin) + +// Search fields +$liste["item"][] = array('field' => 'name', + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'op' => 'like', + 'prefix' => '%', + 'suffix' => '%', + 'width' => '', + 'value' => ''); + +$liste["item"][] = array('field' => 'version', + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'op' => 'like', + 'prefix' => '%', + 'suffix' => '%', + 'width' => '', + 'value' => ''); + +$liste["item"][] = array('field' => 'category', + 'datatype' => 'VARCHAR', + 'formtype' => 'SELECT', + 'op' => '=', + 'prefix' => '', + 'suffix' => '', + 'datasource' => array('type' => 'SQL', + 'querystring' => 'SELECT category FROM aps_packages ORDER BY category', + 'keyfield' => 'category', + 'valuefield' => 'category'), + 'width' => '', + 'value' => ''); + +if($_SESSION['s']['user']['typ'] == 'admin') +{ +$liste['item'][] = array('field' => 'package_status', + 'datatype' => 'VARCHAR', + 'formtype' => 'SELECT', + 'op' => '=', + 'prefix' => '', + 'suffix' => '', + 'width' => '', + 'value' => array(PACKAGE_ENABLED => '<div class="swap" id="ir-Yes"><span>'.$app->lng('Yes').'</span></div>', + PACKAGE_LOCKED => '<div class="swap" id="ir-No"><span>'.$app->lng('No').'</span></div>')); +} ?> \ No newline at end of file diff --git a/interface/web/sites/list/aps_installedpackages.list.php b/interface/web/sites/list/aps_installedpackages.list.php index 2340824a1ee6ccaa9c75c21d5e046b1546a44d22..0f90a7322145aa21f71f6f1f33401a5e05d7f0d2 100644 --- a/interface/web/sites/list/aps_installedpackages.list.php +++ b/interface/web/sites/list/aps_installedpackages.list.php @@ -1,93 +1,93 @@ -<?php -/* -Copyright (c) 2012, ISPConfig UG -Contributors: web wack creations, http://www.web-wack.at -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of ISPConfig nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -$liste['name'] = 'aps_instances'; // Name of the list -$liste['table'] = 'aps_instances'; // Database table -$liste['table_idx'] = 'id'; // Table index - -// if multiple tables are involved, list the additional tables here (comma separated) -$liste["additional_tables"] = "aps_packages"; - -// if multiple tables are involved, specify sql to join these tables -$liste["join_sql"] = " aps_instances.package_id = aps_packages.id"; - -$liste["search_prefix"] = 'search_'; // Search field prefix -$liste['records_per_page'] = 15; // Records per page -$liste['file'] = 'aps_installedpackages_list.php'; // Script file for this list -$liste['edit_file'] = ''; // Script file to edit -$liste['delete_file'] = ''; // Script file to delete -$liste['paging_tpl'] = 'templates/paging.tpl.htm'; // Paging template -$liste['auth'] = 'no'; // Handling it myself (check for admin) - -// Search fields -$liste["item"][] = array('field' => 'name', - 'datatype' => 'VARCHAR', - 'formtype' => 'TEXT', - 'op' => 'LIKE', - 'prefix' => '%', - 'suffix' => '%', - 'width' => '', - 'value' => '', - 'table' => 'aps_packages'); - -$liste["item"][] = array('field' => 'version', - 'datatype' => 'VARCHAR', - 'formtype' => 'TEXT', - 'op' => 'like', - 'prefix' => '%', - 'suffix' => '%', - 'width' => '', - 'value' => '', - 'table' => 'aps_packages'); - - /* -$liste["item"][] = array('field' => 'customer_id', - 'datatype' => 'INTEGER', - 'formtype' => 'SELECT', - 'op' => '=', - 'prefix' => '', - 'suffix' => '', - 'width' => '', - 'value' => ''); -*/ - -$liste["item"][] = array('field' => 'instance_status', - 'datatype' => 'VARCHAR', - 'formtype' => 'SELECT', - 'op' => '=', - 'prefix' => '', - 'suffix' => '', - 'width' => '', - 'value' => array(INSTANCE_INSTALL => $app->lng('Installation_task'), - INSTANCE_ERROR => $app->lng('Installation_error'), - INSTANCE_SUCCESS => $app->lng('Installation_success'), - INSTANCE_REMOVE => $app->lng('Installation_remove')), - 'table' => 'aps_instances'); +<?php +/* +Copyright (c) 2012, ISPConfig UG +Contributors: web wack creations, http://www.web-wack.at +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of ISPConfig nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +$liste['name'] = 'aps_instances'; // Name of the list +$liste['table'] = 'aps_instances'; // Database table +$liste['table_idx'] = 'id'; // Table index + +// if multiple tables are involved, list the additional tables here (comma separated) +$liste["additional_tables"] = "aps_packages"; + +// if multiple tables are involved, specify sql to join these tables +$liste["join_sql"] = " aps_instances.package_id = aps_packages.id"; + +$liste["search_prefix"] = 'search_'; // Search field prefix +$liste['records_per_page'] = 15; // Records per page +$liste['file'] = 'aps_installedpackages_list.php'; // Script file for this list +$liste['edit_file'] = ''; // Script file to edit +$liste['delete_file'] = ''; // Script file to delete +$liste['paging_tpl'] = 'templates/paging.tpl.htm'; // Paging template +$liste['auth'] = 'no'; // Handling it myself (check for admin) + +// Search fields +$liste["item"][] = array('field' => 'name', + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'op' => 'LIKE', + 'prefix' => '%', + 'suffix' => '%', + 'width' => '', + 'value' => '', + 'table' => 'aps_packages'); + +$liste["item"][] = array('field' => 'version', + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'op' => 'like', + 'prefix' => '%', + 'suffix' => '%', + 'width' => '', + 'value' => '', + 'table' => 'aps_packages'); + + /* +$liste["item"][] = array('field' => 'customer_id', + 'datatype' => 'INTEGER', + 'formtype' => 'SELECT', + 'op' => '=', + 'prefix' => '', + 'suffix' => '', + 'width' => '', + 'value' => ''); +*/ + +$liste["item"][] = array('field' => 'instance_status', + 'datatype' => 'VARCHAR', + 'formtype' => 'SELECT', + 'op' => '=', + 'prefix' => '', + 'suffix' => '', + 'width' => '', + 'value' => array(INSTANCE_INSTALL => $app->lng('Installation_task'), + INSTANCE_ERROR => $app->lng('Installation_error'), + INSTANCE_SUCCESS => $app->lng('Installation_success'), + INSTANCE_REMOVE => $app->lng('Installation_remove')), + 'table' => 'aps_instances'); ?> \ No newline at end of file diff --git a/interface/web/sites/templates/aps_install_package.htm b/interface/web/sites/templates/aps_install_package.htm index 4e0c9bd517e660ebbaf564b3b4c6288c26d3aedb..829e8418efaf0c585baafe362e88c1ec108988f1 100644 --- a/interface/web/sites/templates/aps_install_package.htm +++ b/interface/web/sites/templates/aps_install_package.htm @@ -1,56 +1,56 @@ -<h2> - {tmpl_var name='installation_txt'}: {tmpl_var name='pkg_name'} {tmpl_var name='pkg_version'}-{tmpl_var name='pkg_release'} - <span style="float:right"> - <tmpl_if name='pkg_icon' op='!=' value=''> - <img src="{tmpl_var name='pkg_icon'}" height="32" width="32" alt="{tmpl_var name='pkg_name'}" style="vertical-align:text-bottom;" /> - </tmpl_if> - </span> -</h2> - -<tmpl_if name='error'> - <div id="errorMsg"><h3>ERROR</h3><ol>{tmpl_var name='error'}</ol></div> -</tmpl_if> - -<div class="panel panel_install_package"> - - <div class="pnl_formsarea"> - <fieldset class="inlineLabels"> - <legend>{tmpl_var name='basic_settings_txt'}</legend> - <div class="ctrlHolder"> - <label for="main_domain">{tmpl_var name='install_location_txt'}</label> - <div class="resetButton">http(s):// </div>DOMAIN_LIST_SPACE<div style="float:left;"> / </div> - <input type="text" name="main_location" id="main_location" value="{tmpl_var name='inp_main_location'}" maxlength="255" class="textInput formLengthHalf" /> - </div> - <tmpl_if name='pkg_requirements_database' op='!=' value=''> - <div class="ctrlHolder"> - <label for="main_database_password">{tmpl_var name='new_database_password_txt'}</label> - <input type="text" class="textInput" name="main_database_password" id="main_database_password" value="{tmpl_var name='inp_main_database_password'}" size="10" maxlength="255" /> - </div> - </tmpl_if> - - PKG_SETTINGS_SPACE - - <legend>{tmpl_var name='license_txt'}</legend> - <div class="ctrlHolder"> - <label for="license">{tmpl_var name='license_txt'}</label> - <tmpl_if name='pkg_license_content' op='==' value=''>{tmpl_var name='pkg_license_name'}<br /></tmpl_if> - <tmpl_if name='pkg_license_type' op='==' value='url'> - <a href="{tmpl_var name='pkg_license_content'}" target="_blank">{tmpl_var name='pkg_license_content'}</a> - <tmpl_elseif name='pkg_license_content'> - <textarea rows="10" cols="80" id="license_text">{tmpl_var name='pkg_license_content'}</textarea> - </tmpl_if> - </div> - <div class="ctrlHolder"> - <label for="license">{tmpl_var name='acceptance_txt'}</label> - <input type="checkbox" name="license" id="license" <tmpl_if name='inp_license' op='==' value='true'>checked</tmpl_if> /> {tmpl_var name='acceptance_text'} - </div> - </fieldset> - - <input type="hidden" name="install" value="0" /> - <div class="buttonHolder buttons"> - <button class="positive iconstxt icoPositive" type="button" value="{tmpl_var name='btn_install_txt'}" name="btn_install" onclick="document.pageForm.install.value=1; submitForm('pageForm','sites/aps_install_package.php?id={tmpl_var name='pkg_id'}');"><span>{tmpl_var name='btn_install_txt'}</span></button> - <button class="negative iconstxt icoNegative" type="button" value="{tmpl_var name='btn_cancel_txt'}" onclick="loadContent('sites/aps_availablepackages_list.php');"><span>{tmpl_var name='btn_cancel_txt'}</span></button> - </div> - </div> - +<h2> + {tmpl_var name='installation_txt'}: {tmpl_var name='pkg_name'} {tmpl_var name='pkg_version'}-{tmpl_var name='pkg_release'} + <span style="float:right"> + <tmpl_if name='pkg_icon' op='!=' value=''> + <img src="{tmpl_var name='pkg_icon'}" height="32" width="32" alt="{tmpl_var name='pkg_name'}" style="vertical-align:text-bottom;" /> + </tmpl_if> + </span> +</h2> + +<tmpl_if name='error'> + <div id="errorMsg"><h3>ERROR</h3><ol>{tmpl_var name='error'}</ol></div> +</tmpl_if> + +<div class="panel panel_install_package"> + + <div class="pnl_formsarea"> + <fieldset class="inlineLabels"> + <legend>{tmpl_var name='basic_settings_txt'}</legend> + <div class="ctrlHolder"> + <label for="main_domain">{tmpl_var name='install_location_txt'}</label> + <div class="resetButton">http(s):// </div>DOMAIN_LIST_SPACE<div style="float:left;"> / </div> + <input type="text" name="main_location" id="main_location" value="{tmpl_var name='inp_main_location'}" maxlength="255" class="textInput formLengthHalf" /> + </div> + <tmpl_if name='pkg_requirements_database' op='!=' value=''> + <div class="ctrlHolder"> + <label for="main_database_password">{tmpl_var name='new_database_password_txt'}</label> + <input type="text" class="textInput" name="main_database_password" id="main_database_password" value="{tmpl_var name='inp_main_database_password'}" size="10" maxlength="255" /> + </div> + </tmpl_if> + + PKG_SETTINGS_SPACE + + <legend>{tmpl_var name='license_txt'}</legend> + <div class="ctrlHolder"> + <label for="license">{tmpl_var name='license_txt'}</label> + <tmpl_if name='pkg_license_content' op='==' value=''>{tmpl_var name='pkg_license_name'}<br /></tmpl_if> + <tmpl_if name='pkg_license_type' op='==' value='url'> + <a href="{tmpl_var name='pkg_license_content'}" target="_blank">{tmpl_var name='pkg_license_content'}</a> + <tmpl_elseif name='pkg_license_content'> + <textarea rows="10" cols="80" id="license_text">{tmpl_var name='pkg_license_content'}</textarea> + </tmpl_if> + </div> + <div class="ctrlHolder"> + <label for="license">{tmpl_var name='acceptance_txt'}</label> + <input type="checkbox" name="license" id="license" <tmpl_if name='inp_license' op='==' value='true'>checked</tmpl_if> /> {tmpl_var name='acceptance_text'} + </div> + </fieldset> + + <input type="hidden" name="install" value="0" /> + <div class="buttonHolder buttons"> + <button class="positive iconstxt icoPositive" type="button" value="{tmpl_var name='btn_install_txt'}" name="btn_install" onclick="document.pageForm.install.value=1; submitForm('pageForm','sites/aps_install_package.php?id={tmpl_var name='pkg_id'}');"><span>{tmpl_var name='btn_install_txt'}</span></button> + <button class="negative iconstxt icoNegative" type="button" value="{tmpl_var name='btn_cancel_txt'}" onclick="loadContent('sites/aps_availablepackages_list.php');"><span>{tmpl_var name='btn_cancel_txt'}</span></button> + </div> + </div> + </div> \ No newline at end of file diff --git a/interface/web/sites/templates/aps_instances_list.htm b/interface/web/sites/templates/aps_instances_list.htm index 48da5232e6438fb2e1cb9c205e311ea3d412f9e1..2d9c50f6da77d6d2e8f37cd3fc0db96e8527cec1 100644 --- a/interface/web/sites/templates/aps_instances_list.htm +++ b/interface/web/sites/templates/aps_instances_list.htm @@ -1,62 +1,62 @@ -<h2>{tmpl_var name="list_head_txt"}</h2> - -<div class="panel panel_list_instances"> - - <div class="pnl_listarea"> - <fieldset><legend>{tmpl_var name="list_head_txt"}</legend> - <table class="list"> - <thead> - <tr class="caption"> - <th class="tbl_col_name" scope="col">{tmpl_var name='name_txt'}</th> - <th class="tbl_col_version" scope="col">{tmpl_var name='version_txt'}</th> - <tmpl_if name='is_noclient'> - <!--<th class="tbl_col_customer" scope="col">{tmpl_var name='customer_txt'}</th>--> - </tmpl_if> - <th class="tbl_col_installlocation" scope="col">{tmpl_var name='install_location_txt'}</th> - <th class="tbl_col_instancestatus" scope="col">{tmpl_var name='status_txt'}</th> - <th class="tbl_col_limit" scope="col" > </th> - </tr> - <tr class="filter"> - <td class="tbl_col_name"><input type="text" name="search_name" value="{tmpl_var name='search_name'}" /></td> - <td class="tbl_col_version"><input type="text" name="search_version" value="{tmpl_var name='search_version'}" /></td> - <tmpl_if name='is_noclient'> - <!--<td class="tbl_col_customer"><input type="text" name="search_customer_name" value="{tmpl_var name='search_customer_name'}" /></td>--> - </tmpl_if> - <td class="tbl_col_installlocation"> </td> - <td class="tbl_col_instancestatus"><select name="search_instance_status" onChange="submitForm('pageForm','sites/aps_installedpackages_list.php');">{tmpl_var name='search_instance_status'}</select></td> - <td class="tbl_col_buttons"> - <button type="button" class="button icons16 icoFilter" name="Filter" id="Filter" value="{tmpl_var name='filter_txt'}" onclick="submitForm('pageForm','sites/aps_installedpackages_list.php');"><span>{tmpl_var name='filter_txt'}</span></button> - </td> - </tr> - </thead> - <tbody> - <tmpl_loop name='records'> - <tr class="tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>"> - <td class="tbl_col_name"><a href="#" onclick="loadContent('sites/aps_packagedetails_show.php?id={tmpl_var name='package_id'}');">{tmpl_var name='package_name'}</a></td> - <td class="tbl_col_version">{tmpl_var name='package_version'}-{tmpl_var name='package_release'}</td> - <tmpl_if name='is_noclient'> - <!--<td class="tbl_col_customer"><a href="#" onclick="loadContent('sites/aps_packagedetails_show.php?id={tmpl_var name='package_id'}');">{tmpl_var name='customer_name'}</a></td>--> - </tmpl_if> - <td class="tbl_col_installlocation"><a href="http://{tmpl_var name='install_location'}" target="_blank">{tmpl_var name='install_location_short'}</a></td> - <td class="tbl_col_instancestatus"><span id="status_content{tmpl_var name='__ROWNUM__'}">{tmpl_var name='instance_status'}</span></td> - <td class="tbl_col_buttons"> - <tmpl_if name='delete_possible'> - <a class="button icons16 icoDelete" href="javascript: del_record('sites/aps_do_operation.php?action=delete_instance&id={tmpl_var name='id'}','{tmpl_var name='pkg_delete_confirmation'}')"><span>{tmpl_var name='delete_txt'}</span></a> - </tmpl_if> - <tmpl_if name='reinstall_possible'> - <a class="button icons16 icoEdit" href="javascript: del_record('sites/aps_do_operation.php?action=reinstall_instance&id={tmpl_var name='id'}','{tmpl_var name='pkg_reinstall_confirmation'}')"><span>{tmpl_var name='reinstall_txt'}</span></a> - </tmpl_if> - </td> - </tr> - </tmpl_loop> - </tbody> - <tfoot> - <tr> - <td class="tbl_footer tbl_paging" colspan="6">{tmpl_var name='paging'}</td> - </tr> - </tfoot> - </table> - </fieldset> - </div> - +<h2>{tmpl_var name="list_head_txt"}</h2> + +<div class="panel panel_list_instances"> + + <div class="pnl_listarea"> + <fieldset><legend>{tmpl_var name="list_head_txt"}</legend> + <table class="list"> + <thead> + <tr class="caption"> + <th class="tbl_col_name" scope="col">{tmpl_var name='name_txt'}</th> + <th class="tbl_col_version" scope="col">{tmpl_var name='version_txt'}</th> + <tmpl_if name='is_noclient'> + <!--<th class="tbl_col_customer" scope="col">{tmpl_var name='customer_txt'}</th>--> + </tmpl_if> + <th class="tbl_col_installlocation" scope="col">{tmpl_var name='install_location_txt'}</th> + <th class="tbl_col_instancestatus" scope="col">{tmpl_var name='status_txt'}</th> + <th class="tbl_col_limit" scope="col" > </th> + </tr> + <tr class="filter"> + <td class="tbl_col_name"><input type="text" name="search_name" value="{tmpl_var name='search_name'}" /></td> + <td class="tbl_col_version"><input type="text" name="search_version" value="{tmpl_var name='search_version'}" /></td> + <tmpl_if name='is_noclient'> + <!--<td class="tbl_col_customer"><input type="text" name="search_customer_name" value="{tmpl_var name='search_customer_name'}" /></td>--> + </tmpl_if> + <td class="tbl_col_installlocation"> </td> + <td class="tbl_col_instancestatus"><select name="search_instance_status" onChange="submitForm('pageForm','sites/aps_installedpackages_list.php');">{tmpl_var name='search_instance_status'}</select></td> + <td class="tbl_col_buttons"> + <button type="button" class="button icons16 icoFilter" name="Filter" id="Filter" value="{tmpl_var name='filter_txt'}" onclick="submitForm('pageForm','sites/aps_installedpackages_list.php');"><span>{tmpl_var name='filter_txt'}</span></button> + </td> + </tr> + </thead> + <tbody> + <tmpl_loop name='records'> + <tr class="tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>"> + <td class="tbl_col_name"><a href="#" onclick="loadContent('sites/aps_packagedetails_show.php?id={tmpl_var name='package_id'}');">{tmpl_var name='package_name'}</a></td> + <td class="tbl_col_version">{tmpl_var name='package_version'}-{tmpl_var name='package_release'}</td> + <tmpl_if name='is_noclient'> + <!--<td class="tbl_col_customer"><a href="#" onclick="loadContent('sites/aps_packagedetails_show.php?id={tmpl_var name='package_id'}');">{tmpl_var name='customer_name'}</a></td>--> + </tmpl_if> + <td class="tbl_col_installlocation"><a href="http://{tmpl_var name='install_location'}" target="_blank">{tmpl_var name='install_location_short'}</a></td> + <td class="tbl_col_instancestatus"><span id="status_content{tmpl_var name='__ROWNUM__'}">{tmpl_var name='instance_status'}</span></td> + <td class="tbl_col_buttons"> + <tmpl_if name='delete_possible'> + <a class="button icons16 icoDelete" href="javascript: del_record('sites/aps_do_operation.php?action=delete_instance&id={tmpl_var name='id'}','{tmpl_var name='pkg_delete_confirmation'}')"><span>{tmpl_var name='delete_txt'}</span></a> + </tmpl_if> + <tmpl_if name='reinstall_possible'> + <a class="button icons16 icoEdit" href="javascript: del_record('sites/aps_do_operation.php?action=reinstall_instance&id={tmpl_var name='id'}','{tmpl_var name='pkg_reinstall_confirmation'}')"><span>{tmpl_var name='reinstall_txt'}</span></a> + </tmpl_if> + </td> + </tr> + </tmpl_loop> + </tbody> + <tfoot> + <tr> + <td class="tbl_footer tbl_paging" colspan="6">{tmpl_var name='paging'}</td> + </tr> + </tfoot> + </table> + </fieldset> + </div> + </div> \ No newline at end of file diff --git a/interface/web/sites/templates/aps_packagedetails_show.htm b/interface/web/sites/templates/aps_packagedetails_show.htm index a09c26f2039eeca6c638178d1941446cbfcf7e99..5456a8985009c095af8b1287c3e56585f3175ac7 100644 --- a/interface/web/sites/templates/aps_packagedetails_show.htm +++ b/interface/web/sites/templates/aps_packagedetails_show.htm @@ -1,141 +1,141 @@ -<h2> - <tmpl_if name='pkg_icon' op='!=' value=''> - <img src="{tmpl_var name='pkg_icon'}" height="32" width="32" alt="{tmpl_var name='pkg_name'}" style="vertical-align:text-bottom;" /> - </tmpl_if> - {tmpl_var name='pkg_name'} -</h2> -<b>{tmpl_var name='pkg_summary'}</b> -<p> </p> - -<div class="pnl_toolsarea"> - <fieldset> - <div class="buttons"> - <button class="button iconstxt icoAdd" type="button" onclick="loadContent('sites/aps_install_package.php?id={tmpl_var name='pkg_id'}');"> - <span>{tmpl_var name="install_package_txt"}</span> - </button> - </div> - </fieldset> -</div> -<p> </p><p> </p> - - -<div class="tabbox_tabs"> - <input type="hidden" name="next_tab" value="" /> - <ul> - <li<tmpl_if name='next_tab' op='==' value='details'> class="active"</tmpl_if>> - <a href="#" onclick="return changeTab('details', 'sites/aps_packagedetails_show.php?id={tmpl_var name='pkg_id'}');">{tmpl_var name='details_txt'}</a> - </li> - <tmpl_if name='pkg_screenshots'> - <li<tmpl_if name='next_tab' op='==' value='screenshots'> class="active"</tmpl_if>> - <a href="#" onclick="return changeTab('screenshots', 'sites/aps_packagedetails_show.php?id={tmpl_var name='pkg_id'}');">{tmpl_var name='screenshots_txt'}</a> - </li></tmpl_if> - <tmpl_if name='pkg_changelog'> - <li<tmpl_if name='next_tab' op='==' value='changelog'> class="active"</tmpl_if>> - <a href="#" onclick="return changeTab('changelog', 'sites/aps_packagedetails_show.php?id={tmpl_var name='pkg_id'}');">{tmpl_var name='changelog_txt'}</a> - </li></tmpl_if> - <li<tmpl_if name='next_tab' op='==' value='settings'> class="active"</tmpl_if>> - <a href="#" onclick="return changeTab('settings', 'sites/aps_packagedetails_show.php?id={tmpl_var name='pkg_id'}');">{tmpl_var name='settings_txt'}</a> - </li> - </ul> -</div> -<p> </p> - -<div class="panel panel_list_packages"> - - <div class="pnl_listarea"> - <table class="list"> - <tbody> - <tmpl_if name='next_tab' op='==' value='details'> - <tr class="tbl_row_uneven"> - <td width="25%">{tmpl_var name='version_txt'}</td> - <td>{tmpl_var name='pkg_version'} (Release {tmpl_var name='pkg_release'})</td> - </tr> - <tr class="tbl_row_even"> - <td>{tmpl_var name='category_txt'}</td> - <td>{tmpl_var name='pkg_category'}</td> - </tr> - <tr class="tbl_row_uneven"> - <td>{tmpl_var name='description_txt'}</td> - <td>{tmpl_var name='pkg_description'}</td> - </tr> - <tr class="tbl_row_even"> - <td>{tmpl_var name='homepage_txt'}</td> - <td> - <a href="{tmpl_var name='pkg_homepage'}" target="_blank">{tmpl_var name='pkg_homepage'}</a> - </td> - </tr> - <tr class="tbl_row_uneven"> - <td>{tmpl_var name='installed_size_txt'}</td> - <td>{tmpl_var name='pkg_installed_size'}</td> - </tr> - <tr class="tbl_row_even"> - <td>{tmpl_var name='supported_languages_txt'}</td> - <td>{tmpl_var name='pkg_languages'}</td> - </tr> - <tr class="tbl_row_uneven"> - <td>{tmpl_var name='config_script_txt'}</td> - <td>{tmpl_var name='pkg_config_script'}</td> - </tr> - <tr class="tbl_row_even"> - <td>{tmpl_var name='license_txt'}</td> - <td> - <tmpl_if name='pkg_license_name'>{tmpl_var name='pkg_license_name'}<br /></tmpl_if> - <tmpl_if name='pkg_license_type' op='==' value='url'><a href="{tmpl_var name='pkg_license_content'}" target="_blank">{tmpl_var name='pkg_license_content'}</a> - <tmpl_elseif name='pkg_license_content'> - <textarea rows="10" cols="80">{tmpl_var name='pkg_license_content'}</textarea> - </tmpl_if> - </td> - </tr> - <tmpl_elseif name='next_tab' op='==' value='screenshots'> - <tmpl_if name='pkg_screenshots'> - <tr class="tbl_row_even"> - <td style="text-align:center;"> - <tmpl_loop name='pkg_screenshots'> - <img src="{tmpl_var name='ScreenPath'}" alt="{tmpl_var name='ScreenDescription'}" /><br /> - <em>{tmpl_var name='ScreenDescription'}</em><br /><br /> - </tmpl_loop> - </td> - </tr> - </tmpl_if> - <tmpl_elseif name='next_tab' op='==' value='changelog'> - <tmpl_if name='pkg_changelog'> - <tr class="tbl_row_even"> - <td> - <ul> - <tmpl_loop name='pkg_changelog'> - <li>{tmpl_var name='ChangelogVersion'}</li> - <ul> - <tmpl_if name='ChangelogDescription'> - <li>{tmpl_var name='ChangelogDescription'}</li> - </tmpl_if> - </ul> - </tmpl_loop> - </ul> - </td> - </tr> - </tmpl_if> - <tmpl_elseif name='next_tab' op='==' value='settings'> - <tr class="tbl_row_uneven"> - <td width="25%">{tmpl_var name='php_extensions_txt'}</td> - <td>{tmpl_var name='pkg_requirements_php_extensions'}</td> - </tr> - <tr class="tbl_row_even"> - <td>{tmpl_var name='php_settings_txt'}</td> - <td> - <tmpl_loop name='pkg_requirements_php_settings'>{tmpl_var name='PHPSettingName'} = {tmpl_var name='PHPSettingValue'}<br /></tmpl_loop> - </td> - </tr> - <tr class="tbl_row_uneven"> - <td>{tmpl_var name='supported_php_versions_txt'}</td> - <td>{tmpl_var name='pkg_requirements_supported_php_versions'}</td> - </tr> - <tr class="tbl_row_even"> - <td>{tmpl_var name='database_txt'}</td> - <td>{tmpl_var name='pkg_requirements_database'}</a></td> - </tr> - </tmpl_if> - </tbody> - </table> - </div> - +<h2> + <tmpl_if name='pkg_icon' op='!=' value=''> + <img src="{tmpl_var name='pkg_icon'}" height="32" width="32" alt="{tmpl_var name='pkg_name'}" style="vertical-align:text-bottom;" /> + </tmpl_if> + {tmpl_var name='pkg_name'} +</h2> +<b>{tmpl_var name='pkg_summary'}</b> +<p> </p> + +<div class="pnl_toolsarea"> + <fieldset> + <div class="buttons"> + <button class="button iconstxt icoAdd" type="button" onclick="loadContent('sites/aps_install_package.php?id={tmpl_var name='pkg_id'}');"> + <span>{tmpl_var name="install_package_txt"}</span> + </button> + </div> + </fieldset> +</div> +<p> </p><p> </p> + + +<div class="tabbox_tabs"> + <input type="hidden" name="next_tab" value="" /> + <ul> + <li<tmpl_if name='next_tab' op='==' value='details'> class="active"</tmpl_if>> + <a href="#" onclick="return changeTab('details', 'sites/aps_packagedetails_show.php?id={tmpl_var name='pkg_id'}');">{tmpl_var name='details_txt'}</a> + </li> + <tmpl_if name='pkg_screenshots'> + <li<tmpl_if name='next_tab' op='==' value='screenshots'> class="active"</tmpl_if>> + <a href="#" onclick="return changeTab('screenshots', 'sites/aps_packagedetails_show.php?id={tmpl_var name='pkg_id'}');">{tmpl_var name='screenshots_txt'}</a> + </li></tmpl_if> + <tmpl_if name='pkg_changelog'> + <li<tmpl_if name='next_tab' op='==' value='changelog'> class="active"</tmpl_if>> + <a href="#" onclick="return changeTab('changelog', 'sites/aps_packagedetails_show.php?id={tmpl_var name='pkg_id'}');">{tmpl_var name='changelog_txt'}</a> + </li></tmpl_if> + <li<tmpl_if name='next_tab' op='==' value='settings'> class="active"</tmpl_if>> + <a href="#" onclick="return changeTab('settings', 'sites/aps_packagedetails_show.php?id={tmpl_var name='pkg_id'}');">{tmpl_var name='settings_txt'}</a> + </li> + </ul> +</div> +<p> </p> + +<div class="panel panel_list_packages"> + + <div class="pnl_listarea"> + <table class="list"> + <tbody> + <tmpl_if name='next_tab' op='==' value='details'> + <tr class="tbl_row_uneven"> + <td width="25%">{tmpl_var name='version_txt'}</td> + <td>{tmpl_var name='pkg_version'} (Release {tmpl_var name='pkg_release'})</td> + </tr> + <tr class="tbl_row_even"> + <td>{tmpl_var name='category_txt'}</td> + <td>{tmpl_var name='pkg_category'}</td> + </tr> + <tr class="tbl_row_uneven"> + <td>{tmpl_var name='description_txt'}</td> + <td>{tmpl_var name='pkg_description'}</td> + </tr> + <tr class="tbl_row_even"> + <td>{tmpl_var name='homepage_txt'}</td> + <td> + <a href="{tmpl_var name='pkg_homepage'}" target="_blank">{tmpl_var name='pkg_homepage'}</a> + </td> + </tr> + <tr class="tbl_row_uneven"> + <td>{tmpl_var name='installed_size_txt'}</td> + <td>{tmpl_var name='pkg_installed_size'}</td> + </tr> + <tr class="tbl_row_even"> + <td>{tmpl_var name='supported_languages_txt'}</td> + <td>{tmpl_var name='pkg_languages'}</td> + </tr> + <tr class="tbl_row_uneven"> + <td>{tmpl_var name='config_script_txt'}</td> + <td>{tmpl_var name='pkg_config_script'}</td> + </tr> + <tr class="tbl_row_even"> + <td>{tmpl_var name='license_txt'}</td> + <td> + <tmpl_if name='pkg_license_name'>{tmpl_var name='pkg_license_name'}<br /></tmpl_if> + <tmpl_if name='pkg_license_type' op='==' value='url'><a href="{tmpl_var name='pkg_license_content'}" target="_blank">{tmpl_var name='pkg_license_content'}</a> + <tmpl_elseif name='pkg_license_content'> + <textarea rows="10" cols="80">{tmpl_var name='pkg_license_content'}</textarea> + </tmpl_if> + </td> + </tr> + <tmpl_elseif name='next_tab' op='==' value='screenshots'> + <tmpl_if name='pkg_screenshots'> + <tr class="tbl_row_even"> + <td style="text-align:center;"> + <tmpl_loop name='pkg_screenshots'> + <img src="{tmpl_var name='ScreenPath'}" alt="{tmpl_var name='ScreenDescription'}" /><br /> + <em>{tmpl_var name='ScreenDescription'}</em><br /><br /> + </tmpl_loop> + </td> + </tr> + </tmpl_if> + <tmpl_elseif name='next_tab' op='==' value='changelog'> + <tmpl_if name='pkg_changelog'> + <tr class="tbl_row_even"> + <td> + <ul> + <tmpl_loop name='pkg_changelog'> + <li>{tmpl_var name='ChangelogVersion'}</li> + <ul> + <tmpl_if name='ChangelogDescription'> + <li>{tmpl_var name='ChangelogDescription'}</li> + </tmpl_if> + </ul> + </tmpl_loop> + </ul> + </td> + </tr> + </tmpl_if> + <tmpl_elseif name='next_tab' op='==' value='settings'> + <tr class="tbl_row_uneven"> + <td width="25%">{tmpl_var name='php_extensions_txt'}</td> + <td>{tmpl_var name='pkg_requirements_php_extensions'}</td> + </tr> + <tr class="tbl_row_even"> + <td>{tmpl_var name='php_settings_txt'}</td> + <td> + <tmpl_loop name='pkg_requirements_php_settings'>{tmpl_var name='PHPSettingName'} = {tmpl_var name='PHPSettingValue'}<br /></tmpl_loop> + </td> + </tr> + <tr class="tbl_row_uneven"> + <td>{tmpl_var name='supported_php_versions_txt'}</td> + <td>{tmpl_var name='pkg_requirements_supported_php_versions'}</td> + </tr> + <tr class="tbl_row_even"> + <td>{tmpl_var name='database_txt'}</td> + <td>{tmpl_var name='pkg_requirements_database'}</a></td> + </tr> + </tmpl_if> + </tbody> + </table> + </div> + </div> \ No newline at end of file diff --git a/interface/web/sites/templates/aps_packages_list.htm b/interface/web/sites/templates/aps_packages_list.htm index 4765f2edefdf591cf504c1da2023b0d4b962287a..1042e711694182feff40abd67c4fa8bbd1adeb5d 100644 --- a/interface/web/sites/templates/aps_packages_list.htm +++ b/interface/web/sites/templates/aps_packages_list.htm @@ -1,55 +1,55 @@ -<h2>{tmpl_var name="list_head_txt"}</h2> - -<div class="panel panel_list_packages"> - - <div class="pnl_listarea"> - <fieldset><legend>{tmpl_var name="list_head_txt"} ({tmpl_var name='package_count'})</legend> - <table class="list"> - <thead> - <tr class="caption"> - <th class="tbl_col_name" scope="col">{tmpl_var name='name_txt'}</th> - <th class="tbl_col_version" scope="col">{tmpl_var name='version_txt'}</th> - <th class="tbl_col_category" scope="col">{tmpl_var name='category_txt'}</th> - <tmpl_if name='is_admin'> - <th class="tbl_col_package_status" scope="col">{tmpl_var name='status_txt'}</th> - </tmpl_if> - <th class="tbl_col_limit" scope="col"> </th> - </tr> - <tr class="filter"> - <td class="tbl_col_name"><input type="text" name="search_name" value="{tmpl_var name='search_name'}" /></td> - <td class="tbl_col_version"><input type="text" name="search_version" value="{tmpl_var name='search_version'}" /></td> - <td class="tbl_col_customerid"><select name="search_category" onChange="submitForm('pageForm','sites/aps_availablepackages_list.php');">{tmpl_var name='search_category'}</select></td> - <tmpl_if name='is_admin'> - <td class="tbl_col_status"><select name="search_package_status" onChange="submitForm('pageForm','sites/aps_availablepackages_list.php');">{tmpl_var name='search_package_status'}</select></td> - </tmpl_if> - <td class="tbl_col_buttons"><button type="button" class="button icons16 icoFilter" name="Filter" id="Filter" value="{tmpl_var name='filter_txt'}" onclick="submitForm('pageForm','sites/aps_availablepackages_list.php');"><span>{tmpl_var name='filter_txt'}</span></button></td> - </tr> - </thead> - <tbody> - <tmpl_loop name='records'> - <tr class="tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>"> - <td class="tbl_col_name"><a href="#" onclick="loadContent('sites/aps_packagedetails_show.php?id={tmpl_var name='id'}');">{tmpl_var name='name'}</a></td> - <td class="tbl_col_version">{tmpl_var name='version'}-{tmpl_var name='release'}</td> - <td class="tbl_col_category">{tmpl_var name='category'}</td> - <tmpl_if name='is_admin'> - <td class="tbl_col_status"><a href="javascript:loadContentInto('status_content{tmpl_var name='__ROWNUM__'}', 'sites/aps_do_operation.php?action=change_status&id={tmpl_var name='id'}&phpsessid={tmpl_var name='phpsessid'}');"><span id="status_content{tmpl_var name='__ROWNUM__'}">{tmpl_var name='package_status'}</span></a></td> - </tmpl_if> - <td class="tbl_col_buttons"> </td> - </tr> - </tmpl_loop> - <tmpl_unless name="records"> - <tr class="tbl_row_noresults tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>"> - <td colspan="4">{tmpl_var name='globalsearch_noresults_text_txt'}</td> - </tr> - </tmpl_unless> - </tbody> - <tfoot> - <tr> - <td class="tbl_footer tbl_paging" colspan="5">{tmpl_var name='paging'}</td> - </tr> - </tfoot> - </table> - </fieldset> - </div> - +<h2>{tmpl_var name="list_head_txt"}</h2> + +<div class="panel panel_list_packages"> + + <div class="pnl_listarea"> + <fieldset><legend>{tmpl_var name="list_head_txt"} ({tmpl_var name='package_count'})</legend> + <table class="list"> + <thead> + <tr class="caption"> + <th class="tbl_col_name" scope="col">{tmpl_var name='name_txt'}</th> + <th class="tbl_col_version" scope="col">{tmpl_var name='version_txt'}</th> + <th class="tbl_col_category" scope="col">{tmpl_var name='category_txt'}</th> + <tmpl_if name='is_admin'> + <th class="tbl_col_package_status" scope="col">{tmpl_var name='status_txt'}</th> + </tmpl_if> + <th class="tbl_col_limit" scope="col"> </th> + </tr> + <tr class="filter"> + <td class="tbl_col_name"><input type="text" name="search_name" value="{tmpl_var name='search_name'}" /></td> + <td class="tbl_col_version"><input type="text" name="search_version" value="{tmpl_var name='search_version'}" /></td> + <td class="tbl_col_customerid"><select name="search_category" onChange="submitForm('pageForm','sites/aps_availablepackages_list.php');">{tmpl_var name='search_category'}</select></td> + <tmpl_if name='is_admin'> + <td class="tbl_col_status"><select name="search_package_status" onChange="submitForm('pageForm','sites/aps_availablepackages_list.php');">{tmpl_var name='search_package_status'}</select></td> + </tmpl_if> + <td class="tbl_col_buttons"><button type="button" class="button icons16 icoFilter" name="Filter" id="Filter" value="{tmpl_var name='filter_txt'}" onclick="submitForm('pageForm','sites/aps_availablepackages_list.php');"><span>{tmpl_var name='filter_txt'}</span></button></td> + </tr> + </thead> + <tbody> + <tmpl_loop name='records'> + <tr class="tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>"> + <td class="tbl_col_name"><a href="#" onclick="loadContent('sites/aps_packagedetails_show.php?id={tmpl_var name='id'}');">{tmpl_var name='name'}</a></td> + <td class="tbl_col_version">{tmpl_var name='version'}-{tmpl_var name='release'}</td> + <td class="tbl_col_category">{tmpl_var name='category'}</td> + <tmpl_if name='is_admin'> + <td class="tbl_col_status"><a href="javascript:loadContentInto('status_content{tmpl_var name='__ROWNUM__'}', 'sites/aps_do_operation.php?action=change_status&id={tmpl_var name='id'}&phpsessid={tmpl_var name='phpsessid'}');"><span id="status_content{tmpl_var name='__ROWNUM__'}">{tmpl_var name='package_status'}</span></a></td> + </tmpl_if> + <td class="tbl_col_buttons"> </td> + </tr> + </tmpl_loop> + <tmpl_unless name="records"> + <tr class="tbl_row_noresults tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>"> + <td colspan="4">{tmpl_var name='globalsearch_noresults_text_txt'}</td> + </tr> + </tmpl_unless> + </tbody> + <tfoot> + <tr> + <td class="tbl_footer tbl_paging" colspan="5">{tmpl_var name='paging'}</td> + </tr> + </tfoot> + </table> + </fieldset> + </div> + </div> \ No newline at end of file diff --git a/interface/web/sites/templates/web_aliasdomain_advanced.htm b/interface/web/sites/templates/web_aliasdomain_advanced.htm index 293b87124431868510e5b912295e962adcea5bb8..4c605ca94cc75433c8d1ebc6914f26aa999e83b7 100644 --- a/interface/web/sites/templates/web_aliasdomain_advanced.htm +++ b/interface/web/sites/templates/web_aliasdomain_advanced.htm @@ -1,37 +1,37 @@ -<h2><tmpl_var name="list_head_txt"></h2> -<p><tmpl_var name="list_desc_txt"></p> - -<div class="panel panel_web_domain"> - - <div class="pnl_formsarea"> - <fieldset class="inlineLabels"><legend>Options</legend> - <div class="ctrlHolder proxy"> - <label for="proxy_directives">{tmpl_var name='proxy_directives_txt'}</label> - <textarea name="proxy_directives" id="proxy_directives" rows='10' cols='50' style="width:400px;">{tmpl_var name='proxy_directives'}</textarea> <b>{tmpl_var name="available_proxy_directive_snippets_txt"}</b><br><br> {tmpl_var name="proxy_directive_snippets_txt"} - </div> - </fieldset> - - <input type="hidden" name="id" value="{tmpl_var name='id'}"> - - <div class="buttonHolder buttons"> - <button class="positive iconstxt icoPositive" type="button" value="{tmpl_var name='btn_save_txt'}" onclick="submitForm('pageForm','sites/web_aliasdomain_edit.php');"><span>{tmpl_var name='btn_save_txt'}</span></button> - <button class="negative iconstxt icoNegative" type="button" value="{tmpl_var name='btn_cancel_txt'}" onclick="loadContent('sites/web_aliasdomain_list.php');"><span>{tmpl_var name='btn_cancel_txt'}</span></button> - </div> - </div> - -</div> -<script language="JavaScript" type="text/javascript"> - var webId = jQuery('input[name="id"]').val(); - adjustForm(); - - function adjustForm(){ - jQuery.getJSON('sites/ajax_get_json.php'+ '?' + Math.round(new Date().getTime()), {web_id : webId, type : "getredirecttype"}, function(data) { - if(data.redirecttype == "proxy"){ - jQuery('.proxy').show(); - } else { - jQuery('.proxy').hide(); - } - }); - } - +<h2><tmpl_var name="list_head_txt"></h2> +<p><tmpl_var name="list_desc_txt"></p> + +<div class="panel panel_web_domain"> + + <div class="pnl_formsarea"> + <fieldset class="inlineLabels"><legend>Options</legend> + <div class="ctrlHolder proxy"> + <label for="proxy_directives">{tmpl_var name='proxy_directives_txt'}</label> + <textarea name="proxy_directives" id="proxy_directives" rows='10' cols='50' style="width:400px;">{tmpl_var name='proxy_directives'}</textarea> <b>{tmpl_var name="available_proxy_directive_snippets_txt"}</b><br><br> {tmpl_var name="proxy_directive_snippets_txt"} + </div> + </fieldset> + + <input type="hidden" name="id" value="{tmpl_var name='id'}"> + + <div class="buttonHolder buttons"> + <button class="positive iconstxt icoPositive" type="button" value="{tmpl_var name='btn_save_txt'}" onclick="submitForm('pageForm','sites/web_aliasdomain_edit.php');"><span>{tmpl_var name='btn_save_txt'}</span></button> + <button class="negative iconstxt icoNegative" type="button" value="{tmpl_var name='btn_cancel_txt'}" onclick="loadContent('sites/web_aliasdomain_list.php');"><span>{tmpl_var name='btn_cancel_txt'}</span></button> + </div> + </div> + +</div> +<script language="JavaScript" type="text/javascript"> + var webId = jQuery('input[name="id"]').val(); + adjustForm(); + + function adjustForm(){ + jQuery.getJSON('sites/ajax_get_json.php'+ '?' + Math.round(new Date().getTime()), {web_id : webId, type : "getredirecttype"}, function(data) { + if(data.redirecttype == "proxy"){ + jQuery('.proxy').show(); + } else { + jQuery('.proxy').hide(); + } + }); + } + </script> \ No newline at end of file diff --git a/interface/web/sites/templates/web_subdomain_advanced.htm b/interface/web/sites/templates/web_subdomain_advanced.htm index d2beb4275d5924ba81cf4a362f3b6e3cabc8841f..3924362a362cf976c0ec1751c8413ca008bb59fa 100644 --- a/interface/web/sites/templates/web_subdomain_advanced.htm +++ b/interface/web/sites/templates/web_subdomain_advanced.htm @@ -1,37 +1,37 @@ -<h2><tmpl_var name="list_head_txt"></h2> -<p><tmpl_var name="list_desc_txt"></p> - -<div class="panel panel_web_subdomain"> - - <div class="pnl_formsarea"> - <fieldset class="inlineLabels"><legend>Options</legend> - <div class="ctrlHolder proxy"> - <label for="proxy_directives">{tmpl_var name='proxy_directives_txt'}</label> - <textarea name="proxy_directives" id="proxy_directives" rows='10' cols='50' style="width:400px;">{tmpl_var name='proxy_directives'}</textarea> <b>{tmpl_var name="available_proxy_directive_snippets_txt"}</b><br><br> {tmpl_var name="proxy_directive_snippets_txt"} - </div> - </fieldset> - - <input type="hidden" name="id" value="{tmpl_var name='id'}"> - - <div class="buttonHolder buttons"> - <button class="positive iconstxt icoPositive" type="button" value="{tmpl_var name='btn_save_txt'}" onclick="submitForm('pageForm','sites/web_subdomain_edit.php');"><span>{tmpl_var name='btn_save_txt'}</span></button> - <button class="negative iconstxt icoNegative" type="button" value="{tmpl_var name='btn_cancel_txt'}" onclick="loadContent('sites/web_subdomain_list.php');"><span>{tmpl_var name='btn_cancel_txt'}</span></button> - </div> - </div> - -</div> -<script language="JavaScript" type="text/javascript"> - var webId = jQuery('input[name="id"]').val(); - adjustForm(); - - function adjustForm(){ - jQuery.getJSON('sites/ajax_get_json.php'+ '?' + Math.round(new Date().getTime()), {web_id : webId, type : "getredirecttype"}, function(data) { - if(data.redirecttype == "proxy"){ - jQuery('.proxy').show(); - } else { - jQuery('.proxy').hide(); - } - }); - } - -</script> +<h2><tmpl_var name="list_head_txt"></h2> +<p><tmpl_var name="list_desc_txt"></p> + +<div class="panel panel_web_subdomain"> + + <div class="pnl_formsarea"> + <fieldset class="inlineLabels"><legend>Options</legend> + <div class="ctrlHolder proxy"> + <label for="proxy_directives">{tmpl_var name='proxy_directives_txt'}</label> + <textarea name="proxy_directives" id="proxy_directives" rows='10' cols='50' style="width:400px;">{tmpl_var name='proxy_directives'}</textarea> <b>{tmpl_var name="available_proxy_directive_snippets_txt"}</b><br><br> {tmpl_var name="proxy_directive_snippets_txt"} + </div> + </fieldset> + + <input type="hidden" name="id" value="{tmpl_var name='id'}"> + + <div class="buttonHolder buttons"> + <button class="positive iconstxt icoPositive" type="button" value="{tmpl_var name='btn_save_txt'}" onclick="submitForm('pageForm','sites/web_subdomain_edit.php');"><span>{tmpl_var name='btn_save_txt'}</span></button> + <button class="negative iconstxt icoNegative" type="button" value="{tmpl_var name='btn_cancel_txt'}" onclick="loadContent('sites/web_subdomain_list.php');"><span>{tmpl_var name='btn_cancel_txt'}</span></button> + </div> + </div> + +</div> +<script language="JavaScript" type="text/javascript"> + var webId = jQuery('input[name="id"]').val(); + adjustForm(); + + function adjustForm(){ + jQuery.getJSON('sites/ajax_get_json.php'+ '?' + Math.round(new Date().getTime()), {web_id : webId, type : "getredirecttype"}, function(data) { + if(data.redirecttype == "proxy"){ + jQuery('.proxy').show(); + } else { + jQuery('.proxy').hide(); + } + }); + } + +</script> diff --git a/interface/web/sites/web_domain_edit.php b/interface/web/sites/web_domain_edit.php index c3c4f97e697f11dd105617e7a17935f5ed375e4f..5e26a14a53a55faac7e1afcd2f8327da8a100f6a 100644 --- a/interface/web/sites/web_domain_edit.php +++ b/interface/web/sites/web_domain_edit.php @@ -1,1025 +1,1025 @@ -<?php -/* -Copyright (c) 2007 - 2009, Till Brehm, projektfarm Gmbh -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of ISPConfig nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -/****************************************** -* Begin Form configuration -******************************************/ - -$tform_def_file = "form/web_domain.tform.php"; - -/****************************************** -* End Form configuration -******************************************/ - -require_once('../../lib/config.inc.php'); -require_once('../../lib/app.inc.php'); - -//* Check permissions for module -$app->auth->check_module_permissions('sites'); - -// Loading classes -$app->uses('tpl,tform,tform_actions,tools_sites'); -$app->load('tform_actions'); - -class page_action extends tform_actions { - - //* Returna a "3/2/1" path hash from a numeric id '123' - function id_hash($id,$levels) { - $hash = "" . $id % 10 ; - $id /= 10 ; - $levels -- ; - while ( $levels > 0 ) { - $hash .= "/" . $id % 10 ; - $id /= 10 ; - $levels-- ; - } - return $hash; - } - - function onShowNew() { - global $app, $conf; - - // we will check only users, not admins - if($_SESSION["s"]["user"]["typ"] == 'user') { - if(!$app->tform->checkClientLimit('limit_web_domain',"type = 'vhost'")) { - $app->error($app->tform->wordbook["limit_web_domain_txt"]); - } - if(!$app->tform->checkResellerLimit('limit_web_domain',"type = 'vhost'")) { - $app->error('Reseller: '.$app->tform->wordbook["limit_web_domain_txt"]); - } - - // Get the limits of the client - $client_group_id = $_SESSION["s"]["user"]["default_group"]; - $client = $app->db->queryOneRecord("SELECT client.default_webserver FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id"); - $app->tpl->setVar("server_id_value", $client['default_webserver']); - } - $app->tform->formDef['tabs']['domain']['readonly'] = false; - - parent::onShowNew(); - } - - function onShowEnd() { - global $app, $conf; - - $app->uses('ini_parser,getconf'); - - $read_limits = array('limit_cgi', 'limit_ssi', 'limit_perl', 'limit_ruby', 'limit_python', 'force_suexec', 'limit_hterror', 'limit_wildcard', 'limit_ssl'); - - //* Client: If the logged in user is not admin and has no sub clients (no reseller) - if($_SESSION["s"]["user"]["typ"] != 'admin' && !$app->auth->has_clients($_SESSION['s']['user']['userid'])) { - - // Get the limits of the client - $client_group_id = $_SESSION["s"]["user"]["default_group"]; - $client = $app->db->queryOneRecord("SELECT client.limit_web_domain, client.default_webserver, client." . implode(", client.", $read_limits) . " FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id"); - - //* Get global web config - $web_config = $app->getconf->get_server_config($client['default_webserver'], 'web'); - - // Set the webserver to the default server of the client - $tmp = $app->db->queryOneRecord("SELECT server_name FROM server WHERE server_id = ".intval($client['default_webserver'])); - $app->tpl->setVar("server_id","<option value='$client[default_webserver]'>$tmp[server_name]</option>"); - unset($tmp); - - //* Fill the IPv4 select field with the IP addresses that are allowed for this client - $sql = "SELECT ip_address FROM server_ip WHERE server_id = ".$client['default_webserver']." AND ip_type = 'IPv4' AND (client_id = 0 OR client_id=".$_SESSION['s']['user']['client_id'].")"; - $ips = $app->db->queryAllRecords($sql); - $ip_select = ($web_config['enable_ip_wildcard'] == 'y')?"<option value='*'>*</option>":""; - //$ip_select = ""; - if(is_array($ips)) { - foreach( $ips as $ip) { - $selected = ($ip["ip_address"] == $this->dataRecord["ip_address"])?'SELECTED':''; - $ip_select .= "<option value='$ip[ip_address]' $selected>$ip[ip_address]</option>\r\n"; - } - } - $app->tpl->setVar("ip_address",$ip_select); - unset($tmp); - unset($ips); - - //* Fill the IPv6 select field with the IP addresses that are allowed for this client - $sql = "SELECT ip_address FROM server_ip WHERE server_id = ".intval($client['default_webserver'])." AND ip_type = 'IPv6' AND (client_id = 0 OR client_id=".$_SESSION['s']['user']['client_id'].")"; - $ips = $app->db->queryAllRecords($sql); - $ip_select = "<option value=''></option>"; - //$ip_select = ""; - if(is_array($ips)) { - foreach( $ips as $ip) { - $selected = ($ip["ip_address"] == $this->dataRecord["ipv6_address"])?'SELECTED':''; - $ip_select .= "<option value='$ip[ip_address]' $selected>$ip[ip_address]</option>\r\n"; - } - } - $app->tpl->setVar("ipv6_address",$ip_select); - unset($tmp); - unset($ips); - - //PHP Version Selection (FastCGI) - $server_type = 'apache'; - if(!empty($web_config['server_type'])) $server_type = $web_config['server_type']; - if($server_type == 'nginx' && $this->dataRecord['php'] == 'fast-cgi') $this->dataRecord['php'] = 'php-fpm'; - if($this->dataRecord['php'] == 'php-fpm'){ - $php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fpm_init_script != '' AND php_fpm_ini_dir != '' AND php_fpm_pool_dir != '' AND server_id = ".($this->id > 0 ? $this->dataRecord['server_id'] : intval($client['default_webserver']))." AND (client_id = 0 OR client_id=".$_SESSION['s']['user']['client_id'].")"); - } - if($this->dataRecord['php'] == 'fast-cgi'){ - $php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fastcgi_binary != '' AND php_fastcgi_ini_dir != '' AND server_id = ".($this->id > 0 ? $this->dataRecord['server_id'] : intval($client['default_webserver']))." AND (client_id = 0 OR client_id=".$_SESSION['s']['user']['client_id'].")"); - } - $php_select = "<option value=''>Default</option>"; - if(is_array($php_records) && !empty($php_records)) { - foreach( $php_records as $php_record) { - if($this->dataRecord['php'] == 'php-fpm'){ - $php_version = $php_record['name'].':'.$php_record['php_fpm_init_script'].':'.$php_record['php_fpm_ini_dir'].':'.$php_record['php_fpm_pool_dir']; - } else { - $php_version = $php_record['name'].':'.$php_record['php_fastcgi_binary'].':'.$php_record['php_fastcgi_ini_dir']; - } - $selected = ($php_version == $this->dataRecord["fastcgi_php_version"])?'SELECTED':''; - $php_select .= "<option value='$php_version' $selected>".$php_record['name']."</option>\r\n"; - } - } - $app->tpl->setVar("fastcgi_php_version",$php_select); - unset($php_records); - - // add limits to template to be able to hide settings - foreach($read_limits as $limit) $app->tpl->setVar($limit, $client[$limit]); - - - //* Reseller: If the logged in user is not admin and has sub clients (is a reseller) - } elseif ($_SESSION["s"]["user"]["typ"] != 'admin' && $app->auth->has_clients($_SESSION['s']['user']['userid'])) { - - // Get the limits of the client - $client_group_id = $_SESSION["s"]["user"]["default_group"]; - $client = $app->db->queryOneRecord("SELECT client.client_id, client.limit_web_domain, client.default_webserver, client.contact_name, CONCAT(IF(client.company_name != '', CONCAT(client.company_name, ' :: '), ''), client.contact_name, ' (', client.username, IF(client.customer_no != '', CONCAT(', ', client.customer_no), ''), ')') as contactname, sys_group.name, client." . implode(", client.", $read_limits) . " FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id"); - - //* Get global web config - $web_config = $app->getconf->get_server_config($client['default_webserver'], 'web'); - - // Set the webserver to the default server of the client - $tmp = $app->db->queryOneRecord("SELECT server_name FROM server WHERE server_id = ".intval($client['default_webserver'])); - $app->tpl->setVar("server_id","<option value='$client[default_webserver]'>$tmp[server_name]</option>"); - unset($tmp); - - // Fill the client select field - $sql = "SELECT sys_group.groupid, sys_group.name, CONCAT(IF(client.company_name != '', CONCAT(client.company_name, ' :: '), ''), client.contact_name, ' (', client.username, IF(client.customer_no != '', CONCAT(', ', client.customer_no), ''), ')') as contactname FROM sys_group, client WHERE sys_group.client_id = client.client_id AND client.parent_client_id = ".$client['client_id']." ORDER BY sys_group.name"; - $records = $app->db->queryAllRecords($sql); - $tmp = $app->db->queryOneRecord("SELECT groupid FROM sys_group WHERE client_id = ".$client['client_id']); - $client_select = '<option value="'.$tmp['groupid'].'">'.$client['contactname'].'</option>'; - //$tmp_data_record = $app->tform->getDataRecord($this->id); - if(is_array($records)) { - $selected_client_group_id = 0; // needed to get list of PHP versions - foreach( $records as $rec) { - if(is_array($this->dataRecord) && ($rec["groupid"] == $this->dataRecord['client_group_id'] || $rec["groupid"] == $this->dataRecord['sys_groupid']) && !$selected_client_group_id) $selected_client_group_id = $rec["groupid"]; - $selected = @(is_array($this->dataRecord) && ($rec["groupid"] == $this->dataRecord['client_group_id'] || $rec["groupid"] == $this->dataRecord['sys_groupid']))?'SELECTED':''; - if($selected == 'SELECTED') $selected_client_group_id = $rec["groupid"]; - $client_select .= "<option value='$rec[groupid]' $selected>$rec[contactname]</option>\r\n"; - } - } - $app->tpl->setVar("client_group_id",$client_select); - - //* Fill the IPv4 select field with the IP addresses that are allowed for this client - $sql = "SELECT ip_address FROM server_ip WHERE server_id = ".intval($client['default_webserver'])." AND ip_type = 'IPv4' AND (client_id = 0 OR client_id=".$_SESSION['s']['user']['client_id'].")"; - $ips = $app->db->queryAllRecords($sql); - $ip_select = ($web_config['enable_ip_wildcard'] == 'y')?"<option value='*'>*</option>":""; - //$ip_select = ""; - if(is_array($ips)) { - foreach( $ips as $ip) { - $selected = ($ip["ip_address"] == $this->dataRecord["ip_address"])?'SELECTED':''; - $ip_select .= "<option value='$ip[ip_address]' $selected>$ip[ip_address]</option>\r\n"; - } - } - $app->tpl->setVar("ip_address",$ip_select); - unset($tmp); - unset($ips); - - //* Fill the IPv6 select field with the IP addresses that are allowed for this client - $sql = "SELECT ip_address FROM server_ip WHERE server_id = ".intval($client['default_webserver'])." AND ip_type = 'IPv6' AND (client_id = 0 OR client_id=".$_SESSION['s']['user']['client_id'].")"; - $ips = $app->db->queryAllRecords($sql); - $ip_select = "<option value=''></option>"; - //$ip_select = ""; - if(is_array($ips)) { - foreach( $ips as $ip) { - $selected = ($ip["ip_address"] == $this->dataRecord["ipv6_address"])?'SELECTED':''; - $ip_select .= "<option value='$ip[ip_address]' $selected>$ip[ip_address]</option>\r\n"; - } - } - $app->tpl->setVar("ipv6_address",$ip_select); - unset($tmp); - unset($ips); - - //PHP Version Selection (FastCGI) - $server_type = 'apache'; - if(!empty($web_config['server_type'])) $server_type = $web_config['server_type']; - if($server_type == 'nginx' && $this->dataRecord['php'] == 'fast-cgi') $this->dataRecord['php'] = 'php-fpm'; - $selected_client = $app->db->queryOneRecord("SELECT client_id FROM sys_group WHERE groupid = $selected_client_group_id"); - //$sql_where = " AND (client_id = 0 OR client_id=".$_SESSION['s']['user']['client_id']." OR client_id = ".intval($selected_client['client_id']).")"; - $sql_where = " AND (client_id = 0 OR client_id = ".intval($selected_client['client_id']).")"; - if($this->dataRecord['php'] == 'php-fpm'){ - $php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fpm_init_script != '' AND php_fpm_ini_dir != '' AND php_fpm_pool_dir != '' AND server_id = ".($this->id > 0 ? $this->dataRecord['server_id'] : intval($client['default_webserver'])).$sql_where); - } - if($this->dataRecord['php'] == 'fast-cgi') { - $php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fastcgi_binary != '' AND php_fastcgi_ini_dir != '' AND server_id = ".($this->id > 0 ? $this->dataRecord['server_id'] : intval($client['default_webserver'])).$sql_where); - } - $php_select = "<option value=''>Default</option>"; - if(is_array($php_records) && !empty($php_records)) { - foreach( $php_records as $php_record) { - if($this->dataRecord['php'] == 'php-fpm'){ - $php_version = $php_record['name'].':'.$php_record['php_fpm_init_script'].':'.$php_record['php_fpm_ini_dir'].':'.$php_record['php_fpm_pool_dir']; - } else { - $php_version = $php_record['name'].':'.$php_record['php_fastcgi_binary'].':'.$php_record['php_fastcgi_ini_dir']; - } - $selected = ($php_version == $this->dataRecord["fastcgi_php_version"])?'SELECTED':''; - $php_select .= "<option value='$php_version' $selected>".$php_record['name']."</option>\r\n"; - } - } - $app->tpl->setVar("fastcgi_php_version",$php_select); - unset($php_records); - - // add limits to template to be able to hide settings - foreach($read_limits as $limit) $app->tpl->setVar($limit, $client[$limit]); - - - //* Admin: If the logged in user is admin - } else { - - // The user is admin, so we fill in all IP addresses of the server - if($this->id > 0) { - if(!isset($this->dataRecord["server_id"])){ - $tmp = $app->db->queryOneRecord("SELECT server_id FROM web_domain WHERE domain_id = ".$app->functions->intval($this->id)); - $this->dataRecord["server_id"] = $tmp["server_id"]; - unset($tmp); - } - $server_id = intval(@$this->dataRecord["server_id"]); - } else { - // Get the first server ID - $tmp = $app->db->queryOneRecord("SELECT server_id FROM server WHERE web_server = 1 ORDER BY server_name LIMIT 0,1"); - $server_id = intval($tmp['server_id']); - } - - //* get global web config - $web_config = $app->getconf->get_server_config($server_id, 'web'); - - //* Fill the IPv4 select field - $sql = "SELECT ip_address FROM server_ip WHERE ip_type = 'IPv4' AND server_id = $server_id"; - $ips = $app->db->queryAllRecords($sql); - $ip_select = ($web_config['enable_ip_wildcard'] == 'y')?"<option value='*'>*</option>":""; - //$ip_select = ""; - if(is_array($ips)) { - foreach( $ips as $ip) { - $selected = ($ip["ip_address"] == $this->dataRecord["ip_address"])?'SELECTED':''; - $ip_select .= "<option value='$ip[ip_address]' $selected>$ip[ip_address]</option>\r\n"; - } - } - $app->tpl->setVar("ip_address",$ip_select); - unset($tmp); - unset($ips); - - //* Fill the IPv6 select field - $sql = "SELECT ip_address FROM server_ip WHERE ip_type = 'IPv6' AND server_id = $server_id"; - $ips = $app->db->queryAllRecords($sql); - $ip_select = "<option value=''></option>"; - //$ip_select = ""; - if(is_array($ips)) { - foreach( $ips as $ip) { - $selected = ($ip["ip_address"] == $this->dataRecord["ipv6_address"])?'SELECTED':''; - $ip_select .= "<option value='$ip[ip_address]' $selected>$ip[ip_address]</option>\r\n"; - } - } - $app->tpl->setVar("ipv6_address",$ip_select); - unset($tmp); - unset($ips); - - // Fill the client select field - $sql = "SELECT sys_group.groupid, sys_group.name, CONCAT(IF(client.company_name != '', CONCAT(client.company_name, ' :: '), ''), client.contact_name, ' (', client.username, IF(client.customer_no != '', CONCAT(', ', client.customer_no), ''), ')') as contactname FROM sys_group, client WHERE sys_group.client_id = client.client_id AND sys_group.client_id > 0 ORDER BY sys_group.name"; - $clients = $app->db->queryAllRecords($sql); - $client_select = "<option value='0'></option>"; - //$tmp_data_record = $app->tform->getDataRecord($this->id); - if(is_array($clients)) { - $selected_client_group_id = 0; // needed to get list of PHP versions - foreach($clients as $client) { - if(is_array($this->dataRecord) && ($client["groupid"] == $this->dataRecord['client_group_id'] || $client["groupid"] == $this->dataRecord['sys_groupid']) && !$selected_client_group_id) $selected_client_group_id = $client["groupid"]; - //$selected = @($client["groupid"] == $tmp_data_record["sys_groupid"])?'SELECTED':''; - $selected = @(is_array($this->dataRecord) && ($client["groupid"] == $this->dataRecord['client_group_id'] || $client["groupid"] == $this->dataRecord['sys_groupid']))?'SELECTED':''; - if($selected == 'SELECTED') $selected_client_group_id = $client["groupid"]; - $client_select .= "<option value='$client[groupid]' $selected>$client[contactname]</option>\r\n"; - } - } - $app->tpl->setVar("client_group_id",$client_select); - - //PHP Version Selection (FastCGI) - $server_type = 'apache'; - if(!empty($web_config['server_type'])) $server_type = $web_config['server_type']; - if($server_type == 'nginx' && $this->dataRecord['php'] == 'fast-cgi') $this->dataRecord['php'] = 'php-fpm'; - $selected_client = $app->db->queryOneRecord("SELECT client_id FROM sys_group WHERE groupid = $selected_client_group_id"); - //$sql_where = " AND (client_id = 0 OR client_id=".$_SESSION['s']['user']['client_id']." OR client_id = ".intval($selected_client['client_id']).")"; - $sql_where = " AND (client_id = 0 OR client_id = ".intval($selected_client['client_id']).")"; - if($this->dataRecord['php'] == 'php-fpm'){ - $php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fpm_init_script != '' AND php_fpm_ini_dir != '' AND php_fpm_pool_dir != '' AND server_id = $server_id".$sql_where); - } - if($this->dataRecord['php'] == 'fast-cgi') { - $php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fastcgi_binary != '' AND php_fastcgi_ini_dir != '' AND server_id = $server_id".$sql_where); - } - $php_select = "<option value=''>Default</option>"; - if(is_array($php_records) && !empty($php_records)) { - foreach( $php_records as $php_record) { - if($this->dataRecord['php'] == 'php-fpm'){ - $php_version = $php_record['name'].':'.$php_record['php_fpm_init_script'].':'.$php_record['php_fpm_ini_dir'].':'.$php_record['php_fpm_pool_dir']; - } else { - $php_version = $php_record['name'].':'.$php_record['php_fastcgi_binary'].':'.$php_record['php_fastcgi_ini_dir']; - } - $selected = ($php_version == $this->dataRecord["fastcgi_php_version"])?'SELECTED':''; - $php_select .= "<option value='$php_version' $selected>".$php_record['name']."</option>\r\n"; - } - } - $app->tpl->setVar("fastcgi_php_version",$php_select); - unset($php_records); - - foreach($read_limits as $limit) $app->tpl->setVar($limit, ($limit == 'force_suexec' ? 'n' : 'y')); - - // Directive Snippets - $php_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'php' AND active = 'y'"); - $php_directive_snippets_txt = ''; - if(is_array($php_directive_snippets) && !empty($php_directive_snippets)){ - foreach($php_directive_snippets as $php_directive_snippet){ - $php_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$php_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.htmlentities($php_directive_snippet['snippet']).'</pre></a> '; - } - } - if($php_directive_snippets_txt == '') $php_directive_snippets_txt = '------'; - $app->tpl->setVar("php_directive_snippets_txt",$php_directive_snippets_txt); - - if($server_type == 'apache'){ - $apache_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'apache' AND active = 'y'"); - $apache_directive_snippets_txt = ''; - if(is_array($apache_directive_snippets) && !empty($apache_directive_snippets)){ - foreach($apache_directive_snippets as $apache_directive_snippet){ - $apache_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$apache_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.htmlentities($apache_directive_snippet['snippet']).'</pre></a> '; - } - } - if($apache_directive_snippets_txt == '') $apache_directive_snippets_txt = '------'; - $app->tpl->setVar("apache_directive_snippets_txt",$apache_directive_snippets_txt); - } - - if($server_type == 'nginx'){ - $nginx_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'nginx' AND active = 'y'"); - $nginx_directive_snippets_txt = ''; - if(is_array($nginx_directive_snippets) && !empty($nginx_directive_snippets)){ - foreach($nginx_directive_snippets as $nginx_directive_snippet){ - $nginx_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$nginx_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.htmlentities($nginx_directive_snippet['snippet']).'</pre></a> '; - } - } - if($nginx_directive_snippets_txt == '') $nginx_directive_snippets_txt = '------'; - $app->tpl->setVar("nginx_directive_snippets_txt",$nginx_directive_snippets_txt); - } - - $proxy_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'proxy' AND active = 'y'"); - $proxy_directive_snippets_txt = ''; - if(is_array($proxy_directive_snippets) && !empty($proxy_directive_snippets)){ - foreach($proxy_directive_snippets as $proxy_directive_snippet){ - $proxy_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$proxy_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.htmlentities($proxy_directive_snippet['snippet']).'</pre></a> '; - } - } - if($proxy_directive_snippets_txt == '') $proxy_directive_snippets_txt = '------'; - $app->tpl->setVar("proxy_directive_snippets_txt",$proxy_directive_snippets_txt); - } - - $ssl_domain_select = ''; - $tmp = $app->db->queryOneRecord("SELECT domain FROM web_domain WHERE domain_id = ".$this->id); - $ssl_domains = array($tmp["domain"],'www.'.$tmp["domain"],'*.'.$tmp["domain"]); - if(is_array($ssl_domains)) { - foreach( $ssl_domains as $ssl_domain) { - $selected = ($ssl_domain == $this->dataRecord['ssl_domain'])?'SELECTED':''; - $ssl_domain_select .= "<option value='$ssl_domain' $selected>$ssl_domain</option>\r\n"; - } - } - $app->tpl->setVar("ssl_domain",$ssl_domain_select); - unset($ssl_domain_select); - unset($ssl_domains); - unset($ssl_domain); - - if($this->id > 0) { - //* we are editing a existing record - $app->tpl->setVar("edit_disabled", 1); - $app->tpl->setVar("server_id_value", $this->dataRecord["server_id"]); - } else { - $app->tpl->setVar("edit_disabled", 0); - } - - $tmp_txt = ($this->dataRecord['traffic_quota_lock'] == 'y')?'<b>('.$app->tform->lng('traffic_quota_exceeded_txt').')</b>':''; - $app->tpl->setVar("traffic_quota_exceeded_txt", $tmp_txt); - - /* - * Now we have to check, if we should use the domain-module to select the domain - * or not - */ - $settings = $app->getconf->get_global_config('domains'); - if ($settings['use_domain_module'] == 'y') { - /* - * The domain-module is in use. - */ - $domains = $app->tools_sites->getDomainModuleDomains(); - $domain_select = ''; - if(is_array($domains) && sizeof($domains) > 0) { - /* We have domains in the list, so create the drop-down-list */ - foreach( $domains as $domain) { - $domain_select .= "<option value=" . $domain['domain_id'] ; - if ($domain['domain'] == $this->dataRecord["domain"]) { - $domain_select .= " selected"; - } - $domain_select .= ">" . $app->functions->idn_decode($domain['domain']) . "</option>\r\n"; - } - } - else { - /* - * We have no domains in the domain-list. This means, we can not add ANY new domain. - * To avoid, that the variable "domain_option" is empty and so the user can - * free enter a domain, we have to create a empty option! - */ - $domain_select .= "<option value=''></option>\r\n"; - } - $app->tpl->setVar("domain_option",$domain_select); - } - - // check for configuration errors in sys_datalog - if($this->id > 0) { - $datalog = $app->db->queryOneRecord("SELECT sys_datalog.error, sys_log.tstamp FROM sys_datalog, sys_log WHERE sys_datalog.dbtable = 'web_domain' AND sys_datalog.dbidx = 'domain_id:".$this->id."' AND sys_datalog.datalog_id = sys_log.datalog_id AND sys_log.message = CONCAT('Processed datalog_id ',sys_log.datalog_id) ORDER BY sys_datalog.tstamp DESC"); - if(is_array($datalog) && !empty($datalog)){ - if(trim($datalog['error']) != ''){ - $app->tpl->setVar("config_error_msg",nl2br(htmlentities($datalog['error']))); - $app->tpl->setVar("config_error_tstamp",date($app->lng('conf_format_datetime'), $datalog['tstamp'])); - } - } - } - - parent::onShowEnd(); - } - - function onShowEdit() { - global $app; - if($app->tform->checkPerm($this->id, 'riud')) $app->tform->formDef['tabs']['domain']['readonly'] = false; - parent::onShowEdit(); - } - - function onSubmit() { - global $app, $conf; - - /* check if the domain module is used - and check if the selected domain can be used! */ - if($app->tform->getCurrentTab() == 'domain') { - $app->uses('ini_parser,getconf'); - $settings = $app->getconf->get_global_config('domains'); - if ($settings['use_domain_module'] == 'y') { - $domain_check = $app->tools_sites->checkDomainModuleDomain($this->dataRecord['domain']); - if(!$domain_check) { - // invalid domain selected - $app->tform->errorMessage .= $app->tform->lng("domain_error_empty")."<br />"; - } else { - $this->dataRecord['domain'] = $domain_check; - } - } - } - - // nginx: if redirect type is proxy and redirect path is no URL, display error - //if($this->dataRecord["redirect_type"] == 'proxy' && substr($this->dataRecord['redirect_path'],0,1) == '/'){ - // $app->tform->errorMessage .= $app->tform->lng("error_proxy_requires_url")."<br />"; - //} - - // Set a few fixed values - $this->dataRecord["parent_domain_id"] = 0; - $this->dataRecord["type"] = 'vhost'; - $this->dataRecord["vhost_type"] = 'name'; - - $read_limits = array('limit_cgi', 'limit_ssi', 'limit_perl', 'limit_ruby', 'limit_python', 'force_suexec', 'limit_hterror', 'limit_wildcard', 'limit_ssl'); - - - if($_SESSION["s"]["user"]["typ"] != 'admin') { - // Get the limits of the client - $client_group_id = $_SESSION["s"]["user"]["default_group"]; - $client = $app->db->queryOneRecord("SELECT limit_traffic_quota, limit_web_domain, default_webserver, parent_client_id, limit_web_quota, client." . implode(", client.", $read_limits) . " FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id"); - - if($client['limit_cgi'] != 'y') $this->dataRecord['cgi'] = '-'; - if($client['limit_ssi'] != 'y') $this->dataRecord['ssi'] = '-'; - if($client['limit_perl'] != 'y') $this->dataRecord['perl'] = '-'; - if($client['limit_ruby'] != 'y') $this->dataRecord['ruby'] = '-'; - if($client['limit_python'] != 'y') $this->dataRecord['python'] = '-'; - if($client['force_suexec'] == 'y') $this->dataRecord['suexec'] = 'y'; - if($client['limit_hterror'] != 'y') $this->dataRecord['errordocs'] = '-'; - if($client['limit_wildcard'] != 'y' && $this->dataRecord['subdomain'] == '*') $this->dataRecord['subdomain'] = '-'; - if($client['limit_ssl'] != 'y') $this->dataRecord['ssl'] = '-'; - - // only generate quota and traffic warnings if value has changed - if($this->id > 0) { - $old_web_values = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".$app->functions->intval($this->id)); - } else { - $old_web_values = $_POST; - } - - //* Check the website quota of the client - if(isset($_POST["hd_quota"]) && $client["limit_web_quota"] >= 0 && $_POST["hd_quota"] != $old_web_values["hd_quota"]) { - $tmp = $app->db->queryOneRecord("SELECT sum(hd_quota) as webquota FROM web_domain WHERE domain_id != ".$app->functions->intval($this->id)." AND type = 'vhost' AND ".$app->tform->getAuthSQL('u')); - $webquota = $tmp["webquota"]; - $new_web_quota = $app->functions->intval($this->dataRecord["hd_quota"]); - if(($webquota + $new_web_quota > $client["limit_web_quota"]) || ($new_web_quota < 0 && $client["limit_web_quota"] >= 0)) { - $max_free_quota = floor($client["limit_web_quota"] - $webquota); - if($max_free_quota < 0) $max_free_quota = 0; - $app->tform->errorMessage .= $app->tform->lng("limit_web_quota_free_txt").": ".$max_free_quota." MB<br>"; - // Set the quota field to the max free space - $this->dataRecord["hd_quota"] = $max_free_quota; - } - unset($tmp); - unset($tmp_quota); - } - - //* Check the traffic quota of the client - if(isset($_POST["traffic_quota"]) && $client["limit_traffic_quota"] > 0 && $_POST["traffic_quota"] != $old_web_values["traffic_quota"]) { - $tmp = $app->db->queryOneRecord("SELECT sum(traffic_quota) as trafficquota FROM web_domain WHERE domain_id != ".$app->functions->intval($this->id)." AND ".$app->tform->getAuthSQL('u')); - $trafficquota = $tmp["trafficquota"]; - $new_traffic_quota = $app->functions->intval($this->dataRecord["traffic_quota"]); - if(($trafficquota + $new_traffic_quota > $client["limit_traffic_quota"]) || ($new_traffic_quota < 0 && $client["limit_traffic_quota"] >= 0)) { - $max_free_quota = floor($client["limit_traffic_quota"] - $trafficquota); - if($max_free_quota < 0) $max_free_quota = 0; - $app->tform->errorMessage .= $app->tform->lng("limit_traffic_quota_free_txt").": ".$max_free_quota." MB<br>"; - // Set the quota field to the max free space - $this->dataRecord["traffic_quota"] = $max_free_quota; - } - unset($tmp); - unset($tmp_quota); - } - - if($client['parent_client_id'] > 0) { - // Get the limits of the reseller - $reseller = $app->db->queryOneRecord("SELECT limit_traffic_quota, limit_web_domain, default_webserver, limit_web_quota FROM client WHERE client_id = ".$client['parent_client_id']); - - //* Check the website quota of the client - if(isset($_POST["hd_quota"]) && $reseller["limit_web_quota"] >= 0 && $_POST["hd_quota"] != $old_web_values["hd_quota"]) { - $tmp = $app->db->queryOneRecord("SELECT sum(hd_quota) as webquota FROM web_domain WHERE domain_id != ".$app->functions->intval($this->id)." AND type = 'vhost' AND ".$app->tform->getAuthSQL('u')); - $webquota = $tmp["webquota"]; - $new_web_quota = $app->functions->intval($this->dataRecord["hd_quota"]); - if(($webquota + $new_web_quota > $reseller["limit_web_quota"]) || ($new_web_quota < 0 && $reseller["limit_web_quota"] >= 0)) { - $max_free_quota = floor($reseller["limit_web_quota"] - $webquota); - if($max_free_quota < 0) $max_free_quota = 0; - $app->tform->errorMessage .= $app->tform->lng("limit_web_quota_free_txt").": ".$max_free_quota." MB<br>"; - // Set the quota field to the max free space - $this->dataRecord["hd_quota"] = $max_free_quota; - } - unset($tmp); - unset($tmp_quota); - } - - //* Check the traffic quota of the client - if(isset($_POST["traffic_quota"]) && $reseller["limit_traffic_quota"] > 0 && $_POST["traffic_quota"] != $old_web_values["traffic_quota"]) { - $tmp = $app->db->queryOneRecord("SELECT sum(traffic_quota) as trafficquota FROM web_domain WHERE domain_id != ".$app->functions->intval($this->id)." AND ".$app->tform->getAuthSQL('u')); - $trafficquota = $tmp["trafficquota"]; - $new_traffic_quota = $app->functions->intval($this->dataRecord["traffic_quota"]); - if(($trafficquota + $new_traffic_quota > $reseller["limit_traffic_quota"]) || ($new_traffic_quota < 0 && $reseller["limit_traffic_quota"] >= 0)) { - $max_free_quota = floor($reseller["limit_traffic_quota"] - $trafficquota); - if($max_free_quota < 0) $max_free_quota = 0; - $app->tform->errorMessage .= $app->tform->lng("limit_traffic_quota_free_txt").": ".$max_free_quota." MB<br>"; - // Set the quota field to the max free space - $this->dataRecord["traffic_quota"] = $max_free_quota; - } - unset($tmp); - unset($tmp_quota); - } - } - - // When the record is updated - if($this->id > 0) { - // restore the server ID if the user is not admin and record is edited - $tmp = $app->db->queryOneRecord("SELECT server_id, `cgi`, `ssi`, `perl`, `ruby`, `python`, `suexec`, `errordocs`, `subdomain`, `ssl` FROM web_domain WHERE domain_id = ".$app->functions->intval($this->id)); - $this->dataRecord["server_id"] = $tmp["server_id"]; - - // set the settings to current if not provided (or cleared due to limits) - if($this->dataRecord['cgi'] == '-') $this->dataRecord['cgi'] = $tmp['cgi']; - if($this->dataRecord['ssi'] == '-') $this->dataRecord['ssi'] = $tmp['ssi']; - if($this->dataRecord['perl'] == '-') $this->dataRecord['perl'] = $tmp['perl']; - if($this->dataRecord['ruby'] == '-') $this->dataRecord['ruby'] = $tmp['ruby']; - if($this->dataRecord['python'] == '-') $this->dataRecord['python'] = $tmp['python']; - if($this->dataRecord['suexec'] == '-') $this->dataRecord['suexec'] = $tmp['suexec']; - if($this->dataRecord['errordocs'] == '-') $this->dataRecord['errordocs'] = $tmp['errordocs']; - if($this->dataRecord['subdomain'] == '-') $this->dataRecord['subdomain'] = $tmp['subdomain']; - if($this->dataRecord['ssl'] == '-') $this->dataRecord['ssl'] = $tmp['ssl']; - - unset($tmp); - // When the record is inserted - } else { - //* set the server ID to the default webserver of the client - $this->dataRecord["server_id"] = $client["default_webserver"]; - - // Check if the user may add another web_domain - if($client["limit_web_domain"] >= 0) { - $tmp = $app->db->queryOneRecord("SELECT count(domain_id) as number FROM web_domain WHERE sys_groupid = $client_group_id and type = 'vhost'"); - if($tmp["number"] >= $client["limit_web_domain"]) { - $app->error($app->tform->wordbook["limit_web_domain_txt"]); - } - } - - } - - // Clients may not set the client_group_id, so we unset them if user is not a admin and the client is not a reseller - if(!$app->auth->has_clients($_SESSION['s']['user']['userid'])) unset($this->dataRecord["client_group_id"]); - } - - //* make sure that the email domain is lowercase - if(isset($this->dataRecord["domain"])) $this->dataRecord["domain"] = strtolower($this->dataRecord["domain"]); - - //* get the server config for this server - $app->uses("getconf"); - if($this->id > 0){ - $web_rec = $app->tform->getDataRecord($this->id); - $server_id = $web_rec["server_id"]; - } else { - // Get the first server ID - $tmp = $app->db->queryOneRecord("SELECT server_id FROM server WHERE web_server = 1 ORDER BY server_name LIMIT 0,1"); - $server_id = intval($tmp['server_id']); - } - $web_config = $app->getconf->get_server_config($app->functions->intval(isset($this->dataRecord["server_id"]) ? $this->dataRecord["server_id"] : $server_id),'web'); - //* Check for duplicate ssl certs per IP if SNI is disabled - if(isset($this->dataRecord['ssl']) && $this->dataRecord['ssl'] == 'y' && $web_config['enable_sni'] != 'y') { - $sql = "SELECT count(domain_id) as number FROM web_domain WHERE `ssl` = 'y' AND ip_address = '".$app->db->quote($this->dataRecord['ip_address'])."' and domain_id != ".$this->id; - $tmp = $app->db->queryOneRecord($sql); - if($tmp['number'] > 0) $app->tform->errorMessage .= $app->tform->lng("error_no_sni_txt"); - } - - // Check if pm.max_children >= pm.max_spare_servers >= pm.start_servers >= pm.min_spare_servers > 0 - if(isset($this->dataRecord['pm_max_children']) && $this->dataRecord['pm'] == 'dynamic') { - if($app->functions->intval($this->dataRecord['pm_max_children'], true) >= $app->functions->intval($this->dataRecord['pm_max_spare_servers'], true) && $app->functions->intval($this->dataRecord['pm_max_spare_servers'], true) >= $app->functions->intval($this->dataRecord['pm_start_servers'], true) && $app->functions->intval($this->dataRecord['pm_start_servers'], true) >= $app->functions->intval($this->dataRecord['pm_min_spare_servers'], true) && $app->functions->intval($this->dataRecord['pm_min_spare_servers'], true) > 0){ - - } else { - $app->tform->errorMessage .= $app->tform->lng("error_php_fpm_pm_settings_txt").'<br>'; - } - } - - // Check rewrite rules - $server_type = $web_config['server_type']; - - if($server_type == 'nginx' && isset($this->dataRecord['rewrite_rules']) && trim($this->dataRecord['rewrite_rules']) != '') { - $rewrite_rules = trim($this->dataRecord['rewrite_rules']); - $rewrites_are_valid = true; - // use this counter to make sure all curly brackets are properly closed - $if_level = 0; - // Make sure we only have Unix linebreaks - $rewrite_rules = str_replace("\r\n", "\n", $rewrite_rules); - $rewrite_rules = str_replace("\r", "\n", $rewrite_rules); - $rewrite_rule_lines = explode("\n", $rewrite_rules); - if(is_array($rewrite_rule_lines) && !empty($rewrite_rule_lines)){ - foreach($rewrite_rule_lines as $rewrite_rule_line){ - // ignore comments - if(substr(ltrim($rewrite_rule_line),0,1) == '#') continue; - // empty lines - if(trim($rewrite_rule_line) == '') continue; - // rewrite - if(preg_match('@^\s*rewrite\s+(^/)?\S+(\$)?\s+\S+(\s+(last|break|redirect|permanent|))?\s*;\s*$@', $rewrite_rule_line)) continue; - // if - if(preg_match('@^\s*if\s+\(\s*\$\S+(\s+(\!?(=|~|~\*))\s+(\S+|\".+\"))?\s*\)\s*\{\s*$@', $rewrite_rule_line)){ - $if_level += 1; - continue; - } - // if - check for files, directories, etc. - if(preg_match('@^\s*if\s+\(\s*\!?-(f|d|e|x)\s+\S+\s*\)\s*\{\s*$@', $rewrite_rule_line)){ - $if_level += 1; - continue; - } - // break - if(preg_match('@^\s*break\s*;\s*$@', $rewrite_rule_line)){ - continue; - } - // return code [ text ] - if(preg_match('@^\s*return\s+\d\d\d.*;\s*$@', $rewrite_rule_line)) continue; - // return code URL - // return URL - if(preg_match('@^\s*return(\s+\d\d\d)?\s+(http|https|ftp)\://([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&%\$\-]+)*\@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|localhost|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(\:[0-9]+)*(/($|[a-zA-Z0-9\.\,\?\'\\\+&%\$#\=~_\-]+))*\s*;\s*$@', $rewrite_rule_line)) continue; - // set - if(preg_match('@^\s*set\s+\$\S+\s+\S+\s*;\s*$@', $rewrite_rule_line)) continue; - // closing curly bracket - if(trim($rewrite_rule_line) == '}'){ - $if_level -= 1; - continue; - } - $rewrites_are_valid = false; - break; - } - } - - if(!$rewrites_are_valid || $if_level != 0){ - $app->tform->errorMessage .= $app->tform->lng("invalid_rewrite_rules_txt").'<br>'; - } - } - - parent::onSubmit(); - } - - function onAfterInsert() { - global $app, $conf; - - // make sure that the record belongs to the clinet group and not the admin group when admin inserts it - // also make sure that the user can not delete domain created by a admin - if($_SESSION["s"]["user"]["typ"] == 'admin' && isset($this->dataRecord["client_group_id"])) { - $client_group_id = $app->functions->intval($this->dataRecord["client_group_id"]); - $app->db->query("UPDATE web_domain SET sys_groupid = $client_group_id, sys_perm_group = 'ru' WHERE domain_id = ".$this->id); - } - if($app->auth->has_clients($_SESSION['s']['user']['userid']) && isset($this->dataRecord["client_group_id"])) { - $client_group_id = $app->functions->intval($this->dataRecord["client_group_id"]); - $app->db->query("UPDATE web_domain SET sys_groupid = $client_group_id, sys_perm_group = 'riud' WHERE domain_id = ".$this->id); - } - - // Get configuration for the web system - $app->uses("getconf"); - $web_rec = $app->tform->getDataRecord($this->id); - $web_config = $app->getconf->get_server_config($app->functions->intval($web_rec["server_id"]),'web'); - $document_root = str_replace("[website_id]",$this->id,$web_config["website_path"]); - $document_root = str_replace("[website_idhash_1]",$this->id_hash($page_form->id,1),$document_root); - $document_root = str_replace("[website_idhash_2]",$this->id_hash($page_form->id,1),$document_root); - $document_root = str_replace("[website_idhash_3]",$this->id_hash($page_form->id,1),$document_root); - $document_root = str_replace("[website_idhash_4]",$this->id_hash($page_form->id,1),$document_root); - - // get the ID of the client - if($_SESSION["s"]["user"]["typ"] != 'admin' && !$app->auth->has_clients($_SESSION['s']['user']['userid'])) { - $client_group_id = $_SESSION["s"]["user"]["default_group"]; - $client = $app->db->queryOneRecord("SELECT client_id FROM sys_group WHERE sys_group.groupid = $client_group_id"); - $client_id = $app->functions->intval($client["client_id"]); - } else { - //$client_id = $app->functions->intval($this->dataRecord["client_group_id"]); - $client = $app->db->queryOneRecord("SELECT client_id FROM sys_group WHERE sys_group.groupid = ".$app->functions->intval($this->dataRecord["client_group_id"])); - $client_id = $app->functions->intval($client["client_id"]); - } - - // Set the values for document_root, system_user and system_group - $system_user = $app->db->quote('web'.$this->id); - $system_group = $app->db->quote('client'.$client_id); - $document_root = str_replace("[client_id]",$client_id,$document_root); - $document_root = str_replace("[client_idhash_1]",$this->id_hash($client_id,1),$document_root); - $document_root = str_replace("[client_idhash_2]",$this->id_hash($client_id,2),$document_root); - $document_root = str_replace("[client_idhash_3]",$this->id_hash($client_id,3),$document_root); - $document_root = str_replace("[client_idhash_4]",$this->id_hash($client_id,4),$document_root); - $document_root = $app->db->quote($document_root); - $php_open_basedir = str_replace("[website_path]",$document_root,$web_config["php_open_basedir"]); - $php_open_basedir = $app->db->quote(str_replace("[website_domain]",$web_rec['domain'],$php_open_basedir)); - $htaccess_allow_override = $app->db->quote($web_config["htaccess_allow_override"]); - - $sql = "UPDATE web_domain SET system_user = '$system_user', system_group = '$system_group', document_root = '$document_root', allow_override = '$htaccess_allow_override', php_open_basedir = '$php_open_basedir' WHERE domain_id = ".$this->id; - $app->db->query($sql); - } - - function onBeforeUpdate () { - global $app, $conf; - - //* Check if the server has been changed - // We do this only for the admin or reseller users, as normal clients can not change the server ID anyway - if($_SESSION["s"]["user"]["typ"] == 'admin' || $app->auth->has_clients($_SESSION['s']['user']['userid'])) { - if (isset($this->dataRecord["server_id"])) { - $rec = $app->db->queryOneRecord("SELECT server_id from web_domain WHERE domain_id = ".$this->id); - if($rec['server_id'] != $this->dataRecord["server_id"]) { - //* Add a error message and switch back to old server - $app->tform->errorMessage .= $app->lng('The Server can not be changed.'); - $this->dataRecord["server_id"] = $rec['server_id']; - } - unset($rec); - } - //* If the user is neither admin nor reseller - } else { - //* We do not allow users to change a domain which has been created by the admin - $rec = $app->db->queryOneRecord("SELECT sys_perm_group, domain, ip_address, ipv6_address from web_domain WHERE domain_id = ".$this->id); - if(isset($this->dataRecord["domain"]) && $rec['domain'] != $this->dataRecord["domain"] && $app->tform->checkPerm($this->id,'u')) { - //* Add a error message and switch back to old server - $app->tform->errorMessage .= $app->lng('The Domain can not be changed. Please ask your Administrator if you want to change the domain name.'); - $this->dataRecord["domain"] = $rec['domain']; - } - if(isset($this->dataRecord["ip_address"]) && $rec['ip_address'] != $this->dataRecord["ip_address"] && $rec['sys_perm_group'] != 'riud') { - $this->dataRecord["ip_address"] = $rec['ip_address']; - } - if(isset($this->dataRecord["ipv6_address"]) && $rec['ipv6_address'] != $this->dataRecord["ipv6_address"] && $rec['sys_perm_group'] != 'riud') { - $this->dataRecord["ipv6_address"] = $rec['ipv6_address']; - } - unset($rec); - } - - //* Check that all fields for the SSL cert creation are filled - if(isset($this->dataRecord['ssl_action']) && $this->dataRecord['ssl_action'] == 'create') { - if($this->dataRecord['ssl_state'] == '') $app->tform->errorMessage .= $app->tform->lng('error_ssl_state_empty').'<br />'; - if($this->dataRecord['ssl_locality'] == '') $app->tform->errorMessage .= $app->tform->lng('error_ssl_locality_empty').'<br />'; - if($this->dataRecord['ssl_organisation'] == '') $app->tform->errorMessage .= $app->tform->lng('error_ssl_organisation_empty').'<br />'; - if($this->dataRecord['ssl_organisation_unit'] == '') $app->tform->errorMessage .= $app->tform->lng('error_ssl_organisation_unit_empty').'<br />'; - if($this->dataRecord['ssl_country'] == '') $app->tform->errorMessage .= $app->tform->lng('error_ssl_country_empty').'<br />'; - } - - if(isset($this->dataRecord['ssl_action']) && $this->dataRecord['ssl_action'] == 'save') { - if(trim($this->dataRecord['ssl_cert']) == '') $app->tform->errorMessage .= $app->tform->lng('error_ssl_cert_empty').'<br />'; - } - - } - - function onAfterUpdate() { - global $app, $conf; - - // make sure that the record belongs to the client group and not the admin group when a admin inserts it - // also make sure that the user can not delete domain created by a admin - if($_SESSION["s"]["user"]["typ"] == 'admin' && isset($this->dataRecord["client_group_id"])) { - $client_group_id = $app->functions->intval($this->dataRecord["client_group_id"]); - $app->db->query("UPDATE web_domain SET sys_groupid = $client_group_id, sys_perm_group = 'ru' WHERE domain_id = ".$this->id); - } - if($app->auth->has_clients($_SESSION['s']['user']['userid']) && isset($this->dataRecord["client_group_id"])) { - $client_group_id = $app->functions->intval($this->dataRecord["client_group_id"]); - $app->db->query("UPDATE web_domain SET sys_groupid = $client_group_id, sys_perm_group = 'riud' WHERE domain_id = ".$this->id); - } - - // Get configuration for the web system - $app->uses("getconf"); - $web_rec = $app->tform->getDataRecord($this->id); - $web_config = $app->getconf->get_server_config($app->functions->intval($web_rec["server_id"]),'web'); - $document_root = str_replace("[website_id]",$this->id,$web_config["website_path"]); - $page_formid = isset($page_form->id) ? $page_form->id : ''; - $document_root = str_replace("[website_idhash_1]",$this->id_hash($page_formid,1),$document_root); - $document_root = str_replace("[website_idhash_2]",$this->id_hash($page_formid,1),$document_root); - $document_root = str_replace("[website_idhash_3]",$this->id_hash($page_formid,1),$document_root); - $document_root = str_replace("[website_idhash_4]",$this->id_hash($page_formid,1),$document_root); - - // get the ID of the client - if($_SESSION["s"]["user"]["typ"] != 'admin' && !$app->auth->has_clients($_SESSION['s']['user']['userid'])) { - $client_group_id = $_SESSION["s"]["user"]["default_group"]; - $client = $app->db->queryOneRecord("SELECT client_id FROM sys_group WHERE sys_group.groupid = $client_group_id"); - $client_id = $app->functions->intval($client["client_id"]); - } elseif (isset($this->dataRecord["client_group_id"])) { - $client_group_id = $this->dataRecord["client_group_id"]; - $client = $app->db->queryOneRecord("SELECT client_id FROM sys_group WHERE sys_group.groupid = ".$app->functions->intval(@$this->dataRecord["client_group_id"])); - $client_id = $app->functions->intval($client["client_id"]); - } else { - $client_group_id = $web_rec['sys_groupid']; - $client = $app->db->queryOneRecord("SELECT client_id FROM sys_group WHERE sys_group.groupid = ".$app->functions->intval($client_group_id)); - $client_id = $app->functions->intval($client["client_id"]); - } - - if(($_SESSION["s"]["user"]["typ"] == 'admin' || $app->auth->has_clients($_SESSION['s']['user']['userid'])) && isset($this->dataRecord["client_group_id"]) && $this->dataRecord["client_group_id"] != $this->oldDataRecord["sys_groupid"]) { - // Set the values for document_root, system_user and system_group - $system_user = $app->db->quote('web'.$this->id); - $system_group = $app->db->quote('client'.$client_id); - $document_root = str_replace("[client_id]",$client_id,$document_root); - $document_root = str_replace("[client_idhash_1]",$this->id_hash($client_id,1),$document_root); - $document_root = str_replace("[client_idhash_2]",$this->id_hash($client_id,2),$document_root); - $document_root = str_replace("[client_idhash_3]",$this->id_hash($client_id,3),$document_root); - $document_root = str_replace("[client_idhash_4]",$this->id_hash($client_id,4),$document_root); - $document_root = $app->db->quote($document_root); - - $sql = "UPDATE web_domain SET system_user = '$system_user', system_group = '$system_group', document_root = '$document_root' WHERE domain_id = ".$this->id; - //$sql = "UPDATE web_domain SET system_user = '$system_user', system_group = '$system_group' WHERE domain_id = ".$this->id; - $app->db->query($sql); - - // Update the FTP user(s) too - $records = $app->db->queryAllRecords("SELECT ftp_user_id FROM ftp_user WHERE parent_domain_id = ".$this->id); - foreach($records as $rec) { - $app->db->datalogUpdate('ftp_user', "sys_userid = '".$web_rec['sys_userid']."', sys_groupid = '".$web_rec['sys_groupid']."', uid = '$system_user', gid = '$system_group', dir = '$document_root'", 'ftp_user_id', $rec['ftp_user_id']); - } - unset($records); - unset($rec); - - // Update the Shell user(s) too - $records = $app->db->queryAllRecords("SELECT shell_user_id FROM shell_user WHERE parent_domain_id = ".$this->id); - foreach($records as $rec) { - $app->db->datalogUpdate('shell_user', "sys_userid = '".$web_rec['sys_userid']."', sys_groupid = '".$web_rec['sys_groupid']."', puser = '$system_user', pgroup = '$system_group', dir = '$document_root'", 'shell_user_id', $rec['shell_user_id']); - } - unset($records); - unset($rec); - - //* Update all subdomains and alias domains - $records = $app->db->queryAllRecords("SELECT domain_id, `domain`, `type`, `web_folder` FROM web_domain WHERE parent_domain_id = ".$this->id); - foreach($records as $rec) { - $update_columns = "sys_userid = '".$web_rec['sys_userid']."', sys_groupid = '".$web_rec['sys_groupid']."'"; - if($rec['type'] == 'vhostsubdomain') { - $php_open_basedir = str_replace("[website_path]/web",$document_root.'/'.$rec['web_folder'],$web_config["php_open_basedir"]); - $php_open_basedir = str_replace("[website_domain]/web",$rec['domain'].'/'.$rec['web_folder'],$php_open_basedir); - $php_open_basedir = str_replace("[website_path]",$document_root,$php_open_basedir); - $php_open_basedir = $app->db->quote(str_replace("[website_domain]",$rec['domain'],$php_open_basedir)); - - $update_columns .= ", document_root = '".$document_root."', `php_open_basedir` = '".$php_open_basedir."'"; - } - $app->db->datalogUpdate('web_domain', $update_columns, 'domain_id', $rec['domain_id']); - } - unset($records); - unset($rec); - - //* Update all databases - $records = $app->db->queryAllRecords("SELECT database_id FROM web_database WHERE parent_domain_id = ".$this->id); - foreach($records as $rec) { - $app->db->datalogUpdate('web_database', "sys_userid = '".$web_rec['sys_userid']."', sys_groupid = '".$web_rec['sys_groupid']."'", 'database_id', $rec['database_id']); - } - unset($records); - unset($rec); - - } - - //* If the domain name has been changed, we will have to change all subdomains + APS instances - if(!empty($this->dataRecord["domain"]) && !empty($this->oldDataRecord["domain"]) && $this->dataRecord["domain"] != $this->oldDataRecord["domain"]) { - $records = $app->db->queryAllRecords("SELECT domain_id,domain FROM web_domain WHERE (type = 'subdomain' OR type = 'vhostsubdomain') AND domain LIKE '%.".$app->db->quote($this->oldDataRecord["domain"])."'"); - foreach($records as $rec) { - $subdomain = $app->db->quote(str_replace($this->oldDataRecord["domain"],$this->dataRecord["domain"],$rec['domain'])); - $app->db->datalogUpdate('web_domain', "domain = '".$subdomain."'", 'domain_id', $rec['domain_id']); - } - unset($records); - unset($rec); - unset($subdomain); - - // Update APS instances - $records = $app->db->queryAllRecords("SELECT id, instance_id FROM aps_instances_settings WHERE name = 'main_domain' AND value = '".$this->oldDataRecord["domain"]."'"); - if(is_array($records) && !empty($records)){ - foreach($records as $rec){ - $app->db->datalogUpdate('aps_instances_settings', "value = '".$this->dataRecord["domain"]."'", 'id', $rec['id']); - // Reinstall of package needed? - //$app->db->datalogUpdate('aps_instances', "instance_status = '1'", 'id', $rec['instance_id']); - } - } - unset($records); - unset($rec); - } - - //* Set allow_override if empty - if($web_rec['allow_override'] == '') { - $sql = "UPDATE web_domain SET allow_override = '".$app->db->quote($web_config["htaccess_allow_override"])."' WHERE domain_id = ".$this->id; - $app->db->query($sql); - } - - //* Set php_open_basedir if empty or domain or client has been changed - if(empty($web_rec['php_open_basedir']) || - (!empty($this->dataRecord["domain"]) && !empty($this->oldDataRecord["domain"]) && $this->dataRecord["domain"] != $this->oldDataRecord["domain"])) { - $php_open_basedir = $web_rec['php_open_basedir']; - $php_open_basedir = str_replace($this->oldDataRecord['domain'],$web_rec['domain'],$php_open_basedir); - $sql = "UPDATE web_domain SET php_open_basedir = '$php_open_basedir' WHERE domain_id = ".$this->id; - $app->db->query($sql); - } - if(empty($web_rec['php_open_basedir']) || - (isset($this->dataRecord["client_group_id"]) && $this->dataRecord["client_group_id"] != $this->oldDataRecord["sys_groupid"])) { - $document_root = $app->db->quote(str_replace("[client_id]",$client_id,$document_root)); - $php_open_basedir = str_replace("[website_path]",$document_root,$web_config["php_open_basedir"]); - $php_open_basedir = $app->db->quote(str_replace("[website_domain]",$web_rec['domain'],$php_open_basedir)); - $sql = "UPDATE web_domain SET php_open_basedir = '$php_open_basedir' WHERE domain_id = ".$this->id; - $app->db->query($sql); - } - - //* Change database backup options when web backup options have been changed - if(isset($this->dataRecord['backup_interval']) && ($this->dataRecord['backup_interval'] != $this->oldDataRecord['backup_interval'] || $this->dataRecord['backup_copies'] != $this->oldDataRecord['backup_copies'])) { - //* Update all databases - $backup_interval = $this->dataRecord['backup_interval']; - $backup_copies = $this->dataRecord['backup_copies']; - $records = $app->db->queryAllRecords("SELECT database_id FROM web_database WHERE parent_domain_id = ".$this->id); - foreach($records as $rec) { - $app->db->datalogUpdate('web_database', "backup_interval = '$backup_interval', backup_copies = '$backup_copies'", 'database_id', $rec['database_id']); - } - unset($records); - unset($rec); - unset($backup_copies); - unset($backup_interval); - } - - //* Change vhost subdomain ip/ipv6 if domain ip/ipv6 has changed - if(isset($this->dataRecord['ip_address']) && ($this->dataRecord['ip_address'] != $this->oldDataRecord['ip_address'] || $this->dataRecord['ipv6_address'] != $this->oldDataRecord['ipv6_address'])) { - $records = $app->db->queryAllRecords("SELECT domain_id FROM web_domain WHERE type = 'vhostsubdomain' AND parent_domain_id = ".$this->id); - foreach($records as $rec) { - $app->db->datalogUpdate('web_domain', "ip_address = '".$web_rec['ip_address']."', ipv6_address = '".$web_rec['ipv6_address']."'", 'domain_id', $rec['domain_id']); - } - unset($records); - unset($rec); - } - } - - function onAfterDelete() { - global $app, $conf; - - // Delete the sub and alias domains - $child_domains = $app->db->queryAllRecords("SELECT * FROM web_domain WHERE parent_domain_id = ".$this->id); - foreach($child_domains as $d) { - // Saving record to datalog when db_history enabled - if($app->tform->formDef["db_history"] == 'yes') { - $app->tform->datalogSave('DELETE',$d["domain_id"],$d,array()); - } - - $app->db->query("DELETE FROM web_domain WHERE domain_id = ".$d["domain_id"]." LIMIT 0,1"); - } - unset($child_domains); - unset($d); - - } - -} - -$page = new page_action; -$page->onLoad(); - +<?php +/* +Copyright (c) 2007 - 2009, Till Brehm, projektfarm Gmbh +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of ISPConfig nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +/****************************************** +* Begin Form configuration +******************************************/ + +$tform_def_file = "form/web_domain.tform.php"; + +/****************************************** +* End Form configuration +******************************************/ + +require_once('../../lib/config.inc.php'); +require_once('../../lib/app.inc.php'); + +//* Check permissions for module +$app->auth->check_module_permissions('sites'); + +// Loading classes +$app->uses('tpl,tform,tform_actions,tools_sites'); +$app->load('tform_actions'); + +class page_action extends tform_actions { + + //* Returna a "3/2/1" path hash from a numeric id '123' + function id_hash($id,$levels) { + $hash = "" . $id % 10 ; + $id /= 10 ; + $levels -- ; + while ( $levels > 0 ) { + $hash .= "/" . $id % 10 ; + $id /= 10 ; + $levels-- ; + } + return $hash; + } + + function onShowNew() { + global $app, $conf; + + // we will check only users, not admins + if($_SESSION["s"]["user"]["typ"] == 'user') { + if(!$app->tform->checkClientLimit('limit_web_domain',"type = 'vhost'")) { + $app->error($app->tform->wordbook["limit_web_domain_txt"]); + } + if(!$app->tform->checkResellerLimit('limit_web_domain',"type = 'vhost'")) { + $app->error('Reseller: '.$app->tform->wordbook["limit_web_domain_txt"]); + } + + // Get the limits of the client + $client_group_id = $_SESSION["s"]["user"]["default_group"]; + $client = $app->db->queryOneRecord("SELECT client.default_webserver FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id"); + $app->tpl->setVar("server_id_value", $client['default_webserver']); + } + $app->tform->formDef['tabs']['domain']['readonly'] = false; + + parent::onShowNew(); + } + + function onShowEnd() { + global $app, $conf; + + $app->uses('ini_parser,getconf'); + + $read_limits = array('limit_cgi', 'limit_ssi', 'limit_perl', 'limit_ruby', 'limit_python', 'force_suexec', 'limit_hterror', 'limit_wildcard', 'limit_ssl'); + + //* Client: If the logged in user is not admin and has no sub clients (no reseller) + if($_SESSION["s"]["user"]["typ"] != 'admin' && !$app->auth->has_clients($_SESSION['s']['user']['userid'])) { + + // Get the limits of the client + $client_group_id = $_SESSION["s"]["user"]["default_group"]; + $client = $app->db->queryOneRecord("SELECT client.limit_web_domain, client.default_webserver, client." . implode(", client.", $read_limits) . " FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id"); + + //* Get global web config + $web_config = $app->getconf->get_server_config($client['default_webserver'], 'web'); + + // Set the webserver to the default server of the client + $tmp = $app->db->queryOneRecord("SELECT server_name FROM server WHERE server_id = ".intval($client['default_webserver'])); + $app->tpl->setVar("server_id","<option value='$client[default_webserver]'>$tmp[server_name]</option>"); + unset($tmp); + + //* Fill the IPv4 select field with the IP addresses that are allowed for this client + $sql = "SELECT ip_address FROM server_ip WHERE server_id = ".$client['default_webserver']." AND ip_type = 'IPv4' AND (client_id = 0 OR client_id=".$_SESSION['s']['user']['client_id'].")"; + $ips = $app->db->queryAllRecords($sql); + $ip_select = ($web_config['enable_ip_wildcard'] == 'y')?"<option value='*'>*</option>":""; + //$ip_select = ""; + if(is_array($ips)) { + foreach( $ips as $ip) { + $selected = ($ip["ip_address"] == $this->dataRecord["ip_address"])?'SELECTED':''; + $ip_select .= "<option value='$ip[ip_address]' $selected>$ip[ip_address]</option>\r\n"; + } + } + $app->tpl->setVar("ip_address",$ip_select); + unset($tmp); + unset($ips); + + //* Fill the IPv6 select field with the IP addresses that are allowed for this client + $sql = "SELECT ip_address FROM server_ip WHERE server_id = ".intval($client['default_webserver'])." AND ip_type = 'IPv6' AND (client_id = 0 OR client_id=".$_SESSION['s']['user']['client_id'].")"; + $ips = $app->db->queryAllRecords($sql); + $ip_select = "<option value=''></option>"; + //$ip_select = ""; + if(is_array($ips)) { + foreach( $ips as $ip) { + $selected = ($ip["ip_address"] == $this->dataRecord["ipv6_address"])?'SELECTED':''; + $ip_select .= "<option value='$ip[ip_address]' $selected>$ip[ip_address]</option>\r\n"; + } + } + $app->tpl->setVar("ipv6_address",$ip_select); + unset($tmp); + unset($ips); + + //PHP Version Selection (FastCGI) + $server_type = 'apache'; + if(!empty($web_config['server_type'])) $server_type = $web_config['server_type']; + if($server_type == 'nginx' && $this->dataRecord['php'] == 'fast-cgi') $this->dataRecord['php'] = 'php-fpm'; + if($this->dataRecord['php'] == 'php-fpm'){ + $php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fpm_init_script != '' AND php_fpm_ini_dir != '' AND php_fpm_pool_dir != '' AND server_id = ".($this->id > 0 ? $this->dataRecord['server_id'] : intval($client['default_webserver']))." AND (client_id = 0 OR client_id=".$_SESSION['s']['user']['client_id'].")"); + } + if($this->dataRecord['php'] == 'fast-cgi'){ + $php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fastcgi_binary != '' AND php_fastcgi_ini_dir != '' AND server_id = ".($this->id > 0 ? $this->dataRecord['server_id'] : intval($client['default_webserver']))." AND (client_id = 0 OR client_id=".$_SESSION['s']['user']['client_id'].")"); + } + $php_select = "<option value=''>Default</option>"; + if(is_array($php_records) && !empty($php_records)) { + foreach( $php_records as $php_record) { + if($this->dataRecord['php'] == 'php-fpm'){ + $php_version = $php_record['name'].':'.$php_record['php_fpm_init_script'].':'.$php_record['php_fpm_ini_dir'].':'.$php_record['php_fpm_pool_dir']; + } else { + $php_version = $php_record['name'].':'.$php_record['php_fastcgi_binary'].':'.$php_record['php_fastcgi_ini_dir']; + } + $selected = ($php_version == $this->dataRecord["fastcgi_php_version"])?'SELECTED':''; + $php_select .= "<option value='$php_version' $selected>".$php_record['name']."</option>\r\n"; + } + } + $app->tpl->setVar("fastcgi_php_version",$php_select); + unset($php_records); + + // add limits to template to be able to hide settings + foreach($read_limits as $limit) $app->tpl->setVar($limit, $client[$limit]); + + + //* Reseller: If the logged in user is not admin and has sub clients (is a reseller) + } elseif ($_SESSION["s"]["user"]["typ"] != 'admin' && $app->auth->has_clients($_SESSION['s']['user']['userid'])) { + + // Get the limits of the client + $client_group_id = $_SESSION["s"]["user"]["default_group"]; + $client = $app->db->queryOneRecord("SELECT client.client_id, client.limit_web_domain, client.default_webserver, client.contact_name, CONCAT(IF(client.company_name != '', CONCAT(client.company_name, ' :: '), ''), client.contact_name, ' (', client.username, IF(client.customer_no != '', CONCAT(', ', client.customer_no), ''), ')') as contactname, sys_group.name, client." . implode(", client.", $read_limits) . " FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id"); + + //* Get global web config + $web_config = $app->getconf->get_server_config($client['default_webserver'], 'web'); + + // Set the webserver to the default server of the client + $tmp = $app->db->queryOneRecord("SELECT server_name FROM server WHERE server_id = ".intval($client['default_webserver'])); + $app->tpl->setVar("server_id","<option value='$client[default_webserver]'>$tmp[server_name]</option>"); + unset($tmp); + + // Fill the client select field + $sql = "SELECT sys_group.groupid, sys_group.name, CONCAT(IF(client.company_name != '', CONCAT(client.company_name, ' :: '), ''), client.contact_name, ' (', client.username, IF(client.customer_no != '', CONCAT(', ', client.customer_no), ''), ')') as contactname FROM sys_group, client WHERE sys_group.client_id = client.client_id AND client.parent_client_id = ".$client['client_id']." ORDER BY sys_group.name"; + $records = $app->db->queryAllRecords($sql); + $tmp = $app->db->queryOneRecord("SELECT groupid FROM sys_group WHERE client_id = ".$client['client_id']); + $client_select = '<option value="'.$tmp['groupid'].'">'.$client['contactname'].'</option>'; + //$tmp_data_record = $app->tform->getDataRecord($this->id); + if(is_array($records)) { + $selected_client_group_id = 0; // needed to get list of PHP versions + foreach( $records as $rec) { + if(is_array($this->dataRecord) && ($rec["groupid"] == $this->dataRecord['client_group_id'] || $rec["groupid"] == $this->dataRecord['sys_groupid']) && !$selected_client_group_id) $selected_client_group_id = $rec["groupid"]; + $selected = @(is_array($this->dataRecord) && ($rec["groupid"] == $this->dataRecord['client_group_id'] || $rec["groupid"] == $this->dataRecord['sys_groupid']))?'SELECTED':''; + if($selected == 'SELECTED') $selected_client_group_id = $rec["groupid"]; + $client_select .= "<option value='$rec[groupid]' $selected>$rec[contactname]</option>\r\n"; + } + } + $app->tpl->setVar("client_group_id",$client_select); + + //* Fill the IPv4 select field with the IP addresses that are allowed for this client + $sql = "SELECT ip_address FROM server_ip WHERE server_id = ".intval($client['default_webserver'])." AND ip_type = 'IPv4' AND (client_id = 0 OR client_id=".$_SESSION['s']['user']['client_id'].")"; + $ips = $app->db->queryAllRecords($sql); + $ip_select = ($web_config['enable_ip_wildcard'] == 'y')?"<option value='*'>*</option>":""; + //$ip_select = ""; + if(is_array($ips)) { + foreach( $ips as $ip) { + $selected = ($ip["ip_address"] == $this->dataRecord["ip_address"])?'SELECTED':''; + $ip_select .= "<option value='$ip[ip_address]' $selected>$ip[ip_address]</option>\r\n"; + } + } + $app->tpl->setVar("ip_address",$ip_select); + unset($tmp); + unset($ips); + + //* Fill the IPv6 select field with the IP addresses that are allowed for this client + $sql = "SELECT ip_address FROM server_ip WHERE server_id = ".intval($client['default_webserver'])." AND ip_type = 'IPv6' AND (client_id = 0 OR client_id=".$_SESSION['s']['user']['client_id'].")"; + $ips = $app->db->queryAllRecords($sql); + $ip_select = "<option value=''></option>"; + //$ip_select = ""; + if(is_array($ips)) { + foreach( $ips as $ip) { + $selected = ($ip["ip_address"] == $this->dataRecord["ipv6_address"])?'SELECTED':''; + $ip_select .= "<option value='$ip[ip_address]' $selected>$ip[ip_address]</option>\r\n"; + } + } + $app->tpl->setVar("ipv6_address",$ip_select); + unset($tmp); + unset($ips); + + //PHP Version Selection (FastCGI) + $server_type = 'apache'; + if(!empty($web_config['server_type'])) $server_type = $web_config['server_type']; + if($server_type == 'nginx' && $this->dataRecord['php'] == 'fast-cgi') $this->dataRecord['php'] = 'php-fpm'; + $selected_client = $app->db->queryOneRecord("SELECT client_id FROM sys_group WHERE groupid = $selected_client_group_id"); + //$sql_where = " AND (client_id = 0 OR client_id=".$_SESSION['s']['user']['client_id']." OR client_id = ".intval($selected_client['client_id']).")"; + $sql_where = " AND (client_id = 0 OR client_id = ".intval($selected_client['client_id']).")"; + if($this->dataRecord['php'] == 'php-fpm'){ + $php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fpm_init_script != '' AND php_fpm_ini_dir != '' AND php_fpm_pool_dir != '' AND server_id = ".($this->id > 0 ? $this->dataRecord['server_id'] : intval($client['default_webserver'])).$sql_where); + } + if($this->dataRecord['php'] == 'fast-cgi') { + $php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fastcgi_binary != '' AND php_fastcgi_ini_dir != '' AND server_id = ".($this->id > 0 ? $this->dataRecord['server_id'] : intval($client['default_webserver'])).$sql_where); + } + $php_select = "<option value=''>Default</option>"; + if(is_array($php_records) && !empty($php_records)) { + foreach( $php_records as $php_record) { + if($this->dataRecord['php'] == 'php-fpm'){ + $php_version = $php_record['name'].':'.$php_record['php_fpm_init_script'].':'.$php_record['php_fpm_ini_dir'].':'.$php_record['php_fpm_pool_dir']; + } else { + $php_version = $php_record['name'].':'.$php_record['php_fastcgi_binary'].':'.$php_record['php_fastcgi_ini_dir']; + } + $selected = ($php_version == $this->dataRecord["fastcgi_php_version"])?'SELECTED':''; + $php_select .= "<option value='$php_version' $selected>".$php_record['name']."</option>\r\n"; + } + } + $app->tpl->setVar("fastcgi_php_version",$php_select); + unset($php_records); + + // add limits to template to be able to hide settings + foreach($read_limits as $limit) $app->tpl->setVar($limit, $client[$limit]); + + + //* Admin: If the logged in user is admin + } else { + + // The user is admin, so we fill in all IP addresses of the server + if($this->id > 0) { + if(!isset($this->dataRecord["server_id"])){ + $tmp = $app->db->queryOneRecord("SELECT server_id FROM web_domain WHERE domain_id = ".$app->functions->intval($this->id)); + $this->dataRecord["server_id"] = $tmp["server_id"]; + unset($tmp); + } + $server_id = intval(@$this->dataRecord["server_id"]); + } else { + // Get the first server ID + $tmp = $app->db->queryOneRecord("SELECT server_id FROM server WHERE web_server = 1 ORDER BY server_name LIMIT 0,1"); + $server_id = intval($tmp['server_id']); + } + + //* get global web config + $web_config = $app->getconf->get_server_config($server_id, 'web'); + + //* Fill the IPv4 select field + $sql = "SELECT ip_address FROM server_ip WHERE ip_type = 'IPv4' AND server_id = $server_id"; + $ips = $app->db->queryAllRecords($sql); + $ip_select = ($web_config['enable_ip_wildcard'] == 'y')?"<option value='*'>*</option>":""; + //$ip_select = ""; + if(is_array($ips)) { + foreach( $ips as $ip) { + $selected = ($ip["ip_address"] == $this->dataRecord["ip_address"])?'SELECTED':''; + $ip_select .= "<option value='$ip[ip_address]' $selected>$ip[ip_address]</option>\r\n"; + } + } + $app->tpl->setVar("ip_address",$ip_select); + unset($tmp); + unset($ips); + + //* Fill the IPv6 select field + $sql = "SELECT ip_address FROM server_ip WHERE ip_type = 'IPv6' AND server_id = $server_id"; + $ips = $app->db->queryAllRecords($sql); + $ip_select = "<option value=''></option>"; + //$ip_select = ""; + if(is_array($ips)) { + foreach( $ips as $ip) { + $selected = ($ip["ip_address"] == $this->dataRecord["ipv6_address"])?'SELECTED':''; + $ip_select .= "<option value='$ip[ip_address]' $selected>$ip[ip_address]</option>\r\n"; + } + } + $app->tpl->setVar("ipv6_address",$ip_select); + unset($tmp); + unset($ips); + + // Fill the client select field + $sql = "SELECT sys_group.groupid, sys_group.name, CONCAT(IF(client.company_name != '', CONCAT(client.company_name, ' :: '), ''), client.contact_name, ' (', client.username, IF(client.customer_no != '', CONCAT(', ', client.customer_no), ''), ')') as contactname FROM sys_group, client WHERE sys_group.client_id = client.client_id AND sys_group.client_id > 0 ORDER BY sys_group.name"; + $clients = $app->db->queryAllRecords($sql); + $client_select = "<option value='0'></option>"; + //$tmp_data_record = $app->tform->getDataRecord($this->id); + if(is_array($clients)) { + $selected_client_group_id = 0; // needed to get list of PHP versions + foreach($clients as $client) { + if(is_array($this->dataRecord) && ($client["groupid"] == $this->dataRecord['client_group_id'] || $client["groupid"] == $this->dataRecord['sys_groupid']) && !$selected_client_group_id) $selected_client_group_id = $client["groupid"]; + //$selected = @($client["groupid"] == $tmp_data_record["sys_groupid"])?'SELECTED':''; + $selected = @(is_array($this->dataRecord) && ($client["groupid"] == $this->dataRecord['client_group_id'] || $client["groupid"] == $this->dataRecord['sys_groupid']))?'SELECTED':''; + if($selected == 'SELECTED') $selected_client_group_id = $client["groupid"]; + $client_select .= "<option value='$client[groupid]' $selected>$client[contactname]</option>\r\n"; + } + } + $app->tpl->setVar("client_group_id",$client_select); + + //PHP Version Selection (FastCGI) + $server_type = 'apache'; + if(!empty($web_config['server_type'])) $server_type = $web_config['server_type']; + if($server_type == 'nginx' && $this->dataRecord['php'] == 'fast-cgi') $this->dataRecord['php'] = 'php-fpm'; + $selected_client = $app->db->queryOneRecord("SELECT client_id FROM sys_group WHERE groupid = $selected_client_group_id"); + //$sql_where = " AND (client_id = 0 OR client_id=".$_SESSION['s']['user']['client_id']." OR client_id = ".intval($selected_client['client_id']).")"; + $sql_where = " AND (client_id = 0 OR client_id = ".intval($selected_client['client_id']).")"; + if($this->dataRecord['php'] == 'php-fpm'){ + $php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fpm_init_script != '' AND php_fpm_ini_dir != '' AND php_fpm_pool_dir != '' AND server_id = $server_id".$sql_where); + } + if($this->dataRecord['php'] == 'fast-cgi') { + $php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fastcgi_binary != '' AND php_fastcgi_ini_dir != '' AND server_id = $server_id".$sql_where); + } + $php_select = "<option value=''>Default</option>"; + if(is_array($php_records) && !empty($php_records)) { + foreach( $php_records as $php_record) { + if($this->dataRecord['php'] == 'php-fpm'){ + $php_version = $php_record['name'].':'.$php_record['php_fpm_init_script'].':'.$php_record['php_fpm_ini_dir'].':'.$php_record['php_fpm_pool_dir']; + } else { + $php_version = $php_record['name'].':'.$php_record['php_fastcgi_binary'].':'.$php_record['php_fastcgi_ini_dir']; + } + $selected = ($php_version == $this->dataRecord["fastcgi_php_version"])?'SELECTED':''; + $php_select .= "<option value='$php_version' $selected>".$php_record['name']."</option>\r\n"; + } + } + $app->tpl->setVar("fastcgi_php_version",$php_select); + unset($php_records); + + foreach($read_limits as $limit) $app->tpl->setVar($limit, ($limit == 'force_suexec' ? 'n' : 'y')); + + // Directive Snippets + $php_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'php' AND active = 'y'"); + $php_directive_snippets_txt = ''; + if(is_array($php_directive_snippets) && !empty($php_directive_snippets)){ + foreach($php_directive_snippets as $php_directive_snippet){ + $php_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$php_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.htmlentities($php_directive_snippet['snippet']).'</pre></a> '; + } + } + if($php_directive_snippets_txt == '') $php_directive_snippets_txt = '------'; + $app->tpl->setVar("php_directive_snippets_txt",$php_directive_snippets_txt); + + if($server_type == 'apache'){ + $apache_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'apache' AND active = 'y'"); + $apache_directive_snippets_txt = ''; + if(is_array($apache_directive_snippets) && !empty($apache_directive_snippets)){ + foreach($apache_directive_snippets as $apache_directive_snippet){ + $apache_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$apache_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.htmlentities($apache_directive_snippet['snippet']).'</pre></a> '; + } + } + if($apache_directive_snippets_txt == '') $apache_directive_snippets_txt = '------'; + $app->tpl->setVar("apache_directive_snippets_txt",$apache_directive_snippets_txt); + } + + if($server_type == 'nginx'){ + $nginx_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'nginx' AND active = 'y'"); + $nginx_directive_snippets_txt = ''; + if(is_array($nginx_directive_snippets) && !empty($nginx_directive_snippets)){ + foreach($nginx_directive_snippets as $nginx_directive_snippet){ + $nginx_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$nginx_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.htmlentities($nginx_directive_snippet['snippet']).'</pre></a> '; + } + } + if($nginx_directive_snippets_txt == '') $nginx_directive_snippets_txt = '------'; + $app->tpl->setVar("nginx_directive_snippets_txt",$nginx_directive_snippets_txt); + } + + $proxy_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'proxy' AND active = 'y'"); + $proxy_directive_snippets_txt = ''; + if(is_array($proxy_directive_snippets) && !empty($proxy_directive_snippets)){ + foreach($proxy_directive_snippets as $proxy_directive_snippet){ + $proxy_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$proxy_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.htmlentities($proxy_directive_snippet['snippet']).'</pre></a> '; + } + } + if($proxy_directive_snippets_txt == '') $proxy_directive_snippets_txt = '------'; + $app->tpl->setVar("proxy_directive_snippets_txt",$proxy_directive_snippets_txt); + } + + $ssl_domain_select = ''; + $tmp = $app->db->queryOneRecord("SELECT domain FROM web_domain WHERE domain_id = ".$this->id); + $ssl_domains = array($tmp["domain"],'www.'.$tmp["domain"],'*.'.$tmp["domain"]); + if(is_array($ssl_domains)) { + foreach( $ssl_domains as $ssl_domain) { + $selected = ($ssl_domain == $this->dataRecord['ssl_domain'])?'SELECTED':''; + $ssl_domain_select .= "<option value='$ssl_domain' $selected>$ssl_domain</option>\r\n"; + } + } + $app->tpl->setVar("ssl_domain",$ssl_domain_select); + unset($ssl_domain_select); + unset($ssl_domains); + unset($ssl_domain); + + if($this->id > 0) { + //* we are editing a existing record + $app->tpl->setVar("edit_disabled", 1); + $app->tpl->setVar("server_id_value", $this->dataRecord["server_id"]); + } else { + $app->tpl->setVar("edit_disabled", 0); + } + + $tmp_txt = ($this->dataRecord['traffic_quota_lock'] == 'y')?'<b>('.$app->tform->lng('traffic_quota_exceeded_txt').')</b>':''; + $app->tpl->setVar("traffic_quota_exceeded_txt", $tmp_txt); + + /* + * Now we have to check, if we should use the domain-module to select the domain + * or not + */ + $settings = $app->getconf->get_global_config('domains'); + if ($settings['use_domain_module'] == 'y') { + /* + * The domain-module is in use. + */ + $domains = $app->tools_sites->getDomainModuleDomains(); + $domain_select = ''; + if(is_array($domains) && sizeof($domains) > 0) { + /* We have domains in the list, so create the drop-down-list */ + foreach( $domains as $domain) { + $domain_select .= "<option value=" . $domain['domain_id'] ; + if ($domain['domain'] == $this->dataRecord["domain"]) { + $domain_select .= " selected"; + } + $domain_select .= ">" . $app->functions->idn_decode($domain['domain']) . "</option>\r\n"; + } + } + else { + /* + * We have no domains in the domain-list. This means, we can not add ANY new domain. + * To avoid, that the variable "domain_option" is empty and so the user can + * free enter a domain, we have to create a empty option! + */ + $domain_select .= "<option value=''></option>\r\n"; + } + $app->tpl->setVar("domain_option",$domain_select); + } + + // check for configuration errors in sys_datalog + if($this->id > 0) { + $datalog = $app->db->queryOneRecord("SELECT sys_datalog.error, sys_log.tstamp FROM sys_datalog, sys_log WHERE sys_datalog.dbtable = 'web_domain' AND sys_datalog.dbidx = 'domain_id:".$this->id."' AND sys_datalog.datalog_id = sys_log.datalog_id AND sys_log.message = CONCAT('Processed datalog_id ',sys_log.datalog_id) ORDER BY sys_datalog.tstamp DESC"); + if(is_array($datalog) && !empty($datalog)){ + if(trim($datalog['error']) != ''){ + $app->tpl->setVar("config_error_msg",nl2br(htmlentities($datalog['error']))); + $app->tpl->setVar("config_error_tstamp",date($app->lng('conf_format_datetime'), $datalog['tstamp'])); + } + } + } + + parent::onShowEnd(); + } + + function onShowEdit() { + global $app; + if($app->tform->checkPerm($this->id, 'riud')) $app->tform->formDef['tabs']['domain']['readonly'] = false; + parent::onShowEdit(); + } + + function onSubmit() { + global $app, $conf; + + /* check if the domain module is used - and check if the selected domain can be used! */ + if($app->tform->getCurrentTab() == 'domain') { + $app->uses('ini_parser,getconf'); + $settings = $app->getconf->get_global_config('domains'); + if ($settings['use_domain_module'] == 'y') { + $domain_check = $app->tools_sites->checkDomainModuleDomain($this->dataRecord['domain']); + if(!$domain_check) { + // invalid domain selected + $app->tform->errorMessage .= $app->tform->lng("domain_error_empty")."<br />"; + } else { + $this->dataRecord['domain'] = $domain_check; + } + } + } + + // nginx: if redirect type is proxy and redirect path is no URL, display error + //if($this->dataRecord["redirect_type"] == 'proxy' && substr($this->dataRecord['redirect_path'],0,1) == '/'){ + // $app->tform->errorMessage .= $app->tform->lng("error_proxy_requires_url")."<br />"; + //} + + // Set a few fixed values + $this->dataRecord["parent_domain_id"] = 0; + $this->dataRecord["type"] = 'vhost'; + $this->dataRecord["vhost_type"] = 'name'; + + $read_limits = array('limit_cgi', 'limit_ssi', 'limit_perl', 'limit_ruby', 'limit_python', 'force_suexec', 'limit_hterror', 'limit_wildcard', 'limit_ssl'); + + + if($_SESSION["s"]["user"]["typ"] != 'admin') { + // Get the limits of the client + $client_group_id = $_SESSION["s"]["user"]["default_group"]; + $client = $app->db->queryOneRecord("SELECT limit_traffic_quota, limit_web_domain, default_webserver, parent_client_id, limit_web_quota, client." . implode(", client.", $read_limits) . " FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id"); + + if($client['limit_cgi'] != 'y') $this->dataRecord['cgi'] = '-'; + if($client['limit_ssi'] != 'y') $this->dataRecord['ssi'] = '-'; + if($client['limit_perl'] != 'y') $this->dataRecord['perl'] = '-'; + if($client['limit_ruby'] != 'y') $this->dataRecord['ruby'] = '-'; + if($client['limit_python'] != 'y') $this->dataRecord['python'] = '-'; + if($client['force_suexec'] == 'y') $this->dataRecord['suexec'] = 'y'; + if($client['limit_hterror'] != 'y') $this->dataRecord['errordocs'] = '-'; + if($client['limit_wildcard'] != 'y' && $this->dataRecord['subdomain'] == '*') $this->dataRecord['subdomain'] = '-'; + if($client['limit_ssl'] != 'y') $this->dataRecord['ssl'] = '-'; + + // only generate quota and traffic warnings if value has changed + if($this->id > 0) { + $old_web_values = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".$app->functions->intval($this->id)); + } else { + $old_web_values = $_POST; + } + + //* Check the website quota of the client + if(isset($_POST["hd_quota"]) && $client["limit_web_quota"] >= 0 && $_POST["hd_quota"] != $old_web_values["hd_quota"]) { + $tmp = $app->db->queryOneRecord("SELECT sum(hd_quota) as webquota FROM web_domain WHERE domain_id != ".$app->functions->intval($this->id)." AND type = 'vhost' AND ".$app->tform->getAuthSQL('u')); + $webquota = $tmp["webquota"]; + $new_web_quota = $app->functions->intval($this->dataRecord["hd_quota"]); + if(($webquota + $new_web_quota > $client["limit_web_quota"]) || ($new_web_quota < 0 && $client["limit_web_quota"] >= 0)) { + $max_free_quota = floor($client["limit_web_quota"] - $webquota); + if($max_free_quota < 0) $max_free_quota = 0; + $app->tform->errorMessage .= $app->tform->lng("limit_web_quota_free_txt").": ".$max_free_quota." MB<br>"; + // Set the quota field to the max free space + $this->dataRecord["hd_quota"] = $max_free_quota; + } + unset($tmp); + unset($tmp_quota); + } + + //* Check the traffic quota of the client + if(isset($_POST["traffic_quota"]) && $client["limit_traffic_quota"] > 0 && $_POST["traffic_quota"] != $old_web_values["traffic_quota"]) { + $tmp = $app->db->queryOneRecord("SELECT sum(traffic_quota) as trafficquota FROM web_domain WHERE domain_id != ".$app->functions->intval($this->id)." AND ".$app->tform->getAuthSQL('u')); + $trafficquota = $tmp["trafficquota"]; + $new_traffic_quota = $app->functions->intval($this->dataRecord["traffic_quota"]); + if(($trafficquota + $new_traffic_quota > $client["limit_traffic_quota"]) || ($new_traffic_quota < 0 && $client["limit_traffic_quota"] >= 0)) { + $max_free_quota = floor($client["limit_traffic_quota"] - $trafficquota); + if($max_free_quota < 0) $max_free_quota = 0; + $app->tform->errorMessage .= $app->tform->lng("limit_traffic_quota_free_txt").": ".$max_free_quota." MB<br>"; + // Set the quota field to the max free space + $this->dataRecord["traffic_quota"] = $max_free_quota; + } + unset($tmp); + unset($tmp_quota); + } + + if($client['parent_client_id'] > 0) { + // Get the limits of the reseller + $reseller = $app->db->queryOneRecord("SELECT limit_traffic_quota, limit_web_domain, default_webserver, limit_web_quota FROM client WHERE client_id = ".$client['parent_client_id']); + + //* Check the website quota of the client + if(isset($_POST["hd_quota"]) && $reseller["limit_web_quota"] >= 0 && $_POST["hd_quota"] != $old_web_values["hd_quota"]) { + $tmp = $app->db->queryOneRecord("SELECT sum(hd_quota) as webquota FROM web_domain WHERE domain_id != ".$app->functions->intval($this->id)." AND type = 'vhost' AND ".$app->tform->getAuthSQL('u')); + $webquota = $tmp["webquota"]; + $new_web_quota = $app->functions->intval($this->dataRecord["hd_quota"]); + if(($webquota + $new_web_quota > $reseller["limit_web_quota"]) || ($new_web_quota < 0 && $reseller["limit_web_quota"] >= 0)) { + $max_free_quota = floor($reseller["limit_web_quota"] - $webquota); + if($max_free_quota < 0) $max_free_quota = 0; + $app->tform->errorMessage .= $app->tform->lng("limit_web_quota_free_txt").": ".$max_free_quota." MB<br>"; + // Set the quota field to the max free space + $this->dataRecord["hd_quota"] = $max_free_quota; + } + unset($tmp); + unset($tmp_quota); + } + + //* Check the traffic quota of the client + if(isset($_POST["traffic_quota"]) && $reseller["limit_traffic_quota"] > 0 && $_POST["traffic_quota"] != $old_web_values["traffic_quota"]) { + $tmp = $app->db->queryOneRecord("SELECT sum(traffic_quota) as trafficquota FROM web_domain WHERE domain_id != ".$app->functions->intval($this->id)." AND ".$app->tform->getAuthSQL('u')); + $trafficquota = $tmp["trafficquota"]; + $new_traffic_quota = $app->functions->intval($this->dataRecord["traffic_quota"]); + if(($trafficquota + $new_traffic_quota > $reseller["limit_traffic_quota"]) || ($new_traffic_quota < 0 && $reseller["limit_traffic_quota"] >= 0)) { + $max_free_quota = floor($reseller["limit_traffic_quota"] - $trafficquota); + if($max_free_quota < 0) $max_free_quota = 0; + $app->tform->errorMessage .= $app->tform->lng("limit_traffic_quota_free_txt").": ".$max_free_quota." MB<br>"; + // Set the quota field to the max free space + $this->dataRecord["traffic_quota"] = $max_free_quota; + } + unset($tmp); + unset($tmp_quota); + } + } + + // When the record is updated + if($this->id > 0) { + // restore the server ID if the user is not admin and record is edited + $tmp = $app->db->queryOneRecord("SELECT server_id, `cgi`, `ssi`, `perl`, `ruby`, `python`, `suexec`, `errordocs`, `subdomain`, `ssl` FROM web_domain WHERE domain_id = ".$app->functions->intval($this->id)); + $this->dataRecord["server_id"] = $tmp["server_id"]; + + // set the settings to current if not provided (or cleared due to limits) + if($this->dataRecord['cgi'] == '-') $this->dataRecord['cgi'] = $tmp['cgi']; + if($this->dataRecord['ssi'] == '-') $this->dataRecord['ssi'] = $tmp['ssi']; + if($this->dataRecord['perl'] == '-') $this->dataRecord['perl'] = $tmp['perl']; + if($this->dataRecord['ruby'] == '-') $this->dataRecord['ruby'] = $tmp['ruby']; + if($this->dataRecord['python'] == '-') $this->dataRecord['python'] = $tmp['python']; + if($this->dataRecord['suexec'] == '-') $this->dataRecord['suexec'] = $tmp['suexec']; + if($this->dataRecord['errordocs'] == '-') $this->dataRecord['errordocs'] = $tmp['errordocs']; + if($this->dataRecord['subdomain'] == '-') $this->dataRecord['subdomain'] = $tmp['subdomain']; + if($this->dataRecord['ssl'] == '-') $this->dataRecord['ssl'] = $tmp['ssl']; + + unset($tmp); + // When the record is inserted + } else { + //* set the server ID to the default webserver of the client + $this->dataRecord["server_id"] = $client["default_webserver"]; + + // Check if the user may add another web_domain + if($client["limit_web_domain"] >= 0) { + $tmp = $app->db->queryOneRecord("SELECT count(domain_id) as number FROM web_domain WHERE sys_groupid = $client_group_id and type = 'vhost'"); + if($tmp["number"] >= $client["limit_web_domain"]) { + $app->error($app->tform->wordbook["limit_web_domain_txt"]); + } + } + + } + + // Clients may not set the client_group_id, so we unset them if user is not a admin and the client is not a reseller + if(!$app->auth->has_clients($_SESSION['s']['user']['userid'])) unset($this->dataRecord["client_group_id"]); + } + + //* make sure that the email domain is lowercase + if(isset($this->dataRecord["domain"])) $this->dataRecord["domain"] = strtolower($this->dataRecord["domain"]); + + //* get the server config for this server + $app->uses("getconf"); + if($this->id > 0){ + $web_rec = $app->tform->getDataRecord($this->id); + $server_id = $web_rec["server_id"]; + } else { + // Get the first server ID + $tmp = $app->db->queryOneRecord("SELECT server_id FROM server WHERE web_server = 1 ORDER BY server_name LIMIT 0,1"); + $server_id = intval($tmp['server_id']); + } + $web_config = $app->getconf->get_server_config($app->functions->intval(isset($this->dataRecord["server_id"]) ? $this->dataRecord["server_id"] : $server_id),'web'); + //* Check for duplicate ssl certs per IP if SNI is disabled + if(isset($this->dataRecord['ssl']) && $this->dataRecord['ssl'] == 'y' && $web_config['enable_sni'] != 'y') { + $sql = "SELECT count(domain_id) as number FROM web_domain WHERE `ssl` = 'y' AND ip_address = '".$app->db->quote($this->dataRecord['ip_address'])."' and domain_id != ".$this->id; + $tmp = $app->db->queryOneRecord($sql); + if($tmp['number'] > 0) $app->tform->errorMessage .= $app->tform->lng("error_no_sni_txt"); + } + + // Check if pm.max_children >= pm.max_spare_servers >= pm.start_servers >= pm.min_spare_servers > 0 + if(isset($this->dataRecord['pm_max_children']) && $this->dataRecord['pm'] == 'dynamic') { + if($app->functions->intval($this->dataRecord['pm_max_children'], true) >= $app->functions->intval($this->dataRecord['pm_max_spare_servers'], true) && $app->functions->intval($this->dataRecord['pm_max_spare_servers'], true) >= $app->functions->intval($this->dataRecord['pm_start_servers'], true) && $app->functions->intval($this->dataRecord['pm_start_servers'], true) >= $app->functions->intval($this->dataRecord['pm_min_spare_servers'], true) && $app->functions->intval($this->dataRecord['pm_min_spare_servers'], true) > 0){ + + } else { + $app->tform->errorMessage .= $app->tform->lng("error_php_fpm_pm_settings_txt").'<br>'; + } + } + + // Check rewrite rules + $server_type = $web_config['server_type']; + + if($server_type == 'nginx' && isset($this->dataRecord['rewrite_rules']) && trim($this->dataRecord['rewrite_rules']) != '') { + $rewrite_rules = trim($this->dataRecord['rewrite_rules']); + $rewrites_are_valid = true; + // use this counter to make sure all curly brackets are properly closed + $if_level = 0; + // Make sure we only have Unix linebreaks + $rewrite_rules = str_replace("\r\n", "\n", $rewrite_rules); + $rewrite_rules = str_replace("\r", "\n", $rewrite_rules); + $rewrite_rule_lines = explode("\n", $rewrite_rules); + if(is_array($rewrite_rule_lines) && !empty($rewrite_rule_lines)){ + foreach($rewrite_rule_lines as $rewrite_rule_line){ + // ignore comments + if(substr(ltrim($rewrite_rule_line),0,1) == '#') continue; + // empty lines + if(trim($rewrite_rule_line) == '') continue; + // rewrite + if(preg_match('@^\s*rewrite\s+(^/)?\S+(\$)?\s+\S+(\s+(last|break|redirect|permanent|))?\s*;\s*$@', $rewrite_rule_line)) continue; + // if + if(preg_match('@^\s*if\s+\(\s*\$\S+(\s+(\!?(=|~|~\*))\s+(\S+|\".+\"))?\s*\)\s*\{\s*$@', $rewrite_rule_line)){ + $if_level += 1; + continue; + } + // if - check for files, directories, etc. + if(preg_match('@^\s*if\s+\(\s*\!?-(f|d|e|x)\s+\S+\s*\)\s*\{\s*$@', $rewrite_rule_line)){ + $if_level += 1; + continue; + } + // break + if(preg_match('@^\s*break\s*;\s*$@', $rewrite_rule_line)){ + continue; + } + // return code [ text ] + if(preg_match('@^\s*return\s+\d\d\d.*;\s*$@', $rewrite_rule_line)) continue; + // return code URL + // return URL + if(preg_match('@^\s*return(\s+\d\d\d)?\s+(http|https|ftp)\://([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&%\$\-]+)*\@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|localhost|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(\:[0-9]+)*(/($|[a-zA-Z0-9\.\,\?\'\\\+&%\$#\=~_\-]+))*\s*;\s*$@', $rewrite_rule_line)) continue; + // set + if(preg_match('@^\s*set\s+\$\S+\s+\S+\s*;\s*$@', $rewrite_rule_line)) continue; + // closing curly bracket + if(trim($rewrite_rule_line) == '}'){ + $if_level -= 1; + continue; + } + $rewrites_are_valid = false; + break; + } + } + + if(!$rewrites_are_valid || $if_level != 0){ + $app->tform->errorMessage .= $app->tform->lng("invalid_rewrite_rules_txt").'<br>'; + } + } + + parent::onSubmit(); + } + + function onAfterInsert() { + global $app, $conf; + + // make sure that the record belongs to the clinet group and not the admin group when admin inserts it + // also make sure that the user can not delete domain created by a admin + if($_SESSION["s"]["user"]["typ"] == 'admin' && isset($this->dataRecord["client_group_id"])) { + $client_group_id = $app->functions->intval($this->dataRecord["client_group_id"]); + $app->db->query("UPDATE web_domain SET sys_groupid = $client_group_id, sys_perm_group = 'ru' WHERE domain_id = ".$this->id); + } + if($app->auth->has_clients($_SESSION['s']['user']['userid']) && isset($this->dataRecord["client_group_id"])) { + $client_group_id = $app->functions->intval($this->dataRecord["client_group_id"]); + $app->db->query("UPDATE web_domain SET sys_groupid = $client_group_id, sys_perm_group = 'riud' WHERE domain_id = ".$this->id); + } + + // Get configuration for the web system + $app->uses("getconf"); + $web_rec = $app->tform->getDataRecord($this->id); + $web_config = $app->getconf->get_server_config($app->functions->intval($web_rec["server_id"]),'web'); + $document_root = str_replace("[website_id]",$this->id,$web_config["website_path"]); + $document_root = str_replace("[website_idhash_1]",$this->id_hash($page_form->id,1),$document_root); + $document_root = str_replace("[website_idhash_2]",$this->id_hash($page_form->id,1),$document_root); + $document_root = str_replace("[website_idhash_3]",$this->id_hash($page_form->id,1),$document_root); + $document_root = str_replace("[website_idhash_4]",$this->id_hash($page_form->id,1),$document_root); + + // get the ID of the client + if($_SESSION["s"]["user"]["typ"] != 'admin' && !$app->auth->has_clients($_SESSION['s']['user']['userid'])) { + $client_group_id = $_SESSION["s"]["user"]["default_group"]; + $client = $app->db->queryOneRecord("SELECT client_id FROM sys_group WHERE sys_group.groupid = $client_group_id"); + $client_id = $app->functions->intval($client["client_id"]); + } else { + //$client_id = $app->functions->intval($this->dataRecord["client_group_id"]); + $client = $app->db->queryOneRecord("SELECT client_id FROM sys_group WHERE sys_group.groupid = ".$app->functions->intval($this->dataRecord["client_group_id"])); + $client_id = $app->functions->intval($client["client_id"]); + } + + // Set the values for document_root, system_user and system_group + $system_user = $app->db->quote('web'.$this->id); + $system_group = $app->db->quote('client'.$client_id); + $document_root = str_replace("[client_id]",$client_id,$document_root); + $document_root = str_replace("[client_idhash_1]",$this->id_hash($client_id,1),$document_root); + $document_root = str_replace("[client_idhash_2]",$this->id_hash($client_id,2),$document_root); + $document_root = str_replace("[client_idhash_3]",$this->id_hash($client_id,3),$document_root); + $document_root = str_replace("[client_idhash_4]",$this->id_hash($client_id,4),$document_root); + $document_root = $app->db->quote($document_root); + $php_open_basedir = str_replace("[website_path]",$document_root,$web_config["php_open_basedir"]); + $php_open_basedir = $app->db->quote(str_replace("[website_domain]",$web_rec['domain'],$php_open_basedir)); + $htaccess_allow_override = $app->db->quote($web_config["htaccess_allow_override"]); + + $sql = "UPDATE web_domain SET system_user = '$system_user', system_group = '$system_group', document_root = '$document_root', allow_override = '$htaccess_allow_override', php_open_basedir = '$php_open_basedir' WHERE domain_id = ".$this->id; + $app->db->query($sql); + } + + function onBeforeUpdate () { + global $app, $conf; + + //* Check if the server has been changed + // We do this only for the admin or reseller users, as normal clients can not change the server ID anyway + if($_SESSION["s"]["user"]["typ"] == 'admin' || $app->auth->has_clients($_SESSION['s']['user']['userid'])) { + if (isset($this->dataRecord["server_id"])) { + $rec = $app->db->queryOneRecord("SELECT server_id from web_domain WHERE domain_id = ".$this->id); + if($rec['server_id'] != $this->dataRecord["server_id"]) { + //* Add a error message and switch back to old server + $app->tform->errorMessage .= $app->lng('The Server can not be changed.'); + $this->dataRecord["server_id"] = $rec['server_id']; + } + unset($rec); + } + //* If the user is neither admin nor reseller + } else { + //* We do not allow users to change a domain which has been created by the admin + $rec = $app->db->queryOneRecord("SELECT sys_perm_group, domain, ip_address, ipv6_address from web_domain WHERE domain_id = ".$this->id); + if(isset($this->dataRecord["domain"]) && $rec['domain'] != $this->dataRecord["domain"] && $app->tform->checkPerm($this->id,'u')) { + //* Add a error message and switch back to old server + $app->tform->errorMessage .= $app->lng('The Domain can not be changed. Please ask your Administrator if you want to change the domain name.'); + $this->dataRecord["domain"] = $rec['domain']; + } + if(isset($this->dataRecord["ip_address"]) && $rec['ip_address'] != $this->dataRecord["ip_address"] && $rec['sys_perm_group'] != 'riud') { + $this->dataRecord["ip_address"] = $rec['ip_address']; + } + if(isset($this->dataRecord["ipv6_address"]) && $rec['ipv6_address'] != $this->dataRecord["ipv6_address"] && $rec['sys_perm_group'] != 'riud') { + $this->dataRecord["ipv6_address"] = $rec['ipv6_address']; + } + unset($rec); + } + + //* Check that all fields for the SSL cert creation are filled + if(isset($this->dataRecord['ssl_action']) && $this->dataRecord['ssl_action'] == 'create') { + if($this->dataRecord['ssl_state'] == '') $app->tform->errorMessage .= $app->tform->lng('error_ssl_state_empty').'<br />'; + if($this->dataRecord['ssl_locality'] == '') $app->tform->errorMessage .= $app->tform->lng('error_ssl_locality_empty').'<br />'; + if($this->dataRecord['ssl_organisation'] == '') $app->tform->errorMessage .= $app->tform->lng('error_ssl_organisation_empty').'<br />'; + if($this->dataRecord['ssl_organisation_unit'] == '') $app->tform->errorMessage .= $app->tform->lng('error_ssl_organisation_unit_empty').'<br />'; + if($this->dataRecord['ssl_country'] == '') $app->tform->errorMessage .= $app->tform->lng('error_ssl_country_empty').'<br />'; + } + + if(isset($this->dataRecord['ssl_action']) && $this->dataRecord['ssl_action'] == 'save') { + if(trim($this->dataRecord['ssl_cert']) == '') $app->tform->errorMessage .= $app->tform->lng('error_ssl_cert_empty').'<br />'; + } + + } + + function onAfterUpdate() { + global $app, $conf; + + // make sure that the record belongs to the client group and not the admin group when a admin inserts it + // also make sure that the user can not delete domain created by a admin + if($_SESSION["s"]["user"]["typ"] == 'admin' && isset($this->dataRecord["client_group_id"])) { + $client_group_id = $app->functions->intval($this->dataRecord["client_group_id"]); + $app->db->query("UPDATE web_domain SET sys_groupid = $client_group_id, sys_perm_group = 'ru' WHERE domain_id = ".$this->id); + } + if($app->auth->has_clients($_SESSION['s']['user']['userid']) && isset($this->dataRecord["client_group_id"])) { + $client_group_id = $app->functions->intval($this->dataRecord["client_group_id"]); + $app->db->query("UPDATE web_domain SET sys_groupid = $client_group_id, sys_perm_group = 'riud' WHERE domain_id = ".$this->id); + } + + // Get configuration for the web system + $app->uses("getconf"); + $web_rec = $app->tform->getDataRecord($this->id); + $web_config = $app->getconf->get_server_config($app->functions->intval($web_rec["server_id"]),'web'); + $document_root = str_replace("[website_id]",$this->id,$web_config["website_path"]); + $page_formid = isset($page_form->id) ? $page_form->id : ''; + $document_root = str_replace("[website_idhash_1]",$this->id_hash($page_formid,1),$document_root); + $document_root = str_replace("[website_idhash_2]",$this->id_hash($page_formid,1),$document_root); + $document_root = str_replace("[website_idhash_3]",$this->id_hash($page_formid,1),$document_root); + $document_root = str_replace("[website_idhash_4]",$this->id_hash($page_formid,1),$document_root); + + // get the ID of the client + if($_SESSION["s"]["user"]["typ"] != 'admin' && !$app->auth->has_clients($_SESSION['s']['user']['userid'])) { + $client_group_id = $_SESSION["s"]["user"]["default_group"]; + $client = $app->db->queryOneRecord("SELECT client_id FROM sys_group WHERE sys_group.groupid = $client_group_id"); + $client_id = $app->functions->intval($client["client_id"]); + } elseif (isset($this->dataRecord["client_group_id"])) { + $client_group_id = $this->dataRecord["client_group_id"]; + $client = $app->db->queryOneRecord("SELECT client_id FROM sys_group WHERE sys_group.groupid = ".$app->functions->intval(@$this->dataRecord["client_group_id"])); + $client_id = $app->functions->intval($client["client_id"]); + } else { + $client_group_id = $web_rec['sys_groupid']; + $client = $app->db->queryOneRecord("SELECT client_id FROM sys_group WHERE sys_group.groupid = ".$app->functions->intval($client_group_id)); + $client_id = $app->functions->intval($client["client_id"]); + } + + if(($_SESSION["s"]["user"]["typ"] == 'admin' || $app->auth->has_clients($_SESSION['s']['user']['userid'])) && isset($this->dataRecord["client_group_id"]) && $this->dataRecord["client_group_id"] != $this->oldDataRecord["sys_groupid"]) { + // Set the values for document_root, system_user and system_group + $system_user = $app->db->quote('web'.$this->id); + $system_group = $app->db->quote('client'.$client_id); + $document_root = str_replace("[client_id]",$client_id,$document_root); + $document_root = str_replace("[client_idhash_1]",$this->id_hash($client_id,1),$document_root); + $document_root = str_replace("[client_idhash_2]",$this->id_hash($client_id,2),$document_root); + $document_root = str_replace("[client_idhash_3]",$this->id_hash($client_id,3),$document_root); + $document_root = str_replace("[client_idhash_4]",$this->id_hash($client_id,4),$document_root); + $document_root = $app->db->quote($document_root); + + $sql = "UPDATE web_domain SET system_user = '$system_user', system_group = '$system_group', document_root = '$document_root' WHERE domain_id = ".$this->id; + //$sql = "UPDATE web_domain SET system_user = '$system_user', system_group = '$system_group' WHERE domain_id = ".$this->id; + $app->db->query($sql); + + // Update the FTP user(s) too + $records = $app->db->queryAllRecords("SELECT ftp_user_id FROM ftp_user WHERE parent_domain_id = ".$this->id); + foreach($records as $rec) { + $app->db->datalogUpdate('ftp_user', "sys_userid = '".$web_rec['sys_userid']."', sys_groupid = '".$web_rec['sys_groupid']."', uid = '$system_user', gid = '$system_group', dir = '$document_root'", 'ftp_user_id', $rec['ftp_user_id']); + } + unset($records); + unset($rec); + + // Update the Shell user(s) too + $records = $app->db->queryAllRecords("SELECT shell_user_id FROM shell_user WHERE parent_domain_id = ".$this->id); + foreach($records as $rec) { + $app->db->datalogUpdate('shell_user', "sys_userid = '".$web_rec['sys_userid']."', sys_groupid = '".$web_rec['sys_groupid']."', puser = '$system_user', pgroup = '$system_group', dir = '$document_root'", 'shell_user_id', $rec['shell_user_id']); + } + unset($records); + unset($rec); + + //* Update all subdomains and alias domains + $records = $app->db->queryAllRecords("SELECT domain_id, `domain`, `type`, `web_folder` FROM web_domain WHERE parent_domain_id = ".$this->id); + foreach($records as $rec) { + $update_columns = "sys_userid = '".$web_rec['sys_userid']."', sys_groupid = '".$web_rec['sys_groupid']."'"; + if($rec['type'] == 'vhostsubdomain') { + $php_open_basedir = str_replace("[website_path]/web",$document_root.'/'.$rec['web_folder'],$web_config["php_open_basedir"]); + $php_open_basedir = str_replace("[website_domain]/web",$rec['domain'].'/'.$rec['web_folder'],$php_open_basedir); + $php_open_basedir = str_replace("[website_path]",$document_root,$php_open_basedir); + $php_open_basedir = $app->db->quote(str_replace("[website_domain]",$rec['domain'],$php_open_basedir)); + + $update_columns .= ", document_root = '".$document_root."', `php_open_basedir` = '".$php_open_basedir."'"; + } + $app->db->datalogUpdate('web_domain', $update_columns, 'domain_id', $rec['domain_id']); + } + unset($records); + unset($rec); + + //* Update all databases + $records = $app->db->queryAllRecords("SELECT database_id FROM web_database WHERE parent_domain_id = ".$this->id); + foreach($records as $rec) { + $app->db->datalogUpdate('web_database', "sys_userid = '".$web_rec['sys_userid']."', sys_groupid = '".$web_rec['sys_groupid']."'", 'database_id', $rec['database_id']); + } + unset($records); + unset($rec); + + } + + //* If the domain name has been changed, we will have to change all subdomains + APS instances + if(!empty($this->dataRecord["domain"]) && !empty($this->oldDataRecord["domain"]) && $this->dataRecord["domain"] != $this->oldDataRecord["domain"]) { + $records = $app->db->queryAllRecords("SELECT domain_id,domain FROM web_domain WHERE (type = 'subdomain' OR type = 'vhostsubdomain') AND domain LIKE '%.".$app->db->quote($this->oldDataRecord["domain"])."'"); + foreach($records as $rec) { + $subdomain = $app->db->quote(str_replace($this->oldDataRecord["domain"],$this->dataRecord["domain"],$rec['domain'])); + $app->db->datalogUpdate('web_domain', "domain = '".$subdomain."'", 'domain_id', $rec['domain_id']); + } + unset($records); + unset($rec); + unset($subdomain); + + // Update APS instances + $records = $app->db->queryAllRecords("SELECT id, instance_id FROM aps_instances_settings WHERE name = 'main_domain' AND value = '".$this->oldDataRecord["domain"]."'"); + if(is_array($records) && !empty($records)){ + foreach($records as $rec){ + $app->db->datalogUpdate('aps_instances_settings', "value = '".$this->dataRecord["domain"]."'", 'id', $rec['id']); + // Reinstall of package needed? + //$app->db->datalogUpdate('aps_instances', "instance_status = '1'", 'id', $rec['instance_id']); + } + } + unset($records); + unset($rec); + } + + //* Set allow_override if empty + if($web_rec['allow_override'] == '') { + $sql = "UPDATE web_domain SET allow_override = '".$app->db->quote($web_config["htaccess_allow_override"])."' WHERE domain_id = ".$this->id; + $app->db->query($sql); + } + + //* Set php_open_basedir if empty or domain or client has been changed + if(empty($web_rec['php_open_basedir']) || + (!empty($this->dataRecord["domain"]) && !empty($this->oldDataRecord["domain"]) && $this->dataRecord["domain"] != $this->oldDataRecord["domain"])) { + $php_open_basedir = $web_rec['php_open_basedir']; + $php_open_basedir = str_replace($this->oldDataRecord['domain'],$web_rec['domain'],$php_open_basedir); + $sql = "UPDATE web_domain SET php_open_basedir = '$php_open_basedir' WHERE domain_id = ".$this->id; + $app->db->query($sql); + } + if(empty($web_rec['php_open_basedir']) || + (isset($this->dataRecord["client_group_id"]) && $this->dataRecord["client_group_id"] != $this->oldDataRecord["sys_groupid"])) { + $document_root = $app->db->quote(str_replace("[client_id]",$client_id,$document_root)); + $php_open_basedir = str_replace("[website_path]",$document_root,$web_config["php_open_basedir"]); + $php_open_basedir = $app->db->quote(str_replace("[website_domain]",$web_rec['domain'],$php_open_basedir)); + $sql = "UPDATE web_domain SET php_open_basedir = '$php_open_basedir' WHERE domain_id = ".$this->id; + $app->db->query($sql); + } + + //* Change database backup options when web backup options have been changed + if(isset($this->dataRecord['backup_interval']) && ($this->dataRecord['backup_interval'] != $this->oldDataRecord['backup_interval'] || $this->dataRecord['backup_copies'] != $this->oldDataRecord['backup_copies'])) { + //* Update all databases + $backup_interval = $this->dataRecord['backup_interval']; + $backup_copies = $this->dataRecord['backup_copies']; + $records = $app->db->queryAllRecords("SELECT database_id FROM web_database WHERE parent_domain_id = ".$this->id); + foreach($records as $rec) { + $app->db->datalogUpdate('web_database', "backup_interval = '$backup_interval', backup_copies = '$backup_copies'", 'database_id', $rec['database_id']); + } + unset($records); + unset($rec); + unset($backup_copies); + unset($backup_interval); + } + + //* Change vhost subdomain ip/ipv6 if domain ip/ipv6 has changed + if(isset($this->dataRecord['ip_address']) && ($this->dataRecord['ip_address'] != $this->oldDataRecord['ip_address'] || $this->dataRecord['ipv6_address'] != $this->oldDataRecord['ipv6_address'])) { + $records = $app->db->queryAllRecords("SELECT domain_id FROM web_domain WHERE type = 'vhostsubdomain' AND parent_domain_id = ".$this->id); + foreach($records as $rec) { + $app->db->datalogUpdate('web_domain', "ip_address = '".$web_rec['ip_address']."', ipv6_address = '".$web_rec['ipv6_address']."'", 'domain_id', $rec['domain_id']); + } + unset($records); + unset($rec); + } + } + + function onAfterDelete() { + global $app, $conf; + + // Delete the sub and alias domains + $child_domains = $app->db->queryAllRecords("SELECT * FROM web_domain WHERE parent_domain_id = ".$this->id); + foreach($child_domains as $d) { + // Saving record to datalog when db_history enabled + if($app->tform->formDef["db_history"] == 'yes') { + $app->tform->datalogSave('DELETE',$d["domain_id"],$d,array()); + } + + $app->db->query("DELETE FROM web_domain WHERE domain_id = ".$d["domain_id"]." LIMIT 0,1"); + } + unset($child_domains); + unset($d); + + } + +} + +$page = new page_action; +$page->onLoad(); + ?> \ No newline at end of file diff --git a/interface/web/sites/web_vhost_subdomain_edit.php b/interface/web/sites/web_vhost_subdomain_edit.php index f5989f9d15d6f4a7829a9afeef3ce23a3f7f4dbd..9c1a1966f427fb1592c5c2312572e0e3002b3029 100644 --- a/interface/web/sites/web_vhost_subdomain_edit.php +++ b/interface/web/sites/web_vhost_subdomain_edit.php @@ -1,619 +1,619 @@ -<?php -/* -Copyright (c) 2007 - 2009, Till Brehm, projektfarm Gmbh -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of ISPConfig nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -/****************************************** -* Begin Form configuration -******************************************/ - -$tform_def_file = "form/web_vhost_subdomain.tform.php"; - -/****************************************** -* End Form configuration -******************************************/ - -require_once('../../lib/config.inc.php'); -require_once('../../lib/app.inc.php'); - -//* Check permissions for module -$app->auth->check_module_permissions('sites'); - -// Loading classes -$app->uses('tpl,tform,tform_actions,tools_sites'); -$app->load('tform_actions'); - -class page_action extends tform_actions { - - //* Returna a "3/2/1" path hash from a numeric id '123' - function id_hash($id,$levels) { - $hash = "" . $id % 10 ; - $id /= 10 ; - $levels -- ; - while ( $levels > 0 ) { - $hash .= "/" . $id % 10 ; - $id /= 10 ; - $levels-- ; - } - return $hash; - } - - function onShowNew() { - global $app, $conf; - - // we will check only users, not admins - if($_SESSION["s"]["user"]["typ"] == 'user') { - if(!$app->tform->checkClientLimit('limit_web_subdomain',"(type = 'subdomain' OR type = 'vhostsubdomain')")) { - $app->error($app->tform->wordbook["limit_web_subdomain_txt"]); - } - if(!$app->tform->checkResellerLimit('limit_web_subdomain',"(type = 'subdomain' OR type = 'vhostsubdomain')")) { - $app->error('Reseller: '.$app->tform->wordbook["limit_web_subdomain_txt"]); - } - } - parent::onShowNew(); - } - - function onShowEnd() { - global $app, $conf; - - $app->uses('ini_parser,getconf'); - - $read_limits = array('limit_cgi', 'limit_ssi', 'limit_perl', 'limit_ruby', 'limit_python', 'force_suexec', 'limit_hterror', 'limit_wildcard', 'limit_ssl'); - - $parent_domain = $app->db->queryOneRecord("select * FROM web_domain WHERE domain_id = ".$app->functions->intval(@$this->dataRecord["parent_domain_id"])); - - //* Client: If the logged in user is not admin and has no sub clients (no reseller) - if($_SESSION["s"]["user"]["typ"] != 'admin' && !$app->auth->has_clients($_SESSION['s']['user']['userid'])) { - - // Get the limits of the client - $client_group_id = $_SESSION["s"]["user"]["default_group"]; - $client = $app->db->queryOneRecord("SELECT client.limit_web_subdomain, client.default_webserver, client." . implode(", client.", $read_limits) . " FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id"); - - //* Get global web config - $web_config = $app->getconf->get_server_config($parent_domain['server_id'], 'web'); - - //PHP Version Selection (FastCGI) - $server_type = 'apache'; - if(!empty($web_config['server_type'])) $server_type = $web_config['server_type']; - if($server_type == 'nginx' && $this->dataRecord['php'] == 'fast-cgi') $this->dataRecord['php'] = 'php-fpm'; - if($this->dataRecord['php'] == 'php-fpm'){ - $php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fpm_init_script != '' AND php_fpm_ini_dir != '' AND php_fpm_pool_dir != '' AND server_id = ".$parent_domain['server_id']." AND (client_id = 0 OR client_id=".$_SESSION['s']['user']['client_id'].")"); - } - if($this->dataRecord['php'] == 'fast-cgi'){ - $php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fastcgi_binary != '' AND php_fastcgi_ini_dir != '' AND server_id = ".$parent_domain['server_id']." AND (client_id = 0 OR client_id=".$_SESSION['s']['user']['client_id'].")"); - } - $php_select = "<option value=''>Default</option>"; - if(is_array($php_records) && !empty($php_records)) { - foreach( $php_records as $php_record) { - if($this->dataRecord['php'] == 'php-fpm'){ - $php_version = $php_record['name'].':'.$php_record['php_fpm_init_script'].':'.$php_record['php_fpm_ini_dir'].':'.$php_record['php_fpm_pool_dir']; - } else { - $php_version = $php_record['name'].':'.$php_record['php_fastcgi_binary'].':'.$php_record['php_fastcgi_ini_dir']; - } - $selected = ($php_version == $this->dataRecord["fastcgi_php_version"])?'SELECTED':''; - $php_select .= "<option value='$php_version' $selected>".$php_record['name']."</option>\r\n"; - } - } - $app->tpl->setVar("fastcgi_php_version",$php_select); - unset($php_records); - - // add limits to template to be able to hide settings - foreach($read_limits as $limit) $app->tpl->setVar($limit, $client[$limit]); - - - //* Reseller: If the logged in user is not admin and has sub clients (is a reseller) - } elseif ($_SESSION["s"]["user"]["typ"] != 'admin' && $app->auth->has_clients($_SESSION['s']['user']['userid'])) { - - // Get the limits of the client - $client_group_id = $_SESSION["s"]["user"]["default_group"]; - $client = $app->db->queryOneRecord("SELECT client.client_id, client.limit_web_subdomain, client.default_webserver, client.contact_name, CONCAT(IF(client.company_name != '', CONCAT(client.company_name, ' :: '), ''), client.contact_name, ' (', client.username, IF(client.customer_no != '', CONCAT(', ', client.customer_no), ''), ')') as contactname, sys_group.name, client." . implode(", client.", $read_limits) . " FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id"); - - //* Get global web config - $web_config = $app->getconf->get_server_config($parent_domain['server_id'], 'web'); - - //PHP Version Selection (FastCGI) - $server_type = 'apache'; - if(!empty($web_config['server_type'])) $server_type = $web_config['server_type']; - if($server_type == 'nginx' && $this->dataRecord['php'] == 'fast-cgi') $this->dataRecord['php'] = 'php-fpm'; - if($this->dataRecord['php'] == 'php-fpm'){ - $php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fpm_init_script != '' AND php_fpm_ini_dir != '' AND php_fpm_pool_dir != '' AND server_id = ".$parent_domain['server_id']." AND (client_id = 0 OR client_id=".$_SESSION['s']['user']['client_id'].")"); - } - if($this->dataRecord['php'] == 'fast-cgi') { - $php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fastcgi_binary != '' AND php_fastcgi_ini_dir != '' AND server_id = ".$parent_domain['server_id']." AND (client_id = 0 OR client_id=".$_SESSION['s']['user']['client_id'].")"); - } - $php_select = "<option value=''>Default</option>"; - if(is_array($php_records) && !empty($php_records)) { - foreach( $php_records as $php_record) { - if($this->dataRecord['php'] == 'php-fpm'){ - $php_version = $php_record['name'].':'.$php_record['php_fpm_init_script'].':'.$php_record['php_fpm_ini_dir'].':'.$php_record['php_fpm_pool_dir']; - } else { - $php_version = $php_record['name'].':'.$php_record['php_fastcgi_binary'].':'.$php_record['php_fastcgi_ini_dir']; - } - $selected = ($php_version == $this->dataRecord["fastcgi_php_version"])?'SELECTED':''; - $php_select .= "<option value='$php_version' $selected>".$php_record['name']."</option>\r\n"; - } - } - $app->tpl->setVar("fastcgi_php_version",$php_select); - unset($php_records); - - // add limits to template to be able to hide settings - foreach($read_limits as $limit) $app->tpl->setVar($limit, $client[$limit]); - - - //* Admin: If the logged in user is admin - } else { - - //* get global web config - $web_config = $app->getconf->get_server_config($parent_domain['server_id'], 'web'); - - //PHP Version Selection (FastCGI) - $server_type = 'apache'; - if(!empty($web_config['server_type'])) $server_type = $web_config['server_type']; - if($server_type == 'nginx' && $this->dataRecord['php'] == 'fast-cgi') $this->dataRecord['php'] = 'php-fpm'; - if($this->dataRecord['php'] == 'php-fpm'){ - $php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fpm_init_script != '' AND php_fpm_ini_dir != '' AND php_fpm_pool_dir != '' AND server_id = " . $parent_domain['server_id']); - } - if($this->dataRecord['php'] == 'fast-cgi') { - $php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fastcgi_binary != '' AND php_fastcgi_ini_dir != '' AND server_id = " . $parent_domain['server_id']); - } - $php_select = "<option value=''>Default</option>"; - if(is_array($php_records) && !empty($php_records)) { - foreach( $php_records as $php_record) { - if($this->dataRecord['php'] == 'php-fpm'){ - $php_version = $php_record['name'].':'.$php_record['php_fpm_init_script'].':'.$php_record['php_fpm_ini_dir'].':'.$php_record['php_fpm_pool_dir']; - } else { - $php_version = $php_record['name'].':'.$php_record['php_fastcgi_binary'].':'.$php_record['php_fastcgi_ini_dir']; - } - $selected = ($php_version == $this->dataRecord["fastcgi_php_version"])?'SELECTED':''; - $php_select .= "<option value='$php_version' $selected>".$php_record['name']."</option>\r\n"; - } - } - $app->tpl->setVar("fastcgi_php_version",$php_select); - unset($php_records); - - foreach($read_limits as $limit) $app->tpl->setVar($limit, ($limit == 'force_suexec' ? 'n' : 'y')); - - // Directive Snippets - $php_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'php' AND active = 'y'"); - $php_directive_snippets_txt = ''; - if(is_array($php_directive_snippets) && !empty($php_directive_snippets)){ - foreach($php_directive_snippets as $php_directive_snippet){ - $php_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$php_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.$php_directive_snippet['snippet'].'</pre></a> '; - } - } - if($php_directive_snippets_txt == '') $php_directive_snippets_txt = '------'; - $app->tpl->setVar("php_directive_snippets_txt",$php_directive_snippets_txt); - - if($server_type == 'apache'){ - $apache_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'apache' AND active = 'y'"); - $apache_directive_snippets_txt = ''; - if(is_array($apache_directive_snippets) && !empty($apache_directive_snippets)){ - foreach($apache_directive_snippets as $apache_directive_snippet){ - $apache_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$apache_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.$apache_directive_snippet['snippet'].'</pre></a> '; - } - } - if($apache_directive_snippets_txt == '') $apache_directive_snippets_txt = '------'; - $app->tpl->setVar("apache_directive_snippets_txt",$apache_directive_snippets_txt); - } - - if($server_type == 'nginx'){ - $nginx_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'nginx' AND active = 'y'"); - $nginx_directive_snippets_txt = ''; - if(is_array($nginx_directive_snippets) && !empty($nginx_directive_snippets)){ - foreach($nginx_directive_snippets as $nginx_directive_snippet){ - $nginx_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$nginx_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.$nginx_directive_snippet['snippet'].'</pre></a> '; - } - } - if($nginx_directive_snippets_txt == '') $nginx_directive_snippets_txt = '------'; - $app->tpl->setVar("nginx_directive_snippets_txt",$nginx_directive_snippets_txt); - } - - $proxy_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'proxy' AND active = 'y'"); - $proxy_directive_snippets_txt = ''; - if(is_array($proxy_directive_snippets) && !empty($proxy_directive_snippets)){ - foreach($proxy_directive_snippets as $proxy_directive_snippet){ - $proxy_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$proxy_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.$proxy_directive_snippet['snippet'].'</pre></a> '; - } - } - if($proxy_directive_snippets_txt == '') $proxy_directive_snippets_txt = '------'; - $app->tpl->setVar("proxy_directive_snippets_txt",$proxy_directive_snippets_txt); - } - - $ssl_domain_select = ''; - $tmp = $app->db->queryOneRecord("SELECT domain FROM web_domain WHERE domain_id = ".$this->id); - $ssl_domains = array($tmp["domain"],'www.'.$tmp["domain"]); - if(is_array($ssl_domains)) { - foreach( $ssl_domains as $ssl_domain) { - $selected = ($ssl_domain == $this->dataRecord['ssl_domain'])?'SELECTED':''; - $ssl_domain_select .= "<option value='$ssl_domain' $selected>$ssl_domain</option>\r\n"; - } - } - - if($this->id > 0) { - $app->tpl->setVar('fixed_folder', 'y'); - $app->tpl->setVar('server_id_value', $parent_domain['server_id']); - } else { - $app->tpl->setVar('fixed_folder', 'n'); - $app->tpl->setVar('server_id_value', $parent_domain['server_id']); - } - - $app->tpl->setVar("ssl_domain",$ssl_domain_select); - unset($ssl_domain_select); - unset($ssl_domains); - unset($ssl_domain); - - $tmp_txt = ($this->dataRecord['traffic_quota_lock'] == 'y')?'<b>('.$app->tform->lng('traffic_quota_exceeded_txt').')</b>':''; - $app->tpl->setVar("traffic_quota_exceeded_txt", $tmp_txt); - - - $app->uses('ini_parser,getconf'); - $settings = $app->getconf->get_global_config('domains'); - if ($settings['use_domain_module'] == 'y') { - /* - * The domain-module is in use. - */ - $domains = $app->tools_sites->getDomainModuleDomains(); - $domain_select = ''; - $selected_domain = ''; - if(is_array($domains) && sizeof($domains) > 0) { - /* We have domains in the list, so create the drop-down-list */ - foreach( $domains as $domain) { - $domain_select .= "<option value=" . $domain['domain_id'] ; - if ('.' . $domain['domain'] == substr($this->dataRecord["domain"], -strlen($domain['domain']) - 1)) { - $domain_select .= " selected"; - $selected_domain = $domain['domain']; - } - $domain_select .= ">" . $app->functions->idn_decode($domain['domain']) . "</option>\r\n"; - } - } - else { - /* - * We have no domains in the domain-list. This means, we can not add ANY new domain. - * To avoid, that the variable "domain_option" is empty and so the user can - * free enter a domain, we have to create a empty option! - */ - $domain_select .= "<option value=''></option>\r\n"; - } - $app->tpl->setVar("domain_option",$domain_select); - $this->dataRecord['domain'] = substr($this->dataRecord["domain"], 0, strlen($this->dataRecord['domain']) - strlen($selected_domain) - 1); - } else { - - // remove the parent domain part of the domain name before we show it in the text field. - $this->dataRecord["domain"] = str_replace('.'.$parent_domain["domain"],'',$this->dataRecord["domain"]); - } - $app->tpl->setVar("domain",$this->dataRecord["domain"]); - - parent::onShowEnd(); - } - - function onSubmit() { - global $app, $conf; - - // Get the record of the parent domain - if(!@$this->dataRecord["parent_domain_id"] && $this->id) { - $tmp = $app->db->queryOneRecord("SELECT parent_domain_id FROM web_domain WHERE domain_id = ".$app->functions->intval($this->id)); - if($tmp) $this->dataRecord["parent_domain_id"] = $tmp['parent_domain_id']; - unset($tmp); - } - - $parent_domain = $app->db->queryOneRecord("select * FROM web_domain WHERE domain_id = ".$app->functions->intval(@$this->dataRecord["parent_domain_id"]) . " AND ".$app->tform->getAuthSQL('r')); - if(!$parent_domain || $parent_domain['domain_id'] != @$this->dataRecord['parent_domain_id']) $app->tform->errorMessage .= $app->tform->lng("no_domain_perm"); - - // Set a few fixed values - $this->dataRecord["type"] = 'vhostsubdomain'; - $this->dataRecord["server_id"] = $parent_domain["server_id"]; - $this->dataRecord["ip_address"] = $parent_domain["ip_address"]; - $this->dataRecord["ipv6_address"] = $parent_domain["ipv6_address"]; - $this->dataRecord["client_group_id"] = $parent_domain["client_group_id"]; - $this->dataRecord["vhost_type"] = 'name'; - - $this->parent_domain_record = $parent_domain; - - $read_limits = array('limit_cgi', 'limit_ssi', 'limit_perl', 'limit_ruby', 'limit_python', 'force_suexec', 'limit_hterror', 'limit_wildcard', 'limit_ssl'); - - if($app->tform->getCurrentTab() == 'domain') { - - /* check if the domain module is used - and check if the selected domain can be used! */ - $app->uses('ini_parser,getconf'); - $settings = $app->getconf->get_global_config('domains'); - if ($settings['use_domain_module'] == 'y') { - $domain_check = $app->tools_sites->checkDomainModuleDomain($this->dataRecord['sel_domain']); - if(!$domain_check) { - // invalid domain selected - $app->tform->errorMessage .= $app->tform->lng("domain_error_empty")."<br />"; - } else { - $this->dataRecord['domain'] = $this->dataRecord['domain'] . '.' . $domain_check; - } - } else { - $this->dataRecord["domain"] = $this->dataRecord["domain"].'.'.$parent_domain["domain"]; - } - - - $this->dataRecord['web_folder'] = strtolower($this->dataRecord['web_folder']); - if(substr($this->dataRecord['web_folder'], 0, 1) === '/') $this->dataRecord['web_folder'] = substr($this->dataRecord['web_folder'], 1); - if(substr($this->dataRecord['web_folder'], -1) === '/') $this->dataRecord['web_folder'] = substr($this->dataRecord['web_folder'], 0, -1); - $forbidden_folders = array('', 'cgi-bin', 'log', 'private', 'ssl', 'tmp', 'webdav'); - $check_folder = strtolower($this->dataRecord['web_folder']); - if(substr($check_folder, 0, 1) === '/') $check_folder = substr($check_folder, 1); // strip / at beginning to check against forbidden entries - if(strpos($check_folder, '/') !== false) $check_folder = substr($check_folder, 0, strpos($check_folder, '/')); // get the first part of the path to check it - if(in_array($check_folder, $forbidden_folders)) { - $app->tform->errorMessage .= $app->tform->lng("web_folder_invalid_txt")."<br>"; - } - - // vhostsubdomains do not have a quota of their own - $this->dataRecord["hd_quota"] = 0; - - // check for duplicate folder usage - /* - $check = $app->db->queryOneRecord("SELECT COUNT(*) as `cnt` FROM `web_domain` WHERE `type` = 'vhostsubdomain' AND `parent_domain_id` = '" . $app->functions->intval($this->dataRecord['parent_domain_id']) . "' AND `web_folder` = '" . $app->db->quote($this->dataRecord['web_folder']) . "' AND `domain_id` != '" . $app->functions->intval($this->id) . "'"); - if($check && $check['cnt'] > 0) { - $app->tform->errorMessage .= $app->tform->lng("web_folder_unique_txt")."<br>"; - } - */ - } else { - $this->dataRecord["domain"] = $this->dataRecord["domain"].'.'.$parent_domain["domain"]; - } - - if($_SESSION["s"]["user"]["typ"] != 'admin') { - // Get the limits of the client - $client_group_id = $_SESSION["s"]["user"]["default_group"]; - $client = $app->db->queryOneRecord("SELECT limit_traffic_quota, limit_web_subdomain, default_webserver, parent_client_id, limit_web_quota, client." . implode(", client.", $read_limits) . " FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id"); - - if($client['limit_cgi'] != 'y') $this->dataRecord['cgi'] = '-'; - if($client['limit_ssi'] != 'y') $this->dataRecord['ssi'] = '-'; - if($client['limit_perl'] != 'y') $this->dataRecord['perl'] = '-'; - if($client['limit_ruby'] != 'y') $this->dataRecord['ruby'] = '-'; - if($client['limit_python'] != 'y') $this->dataRecord['python'] = '-'; - if($client['force_suexec'] != 'n') $this->dataRecord['suexec'] = 'y'; - if($client['limit_hterror'] != 'y') $this->dataRecord['errordocs'] = '-'; - if($client['limit_wildcard'] != 'y' && $this->dataRecord['subdomain'] == '*') $this->dataRecord['subdomain'] = '-'; - if($client['limit_ssl'] != 'y') $this->dataRecord['ssl'] = '-'; - - // only generate quota and traffic warnings if value has changed - if($this->id > 0) { - $old_web_values = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".$app->functions->intval($this->id)); - } else { - $old_web_values = $_POST; - } - - //* Check the traffic quota of the client - if(isset($_POST["traffic_quota"]) && $client["limit_traffic_quota"] > 0 && $_POST["traffic_quota"] != $old_web_values["traffic_quota"]) { - $tmp = $app->db->queryOneRecord("SELECT sum(traffic_quota) as trafficquota FROM web_domain WHERE domain_id != ".$app->functions->intval($this->id)." AND ".$app->tform->getAuthSQL('u')); - $trafficquota = $tmp["trafficquota"]; - $new_traffic_quota = $app->functions->intval($this->dataRecord["traffic_quota"]); - if(($trafficquota + $new_traffic_quota > $client["limit_traffic_quota"]) || ($new_traffic_quota < 0 && $client["limit_traffic_quota"] >= 0)) { - $max_free_quota = floor($client["limit_traffic_quota"] - $trafficquota); - if($max_free_quota < 0) $max_free_quota = 0; - $app->tform->errorMessage .= $app->tform->lng("limit_traffic_quota_free_txt").": ".$max_free_quota." MB<br>"; - // Set the quota field to the max free space - $this->dataRecord["traffic_quota"] = $max_free_quota; - } - unset($tmp); - unset($tmp_quota); - } - - if($client['parent_client_id'] > 0) { - // Get the limits of the reseller - $reseller = $app->db->queryOneRecord("SELECT limit_traffic_quota, limit_web_subdomain, default_webserver, limit_web_quota FROM client WHERE client_id = ".$client['parent_client_id']); - - //* Check the traffic quota of the client - if(isset($_POST["traffic_quota"]) && $reseller["limit_traffic_quota"] > 0 && $_POST["traffic_quota"] != $old_web_values["traffic_quota"]) { - $tmp = $app->db->queryOneRecord("SELECT sum(traffic_quota) as trafficquota FROM web_domain WHERE domain_id != ".$app->functions->intval($this->id)." AND ".$app->tform->getAuthSQL('u')); - $trafficquota = $tmp["trafficquota"]; - $new_traffic_quota = $app->functions->intval($this->dataRecord["traffic_quota"]); - if(($trafficquota + $new_traffic_quota > $reseller["limit_traffic_quota"]) || ($new_traffic_quota < 0 && $reseller["limit_traffic_quota"] >= 0)) { - $max_free_quota = floor($reseller["limit_traffic_quota"] - $trafficquota); - if($max_free_quota < 0) $max_free_quota = 0; - $app->tform->errorMessage .= $app->tform->lng("limit_traffic_quota_free_txt").": ".$max_free_quota." MB<br>"; - // Set the quota field to the max free space - $this->dataRecord["traffic_quota"] = $max_free_quota; - } - unset($tmp); - unset($tmp_quota); - } - } - - // When the record is updated - if($this->id > 0) { - // restore the server ID if the user is not admin and record is edited - $tmp = $app->db->queryOneRecord("SELECT server_id, `web_folder`, `cgi`, `ssi`, `perl`, `ruby`, `python`, `suexec`, `errordocs`, `subdomain`, `ssl` FROM web_domain WHERE domain_id = ".$app->functions->intval($this->id)); - $this->dataRecord['web_folder'] = $tmp['web_folder']; // cannot be changed! - - // set the settings to current if not provided (or cleared due to limits) - if($this->dataRecord['cgi'] == '-') $this->dataRecord['cgi'] = $tmp['cgi']; - if($this->dataRecord['ssi'] == '-') $this->dataRecord['ssi'] = $tmp['ssi']; - if($this->dataRecord['perl'] == '-') $this->dataRecord['perl'] = $tmp['perl']; - if($this->dataRecord['ruby'] == '-') $this->dataRecord['ruby'] = $tmp['ruby']; - if($this->dataRecord['python'] == '-') $this->dataRecord['python'] = $tmp['python']; - if($this->dataRecord['suexec'] == '-') $this->dataRecord['suexec'] = $tmp['suexec']; - if($this->dataRecord['errordocs'] == '-') $this->dataRecord['errordocs'] = $tmp['errordocs']; - if($this->dataRecord['subdomain'] == '-') $this->dataRecord['subdomain'] = $tmp['subdomain']; - if($this->dataRecord['ssl'] == '-') $this->dataRecord['ssl'] = $tmp['ssl']; - - unset($tmp); - // When the record is inserted - } else { - // Check if the user may add another web_domain - if($client["limit_web_subdomain"] >= 0) { - $tmp = $app->db->queryOneRecord("SELECT count(domain_id) as number FROM web_domain WHERE sys_groupid = $client_group_id and (type = 'subdomain' OR type = 'vhostsubdomain')"); - if($tmp["number"] >= $client["limit_web_subdomain"]) { - $app->error($app->tform->wordbook["limit_web_subdomain_txt"]); - } - } - } - } - - //* make sure that the domain is lowercase - if(isset($this->dataRecord["domain"])) $this->dataRecord["domain"] = strtolower($this->dataRecord["domain"]); - - //* get the server config for this server - $app->uses("getconf"); - $web_config = $app->getconf->get_server_config($app->functions->intval(isset($this->dataRecord["server_id"]) ? $this->dataRecord["server_id"] : 0),'web'); - //* Check for duplicate ssl certs per IP if SNI is disabled - if(isset($this->dataRecord['ssl']) && $this->dataRecord['ssl'] == 'y' && $web_config['enable_sni'] != 'y') { - $sql = "SELECT count(domain_id) as number FROM web_domain WHERE `ssl` = 'y' AND ip_address = '".$app->db->quote($this->dataRecord['ip_address'])."' and domain_id != ".$this->id; - $tmp = $app->db->queryOneRecord($sql); - if($tmp['number'] > 0) $app->tform->errorMessage .= $app->tform->lng("error_no_sni_txt"); - } - - // Check if pm.max_children >= pm.max_spare_servers >= pm.start_servers >= pm.min_spare_servers > 0 - if(isset($this->dataRecord['pm_max_children']) && $this->dataRecord['pm'] == 'dynamic') { - if($app->functions->intval($this->dataRecord['pm_max_children'], true) >= $app->functions->intval($this->dataRecord['pm_max_spare_servers'], true) && $app->functions->intval($this->dataRecord['pm_max_spare_servers'], true) >= $app->functions->intval($this->dataRecord['pm_start_servers'], true) && $app->functions->intval($this->dataRecord['pm_start_servers'], true) >= $app->functions->intval($this->dataRecord['pm_min_spare_servers'], true) && $app->functions->intval($this->dataRecord['pm_min_spare_servers'], true) > 0){ - - } else { - $app->tform->errorMessage .= $app->tform->lng("error_php_fpm_pm_settings_txt").'<br>'; - } - } - - // Check rewrite rules - $server_type = $web_config['server_type']; - - if($server_type == 'nginx' && isset($this->dataRecord['rewrite_rules']) && trim($this->dataRecord['rewrite_rules']) != '') { - $rewrite_rules = trim($this->dataRecord['rewrite_rules']); - $rewrites_are_valid = true; - // use this counter to make sure all curly brackets are properly closed - $if_level = 0; - // Make sure we only have Unix linebreaks - $rewrite_rules = str_replace("\r\n", "\n", $rewrite_rules); - $rewrite_rules = str_replace("\r", "\n", $rewrite_rules); - $rewrite_rule_lines = explode("\n", $rewrite_rules); - if(is_array($rewrite_rule_lines) && !empty($rewrite_rule_lines)){ - foreach($rewrite_rule_lines as $rewrite_rule_line){ - // ignore comments - if(substr(ltrim($rewrite_rule_line),0,1) == '#') continue; - // empty lines - if(trim($rewrite_rule_line) == '') continue; - // rewrite - if(preg_match('@^\s*rewrite\s+(^/)?\S+(\$)?\s+\S+(\s+(last|break|redirect|permanent|))?\s*;\s*$@', $rewrite_rule_line)) continue; - // if - if(preg_match('@^\s*if\s+\(\s*\$\S+(\s+(\!?(=|~|~\*))\s+(\S+|\".+\"))?\s*\)\s*\{\s*$@', $rewrite_rule_line)){ - $if_level += 1; - continue; - } - // if - check for files, directories, etc. - if(preg_match('@^\s*if\s+\(\s*\!?-(f|d|e|x)\s+\S+\s*\)\s*\{\s*$@', $rewrite_rule_line)){ - $if_level += 1; - continue; - } - // break - if(preg_match('@^\s*break\s*;\s*$@', $rewrite_rule_line)){ - continue; - } - // return code [ text ] - if(preg_match('@^\s*return\s+\d\d\d.*;\s*$@', $rewrite_rule_line)) continue; - // return code URL - // return URL - if(preg_match('@^\s*return(\s+\d\d\d)?\s+(http|https|ftp)\://([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&%\$\-]+)*\@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|localhost|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(\:[0-9]+)*(/($|[a-zA-Z0-9\.\,\?\'\\\+&%\$#\=~_\-]+))*\s*;\s*$@', $rewrite_rule_line)) continue; - // set - if(preg_match('@^\s*set\s+\$\S+\s+\S+\s*;\s*$@', $rewrite_rule_line)) continue; - // closing curly bracket - if(trim($rewrite_rule_line) == '}'){ - $if_level -= 1; - continue; - } - $rewrites_are_valid = false; - break; - } - } - - if(!$rewrites_are_valid || $if_level != 0){ - $app->tform->errorMessage .= $app->tform->lng("invalid_rewrite_rules_txt").'<br>'; - } - } - - parent::onSubmit(); - } - - function onAfterInsert() { - global $app, $conf; - - // Get configuration for the web system - $app->uses("getconf"); - $web_rec = $app->tform->getDataRecord($this->id); - $web_config = $app->getconf->get_server_config($app->functions->intval($web_rec["server_id"]),'web'); - //var_dump($this->parent_domain_record, $web_rec); - // Set the values for document_root, system_user and system_group - $system_user = $app->db->quote($this->parent_domain_record['system_user']); - $system_group = $app->db->quote($this->parent_domain_record['system_group']); - $document_root = $app->db->quote($this->parent_domain_record['document_root']); - $php_open_basedir = str_replace("[website_path]/web",$document_root.'/'.$web_rec['web_folder'],$web_config["php_open_basedir"]); - $php_open_basedir = str_replace("[website_domain]/web",$web_rec['domain'].'/'.$web_rec['web_folder'],$php_open_basedir); - $php_open_basedir = str_replace("[website_path]",$document_root,$php_open_basedir); - $php_open_basedir = $app->db->quote(str_replace("[website_domain]",$web_rec['domain'],$php_open_basedir)); - $htaccess_allow_override = $app->db->quote($this->parent_domain_record['allow_override']); - - $sql = "UPDATE web_domain SET sys_groupid = ".$app->functions->intval($this->parent_domain_record['sys_groupid']).",system_user = '$system_user', system_group = '$system_group', document_root = '$document_root', allow_override = '$htaccess_allow_override', php_open_basedir = '$php_open_basedir' WHERE domain_id = ".$this->id; - $app->db->query($sql); - } - - function onBeforeUpdate () { - global $app, $conf; - - //* Check that all fields for the SSL cert creation are filled - if(isset($this->dataRecord['ssl_action']) && $this->dataRecord['ssl_action'] == 'create') { - if($this->dataRecord['ssl_state'] == '') $app->tform->errorMessage .= $app->tform->lng('error_ssl_state_empty').'<br />'; - if($this->dataRecord['ssl_locality'] == '') $app->tform->errorMessage .= $app->tform->lng('error_ssl_locality_empty').'<br />'; - if($this->dataRecord['ssl_organisation'] == '') $app->tform->errorMessage .= $app->tform->lng('error_ssl_organisation_empty').'<br />'; - if($this->dataRecord['ssl_organisation_unit'] == '') $app->tform->errorMessage .= $app->tform->lng('error_ssl_organisation_unit_empty').'<br />'; - if($this->dataRecord['ssl_country'] == '') $app->tform->errorMessage .= $app->tform->lng('error_ssl_country_empty').'<br />'; - } - - if(isset($this->dataRecord['ssl_action']) && $this->dataRecord['ssl_action'] == 'save') { - if(trim($this->dataRecord['ssl_cert']) == '') $app->tform->errorMessage .= $app->tform->lng('error_ssl_cert_empty').'<br />'; - } - - } - - function onAfterUpdate() { - global $app, $conf; - - // Get configuration for the web system - $app->uses("getconf"); - $web_rec = $app->tform->getDataRecord($this->id); - $web_config = $app->getconf->get_server_config($app->functions->intval($web_rec["server_id"]),'web'); - - // Set the values for document_root, system_user and system_group - $system_user = $app->db->quote($this->parent_domain_record['system_user']); - $system_group = $app->db->quote($this->parent_domain_record['system_group']); - $document_root = $app->db->quote($this->parent_domain_record['document_root']); - $php_open_basedir = str_replace("[website_path]/web",$document_root.'/'.$web_rec['web_folder'],$web_config["php_open_basedir"]); - $php_open_basedir = str_replace("[website_domain]/web",$web_rec['domain'].'/'.$web_rec['web_folder'],$php_open_basedir); - $php_open_basedir = str_replace("[website_path]",$document_root,$php_open_basedir); - $php_open_basedir = $app->db->quote(str_replace("[website_domain]",$web_rec['domain'],$php_open_basedir)); - $htaccess_allow_override = $app->db->quote($this->parent_domain_record['allow_override']); - - $sql = "UPDATE web_domain SET sys_groupid = ".$app->functions->intval($this->parent_domain_record['sys_groupid']).",system_user = '$system_user', system_group = '$system_group', document_root = '$document_root', allow_override = '$htaccess_allow_override', php_open_basedir = '$php_open_basedir' WHERE domain_id = ".$this->id; - $app->db->query($sql); - } - -} - -$page = new page_action; -$page->onLoad(); - +<?php +/* +Copyright (c) 2007 - 2009, Till Brehm, projektfarm Gmbh +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of ISPConfig nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +/****************************************** +* Begin Form configuration +******************************************/ + +$tform_def_file = "form/web_vhost_subdomain.tform.php"; + +/****************************************** +* End Form configuration +******************************************/ + +require_once('../../lib/config.inc.php'); +require_once('../../lib/app.inc.php'); + +//* Check permissions for module +$app->auth->check_module_permissions('sites'); + +// Loading classes +$app->uses('tpl,tform,tform_actions,tools_sites'); +$app->load('tform_actions'); + +class page_action extends tform_actions { + + //* Returna a "3/2/1" path hash from a numeric id '123' + function id_hash($id,$levels) { + $hash = "" . $id % 10 ; + $id /= 10 ; + $levels -- ; + while ( $levels > 0 ) { + $hash .= "/" . $id % 10 ; + $id /= 10 ; + $levels-- ; + } + return $hash; + } + + function onShowNew() { + global $app, $conf; + + // we will check only users, not admins + if($_SESSION["s"]["user"]["typ"] == 'user') { + if(!$app->tform->checkClientLimit('limit_web_subdomain',"(type = 'subdomain' OR type = 'vhostsubdomain')")) { + $app->error($app->tform->wordbook["limit_web_subdomain_txt"]); + } + if(!$app->tform->checkResellerLimit('limit_web_subdomain',"(type = 'subdomain' OR type = 'vhostsubdomain')")) { + $app->error('Reseller: '.$app->tform->wordbook["limit_web_subdomain_txt"]); + } + } + parent::onShowNew(); + } + + function onShowEnd() { + global $app, $conf; + + $app->uses('ini_parser,getconf'); + + $read_limits = array('limit_cgi', 'limit_ssi', 'limit_perl', 'limit_ruby', 'limit_python', 'force_suexec', 'limit_hterror', 'limit_wildcard', 'limit_ssl'); + + $parent_domain = $app->db->queryOneRecord("select * FROM web_domain WHERE domain_id = ".$app->functions->intval(@$this->dataRecord["parent_domain_id"])); + + //* Client: If the logged in user is not admin and has no sub clients (no reseller) + if($_SESSION["s"]["user"]["typ"] != 'admin' && !$app->auth->has_clients($_SESSION['s']['user']['userid'])) { + + // Get the limits of the client + $client_group_id = $_SESSION["s"]["user"]["default_group"]; + $client = $app->db->queryOneRecord("SELECT client.limit_web_subdomain, client.default_webserver, client." . implode(", client.", $read_limits) . " FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id"); + + //* Get global web config + $web_config = $app->getconf->get_server_config($parent_domain['server_id'], 'web'); + + //PHP Version Selection (FastCGI) + $server_type = 'apache'; + if(!empty($web_config['server_type'])) $server_type = $web_config['server_type']; + if($server_type == 'nginx' && $this->dataRecord['php'] == 'fast-cgi') $this->dataRecord['php'] = 'php-fpm'; + if($this->dataRecord['php'] == 'php-fpm'){ + $php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fpm_init_script != '' AND php_fpm_ini_dir != '' AND php_fpm_pool_dir != '' AND server_id = ".$parent_domain['server_id']." AND (client_id = 0 OR client_id=".$_SESSION['s']['user']['client_id'].")"); + } + if($this->dataRecord['php'] == 'fast-cgi'){ + $php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fastcgi_binary != '' AND php_fastcgi_ini_dir != '' AND server_id = ".$parent_domain['server_id']." AND (client_id = 0 OR client_id=".$_SESSION['s']['user']['client_id'].")"); + } + $php_select = "<option value=''>Default</option>"; + if(is_array($php_records) && !empty($php_records)) { + foreach( $php_records as $php_record) { + if($this->dataRecord['php'] == 'php-fpm'){ + $php_version = $php_record['name'].':'.$php_record['php_fpm_init_script'].':'.$php_record['php_fpm_ini_dir'].':'.$php_record['php_fpm_pool_dir']; + } else { + $php_version = $php_record['name'].':'.$php_record['php_fastcgi_binary'].':'.$php_record['php_fastcgi_ini_dir']; + } + $selected = ($php_version == $this->dataRecord["fastcgi_php_version"])?'SELECTED':''; + $php_select .= "<option value='$php_version' $selected>".$php_record['name']."</option>\r\n"; + } + } + $app->tpl->setVar("fastcgi_php_version",$php_select); + unset($php_records); + + // add limits to template to be able to hide settings + foreach($read_limits as $limit) $app->tpl->setVar($limit, $client[$limit]); + + + //* Reseller: If the logged in user is not admin and has sub clients (is a reseller) + } elseif ($_SESSION["s"]["user"]["typ"] != 'admin' && $app->auth->has_clients($_SESSION['s']['user']['userid'])) { + + // Get the limits of the client + $client_group_id = $_SESSION["s"]["user"]["default_group"]; + $client = $app->db->queryOneRecord("SELECT client.client_id, client.limit_web_subdomain, client.default_webserver, client.contact_name, CONCAT(IF(client.company_name != '', CONCAT(client.company_name, ' :: '), ''), client.contact_name, ' (', client.username, IF(client.customer_no != '', CONCAT(', ', client.customer_no), ''), ')') as contactname, sys_group.name, client." . implode(", client.", $read_limits) . " FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id"); + + //* Get global web config + $web_config = $app->getconf->get_server_config($parent_domain['server_id'], 'web'); + + //PHP Version Selection (FastCGI) + $server_type = 'apache'; + if(!empty($web_config['server_type'])) $server_type = $web_config['server_type']; + if($server_type == 'nginx' && $this->dataRecord['php'] == 'fast-cgi') $this->dataRecord['php'] = 'php-fpm'; + if($this->dataRecord['php'] == 'php-fpm'){ + $php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fpm_init_script != '' AND php_fpm_ini_dir != '' AND php_fpm_pool_dir != '' AND server_id = ".$parent_domain['server_id']." AND (client_id = 0 OR client_id=".$_SESSION['s']['user']['client_id'].")"); + } + if($this->dataRecord['php'] == 'fast-cgi') { + $php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fastcgi_binary != '' AND php_fastcgi_ini_dir != '' AND server_id = ".$parent_domain['server_id']." AND (client_id = 0 OR client_id=".$_SESSION['s']['user']['client_id'].")"); + } + $php_select = "<option value=''>Default</option>"; + if(is_array($php_records) && !empty($php_records)) { + foreach( $php_records as $php_record) { + if($this->dataRecord['php'] == 'php-fpm'){ + $php_version = $php_record['name'].':'.$php_record['php_fpm_init_script'].':'.$php_record['php_fpm_ini_dir'].':'.$php_record['php_fpm_pool_dir']; + } else { + $php_version = $php_record['name'].':'.$php_record['php_fastcgi_binary'].':'.$php_record['php_fastcgi_ini_dir']; + } + $selected = ($php_version == $this->dataRecord["fastcgi_php_version"])?'SELECTED':''; + $php_select .= "<option value='$php_version' $selected>".$php_record['name']."</option>\r\n"; + } + } + $app->tpl->setVar("fastcgi_php_version",$php_select); + unset($php_records); + + // add limits to template to be able to hide settings + foreach($read_limits as $limit) $app->tpl->setVar($limit, $client[$limit]); + + + //* Admin: If the logged in user is admin + } else { + + //* get global web config + $web_config = $app->getconf->get_server_config($parent_domain['server_id'], 'web'); + + //PHP Version Selection (FastCGI) + $server_type = 'apache'; + if(!empty($web_config['server_type'])) $server_type = $web_config['server_type']; + if($server_type == 'nginx' && $this->dataRecord['php'] == 'fast-cgi') $this->dataRecord['php'] = 'php-fpm'; + if($this->dataRecord['php'] == 'php-fpm'){ + $php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fpm_init_script != '' AND php_fpm_ini_dir != '' AND php_fpm_pool_dir != '' AND server_id = " . $parent_domain['server_id']); + } + if($this->dataRecord['php'] == 'fast-cgi') { + $php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fastcgi_binary != '' AND php_fastcgi_ini_dir != '' AND server_id = " . $parent_domain['server_id']); + } + $php_select = "<option value=''>Default</option>"; + if(is_array($php_records) && !empty($php_records)) { + foreach( $php_records as $php_record) { + if($this->dataRecord['php'] == 'php-fpm'){ + $php_version = $php_record['name'].':'.$php_record['php_fpm_init_script'].':'.$php_record['php_fpm_ini_dir'].':'.$php_record['php_fpm_pool_dir']; + } else { + $php_version = $php_record['name'].':'.$php_record['php_fastcgi_binary'].':'.$php_record['php_fastcgi_ini_dir']; + } + $selected = ($php_version == $this->dataRecord["fastcgi_php_version"])?'SELECTED':''; + $php_select .= "<option value='$php_version' $selected>".$php_record['name']."</option>\r\n"; + } + } + $app->tpl->setVar("fastcgi_php_version",$php_select); + unset($php_records); + + foreach($read_limits as $limit) $app->tpl->setVar($limit, ($limit == 'force_suexec' ? 'n' : 'y')); + + // Directive Snippets + $php_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'php' AND active = 'y'"); + $php_directive_snippets_txt = ''; + if(is_array($php_directive_snippets) && !empty($php_directive_snippets)){ + foreach($php_directive_snippets as $php_directive_snippet){ + $php_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$php_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.$php_directive_snippet['snippet'].'</pre></a> '; + } + } + if($php_directive_snippets_txt == '') $php_directive_snippets_txt = '------'; + $app->tpl->setVar("php_directive_snippets_txt",$php_directive_snippets_txt); + + if($server_type == 'apache'){ + $apache_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'apache' AND active = 'y'"); + $apache_directive_snippets_txt = ''; + if(is_array($apache_directive_snippets) && !empty($apache_directive_snippets)){ + foreach($apache_directive_snippets as $apache_directive_snippet){ + $apache_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$apache_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.$apache_directive_snippet['snippet'].'</pre></a> '; + } + } + if($apache_directive_snippets_txt == '') $apache_directive_snippets_txt = '------'; + $app->tpl->setVar("apache_directive_snippets_txt",$apache_directive_snippets_txt); + } + + if($server_type == 'nginx'){ + $nginx_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'nginx' AND active = 'y'"); + $nginx_directive_snippets_txt = ''; + if(is_array($nginx_directive_snippets) && !empty($nginx_directive_snippets)){ + foreach($nginx_directive_snippets as $nginx_directive_snippet){ + $nginx_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$nginx_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.$nginx_directive_snippet['snippet'].'</pre></a> '; + } + } + if($nginx_directive_snippets_txt == '') $nginx_directive_snippets_txt = '------'; + $app->tpl->setVar("nginx_directive_snippets_txt",$nginx_directive_snippets_txt); + } + + $proxy_directive_snippets = $app->db->queryAllRecords("SELECT * FROM directive_snippets WHERE type = 'proxy' AND active = 'y'"); + $proxy_directive_snippets_txt = ''; + if(is_array($proxy_directive_snippets) && !empty($proxy_directive_snippets)){ + foreach($proxy_directive_snippets as $proxy_directive_snippet){ + $proxy_directive_snippets_txt .= '<a href="javascript:void(0);" class="addPlaceholderContent">['.$proxy_directive_snippet['name'].']<pre class="addPlaceholderContent" style="display:none;">'.$proxy_directive_snippet['snippet'].'</pre></a> '; + } + } + if($proxy_directive_snippets_txt == '') $proxy_directive_snippets_txt = '------'; + $app->tpl->setVar("proxy_directive_snippets_txt",$proxy_directive_snippets_txt); + } + + $ssl_domain_select = ''; + $tmp = $app->db->queryOneRecord("SELECT domain FROM web_domain WHERE domain_id = ".$this->id); + $ssl_domains = array($tmp["domain"],'www.'.$tmp["domain"]); + if(is_array($ssl_domains)) { + foreach( $ssl_domains as $ssl_domain) { + $selected = ($ssl_domain == $this->dataRecord['ssl_domain'])?'SELECTED':''; + $ssl_domain_select .= "<option value='$ssl_domain' $selected>$ssl_domain</option>\r\n"; + } + } + + if($this->id > 0) { + $app->tpl->setVar('fixed_folder', 'y'); + $app->tpl->setVar('server_id_value', $parent_domain['server_id']); + } else { + $app->tpl->setVar('fixed_folder', 'n'); + $app->tpl->setVar('server_id_value', $parent_domain['server_id']); + } + + $app->tpl->setVar("ssl_domain",$ssl_domain_select); + unset($ssl_domain_select); + unset($ssl_domains); + unset($ssl_domain); + + $tmp_txt = ($this->dataRecord['traffic_quota_lock'] == 'y')?'<b>('.$app->tform->lng('traffic_quota_exceeded_txt').')</b>':''; + $app->tpl->setVar("traffic_quota_exceeded_txt", $tmp_txt); + + + $app->uses('ini_parser,getconf'); + $settings = $app->getconf->get_global_config('domains'); + if ($settings['use_domain_module'] == 'y') { + /* + * The domain-module is in use. + */ + $domains = $app->tools_sites->getDomainModuleDomains(); + $domain_select = ''; + $selected_domain = ''; + if(is_array($domains) && sizeof($domains) > 0) { + /* We have domains in the list, so create the drop-down-list */ + foreach( $domains as $domain) { + $domain_select .= "<option value=" . $domain['domain_id'] ; + if ('.' . $domain['domain'] == substr($this->dataRecord["domain"], -strlen($domain['domain']) - 1)) { + $domain_select .= " selected"; + $selected_domain = $domain['domain']; + } + $domain_select .= ">" . $app->functions->idn_decode($domain['domain']) . "</option>\r\n"; + } + } + else { + /* + * We have no domains in the domain-list. This means, we can not add ANY new domain. + * To avoid, that the variable "domain_option" is empty and so the user can + * free enter a domain, we have to create a empty option! + */ + $domain_select .= "<option value=''></option>\r\n"; + } + $app->tpl->setVar("domain_option",$domain_select); + $this->dataRecord['domain'] = substr($this->dataRecord["domain"], 0, strlen($this->dataRecord['domain']) - strlen($selected_domain) - 1); + } else { + + // remove the parent domain part of the domain name before we show it in the text field. + $this->dataRecord["domain"] = str_replace('.'.$parent_domain["domain"],'',$this->dataRecord["domain"]); + } + $app->tpl->setVar("domain",$this->dataRecord["domain"]); + + parent::onShowEnd(); + } + + function onSubmit() { + global $app, $conf; + + // Get the record of the parent domain + if(!@$this->dataRecord["parent_domain_id"] && $this->id) { + $tmp = $app->db->queryOneRecord("SELECT parent_domain_id FROM web_domain WHERE domain_id = ".$app->functions->intval($this->id)); + if($tmp) $this->dataRecord["parent_domain_id"] = $tmp['parent_domain_id']; + unset($tmp); + } + + $parent_domain = $app->db->queryOneRecord("select * FROM web_domain WHERE domain_id = ".$app->functions->intval(@$this->dataRecord["parent_domain_id"]) . " AND ".$app->tform->getAuthSQL('r')); + if(!$parent_domain || $parent_domain['domain_id'] != @$this->dataRecord['parent_domain_id']) $app->tform->errorMessage .= $app->tform->lng("no_domain_perm"); + + // Set a few fixed values + $this->dataRecord["type"] = 'vhostsubdomain'; + $this->dataRecord["server_id"] = $parent_domain["server_id"]; + $this->dataRecord["ip_address"] = $parent_domain["ip_address"]; + $this->dataRecord["ipv6_address"] = $parent_domain["ipv6_address"]; + $this->dataRecord["client_group_id"] = $parent_domain["client_group_id"]; + $this->dataRecord["vhost_type"] = 'name'; + + $this->parent_domain_record = $parent_domain; + + $read_limits = array('limit_cgi', 'limit_ssi', 'limit_perl', 'limit_ruby', 'limit_python', 'force_suexec', 'limit_hterror', 'limit_wildcard', 'limit_ssl'); + + if($app->tform->getCurrentTab() == 'domain') { + + /* check if the domain module is used - and check if the selected domain can be used! */ + $app->uses('ini_parser,getconf'); + $settings = $app->getconf->get_global_config('domains'); + if ($settings['use_domain_module'] == 'y') { + $domain_check = $app->tools_sites->checkDomainModuleDomain($this->dataRecord['sel_domain']); + if(!$domain_check) { + // invalid domain selected + $app->tform->errorMessage .= $app->tform->lng("domain_error_empty")."<br />"; + } else { + $this->dataRecord['domain'] = $this->dataRecord['domain'] . '.' . $domain_check; + } + } else { + $this->dataRecord["domain"] = $this->dataRecord["domain"].'.'.$parent_domain["domain"]; + } + + + $this->dataRecord['web_folder'] = strtolower($this->dataRecord['web_folder']); + if(substr($this->dataRecord['web_folder'], 0, 1) === '/') $this->dataRecord['web_folder'] = substr($this->dataRecord['web_folder'], 1); + if(substr($this->dataRecord['web_folder'], -1) === '/') $this->dataRecord['web_folder'] = substr($this->dataRecord['web_folder'], 0, -1); + $forbidden_folders = array('', 'cgi-bin', 'log', 'private', 'ssl', 'tmp', 'webdav'); + $check_folder = strtolower($this->dataRecord['web_folder']); + if(substr($check_folder, 0, 1) === '/') $check_folder = substr($check_folder, 1); // strip / at beginning to check against forbidden entries + if(strpos($check_folder, '/') !== false) $check_folder = substr($check_folder, 0, strpos($check_folder, '/')); // get the first part of the path to check it + if(in_array($check_folder, $forbidden_folders)) { + $app->tform->errorMessage .= $app->tform->lng("web_folder_invalid_txt")."<br>"; + } + + // vhostsubdomains do not have a quota of their own + $this->dataRecord["hd_quota"] = 0; + + // check for duplicate folder usage + /* + $check = $app->db->queryOneRecord("SELECT COUNT(*) as `cnt` FROM `web_domain` WHERE `type` = 'vhostsubdomain' AND `parent_domain_id` = '" . $app->functions->intval($this->dataRecord['parent_domain_id']) . "' AND `web_folder` = '" . $app->db->quote($this->dataRecord['web_folder']) . "' AND `domain_id` != '" . $app->functions->intval($this->id) . "'"); + if($check && $check['cnt'] > 0) { + $app->tform->errorMessage .= $app->tform->lng("web_folder_unique_txt")."<br>"; + } + */ + } else { + $this->dataRecord["domain"] = $this->dataRecord["domain"].'.'.$parent_domain["domain"]; + } + + if($_SESSION["s"]["user"]["typ"] != 'admin') { + // Get the limits of the client + $client_group_id = $_SESSION["s"]["user"]["default_group"]; + $client = $app->db->queryOneRecord("SELECT limit_traffic_quota, limit_web_subdomain, default_webserver, parent_client_id, limit_web_quota, client." . implode(", client.", $read_limits) . " FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $client_group_id"); + + if($client['limit_cgi'] != 'y') $this->dataRecord['cgi'] = '-'; + if($client['limit_ssi'] != 'y') $this->dataRecord['ssi'] = '-'; + if($client['limit_perl'] != 'y') $this->dataRecord['perl'] = '-'; + if($client['limit_ruby'] != 'y') $this->dataRecord['ruby'] = '-'; + if($client['limit_python'] != 'y') $this->dataRecord['python'] = '-'; + if($client['force_suexec'] != 'n') $this->dataRecord['suexec'] = 'y'; + if($client['limit_hterror'] != 'y') $this->dataRecord['errordocs'] = '-'; + if($client['limit_wildcard'] != 'y' && $this->dataRecord['subdomain'] == '*') $this->dataRecord['subdomain'] = '-'; + if($client['limit_ssl'] != 'y') $this->dataRecord['ssl'] = '-'; + + // only generate quota and traffic warnings if value has changed + if($this->id > 0) { + $old_web_values = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".$app->functions->intval($this->id)); + } else { + $old_web_values = $_POST; + } + + //* Check the traffic quota of the client + if(isset($_POST["traffic_quota"]) && $client["limit_traffic_quota"] > 0 && $_POST["traffic_quota"] != $old_web_values["traffic_quota"]) { + $tmp = $app->db->queryOneRecord("SELECT sum(traffic_quota) as trafficquota FROM web_domain WHERE domain_id != ".$app->functions->intval($this->id)." AND ".$app->tform->getAuthSQL('u')); + $trafficquota = $tmp["trafficquota"]; + $new_traffic_quota = $app->functions->intval($this->dataRecord["traffic_quota"]); + if(($trafficquota + $new_traffic_quota > $client["limit_traffic_quota"]) || ($new_traffic_quota < 0 && $client["limit_traffic_quota"] >= 0)) { + $max_free_quota = floor($client["limit_traffic_quota"] - $trafficquota); + if($max_free_quota < 0) $max_free_quota = 0; + $app->tform->errorMessage .= $app->tform->lng("limit_traffic_quota_free_txt").": ".$max_free_quota." MB<br>"; + // Set the quota field to the max free space + $this->dataRecord["traffic_quota"] = $max_free_quota; + } + unset($tmp); + unset($tmp_quota); + } + + if($client['parent_client_id'] > 0) { + // Get the limits of the reseller + $reseller = $app->db->queryOneRecord("SELECT limit_traffic_quota, limit_web_subdomain, default_webserver, limit_web_quota FROM client WHERE client_id = ".$client['parent_client_id']); + + //* Check the traffic quota of the client + if(isset($_POST["traffic_quota"]) && $reseller["limit_traffic_quota"] > 0 && $_POST["traffic_quota"] != $old_web_values["traffic_quota"]) { + $tmp = $app->db->queryOneRecord("SELECT sum(traffic_quota) as trafficquota FROM web_domain WHERE domain_id != ".$app->functions->intval($this->id)." AND ".$app->tform->getAuthSQL('u')); + $trafficquota = $tmp["trafficquota"]; + $new_traffic_quota = $app->functions->intval($this->dataRecord["traffic_quota"]); + if(($trafficquota + $new_traffic_quota > $reseller["limit_traffic_quota"]) || ($new_traffic_quota < 0 && $reseller["limit_traffic_quota"] >= 0)) { + $max_free_quota = floor($reseller["limit_traffic_quota"] - $trafficquota); + if($max_free_quota < 0) $max_free_quota = 0; + $app->tform->errorMessage .= $app->tform->lng("limit_traffic_quota_free_txt").": ".$max_free_quota." MB<br>"; + // Set the quota field to the max free space + $this->dataRecord["traffic_quota"] = $max_free_quota; + } + unset($tmp); + unset($tmp_quota); + } + } + + // When the record is updated + if($this->id > 0) { + // restore the server ID if the user is not admin and record is edited + $tmp = $app->db->queryOneRecord("SELECT server_id, `web_folder`, `cgi`, `ssi`, `perl`, `ruby`, `python`, `suexec`, `errordocs`, `subdomain`, `ssl` FROM web_domain WHERE domain_id = ".$app->functions->intval($this->id)); + $this->dataRecord['web_folder'] = $tmp['web_folder']; // cannot be changed! + + // set the settings to current if not provided (or cleared due to limits) + if($this->dataRecord['cgi'] == '-') $this->dataRecord['cgi'] = $tmp['cgi']; + if($this->dataRecord['ssi'] == '-') $this->dataRecord['ssi'] = $tmp['ssi']; + if($this->dataRecord['perl'] == '-') $this->dataRecord['perl'] = $tmp['perl']; + if($this->dataRecord['ruby'] == '-') $this->dataRecord['ruby'] = $tmp['ruby']; + if($this->dataRecord['python'] == '-') $this->dataRecord['python'] = $tmp['python']; + if($this->dataRecord['suexec'] == '-') $this->dataRecord['suexec'] = $tmp['suexec']; + if($this->dataRecord['errordocs'] == '-') $this->dataRecord['errordocs'] = $tmp['errordocs']; + if($this->dataRecord['subdomain'] == '-') $this->dataRecord['subdomain'] = $tmp['subdomain']; + if($this->dataRecord['ssl'] == '-') $this->dataRecord['ssl'] = $tmp['ssl']; + + unset($tmp); + // When the record is inserted + } else { + // Check if the user may add another web_domain + if($client["limit_web_subdomain"] >= 0) { + $tmp = $app->db->queryOneRecord("SELECT count(domain_id) as number FROM web_domain WHERE sys_groupid = $client_group_id and (type = 'subdomain' OR type = 'vhostsubdomain')"); + if($tmp["number"] >= $client["limit_web_subdomain"]) { + $app->error($app->tform->wordbook["limit_web_subdomain_txt"]); + } + } + } + } + + //* make sure that the domain is lowercase + if(isset($this->dataRecord["domain"])) $this->dataRecord["domain"] = strtolower($this->dataRecord["domain"]); + + //* get the server config for this server + $app->uses("getconf"); + $web_config = $app->getconf->get_server_config($app->functions->intval(isset($this->dataRecord["server_id"]) ? $this->dataRecord["server_id"] : 0),'web'); + //* Check for duplicate ssl certs per IP if SNI is disabled + if(isset($this->dataRecord['ssl']) && $this->dataRecord['ssl'] == 'y' && $web_config['enable_sni'] != 'y') { + $sql = "SELECT count(domain_id) as number FROM web_domain WHERE `ssl` = 'y' AND ip_address = '".$app->db->quote($this->dataRecord['ip_address'])."' and domain_id != ".$this->id; + $tmp = $app->db->queryOneRecord($sql); + if($tmp['number'] > 0) $app->tform->errorMessage .= $app->tform->lng("error_no_sni_txt"); + } + + // Check if pm.max_children >= pm.max_spare_servers >= pm.start_servers >= pm.min_spare_servers > 0 + if(isset($this->dataRecord['pm_max_children']) && $this->dataRecord['pm'] == 'dynamic') { + if($app->functions->intval($this->dataRecord['pm_max_children'], true) >= $app->functions->intval($this->dataRecord['pm_max_spare_servers'], true) && $app->functions->intval($this->dataRecord['pm_max_spare_servers'], true) >= $app->functions->intval($this->dataRecord['pm_start_servers'], true) && $app->functions->intval($this->dataRecord['pm_start_servers'], true) >= $app->functions->intval($this->dataRecord['pm_min_spare_servers'], true) && $app->functions->intval($this->dataRecord['pm_min_spare_servers'], true) > 0){ + + } else { + $app->tform->errorMessage .= $app->tform->lng("error_php_fpm_pm_settings_txt").'<br>'; + } + } + + // Check rewrite rules + $server_type = $web_config['server_type']; + + if($server_type == 'nginx' && isset($this->dataRecord['rewrite_rules']) && trim($this->dataRecord['rewrite_rules']) != '') { + $rewrite_rules = trim($this->dataRecord['rewrite_rules']); + $rewrites_are_valid = true; + // use this counter to make sure all curly brackets are properly closed + $if_level = 0; + // Make sure we only have Unix linebreaks + $rewrite_rules = str_replace("\r\n", "\n", $rewrite_rules); + $rewrite_rules = str_replace("\r", "\n", $rewrite_rules); + $rewrite_rule_lines = explode("\n", $rewrite_rules); + if(is_array($rewrite_rule_lines) && !empty($rewrite_rule_lines)){ + foreach($rewrite_rule_lines as $rewrite_rule_line){ + // ignore comments + if(substr(ltrim($rewrite_rule_line),0,1) == '#') continue; + // empty lines + if(trim($rewrite_rule_line) == '') continue; + // rewrite + if(preg_match('@^\s*rewrite\s+(^/)?\S+(\$)?\s+\S+(\s+(last|break|redirect|permanent|))?\s*;\s*$@', $rewrite_rule_line)) continue; + // if + if(preg_match('@^\s*if\s+\(\s*\$\S+(\s+(\!?(=|~|~\*))\s+(\S+|\".+\"))?\s*\)\s*\{\s*$@', $rewrite_rule_line)){ + $if_level += 1; + continue; + } + // if - check for files, directories, etc. + if(preg_match('@^\s*if\s+\(\s*\!?-(f|d|e|x)\s+\S+\s*\)\s*\{\s*$@', $rewrite_rule_line)){ + $if_level += 1; + continue; + } + // break + if(preg_match('@^\s*break\s*;\s*$@', $rewrite_rule_line)){ + continue; + } + // return code [ text ] + if(preg_match('@^\s*return\s+\d\d\d.*;\s*$@', $rewrite_rule_line)) continue; + // return code URL + // return URL + if(preg_match('@^\s*return(\s+\d\d\d)?\s+(http|https|ftp)\://([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&%\$\-]+)*\@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|localhost|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(\:[0-9]+)*(/($|[a-zA-Z0-9\.\,\?\'\\\+&%\$#\=~_\-]+))*\s*;\s*$@', $rewrite_rule_line)) continue; + // set + if(preg_match('@^\s*set\s+\$\S+\s+\S+\s*;\s*$@', $rewrite_rule_line)) continue; + // closing curly bracket + if(trim($rewrite_rule_line) == '}'){ + $if_level -= 1; + continue; + } + $rewrites_are_valid = false; + break; + } + } + + if(!$rewrites_are_valid || $if_level != 0){ + $app->tform->errorMessage .= $app->tform->lng("invalid_rewrite_rules_txt").'<br>'; + } + } + + parent::onSubmit(); + } + + function onAfterInsert() { + global $app, $conf; + + // Get configuration for the web system + $app->uses("getconf"); + $web_rec = $app->tform->getDataRecord($this->id); + $web_config = $app->getconf->get_server_config($app->functions->intval($web_rec["server_id"]),'web'); + //var_dump($this->parent_domain_record, $web_rec); + // Set the values for document_root, system_user and system_group + $system_user = $app->db->quote($this->parent_domain_record['system_user']); + $system_group = $app->db->quote($this->parent_domain_record['system_group']); + $document_root = $app->db->quote($this->parent_domain_record['document_root']); + $php_open_basedir = str_replace("[website_path]/web",$document_root.'/'.$web_rec['web_folder'],$web_config["php_open_basedir"]); + $php_open_basedir = str_replace("[website_domain]/web",$web_rec['domain'].'/'.$web_rec['web_folder'],$php_open_basedir); + $php_open_basedir = str_replace("[website_path]",$document_root,$php_open_basedir); + $php_open_basedir = $app->db->quote(str_replace("[website_domain]",$web_rec['domain'],$php_open_basedir)); + $htaccess_allow_override = $app->db->quote($this->parent_domain_record['allow_override']); + + $sql = "UPDATE web_domain SET sys_groupid = ".$app->functions->intval($this->parent_domain_record['sys_groupid']).",system_user = '$system_user', system_group = '$system_group', document_root = '$document_root', allow_override = '$htaccess_allow_override', php_open_basedir = '$php_open_basedir' WHERE domain_id = ".$this->id; + $app->db->query($sql); + } + + function onBeforeUpdate () { + global $app, $conf; + + //* Check that all fields for the SSL cert creation are filled + if(isset($this->dataRecord['ssl_action']) && $this->dataRecord['ssl_action'] == 'create') { + if($this->dataRecord['ssl_state'] == '') $app->tform->errorMessage .= $app->tform->lng('error_ssl_state_empty').'<br />'; + if($this->dataRecord['ssl_locality'] == '') $app->tform->errorMessage .= $app->tform->lng('error_ssl_locality_empty').'<br />'; + if($this->dataRecord['ssl_organisation'] == '') $app->tform->errorMessage .= $app->tform->lng('error_ssl_organisation_empty').'<br />'; + if($this->dataRecord['ssl_organisation_unit'] == '') $app->tform->errorMessage .= $app->tform->lng('error_ssl_organisation_unit_empty').'<br />'; + if($this->dataRecord['ssl_country'] == '') $app->tform->errorMessage .= $app->tform->lng('error_ssl_country_empty').'<br />'; + } + + if(isset($this->dataRecord['ssl_action']) && $this->dataRecord['ssl_action'] == 'save') { + if(trim($this->dataRecord['ssl_cert']) == '') $app->tform->errorMessage .= $app->tform->lng('error_ssl_cert_empty').'<br />'; + } + + } + + function onAfterUpdate() { + global $app, $conf; + + // Get configuration for the web system + $app->uses("getconf"); + $web_rec = $app->tform->getDataRecord($this->id); + $web_config = $app->getconf->get_server_config($app->functions->intval($web_rec["server_id"]),'web'); + + // Set the values for document_root, system_user and system_group + $system_user = $app->db->quote($this->parent_domain_record['system_user']); + $system_group = $app->db->quote($this->parent_domain_record['system_group']); + $document_root = $app->db->quote($this->parent_domain_record['document_root']); + $php_open_basedir = str_replace("[website_path]/web",$document_root.'/'.$web_rec['web_folder'],$web_config["php_open_basedir"]); + $php_open_basedir = str_replace("[website_domain]/web",$web_rec['domain'].'/'.$web_rec['web_folder'],$php_open_basedir); + $php_open_basedir = str_replace("[website_path]",$document_root,$php_open_basedir); + $php_open_basedir = $app->db->quote(str_replace("[website_domain]",$web_rec['domain'],$php_open_basedir)); + $htaccess_allow_override = $app->db->quote($this->parent_domain_record['allow_override']); + + $sql = "UPDATE web_domain SET sys_groupid = ".$app->functions->intval($this->parent_domain_record['sys_groupid']).",system_user = '$system_user', system_group = '$system_group', document_root = '$document_root', allow_override = '$htaccess_allow_override', php_open_basedir = '$php_open_basedir' WHERE domain_id = ".$this->id; + $app->db->query($sql); + } + +} + +$page = new page_action; +$page->onLoad(); + ?> \ No newline at end of file diff --git a/interface/web/themes/default-304/css/screen/redmond/jquery-ui-1.8.16.custom.css b/interface/web/themes/default-304/css/screen/redmond/jquery-ui-1.8.16.custom.css index 88353fe6a8df26718f7db109ad8f833629517295..e3e05d1d9ee93d5720023297afea0e4028db2061 100644 --- a/interface/web/themes/default-304/css/screen/redmond/jquery-ui-1.8.16.custom.css +++ b/interface/web/themes/default-304/css/screen/redmond/jquery-ui-1.8.16.custom.css @@ -1,444 +1,444 @@ -/* - * jQuery UI CSS Framework 1.8.16 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Theming/API - */ - -/* Layout helpers -----------------------------------*/ -.ui-helper-hidden { display: none; } -.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); } -.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } -.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } -.ui-helper-clearfix { display: inline-block; } -/* required comment for clearfix to work in Opera \*/ -* html .ui-helper-clearfix { height:1%; } -.ui-helper-clearfix { display:block; } -/* end clearfix */ -.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } - - -/* Interaction Cues -----------------------------------*/ -.ui-state-disabled { cursor: default !important; } - - -/* Icons -----------------------------------*/ - -/* states and images */ -.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } - - -/* Misc visuals -----------------------------------*/ - -/* Overlays */ -.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } - - -/* - * jQuery UI CSS Framework 1.8.16 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Theming/API - * - * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Lucida%20Grande,%20Lucida%20Sans,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=0px&bgColorHeader=5c9ccc&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=55&borderColorHeader=4297d7&fcHeader=ffffff&iconColorHeader=d8e7f3&bgColorContent=fcfdfd&bgTextureContent=06_inset_hard.png&bgImgOpacityContent=100&borderColorContent=a6c9e2&fcContent=222222&iconColorContent=469bdd&bgColorDefault=dfeffc&bgTextureDefault=02_glass.png&bgImgOpacityDefault=85&borderColorDefault=c5dbec&fcDefault=2e6e9e&iconColorDefault=6da8d5&bgColorHover=d0e5f5&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=79b7e7&fcHover=1d5987&iconColorHover=217bc0&bgColorActive=f5f8f9&bgTextureActive=06_inset_hard.png&bgImgOpacityActive=100&borderColorActive=79b7e7&fcActive=e17009&iconColorActive=f9bd01&bgColorHighlight=fbec88&bgTextureHighlight=01_flat.png&bgImgOpacityHighlight=55&borderColorHighlight=fad42e&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=0px - */ - - -/* Component containers -----------------------------------*/ -.ui-widget { font-family: Lucida Grande, Lucida Sans, Arial, sans-serif; font-size: 1.1em; } -.ui-widget .ui-widget { font-size: 1em; } -.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Lucida Grande, Lucida Sans, Arial, sans-serif; font-size: 1em; } -.ui-widget-content { border: 1px solid #a6c9e2; background: #fcfdfd url(images/ui-bg_inset-hard_100_fcfdfd_1x100.png) 50% bottom repeat-x; color: #222222; } -.ui-widget-content a { color: #222222; } -.ui-widget-header { border: 1px solid #4297d7; background: #5c9ccc url(images/ui-bg_gloss-wave_55_5c9ccc_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; } -.ui-widget-header a { color: #ffffff; } - -/* Interaction states -----------------------------------*/ -.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #c5dbec; background: #dfeffc url(images/ui-bg_glass_85_dfeffc_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #2e6e9e; } -.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #2e6e9e; text-decoration: none; } -.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #79b7e7; background: #d0e5f5 url(images/ui-bg_glass_75_d0e5f5_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1d5987; } -.ui-state-hover a, .ui-state-hover a:hover { color: #1d5987; text-decoration: none; } -.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #79b7e7; background: #f5f8f9 url(images/ui-bg_inset-hard_100_f5f8f9_1x100.png) 50% 50% repeat-x; font-weight: bold; color: #e17009; } -.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #e17009; text-decoration: none; } -.ui-widget :active { outline: none; } - -/* Interaction Cues -----------------------------------*/ -.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fad42e; background: #fbec88 url(images/ui-bg_flat_55_fbec88_40x100.png) 50% 50% repeat-x; color: #363636; } -.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; } -.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; } -.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; } -.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; } -.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } -.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } -.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } - -/* Icons -----------------------------------*/ - -/* states and images */ -.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_469bdd_256x240.png); } -.ui-widget-content .ui-icon {background-image: url(images/ui-icons_469bdd_256x240.png); } -.ui-widget-header .ui-icon {background-image: url(images/ui-icons_d8e7f3_256x240.png); } -.ui-state-default .ui-icon { background-image: url(images/ui-icons_6da8d5_256x240.png); } -.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_217bc0_256x240.png); } -.ui-state-active .ui-icon {background-image: url(images/ui-icons_f9bd01_256x240.png); } -.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); } -.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); } - -/* positioning */ -.ui-icon-carat-1-n { background-position: 0 0; } -.ui-icon-carat-1-ne { background-position: -16px 0; } -.ui-icon-carat-1-e { background-position: -32px 0; } -.ui-icon-carat-1-se { background-position: -48px 0; } -.ui-icon-carat-1-s { background-position: -64px 0; } -.ui-icon-carat-1-sw { background-position: -80px 0; } -.ui-icon-carat-1-w { background-position: -96px 0; } -.ui-icon-carat-1-nw { background-position: -112px 0; } -.ui-icon-carat-2-n-s { background-position: -128px 0; } -.ui-icon-carat-2-e-w { background-position: -144px 0; } -.ui-icon-triangle-1-n { background-position: 0 -16px; } -.ui-icon-triangle-1-ne { background-position: -16px -16px; } -.ui-icon-triangle-1-e { background-position: -32px -16px; } -.ui-icon-triangle-1-se { background-position: -48px -16px; } -.ui-icon-triangle-1-s { background-position: -64px -16px; } -.ui-icon-triangle-1-sw { background-position: -80px -16px; } -.ui-icon-triangle-1-w { background-position: -96px -16px; } -.ui-icon-triangle-1-nw { background-position: -112px -16px; } -.ui-icon-triangle-2-n-s { background-position: -128px -16px; } -.ui-icon-triangle-2-e-w { background-position: -144px -16px; } -.ui-icon-arrow-1-n { background-position: 0 -32px; } -.ui-icon-arrow-1-ne { background-position: -16px -32px; } -.ui-icon-arrow-1-e { background-position: -32px -32px; } -.ui-icon-arrow-1-se { background-position: -48px -32px; } -.ui-icon-arrow-1-s { background-position: -64px -32px; } -.ui-icon-arrow-1-sw { background-position: -80px -32px; } -.ui-icon-arrow-1-w { background-position: -96px -32px; } -.ui-icon-arrow-1-nw { background-position: -112px -32px; } -.ui-icon-arrow-2-n-s { background-position: -128px -32px; } -.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } -.ui-icon-arrow-2-e-w { background-position: -160px -32px; } -.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } -.ui-icon-arrowstop-1-n { background-position: -192px -32px; } -.ui-icon-arrowstop-1-e { background-position: -208px -32px; } -.ui-icon-arrowstop-1-s { background-position: -224px -32px; } -.ui-icon-arrowstop-1-w { background-position: -240px -32px; } -.ui-icon-arrowthick-1-n { background-position: 0 -48px; } -.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } -.ui-icon-arrowthick-1-e { background-position: -32px -48px; } -.ui-icon-arrowthick-1-se { background-position: -48px -48px; } -.ui-icon-arrowthick-1-s { background-position: -64px -48px; } -.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } -.ui-icon-arrowthick-1-w { background-position: -96px -48px; } -.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } -.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } -.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } -.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } -.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } -.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } -.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } -.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } -.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } -.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } -.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } -.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } -.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } -.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } -.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } -.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } -.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } -.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } -.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } -.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } -.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } -.ui-icon-arrow-4 { background-position: 0 -80px; } -.ui-icon-arrow-4-diag { background-position: -16px -80px; } -.ui-icon-extlink { background-position: -32px -80px; } -.ui-icon-newwin { background-position: -48px -80px; } -.ui-icon-refresh { background-position: -64px -80px; } -.ui-icon-shuffle { background-position: -80px -80px; } -.ui-icon-transfer-e-w { background-position: -96px -80px; } -.ui-icon-transferthick-e-w { background-position: -112px -80px; } -.ui-icon-folder-collapsed { background-position: 0 -96px; } -.ui-icon-folder-open { background-position: -16px -96px; } -.ui-icon-document { background-position: -32px -96px; } -.ui-icon-document-b { background-position: -48px -96px; } -.ui-icon-note { background-position: -64px -96px; } -.ui-icon-mail-closed { background-position: -80px -96px; } -.ui-icon-mail-open { background-position: -96px -96px; } -.ui-icon-suitcase { background-position: -112px -96px; } -.ui-icon-comment { background-position: -128px -96px; } -.ui-icon-person { background-position: -144px -96px; } -.ui-icon-print { background-position: -160px -96px; } -.ui-icon-trash { background-position: -176px -96px; } -.ui-icon-locked { background-position: -192px -96px; } -.ui-icon-unlocked { background-position: -208px -96px; } -.ui-icon-bookmark { background-position: -224px -96px; } -.ui-icon-tag { background-position: -240px -96px; } -.ui-icon-home { background-position: 0 -112px; } -.ui-icon-flag { background-position: -16px -112px; } -.ui-icon-calendar { background-position: -32px -112px; } -.ui-icon-cart { background-position: -48px -112px; } -.ui-icon-pencil { background-position: -64px -112px; } -.ui-icon-clock { background-position: -80px -112px; } -.ui-icon-disk { background-position: -96px -112px; } -.ui-icon-calculator { background-position: -112px -112px; } -.ui-icon-zoomin { background-position: -128px -112px; } -.ui-icon-zoomout { background-position: -144px -112px; } -.ui-icon-search { background-position: -160px -112px; } -.ui-icon-wrench { background-position: -176px -112px; } -.ui-icon-gear { background-position: -192px -112px; } -.ui-icon-heart { background-position: -208px -112px; } -.ui-icon-star { background-position: -224px -112px; } -.ui-icon-link { background-position: -240px -112px; } -.ui-icon-cancel { background-position: 0 -128px; } -.ui-icon-plus { background-position: -16px -128px; } -.ui-icon-plusthick { background-position: -32px -128px; } -.ui-icon-minus { background-position: -48px -128px; } -.ui-icon-minusthick { background-position: -64px -128px; } -.ui-icon-close { background-position: -80px -128px; } -.ui-icon-closethick { background-position: -96px -128px; } -.ui-icon-key { background-position: -112px -128px; } -.ui-icon-lightbulb { background-position: -128px -128px; } -.ui-icon-scissors { background-position: -144px -128px; } -.ui-icon-clipboard { background-position: -160px -128px; } -.ui-icon-copy { background-position: -176px -128px; } -.ui-icon-contact { background-position: -192px -128px; } -.ui-icon-image { background-position: -208px -128px; } -.ui-icon-video { background-position: -224px -128px; } -.ui-icon-script { background-position: -240px -128px; } -.ui-icon-alert { background-position: 0 -144px; } -.ui-icon-info { background-position: -16px -144px; } -.ui-icon-notice { background-position: -32px -144px; } -.ui-icon-help { background-position: -48px -144px; } -.ui-icon-check { background-position: -64px -144px; } -.ui-icon-bullet { background-position: -80px -144px; } -.ui-icon-radio-off { background-position: -96px -144px; } -.ui-icon-radio-on { background-position: -112px -144px; } -.ui-icon-pin-w { background-position: -128px -144px; } -.ui-icon-pin-s { background-position: -144px -144px; } -.ui-icon-play { background-position: 0 -160px; } -.ui-icon-pause { background-position: -16px -160px; } -.ui-icon-seek-next { background-position: -32px -160px; } -.ui-icon-seek-prev { background-position: -48px -160px; } -.ui-icon-seek-end { background-position: -64px -160px; } -.ui-icon-seek-start { background-position: -80px -160px; } -/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ -.ui-icon-seek-first { background-position: -80px -160px; } -.ui-icon-stop { background-position: -96px -160px; } -.ui-icon-eject { background-position: -112px -160px; } -.ui-icon-volume-off { background-position: -128px -160px; } -.ui-icon-volume-on { background-position: -144px -160px; } -.ui-icon-power { background-position: 0 -176px; } -.ui-icon-signal-diag { background-position: -16px -176px; } -.ui-icon-signal { background-position: -32px -176px; } -.ui-icon-battery-0 { background-position: -48px -176px; } -.ui-icon-battery-1 { background-position: -64px -176px; } -.ui-icon-battery-2 { background-position: -80px -176px; } -.ui-icon-battery-3 { background-position: -96px -176px; } -.ui-icon-circle-plus { background-position: 0 -192px; } -.ui-icon-circle-minus { background-position: -16px -192px; } -.ui-icon-circle-close { background-position: -32px -192px; } -.ui-icon-circle-triangle-e { background-position: -48px -192px; } -.ui-icon-circle-triangle-s { background-position: -64px -192px; } -.ui-icon-circle-triangle-w { background-position: -80px -192px; } -.ui-icon-circle-triangle-n { background-position: -96px -192px; } -.ui-icon-circle-arrow-e { background-position: -112px -192px; } -.ui-icon-circle-arrow-s { background-position: -128px -192px; } -.ui-icon-circle-arrow-w { background-position: -144px -192px; } -.ui-icon-circle-arrow-n { background-position: -160px -192px; } -.ui-icon-circle-zoomin { background-position: -176px -192px; } -.ui-icon-circle-zoomout { background-position: -192px -192px; } -.ui-icon-circle-check { background-position: -208px -192px; } -.ui-icon-circlesmall-plus { background-position: 0 -208px; } -.ui-icon-circlesmall-minus { background-position: -16px -208px; } -.ui-icon-circlesmall-close { background-position: -32px -208px; } -.ui-icon-squaresmall-plus { background-position: -48px -208px; } -.ui-icon-squaresmall-minus { background-position: -64px -208px; } -.ui-icon-squaresmall-close { background-position: -80px -208px; } -.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } -.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } -.ui-icon-grip-solid-vertical { background-position: -32px -224px; } -.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } -.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } -.ui-icon-grip-diagonal-se { background-position: -80px -224px; } - - -/* Misc visuals -----------------------------------*/ - -/* Corner radius */ - -/* Overlays */ -.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); } -.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); }/* - * jQuery UI Autocomplete 1.8.16 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Autocomplete#theming - */ -.ui-autocomplete { position: absolute; cursor: default; } - -/* workarounds */ -* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ - -/* - * jQuery UI Menu 1.8.16 - * - * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Menu#theming - */ -.ui-menu { - list-style:none; - padding: 2px; - margin: 0; - display:block; - float: left; -} -.ui-menu .ui-menu { - margin-top: -3px; -} -.ui-menu .ui-menu-item { - margin:0; - padding: 0; - zoom: 1; - float: left; - clear: left; - width: 100%; -} -.ui-menu .ui-menu-item a { - text-decoration:none; - display:block; - padding:.2em .4em; - line-height:1.5; - zoom:1; -} -.ui-menu .ui-menu-item a.ui-state-hover, -.ui-menu .ui-menu-item a.ui-state-active { - font-weight: normal; - margin: -1px; -} -/* - * jQuery UI Button 1.8.16 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Button#theming - */ -.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ -.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ -button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ -.ui-button-icons-only { width: 3.4em; } -button.ui-button-icons-only { width: 3.7em; } - -/*button text element */ -.ui-button .ui-button-text { display: block; line-height: 1.4; } -.ui-button-text-only .ui-button-text { padding: .4em 1em; } -.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; } -.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } -.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; } -.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } -/* no icon support for input elements, provide padding by default */ -input.ui-button { padding: .4em 1em; } - -/*button icon element(s) */ -.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } -.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } -.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } -.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } -.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } - -/*button sets*/ -.ui-buttonset { margin-right: 7px; } -.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; } - -/* workarounds */ -button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ -/* - * jQuery UI Datepicker 1.8.16 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Datepicker#theming - */ -.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; } -.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } -.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } -.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } -.ui-datepicker .ui-datepicker-prev { left:2px; } -.ui-datepicker .ui-datepicker-next { right:2px; } -.ui-datepicker .ui-datepicker-prev-hover { left:1px; } -.ui-datepicker .ui-datepicker-next-hover { right:1px; } -.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } -.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } -.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; } -.ui-datepicker select.ui-datepicker-month-year {width: 100%;} -.ui-datepicker select.ui-datepicker-month, -.ui-datepicker select.ui-datepicker-year { width: 49%;} -.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } -.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } -.ui-datepicker td { border: 0; padding: 1px; } -.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } -.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } -.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } -.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } - -/* with multiple calendars */ -.ui-datepicker.ui-datepicker-multi { width:auto; } -.ui-datepicker-multi .ui-datepicker-group { float:left; } -.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } -.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } -.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } -.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } -.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } -.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } -.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } -.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; } - -/* RTL support */ -.ui-datepicker-rtl { direction: rtl; } -.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } -.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } -.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } -.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } -.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } -.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } -.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } -.ui-datepicker-rtl .ui-datepicker-group { float:right; } -.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } -.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } - -/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ -.ui-datepicker-cover { - display: none; /*sorry for IE5*/ - display/**/: block; /*sorry for IE5*/ - position: absolute; /*must have*/ - z-index: -1; /*must have*/ - filter: mask(); /*must have*/ - top: -4px; /*must have*/ - left: -4px; /*must have*/ - width: 200px; /*must have*/ - height: 200px; /*must have*/ +/* + * jQuery UI CSS Framework 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + */ + +/* Layout helpers +----------------------------------*/ +.ui-helper-hidden { display: none; } +.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); } +.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } +.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } +.ui-helper-clearfix { display: inline-block; } +/* required comment for clearfix to work in Opera \*/ +* html .ui-helper-clearfix { height:1%; } +.ui-helper-clearfix { display:block; } +/* end clearfix */ +.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } + + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { cursor: default !important; } + + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } + + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } + + +/* + * jQuery UI CSS Framework 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + * + * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Lucida%20Grande,%20Lucida%20Sans,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=0px&bgColorHeader=5c9ccc&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=55&borderColorHeader=4297d7&fcHeader=ffffff&iconColorHeader=d8e7f3&bgColorContent=fcfdfd&bgTextureContent=06_inset_hard.png&bgImgOpacityContent=100&borderColorContent=a6c9e2&fcContent=222222&iconColorContent=469bdd&bgColorDefault=dfeffc&bgTextureDefault=02_glass.png&bgImgOpacityDefault=85&borderColorDefault=c5dbec&fcDefault=2e6e9e&iconColorDefault=6da8d5&bgColorHover=d0e5f5&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=79b7e7&fcHover=1d5987&iconColorHover=217bc0&bgColorActive=f5f8f9&bgTextureActive=06_inset_hard.png&bgImgOpacityActive=100&borderColorActive=79b7e7&fcActive=e17009&iconColorActive=f9bd01&bgColorHighlight=fbec88&bgTextureHighlight=01_flat.png&bgImgOpacityHighlight=55&borderColorHighlight=fad42e&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=0px + */ + + +/* Component containers +----------------------------------*/ +.ui-widget { font-family: Lucida Grande, Lucida Sans, Arial, sans-serif; font-size: 1.1em; } +.ui-widget .ui-widget { font-size: 1em; } +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Lucida Grande, Lucida Sans, Arial, sans-serif; font-size: 1em; } +.ui-widget-content { border: 1px solid #a6c9e2; background: #fcfdfd url(images/ui-bg_inset-hard_100_fcfdfd_1x100.png) 50% bottom repeat-x; color: #222222; } +.ui-widget-content a { color: #222222; } +.ui-widget-header { border: 1px solid #4297d7; background: #5c9ccc url(images/ui-bg_gloss-wave_55_5c9ccc_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; } +.ui-widget-header a { color: #ffffff; } + +/* Interaction states +----------------------------------*/ +.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #c5dbec; background: #dfeffc url(images/ui-bg_glass_85_dfeffc_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #2e6e9e; } +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #2e6e9e; text-decoration: none; } +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #79b7e7; background: #d0e5f5 url(images/ui-bg_glass_75_d0e5f5_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1d5987; } +.ui-state-hover a, .ui-state-hover a:hover { color: #1d5987; text-decoration: none; } +.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #79b7e7; background: #f5f8f9 url(images/ui-bg_inset-hard_100_f5f8f9_1x100.png) 50% 50% repeat-x; font-weight: bold; color: #e17009; } +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #e17009; text-decoration: none; } +.ui-widget :active { outline: none; } + +/* Interaction Cues +----------------------------------*/ +.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fad42e; background: #fbec88 url(images/ui-bg_flat_55_fbec88_40x100.png) 50% 50% repeat-x; color: #363636; } +.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; } +.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; } +.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; } +.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; } +.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } +.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } +.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_469bdd_256x240.png); } +.ui-widget-content .ui-icon {background-image: url(images/ui-icons_469bdd_256x240.png); } +.ui-widget-header .ui-icon {background-image: url(images/ui-icons_d8e7f3_256x240.png); } +.ui-state-default .ui-icon { background-image: url(images/ui-icons_6da8d5_256x240.png); } +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_217bc0_256x240.png); } +.ui-state-active .ui-icon {background-image: url(images/ui-icons_f9bd01_256x240.png); } +.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); } +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); } + +/* positioning */ +.ui-icon-carat-1-n { background-position: 0 0; } +.ui-icon-carat-1-ne { background-position: -16px 0; } +.ui-icon-carat-1-e { background-position: -32px 0; } +.ui-icon-carat-1-se { background-position: -48px 0; } +.ui-icon-carat-1-s { background-position: -64px 0; } +.ui-icon-carat-1-sw { background-position: -80px 0; } +.ui-icon-carat-1-w { background-position: -96px 0; } +.ui-icon-carat-1-nw { background-position: -112px 0; } +.ui-icon-carat-2-n-s { background-position: -128px 0; } +.ui-icon-carat-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -64px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -64px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 0 -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-off { background-position: -96px -144px; } +.ui-icon-radio-on { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-start { background-position: -80px -160px; } +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/* Misc visuals +----------------------------------*/ + +/* Corner radius */ + +/* Overlays */ +.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); } +.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); }/* + * jQuery UI Autocomplete 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Autocomplete#theming + */ +.ui-autocomplete { position: absolute; cursor: default; } + +/* workarounds */ +* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ + +/* + * jQuery UI Menu 1.8.16 + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Menu#theming + */ +.ui-menu { + list-style:none; + padding: 2px; + margin: 0; + display:block; + float: left; +} +.ui-menu .ui-menu { + margin-top: -3px; +} +.ui-menu .ui-menu-item { + margin:0; + padding: 0; + zoom: 1; + float: left; + clear: left; + width: 100%; +} +.ui-menu .ui-menu-item a { + text-decoration:none; + display:block; + padding:.2em .4em; + line-height:1.5; + zoom:1; +} +.ui-menu .ui-menu-item a.ui-state-hover, +.ui-menu .ui-menu-item a.ui-state-active { + font-weight: normal; + margin: -1px; +} +/* + * jQuery UI Button 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Button#theming + */ +.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ +.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ +button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ +.ui-button-icons-only { width: 3.4em; } +button.ui-button-icons-only { width: 3.7em; } + +/*button text element */ +.ui-button .ui-button-text { display: block; line-height: 1.4; } +.ui-button-text-only .ui-button-text { padding: .4em 1em; } +.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; } +.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } +.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; } +.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } +/* no icon support for input elements, provide padding by default */ +input.ui-button { padding: .4em 1em; } + +/*button icon element(s) */ +.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } +.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } +.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } +.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } +.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } + +/*button sets*/ +.ui-buttonset { margin-right: 7px; } +.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; } + +/* workarounds */ +button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ +/* + * jQuery UI Datepicker 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Datepicker#theming + */ +.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; } +.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } +.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } +.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } +.ui-datepicker .ui-datepicker-prev { left:2px; } +.ui-datepicker .ui-datepicker-next { right:2px; } +.ui-datepicker .ui-datepicker-prev-hover { left:1px; } +.ui-datepicker .ui-datepicker-next-hover { right:1px; } +.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } +.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } +.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; } +.ui-datepicker select.ui-datepicker-month-year {width: 100%;} +.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { width: 49%;} +.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } +.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } +.ui-datepicker td { border: 0; padding: 1px; } +.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } +.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } +.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } + +/* with multiple calendars */ +.ui-datepicker.ui-datepicker-multi { width:auto; } +.ui-datepicker-multi .ui-datepicker-group { float:left; } +.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } +.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } +.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } +.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } +.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; } + +/* RTL support */ +.ui-datepicker-rtl { direction: rtl; } +.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } +.ui-datepicker-rtl .ui-datepicker-group { float:right; } +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } + +/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ +.ui-datepicker-cover { + display: none; /*sorry for IE5*/ + display/**/: block; /*sorry for IE5*/ + position: absolute; /*must have*/ + z-index: -1; /*must have*/ + filter: mask(); /*must have*/ + top: -4px; /*must have*/ + left: -4px; /*must have*/ + width: 200px; /*must have*/ + height: 200px; /*must have*/ } \ No newline at end of file diff --git a/interface/web/themes/default-304/css/screen/tipsy.css b/interface/web/themes/default-304/css/screen/tipsy.css index 3d6295408849a6a80062536a55f65657a67888d4..ea735c76278167dbe19710a84f890b3ee2f17d12 100644 --- a/interface/web/themes/default-304/css/screen/tipsy.css +++ b/interface/web/themes/default-304/css/screen/tipsy.css @@ -1,25 +1,25 @@ -.tipsy { font-size: 10px; position: absolute; padding: 5px; z-index: 100000; } - .tipsy-inner { background-color: #000; color: #FFF; max-width: 350px; padding: 5px 8px 4px 8px; text-align: left; } - - /* Rounded corners */ - .tipsy-inner { border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; } - - /* Uncomment for shadow */ - /*.tipsy-inner { box-shadow: 0 0 5px #000000; -webkit-box-shadow: 0 0 5px #000000; -moz-box-shadow: 0 0 5px #000000; }*/ - - .tipsy-arrow { position: absolute; width: 0; height: 0; line-height: 0; border: 5px dashed #000; } - - /* Rules to colour arrows */ - .tipsy-arrow-n { border-bottom-color: #000; } - .tipsy-arrow-s { border-top-color: #000; } - .tipsy-arrow-e { border-left-color: #000; } - .tipsy-arrow-w { border-right-color: #000; } - - .tipsy-n .tipsy-arrow { top: 0px; left: 50%; margin-left: -5px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent; } - .tipsy-nw .tipsy-arrow { top: 0; left: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;} - .tipsy-ne .tipsy-arrow { top: 0; right: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;} - .tipsy-s .tipsy-arrow { bottom: 0; left: 50%; margin-left: -5px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; } - .tipsy-sw .tipsy-arrow { bottom: 0; left: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; } - .tipsy-se .tipsy-arrow { bottom: 0; right: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; } - .tipsy-e .tipsy-arrow { right: 0; top: 50%; margin-top: -5px; border-left-style: solid; border-right: none; border-top-color: transparent; border-bottom-color: transparent; } - .tipsy-w .tipsy-arrow { left: 0; top: 50%; margin-top: -5px; border-right-style: solid; border-left: none; border-top-color: transparent; border-bottom-color: transparent; } +.tipsy { font-size: 10px; position: absolute; padding: 5px; z-index: 100000; } + .tipsy-inner { background-color: #000; color: #FFF; max-width: 350px; padding: 5px 8px 4px 8px; text-align: left; } + + /* Rounded corners */ + .tipsy-inner { border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; } + + /* Uncomment for shadow */ + /*.tipsy-inner { box-shadow: 0 0 5px #000000; -webkit-box-shadow: 0 0 5px #000000; -moz-box-shadow: 0 0 5px #000000; }*/ + + .tipsy-arrow { position: absolute; width: 0; height: 0; line-height: 0; border: 5px dashed #000; } + + /* Rules to colour arrows */ + .tipsy-arrow-n { border-bottom-color: #000; } + .tipsy-arrow-s { border-top-color: #000; } + .tipsy-arrow-e { border-left-color: #000; } + .tipsy-arrow-w { border-right-color: #000; } + + .tipsy-n .tipsy-arrow { top: 0px; left: 50%; margin-left: -5px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent; } + .tipsy-nw .tipsy-arrow { top: 0; left: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;} + .tipsy-ne .tipsy-arrow { top: 0; right: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;} + .tipsy-s .tipsy-arrow { bottom: 0; left: 50%; margin-left: -5px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; } + .tipsy-sw .tipsy-arrow { bottom: 0; left: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; } + .tipsy-se .tipsy-arrow { bottom: 0; right: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; } + .tipsy-e .tipsy-arrow { right: 0; top: 50%; margin-top: -5px; border-left-style: solid; border-right: none; border-top-color: transparent; border-bottom-color: transparent; } + .tipsy-w .tipsy-arrow { left: 0; top: 50%; margin-top: -5px; border-right-style: solid; border-left: none; border-top-color: transparent; border-bottom-color: transparent; } diff --git a/interface/web/themes/default-304/templates/monitor/show_sys_state.htm b/interface/web/themes/default-304/templates/monitor/show_sys_state.htm index 740141b26998f91426e3559dda7aed00839aadc8..9a5830c19c0a89834aadab9a32b7d9416a792652 100644 --- a/interface/web/themes/default-304/templates/monitor/show_sys_state.htm +++ b/interface/web/themes/default-304/templates/monitor/show_sys_state.htm @@ -1,25 +1,25 @@ -<h2><tmpl_var name="list_head_txt"></h2> -<p><tmpl_var name="list_desc_txt"></p> - -<div class="panel panel_sys_state"> - - <div class="pnl_toolsarea"> - <fieldset class="inlineLabels"><legend><tmpl_var name="monTransRefreshsq"></legend> - <div class="buttons"> - <div class="ctrlHolder"> - <label for="refreshinterval">{tmpl_var name='refreshinterval_txt'}</label> - <select name="refreshinterval" id="refreshinterval" class="selectInput withicons" onChange="loadContentRefresh('monitor/show_sys_state.php?state={tmpl_var name="state_type"}')"> - {tmpl_var name='refresh'} - </select> - </div> - </div> - </fieldset> - </div> - - <div class="pnl_formarea"> - <fieldset><legend></legend> - <div class="stateview"><tmpl_var name="state_data"></div> - </fieldset> - </div> - +<h2><tmpl_var name="list_head_txt"></h2> +<p><tmpl_var name="list_desc_txt"></p> + +<div class="panel panel_sys_state"> + + <div class="pnl_toolsarea"> + <fieldset class="inlineLabels"><legend><tmpl_var name="monTransRefreshsq"></legend> + <div class="buttons"> + <div class="ctrlHolder"> + <label for="refreshinterval">{tmpl_var name='refreshinterval_txt'}</label> + <select name="refreshinterval" id="refreshinterval" class="selectInput withicons" onChange="loadContentRefresh('monitor/show_sys_state.php?state={tmpl_var name="state_type"}')"> + {tmpl_var name='refresh'} + </select> + </div> + </div> + </fieldset> + </div> + + <div class="pnl_formarea"> + <fieldset><legend></legend> + <div class="stateview"><tmpl_var name="state_data"></div> + </fieldset> + </div> + </div> \ No newline at end of file diff --git a/interface/web/themes/default-304/templates/sites/aps_install_package.htm b/interface/web/themes/default-304/templates/sites/aps_install_package.htm index e6ce02a445cf01565835fddbbc0933b56bd227ed..eeed54f970f1d6545fb18184e3a96b9be3877186 100644 --- a/interface/web/themes/default-304/templates/sites/aps_install_package.htm +++ b/interface/web/themes/default-304/templates/sites/aps_install_package.htm @@ -1,56 +1,56 @@ -<h2> - {tmpl_var name='installation_txt'}: {tmpl_var name='pkg_name'} {tmpl_var name='pkg_version'}-{tmpl_var name='pkg_release'} - <span style="float:right"> - <tmpl_if name='pkg_icon' op='!=' value=''> - <img src="{tmpl_var name='pkg_icon'}" height="32" width="32" alt="{tmpl_var name='pkg_name'}" style="vertical-align:text-bottom;" /> - </tmpl_if> - </span> -</h2> - -<tmpl_if name='error'> - <div id="errorMsg"><h3>ERROR</h3><ol>{tmpl_var name='error'}</ol></div> -</tmpl_if> - -<div class="panel panel_install_package"> - - <div class="pnl_formsarea"> - <fieldset class="inlineLabels"> - <legend>{tmpl_var name='basic_settings_txt'}</legend> - <div class="ctrlHolder"> - <label for="main_domain">{tmpl_var name='install_location_txt'}</label> - <div class="resetButton">http(s):// </div>DOMAIN_LIST_SPACE<div style="float:left;"> / </div> - <input type="text" name="main_location" id="main_location" value="{tmpl_var name='inp_main_location'}" maxlength="255" class="textInput formLengthHalf" /> - </div> - <tmpl_if name='pkg_requirements_database' op='!=' value=''> - <div class="ctrlHolder"> - <label for="main_database_password">{tmpl_var name='new_database_password_txt'}</label> - <input type="text" class="textInput" name="main_database_password" id="main_database_password" value="{tmpl_var name='inp_main_database_password'}" size="10" maxlength="255" /> - </div> - </tmpl_if> - - PKG_SETTINGS_SPACE - - <legend>{tmpl_var name='license_txt'}</legend> - <div class="ctrlHolder"> - <label for="license">{tmpl_var name='license_txt'}</label> - <tmpl_if name='pkg_license_content' op='==' value=''>{tmpl_var name='pkg_license_name'}<br /></tmpl_if> - <tmpl_if name='pkg_license_type' op='==' value='url'> - <a href="{tmpl_var name='pkg_license_content'}" target="_blank">{tmpl_var name='pkg_license_content'}</a> - <tmpl_elseif name='pkg_license_content'> - <textarea rows="10" cols="80" id="license_text">{tmpl_var name='pkg_license_content'}</textarea> - </tmpl_if> - </div> - <div class="ctrlHolder"> - <label for="license">{tmpl_var name='acceptance_txt'}</label> - <input type="checkbox" name="license" id="license" <tmpl_if name='inp_license' op='==' value='true'>checked</tmpl_if> /> {tmpl_var name='acceptance_text'} - </div> - </fieldset> - - <input type="hidden" name="install" value="0" /> - <div class="buttonHolder buttons"> - <button class="positive iconstxt icoPositive" type="button" value="{tmpl_var name='btn_install'}" name="btn_install" onClick="document.pageForm.install.value=1; submitForm('pageForm','sites/aps_install_package.php?id={tmpl_var name='pkg_id'}');"><span>{tmpl_var name='btn_install'}</span></button> - <button class="negative iconstxt icoNegative" type="button" value="{tmpl_var name='btn_cancel'}" onClick="loadContent('aps/availablepackages_list.php');"><span>{tmpl_var name='btn_cancel'}</span></button> - </div> - </div> - +<h2> + {tmpl_var name='installation_txt'}: {tmpl_var name='pkg_name'} {tmpl_var name='pkg_version'}-{tmpl_var name='pkg_release'} + <span style="float:right"> + <tmpl_if name='pkg_icon' op='!=' value=''> + <img src="{tmpl_var name='pkg_icon'}" height="32" width="32" alt="{tmpl_var name='pkg_name'}" style="vertical-align:text-bottom;" /> + </tmpl_if> + </span> +</h2> + +<tmpl_if name='error'> + <div id="errorMsg"><h3>ERROR</h3><ol>{tmpl_var name='error'}</ol></div> +</tmpl_if> + +<div class="panel panel_install_package"> + + <div class="pnl_formsarea"> + <fieldset class="inlineLabels"> + <legend>{tmpl_var name='basic_settings_txt'}</legend> + <div class="ctrlHolder"> + <label for="main_domain">{tmpl_var name='install_location_txt'}</label> + <div class="resetButton">http(s):// </div>DOMAIN_LIST_SPACE<div style="float:left;"> / </div> + <input type="text" name="main_location" id="main_location" value="{tmpl_var name='inp_main_location'}" maxlength="255" class="textInput formLengthHalf" /> + </div> + <tmpl_if name='pkg_requirements_database' op='!=' value=''> + <div class="ctrlHolder"> + <label for="main_database_password">{tmpl_var name='new_database_password_txt'}</label> + <input type="text" class="textInput" name="main_database_password" id="main_database_password" value="{tmpl_var name='inp_main_database_password'}" size="10" maxlength="255" /> + </div> + </tmpl_if> + + PKG_SETTINGS_SPACE + + <legend>{tmpl_var name='license_txt'}</legend> + <div class="ctrlHolder"> + <label for="license">{tmpl_var name='license_txt'}</label> + <tmpl_if name='pkg_license_content' op='==' value=''>{tmpl_var name='pkg_license_name'}<br /></tmpl_if> + <tmpl_if name='pkg_license_type' op='==' value='url'> + <a href="{tmpl_var name='pkg_license_content'}" target="_blank">{tmpl_var name='pkg_license_content'}</a> + <tmpl_elseif name='pkg_license_content'> + <textarea rows="10" cols="80" id="license_text">{tmpl_var name='pkg_license_content'}</textarea> + </tmpl_if> + </div> + <div class="ctrlHolder"> + <label for="license">{tmpl_var name='acceptance_txt'}</label> + <input type="checkbox" name="license" id="license" <tmpl_if name='inp_license' op='==' value='true'>checked</tmpl_if> /> {tmpl_var name='acceptance_text'} + </div> + </fieldset> + + <input type="hidden" name="install" value="0" /> + <div class="buttonHolder buttons"> + <button class="positive iconstxt icoPositive" type="button" value="{tmpl_var name='btn_install'}" name="btn_install" onClick="document.pageForm.install.value=1; submitForm('pageForm','sites/aps_install_package.php?id={tmpl_var name='pkg_id'}');"><span>{tmpl_var name='btn_install'}</span></button> + <button class="negative iconstxt icoNegative" type="button" value="{tmpl_var name='btn_cancel'}" onClick="loadContent('aps/availablepackages_list.php');"><span>{tmpl_var name='btn_cancel'}</span></button> + </div> + </div> + </div> \ No newline at end of file diff --git a/interface/web/themes/default-304/templates/sites/aps_instances_list.htm b/interface/web/themes/default-304/templates/sites/aps_instances_list.htm index 640c0bb96c8ab99e50f9efb0d225107e63cfebc9..6f4ab80e875e0b4d5f1068ebbfcb2fd7e00a76de 100644 --- a/interface/web/themes/default-304/templates/sites/aps_instances_list.htm +++ b/interface/web/themes/default-304/templates/sites/aps_instances_list.htm @@ -1,62 +1,62 @@ -<h2>{tmpl_var name="list_head_txt"}</h2> - -<div class="panel panel_list_instances"> - - <div class="pnl_listarea"> - <fieldset><legend>{tmpl_var name="list_head_txt"}</legend> - <table class="list"> - <thead> - <tr> - <th class="tbl_col_name" scope="col">{tmpl_var name='name_txt'}</th> - <th class="tbl_col_version" scope="col">{tmpl_var name='version_txt'}</th> - <tmpl_if name='is_noclient'> - <th class="tbl_col_customer" scope="col">{tmpl_var name='customer_txt'}</th> - </tmpl_if> - <th class="tbl_col_installlocation" scope="col">{tmpl_var name='install_location_txt'}</th> - <th class="tbl_col_instancestatus" scope="col">{tmpl_var name='status_txt'}</th> - <th class="tbl_col_buttons" scope="col" > </th> - </tr> - <tr> - <td class="tbl_col_name"><input type="text" name="search_name" value="{tmpl_var name='search_name'}" /></td> - <td class="tbl_col_version"><input type="text" name="search_version" value="{tmpl_var name='search_version'}" /></td> - <tmpl_if name='is_noclient'> - <td class="tbl_col_customer"><input type="text" name="search_customer_name" value="{tmpl_var name='search_customer_name'}" /></td> - </tmpl_if> - <td class="tbl_col_installlocation"> </td> - <td class="tbl_col_instancestatus"><select name="search_instance_status" onChange="submitForm('pageForm','sites/aps_installedpackages_list.php');">{tmpl_var name='search_instance_status'}</select></td> - <td class="tbl_col_buttons"> - <button type="button" class="icons16 icoFilter" name="Filter" id="Filter" value="{tmpl_var name='filter_txt'}" onClick="submitForm('pageForm','sites/aps_installedpackages_list.php');"> - <span>{tmpl_var name='filter_txt'}</span> - </button> - </td> - </tr> - </thead> - <tbody> - <tmpl_loop name='records'> - <tr class="tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>"> - <td class="tbl_col_name"><a href="#" onClick="loadContent('sites/aps_packagedetails_show.php?id={tmpl_var name='package_id'}');">{tmpl_var name='package_name'}</a></td> - <td class="tbl_col_version">{tmpl_var name='package_version'}-{tmpl_var name='package_release'}</td> - <tmpl_if name='is_noclient'> - <td class="tbl_col_customer"><a href="#" onClick="loadContent('client/client_edit.php?id={tmpl_var name='CustomerID'}');">{tmpl_var name='customer_name'}</a></td> - </tmpl_if> - <td class="tbl_col_installlocation"><a href="http://{tmpl_var name='install_location'}" target="_blank">{tmpl_var name='install_location_short'}</a></td> - <td class="tbl_col_instancestatus"><span id="status_content{tmpl_var name='__ROWNUM__'}">{tmpl_var name='instance_status'}</span></td> - <td class="tbl_col_buttons"> - <div class="buttons icons16" style="width:60px;"> - <tmpl_if name='delete_possible'><a class="icons16 icoDelete" href="javascript:if(window.confirm('{tmpl_var name='pkg_delete_confirmation'}')){ loadContentInto('status_content{tmpl_var name='__ROWNUM__'}', 'sites/aps_do_operation.php?action=delete_instance&id={tmpl_var name='id'}&phpsessid={tmpl_var name='phpsessid'}'); }"><span>{tmpl_var name='delete_txt'}</span></a></tmpl_if> - <tmpl_if name='reinstall_possible'><a class="icons16 icoEdit" href="javascript:if(window.confirm('{tmpl_var name='pkg_reinstall_confirmation'}')){ loadContentInto('status_content{tmpl_var name='__ROWNUM__'}', 'sites/aps_do_operation.php?action=reinstall_instance&id={tmpl_var name='id'}&phpsessid={tmpl_var name='phpsessid'}'); }"><span>{tmpl_var name='reinstall_txt'}</span></a></tmpl_if> - </div> - </td> - </tr> - </tmpl_loop> - </tbody> - <tfoot> - <tr> - <td class="tbl_footer tbl_paging" colspan="6">{tmpl_var name='paging'}</td> - </tr> - </tfoot> - </table> - </fieldset> - </div> - +<h2>{tmpl_var name="list_head_txt"}</h2> + +<div class="panel panel_list_instances"> + + <div class="pnl_listarea"> + <fieldset><legend>{tmpl_var name="list_head_txt"}</legend> + <table class="list"> + <thead> + <tr> + <th class="tbl_col_name" scope="col">{tmpl_var name='name_txt'}</th> + <th class="tbl_col_version" scope="col">{tmpl_var name='version_txt'}</th> + <tmpl_if name='is_noclient'> + <th class="tbl_col_customer" scope="col">{tmpl_var name='customer_txt'}</th> + </tmpl_if> + <th class="tbl_col_installlocation" scope="col">{tmpl_var name='install_location_txt'}</th> + <th class="tbl_col_instancestatus" scope="col">{tmpl_var name='status_txt'}</th> + <th class="tbl_col_buttons" scope="col" > </th> + </tr> + <tr> + <td class="tbl_col_name"><input type="text" name="search_name" value="{tmpl_var name='search_name'}" /></td> + <td class="tbl_col_version"><input type="text" name="search_version" value="{tmpl_var name='search_version'}" /></td> + <tmpl_if name='is_noclient'> + <td class="tbl_col_customer"><input type="text" name="search_customer_name" value="{tmpl_var name='search_customer_name'}" /></td> + </tmpl_if> + <td class="tbl_col_installlocation"> </td> + <td class="tbl_col_instancestatus"><select name="search_instance_status" onChange="submitForm('pageForm','sites/aps_installedpackages_list.php');">{tmpl_var name='search_instance_status'}</select></td> + <td class="tbl_col_buttons"> + <button type="button" class="icons16 icoFilter" name="Filter" id="Filter" value="{tmpl_var name='filter_txt'}" onClick="submitForm('pageForm','sites/aps_installedpackages_list.php');"> + <span>{tmpl_var name='filter_txt'}</span> + </button> + </td> + </tr> + </thead> + <tbody> + <tmpl_loop name='records'> + <tr class="tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>"> + <td class="tbl_col_name"><a href="#" onClick="loadContent('sites/aps_packagedetails_show.php?id={tmpl_var name='package_id'}');">{tmpl_var name='package_name'}</a></td> + <td class="tbl_col_version">{tmpl_var name='package_version'}-{tmpl_var name='package_release'}</td> + <tmpl_if name='is_noclient'> + <td class="tbl_col_customer"><a href="#" onClick="loadContent('client/client_edit.php?id={tmpl_var name='CustomerID'}');">{tmpl_var name='customer_name'}</a></td> + </tmpl_if> + <td class="tbl_col_installlocation"><a href="http://{tmpl_var name='install_location'}" target="_blank">{tmpl_var name='install_location_short'}</a></td> + <td class="tbl_col_instancestatus"><span id="status_content{tmpl_var name='__ROWNUM__'}">{tmpl_var name='instance_status'}</span></td> + <td class="tbl_col_buttons"> + <div class="buttons icons16" style="width:60px;"> + <tmpl_if name='delete_possible'><a class="icons16 icoDelete" href="javascript:if(window.confirm('{tmpl_var name='pkg_delete_confirmation'}')){ loadContentInto('status_content{tmpl_var name='__ROWNUM__'}', 'sites/aps_do_operation.php?action=delete_instance&id={tmpl_var name='id'}&phpsessid={tmpl_var name='phpsessid'}'); }"><span>{tmpl_var name='delete_txt'}</span></a></tmpl_if> + <tmpl_if name='reinstall_possible'><a class="icons16 icoEdit" href="javascript:if(window.confirm('{tmpl_var name='pkg_reinstall_confirmation'}')){ loadContentInto('status_content{tmpl_var name='__ROWNUM__'}', 'sites/aps_do_operation.php?action=reinstall_instance&id={tmpl_var name='id'}&phpsessid={tmpl_var name='phpsessid'}'); }"><span>{tmpl_var name='reinstall_txt'}</span></a></tmpl_if> + </div> + </td> + </tr> + </tmpl_loop> + </tbody> + <tfoot> + <tr> + <td class="tbl_footer tbl_paging" colspan="6">{tmpl_var name='paging'}</td> + </tr> + </tfoot> + </table> + </fieldset> + </div> + </div> \ No newline at end of file diff --git a/interface/web/themes/default-304/templates/sites/aps_packagedetails_show.htm b/interface/web/themes/default-304/templates/sites/aps_packagedetails_show.htm index 351d3ac0460a708d0fdcc02d175149bd8ef3a4b5..18a6fc9e96b0639c44281840cd8068dc7a01cb81 100644 --- a/interface/web/themes/default-304/templates/sites/aps_packagedetails_show.htm +++ b/interface/web/themes/default-304/templates/sites/aps_packagedetails_show.htm @@ -1,139 +1,139 @@ -<h2> - <tmpl_if name='pkg_icon' op='!=' value=''> - <img src="{tmpl_var name='pkg_icon'}" height="32" width="32" alt="{tmpl_var name='pkg_name'}" style="vertical-align:text-bottom;" /> - </tmpl_if> - {tmpl_var name='pkg_name'} -</h2> -<b>{tmpl_var name='pkg_summary'}</b> -<p> </p> - -<div class="pnl_toolsarea"> - <div class="buttons"> - <button class="iconstxt icoAdd" type="button" onClick="loadContent('sites/aps_install_package.php?id={tmpl_var name='pkg_id'}');"> - <span>{tmpl_var name='install_package_txt'}</span> - </button> - </div> - <p> </p><p> </p> -</div> - - -<div class="tabbox_tabs"> - <input type="hidden" name="next_tab" value="" /> - <ul> - <li<tmpl_if name='next_tab' op='==' value='details'> class="active"</tmpl_if>> - <a href="javascript:changeTab('details', 'sites/aps_packagedetails_show.php?id={tmpl_var name='pkg_id'}');">{tmpl_var name='details_txt'}</a> - </li> - <tmpl_if name='pkg_screenshots'> - <li<tmpl_if name='next_tab' op='==' value='screenshots'> class="active"</tmpl_if>> - <a href="javascript:changeTab('screenshots', 'sites/aps_packagedetails_show.php?id={tmpl_var name='pkg_id'}');">{tmpl_var name='screenshots_txt'}</a> - </li></tmpl_if> - <tmpl_if name='pkg_changelog'> - <li<tmpl_if name='next_tab' op='==' value='changelog'> class="active"</tmpl_if>> - <a href="javascript:changeTab('changelog', 'sites/aps_packagedetails_show.php?id={tmpl_var name='pkg_id'}');">{tmpl_var name='changelog_txt'}</a> - </li></tmpl_if> - <li<tmpl_if name='next_tab' op='==' value='settings'> class="active"</tmpl_if>> - <a href="javascript:changeTab('settings', 'sites/aps_packagedetails_show.php?id={tmpl_var name='pkg_id'}');">{tmpl_var name='settings_txt'}</a> - </li> - </ul> -</div> -<p> </p> - -<div class="panel panel_list_packages"> - - <div class="pnl_listarea"> - <table class="list"> - <tbody> - <tmpl_if name='next_tab' op='==' value='details'> - <tr class="tbl_row_uneven"> - <td width="25%">{tmpl_var name='version_txt'}</td> - <td>{tmpl_var name='pkg_version'} (Release {tmpl_var name='pkg_release'})</td> - </tr> - <tr class="tbl_row_even"> - <td>{tmpl_var name='category_txt'}</td> - <td>{tmpl_var name='pkg_category'}</td> - </tr> - <tr class="tbl_row_uneven"> - <td>{tmpl_var name='description_txt'}</td> - <td>{tmpl_var name='pkg_description'}</td> - </tr> - <tr class="tbl_row_even"> - <td>{tmpl_var name='homepage_txt'}</td> - <td> - <a href="{tmpl_var name='pkg_homepage'}" target="_blank">{tmpl_var name='pkg_homepage'}</a> - </td> - </tr> - <tr class="tbl_row_uneven"> - <td>{tmpl_var name='installed_size_txt'}</td> - <td>{tmpl_var name='pkg_installed_size'}</td> - </tr> - <tr class="tbl_row_even"> - <td>{tmpl_var name='supported_languages_txt'}</td> - <td>{tmpl_var name='pkg_languages'}</td> - </tr> - <tr class="tbl_row_uneven"> - <td>{tmpl_var name='config_script_txt'}</td> - <td>{tmpl_var name='pkg_config_script'}</td> - </tr> - <tr class="tbl_row_even"> - <td>{tmpl_var name='license_txt'}</td> - <td> - <tmpl_if name='pkg_license_name'>{tmpl_var name='pkg_license_name'}<br /></tmpl_if> - <tmpl_if name='pkg_license_type' op='==' value='url'><a href="{tmpl_var name='pkg_license_content'}" target="_blank">{tmpl_var name='pkg_license_content'}</a> - <tmpl_elseif name='pkg_license_content'> - <textarea rows="10" cols="80">{tmpl_var name='pkg_license_content'}</textarea> - </tmpl_if> - </td> - </tr> - <tmpl_elseif name='next_tab' op='==' value='screenshots'> - <tmpl_if name='pkg_screenshots'> - <tr class="tbl_row_even"> - <td style="text-align:center;"> - <tmpl_loop name='pkg_screenshots'> - <img src="{tmpl_var name='ScreenPath'}" alt="{tmpl_var name='ScreenDescription'}" /><br /> - <em>{tmpl_var name='ScreenDescription'}</em><br /><br /> - </tmpl_loop> - </td> - </tr> - </tmpl_if> - <tmpl_elseif name='next_tab' op='==' value='changelog'> - <tmpl_if name='pkg_changelog'> - <tr class="tbl_row_even"> - <td> - <ul> - <tmpl_loop name='pkg_changelog'> - <li>{tmpl_var name='ChangelogVersion'}</li> - <ul> - <tmpl_if name='ChangelogDescription'> - <li>{tmpl_var name='ChangelogDescription'}</li> - </tmpl_if> - </ul> - </tmpl_loop> - </ul> - </td> - </tr> - </tmpl_if> - <tmpl_elseif name='next_tab' op='==' value='settings'> - <tr class="tbl_row_uneven"> - <td width="25%">{tmpl_var name='php_extensions_txt'}</td> - <td>{tmpl_var name='pkg_requirements_php_extensions'}</td> - </tr> - <tr class="tbl_row_even"> - <td>{tmpl_var name='php_settings_txt'}</td> - <td> - <tmpl_loop name='pkg_requirements_php_settings'>{tmpl_var name='PHPSettingName'} = {tmpl_var name='PHPSettingValue'}<br /></tmpl_loop> - </td> - </tr> - <tr class="tbl_row_uneven"> - <td>{tmpl_var name='supported_php_versions_txt'}</td> - <td>{tmpl_var name='pkg_requirements_supported_php_versions'}</td> - </tr> - <tr class="tbl_row_even"> - <td>{tmpl_var name='database_txt'}</td> - <td>{tmpl_var name='pkg_requirements_database'}</a></td> - </tr> - </tmpl_if> - </tbody> - </table> - </div> - +<h2> + <tmpl_if name='pkg_icon' op='!=' value=''> + <img src="{tmpl_var name='pkg_icon'}" height="32" width="32" alt="{tmpl_var name='pkg_name'}" style="vertical-align:text-bottom;" /> + </tmpl_if> + {tmpl_var name='pkg_name'} +</h2> +<b>{tmpl_var name='pkg_summary'}</b> +<p> </p> + +<div class="pnl_toolsarea"> + <div class="buttons"> + <button class="iconstxt icoAdd" type="button" onClick="loadContent('sites/aps_install_package.php?id={tmpl_var name='pkg_id'}');"> + <span>{tmpl_var name='install_package_txt'}</span> + </button> + </div> + <p> </p><p> </p> +</div> + + +<div class="tabbox_tabs"> + <input type="hidden" name="next_tab" value="" /> + <ul> + <li<tmpl_if name='next_tab' op='==' value='details'> class="active"</tmpl_if>> + <a href="javascript:changeTab('details', 'sites/aps_packagedetails_show.php?id={tmpl_var name='pkg_id'}');">{tmpl_var name='details_txt'}</a> + </li> + <tmpl_if name='pkg_screenshots'> + <li<tmpl_if name='next_tab' op='==' value='screenshots'> class="active"</tmpl_if>> + <a href="javascript:changeTab('screenshots', 'sites/aps_packagedetails_show.php?id={tmpl_var name='pkg_id'}');">{tmpl_var name='screenshots_txt'}</a> + </li></tmpl_if> + <tmpl_if name='pkg_changelog'> + <li<tmpl_if name='next_tab' op='==' value='changelog'> class="active"</tmpl_if>> + <a href="javascript:changeTab('changelog', 'sites/aps_packagedetails_show.php?id={tmpl_var name='pkg_id'}');">{tmpl_var name='changelog_txt'}</a> + </li></tmpl_if> + <li<tmpl_if name='next_tab' op='==' value='settings'> class="active"</tmpl_if>> + <a href="javascript:changeTab('settings', 'sites/aps_packagedetails_show.php?id={tmpl_var name='pkg_id'}');">{tmpl_var name='settings_txt'}</a> + </li> + </ul> +</div> +<p> </p> + +<div class="panel panel_list_packages"> + + <div class="pnl_listarea"> + <table class="list"> + <tbody> + <tmpl_if name='next_tab' op='==' value='details'> + <tr class="tbl_row_uneven"> + <td width="25%">{tmpl_var name='version_txt'}</td> + <td>{tmpl_var name='pkg_version'} (Release {tmpl_var name='pkg_release'})</td> + </tr> + <tr class="tbl_row_even"> + <td>{tmpl_var name='category_txt'}</td> + <td>{tmpl_var name='pkg_category'}</td> + </tr> + <tr class="tbl_row_uneven"> + <td>{tmpl_var name='description_txt'}</td> + <td>{tmpl_var name='pkg_description'}</td> + </tr> + <tr class="tbl_row_even"> + <td>{tmpl_var name='homepage_txt'}</td> + <td> + <a href="{tmpl_var name='pkg_homepage'}" target="_blank">{tmpl_var name='pkg_homepage'}</a> + </td> + </tr> + <tr class="tbl_row_uneven"> + <td>{tmpl_var name='installed_size_txt'}</td> + <td>{tmpl_var name='pkg_installed_size'}</td> + </tr> + <tr class="tbl_row_even"> + <td>{tmpl_var name='supported_languages_txt'}</td> + <td>{tmpl_var name='pkg_languages'}</td> + </tr> + <tr class="tbl_row_uneven"> + <td>{tmpl_var name='config_script_txt'}</td> + <td>{tmpl_var name='pkg_config_script'}</td> + </tr> + <tr class="tbl_row_even"> + <td>{tmpl_var name='license_txt'}</td> + <td> + <tmpl_if name='pkg_license_name'>{tmpl_var name='pkg_license_name'}<br /></tmpl_if> + <tmpl_if name='pkg_license_type' op='==' value='url'><a href="{tmpl_var name='pkg_license_content'}" target="_blank">{tmpl_var name='pkg_license_content'}</a> + <tmpl_elseif name='pkg_license_content'> + <textarea rows="10" cols="80">{tmpl_var name='pkg_license_content'}</textarea> + </tmpl_if> + </td> + </tr> + <tmpl_elseif name='next_tab' op='==' value='screenshots'> + <tmpl_if name='pkg_screenshots'> + <tr class="tbl_row_even"> + <td style="text-align:center;"> + <tmpl_loop name='pkg_screenshots'> + <img src="{tmpl_var name='ScreenPath'}" alt="{tmpl_var name='ScreenDescription'}" /><br /> + <em>{tmpl_var name='ScreenDescription'}</em><br /><br /> + </tmpl_loop> + </td> + </tr> + </tmpl_if> + <tmpl_elseif name='next_tab' op='==' value='changelog'> + <tmpl_if name='pkg_changelog'> + <tr class="tbl_row_even"> + <td> + <ul> + <tmpl_loop name='pkg_changelog'> + <li>{tmpl_var name='ChangelogVersion'}</li> + <ul> + <tmpl_if name='ChangelogDescription'> + <li>{tmpl_var name='ChangelogDescription'}</li> + </tmpl_if> + </ul> + </tmpl_loop> + </ul> + </td> + </tr> + </tmpl_if> + <tmpl_elseif name='next_tab' op='==' value='settings'> + <tr class="tbl_row_uneven"> + <td width="25%">{tmpl_var name='php_extensions_txt'}</td> + <td>{tmpl_var name='pkg_requirements_php_extensions'}</td> + </tr> + <tr class="tbl_row_even"> + <td>{tmpl_var name='php_settings_txt'}</td> + <td> + <tmpl_loop name='pkg_requirements_php_settings'>{tmpl_var name='PHPSettingName'} = {tmpl_var name='PHPSettingValue'}<br /></tmpl_loop> + </td> + </tr> + <tr class="tbl_row_uneven"> + <td>{tmpl_var name='supported_php_versions_txt'}</td> + <td>{tmpl_var name='pkg_requirements_supported_php_versions'}</td> + </tr> + <tr class="tbl_row_even"> + <td>{tmpl_var name='database_txt'}</td> + <td>{tmpl_var name='pkg_requirements_database'}</a></td> + </tr> + </tmpl_if> + </tbody> + </table> + </div> + </div> \ No newline at end of file diff --git a/interface/web/themes/default-304/templates/sites/aps_packages_list.htm b/interface/web/themes/default-304/templates/sites/aps_packages_list.htm index e7db3e84a4e7b5313658dac83414c8a443f005f1..fe997430398297845e1d4b38b8f0f29d38c57836 100644 --- a/interface/web/themes/default-304/templates/sites/aps_packages_list.htm +++ b/interface/web/themes/default-304/templates/sites/aps_packages_list.htm @@ -1,50 +1,50 @@ -<h2>{tmpl_var name="list_head_txt"}</h2> - -<div class="panel panel_list_packages"> - - <div class="pnl_listarea"> - <fieldset><legend>{tmpl_var name="list_head_txt"} ({tmpl_var name='package_count'})</legend> - <table class="list"> - <thead> - <tr> - <th class="tbl_col_name" scope="col">{tmpl_var name='name_txt'}</th> - <th class="tbl_col_version" scope="col">{tmpl_var name='version_txt'}</th> - <th class="tbl_col_category" scope="col">{tmpl_var name='category_txt'}</th> - <tmpl_if name='is_admin'> - <th class="tbl_col_status" scope="col">{tmpl_var name='status_txt'}</th> - </tmpl_if> - <th class="tbl_col_buttons" scope="col" width="60px;"> </th> - </tr> - <tr> - <td class="tbl_col_name"><input type="text" name="search_name" value="{tmpl_var name='search_name'}" /></td> - <td class="tbl_col_version"><input type="text" name="search_version" value="{tmpl_var name='search_version'}" /></td> - <td class="tbl_col_customerid"><select name="search_category" onChange="submitForm('pageForm','sites/aps_availablepackages_list.php');">{tmpl_var name='search_category'}</select></td> - <tmpl_if name='is_admin'> - <td class="tbl_col_status"><select name="search_package_status" onChange="submitForm('pageForm','sites/aps_availablepackages_list.php');">{tmpl_var name='search_package_status'}</select></td> - </tmpl_if> - <td class="tbl_col_buttons"><button type="button" class="icons16 icoFilter" name="Filter" id="Filter" value="{tmpl_var name='filter_txt'}" onClick="submitForm('pageForm','sites/aps_availablepackages_list.php');"><span>{tmpl_var name='filter_txt'}</span></button></td> - </tr> - </thead> - <tbody> - <tmpl_loop name='records'> - <tr class="tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>"> - <td class="tbl_col_name"><a href="#" onClick="loadContent('sites/aps_packagedetails_show.php?id={tmpl_var name='id'}');">{tmpl_var name='name'}</a></td> - <td class="tbl_col_version">{tmpl_var name='version'}-{tmpl_var name='release'}</td> - <td class="tbl_col_category">{tmpl_var name='category'}</td> - <tmpl_if name='is_admin'> - <td class="tbl_col_status"><a href="javascript:loadContentInto('status_content{tmpl_var name='__ROWNUM__'}', 'sites/aps_do_operation.php?action=change_status&id={tmpl_var name='id'}&phpsessid={tmpl_var name='phpsessid'}');"><span id="status_content{tmpl_var name='__ROWNUM__'}">{tmpl_var name='package_status'}</span></a></td> - </tmpl_if> - <td> </td> - </tr> - </tmpl_loop> - </tbody> - <tfoot> - <tr> - <td class="tbl_footer tbl_paging" colspan="5">{tmpl_var name='paging'}</td> - </tr> - </tfoot> - </table> - </fieldset> - </div> - +<h2>{tmpl_var name="list_head_txt"}</h2> + +<div class="panel panel_list_packages"> + + <div class="pnl_listarea"> + <fieldset><legend>{tmpl_var name="list_head_txt"} ({tmpl_var name='package_count'})</legend> + <table class="list"> + <thead> + <tr> + <th class="tbl_col_name" scope="col">{tmpl_var name='name_txt'}</th> + <th class="tbl_col_version" scope="col">{tmpl_var name='version_txt'}</th> + <th class="tbl_col_category" scope="col">{tmpl_var name='category_txt'}</th> + <tmpl_if name='is_admin'> + <th class="tbl_col_status" scope="col">{tmpl_var name='status_txt'}</th> + </tmpl_if> + <th class="tbl_col_buttons" scope="col" width="60px;"> </th> + </tr> + <tr> + <td class="tbl_col_name"><input type="text" name="search_name" value="{tmpl_var name='search_name'}" /></td> + <td class="tbl_col_version"><input type="text" name="search_version" value="{tmpl_var name='search_version'}" /></td> + <td class="tbl_col_customerid"><select name="search_category" onChange="submitForm('pageForm','sites/aps_availablepackages_list.php');">{tmpl_var name='search_category'}</select></td> + <tmpl_if name='is_admin'> + <td class="tbl_col_status"><select name="search_package_status" onChange="submitForm('pageForm','sites/aps_availablepackages_list.php');">{tmpl_var name='search_package_status'}</select></td> + </tmpl_if> + <td class="tbl_col_buttons"><button type="button" class="icons16 icoFilter" name="Filter" id="Filter" value="{tmpl_var name='filter_txt'}" onClick="submitForm('pageForm','sites/aps_availablepackages_list.php');"><span>{tmpl_var name='filter_txt'}</span></button></td> + </tr> + </thead> + <tbody> + <tmpl_loop name='records'> + <tr class="tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>"> + <td class="tbl_col_name"><a href="#" onClick="loadContent('sites/aps_packagedetails_show.php?id={tmpl_var name='id'}');">{tmpl_var name='name'}</a></td> + <td class="tbl_col_version">{tmpl_var name='version'}-{tmpl_var name='release'}</td> + <td class="tbl_col_category">{tmpl_var name='category'}</td> + <tmpl_if name='is_admin'> + <td class="tbl_col_status"><a href="javascript:loadContentInto('status_content{tmpl_var name='__ROWNUM__'}', 'sites/aps_do_operation.php?action=change_status&id={tmpl_var name='id'}&phpsessid={tmpl_var name='phpsessid'}');"><span id="status_content{tmpl_var name='__ROWNUM__'}">{tmpl_var name='package_status'}</span></a></td> + </tmpl_if> + <td> </td> + </tr> + </tmpl_loop> + </tbody> + <tfoot> + <tr> + <td class="tbl_footer tbl_paging" colspan="5">{tmpl_var name='paging'}</td> + </tr> + </tfoot> + </table> + </fieldset> + </div> + </div> \ No newline at end of file diff --git a/interface/web/themes/default/CHANGELOG b/interface/web/themes/default/CHANGELOG index cae152a05c5b9b204c0f6c31e13c0ad99f6b5339..454964210b1c78a57d230d7230ffbaf243d4ce40 100644 --- a/interface/web/themes/default/CHANGELOG +++ b/interface/web/themes/default/CHANGELOG @@ -1,32 +1,32 @@ -CHANGELOG -default -> default-v2 -source: default $3241 07/06/2012 @ 12:00 UTC+2 -resources @ https://github.com/foe-services/ispc-resources - -- changed doctype to <!DOCTYPE html> (HTML5) -- rm yaml/* -- rm css/patches/* -- cp yaml/patches/iehacks.css css/* -- rm <!--[if lte ie 6]> from templates/main.tpl.htm -- rm IE6 support from css/iehacks.css -- mv css/nav/* into css/style.css -- mv css/print/* into css/print.css -- add css/print.css to templates/main.tpl.htm -- rm css/print/* -- rm css/nav/* -- rm css projection-type support -- mv css/screen/redmond/* css/* -- rm css/screen/* -- mv css media-recognition from css-files to <head>-link tag -- change most div-containers to new html5 tags in main.tpl.htm -- rm dom elements from main.tpl.htm -- add html5shiv.js (https://github.com/aFarkas/html5shiv) for better HTML5-compatibility -- reduction of dom elements -- reduction of css rules -- removed all single icons - - all icons separate: https://github.com/downloads/foe-services/ispc-larry/ispc-default_separate.zip - - all used icons as layers and sprite as .psd: https://github.com/downloads/foe-services/ispc-larry/ispc-default_psd.zip -- added sprites for (nearly) all used icons where suitable -- added flags for country text in lists -- added some list column widths +CHANGELOG +default -> default-v2 +source: default $3241 07/06/2012 @ 12:00 UTC+2 +resources @ https://github.com/foe-services/ispc-resources + +- changed doctype to <!DOCTYPE html> (HTML5) +- rm yaml/* +- rm css/patches/* +- cp yaml/patches/iehacks.css css/* +- rm <!--[if lte ie 6]> from templates/main.tpl.htm +- rm IE6 support from css/iehacks.css +- mv css/nav/* into css/style.css +- mv css/print/* into css/print.css +- add css/print.css to templates/main.tpl.htm +- rm css/print/* +- rm css/nav/* +- rm css projection-type support +- mv css/screen/redmond/* css/* +- rm css/screen/* +- mv css media-recognition from css-files to <head>-link tag +- change most div-containers to new html5 tags in main.tpl.htm +- rm dom elements from main.tpl.htm +- add html5shiv.js (https://github.com/aFarkas/html5shiv) for better HTML5-compatibility +- reduction of dom elements +- reduction of css rules +- removed all single icons + - all icons separate: https://github.com/downloads/foe-services/ispc-larry/ispc-default_separate.zip + - all used icons as layers and sprite as .psd: https://github.com/downloads/foe-services/ispc-larry/ispc-default_psd.zip +- added sprites for (nearly) all used icons where suitable +- added flags for country text in lists +- added some list column widths - limited height (500px) for the globalsearch results \ No newline at end of file diff --git a/interface/web/themes/default/TODO b/interface/web/themes/default/TODO index b39fb99faa9911186dd0bf40b116bb720f462504..177a86333628eae224444fb622956054852df473 100644 --- a/interface/web/themes/default/TODO +++ b/interface/web/themes/default/TODO @@ -1,8 +1,8 @@ -TODO -- css/print.css is useless in current state -- css/iehacks.css is useless in current state -- some more icons need to be changed into sprites - -- <html dir="ltr" lang="en-US"> set lang variable with data from the user data or config data - +TODO +- css/print.css is useless in current state +- css/iehacks.css is useless in current state +- some more icons need to be changed into sprites + +- <html dir="ltr" lang="en-US"> set lang variable with data from the user data or config data + - Lists of servers in monitor module break in IE7 + IE8 \ No newline at end of file diff --git a/interface/web/themes/default/css/jquery-ui-1.8.16.custom.css b/interface/web/themes/default/css/jquery-ui-1.8.16.custom.css index 54dfd6573ec6a0e3200aa63d439645a2cd13c72d..cf52f36c58f61e21c7051bd0342d486d802b2e66 100644 --- a/interface/web/themes/default/css/jquery-ui-1.8.16.custom.css +++ b/interface/web/themes/default/css/jquery-ui-1.8.16.custom.css @@ -1,446 +1,446 @@ -/* - * jQuery UI CSS Framework 1.8.16 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Theming/API - */ - -/* Layout helpers -----------------------------------*/ -.ui-helper-hidden { display: none; } -.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); } -.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } -.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } -.ui-helper-clearfix { display: inline-block; } -/* required comment for clearfix to work in Opera \*/ -* html .ui-helper-clearfix { height:1%; } -.ui-helper-clearfix { display:block; } -/* end clearfix */ -.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } - - -/* Interaction Cues -----------------------------------*/ -.ui-state-disabled { cursor: default !important; } - - -/* Icons -----------------------------------*/ - -/* states and images */ -.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } - - -/* Misc visuals -----------------------------------*/ - -/* Overlays */ -.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } - - -/* - * jQuery UI CSS Framework 1.8.16 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Theming/API - * - * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Lucida%20Grande,%20Lucida%20Sans,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=0px&bgColorHeader=5c9ccc&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=55&borderColorHeader=4297d7&fcHeader=ffffff&iconColorHeader=d8e7f3&bgColorContent=fcfdfd&bgTextureContent=06_inset_hard.png&bgImgOpacityContent=100&borderColorContent=a6c9e2&fcContent=222222&iconColorContent=469bdd&bgColorDefault=dfeffc&bgTextureDefault=02_glass.png&bgImgOpacityDefault=85&borderColorDefault=c5dbec&fcDefault=2e6e9e&iconColorDefault=6da8d5&bgColorHover=d0e5f5&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=79b7e7&fcHover=1d5987&iconColorHover=217bc0&bgColorActive=f5f8f9&bgTextureActive=06_inset_hard.png&bgImgOpacityActive=100&borderColorActive=79b7e7&fcActive=e17009&iconColorActive=f9bd01&bgColorHighlight=fbec88&bgTextureHighlight=01_flat.png&bgImgOpacityHighlight=55&borderColorHighlight=fad42e&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=0px - */ - - -/* Component containers -----------------------------------*/ -/*.ui-widget { font-family: Lucida Grande, Lucida Sans, Arial, sans-serif; font-size: 1.1em; }*/ -.ui-widget { font-size: 1.1em; } -.ui-widget .ui-widget { font-size: 1em; } -.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-size: 1em; } -.ui-widget-content { border: 1px solid #a6c9e2; background: #fcfdfd url(images/ui-bg_inset-hard_100_fcfdfd_1x100.png) 50% bottom repeat-x; color: #222222; } -.ui-widget-content a { color: #222222; } -.ui-widget-header { border: 1px solid #4297d7; background: #5c9ccc url(images/ui-bg_gloss-wave_55_5c9ccc_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; } -.ui-widget-header a { color: #ffffff; } - -/* Interaction states -----------------------------------*/ -.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #c5dbec; background: #dfeffc url(images/ui-bg_glass_85_dfeffc_1x400.png) 50% 50% repeat-x; font-weight: bold; /*color: #2e6e9e;*/ } -.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #2e6e9e; text-decoration: none; } -.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #79b7e7; background: #d0e5f5 url(images/ui-bg_glass_75_d0e5f5_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1d5987; } -.ui-state-hover a, .ui-state-hover a:hover { color: #1d5987; text-decoration: none; } -.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #79b7e7; background: #f5f8f9 url(images/ui-bg_inset-hard_100_f5f8f9_1x100.png) 50% 50% repeat-x; font-weight: bold; color: #e17009; } -.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #e17009; text-decoration: none; } -.ui-widget :active { outline: none; } - -/* Interaction Cues -----------------------------------*/ -.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fad42e; background: #fbec88 url(images/ui-bg_flat_55_fbec88_40x100.png) 50% 50% repeat-x; color: #363636; } -.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; } -.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; } -.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; } -.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; } -.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } -.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } -.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } - -/* Icons -----------------------------------*/ - -/* states and images */ -.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_469bdd_256x240.png); } -.ui-widget-content .ui-icon {background-image: url(images/ui-icons_469bdd_256x240.png); } -.ui-widget-header .ui-icon {background-image: url(images/ui-icons_d8e7f3_256x240.png); } -.ui-state-default .ui-icon { background-image: url(images/ui-icons_6da8d5_256x240.png); } -.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_217bc0_256x240.png); } -.ui-state-active .ui-icon {background-image: url(images/ui-icons_f9bd01_256x240.png); } -.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); } -.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); } - -/* positioning */ -.ui-icon-carat-1-n { background-position: 0 0; } -.ui-icon-carat-1-ne { background-position: -16px 0; } -.ui-icon-carat-1-e { background-position: -32px 0; } -.ui-icon-carat-1-se { background-position: -48px 0; } -.ui-icon-carat-1-s { background-position: -64px 0; } -.ui-icon-carat-1-sw { background-position: -80px 0; } -.ui-icon-carat-1-w { background-position: -96px 0; } -.ui-icon-carat-1-nw { background-position: -112px 0; } -.ui-icon-carat-2-n-s { background-position: -128px 0; } -.ui-icon-carat-2-e-w { background-position: -144px 0; } -.ui-icon-triangle-1-n { background-position: 0 -16px; } -.ui-icon-triangle-1-ne { background-position: -16px -16px; } -.ui-icon-triangle-1-e { background-position: -32px -16px; } -.ui-icon-triangle-1-se { background-position: -48px -16px; } -.ui-icon-triangle-1-s { background-position: -64px -16px; } -.ui-icon-triangle-1-sw { background-position: -80px -16px; } -.ui-icon-triangle-1-w { background-position: -96px -16px; } -.ui-icon-triangle-1-nw { background-position: -112px -16px; } -.ui-icon-triangle-2-n-s { background-position: -128px -16px; } -.ui-icon-triangle-2-e-w { background-position: -144px -16px; } -.ui-icon-arrow-1-n { background-position: 0 -32px; } -.ui-icon-arrow-1-ne { background-position: -16px -32px; } -.ui-icon-arrow-1-e { background-position: -32px -32px; } -.ui-icon-arrow-1-se { background-position: -48px -32px; } -.ui-icon-arrow-1-s { background-position: -64px -32px; } -.ui-icon-arrow-1-sw { background-position: -80px -32px; } -.ui-icon-arrow-1-w { background-position: -96px -32px; } -.ui-icon-arrow-1-nw { background-position: -112px -32px; } -.ui-icon-arrow-2-n-s { background-position: -128px -32px; } -.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } -.ui-icon-arrow-2-e-w { background-position: -160px -32px; } -.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } -.ui-icon-arrowstop-1-n { background-position: -192px -32px; } -.ui-icon-arrowstop-1-e { background-position: -208px -32px; } -.ui-icon-arrowstop-1-s { background-position: -224px -32px; } -.ui-icon-arrowstop-1-w { background-position: -240px -32px; } -.ui-icon-arrowthick-1-n { background-position: 0 -48px; } -.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } -.ui-icon-arrowthick-1-e { background-position: -32px -48px; } -.ui-icon-arrowthick-1-se { background-position: -48px -48px; } -.ui-icon-arrowthick-1-s { background-position: -64px -48px; } -.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } -.ui-icon-arrowthick-1-w { background-position: -96px -48px; } -.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } -.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } -.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } -.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } -.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } -.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } -.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } -.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } -.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } -.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } -.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } -.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } -.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } -.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } -.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } -.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } -.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } -.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } -.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } -.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } -.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } -.ui-icon-arrow-4 { background-position: 0 -80px; } -.ui-icon-arrow-4-diag { background-position: -16px -80px; } -.ui-icon-extlink { background-position: -32px -80px; } -.ui-icon-newwin { background-position: -48px -80px; } -.ui-icon-refresh { background-position: -64px -80px; } -.ui-icon-shuffle { background-position: -80px -80px; } -.ui-icon-transfer-e-w { background-position: -96px -80px; } -.ui-icon-transferthick-e-w { background-position: -112px -80px; } -.ui-icon-folder-collapsed { background-position: 0 -96px; } -.ui-icon-folder-open { background-position: -16px -96px; } -.ui-icon-document { background-position: -32px -96px; } -.ui-icon-document-b { background-position: -48px -96px; } -.ui-icon-note { background-position: -64px -96px; } -.ui-icon-mail-closed { background-position: -80px -96px; } -.ui-icon-mail-open { background-position: -96px -96px; } -.ui-icon-suitcase { background-position: -112px -96px; } -.ui-icon-comment { background-position: -128px -96px; } -.ui-icon-person { background-position: -144px -96px; } -.ui-icon-print { background-position: -160px -96px; } -.ui-icon-trash { background-position: -176px -96px; } -.ui-icon-locked { background-position: -192px -96px; } -.ui-icon-unlocked { background-position: -208px -96px; } -.ui-icon-bookmark { background-position: -224px -96px; } -.ui-icon-tag { background-position: -240px -96px; } -.ui-icon-home { background-position: 0 -112px; } -.ui-icon-flag { background-position: -16px -112px; } -.ui-icon-calendar { background-position: -32px -112px; } -.ui-icon-cart { background-position: -48px -112px; } -.ui-icon-pencil { background-position: -64px -112px; } -.ui-icon-clock { background-position: -80px -112px; } -.ui-icon-disk { background-position: -96px -112px; } -.ui-icon-calculator { background-position: -112px -112px; } -.ui-icon-zoomin { background-position: -128px -112px; } -.ui-icon-zoomout { background-position: -144px -112px; } -.ui-icon-search { background-position: -160px -112px; } -.ui-icon-wrench { background-position: -176px -112px; } -.ui-icon-gear { background-position: -192px -112px; } -.ui-icon-heart { background-position: -208px -112px; } -.ui-icon-star { background-position: -224px -112px; } -.ui-icon-link { background-position: -240px -112px; } -.ui-icon-cancel { background-position: 0 -128px; } -.ui-icon-plus { background-position: -16px -128px; } -.ui-icon-plusthick { background-position: -32px -128px; } -.ui-icon-minus { background-position: -48px -128px; } -.ui-icon-minusthick { background-position: -64px -128px; } -.ui-icon-close { background-position: -80px -128px; } -.ui-icon-closethick { background-position: -96px -128px; } -.ui-icon-key { background-position: -112px -128px; } -.ui-icon-lightbulb { background-position: -128px -128px; } -.ui-icon-scissors { background-position: -144px -128px; } -.ui-icon-clipboard { background-position: -160px -128px; } -.ui-icon-copy { background-position: -176px -128px; } -.ui-icon-contact { background-position: -192px -128px; } -.ui-icon-image { background-position: -208px -128px; } -.ui-icon-video { background-position: -224px -128px; } -.ui-icon-script { background-position: -240px -128px; } -.ui-icon-alert { background-position: 0 -144px; } -.ui-icon-info { background-position: -16px -144px; } -.ui-icon-notice { background-position: -32px -144px; } -.ui-icon-help { background-position: -48px -144px; } -.ui-icon-check { background-position: -64px -144px; } -.ui-icon-bullet { background-position: -80px -144px; } -.ui-icon-radio-off { background-position: -96px -144px; } -.ui-icon-radio-on { background-position: -112px -144px; } -.ui-icon-pin-w { background-position: -128px -144px; } -.ui-icon-pin-s { background-position: -144px -144px; } -.ui-icon-play { background-position: 0 -160px; } -.ui-icon-pause { background-position: -16px -160px; } -.ui-icon-seek-next { background-position: -32px -160px; } -.ui-icon-seek-prev { background-position: -48px -160px; } -.ui-icon-seek-end { background-position: -64px -160px; } -.ui-icon-seek-start { background-position: -80px -160px; } -/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ -.ui-icon-seek-first { background-position: -80px -160px; } -.ui-icon-stop { background-position: -96px -160px; } -.ui-icon-eject { background-position: -112px -160px; } -.ui-icon-volume-off { background-position: -128px -160px; } -.ui-icon-volume-on { background-position: -144px -160px; } -.ui-icon-power { background-position: 0 -176px; } -.ui-icon-signal-diag { background-position: -16px -176px; } -.ui-icon-signal { background-position: -32px -176px; } -.ui-icon-battery-0 { background-position: -48px -176px; } -.ui-icon-battery-1 { background-position: -64px -176px; } -.ui-icon-battery-2 { background-position: -80px -176px; } -.ui-icon-battery-3 { background-position: -96px -176px; } -.ui-icon-circle-plus { background-position: 0 -192px; } -.ui-icon-circle-minus { background-position: -16px -192px; } -.ui-icon-circle-close { background-position: -32px -192px; } -.ui-icon-circle-triangle-e { background-position: -48px -192px; } -.ui-icon-circle-triangle-s { background-position: -64px -192px; } -.ui-icon-circle-triangle-w { background-position: -80px -192px; } -.ui-icon-circle-triangle-n { background-position: -96px -192px; } -.ui-icon-circle-arrow-e { background-position: -112px -192px; } -.ui-icon-circle-arrow-s { background-position: -128px -192px; } -.ui-icon-circle-arrow-w { background-position: -144px -192px; } -.ui-icon-circle-arrow-n { background-position: -160px -192px; } -.ui-icon-circle-zoomin { background-position: -176px -192px; } -.ui-icon-circle-zoomout { background-position: -192px -192px; } -.ui-icon-circle-check { background-position: -208px -192px; } -.ui-icon-circlesmall-plus { background-position: 0 -208px; } -.ui-icon-circlesmall-minus { background-position: -16px -208px; } -.ui-icon-circlesmall-close { background-position: -32px -208px; } -.ui-icon-squaresmall-plus { background-position: -48px -208px; } -.ui-icon-squaresmall-minus { background-position: -64px -208px; } -.ui-icon-squaresmall-close { background-position: -80px -208px; } -.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } -.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } -.ui-icon-grip-solid-vertical { background-position: -32px -224px; } -.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } -.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } -.ui-icon-grip-diagonal-se { background-position: -80px -224px; } - - -/* Misc visuals -----------------------------------*/ - -/* Corner radius */ - -/* Overlays */ -.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); } -.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); }/* - * jQuery UI Autocomplete 1.8.16 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Autocomplete#theming - */ -.ui-autocomplete { position: absolute; cursor: default; } - -/* workarounds */ -* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ - -/* - * jQuery UI Menu 1.8.16 - * - * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Menu#theming - */ -.ui-menu { - list-style:none; - padding: 2px; - margin: 0; - display:block; - float: left; -} -.ui-menu .ui-menu { - margin-top: -3px; -} -.ui-menu .ui-menu-item { - margin:0; - padding: 0; - zoom: 1; - float: left; - clear: left; - width: 100%; -} -.ui-menu .ui-menu-item a { - text-decoration:none; - display:block; - padding:.2em .4em; - line-height:1.5; - white-space: nowrap; - zoom:1; -} -.ui-menu .ui-menu-item a.ui-state-hover, -.ui-menu .ui-menu-item a.ui-state-active { - font-weight: normal; - margin: -1px; -} -/* - * jQuery UI Button 1.8.16 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Button#theming - */ -.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ -.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ -button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ -.ui-button-icons-only { width: 3.4em; } -button.ui-button-icons-only { width: 3.7em; } - -/*button text element */ -.ui-button .ui-button-text { display: block; line-height: 1.4; } -.ui-button-text-only .ui-button-text { padding: .4em 1em; } -.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; } -.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } -.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; } -.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } -/* no icon support for input elements, provide padding by default */ -input.ui-button { padding: .4em 1em; } - -/*button icon element(s) */ -.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } -.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } -.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } -.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } -.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } - -/*button sets*/ -.ui-buttonset { margin-right: 7px; } -.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; } - -/* workarounds */ -button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ -/* - * jQuery UI Datepicker 1.8.16 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Datepicker#theming - */ -.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; } -.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } -.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } -.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } -.ui-datepicker .ui-datepicker-prev { left:2px; } -.ui-datepicker .ui-datepicker-next { right:2px; } -.ui-datepicker .ui-datepicker-prev-hover { left:1px; } -.ui-datepicker .ui-datepicker-next-hover { right:1px; } -.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } -.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } -.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; } -.ui-datepicker select.ui-datepicker-month-year {width: 100%;} -.ui-datepicker select.ui-datepicker-month, -.ui-datepicker select.ui-datepicker-year { width: 49%;} -.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } -.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } -.ui-datepicker td { border: 0; padding: 1px; } -.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } -.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } -.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } -.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } - -/* with multiple calendars */ -.ui-datepicker.ui-datepicker-multi { width:auto; } -.ui-datepicker-multi .ui-datepicker-group { float:left; } -.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } -.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } -.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } -.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } -.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } -.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } -.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } -.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; } - -/* RTL support */ -.ui-datepicker-rtl { direction: rtl; } -.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } -.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } -.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } -.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } -.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } -.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } -.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } -.ui-datepicker-rtl .ui-datepicker-group { float:right; } -.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } -.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } - -/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ -.ui-datepicker-cover { - display: none; /*sorry for IE5*/ - display/**/: block; /*sorry for IE5*/ - position: absolute; /*must have*/ - z-index: -1; /*must have*/ - filter: mask(); /*must have*/ - top: -4px; /*must have*/ - left: -4px; /*must have*/ - width: 200px; /*must have*/ - height: 200px; /*must have*/ +/* + * jQuery UI CSS Framework 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + */ + +/* Layout helpers +----------------------------------*/ +.ui-helper-hidden { display: none; } +.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); } +.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } +.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } +.ui-helper-clearfix { display: inline-block; } +/* required comment for clearfix to work in Opera \*/ +* html .ui-helper-clearfix { height:1%; } +.ui-helper-clearfix { display:block; } +/* end clearfix */ +.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } + + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { cursor: default !important; } + + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } + + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } + + +/* + * jQuery UI CSS Framework 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + * + * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Lucida%20Grande,%20Lucida%20Sans,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=0px&bgColorHeader=5c9ccc&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=55&borderColorHeader=4297d7&fcHeader=ffffff&iconColorHeader=d8e7f3&bgColorContent=fcfdfd&bgTextureContent=06_inset_hard.png&bgImgOpacityContent=100&borderColorContent=a6c9e2&fcContent=222222&iconColorContent=469bdd&bgColorDefault=dfeffc&bgTextureDefault=02_glass.png&bgImgOpacityDefault=85&borderColorDefault=c5dbec&fcDefault=2e6e9e&iconColorDefault=6da8d5&bgColorHover=d0e5f5&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=79b7e7&fcHover=1d5987&iconColorHover=217bc0&bgColorActive=f5f8f9&bgTextureActive=06_inset_hard.png&bgImgOpacityActive=100&borderColorActive=79b7e7&fcActive=e17009&iconColorActive=f9bd01&bgColorHighlight=fbec88&bgTextureHighlight=01_flat.png&bgImgOpacityHighlight=55&borderColorHighlight=fad42e&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=0px + */ + + +/* Component containers +----------------------------------*/ +/*.ui-widget { font-family: Lucida Grande, Lucida Sans, Arial, sans-serif; font-size: 1.1em; }*/ +.ui-widget { font-size: 1.1em; } +.ui-widget .ui-widget { font-size: 1em; } +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-size: 1em; } +.ui-widget-content { border: 1px solid #a6c9e2; background: #fcfdfd url(images/ui-bg_inset-hard_100_fcfdfd_1x100.png) 50% bottom repeat-x; color: #222222; } +.ui-widget-content a { color: #222222; } +.ui-widget-header { border: 1px solid #4297d7; background: #5c9ccc url(images/ui-bg_gloss-wave_55_5c9ccc_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; } +.ui-widget-header a { color: #ffffff; } + +/* Interaction states +----------------------------------*/ +.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #c5dbec; background: #dfeffc url(images/ui-bg_glass_85_dfeffc_1x400.png) 50% 50% repeat-x; font-weight: bold; /*color: #2e6e9e;*/ } +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #2e6e9e; text-decoration: none; } +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #79b7e7; background: #d0e5f5 url(images/ui-bg_glass_75_d0e5f5_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1d5987; } +.ui-state-hover a, .ui-state-hover a:hover { color: #1d5987; text-decoration: none; } +.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #79b7e7; background: #f5f8f9 url(images/ui-bg_inset-hard_100_f5f8f9_1x100.png) 50% 50% repeat-x; font-weight: bold; color: #e17009; } +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #e17009; text-decoration: none; } +.ui-widget :active { outline: none; } + +/* Interaction Cues +----------------------------------*/ +.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fad42e; background: #fbec88 url(images/ui-bg_flat_55_fbec88_40x100.png) 50% 50% repeat-x; color: #363636; } +.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; } +.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; } +.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; } +.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; } +.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } +.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } +.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_469bdd_256x240.png); } +.ui-widget-content .ui-icon {background-image: url(images/ui-icons_469bdd_256x240.png); } +.ui-widget-header .ui-icon {background-image: url(images/ui-icons_d8e7f3_256x240.png); } +.ui-state-default .ui-icon { background-image: url(images/ui-icons_6da8d5_256x240.png); } +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_217bc0_256x240.png); } +.ui-state-active .ui-icon {background-image: url(images/ui-icons_f9bd01_256x240.png); } +.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); } +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); } + +/* positioning */ +.ui-icon-carat-1-n { background-position: 0 0; } +.ui-icon-carat-1-ne { background-position: -16px 0; } +.ui-icon-carat-1-e { background-position: -32px 0; } +.ui-icon-carat-1-se { background-position: -48px 0; } +.ui-icon-carat-1-s { background-position: -64px 0; } +.ui-icon-carat-1-sw { background-position: -80px 0; } +.ui-icon-carat-1-w { background-position: -96px 0; } +.ui-icon-carat-1-nw { background-position: -112px 0; } +.ui-icon-carat-2-n-s { background-position: -128px 0; } +.ui-icon-carat-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -64px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -64px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 0 -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-off { background-position: -96px -144px; } +.ui-icon-radio-on { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-start { background-position: -80px -160px; } +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/* Misc visuals +----------------------------------*/ + +/* Corner radius */ + +/* Overlays */ +.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); } +.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); }/* + * jQuery UI Autocomplete 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Autocomplete#theming + */ +.ui-autocomplete { position: absolute; cursor: default; } + +/* workarounds */ +* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ + +/* + * jQuery UI Menu 1.8.16 + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Menu#theming + */ +.ui-menu { + list-style:none; + padding: 2px; + margin: 0; + display:block; + float: left; +} +.ui-menu .ui-menu { + margin-top: -3px; +} +.ui-menu .ui-menu-item { + margin:0; + padding: 0; + zoom: 1; + float: left; + clear: left; + width: 100%; +} +.ui-menu .ui-menu-item a { + text-decoration:none; + display:block; + padding:.2em .4em; + line-height:1.5; + white-space: nowrap; + zoom:1; +} +.ui-menu .ui-menu-item a.ui-state-hover, +.ui-menu .ui-menu-item a.ui-state-active { + font-weight: normal; + margin: -1px; +} +/* + * jQuery UI Button 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Button#theming + */ +.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ +.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ +button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ +.ui-button-icons-only { width: 3.4em; } +button.ui-button-icons-only { width: 3.7em; } + +/*button text element */ +.ui-button .ui-button-text { display: block; line-height: 1.4; } +.ui-button-text-only .ui-button-text { padding: .4em 1em; } +.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; } +.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } +.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; } +.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } +/* no icon support for input elements, provide padding by default */ +input.ui-button { padding: .4em 1em; } + +/*button icon element(s) */ +.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } +.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } +.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } +.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } +.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } + +/*button sets*/ +.ui-buttonset { margin-right: 7px; } +.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; } + +/* workarounds */ +button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ +/* + * jQuery UI Datepicker 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Datepicker#theming + */ +.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; } +.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } +.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } +.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } +.ui-datepicker .ui-datepicker-prev { left:2px; } +.ui-datepicker .ui-datepicker-next { right:2px; } +.ui-datepicker .ui-datepicker-prev-hover { left:1px; } +.ui-datepicker .ui-datepicker-next-hover { right:1px; } +.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } +.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } +.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; } +.ui-datepicker select.ui-datepicker-month-year {width: 100%;} +.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { width: 49%;} +.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } +.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } +.ui-datepicker td { border: 0; padding: 1px; } +.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } +.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } +.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } + +/* with multiple calendars */ +.ui-datepicker.ui-datepicker-multi { width:auto; } +.ui-datepicker-multi .ui-datepicker-group { float:left; } +.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } +.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } +.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } +.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } +.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; } + +/* RTL support */ +.ui-datepicker-rtl { direction: rtl; } +.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } +.ui-datepicker-rtl .ui-datepicker-group { float:right; } +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } + +/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ +.ui-datepicker-cover { + display: none; /*sorry for IE5*/ + display/**/: block; /*sorry for IE5*/ + position: absolute; /*must have*/ + z-index: -1; /*must have*/ + filter: mask(); /*must have*/ + top: -4px; /*must have*/ + left: -4px; /*must have*/ + width: 200px; /*must have*/ + height: 200px; /*must have*/ } \ No newline at end of file diff --git a/interface/web/themes/default/css/styles.css b/interface/web/themes/default/css/styles.css index c937f96de0e804557e31a5adef9d334fc685e555..08dfb8973b321831893d8f218708c7e927b38864 100644 --- a/interface/web/themes/default/css/styles.css +++ b/interface/web/themes/default/css/styles.css @@ -1,1866 +1,1866 @@ -@charset "UTF-8"; -/* - Document : styles.css - Created on : 06.07.2012, 12:21:59 - Author : Christian Foellmann (foe-services.de) - Description: - Basis was css-code from the "ISPConfig 3: default theme" which was based on - "Yet Another Multicolumn Layout" - (X)HTML/CSS Framework 3.0.6 - by Copyright 2005-2008, Dirk Jesse (http://www.yaml.de) -*/ - -/* overall --------------------------------------------------------------- */ -* { - margin: 0; - padding: 0; -} -html * { font-size: 100.01% } -body { - font-family: "Trebuchet MS", sans-serif; - font-size: 75.00%; - color: #444; - background: url("../images/screen_bg.png") repeat-x top left fixed #EEEEEE; - padding: 10px 0; -} -ul, ol, dl { line-height: 1.5em; margin: 0 0 1em 1em } -li { margin-left: 1.5em; line-height: 1.5em } -dt { font-weight: bold } -dd { margin: 0 0 1em 2em } -a { - color: #4D87C7; - text-decoration:none; -} -a:focus, -a:hover, -a:active { - color:#182E7A; - text-decoration:underline; -} -hr { - color: #fff; - background:transparent; - margin: 0 0 0.5em 0; - padding: 0 0 0.5em 0; - border:0; - border-bottom: 1px #eee solid; -} -textarea, pre, tt, code { - font-family: Consolas,"Lucida Console","Courier New",monospace; - font-size: 0.9em; -} - -h1,h2,h3,h4,h5,h6 { - font-family: "Trebuchet MS", sans-serif; - font-weight:bold; - color:#666; - margin: 0 0 0.25em 0; -} -h1 { font-size: 200% } /* 24px */ -h2 { font-size: 200% } /* 24px */ -h3 { font-size: 150% } /* 18px */ -h4 { font-size: 133.33% } /* 16px */ -h5 { font-size: 116.67% } /* 14px */ -h6 { font-size: 116.67%; font-style:italic } /* 14px */ - -p { line-height: 1.5em; margin: 0 0 1em 0; } - -cite, blockquote { font-style:italic } -blockquote { margin: 0 0 1em 1.5em } - -strong,b { font-weight: bold } -em,i { font-style:italic } - -pre, code { font-family: monospace; font-size: 1.1em; } - -acronym, abbr { - letter-spacing: .07em; - border-bottom: .1em dashed #c00; - cursor: help; -} - -header, #nav, #main, footer { - clear: both; -} -#page { - min-width: 980px; - max-width: 80%; - background: #fff; - text-align:left; - margin: 0 auto; - padding: 10px; -} -.skip, .hideme, .print { - height: 1px; - left: -1000em; - position: absolute; - top: -1000em; - width: 1px; -} - -/* header --------------------------------------------------------------- */ -header { - position: relative; - color: #faf0e6; - padding: 15px 2em 5px 20px; - background: url("../images/header_bg.png") repeat-x top left #9a9a9a; -} -header h1 { - font-size:2.5em; - letter-spacing:-2px; - line-height:65%; - color: silver; -} -header span { - color: #333333; -} - -/* header/topsubnav --------------------------------------------------------------- */ -#topsubnav { - position:absolute; - top: 10px; - right: 10px; - text-align: right; -} -#topsubnav a { - color: #f0f8ff; - font-weight: normal; - background:transparent; - text-decoration:none; -} -#topsubnav a:focus, -#topsubnav a:hover, -#topsubnav a:active { - text-decoration:underline; - background-color: transparent; -} - -/* nav --------------------------------------------------------------- */ -#topNav ul { - list-style: none; - padding: 0 0 0 20px; - margin: 0; - background: #9a9a9a -} - -#topNav ul li { - display: inline; - margin: 0 2px 0 0; -} - -#topNav a { - background: url("../icons/x32_sprite.png") no-repeat #D3D3D3; - border-top-left-radius:5px; - border-top-right-radius:5px; - color:black; - display:inline-block; - height:20px; - padding-top:37px; - text-align:center; - text-decoration:none; - min-width:78px; -} - -#topNav a:hover { - background-color: #eeeeee; - color: #000000; -} - -#topNav #topNav_current a { - font-weight: bold; - color: black; - background-color: #ffffff; -} -.topnav-tools { background-position: 22px -10px !important; } -.topnav-admin { background-position: 22px -74px !important; } -.topnav-sites { background-position: 22px -523px !important; } -.topnav-monitor { background-position: 22px -585px !important; } -.topnav- { background-position: 22px -650px !important; } -.topnav-help { background-position: 22px -715px !important; } -.topnav-mail { background-position: 22px -780px !important; } -.topnav-mailuser { background-position: 22px -780px !important; } -.topnav-vm { background-position: 22px -842px !important; } -.topnav-domain { background-position: 22px -905px !important; } -.topnav-dns { background-position: 22px -970px !important; } -.topnav-dashboard { background-position: 22px -1035px !important; } -.topnav-client { background-position: 22px -1098px !important; } -.topnav-billing { background-position: 22px -1162px !important; } -#topNav a span { - padding: 0 3px; - } -/* main --------------------------------------------------------------- */ -#main { - background: #fff; - padding: 1em 0; -} - -/* main/sideNav + submenu --------------------------------------------------------------- */ -#sideNav { - width: 200px; - float:left; - padding: 0 10px 0 0; -} - -#submenu { - width: 100%; - overflow: hidden; - margin: 0px; - list-style-type: none; - border-bottom: 2px #ddd solid; -} - -#submenu ul { - list-style-type: none; - margin:0; - padding: 0; -} -#submenu li { - float:left; - width: 100%; - margin:0; - padding: 0; - font-size:0.9em; -} - -#submenu a, -#submenu strong { - display:block; - width: 90%; - padding: 2px 0px 2px 10%; - text-decoration: none; - background-color:#fff; - color: #444; - border-bottom: 1px #eee solid; -} - -/* Menu Title */ -#submenu li.title { - width: 100%; - padding: 0px; - font-weight: bold; - color: #444; - background-color: #fff; - border-top: 2px #888 solid; - font-size: 1.1em; -} - -#submenu li.title a { - background-color: #f0f8ff; - color: #444; -} -#submenu li.title a:hover { - color: white; -} - -#submenu li span { - display:block; - width: 90%; - padding: 3px 0px 3px 10%; - font-weight: bold; - border-bottom: 1px #ddd solid; -} - -/* Level 1 */ -#submenu li.active, -#submenu li strong { - width: 90%; - padding: 3px 0px 3px 10%; - font-weight: bold; - color: #fff; - background-color:#aab; - border-bottom: 1px #eee solid; -} - -#submenu li a { - width: 90%; - padding-left: 10%; - background-color:#fff; - color: #444; -} -#submenu li a:focus, -#submenu li a:hover, -#submenu li a:active { - background-color:#f63; - color: #fff; -} - -/* Form-Elements in the Menu*/ -#submenu * select#server_id { - margin: 3px 10%; - padding: 1px; - width: 80%; -} - -/* main/content --------------------------------------------------------------- */ -#content { - margin-left: 200px; - margin-right: 0; - padding: 0px 10px 10px 20px; - border-left: 1px #ddd solid; -} - -/* footer --------------------------------------------------------------- */ - -footer { - color:#666; - background: #f9f9f9; - padding: 10px 20px; - border-top: 5px #efefef solid; - font-size: 0.8em; - text-align: center; -} -footer a { - color: #999; - background:transparent; - font-weight: bold; -} -footer a:hover, footer a:active { - color: #4D87C7; - background-color: transparent; - text-decoration:underline; -} - -/* Set a background-color, no system backgorund used anymore */ -select, input, textarea { - background: #FFFFFF; - border: 1px solid #DFDFDF; - padding: 1px; - outline:none; -} - -table { width: auto; border-collapse:collapse; margin-bottom: 0.5em; } -table.full { width: 100%; } -table.fixed { table-layout:fixed } - -table.list td { - max-width: 350px; - min-width: 32px; - white-space: nowrap; - overflow:hidden; - text-overflow: ellipsis; - -o-text-overflow: ellipsis; - -icab-text-overflow: ellipsis; - -khtml-text-overflow: ellipsis; - -moz-text-overflow: ellipsis; - -webkit-text-overflow: ellipsis; -} -th, -td { - padding: 0.5em; - text-align:left; -} -thead th { - background: #444 url("../images/lists_thead_bg.png") repeat-x; - color: #fff; -} -tbody th { - background: #ccc; - color: #333; -} -tbody th.sub { - background: #ddd; - color: #333; -} -table.list th[class$="_pid"], -table.list td[class$="_pid"], -table.list th[class$="_active"], -table.list td[class$="_active"], -table.list th.tbl_col_autoresponder, -table.list td.tbl_col_autoresponder { - width: 70px; - text-align: center; -} -table.list .tbl_col_buttons, -table.list .tbl_col_limit { - width: 150px; -} -.tbl_col_client_pid input { - width: 50px; -} -.pnl_listarea th[class^="tbl_col"] { cursor:pointer; } -.pnl_listarea th[class^="tbl_col"]:hover { background-position:0 -15px!important; } -.pnl_listarea th.tbl_col_nosort { cursor:default; } -.pnl_listarea th.tbl_col_nosort:hover { background-position:0 0!important; } - -.pageForm_description { font-size: 12px; } - -/* Tab-Box */ -.tabbox_tabs { border-bottom: 1px solid #d3d3d3; } -.tabbox_tabs ul { - list-style: none; - padding: 0; - margin: 0; -} -.tabbox_tabs li { - display: inline; - margin: 0 2px 0 0; -} -.tabbox_tabs a { - padding: 0 1em; - text-decoration: none; - color: black; - background: #d3d3d3; - border: 1px solid #d3d3d3; -} -.tabbox_tabs a:hover { - background: #fc0; - color: #540; -} -.tabbox_tabs .active a { - font-weight: bold; - color: #ff6600; - background: #ffffff; -} -.pnl_toolsarea fieldset, .pnl_listarea fieldset, .pnl_formsarea fieldset { - border-top: 1px solid #949494; - margin: 20px 0; -} -.pnl_toolsarea fieldset legend , .pnl_listarea fieldset legend { - font-weight: bold; - color: #6299c5; -} -.pnl_formarea fieldset { - font-weight: bold; -} -/* hide line and legend when inside tabbed content */ -#tabbox_content * .pnl_toolsarea fieldset, #tabbox_content * .pnl_listarea fieldset, #tabbox_content * .pnl_formsarea fieldset { border: none !important; } -#tabbox_content * .pnl_toolsarea fieldset legend, #tabbox_content * .pnl_listarea fieldset legend, #tabbox_content * .pnl_formsarea fieldset legend { display: none !important; } -.codeview { - margin:20px 0; - padding:2px; - border: 1px solid #ffcc00; - background: #fffaea; - font-family: Consolas, "Lucida Console", "Courier New", monospace; - font-size: 0.9em; -} -/* Lists */ -table.list { - width: 100%; - border: 1px solid #d3d3d3 !important; -} -table.list thead th { font-size: 10px; } -table.list tbody { border: 1px solid #d3d3d3 !important; } -table.list tfoot td { text-align: center; background: #f8f8f8 url("../images/lists_tfoot_bg.png") repeat-x bottom left; padding: 24px 8px 8px 8px; } -table.list .tbl_paging img { vertical-align: top; } -table.list .tbl_row_even { background: #fcfcfc; } -table.list .tbl_row_uneven { background: #f0f8ff; } -table.list tr:hover { background: #fffacd; } -table.list td { word-wrap:break-word;white-space:pre-wrap; } -table.list td.tbl_col_buttons { word-wrap:normal;white-space:normal;overflow:visible; } - -/* Password Strength */ -#passBar { - width: 101px; height: 10px; - background: url("../images/meter_bg.gif") repeat-x bottom left; - margin: 2px 0; - float: left; -} -#passText { - padding: 0; - float: left; -} - -/* Systemmonitor */ -.systemmonitor-server, -.systemmonitor-ve, -.systemmonitor-state { - margin: 10px 5px; - font-family: Consolas, "Lucida Console", "Courier New", monospace; - font-size: 0.9em; - float: left; - width: 100%; -} -.systemmonitor-server:hover, -.systemmonitor-vm:hover { background-color: #FFFACD; } -.state-no_state, -.state-no_state-ve { - border-top: 4px solid #95A19F; - background-color: #f8f8ff; -} -.state-unknown, -.state-unknown-ve { - border-top: 4px solid #30302e; - background-color: #cecfc5; -} -.state-ok, -.state-ok-ve { - border-top: 4px solid #23fb00; - background-color: #adffa2; -} -.state-info, -.state-info-ve { - border-top: 4px solid #183e99; - background-color: #d4e2ff; -} -.state-warning, -.state-warning-ve { - border-top: 4px solid #ffa800; - background-color: #ffda93; -} -.state-critical, -.state-critical-ve { - border-top: 4px solid #ff0000; - background-color: #ffb9b9; -} -.state-error, -.state-error-ve { - border-top: 4px solid #ff0000; - background-color: #ff7f7f; -} -div.icoDevice { - float: left; - width: 64px; - height: 64px; - margin: 5px; - background: url("../icons/device_sprite.png") no-repeat transparent; -} -.systemmonitor-server div.icoDevice { background-position: 0 0; } -.systemmonitor-ve div.icoDevice { background-position: -64px 0; } -.systemmonitor-network div.icoDevice { background-position: -128px 0; } -div.statusDevice, -div.statusMsg { float: left; } -div.statusMsg p { - float: left; - padding: 5px; -} -.systemmonitor-state .status { - margin: 5px; -} -.status { - float: right; - width: 32px; - height: 32px; - background: url("../icons/x32_sprite.png") no-repeat transparent; -} -div.status { - float: left !important; -} -.state-warning .status, -.state-warning-ve .status { background-position: 0 -143px; } -.state-no_state .status, -.state-no_state-ve .status, -.state-unknown .status, -.state-unknown-ve .status { background-position: 0 -207px; } -.state-ok .status, -.state-ok-ve .status { background-position: 0 -270px; } -.state-info .status, -.state-info-ve .status { background-position: 0 -336px; } -.state-error .status, -.state-error-ve .status { background-position: 0 -400px; } -.state-critical .status, -.state-critical-ve .status { background-position: 0 -463px; } - -/* Usage unknown -.systemmonitor-content table { - border: none; - margin-top: 10px; -} - -.systemmonitor-content * .online { - border: 1px solid #ffffff; - background-color: #E3FFB8; - color: #000000; - padding:0px 5px; -} -.systemmonitor-content * .offline { - border: 1px solid #ffffff; - background-color: #d12f19; - color:#ffffff; - padding:0px 5px; -}*/ - -/* Dashboard */ -.dashboard-modules { - float:left; - width:60px; - height: 60px; - border:1px dotted #888888; - border-radius:5px; - background-color: #cccccc; - margin:10px; - background-position: center 5px; - background-repeat: no-repeat; - text-align: center; -} -.dashboard-modules a, -.dashboard-modules a:hover { - background: url("../icons/x32_sprite.png") no-repeat transparent; - color:Black; - display:block; - font-weight:bold; - height:30px; - padding-top:42px; - width:60px; - text-decoration: none; -} -.dashboard-modules.tools a { background-position: 12px -9px; } -.dashboard-modules.admin a { background-position: 12px -73px; } -.dashboard-modules.sites a { background-position: 12px -520px; } -.dashboard-modules.monitor a { background-position: 13px -585px; } -.dashboard-modules.help a { background-position: 13px -716px; } -.dashboard-modules.mail a { background-position: 12px -776px; } -.dashboard-modules.vm a { background-position: 14px -842px; } -.dashboard-modules.domain a { background-position: 12px -905px; } -.dashboard-modules.dns a { background-position: 12px -970px; } -.dashboard-modules.client a { background-position: 13px -1096px; } -.dashboard-modules.billing a { background-position: 14px -1162px; } - -.panel_dashboard h2 { font-size:20px; } - -/* Image-Replacement */ -.swap { background-repeat:no-repeat; } -.swap span { display:none; height:16px; } -#ir-HeaderLogo { - background-image: url("../images/header_logo.png"); - height:32px; - margin:0 0 0.2em; -} -div#ir-Yes, -div#ir-No { - text-align: center; - background: url("../icons/x16_sprite.png") no-repeat transparent; -} -#ir-Yes { - background-position: center -342px !important; - height: 16px; -} -#ir-No { - background-position: center -362px !important; - height: 16px; -} -.swap { - background-repeat: no-repeat; -} -.swap span { - display: none; - height: 16px; -} -/* BUTTONS */ -a.button, -.button, -.buttons button { - display: inline-block; - margin: 0 2px; - padding: 2px 5px; - color: #525252; - text-shadow: 0px 1px 1px #fff; - border: 1px solid #c6c6c6; - border-radius: 4px; - background-color: #f7f7f7; - box-shadow: 0 1px 1px 0 rgba(140, 140, 140, 0.3); - -o-box-shadow: 0 1px 1px 0 rgba(140, 140, 140, 0.3); - -webkit-box-shadow: 0 1px 1px 0 rgba(140, 140, 140, 0.3); - -moz-box-shadow: 0 1px 1px 0 rgba(140, 140, 140, 0.3); - text-decoration: none; -} -a.button:focus, -input.button:focus, -.buttons button:focus { - border-color: #4fadd5; - box-shadow: 0 0 2px 1px rgba(71,135,177, 0.6); - -moz-box-shadow: 0 0 2px 1px rgba(71,135,177, 0.6); - -webkit-box-shadow: 0 0 2px 1px rgba(71,135,177, 0.6); - -o-box-shadow: 0 0 2px 1px rgba(71,135,177, 0.6); - outline: none; -} -.buttons button[type]{ - padding:5px 10px 5px 7px; /* Firefox */ - line-height:17px; /* Safari */ - white-space: nowrap; -} -*:first-child+html button[type]{ - padding:4px 10px 3px 7px; /* IE7 */ -} -.buttons button img, -.buttons a img { - margin:0 3px -3px 0 !important; - padding:0; - border:none; - width:16px; - height:16px; -} -.topbuttons { - margin-bottom: 10px; -} -/* BUTTONS STANDARD */ -button:hover, -.buttons a:hover { - background-color:#dff4ff; - border:1px solid #c2e1ef; - color:#336699; -} -.buttons a:active { - background-color:#6299c5; - border:1px solid #6299c5; - color:#fff; -} - -/* BUTTONS POSITIVE */ -button.positive, -.buttons a.positive { color:#529214; } -.buttons a.positive:hover, -button.positive:hover { - background-color:#E6EFC2; - border:1px solid #C6D880; - color:#529214; -} -.buttons a.positive:active { - background-color:#529214; - border:1px solid #529214; - color:#fff; -} - -/* BUTTONS NEGATIVE */ -.buttons a.negative, -button.negative { - color:#d12f19; -} -.buttons a.negative:hover, -button.negative:hover { - background-color:#fbe3e4; - border:1px solid #fbc2c4; - color:#d12f19; -} -.buttons a.negative:active { - background-color:#d12f19; - border:1px solid #d12f19; - color:#fff; -} - -/* Button with icon and text */ -.iconstxt { background: url("../icons/button_sprite.png") no-repeat transparent; } -.iconstxt span { padding-left: 20px; font-weight: bold; } -.iconstxt.icoPositive { background-position: 6px -130px; } -.iconstxt.icoNegative { background-position: 6px -98px; } -.iconstxt.icoAdd { background-position: 6px -66px; } -.iconstxt.icoKey { background-position: 6px -1px; } -.iconstxt.icoDelete { background-position: 6px -34px; } -.iconstxt.icoDownload { background-position: 6px -1px; } -.iconstxt.icoRestore { background-position: 6px -1px; } - -/* Button with icon and without text */ -.icons16 { position: relative; } -.icons16>span { - opacity: 0; - visibility: hidden; - -webkit-transition: opacity 1s linear; - -moz-transition: opacity 1s linear; - -o-transition: opacity 1s linear; - -ms-transition: opacity 1s linear; - transition: opacity 1s linear; - position: absolute; - right: 23px; - top: -1px; - padding: 1px 2px; - border: 1px solid rgb(155,155,11); - background: rgb(255,255,111); - white-space: nowrap; -} -.icons16:hover>span { - opacity: 1.0; - visibility: visible; -} -a.icons16 { - height: 18px; - width: 18px; - padding: 0; - background: url("../icons/x16_sprite.png") no-repeat transparent; -} -button.icons16 { - height: 20px; - width: 20px; - padding: 0; - background: url("../icons/x16_sprite.png") no-repeat transparent; -} -.icons16.icoEdit { background-position: -1px -1px; } -.icons16.icoLoginAs { background-position: -1px -21px; } -.icons16.icoPDF { background-position: -1px -61px; } -.icons16.icoDelete { background-position: -1px -81px; } -.icons16.icoWebmailer { background-position: -1px -101px; } -.icons16.icoFilter { background-position: -1px -161px; } -.icons16.icoDbAdmin { background-position: -1px -221px; } -.icons16.icoAction { background-position: -1px -241px; } -.icons16.icoLink { background-position: -1px -422px; float: right; } - -div.group-icon { - float: left; - padding: 2px 0; -} -.group-admin, -.group-user { - height: 20px; - width: 20px; - padding: 0; - float: left; - background: url("../icons/x16_sprite.png") no-repeat transparent; -} -.group-admin { background-position: 0 -380px; } -.group-user { background-position: 0 -400px; } - -span.marked { color: #cc0000; } -span.small { font-size: 0.9em; } - -#ajaxloader { - position: absolute; - width: 325px; - height: 150px; - background: #ffffff url('../images/ajax-loader.gif') no-repeat center center; - border: solid 2px #e1e1e1; - border-radius: 10px; - /*background: rgba(255, 255, 255, 0.85);*/ - padding: 20px; - text-align:center; - z-index: 100; -} -.blockLabel.email_at { - width: 20px !important; - margin: 1.6em 0.3em 0 0 !important; -} -.textDisplay { display: block; } - -/* Form Length Classes */ -.textInput.formLengthBool { width: 25px !important; } -.selectInput.formLengthBool { width: 60px !important; } -.textInput.formLengthLimit { width: 50px !important; } -.selectInput.formLengthLimit { width: 85px !important; } -.formLengthDate { width: 75px !important; } -.formLengthIPv4 { width: 125px !important; } -.formLengthIPv6 { } -.formLengthEmailUser { width: 30% !important; } -.formLengthEmailDomain { width: 30% !important; } -.formLengthHalf { width: 15% !important; } -.formLengthDouble { width: 50% !important; } - -/* Individual Form Lengths */ -.textInput#username, -.textInput#password, -.textInput#passwort, -.textInput#source_password { width: 100px; } -.selectInput#language { width: 75px; } -.selectInput#client_group_id, .selectInput#default_group { width: 125px; } -input#refresh, input#retry, input#expire, input#minimum, input#ttl { width: 50px !important; } - -/* --- */ - -a[href $="#logout"] { - padding-right: 20px; - background: url("../icons/x16_sprite.png") no-repeat right -143px transparent !important; -} - -/* Select Menu with Images */ -select.withicons option { - background-repeat:no-repeat; - background-position: 1px; - padding-left:24px; -} -div[class^=country-] { - background-image: url("../icons/flags_sprite.png"); - background-repeat: no-repeat; - height: 20px; - width: 26px; -} -li[class^=country-] { - background-image: url("../icons/flags_sprite.png"); - background-repeat: no-repeat; - text-indent: 24px; -} -li[class^=country-] a.ui-state-hover { background: transparent; } -div[class^=country-] span { - display: none; -} -select.flags option { - background-image: url("../icons/flags_sprite.png"); - background-repeat: no-repeat; - padding: 1px 0 1px 30px; -} -select.flags option[value=EL] {background-position:0 -1475px} -select.flags option[value=AD], select.flags option[value=ad], .country-AD {background-position:0 -1px} -select.flags option[value=AE], select.flags option[value=ae], .country-AE {background-position:0 -23px} -select.flags option[value=AF], select.flags option[value=af], .country-AF {background-position:0 -45px} -select.flags option[value=AG], select.flags option[value=ag], .country-AG {background-position:0 -67px} -select.flags option[value=AI], select.flags option[value=ai], .country-AI {background-position:0 -89px} -select.flags option[value=AL], select.flags option[value=al], .country-AL {background-position:0 -111px} -select.flags option[value=AM], select.flags option[value=am], .country-AM {background-position:0 -133px} -select.flags option[value=AN], select.flags option[value=an], .country-AN {background-position:0 -155px} -select.flags option[value=AO], select.flags option[value=ao], .country-AO {background-position:0 -177px} -select.flags option[value=AQ], select.flags option[value=aq], .country-AQ {background-position:0 -199px} -select.flags option[value=AR], select.flags option[value=ar], .country-AR {background-position:0 -221px} -select.flags option[value=AS], select.flags option[value=as], .country-AS {background-position:0 -243px} -select.flags option[value=AT], select.flags option[value=at], .country-AT {background-position:0 -265px} -select.flags option[value=AU], select.flags option[value=au], .country-AU {background-position:0 -287px} -select.flags option[value=AW], select.flags option[value=aw], .country-AW {background-position:0 -309px} -select.flags option[value=AX], select.flags option[value=ax], .country-AX {background-position:0 -331px} -select.flags option[value=AZ], select.flags option[value=az], .country-AZ {background-position:0 -353px} -select.flags option[value=BA], select.flags option[value=ba], .country-BA {background-position:0 -375px} -select.flags option[value=BB], select.flags option[value=bb], .country-BB {background-position:0 -397px} -select.flags option[value=BD], select.flags option[value=bd], .country-BD {background-position:0 -419px} -select.flags option[value=BE], select.flags option[value=be], .country-BE {background-position:0 -441px} -select.flags option[value=BF], select.flags option[value=bf], .country-BF {background-position:0 -463px} -select.flags option[value=BG], select.flags option[value=bg], .country-BG {background-position:0 -485px} -select.flags option[value=BH], select.flags option[value=bh], .country-BH {background-position:0 -507px} -select.flags option[value=BI], select.flags option[value=bi], .country-BI {background-position:0 -529px} -select.flags option[value=BJ], select.flags option[value=bj], .country-BJ {background-position:0 -551px} -select.flags option[value=BM], select.flags option[value=bm], .country-BM {background-position:0 -573px} -select.flags option[value=BN], select.flags option[value=bn], .country-BN {background-position:0 -595px} -select.flags option[value=BO], select.flags option[value=bo], .country-BO {background-position:0 -617px} -select.flags option[value=BR], select.flags option[value=br], .country-BR {background-position:0 -639px} -select.flags option[value=BS], select.flags option[value=bs], .country-BS {background-position:0 -661px} -select.flags option[value=BT], select.flags option[value=bt], .country-BT {background-position:0 -683px} -select.flags option[value=BV], select.flags option[value=bv], .country-BV {background-position:0 -705px} -select.flags option[value=BW], select.flags option[value=bw], .country-BW {background-position:0 -727px} -select.flags option[value=BY], select.flags option[value=by], .country-BY {background-position:0 -749px} -select.flags option[value=BZ], select.flags option[value=bz], .country-BZ {background-position:0 -771px} -select.flags option[value=CA], select.flags option[value=ca], .country-CA {background-position:0 -793px} -select.flags option[value=CC], select.flags option[value=cc], .country-CC {background-position:0 -837px} -select.flags option[value=CD], select.flags option[value=cd], .country-CD {background-position:0 -859px} -select.flags option[value=CF], select.flags option[value=cf], .country-CF {background-position:0 -881px} -select.flags option[value=CG], select.flags option[value=cg], .country-CG {background-position:0 -903px} -select.flags option[value=CH], select.flags option[value=ch], .country-CH {background-position:0 -925px} -select.flags option[value=CI], select.flags option[value=ci], .country-CI {background-position:0 -947px} -select.flags option[value=CK], select.flags option[value=ck], .country-CK {background-position:0 -969px} -select.flags option[value=CL], select.flags option[value=cl], .country-CL {background-position:0 -991px} -select.flags option[value=CM], select.flags option[value=cm], .country-CM {background-position:0 -1013px} -select.flags option[value=CN], select.flags option[value=cn], .country-CN {background-position:0 -1035px} -select.flags option[value=CO], select.flags option[value=co], .country-CO {background-position:0 -1057px} -select.flags option[value=CR], select.flags option[value=cr], .country-CR {background-position:0 -1079px} -select.flags option[value=CS], select.flags option[value=cs], .country-CS {background-position:0 -1101px} -select.flags option[value=CU], select.flags option[value=cu], .country-CU {background-position:0 -1123px} -select.flags option[value=CV], select.flags option[value=cv], .country-CV {background-position:0 -1145px} -select.flags option[value=CX], select.flags option[value=cx], .country-CX {background-position:0 -1167px} -select.flags option[value=CY], select.flags option[value=cy], .country-CY {background-position:0 -1189px} -select.flags option[value=CZ], select.flags option[value=cz], .country-CZ {background-position:0 -1211px} -select.flags option[value=DE], select.flags option[value=de], .country-DE {background-position:0 -1233px} -select.flags option[value=DJ], select.flags option[value=dj], .country-DJ {background-position:0 -1255px} -select.flags option[value=DK], select.flags option[value=dk], .country-DK {background-position:0 -1277px} -select.flags option[value=DM], select.flags option[value=dm], .country-DM {background-position:0 -1299px} -select.flags option[value=DO], select.flags option[value=do], .country-DO {background-position:0 -1321px} -select.flags option[value=DZ], select.flags option[value=dz], .country-DZ {background-position:0 -1343px} -select.flags option[value=EC], select.flags option[value=ec], .country-EC {background-position:0 -1365px} -select.flags option[value=EE], select.flags option[value=ee], .country-EE {background-position:0 -1387px} -select.flags option[value=EG], select.flags option[value=eg], .country-EG {background-position:0 -1409px} -select.flags option[value=EH], select.flags option[value=eh], .country-EH {background-position:0 -1431px} -select.flags option[value=ER], select.flags option[value=er], .country-ER {background-position:0 -1475px} -select.flags option[value=ES], select.flags option[value=es], .country-ES {background-position:0 -1497px} -select.flags option[value=ET], select.flags option[value=ET], select.flags option[value=et], .country-ET {background-position:0 -1519px} -select.flags option[value=FI], select.flags option[value=fi], .country-FI {background-position:0 -1585px} -select.flags option[value=FJ], select.flags option[value=fj], .country-FJ {background-position:0 -1607px} -select.flags option[value=FK], select.flags option[value=fk], .country-FK {background-position:0 -1629px} -select.flags option[value=FM], select.flags option[value=fm], .country-FM {background-position:0 -1651px} -select.flags option[value=FO], select.flags option[value=fo], .country-FO {background-position:0 -1673px} -select.flags option[value=FR], select.flags option[value=fr], .country-FR {background-position:0 -1695px} -select.flags option[value=GA], select.flags option[value=ga], .country-GA {background-position:0 -1717px} -select.flags option[value=GB], select.flags option[value=en], select.flags option[value=gb], .country-GB, .country-EN {background-position:0 -1739px} -select.flags option[value=GD], select.flags option[value=gd], .country-GD {background-position:0 -1761px} -select.flags option[value=GE], select.flags option[value=ge], .country-GE {background-position:0 -1783px} -select.flags option[value=GF], select.flags option[value=gf], .country-GF {background-position:0 -1805px} -select.flags option[value=GH], select.flags option[value=gh], .country-GH {background-position:0 -1827px} -select.flags option[value=GI], select.flags option[value=gi], .country-GI {background-position:0 -1849px} -select.flags option[value=GL], select.flags option[value=gl], .country-GL {background-position:0 -1871px} -select.flags option[value=GM], select.flags option[value=gm], .country-GM {background-position:0 -1893px} -select.flags option[value=GN], select.flags option[value=gn], .country-GN {background-position:0 -1915px} -select.flags option[value=GP], select.flags option[value=gp], .country-GP {background-position:0 -1937px} -select.flags option[value=GQ], select.flags option[value=gq], .country-GQ {background-position:0 -1959px} -select.flags option[value=GR], select.flags option[value=el], select.flags option[value=gr], .country-GR, .country-EL {background-position:0 -1981px} -select.flags option[value=GS], select.flags option[value=gs], .country-GS {background-position:0 -2003px} -select.flags option[value=GT], select.flags option[value=gt], .country-GT {background-position:0 -2025px} -select.flags option[value=GU], select.flags option[value=gu], .country-GU {background-position:0 -2047px} -select.flags option[value=GW], select.flags option[value=gw], .country-GW {background-position:0 -2069px} -select.flags option[value=GY], select.flags option[value=gy], .country-GY {background-position:0 -2091px} -select.flags option[value=HK], select.flags option[value=hk], .country-HK {background-position:0 -2113px} -select.flags option[value=HM], select.flags option[value=hm], .country-HM {background-position:0 -2135px} -select.flags option[value=HN], select.flags option[value=hn], .country-HN {background-position:0 -2157px} -select.flags option[value=HR], select.flags option[value=hr], .country-HR {background-position:0 -2179px} -select.flags option[value=HT], select.flags option[value=ht], .country-HT {background-position:0 -2201px} -select.flags option[value=HU], select.flags option[value=hu], .country-HU {background-position:0 -2223px} -select.flags option[value=ID], select.flags option[value=id], .country-ID {background-position:0 -2245px} -select.flags option[value=IE], select.flags option[value=ie], .country-IE {background-position:0 -2267px} -select.flags option[value=IL], select.flags option[value=il], .country-IL {background-position:0 -2289px} -select.flags option[value=IN], select.flags option[value=in], .country-IN {background-position:0 -2311px} -select.flags option[value=IO], select.flags option[value=io], .country-IO {background-position:0 -2333px} -select.flags option[value=IQ], select.flags option[value=iq], .country-IQ {background-position:0 -2355px} -select.flags option[value=IR], select.flags option[value=ir], .country-IR {background-position:0 -2377px} -select.flags option[value=IS], select.flags option[value=is], .country-IS {background-position:0 -2399px} -select.flags option[value=IT], select.flags option[value=it], .country-IT {background-position:0 -2421px} -select.flags option[value=JM], select.flags option[value=jm], .country-JM {background-position:0 -2443px} -select.flags option[value=JO], select.flags option[value=jo], .country-JO {background-position:0 -2465px} -select.flags option[value=JP], select.flags option[value=ja], select.flags option[value=jp], .country-JP, .country-JA {background-position:0 -2487px} -select.flags option[value=KE], select.flags option[value=ke], .country-KE {background-position:0 -2509px} -select.flags option[value=KG], select.flags option[value=kg], .country-KG {background-position:0 -2531px} -select.flags option[value=KH], select.flags option[value=kh], .country-KH {background-position:0 -2553px} -select.flags option[value=KI], select.flags option[value=ki], .country-KI {background-position:0 -2575px} -select.flags option[value=KM], select.flags option[value=km], .country-KM {background-position:0 -2597px} -select.flags option[value=KN], select.flags option[value=kn], .country-KN {background-position:0 -2619px} -select.flags option[value=KP], select.flags option[value=kp], .country-KP {background-position:0 -2641px} -select.flags option[value=KR], select.flags option[value=kr], .country-KR {background-position:0 -2663px} -select.flags option[value=KW], select.flags option[value=kw], .country-KW {background-position:0 -2685px} -select.flags option[value=KY], select.flags option[value=ky], .country-KY {background-position:0 -2707px} -select.flags option[value=KZ], select.flags option[value=kz], .country-KZ {background-position:0 -2729px} -select.flags option[value=LA], select.flags option[value=la], .country-LA {background-position:0 -2751px} -select.flags option[value=LB], select.flags option[value=lb], .country-LB {background-position:0 -2773px} -select.flags option[value=LC], select.flags option[value=lc], .country-LC {background-position:0 -2795px} -select.flags option[value=LI], select.flags option[value=li], .country-LI {background-position:0 -2817px} -select.flags option[value=LK], select.flags option[value=lk], .country-LK {background-position:0 -2839px} -select.flags option[value=LR], select.flags option[value=lr], .country-LR {background-position:0 -2861px} -select.flags option[value=LS], select.flags option[value=ls], .country-LS {background-position:0 -2883px} -select.flags option[value=LT], select.flags option[value=lt], .country-LT {background-position:0 -2905px} -select.flags option[value=LU], select.flags option[value=lu], .country-LU {background-position:0 -2927px} -select.flags option[value=LV], select.flags option[value=lv], .country-LV {background-position:0 -2949px} -select.flags option[value=LY], select.flags option[value=ly], .country-LY {background-position:0 -2971px} -select.flags option[value=MA], select.flags option[value=ma], .country-MA {background-position:0 -2993px} -select.flags option[value=MC], select.flags option[value=mc], .country-MC {background-position:0 -3015px} -select.flags option[value=MD], select.flags option[value=md], .country-MD {background-position:0 -3037px} -select.flags option[value=ME], select.flags option[value=me], .country-ME {background-position:0 -3059px} -select.flags option[value=MG], select.flags option[value=mg], .country-MG {background-position:0 -3081px} -select.flags option[value=MH], select.flags option[value=mh], .country-MH {background-position:0 -3103px} -select.flags option[value=MK], select.flags option[value=mk], .country-MK {background-position:0 -3125px} -select.flags option[value=ML], select.flags option[value=ml], .country-ML {background-position:0 -3147px} -select.flags option[value=MM], select.flags option[value=mm], .country-MM {background-position:0 -3169px} -select.flags option[value=MN], select.flags option[value=mn], .country-MN {background-position:0 -3191px} -select.flags option[value=MO], select.flags option[value=mo], .country-MO {background-position:0 -3213px} -select.flags option[value=MP], select.flags option[value=mp], .country-MP {background-position:0 -3235px} -select.flags option[value=MQ], select.flags option[value=mq], .country-MQ {background-position:0 -3257px} -select.flags option[value=MR], select.flags option[value=mr], .country-MR {background-position:0 -3279px} -select.flags option[value=MS], select.flags option[value=ms], .country-MS {background-position:0 -3301px} -select.flags option[value=MT], select.flags option[value=mt], .country-MT {background-position:0 -3323px} -select.flags option[value=MU], select.flags option[value=mu], .country-MU {background-position:0 -3345px} -select.flags option[value=MV], select.flags option[value=mv], .country-MV {background-position:0 -3367px} -select.flags option[value=MW], select.flags option[value=mw], .country-MW {background-position:0 -3389px} -select.flags option[value=MX], select.flags option[value=mx], .country-MX {background-position:0 -3411px} -select.flags option[value=MY], select.flags option[value=my], .country-MY {background-position:0 -3433px} -select.flags option[value=MZ], select.flags option[value=mz], .country-MZ {background-position:0 -3455px} -select.flags option[value=NA], select.flags option[value=na], .country-NA {background-position:0 -3477px} -select.flags option[value=NC], select.flags option[value=nc], .country-NC {background-position:0 -3499px} -select.flags option[value=NE], select.flags option[value=ne], .country-NE {background-position:0 -3521px} -select.flags option[value=NF], select.flags option[value=nf], .country-NF {background-position:0 -3543px} -select.flags option[value=NG], select.flags option[value=ng], .country-NG {background-position:0 -3565px} -select.flags option[value=NI], select.flags option[value=ni], .country-NI {background-position:0 -3587px} -select.flags option[value=NL], select.flags option[value=nl], .country-NL {background-position:0 -3609px} -select.flags option[value=NO], select.flags option[value=no], .country-NO {background-position:0 -3631px} -select.flags option[value=NP], select.flags option[value=np], .country-NP {background-position:0 -3653px} -select.flags option[value=NR], select.flags option[value=nr], .country-NR {background-position:0 -3675px} -select.flags option[value=NU], select.flags option[value=nu], .country-NU {background-position:0 -3697px} -select.flags option[value=NZ], select.flags option[value=nz], .country-NZ {background-position:0 -3719px} -select.flags option[value=OM], select.flags option[value=om], .country-OM {background-position:0 -3741px} -select.flags option[value=PA], select.flags option[value=pa], .country-PA {background-position:0 -3763px} -select.flags option[value=PE], select.flags option[value=pe], .country-PE {background-position:0 -3785px} -select.flags option[value=PF], select.flags option[value=pf], .country-PF {background-position:0 -3807px} -select.flags option[value=PG], select.flags option[value=pg], .country-PG {background-position:0 -3829px} -select.flags option[value=PH], select.flags option[value=ph], .country-PH {background-position:0 -3851px} -select.flags option[value=PK], select.flags option[value=pk], .country-PK {background-position:0 -3873px} -select.flags option[value=PL], select.flags option[value=pl], .country-PL {background-position:0 -3895px} -select.flags option[value=PM], select.flags option[value=pm], .country-PM {background-position:0 -3917px} -select.flags option[value=PN], select.flags option[value=pn], .country-PN {background-position:0 -3939px} -select.flags option[value=PR], select.flags option[value=pr], .country-PR {background-position:0 -3961px} -select.flags option[value=PS], select.flags option[value=ps], .country-PS {background-position:0 -3983px} -select.flags option[value=PT], select.flags option[value=pt], .country-PT {background-position:0 -4005px} -select.flags option[value=PW], select.flags option[value=pw], .country-PW {background-position:0 -4027px} -select.flags option[value=PY], select.flags option[value=py], .country-PY {background-position:0 -4049px} -select.flags option[value=QA], select.flags option[value=qa], .country-QA {background-position:0 -4071px} -select.flags option[value=RE], select.flags option[value=re], .country-RE {background-position:0 -4093px} -select.flags option[value=RO], select.flags option[value=ro], .country-RO {background-position:0 -4115px} -select.flags option[value=RS], select.flags option[value=rs], .country-RS {background-position:0 -4137px} -select.flags option[value=RU], select.flags option[value=ru], .country-RU {background-position:0 -4159px} -select.flags option[value=RW], select.flags option[value=rw], .country-RW {background-position:0 -4181px} -select.flags option[value=SA], select.flags option[value=sa], .country-SA {background-position:0 -4203px} -select.flags option[value=SB], select.flags option[value=sb], .country-SB {background-position:0 -4225px} -select.flags option[value=SC], select.flags option[value=sc], .country-SC {background-position:0 -4247px} -select.flags option[value=SD], select.flags option[value=sd], .country-SD {background-position:0 -4291px} -select.flags option[value=SE], select.flags option[value=se], .country-SE {background-position:0 -4313px} -select.flags option[value=SG], select.flags option[value=sg], .country-SG {background-position:0 -4335px} -select.flags option[value=SH], select.flags option[value=sh], .country-SH {background-position:0 -4357px} -select.flags option[value=SI], select.flags option[value=si], .country-SI {background-position:0 -4379px} -select.flags option[value=SJ], select.flags option[value=sj], .country-SJ {background-position:0 -4401px} -select.flags option[value=SK], select.flags option[value=sk], .country-SK {background-position:0 -4423px} -select.flags option[value=SL], select.flags option[value=sl], .country-SL {background-position:0 -4445px} -select.flags option[value=SM], select.flags option[value=sm], .country-SM {background-position:0 -4467px} -select.flags option[value=SN], select.flags option[value=sn], .country-SN {background-position:0 -4489px} -select.flags option[value=SO], select.flags option[value=so], .country-SO {background-position:0 -4511px} -select.flags option[value=SR], select.flags option[value=sr], .country-SR {background-position:0 -4533px} -select.flags option[value=ST], select.flags option[value=st], .country-ST {background-position:0 -4555px} -select.flags option[value=SV], select.flags option[value=sv], .country-SV {background-position:0 -4577px} -select.flags option[value=SY], select.flags option[value=sy], .country-SY {background-position:0 -4599px} -select.flags option[value=SZ], select.flags option[value=sz], .country-SZ {background-position:0 -4621px} -select.flags option[value=TC], select.flags option[value=tc], .country-TC {background-position:0 -4643px} -select.flags option[value=TD], select.flags option[value=td], .country-TD {background-position:0 -4665px} -select.flags option[value=TF], select.flags option[value=tf], .country-TF {background-position:0 -4687px} -select.flags option[value=TG], select.flags option[value=tg], .country-TG {background-position:0 -4709px} -select.flags option[value=TH], select.flags option[value=th], .country-TH {background-position:0 -4731px} -select.flags option[value=TJ], select.flags option[value=tj], .country-TJ {background-position:0 -4753px} -select.flags option[value=TK], select.flags option[value=tk], .country-TK {background-position:0 -4775px} -select.flags option[value=TL], select.flags option[value=tl], .country-TL {background-position:0 -4797px} -select.flags option[value=TM], select.flags option[value=tm], .country-TM {background-position:0 -4819px} -select.flags option[value=TN], select.flags option[value=tn], .country-TN {background-position:0 -4841px} -select.flags option[value=TO], select.flags option[value=to], .country-TO {background-position:0 -4863px} -select.flags option[value=TR], select.flags option[value=tr], .country-TR {background-position:0 -4885px} -select.flags option[value=TT], select.flags option[value=tt], .country-TT {background-position:0 -4907px} -select.flags option[value=TV], select.flags option[value=tv], .country-TV {background-position:0 -4929px} -select.flags option[value=TW], select.flags option[value=tw], .country-TW {background-position:0 -4951px} -select.flags option[value=TZ], select.flags option[value=tz], .country-TZ {background-position:0 -4973px} -select.flags option[value=UA], select.flags option[value=ua], .country-UA {background-position:0 -4995px} -select.flags option[value=UG], select.flags option[value=ug], .country-UG {background-position:0 -5017px} -select.flags option[value=UM], select.flags option[value=um], .country-UM {background-position:0 -5039px} -select.flags option[value=US], select.flags option[value=us], .country-US {background-position:0 -5061px} -select.flags option[value=UY], select.flags option[value=uy], .country-UY {background-position:0 -5083px} -select.flags option[value=UZ], select.flags option[value=uz], .country-UZ {background-position:0 -5105px} -select.flags option[value=VA], select.flags option[value=va], .country-VA {background-position:0 -5127px} -select.flags option[value=VC], select.flags option[value=vc], .country-VC {background-position:0 -5149px} -select.flags option[value=VE], select.flags option[value=ve], .country-VE {background-position:0 -5171px} -select.flags option[value=VG], select.flags option[value=vg], .country-VG {background-position:0 -5193px} -select.flags option[value=VI], select.flags option[value=vi], .country-VI {background-position:0 -5215px} -select.flags option[value=VN], select.flags option[value=vn], .country-VN {background-position:0 -5237px} -select.flags option[value=VU], select.flags option[value=vu], .country-VU {background-position:0 -5259px} -select.flags option[value=WF], select.flags option[value=wf], .country-WF {background-position:0 -5303px} -select.flags option[value=WS], select.flags option[value=ws], .country-WS {background-position:0 -5325px} -select.flags option[value=YE], select.flags option[value=ye], .country-YE {background-position:0 -5347px} -select.flags option[value=YT], select.flags option[value=yt], .country-YT {background-position:0 -5369px} -select.flags option[value=ZA], select.flags option[value=za], .country-ZA {background-position:0 -5391px} -select.flags option[value=ZM], select.flags option[value=zm], .country-ZM {background-position:0 -5413px} -select.flags option[value=ZW], select.flags option[value=zw], .country-ZW {background-position:0 -5435px} - -.panel_login { - max-width: 80%; - min-width: 680px; -} -div.subsectiontoggle { - border:1px solid #ccc; - font-weight:bold; - font-size:14px; - padding-top:10px; - padding-bottom:0; - margin-top:5px; - text-indent:15px; - cursor:pointer; - margin-bottom:10px; - background-color:#f4f4f4; - -moz-border-radius:5px; - -webkit-border-radius:5px; - -khtml-border-radius:5px; - -o-border-radius:5px; - -ms-border-radius:5px; - border-radius:5px; -} -div.subsectiontoggle span { - display:inline-block; - margin-bottom:-3px; - margin-right:10px; - width:16px; - height:16px; - background: url("../icons/button_sprite.png") 0 -72px no-repeat transparent; -} -div.subsectiontoggle span.showing{ - background-position: 0 -40px; -} -div.subsectiontoggle em { - display:block; - position:relative; - left:425px; - top:-13px; - margin-bottom:-3px; - width:13px; - height:13px; - background:url("../images/chevron.png") top left no-repeat; - -webkit-transform:none; - -moz-transform:none; - -khtml-transform:none; - -o-transform:none; - -ms-transform:none; - transform:none; - -webkit-transition-duration: .2s; - -moz-transition-duration: .2s; - -khtml-transition-duration: .2s; - -o-transition-duration: .2s; - -ms-transition-duration: .2s; - transition-duration: .2s; - -webkit-transition-property: -webkit-transform; - -moz-transition-property: -moz-transform; - -khtml-transition-property: -khtml-transform; - -o-transition-property: -o-transform; - -ms-transition-property: -ms-transform; - transition-property: transform; -} -div.subsectiontoggle em.showing { - display:block; - position:relative; - left:425px; - top:-13px; - background:url("../images/chevron.png") top left no-repeat; - width:13px; - height:13px; - -webkit-transform:rotate(90deg); - -moz-transform:rotate(90deg); - -khtml-transform:rotate(90deg); - -o-transform:rotate(90deg); - -ms-transform:rotate(90deg); - transform:rotate(90deg); -} -div.subsectiontoggle:hover em { - -webkit-transform:rotate(90deg); - -moz-transform:rotate(90deg); - -khtml-transform:rotate(90deg); - -o-transform:rotate(90deg); - -ms-transform:rotate(90deg); - transform:rotate(90deg); -} - - -div.gs-container { - margin-top:10px; -} -div.gs-container * { - margin: 0; - padding: 0; - background-position: 0 0; - text-decoration: none; - font-size: 1em; -} -div.gs-container input { - background: url("../icons/x16_sprite.png") no-repeat 2px -119px #FFFFFF; - height:20px; - border:1px solid #444; - padding:0 22px 2px; - color:#444; - -moz-border-radius:5px; - -webkit-border-radius:5px; - -khtml-border-radius:5px; - -o-border-radius:5px; - -ms-border-radius:5px; - border-radius:5px; -} -input.gs-loading { - background-image: url("../images/loading.gif"); - background-repeat: no-repeat; - background-position: center right; -} -ul.gs-resultbox { - margin: 0 !important; - padding: 0 !important; - width: 300px; - z-index: 999999; - border: 1px solid #777; - font-size: 11px; - background: #fff; - -moz-box-shadow: 2px 2px 5px 0 #c5c5c5; - -webkit-box-shadow: 2px 2px 5px 0 #c5c5c5; - -khtml-box-shadow: 2px 2px 5px 0 #c5c5c5; - -o-box-shadow: 2px 2px 5px 0 #c5c5c5; - -ms-box-shadow: 2px 2px 5px 0 #c5c5c5; - box-shadow: 2px 2px 5px 0 #c5c5c5; - list-style: none; - -moz-border-radius:5px; - -webkit-border-radius:5px; - -khtml-border-radius:5px; - -o-border-radius:5px; - -ms-border-radius:5px; - border-radius:5px; - max-height:500px; - overflow:auto; -} -ul.gs-resultbox li { - float: left; - width: 100%; - clear: both; - cursor: pointer; -} -ul.gs-resultbox li.gs-cheader { - height: 13px; - overflow: hidden; - padding: 5px 0; - color: #fff; - background: #6ea6d1; - cursor:default; - padding-bottom:10px; -} -ul.gs-resultbox li.gs-cheader p.gs-cheader-title { - margin: 0 !important; - padding: 0 0 0 10px !important; - float: left; - font-size: 12px; - font-weight: bold; -} -ul.gs-resultbox li.gs-cheader p.gs-cheader-limit { - margin: 0 !important; - padding: 0 10px 0 0 !important; - float: right; - font-size: 11px; - font-weight: normal; -} -ul.gs-resultbox li.gs-cdata { - margin: 0 !important; - padding: 0 !important; - border-bottom: 1px solid #c5c5c5; -} -ul.gs-resultbox li.gs-cdata:last-child { - border-bottom: none; -} -ul.gs-resultbox li.gs-cdata:hover { - background: #eaf4fd; -} -ul.gs-resultbox li.gs-cdata a { - display: block; - padding: 5px 10px; - text-decoration: none !important; - background: #fff; -} -ul.gs-resultbox li.gs-cdata a:hover { - background: #cde0ff; -} -ul.gs-resultbox li.gs-cdata img { - margin-right: 12px; -} -ul.gs-resultbox li.gs-cdata p { - margin: 0 !important; - padding: 0 !important; - color: #444; - font-size: 10px; - min-height:30px; -} -ul.gs-resultbox li.gs-cdata p span.gs-cdata-title { - display: inline !important; - margin: 0 !important; - padding: 0 !important; - font-size: 11px; - font-weight: bold; - color: #000; -} -ul.gs-resultbox li:first-child { - -moz-border-radius:5px 5px 0 0; - -webkit-border-radius:5px 5px 0 0; - -khtml-border-radius:5px 5px 0 0; - -o-border-radius:5px 5px 0 0; - -ms-border-radius:5px 5px 0 0; - border-radius:5px 5px 0 0; -} -ul.gs-resultbox li:last-child { - -moz-border-radius:0 0 5px 5px; - -webkit-border-radius:0 0 5px 5px; - -khtml-border-radius:0 0 5px 5px; - -o-border-radius:0 0 5px 5px; - -ms-border-radius:0 0 5px 5px; - border-radius:0 0 5px 5px; -} - -div.df-container { -} -div.df-container * { - margin: 0; - padding: 0; - background-position: 0 0; - text-decoration: none; - font-size: 1em; -} -div.df-container input { -} -input.df-loading { - background-image: url("../images/loading.gif"); - background-repeat: no-repeat; - background-position: center right; -} -ul.df-resultbox { - margin: 0 !important; - padding: 0 !important; - min-width: 250px; - max-width: 500px; - z-index: 999999; - border: 1px solid #777; - font-size: 11px; - background: #fff; - -moz-box-shadow: 2px 2px 5px 0 #c5c5c5; - -webkit-box-shadow: 2px 2px 5px 0 #c5c5c5; - -khtml-box-shadow: 2px 2px 5px 0 #c5c5c5; - -o-box-shadow: 2px 2px 5px 0 #c5c5c5; - -ms-box-shadow: 2px 2px 5px 0 #c5c5c5; - box-shadow: 2px 2px 5px 0 #c5c5c5; - list-style: none; - -moz-border-radius:5px; - -webkit-border-radius:5px; - -khtml-border-radius:5px; - -o-border-radius:5px; - -ms-border-radius:5px; - border-radius:5px; -} -ul.df-resultbox li { - float: left; - width: 100%; - clear: both; - cursor: pointer; -} -ul.df-resultbox li.df-cheader { - height: 13px; - overflow: hidden; - padding: 5px 0; - color: #fff; - background: #6ea6d1; - cursor:default; - padding-bottom:10px; -} -ul.df-resultbox li.df-cheader p.df-cheader-title { - margin: 0 !important; - padding: 0 0 0 10px !important; - float: left; - font-size: 12px; - font-weight: bold; -} -ul.df-resultbox li.df-cheader p.df-cheader-limit { - margin: 0 !important; - padding: 0 10px 0 0 !important; - float: right; - font-size: 11px; - font-weight: normal; -} -ul.df-resultbox li.df-cdata { - margin: 0 !important; - padding: 0 !important; - border-bottom: 1px solid #c5c5c5; -} -ul.df-resultbox li.df-cdata:last-child { - border-bottom: none; -} -ul.df-resultbox li.df-cdata:hover { - background: #eaf4fd; -} -ul.df-resultbox li.df-cdata a { - display: block; - padding: 5px 10px; - text-decoration: none !important; - background: #fff; -} -ul.df-resultbox li.df-cdata a:hover { - background: #cde0ff; -} -ul.df-resultbox li.df-cdata img { - margin-right: 12px; -} -ul.df-resultbox li.df-cdata p { - margin: 0 !important; - padding: 0 !important; - color: #444; - font-size: 10px; - min-height:30px; -} -ul.df-resultbox li.df-cdata p span.df-cdata-title { - display: inline !important; - margin: 0 !important; - padding: 0 !important; - font-size: 11px; - font-weight: bold; - color: #000; -} -ul.df-resultbox li:first-child { - -moz-border-radius:5px 5px 0 0; - -webkit-border-radius:5px 5px 0 0; - -khtml-border-radius:5px 5px 0 0; - -o-border-radius:5px 5px 0 0; - -ms-border-radius:5px 5px 0 0; - border-radius:5px 5px 0 0; -} -ul.df-resultbox li:last-child { - -moz-border-radius:0 0 5px 5px; - -webkit-border-radius:0 0 5px 5px; - -khtml-border-radius:0 0 5px 5px; - -o-border-radius:0 0 5px 5px; - -ms-border-radius:0 0 5px 5px; - border-radius:0 0 5px 5px; -} - -span.icons16-empty { - float:left; - display:block; - height:20px; - width:20px; - margin:0 7px 0 0; -} - -.ttip { - width:16px; - height:16px; - cursor:pointer; - background: url("../icons/x16_sprite.png") no-repeat -2px -42px transparent; - float:right; - display:inline; - position:relative; - right:-2px; - top:-2px; -} - -p.prefix { - float: left; - margin: 0; - text-align: right; -} -p.label { - float: left; - margin: 5px 15px 0 0; -} -p.value { - float:left; - margin: 0 0 0 2px; -} - -/* content_ispc --------------------------------------------------------------- */ -.tipsy { - font-size: 10px; - position: absolute; - padding: 5px; - z-index: 100000; -} -.tipsy-inner { - background-color: #000; - color: #FFF; - max-width: 350px; - padding: 5px 8px 4px 8px; - text-align: left; -} - -/* Rounded corners */ -.tipsy-inner { - border-radius: 5px; - -moz-border-radius: 5px; - -webkit-border-radius: 5px; -} - -/* Uncomment for shadow */ -/*.tipsy-inner { box-shadow: 0 0 5px #000000; -webkit-box-shadow: 0 0 5px #000000; -moz-box-shadow: 0 0 5px #000000; }*/ - -.tipsy-arrow { - position: absolute; - width: 0; - height: 0; - line-height: 0; - border: 5px dashed #000; -} -/* Rules to colour arrows */ -.tipsy-arrow-n { border-bottom-color: #000; } -.tipsy-arrow-s { border-top-color: #000; } -.tipsy-arrow-e { border-left-color: #000; } -.tipsy-arrow-w { border-right-color: #000; } - -.tipsy-n .tipsy-arrow { top: 0px; left: 50%; margin-left: -5px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent; } -.tipsy-nw .tipsy-arrow { top: 0; left: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;} -.tipsy-ne .tipsy-arrow { top: 0; right: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;} -.tipsy-s .tipsy-arrow { bottom: 0; left: 50%; margin-left: -5px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; } -.tipsy-sw .tipsy-arrow { bottom: 0; left: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; } -.tipsy-se .tipsy-arrow { bottom: 0; right: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; } -.tipsy-e .tipsy-arrow { right: 0; top: 50%; margin-top: -5px; border-left-style: solid; border-right: none; border-top-color: transparent; border-bottom-color: transparent; } -.tipsy-w .tipsy-arrow { left: 0; top: 50%; margin-top: -5px; border-right-style: solid; border-left: none; border-top-color: transparent; border-bottom-color: transparent; } - -/* uni-form-generic --------------------------------------------------------------- */ - -/* Uni-Form by Dragan Babic [Superawesome Industries] - http: //sprawsm.com/uni-form/ */ -/* Some rights reserved - http: //creativecommons.org/licenses/by-sa/2.5/ */ -/* Do not edit this file directly, make your changes to uni-form.css in the same folder */ - -.uniForm{ margin: 0; padding: 0; position: relative; z-index: 1; } /* reset stuff */ - -/* Some generals and more resets */ -.uniForm fieldset{ border: none; margin: 0; padding: 0; } -.uniForm fieldset legend{ margin: 0; padding: 0; } - -/* This is the main unit that contains our form elements */ -.uniForm .ctrlHolder, -.uniForm .buttonHolder{ margin: 0; padding: 0; clear: both; } - -/* Clear all floats */ -.uniForm:after, -.uniForm .buttonHolder:after, -.uniForm .ctrlHolder:after, -.uniForm .ctrlHolder .multiField:after, -.uniForm .inlineLabel:after{ content: "."; display: block; height: 0; line-height: 0; font-size: 0; clear: both; min-height: 0; visibility: hidden; } - -/* A class to be used on a label that contains a checkbox or a radio button */ -.uniForm .inlineLabel, -.uniForm .inlineLabels .inlineLabel, -.uniForm .blockLabels .inlineLabel{ width: auto; float: none; margin: 0; display: block; } -/* IE shows borders & padding on checkboxes and radio buttons if they are declared on an input element, remove them */ -/* Legacy/Inheritance fix */ -.uniForm .inlineLabel input, -.uniForm .inlineLabels .inlineLabel input, -.uniForm .blockLabels .inlineLabel input{ border: none; padding: 0; margin: 0; } - -/* Styles for form controls where labels are above the input elements */ -/* Set the class of the parent (preferably to a fieldset) to .blockLabels */ - -.uniForm label, -.uniForm .label, -.uniForm .blockLabels label, -.uniForm .blockLabels .label{ display: block; float: none; padding: 0; line-height: 100%; width: auto; } - -/* Float the input elements */ -.uniForm .textInput, -.uniForm .blockLabels .textInput, -.uniForm .blockLabels .fileUpload, -.uniForm .selectInput, -.uniForm .blockLabels .selectInput, -.uniForm .blockLabels select, -.uniForm textarea, -.uniForm .blockLabels textarea{ float: left; } - -/* Postition the hints */ -.uniForm .formHint, -.uniForm .blockLabels .formHint{ float: right; margin: 0; clear: none; } - -/* Position the elements inside combo boxes (multiple selects/checkboxes/radio buttons per unit) */ -.uniForm .multiField, -.uniForm .blockLabels .multiField{ width: auto; float: left; } -.uniForm .multiField .inlineLabel, -.uniForm .blockLabels .multiField .inlineLabel{ display: block; margin: 0 0 .5em 0; } -.uniForm .multiField .blockLabel, -.uniForm .blockLabels .multiField .blockLabel{ float: left; width: auto; margin: 0; } -.uniForm .multiField .blockLabel .textInput, -.uniForm .multiField .blockLabel .selectInput, -.uniForm .multiField .blockLabel select, -.uniForm .blockLabels .multiField .blockLabel .textInput, -.uniForm .blockLabels .multiField .blockLabel .selectInput, -.uniForm .blockLabels .multiField .blockLabel select{ width: 100%; margin: 0; } - -/* Styles for form controls where labels are in line with the input elements */ -/* Set the class of the parent (preferably to a fieldset) to .inlineLabels */ -.uniForm .inlineLabels label, -.uniForm .inlineLabels .label{ float: left; margin: 0; padding: 0; line-height: 100%; position: relative; } - -/* Float the input elements */ -.uniForm .inlineLabels .textInput, -.uniForm .inlineLabels .fileUpload, -.uniForm .inlineLabels .selectInput, -.uniForm .inlineLabels select, -.uniForm .inlineLabels textarea{ float: left; } - -/* Postition the hints */ -.uniForm .inlineLabels .formHint{ clear: both; float: none; } -.uniForm .inlineLabels .multiField{ float: left; } -.uniForm .inlineLabels .multiField .inlineLabel{} -.uniForm .inlineLabels .multiField .blockLabel{} -.uniForm .inlineLabels .multiField .blockLabel .textInput, -.uniForm .inlineLabels .multiField .blockLabel .selectInput, -.uniForm .inlineLabels .multiField .blockLabel select{ display: block; width: 100%; float: none; } -.uniForm .inlineLabels .multiField select{ float: left; } - -/* Required fields asterisk styling for .blockLabels */ -.uniForm label em, -.uniForm .label em, -.uniForm .blockLabels label em, -.uniForm .blockLabels .label em{ position: absolute; left: -7px; } - -/* Required fields asterisk styling for .inlineLabels */ -.uniForm .inlineLabels label em, -.uniForm .inlineLabels .label em{ display: block; position: absolute; left: auto; right: 0; font-style: normal; font-weight: bold; } -.uniForm .inlineLabel em{ position: absolute; left: 7px; } - -/* Messages */ -.uniForm #errorMsg, -.uniForm .error{} -.uniForm #errorMsg dt, -.uniForm #errorMsg h3{} -.uniForm #errorMsg dd{} -.uniForm #errorMsg ol{} -.uniForm #errorMsg ol li{} -.uniForm .errorField{} -.uniForm #OKMsg{} - -/* Columns */ - -.uniForm .col{ float: left; } -.uniForm .col.first{} -.uniForm .col.last{} - -/* uni-form --------------------------------------------------------------- */ - -/* Keep in mind that wherever you see "Required property" it means that the property must exist */ - -/* ------------------------------------------------------------------------------ */ - -/* Generals */ -.uniForm fieldset{} -.uniForm fieldset legend{ color: #333; font-weight: bold; font-size: 100%; margin: 0; padding: 1.5em 1.5em 1.5em 0; } - -/* This is the main unit that contains our form elements */ -.uniForm .ctrlHolder{ padding: 3px; border-bottom: 1px dotted #dfdfdf; } - -.uniForm .buttonHolder{ - text-align: left; - background: #CEDEEF url("../images/buttonHolder_bg.gif") no-repeat right; - margin: 3em 0 1em; - padding: 8px; -} -.uniForm .resetButton{ float: left; } -.uniForm .primaryAction{ font-weight: bold; } - -/* This class gets added to div.ctrlHolder to highlight the row */ -.uniForm .focused{ background: #fffcdf; } - -/* .inlineLabel is used for inputs within labels - checkboxes and radio buttons */ -.uniForm .inlineLabel input, -.uniForm .inlineLabels .inlineLabel input, -.uniForm .blockLabels .inlineLabel input{ float: left; margin: 0 .4em 0 0; } -.uniForm .inlineLabel span{ float: left; width: 90%; } - -/* ------------------------------------------------------------------------------ */ - -/* .blockLabels (default style, will be applied even if you don"t class the parent element) */ -.uniForm .blockLabels .ctrlHolder{} - -.uniForm label, -.uniForm .blockLabels label, -.uniForm .blockLabels .label{ margin: 0 0 .5em 0; } - -.uniForm .textInput, -.uniForm .blockLabels .textInput, -.uniForm .blockLabels .fileUpload{ width: 43%; /* <- Required property */ } - -.uniForm .selectInput, -.uniForm select, -.uniForm .blockLabels .selectInput, -.uniForm .blockLabels select{ width: 43.5%; /* <- Required property */ } -.uniForm textarea, -.uniForm .blockLabels textarea{ width: 43%; /* <- Required property */ height: 12em; } - -.uniForm .formHint, -.uniForm .blockLabels .formHint{ width: 55%; /* <- Required property */ font-size: .9em; color: #777; position: relative; top: -.5em; } - -.uniForm .multiField, -.uniForm .blockLabels .multiField{ width: 43%; } -.uniForm .multiField .inlineLabel, -.uniForm .blockLabels .multiField .inlineLabel{ display: block; margin: 0 0 .5em 0; } -.uniForm .multiField .blockLabel, -.uniForm .blockLabels .multiField .blockLabel{ width: 30%; margin: 0 10px 0 0; } -.uniForm .multiField .blockLabel .textInput, -.uniForm .multiField .blockLabel .selectInput, -.uniForm .multiField .blockLabel select, -.uniForm .blockLabels .multiField .blockLabel .textInput, -.uniForm .blockLabels .multiField .blockLabel .selectInput, -.uniForm .blockLabels .multiField .blockLabel select{ width: 100%; margin: .3em 0 0 0; } - -/* ------------------------------------------------------------------------------ */ - -/* .inlineLabels */ -.uniForm .inlineLabels .ctrlHolder{} - -.uniForm .inlineLabels label, -.uniForm .inlineLabels .label{ width: 20%; /* <- Required property */ margin: .3em 2% 0 0; /* <- Required property */ } - -.uniForm .inlineLabels .textInput, -.uniForm .inlineLabels .fileUpload{ width: 35%; /* <- Required property */ } - -.uniForm .inlineLabels .selectInput, -.uniForm .inlineLabels select{ width: 35%; /* <- Required property */ } - -.uniForm .inlineLabels textarea{ width: 35%; /* <- Required property */ height: 12em; } - -.uniForm .inlineLabels .formHint{ margin-top: 0; margin-left: 22%; font-size: .9em; color: #777; position: static; } - -.uniForm .inlineLabels .multiField{ width: 60%; /* <- Required property */ margin: 0 0 .3em 0; } -.uniForm .inlineLabels .multiField .inlineLabel{ display: block; margin: 0 0 .5em 0; } -.uniForm .inlineLabels .multiField .blockLabel{ float: left; width: 26%; margin: 0 3% 0 0; } -.uniForm .inlineLabels .multiField .blockLabel .textInput, -.uniForm .inlineLabels .multiField .blockLabel .selectInput, -.uniForm .inlineLabels .multiField .blockLabel select{ width: 100%; margin: .3em 0 0 0; } - -/* Focus pseudoclasses */ -.uniForm .ctrlHolder .textInput:focus{ outline: none; /* Get rid of the "glow" effect in WebKit, optional */ } -.uniForm .ctrlHolder textarea:focus{ outline: none; /* Get rid of the "glow" effect in WebKit, optional */ } -.uniForm div.focused .formHint{ color: #333; } - -/* Columns (they are floated left by default) */ -.uniForm .col{ width: 37.9%; /* <- Required property */ margin: 0 2% 20px 0; } -/* Use .first and .last classes to control the layout/spacing of your columns */ -.uniForm .col.first{ width: 39%; /* <- Required property */ float: left; clear: none; } -.uniForm .col.last{ width: 39%; /* <- Required property */ float: right; clear: none; margin-right: 0; } - -/* Messages */ -.uniForm #errorMsg, .confirmpassworderror{ background: #ffdfdf; border: 1px solid #df7d7d; border-width: 1px 0; margin: 1.5em 0 1.5em 0; padding: 7px; } -.uniForm .error{ background: #ffdfdf; border: 1px solid #df7d7d; border-width: 1px 0; } - -.uniForm #errorMsg dt, .uniForm #errorMsg h3{ margin: 0 0 .5em 0; font-size: 100%; line-height: 100%; font-weight: bold; } -.uniForm #errorMsg dd{ margin: 0; padding: 0; } -.uniForm #errorMsg ol{ margin: 0; padding: 0; list-style:none;} -.uniForm #errorMsg ol li{ margin: 0; padding: 2px; list-style-position: inside; border-bottom: 1px dotted #df7d7d; position: relative; } -.uniForm .errorField{ color: #af4c4c; margin: 0 0 6px 0; padding: 4px; background: #ffbfbf; } - -.uniForm #OKMsg, .confirmpasswordok{ background: #C8FFBF; border: 1px solid #A2EF95; border-width: 1px 0; margin: 1.5em 0 1.5em 0; padding: 7px; } -.uniForm #OKMsg p{ margin: 0; } - -/* ------------------------------------------------------------------------------ */ - -/* This is the main unit that contains our form elements */ - -.uniForm .textInput, .uniForm .selectInput, .uniForm textarea { - background:#FFFFFF none repeat scroll 0 0; - color: #000000; - border: 1px solid #DFDFDF; - padding: 1px; -} - -/* jquery-ui-custom --------------------------------------------------------------- */ -.ui-datepicker-calendar thead tr th { - background-image:none; - background-color:#FFFFFF; - color:#000000; -} -.ui-widget { font-family: "Trebuchet MS", Arial, sans-serif; font-size: 100%; } -.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: "Trebuchet MS", Arial, sans-serif; font-size: 100%; } -ul.ui-autocomplete { max-height: 250px; overflow-y: auto; min-width: 85px;} -.ui-combobox { position: relative; display: inline-block; margin-right: 17px; } -.ui-combobox-toggle { position: absolute !important; top: 0; bottom: 0; margin-left: -1px; padding: 1px !important; background: none repeat scroll 0 0 #FFFFFF !important; border: 1px solid #DFDFDF !important;} -.ui-combobox-input { background: none repeat scroll 0 0 #FFFFFF !important; border: 1px solid #DFDFDF !important; padding: 1px; font-weight: normal !important; } -.panel_install_package .ui-combobox { float: left; } -.clear-float { clear: both; } - -a.link-page, span.page-spacer { - display: inline-block; - text-align: center; - padding: 2px; - line-height: 16px; - text-decoration: none !important; - color: inherit !important; - min-width: 16px; -} -a.link-page { - border: 1px solid #FFFFFF; - margin: 0 5px; -} - -a.link-page:hover { - background-color: #DFDFDF; -} - -span.page-spacer { - margin: 0 -5px; -} - -a.link-page.current-page { - background-color: #DFDFDF; - font-weight: bold; -} - -.command { - padding: 1em; - border: 1px dashed #2f6fab; - color: black; - background-color: #f9f9f9; - line-height: 1.1em; - font-family: Courier New, Courier, mono; - font-size: 12px; - font-style: italic; -} -.system { - color: black; - font-family: Courier New, Courier, mono; - font-size: 12px; - font-style: italic; -} -.highlight { - color: #FF0000; - font-family: Georgia, "Times New Roman", Times, serif; - font-size: 12px; - text-decoration: underline; +@charset "UTF-8"; +/* + Document : styles.css + Created on : 06.07.2012, 12:21:59 + Author : Christian Foellmann (foe-services.de) + Description: + Basis was css-code from the "ISPConfig 3: default theme" which was based on + "Yet Another Multicolumn Layout" - (X)HTML/CSS Framework 3.0.6 + by Copyright 2005-2008, Dirk Jesse (http://www.yaml.de) +*/ + +/* overall +-------------------------------------------------------------- */ +* { + margin: 0; + padding: 0; +} +html * { font-size: 100.01% } +body { + font-family: "Trebuchet MS", sans-serif; + font-size: 75.00%; + color: #444; + background: url("../images/screen_bg.png") repeat-x top left fixed #EEEEEE; + padding: 10px 0; +} +ul, ol, dl { line-height: 1.5em; margin: 0 0 1em 1em } +li { margin-left: 1.5em; line-height: 1.5em } +dt { font-weight: bold } +dd { margin: 0 0 1em 2em } +a { + color: #4D87C7; + text-decoration:none; +} +a:focus, +a:hover, +a:active { + color:#182E7A; + text-decoration:underline; +} +hr { + color: #fff; + background:transparent; + margin: 0 0 0.5em 0; + padding: 0 0 0.5em 0; + border:0; + border-bottom: 1px #eee solid; +} +textarea, pre, tt, code { + font-family: Consolas,"Lucida Console","Courier New",monospace; + font-size: 0.9em; +} + +h1,h2,h3,h4,h5,h6 { + font-family: "Trebuchet MS", sans-serif; + font-weight:bold; + color:#666; + margin: 0 0 0.25em 0; +} +h1 { font-size: 200% } /* 24px */ +h2 { font-size: 200% } /* 24px */ +h3 { font-size: 150% } /* 18px */ +h4 { font-size: 133.33% } /* 16px */ +h5 { font-size: 116.67% } /* 14px */ +h6 { font-size: 116.67%; font-style:italic } /* 14px */ + +p { line-height: 1.5em; margin: 0 0 1em 0; } + +cite, blockquote { font-style:italic } +blockquote { margin: 0 0 1em 1.5em } + +strong,b { font-weight: bold } +em,i { font-style:italic } + +pre, code { font-family: monospace; font-size: 1.1em; } + +acronym, abbr { + letter-spacing: .07em; + border-bottom: .1em dashed #c00; + cursor: help; +} + +header, #nav, #main, footer { + clear: both; +} +#page { + min-width: 980px; + max-width: 80%; + background: #fff; + text-align:left; + margin: 0 auto; + padding: 10px; +} +.skip, .hideme, .print { + height: 1px; + left: -1000em; + position: absolute; + top: -1000em; + width: 1px; +} + +/* header +-------------------------------------------------------------- */ +header { + position: relative; + color: #faf0e6; + padding: 15px 2em 5px 20px; + background: url("../images/header_bg.png") repeat-x top left #9a9a9a; +} +header h1 { + font-size:2.5em; + letter-spacing:-2px; + line-height:65%; + color: silver; +} +header span { + color: #333333; +} + +/* header/topsubnav +-------------------------------------------------------------- */ +#topsubnav { + position:absolute; + top: 10px; + right: 10px; + text-align: right; +} +#topsubnav a { + color: #f0f8ff; + font-weight: normal; + background:transparent; + text-decoration:none; +} +#topsubnav a:focus, +#topsubnav a:hover, +#topsubnav a:active { + text-decoration:underline; + background-color: transparent; +} + +/* nav +-------------------------------------------------------------- */ +#topNav ul { + list-style: none; + padding: 0 0 0 20px; + margin: 0; + background: #9a9a9a +} + +#topNav ul li { + display: inline; + margin: 0 2px 0 0; +} + +#topNav a { + background: url("../icons/x32_sprite.png") no-repeat #D3D3D3; + border-top-left-radius:5px; + border-top-right-radius:5px; + color:black; + display:inline-block; + height:20px; + padding-top:37px; + text-align:center; + text-decoration:none; + min-width:78px; +} + +#topNav a:hover { + background-color: #eeeeee; + color: #000000; +} + +#topNav #topNav_current a { + font-weight: bold; + color: black; + background-color: #ffffff; +} +.topnav-tools { background-position: 22px -10px !important; } +.topnav-admin { background-position: 22px -74px !important; } +.topnav-sites { background-position: 22px -523px !important; } +.topnav-monitor { background-position: 22px -585px !important; } +.topnav- { background-position: 22px -650px !important; } +.topnav-help { background-position: 22px -715px !important; } +.topnav-mail { background-position: 22px -780px !important; } +.topnav-mailuser { background-position: 22px -780px !important; } +.topnav-vm { background-position: 22px -842px !important; } +.topnav-domain { background-position: 22px -905px !important; } +.topnav-dns { background-position: 22px -970px !important; } +.topnav-dashboard { background-position: 22px -1035px !important; } +.topnav-client { background-position: 22px -1098px !important; } +.topnav-billing { background-position: 22px -1162px !important; } +#topNav a span { + padding: 0 3px; + } +/* main +-------------------------------------------------------------- */ +#main { + background: #fff; + padding: 1em 0; +} + +/* main/sideNav + submenu +-------------------------------------------------------------- */ +#sideNav { + width: 200px; + float:left; + padding: 0 10px 0 0; +} + +#submenu { + width: 100%; + overflow: hidden; + margin: 0px; + list-style-type: none; + border-bottom: 2px #ddd solid; +} + +#submenu ul { + list-style-type: none; + margin:0; + padding: 0; +} +#submenu li { + float:left; + width: 100%; + margin:0; + padding: 0; + font-size:0.9em; +} + +#submenu a, +#submenu strong { + display:block; + width: 90%; + padding: 2px 0px 2px 10%; + text-decoration: none; + background-color:#fff; + color: #444; + border-bottom: 1px #eee solid; +} + +/* Menu Title */ +#submenu li.title { + width: 100%; + padding: 0px; + font-weight: bold; + color: #444; + background-color: #fff; + border-top: 2px #888 solid; + font-size: 1.1em; +} + +#submenu li.title a { + background-color: #f0f8ff; + color: #444; +} +#submenu li.title a:hover { + color: white; +} + +#submenu li span { + display:block; + width: 90%; + padding: 3px 0px 3px 10%; + font-weight: bold; + border-bottom: 1px #ddd solid; +} + +/* Level 1 */ +#submenu li.active, +#submenu li strong { + width: 90%; + padding: 3px 0px 3px 10%; + font-weight: bold; + color: #fff; + background-color:#aab; + border-bottom: 1px #eee solid; +} + +#submenu li a { + width: 90%; + padding-left: 10%; + background-color:#fff; + color: #444; +} +#submenu li a:focus, +#submenu li a:hover, +#submenu li a:active { + background-color:#f63; + color: #fff; +} + +/* Form-Elements in the Menu*/ +#submenu * select#server_id { + margin: 3px 10%; + padding: 1px; + width: 80%; +} + +/* main/content +-------------------------------------------------------------- */ +#content { + margin-left: 200px; + margin-right: 0; + padding: 0px 10px 10px 20px; + border-left: 1px #ddd solid; +} + +/* footer +-------------------------------------------------------------- */ + +footer { + color:#666; + background: #f9f9f9; + padding: 10px 20px; + border-top: 5px #efefef solid; + font-size: 0.8em; + text-align: center; +} +footer a { + color: #999; + background:transparent; + font-weight: bold; +} +footer a:hover, footer a:active { + color: #4D87C7; + background-color: transparent; + text-decoration:underline; +} + +/* Set a background-color, no system backgorund used anymore */ +select, input, textarea { + background: #FFFFFF; + border: 1px solid #DFDFDF; + padding: 1px; + outline:none; +} + +table { width: auto; border-collapse:collapse; margin-bottom: 0.5em; } +table.full { width: 100%; } +table.fixed { table-layout:fixed } + +table.list td { + max-width: 350px; + min-width: 32px; + white-space: nowrap; + overflow:hidden; + text-overflow: ellipsis; + -o-text-overflow: ellipsis; + -icab-text-overflow: ellipsis; + -khtml-text-overflow: ellipsis; + -moz-text-overflow: ellipsis; + -webkit-text-overflow: ellipsis; +} +th, +td { + padding: 0.5em; + text-align:left; +} +thead th { + background: #444 url("../images/lists_thead_bg.png") repeat-x; + color: #fff; +} +tbody th { + background: #ccc; + color: #333; +} +tbody th.sub { + background: #ddd; + color: #333; +} +table.list th[class$="_pid"], +table.list td[class$="_pid"], +table.list th[class$="_active"], +table.list td[class$="_active"], +table.list th.tbl_col_autoresponder, +table.list td.tbl_col_autoresponder { + width: 70px; + text-align: center; +} +table.list .tbl_col_buttons, +table.list .tbl_col_limit { + width: 150px; +} +.tbl_col_client_pid input { + width: 50px; +} +.pnl_listarea th[class^="tbl_col"] { cursor:pointer; } +.pnl_listarea th[class^="tbl_col"]:hover { background-position:0 -15px!important; } +.pnl_listarea th.tbl_col_nosort { cursor:default; } +.pnl_listarea th.tbl_col_nosort:hover { background-position:0 0!important; } + +.pageForm_description { font-size: 12px; } + +/* Tab-Box */ +.tabbox_tabs { border-bottom: 1px solid #d3d3d3; } +.tabbox_tabs ul { + list-style: none; + padding: 0; + margin: 0; +} +.tabbox_tabs li { + display: inline; + margin: 0 2px 0 0; +} +.tabbox_tabs a { + padding: 0 1em; + text-decoration: none; + color: black; + background: #d3d3d3; + border: 1px solid #d3d3d3; +} +.tabbox_tabs a:hover { + background: #fc0; + color: #540; +} +.tabbox_tabs .active a { + font-weight: bold; + color: #ff6600; + background: #ffffff; +} +.pnl_toolsarea fieldset, .pnl_listarea fieldset, .pnl_formsarea fieldset { + border-top: 1px solid #949494; + margin: 20px 0; +} +.pnl_toolsarea fieldset legend , .pnl_listarea fieldset legend { + font-weight: bold; + color: #6299c5; +} +.pnl_formarea fieldset { + font-weight: bold; +} +/* hide line and legend when inside tabbed content */ +#tabbox_content * .pnl_toolsarea fieldset, #tabbox_content * .pnl_listarea fieldset, #tabbox_content * .pnl_formsarea fieldset { border: none !important; } +#tabbox_content * .pnl_toolsarea fieldset legend, #tabbox_content * .pnl_listarea fieldset legend, #tabbox_content * .pnl_formsarea fieldset legend { display: none !important; } +.codeview { + margin:20px 0; + padding:2px; + border: 1px solid #ffcc00; + background: #fffaea; + font-family: Consolas, "Lucida Console", "Courier New", monospace; + font-size: 0.9em; +} +/* Lists */ +table.list { + width: 100%; + border: 1px solid #d3d3d3 !important; +} +table.list thead th { font-size: 10px; } +table.list tbody { border: 1px solid #d3d3d3 !important; } +table.list tfoot td { text-align: center; background: #f8f8f8 url("../images/lists_tfoot_bg.png") repeat-x bottom left; padding: 24px 8px 8px 8px; } +table.list .tbl_paging img { vertical-align: top; } +table.list .tbl_row_even { background: #fcfcfc; } +table.list .tbl_row_uneven { background: #f0f8ff; } +table.list tr:hover { background: #fffacd; } +table.list td { word-wrap:break-word;white-space:pre-wrap; } +table.list td.tbl_col_buttons { word-wrap:normal;white-space:normal;overflow:visible; } + +/* Password Strength */ +#passBar { + width: 101px; height: 10px; + background: url("../images/meter_bg.gif") repeat-x bottom left; + margin: 2px 0; + float: left; +} +#passText { + padding: 0; + float: left; +} + +/* Systemmonitor */ +.systemmonitor-server, +.systemmonitor-ve, +.systemmonitor-state { + margin: 10px 5px; + font-family: Consolas, "Lucida Console", "Courier New", monospace; + font-size: 0.9em; + float: left; + width: 100%; +} +.systemmonitor-server:hover, +.systemmonitor-vm:hover { background-color: #FFFACD; } +.state-no_state, +.state-no_state-ve { + border-top: 4px solid #95A19F; + background-color: #f8f8ff; +} +.state-unknown, +.state-unknown-ve { + border-top: 4px solid #30302e; + background-color: #cecfc5; +} +.state-ok, +.state-ok-ve { + border-top: 4px solid #23fb00; + background-color: #adffa2; +} +.state-info, +.state-info-ve { + border-top: 4px solid #183e99; + background-color: #d4e2ff; +} +.state-warning, +.state-warning-ve { + border-top: 4px solid #ffa800; + background-color: #ffda93; +} +.state-critical, +.state-critical-ve { + border-top: 4px solid #ff0000; + background-color: #ffb9b9; +} +.state-error, +.state-error-ve { + border-top: 4px solid #ff0000; + background-color: #ff7f7f; +} +div.icoDevice { + float: left; + width: 64px; + height: 64px; + margin: 5px; + background: url("../icons/device_sprite.png") no-repeat transparent; +} +.systemmonitor-server div.icoDevice { background-position: 0 0; } +.systemmonitor-ve div.icoDevice { background-position: -64px 0; } +.systemmonitor-network div.icoDevice { background-position: -128px 0; } +div.statusDevice, +div.statusMsg { float: left; } +div.statusMsg p { + float: left; + padding: 5px; +} +.systemmonitor-state .status { + margin: 5px; +} +.status { + float: right; + width: 32px; + height: 32px; + background: url("../icons/x32_sprite.png") no-repeat transparent; +} +div.status { + float: left !important; +} +.state-warning .status, +.state-warning-ve .status { background-position: 0 -143px; } +.state-no_state .status, +.state-no_state-ve .status, +.state-unknown .status, +.state-unknown-ve .status { background-position: 0 -207px; } +.state-ok .status, +.state-ok-ve .status { background-position: 0 -270px; } +.state-info .status, +.state-info-ve .status { background-position: 0 -336px; } +.state-error .status, +.state-error-ve .status { background-position: 0 -400px; } +.state-critical .status, +.state-critical-ve .status { background-position: 0 -463px; } + +/* Usage unknown +.systemmonitor-content table { + border: none; + margin-top: 10px; +} + +.systemmonitor-content * .online { + border: 1px solid #ffffff; + background-color: #E3FFB8; + color: #000000; + padding:0px 5px; +} +.systemmonitor-content * .offline { + border: 1px solid #ffffff; + background-color: #d12f19; + color:#ffffff; + padding:0px 5px; +}*/ + +/* Dashboard */ +.dashboard-modules { + float:left; + width:60px; + height: 60px; + border:1px dotted #888888; + border-radius:5px; + background-color: #cccccc; + margin:10px; + background-position: center 5px; + background-repeat: no-repeat; + text-align: center; +} +.dashboard-modules a, +.dashboard-modules a:hover { + background: url("../icons/x32_sprite.png") no-repeat transparent; + color:Black; + display:block; + font-weight:bold; + height:30px; + padding-top:42px; + width:60px; + text-decoration: none; +} +.dashboard-modules.tools a { background-position: 12px -9px; } +.dashboard-modules.admin a { background-position: 12px -73px; } +.dashboard-modules.sites a { background-position: 12px -520px; } +.dashboard-modules.monitor a { background-position: 13px -585px; } +.dashboard-modules.help a { background-position: 13px -716px; } +.dashboard-modules.mail a { background-position: 12px -776px; } +.dashboard-modules.vm a { background-position: 14px -842px; } +.dashboard-modules.domain a { background-position: 12px -905px; } +.dashboard-modules.dns a { background-position: 12px -970px; } +.dashboard-modules.client a { background-position: 13px -1096px; } +.dashboard-modules.billing a { background-position: 14px -1162px; } + +.panel_dashboard h2 { font-size:20px; } + +/* Image-Replacement */ +.swap { background-repeat:no-repeat; } +.swap span { display:none; height:16px; } +#ir-HeaderLogo { + background-image: url("../images/header_logo.png"); + height:32px; + margin:0 0 0.2em; +} +div#ir-Yes, +div#ir-No { + text-align: center; + background: url("../icons/x16_sprite.png") no-repeat transparent; +} +#ir-Yes { + background-position: center -342px !important; + height: 16px; +} +#ir-No { + background-position: center -362px !important; + height: 16px; +} +.swap { + background-repeat: no-repeat; +} +.swap span { + display: none; + height: 16px; +} +/* BUTTONS */ +a.button, +.button, +.buttons button { + display: inline-block; + margin: 0 2px; + padding: 2px 5px; + color: #525252; + text-shadow: 0px 1px 1px #fff; + border: 1px solid #c6c6c6; + border-radius: 4px; + background-color: #f7f7f7; + box-shadow: 0 1px 1px 0 rgba(140, 140, 140, 0.3); + -o-box-shadow: 0 1px 1px 0 rgba(140, 140, 140, 0.3); + -webkit-box-shadow: 0 1px 1px 0 rgba(140, 140, 140, 0.3); + -moz-box-shadow: 0 1px 1px 0 rgba(140, 140, 140, 0.3); + text-decoration: none; +} +a.button:focus, +input.button:focus, +.buttons button:focus { + border-color: #4fadd5; + box-shadow: 0 0 2px 1px rgba(71,135,177, 0.6); + -moz-box-shadow: 0 0 2px 1px rgba(71,135,177, 0.6); + -webkit-box-shadow: 0 0 2px 1px rgba(71,135,177, 0.6); + -o-box-shadow: 0 0 2px 1px rgba(71,135,177, 0.6); + outline: none; +} +.buttons button[type]{ + padding:5px 10px 5px 7px; /* Firefox */ + line-height:17px; /* Safari */ + white-space: nowrap; +} +*:first-child+html button[type]{ + padding:4px 10px 3px 7px; /* IE7 */ +} +.buttons button img, +.buttons a img { + margin:0 3px -3px 0 !important; + padding:0; + border:none; + width:16px; + height:16px; +} +.topbuttons { + margin-bottom: 10px; +} +/* BUTTONS STANDARD */ +button:hover, +.buttons a:hover { + background-color:#dff4ff; + border:1px solid #c2e1ef; + color:#336699; +} +.buttons a:active { + background-color:#6299c5; + border:1px solid #6299c5; + color:#fff; +} + +/* BUTTONS POSITIVE */ +button.positive, +.buttons a.positive { color:#529214; } +.buttons a.positive:hover, +button.positive:hover { + background-color:#E6EFC2; + border:1px solid #C6D880; + color:#529214; +} +.buttons a.positive:active { + background-color:#529214; + border:1px solid #529214; + color:#fff; +} + +/* BUTTONS NEGATIVE */ +.buttons a.negative, +button.negative { + color:#d12f19; +} +.buttons a.negative:hover, +button.negative:hover { + background-color:#fbe3e4; + border:1px solid #fbc2c4; + color:#d12f19; +} +.buttons a.negative:active { + background-color:#d12f19; + border:1px solid #d12f19; + color:#fff; +} + +/* Button with icon and text */ +.iconstxt { background: url("../icons/button_sprite.png") no-repeat transparent; } +.iconstxt span { padding-left: 20px; font-weight: bold; } +.iconstxt.icoPositive { background-position: 6px -130px; } +.iconstxt.icoNegative { background-position: 6px -98px; } +.iconstxt.icoAdd { background-position: 6px -66px; } +.iconstxt.icoKey { background-position: 6px -1px; } +.iconstxt.icoDelete { background-position: 6px -34px; } +.iconstxt.icoDownload { background-position: 6px -1px; } +.iconstxt.icoRestore { background-position: 6px -1px; } + +/* Button with icon and without text */ +.icons16 { position: relative; } +.icons16>span { + opacity: 0; + visibility: hidden; + -webkit-transition: opacity 1s linear; + -moz-transition: opacity 1s linear; + -o-transition: opacity 1s linear; + -ms-transition: opacity 1s linear; + transition: opacity 1s linear; + position: absolute; + right: 23px; + top: -1px; + padding: 1px 2px; + border: 1px solid rgb(155,155,11); + background: rgb(255,255,111); + white-space: nowrap; +} +.icons16:hover>span { + opacity: 1.0; + visibility: visible; +} +a.icons16 { + height: 18px; + width: 18px; + padding: 0; + background: url("../icons/x16_sprite.png") no-repeat transparent; +} +button.icons16 { + height: 20px; + width: 20px; + padding: 0; + background: url("../icons/x16_sprite.png") no-repeat transparent; +} +.icons16.icoEdit { background-position: -1px -1px; } +.icons16.icoLoginAs { background-position: -1px -21px; } +.icons16.icoPDF { background-position: -1px -61px; } +.icons16.icoDelete { background-position: -1px -81px; } +.icons16.icoWebmailer { background-position: -1px -101px; } +.icons16.icoFilter { background-position: -1px -161px; } +.icons16.icoDbAdmin { background-position: -1px -221px; } +.icons16.icoAction { background-position: -1px -241px; } +.icons16.icoLink { background-position: -1px -422px; float: right; } + +div.group-icon { + float: left; + padding: 2px 0; +} +.group-admin, +.group-user { + height: 20px; + width: 20px; + padding: 0; + float: left; + background: url("../icons/x16_sprite.png") no-repeat transparent; +} +.group-admin { background-position: 0 -380px; } +.group-user { background-position: 0 -400px; } + +span.marked { color: #cc0000; } +span.small { font-size: 0.9em; } + +#ajaxloader { + position: absolute; + width: 325px; + height: 150px; + background: #ffffff url('../images/ajax-loader.gif') no-repeat center center; + border: solid 2px #e1e1e1; + border-radius: 10px; + /*background: rgba(255, 255, 255, 0.85);*/ + padding: 20px; + text-align:center; + z-index: 100; +} +.blockLabel.email_at { + width: 20px !important; + margin: 1.6em 0.3em 0 0 !important; +} +.textDisplay { display: block; } + +/* Form Length Classes */ +.textInput.formLengthBool { width: 25px !important; } +.selectInput.formLengthBool { width: 60px !important; } +.textInput.formLengthLimit { width: 50px !important; } +.selectInput.formLengthLimit { width: 85px !important; } +.formLengthDate { width: 75px !important; } +.formLengthIPv4 { width: 125px !important; } +.formLengthIPv6 { } +.formLengthEmailUser { width: 30% !important; } +.formLengthEmailDomain { width: 30% !important; } +.formLengthHalf { width: 15% !important; } +.formLengthDouble { width: 50% !important; } + +/* Individual Form Lengths */ +.textInput#username, +.textInput#password, +.textInput#passwort, +.textInput#source_password { width: 100px; } +.selectInput#language { width: 75px; } +.selectInput#client_group_id, .selectInput#default_group { width: 125px; } +input#refresh, input#retry, input#expire, input#minimum, input#ttl { width: 50px !important; } + +/* --- */ + +a[href $="#logout"] { + padding-right: 20px; + background: url("../icons/x16_sprite.png") no-repeat right -143px transparent !important; +} + +/* Select Menu with Images */ +select.withicons option { + background-repeat:no-repeat; + background-position: 1px; + padding-left:24px; +} +div[class^=country-] { + background-image: url("../icons/flags_sprite.png"); + background-repeat: no-repeat; + height: 20px; + width: 26px; +} +li[class^=country-] { + background-image: url("../icons/flags_sprite.png"); + background-repeat: no-repeat; + text-indent: 24px; +} +li[class^=country-] a.ui-state-hover { background: transparent; } +div[class^=country-] span { + display: none; +} +select.flags option { + background-image: url("../icons/flags_sprite.png"); + background-repeat: no-repeat; + padding: 1px 0 1px 30px; +} +select.flags option[value=EL] {background-position:0 -1475px} +select.flags option[value=AD], select.flags option[value=ad], .country-AD {background-position:0 -1px} +select.flags option[value=AE], select.flags option[value=ae], .country-AE {background-position:0 -23px} +select.flags option[value=AF], select.flags option[value=af], .country-AF {background-position:0 -45px} +select.flags option[value=AG], select.flags option[value=ag], .country-AG {background-position:0 -67px} +select.flags option[value=AI], select.flags option[value=ai], .country-AI {background-position:0 -89px} +select.flags option[value=AL], select.flags option[value=al], .country-AL {background-position:0 -111px} +select.flags option[value=AM], select.flags option[value=am], .country-AM {background-position:0 -133px} +select.flags option[value=AN], select.flags option[value=an], .country-AN {background-position:0 -155px} +select.flags option[value=AO], select.flags option[value=ao], .country-AO {background-position:0 -177px} +select.flags option[value=AQ], select.flags option[value=aq], .country-AQ {background-position:0 -199px} +select.flags option[value=AR], select.flags option[value=ar], .country-AR {background-position:0 -221px} +select.flags option[value=AS], select.flags option[value=as], .country-AS {background-position:0 -243px} +select.flags option[value=AT], select.flags option[value=at], .country-AT {background-position:0 -265px} +select.flags option[value=AU], select.flags option[value=au], .country-AU {background-position:0 -287px} +select.flags option[value=AW], select.flags option[value=aw], .country-AW {background-position:0 -309px} +select.flags option[value=AX], select.flags option[value=ax], .country-AX {background-position:0 -331px} +select.flags option[value=AZ], select.flags option[value=az], .country-AZ {background-position:0 -353px} +select.flags option[value=BA], select.flags option[value=ba], .country-BA {background-position:0 -375px} +select.flags option[value=BB], select.flags option[value=bb], .country-BB {background-position:0 -397px} +select.flags option[value=BD], select.flags option[value=bd], .country-BD {background-position:0 -419px} +select.flags option[value=BE], select.flags option[value=be], .country-BE {background-position:0 -441px} +select.flags option[value=BF], select.flags option[value=bf], .country-BF {background-position:0 -463px} +select.flags option[value=BG], select.flags option[value=bg], .country-BG {background-position:0 -485px} +select.flags option[value=BH], select.flags option[value=bh], .country-BH {background-position:0 -507px} +select.flags option[value=BI], select.flags option[value=bi], .country-BI {background-position:0 -529px} +select.flags option[value=BJ], select.flags option[value=bj], .country-BJ {background-position:0 -551px} +select.flags option[value=BM], select.flags option[value=bm], .country-BM {background-position:0 -573px} +select.flags option[value=BN], select.flags option[value=bn], .country-BN {background-position:0 -595px} +select.flags option[value=BO], select.flags option[value=bo], .country-BO {background-position:0 -617px} +select.flags option[value=BR], select.flags option[value=br], .country-BR {background-position:0 -639px} +select.flags option[value=BS], select.flags option[value=bs], .country-BS {background-position:0 -661px} +select.flags option[value=BT], select.flags option[value=bt], .country-BT {background-position:0 -683px} +select.flags option[value=BV], select.flags option[value=bv], .country-BV {background-position:0 -705px} +select.flags option[value=BW], select.flags option[value=bw], .country-BW {background-position:0 -727px} +select.flags option[value=BY], select.flags option[value=by], .country-BY {background-position:0 -749px} +select.flags option[value=BZ], select.flags option[value=bz], .country-BZ {background-position:0 -771px} +select.flags option[value=CA], select.flags option[value=ca], .country-CA {background-position:0 -793px} +select.flags option[value=CC], select.flags option[value=cc], .country-CC {background-position:0 -837px} +select.flags option[value=CD], select.flags option[value=cd], .country-CD {background-position:0 -859px} +select.flags option[value=CF], select.flags option[value=cf], .country-CF {background-position:0 -881px} +select.flags option[value=CG], select.flags option[value=cg], .country-CG {background-position:0 -903px} +select.flags option[value=CH], select.flags option[value=ch], .country-CH {background-position:0 -925px} +select.flags option[value=CI], select.flags option[value=ci], .country-CI {background-position:0 -947px} +select.flags option[value=CK], select.flags option[value=ck], .country-CK {background-position:0 -969px} +select.flags option[value=CL], select.flags option[value=cl], .country-CL {background-position:0 -991px} +select.flags option[value=CM], select.flags option[value=cm], .country-CM {background-position:0 -1013px} +select.flags option[value=CN], select.flags option[value=cn], .country-CN {background-position:0 -1035px} +select.flags option[value=CO], select.flags option[value=co], .country-CO {background-position:0 -1057px} +select.flags option[value=CR], select.flags option[value=cr], .country-CR {background-position:0 -1079px} +select.flags option[value=CS], select.flags option[value=cs], .country-CS {background-position:0 -1101px} +select.flags option[value=CU], select.flags option[value=cu], .country-CU {background-position:0 -1123px} +select.flags option[value=CV], select.flags option[value=cv], .country-CV {background-position:0 -1145px} +select.flags option[value=CX], select.flags option[value=cx], .country-CX {background-position:0 -1167px} +select.flags option[value=CY], select.flags option[value=cy], .country-CY {background-position:0 -1189px} +select.flags option[value=CZ], select.flags option[value=cz], .country-CZ {background-position:0 -1211px} +select.flags option[value=DE], select.flags option[value=de], .country-DE {background-position:0 -1233px} +select.flags option[value=DJ], select.flags option[value=dj], .country-DJ {background-position:0 -1255px} +select.flags option[value=DK], select.flags option[value=dk], .country-DK {background-position:0 -1277px} +select.flags option[value=DM], select.flags option[value=dm], .country-DM {background-position:0 -1299px} +select.flags option[value=DO], select.flags option[value=do], .country-DO {background-position:0 -1321px} +select.flags option[value=DZ], select.flags option[value=dz], .country-DZ {background-position:0 -1343px} +select.flags option[value=EC], select.flags option[value=ec], .country-EC {background-position:0 -1365px} +select.flags option[value=EE], select.flags option[value=ee], .country-EE {background-position:0 -1387px} +select.flags option[value=EG], select.flags option[value=eg], .country-EG {background-position:0 -1409px} +select.flags option[value=EH], select.flags option[value=eh], .country-EH {background-position:0 -1431px} +select.flags option[value=ER], select.flags option[value=er], .country-ER {background-position:0 -1475px} +select.flags option[value=ES], select.flags option[value=es], .country-ES {background-position:0 -1497px} +select.flags option[value=ET], select.flags option[value=ET], select.flags option[value=et], .country-ET {background-position:0 -1519px} +select.flags option[value=FI], select.flags option[value=fi], .country-FI {background-position:0 -1585px} +select.flags option[value=FJ], select.flags option[value=fj], .country-FJ {background-position:0 -1607px} +select.flags option[value=FK], select.flags option[value=fk], .country-FK {background-position:0 -1629px} +select.flags option[value=FM], select.flags option[value=fm], .country-FM {background-position:0 -1651px} +select.flags option[value=FO], select.flags option[value=fo], .country-FO {background-position:0 -1673px} +select.flags option[value=FR], select.flags option[value=fr], .country-FR {background-position:0 -1695px} +select.flags option[value=GA], select.flags option[value=ga], .country-GA {background-position:0 -1717px} +select.flags option[value=GB], select.flags option[value=en], select.flags option[value=gb], .country-GB, .country-EN {background-position:0 -1739px} +select.flags option[value=GD], select.flags option[value=gd], .country-GD {background-position:0 -1761px} +select.flags option[value=GE], select.flags option[value=ge], .country-GE {background-position:0 -1783px} +select.flags option[value=GF], select.flags option[value=gf], .country-GF {background-position:0 -1805px} +select.flags option[value=GH], select.flags option[value=gh], .country-GH {background-position:0 -1827px} +select.flags option[value=GI], select.flags option[value=gi], .country-GI {background-position:0 -1849px} +select.flags option[value=GL], select.flags option[value=gl], .country-GL {background-position:0 -1871px} +select.flags option[value=GM], select.flags option[value=gm], .country-GM {background-position:0 -1893px} +select.flags option[value=GN], select.flags option[value=gn], .country-GN {background-position:0 -1915px} +select.flags option[value=GP], select.flags option[value=gp], .country-GP {background-position:0 -1937px} +select.flags option[value=GQ], select.flags option[value=gq], .country-GQ {background-position:0 -1959px} +select.flags option[value=GR], select.flags option[value=el], select.flags option[value=gr], .country-GR, .country-EL {background-position:0 -1981px} +select.flags option[value=GS], select.flags option[value=gs], .country-GS {background-position:0 -2003px} +select.flags option[value=GT], select.flags option[value=gt], .country-GT {background-position:0 -2025px} +select.flags option[value=GU], select.flags option[value=gu], .country-GU {background-position:0 -2047px} +select.flags option[value=GW], select.flags option[value=gw], .country-GW {background-position:0 -2069px} +select.flags option[value=GY], select.flags option[value=gy], .country-GY {background-position:0 -2091px} +select.flags option[value=HK], select.flags option[value=hk], .country-HK {background-position:0 -2113px} +select.flags option[value=HM], select.flags option[value=hm], .country-HM {background-position:0 -2135px} +select.flags option[value=HN], select.flags option[value=hn], .country-HN {background-position:0 -2157px} +select.flags option[value=HR], select.flags option[value=hr], .country-HR {background-position:0 -2179px} +select.flags option[value=HT], select.flags option[value=ht], .country-HT {background-position:0 -2201px} +select.flags option[value=HU], select.flags option[value=hu], .country-HU {background-position:0 -2223px} +select.flags option[value=ID], select.flags option[value=id], .country-ID {background-position:0 -2245px} +select.flags option[value=IE], select.flags option[value=ie], .country-IE {background-position:0 -2267px} +select.flags option[value=IL], select.flags option[value=il], .country-IL {background-position:0 -2289px} +select.flags option[value=IN], select.flags option[value=in], .country-IN {background-position:0 -2311px} +select.flags option[value=IO], select.flags option[value=io], .country-IO {background-position:0 -2333px} +select.flags option[value=IQ], select.flags option[value=iq], .country-IQ {background-position:0 -2355px} +select.flags option[value=IR], select.flags option[value=ir], .country-IR {background-position:0 -2377px} +select.flags option[value=IS], select.flags option[value=is], .country-IS {background-position:0 -2399px} +select.flags option[value=IT], select.flags option[value=it], .country-IT {background-position:0 -2421px} +select.flags option[value=JM], select.flags option[value=jm], .country-JM {background-position:0 -2443px} +select.flags option[value=JO], select.flags option[value=jo], .country-JO {background-position:0 -2465px} +select.flags option[value=JP], select.flags option[value=ja], select.flags option[value=jp], .country-JP, .country-JA {background-position:0 -2487px} +select.flags option[value=KE], select.flags option[value=ke], .country-KE {background-position:0 -2509px} +select.flags option[value=KG], select.flags option[value=kg], .country-KG {background-position:0 -2531px} +select.flags option[value=KH], select.flags option[value=kh], .country-KH {background-position:0 -2553px} +select.flags option[value=KI], select.flags option[value=ki], .country-KI {background-position:0 -2575px} +select.flags option[value=KM], select.flags option[value=km], .country-KM {background-position:0 -2597px} +select.flags option[value=KN], select.flags option[value=kn], .country-KN {background-position:0 -2619px} +select.flags option[value=KP], select.flags option[value=kp], .country-KP {background-position:0 -2641px} +select.flags option[value=KR], select.flags option[value=kr], .country-KR {background-position:0 -2663px} +select.flags option[value=KW], select.flags option[value=kw], .country-KW {background-position:0 -2685px} +select.flags option[value=KY], select.flags option[value=ky], .country-KY {background-position:0 -2707px} +select.flags option[value=KZ], select.flags option[value=kz], .country-KZ {background-position:0 -2729px} +select.flags option[value=LA], select.flags option[value=la], .country-LA {background-position:0 -2751px} +select.flags option[value=LB], select.flags option[value=lb], .country-LB {background-position:0 -2773px} +select.flags option[value=LC], select.flags option[value=lc], .country-LC {background-position:0 -2795px} +select.flags option[value=LI], select.flags option[value=li], .country-LI {background-position:0 -2817px} +select.flags option[value=LK], select.flags option[value=lk], .country-LK {background-position:0 -2839px} +select.flags option[value=LR], select.flags option[value=lr], .country-LR {background-position:0 -2861px} +select.flags option[value=LS], select.flags option[value=ls], .country-LS {background-position:0 -2883px} +select.flags option[value=LT], select.flags option[value=lt], .country-LT {background-position:0 -2905px} +select.flags option[value=LU], select.flags option[value=lu], .country-LU {background-position:0 -2927px} +select.flags option[value=LV], select.flags option[value=lv], .country-LV {background-position:0 -2949px} +select.flags option[value=LY], select.flags option[value=ly], .country-LY {background-position:0 -2971px} +select.flags option[value=MA], select.flags option[value=ma], .country-MA {background-position:0 -2993px} +select.flags option[value=MC], select.flags option[value=mc], .country-MC {background-position:0 -3015px} +select.flags option[value=MD], select.flags option[value=md], .country-MD {background-position:0 -3037px} +select.flags option[value=ME], select.flags option[value=me], .country-ME {background-position:0 -3059px} +select.flags option[value=MG], select.flags option[value=mg], .country-MG {background-position:0 -3081px} +select.flags option[value=MH], select.flags option[value=mh], .country-MH {background-position:0 -3103px} +select.flags option[value=MK], select.flags option[value=mk], .country-MK {background-position:0 -3125px} +select.flags option[value=ML], select.flags option[value=ml], .country-ML {background-position:0 -3147px} +select.flags option[value=MM], select.flags option[value=mm], .country-MM {background-position:0 -3169px} +select.flags option[value=MN], select.flags option[value=mn], .country-MN {background-position:0 -3191px} +select.flags option[value=MO], select.flags option[value=mo], .country-MO {background-position:0 -3213px} +select.flags option[value=MP], select.flags option[value=mp], .country-MP {background-position:0 -3235px} +select.flags option[value=MQ], select.flags option[value=mq], .country-MQ {background-position:0 -3257px} +select.flags option[value=MR], select.flags option[value=mr], .country-MR {background-position:0 -3279px} +select.flags option[value=MS], select.flags option[value=ms], .country-MS {background-position:0 -3301px} +select.flags option[value=MT], select.flags option[value=mt], .country-MT {background-position:0 -3323px} +select.flags option[value=MU], select.flags option[value=mu], .country-MU {background-position:0 -3345px} +select.flags option[value=MV], select.flags option[value=mv], .country-MV {background-position:0 -3367px} +select.flags option[value=MW], select.flags option[value=mw], .country-MW {background-position:0 -3389px} +select.flags option[value=MX], select.flags option[value=mx], .country-MX {background-position:0 -3411px} +select.flags option[value=MY], select.flags option[value=my], .country-MY {background-position:0 -3433px} +select.flags option[value=MZ], select.flags option[value=mz], .country-MZ {background-position:0 -3455px} +select.flags option[value=NA], select.flags option[value=na], .country-NA {background-position:0 -3477px} +select.flags option[value=NC], select.flags option[value=nc], .country-NC {background-position:0 -3499px} +select.flags option[value=NE], select.flags option[value=ne], .country-NE {background-position:0 -3521px} +select.flags option[value=NF], select.flags option[value=nf], .country-NF {background-position:0 -3543px} +select.flags option[value=NG], select.flags option[value=ng], .country-NG {background-position:0 -3565px} +select.flags option[value=NI], select.flags option[value=ni], .country-NI {background-position:0 -3587px} +select.flags option[value=NL], select.flags option[value=nl], .country-NL {background-position:0 -3609px} +select.flags option[value=NO], select.flags option[value=no], .country-NO {background-position:0 -3631px} +select.flags option[value=NP], select.flags option[value=np], .country-NP {background-position:0 -3653px} +select.flags option[value=NR], select.flags option[value=nr], .country-NR {background-position:0 -3675px} +select.flags option[value=NU], select.flags option[value=nu], .country-NU {background-position:0 -3697px} +select.flags option[value=NZ], select.flags option[value=nz], .country-NZ {background-position:0 -3719px} +select.flags option[value=OM], select.flags option[value=om], .country-OM {background-position:0 -3741px} +select.flags option[value=PA], select.flags option[value=pa], .country-PA {background-position:0 -3763px} +select.flags option[value=PE], select.flags option[value=pe], .country-PE {background-position:0 -3785px} +select.flags option[value=PF], select.flags option[value=pf], .country-PF {background-position:0 -3807px} +select.flags option[value=PG], select.flags option[value=pg], .country-PG {background-position:0 -3829px} +select.flags option[value=PH], select.flags option[value=ph], .country-PH {background-position:0 -3851px} +select.flags option[value=PK], select.flags option[value=pk], .country-PK {background-position:0 -3873px} +select.flags option[value=PL], select.flags option[value=pl], .country-PL {background-position:0 -3895px} +select.flags option[value=PM], select.flags option[value=pm], .country-PM {background-position:0 -3917px} +select.flags option[value=PN], select.flags option[value=pn], .country-PN {background-position:0 -3939px} +select.flags option[value=PR], select.flags option[value=pr], .country-PR {background-position:0 -3961px} +select.flags option[value=PS], select.flags option[value=ps], .country-PS {background-position:0 -3983px} +select.flags option[value=PT], select.flags option[value=pt], .country-PT {background-position:0 -4005px} +select.flags option[value=PW], select.flags option[value=pw], .country-PW {background-position:0 -4027px} +select.flags option[value=PY], select.flags option[value=py], .country-PY {background-position:0 -4049px} +select.flags option[value=QA], select.flags option[value=qa], .country-QA {background-position:0 -4071px} +select.flags option[value=RE], select.flags option[value=re], .country-RE {background-position:0 -4093px} +select.flags option[value=RO], select.flags option[value=ro], .country-RO {background-position:0 -4115px} +select.flags option[value=RS], select.flags option[value=rs], .country-RS {background-position:0 -4137px} +select.flags option[value=RU], select.flags option[value=ru], .country-RU {background-position:0 -4159px} +select.flags option[value=RW], select.flags option[value=rw], .country-RW {background-position:0 -4181px} +select.flags option[value=SA], select.flags option[value=sa], .country-SA {background-position:0 -4203px} +select.flags option[value=SB], select.flags option[value=sb], .country-SB {background-position:0 -4225px} +select.flags option[value=SC], select.flags option[value=sc], .country-SC {background-position:0 -4247px} +select.flags option[value=SD], select.flags option[value=sd], .country-SD {background-position:0 -4291px} +select.flags option[value=SE], select.flags option[value=se], .country-SE {background-position:0 -4313px} +select.flags option[value=SG], select.flags option[value=sg], .country-SG {background-position:0 -4335px} +select.flags option[value=SH], select.flags option[value=sh], .country-SH {background-position:0 -4357px} +select.flags option[value=SI], select.flags option[value=si], .country-SI {background-position:0 -4379px} +select.flags option[value=SJ], select.flags option[value=sj], .country-SJ {background-position:0 -4401px} +select.flags option[value=SK], select.flags option[value=sk], .country-SK {background-position:0 -4423px} +select.flags option[value=SL], select.flags option[value=sl], .country-SL {background-position:0 -4445px} +select.flags option[value=SM], select.flags option[value=sm], .country-SM {background-position:0 -4467px} +select.flags option[value=SN], select.flags option[value=sn], .country-SN {background-position:0 -4489px} +select.flags option[value=SO], select.flags option[value=so], .country-SO {background-position:0 -4511px} +select.flags option[value=SR], select.flags option[value=sr], .country-SR {background-position:0 -4533px} +select.flags option[value=ST], select.flags option[value=st], .country-ST {background-position:0 -4555px} +select.flags option[value=SV], select.flags option[value=sv], .country-SV {background-position:0 -4577px} +select.flags option[value=SY], select.flags option[value=sy], .country-SY {background-position:0 -4599px} +select.flags option[value=SZ], select.flags option[value=sz], .country-SZ {background-position:0 -4621px} +select.flags option[value=TC], select.flags option[value=tc], .country-TC {background-position:0 -4643px} +select.flags option[value=TD], select.flags option[value=td], .country-TD {background-position:0 -4665px} +select.flags option[value=TF], select.flags option[value=tf], .country-TF {background-position:0 -4687px} +select.flags option[value=TG], select.flags option[value=tg], .country-TG {background-position:0 -4709px} +select.flags option[value=TH], select.flags option[value=th], .country-TH {background-position:0 -4731px} +select.flags option[value=TJ], select.flags option[value=tj], .country-TJ {background-position:0 -4753px} +select.flags option[value=TK], select.flags option[value=tk], .country-TK {background-position:0 -4775px} +select.flags option[value=TL], select.flags option[value=tl], .country-TL {background-position:0 -4797px} +select.flags option[value=TM], select.flags option[value=tm], .country-TM {background-position:0 -4819px} +select.flags option[value=TN], select.flags option[value=tn], .country-TN {background-position:0 -4841px} +select.flags option[value=TO], select.flags option[value=to], .country-TO {background-position:0 -4863px} +select.flags option[value=TR], select.flags option[value=tr], .country-TR {background-position:0 -4885px} +select.flags option[value=TT], select.flags option[value=tt], .country-TT {background-position:0 -4907px} +select.flags option[value=TV], select.flags option[value=tv], .country-TV {background-position:0 -4929px} +select.flags option[value=TW], select.flags option[value=tw], .country-TW {background-position:0 -4951px} +select.flags option[value=TZ], select.flags option[value=tz], .country-TZ {background-position:0 -4973px} +select.flags option[value=UA], select.flags option[value=ua], .country-UA {background-position:0 -4995px} +select.flags option[value=UG], select.flags option[value=ug], .country-UG {background-position:0 -5017px} +select.flags option[value=UM], select.flags option[value=um], .country-UM {background-position:0 -5039px} +select.flags option[value=US], select.flags option[value=us], .country-US {background-position:0 -5061px} +select.flags option[value=UY], select.flags option[value=uy], .country-UY {background-position:0 -5083px} +select.flags option[value=UZ], select.flags option[value=uz], .country-UZ {background-position:0 -5105px} +select.flags option[value=VA], select.flags option[value=va], .country-VA {background-position:0 -5127px} +select.flags option[value=VC], select.flags option[value=vc], .country-VC {background-position:0 -5149px} +select.flags option[value=VE], select.flags option[value=ve], .country-VE {background-position:0 -5171px} +select.flags option[value=VG], select.flags option[value=vg], .country-VG {background-position:0 -5193px} +select.flags option[value=VI], select.flags option[value=vi], .country-VI {background-position:0 -5215px} +select.flags option[value=VN], select.flags option[value=vn], .country-VN {background-position:0 -5237px} +select.flags option[value=VU], select.flags option[value=vu], .country-VU {background-position:0 -5259px} +select.flags option[value=WF], select.flags option[value=wf], .country-WF {background-position:0 -5303px} +select.flags option[value=WS], select.flags option[value=ws], .country-WS {background-position:0 -5325px} +select.flags option[value=YE], select.flags option[value=ye], .country-YE {background-position:0 -5347px} +select.flags option[value=YT], select.flags option[value=yt], .country-YT {background-position:0 -5369px} +select.flags option[value=ZA], select.flags option[value=za], .country-ZA {background-position:0 -5391px} +select.flags option[value=ZM], select.flags option[value=zm], .country-ZM {background-position:0 -5413px} +select.flags option[value=ZW], select.flags option[value=zw], .country-ZW {background-position:0 -5435px} + +.panel_login { + max-width: 80%; + min-width: 680px; +} +div.subsectiontoggle { + border:1px solid #ccc; + font-weight:bold; + font-size:14px; + padding-top:10px; + padding-bottom:0; + margin-top:5px; + text-indent:15px; + cursor:pointer; + margin-bottom:10px; + background-color:#f4f4f4; + -moz-border-radius:5px; + -webkit-border-radius:5px; + -khtml-border-radius:5px; + -o-border-radius:5px; + -ms-border-radius:5px; + border-radius:5px; +} +div.subsectiontoggle span { + display:inline-block; + margin-bottom:-3px; + margin-right:10px; + width:16px; + height:16px; + background: url("../icons/button_sprite.png") 0 -72px no-repeat transparent; +} +div.subsectiontoggle span.showing{ + background-position: 0 -40px; +} +div.subsectiontoggle em { + display:block; + position:relative; + left:425px; + top:-13px; + margin-bottom:-3px; + width:13px; + height:13px; + background:url("../images/chevron.png") top left no-repeat; + -webkit-transform:none; + -moz-transform:none; + -khtml-transform:none; + -o-transform:none; + -ms-transform:none; + transform:none; + -webkit-transition-duration: .2s; + -moz-transition-duration: .2s; + -khtml-transition-duration: .2s; + -o-transition-duration: .2s; + -ms-transition-duration: .2s; + transition-duration: .2s; + -webkit-transition-property: -webkit-transform; + -moz-transition-property: -moz-transform; + -khtml-transition-property: -khtml-transform; + -o-transition-property: -o-transform; + -ms-transition-property: -ms-transform; + transition-property: transform; +} +div.subsectiontoggle em.showing { + display:block; + position:relative; + left:425px; + top:-13px; + background:url("../images/chevron.png") top left no-repeat; + width:13px; + height:13px; + -webkit-transform:rotate(90deg); + -moz-transform:rotate(90deg); + -khtml-transform:rotate(90deg); + -o-transform:rotate(90deg); + -ms-transform:rotate(90deg); + transform:rotate(90deg); +} +div.subsectiontoggle:hover em { + -webkit-transform:rotate(90deg); + -moz-transform:rotate(90deg); + -khtml-transform:rotate(90deg); + -o-transform:rotate(90deg); + -ms-transform:rotate(90deg); + transform:rotate(90deg); +} + + +div.gs-container { + margin-top:10px; +} +div.gs-container * { + margin: 0; + padding: 0; + background-position: 0 0; + text-decoration: none; + font-size: 1em; +} +div.gs-container input { + background: url("../icons/x16_sprite.png") no-repeat 2px -119px #FFFFFF; + height:20px; + border:1px solid #444; + padding:0 22px 2px; + color:#444; + -moz-border-radius:5px; + -webkit-border-radius:5px; + -khtml-border-radius:5px; + -o-border-radius:5px; + -ms-border-radius:5px; + border-radius:5px; +} +input.gs-loading { + background-image: url("../images/loading.gif"); + background-repeat: no-repeat; + background-position: center right; +} +ul.gs-resultbox { + margin: 0 !important; + padding: 0 !important; + width: 300px; + z-index: 999999; + border: 1px solid #777; + font-size: 11px; + background: #fff; + -moz-box-shadow: 2px 2px 5px 0 #c5c5c5; + -webkit-box-shadow: 2px 2px 5px 0 #c5c5c5; + -khtml-box-shadow: 2px 2px 5px 0 #c5c5c5; + -o-box-shadow: 2px 2px 5px 0 #c5c5c5; + -ms-box-shadow: 2px 2px 5px 0 #c5c5c5; + box-shadow: 2px 2px 5px 0 #c5c5c5; + list-style: none; + -moz-border-radius:5px; + -webkit-border-radius:5px; + -khtml-border-radius:5px; + -o-border-radius:5px; + -ms-border-radius:5px; + border-radius:5px; + max-height:500px; + overflow:auto; +} +ul.gs-resultbox li { + float: left; + width: 100%; + clear: both; + cursor: pointer; +} +ul.gs-resultbox li.gs-cheader { + height: 13px; + overflow: hidden; + padding: 5px 0; + color: #fff; + background: #6ea6d1; + cursor:default; + padding-bottom:10px; +} +ul.gs-resultbox li.gs-cheader p.gs-cheader-title { + margin: 0 !important; + padding: 0 0 0 10px !important; + float: left; + font-size: 12px; + font-weight: bold; +} +ul.gs-resultbox li.gs-cheader p.gs-cheader-limit { + margin: 0 !important; + padding: 0 10px 0 0 !important; + float: right; + font-size: 11px; + font-weight: normal; +} +ul.gs-resultbox li.gs-cdata { + margin: 0 !important; + padding: 0 !important; + border-bottom: 1px solid #c5c5c5; +} +ul.gs-resultbox li.gs-cdata:last-child { + border-bottom: none; +} +ul.gs-resultbox li.gs-cdata:hover { + background: #eaf4fd; +} +ul.gs-resultbox li.gs-cdata a { + display: block; + padding: 5px 10px; + text-decoration: none !important; + background: #fff; +} +ul.gs-resultbox li.gs-cdata a:hover { + background: #cde0ff; +} +ul.gs-resultbox li.gs-cdata img { + margin-right: 12px; +} +ul.gs-resultbox li.gs-cdata p { + margin: 0 !important; + padding: 0 !important; + color: #444; + font-size: 10px; + min-height:30px; +} +ul.gs-resultbox li.gs-cdata p span.gs-cdata-title { + display: inline !important; + margin: 0 !important; + padding: 0 !important; + font-size: 11px; + font-weight: bold; + color: #000; +} +ul.gs-resultbox li:first-child { + -moz-border-radius:5px 5px 0 0; + -webkit-border-radius:5px 5px 0 0; + -khtml-border-radius:5px 5px 0 0; + -o-border-radius:5px 5px 0 0; + -ms-border-radius:5px 5px 0 0; + border-radius:5px 5px 0 0; +} +ul.gs-resultbox li:last-child { + -moz-border-radius:0 0 5px 5px; + -webkit-border-radius:0 0 5px 5px; + -khtml-border-radius:0 0 5px 5px; + -o-border-radius:0 0 5px 5px; + -ms-border-radius:0 0 5px 5px; + border-radius:0 0 5px 5px; +} + +div.df-container { +} +div.df-container * { + margin: 0; + padding: 0; + background-position: 0 0; + text-decoration: none; + font-size: 1em; +} +div.df-container input { +} +input.df-loading { + background-image: url("../images/loading.gif"); + background-repeat: no-repeat; + background-position: center right; +} +ul.df-resultbox { + margin: 0 !important; + padding: 0 !important; + min-width: 250px; + max-width: 500px; + z-index: 999999; + border: 1px solid #777; + font-size: 11px; + background: #fff; + -moz-box-shadow: 2px 2px 5px 0 #c5c5c5; + -webkit-box-shadow: 2px 2px 5px 0 #c5c5c5; + -khtml-box-shadow: 2px 2px 5px 0 #c5c5c5; + -o-box-shadow: 2px 2px 5px 0 #c5c5c5; + -ms-box-shadow: 2px 2px 5px 0 #c5c5c5; + box-shadow: 2px 2px 5px 0 #c5c5c5; + list-style: none; + -moz-border-radius:5px; + -webkit-border-radius:5px; + -khtml-border-radius:5px; + -o-border-radius:5px; + -ms-border-radius:5px; + border-radius:5px; +} +ul.df-resultbox li { + float: left; + width: 100%; + clear: both; + cursor: pointer; +} +ul.df-resultbox li.df-cheader { + height: 13px; + overflow: hidden; + padding: 5px 0; + color: #fff; + background: #6ea6d1; + cursor:default; + padding-bottom:10px; +} +ul.df-resultbox li.df-cheader p.df-cheader-title { + margin: 0 !important; + padding: 0 0 0 10px !important; + float: left; + font-size: 12px; + font-weight: bold; +} +ul.df-resultbox li.df-cheader p.df-cheader-limit { + margin: 0 !important; + padding: 0 10px 0 0 !important; + float: right; + font-size: 11px; + font-weight: normal; +} +ul.df-resultbox li.df-cdata { + margin: 0 !important; + padding: 0 !important; + border-bottom: 1px solid #c5c5c5; +} +ul.df-resultbox li.df-cdata:last-child { + border-bottom: none; +} +ul.df-resultbox li.df-cdata:hover { + background: #eaf4fd; +} +ul.df-resultbox li.df-cdata a { + display: block; + padding: 5px 10px; + text-decoration: none !important; + background: #fff; +} +ul.df-resultbox li.df-cdata a:hover { + background: #cde0ff; +} +ul.df-resultbox li.df-cdata img { + margin-right: 12px; +} +ul.df-resultbox li.df-cdata p { + margin: 0 !important; + padding: 0 !important; + color: #444; + font-size: 10px; + min-height:30px; +} +ul.df-resultbox li.df-cdata p span.df-cdata-title { + display: inline !important; + margin: 0 !important; + padding: 0 !important; + font-size: 11px; + font-weight: bold; + color: #000; +} +ul.df-resultbox li:first-child { + -moz-border-radius:5px 5px 0 0; + -webkit-border-radius:5px 5px 0 0; + -khtml-border-radius:5px 5px 0 0; + -o-border-radius:5px 5px 0 0; + -ms-border-radius:5px 5px 0 0; + border-radius:5px 5px 0 0; +} +ul.df-resultbox li:last-child { + -moz-border-radius:0 0 5px 5px; + -webkit-border-radius:0 0 5px 5px; + -khtml-border-radius:0 0 5px 5px; + -o-border-radius:0 0 5px 5px; + -ms-border-radius:0 0 5px 5px; + border-radius:0 0 5px 5px; +} + +span.icons16-empty { + float:left; + display:block; + height:20px; + width:20px; + margin:0 7px 0 0; +} + +.ttip { + width:16px; + height:16px; + cursor:pointer; + background: url("../icons/x16_sprite.png") no-repeat -2px -42px transparent; + float:right; + display:inline; + position:relative; + right:-2px; + top:-2px; +} + +p.prefix { + float: left; + margin: 0; + text-align: right; +} +p.label { + float: left; + margin: 5px 15px 0 0; +} +p.value { + float:left; + margin: 0 0 0 2px; +} + +/* content_ispc +-------------------------------------------------------------- */ +.tipsy { + font-size: 10px; + position: absolute; + padding: 5px; + z-index: 100000; +} +.tipsy-inner { + background-color: #000; + color: #FFF; + max-width: 350px; + padding: 5px 8px 4px 8px; + text-align: left; +} + +/* Rounded corners */ +.tipsy-inner { + border-radius: 5px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; +} + +/* Uncomment for shadow */ +/*.tipsy-inner { box-shadow: 0 0 5px #000000; -webkit-box-shadow: 0 0 5px #000000; -moz-box-shadow: 0 0 5px #000000; }*/ + +.tipsy-arrow { + position: absolute; + width: 0; + height: 0; + line-height: 0; + border: 5px dashed #000; +} +/* Rules to colour arrows */ +.tipsy-arrow-n { border-bottom-color: #000; } +.tipsy-arrow-s { border-top-color: #000; } +.tipsy-arrow-e { border-left-color: #000; } +.tipsy-arrow-w { border-right-color: #000; } + +.tipsy-n .tipsy-arrow { top: 0px; left: 50%; margin-left: -5px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent; } +.tipsy-nw .tipsy-arrow { top: 0; left: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;} +.tipsy-ne .tipsy-arrow { top: 0; right: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;} +.tipsy-s .tipsy-arrow { bottom: 0; left: 50%; margin-left: -5px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; } +.tipsy-sw .tipsy-arrow { bottom: 0; left: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; } +.tipsy-se .tipsy-arrow { bottom: 0; right: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; } +.tipsy-e .tipsy-arrow { right: 0; top: 50%; margin-top: -5px; border-left-style: solid; border-right: none; border-top-color: transparent; border-bottom-color: transparent; } +.tipsy-w .tipsy-arrow { left: 0; top: 50%; margin-top: -5px; border-right-style: solid; border-left: none; border-top-color: transparent; border-bottom-color: transparent; } + +/* uni-form-generic +-------------------------------------------------------------- */ + +/* Uni-Form by Dragan Babic [Superawesome Industries] - http: //sprawsm.com/uni-form/ */ +/* Some rights reserved - http: //creativecommons.org/licenses/by-sa/2.5/ */ +/* Do not edit this file directly, make your changes to uni-form.css in the same folder */ + +.uniForm{ margin: 0; padding: 0; position: relative; z-index: 1; } /* reset stuff */ + +/* Some generals and more resets */ +.uniForm fieldset{ border: none; margin: 0; padding: 0; } +.uniForm fieldset legend{ margin: 0; padding: 0; } + +/* This is the main unit that contains our form elements */ +.uniForm .ctrlHolder, +.uniForm .buttonHolder{ margin: 0; padding: 0; clear: both; } + +/* Clear all floats */ +.uniForm:after, +.uniForm .buttonHolder:after, +.uniForm .ctrlHolder:after, +.uniForm .ctrlHolder .multiField:after, +.uniForm .inlineLabel:after{ content: "."; display: block; height: 0; line-height: 0; font-size: 0; clear: both; min-height: 0; visibility: hidden; } + +/* A class to be used on a label that contains a checkbox or a radio button */ +.uniForm .inlineLabel, +.uniForm .inlineLabels .inlineLabel, +.uniForm .blockLabels .inlineLabel{ width: auto; float: none; margin: 0; display: block; } +/* IE shows borders & padding on checkboxes and radio buttons if they are declared on an input element, remove them */ +/* Legacy/Inheritance fix */ +.uniForm .inlineLabel input, +.uniForm .inlineLabels .inlineLabel input, +.uniForm .blockLabels .inlineLabel input{ border: none; padding: 0; margin: 0; } + +/* Styles for form controls where labels are above the input elements */ +/* Set the class of the parent (preferably to a fieldset) to .blockLabels */ + +.uniForm label, +.uniForm .label, +.uniForm .blockLabels label, +.uniForm .blockLabels .label{ display: block; float: none; padding: 0; line-height: 100%; width: auto; } + +/* Float the input elements */ +.uniForm .textInput, +.uniForm .blockLabels .textInput, +.uniForm .blockLabels .fileUpload, +.uniForm .selectInput, +.uniForm .blockLabels .selectInput, +.uniForm .blockLabels select, +.uniForm textarea, +.uniForm .blockLabels textarea{ float: left; } + +/* Postition the hints */ +.uniForm .formHint, +.uniForm .blockLabels .formHint{ float: right; margin: 0; clear: none; } + +/* Position the elements inside combo boxes (multiple selects/checkboxes/radio buttons per unit) */ +.uniForm .multiField, +.uniForm .blockLabels .multiField{ width: auto; float: left; } +.uniForm .multiField .inlineLabel, +.uniForm .blockLabels .multiField .inlineLabel{ display: block; margin: 0 0 .5em 0; } +.uniForm .multiField .blockLabel, +.uniForm .blockLabels .multiField .blockLabel{ float: left; width: auto; margin: 0; } +.uniForm .multiField .blockLabel .textInput, +.uniForm .multiField .blockLabel .selectInput, +.uniForm .multiField .blockLabel select, +.uniForm .blockLabels .multiField .blockLabel .textInput, +.uniForm .blockLabels .multiField .blockLabel .selectInput, +.uniForm .blockLabels .multiField .blockLabel select{ width: 100%; margin: 0; } + +/* Styles for form controls where labels are in line with the input elements */ +/* Set the class of the parent (preferably to a fieldset) to .inlineLabels */ +.uniForm .inlineLabels label, +.uniForm .inlineLabels .label{ float: left; margin: 0; padding: 0; line-height: 100%; position: relative; } + +/* Float the input elements */ +.uniForm .inlineLabels .textInput, +.uniForm .inlineLabels .fileUpload, +.uniForm .inlineLabels .selectInput, +.uniForm .inlineLabels select, +.uniForm .inlineLabels textarea{ float: left; } + +/* Postition the hints */ +.uniForm .inlineLabels .formHint{ clear: both; float: none; } +.uniForm .inlineLabels .multiField{ float: left; } +.uniForm .inlineLabels .multiField .inlineLabel{} +.uniForm .inlineLabels .multiField .blockLabel{} +.uniForm .inlineLabels .multiField .blockLabel .textInput, +.uniForm .inlineLabels .multiField .blockLabel .selectInput, +.uniForm .inlineLabels .multiField .blockLabel select{ display: block; width: 100%; float: none; } +.uniForm .inlineLabels .multiField select{ float: left; } + +/* Required fields asterisk styling for .blockLabels */ +.uniForm label em, +.uniForm .label em, +.uniForm .blockLabels label em, +.uniForm .blockLabels .label em{ position: absolute; left: -7px; } + +/* Required fields asterisk styling for .inlineLabels */ +.uniForm .inlineLabels label em, +.uniForm .inlineLabels .label em{ display: block; position: absolute; left: auto; right: 0; font-style: normal; font-weight: bold; } +.uniForm .inlineLabel em{ position: absolute; left: 7px; } + +/* Messages */ +.uniForm #errorMsg, +.uniForm .error{} +.uniForm #errorMsg dt, +.uniForm #errorMsg h3{} +.uniForm #errorMsg dd{} +.uniForm #errorMsg ol{} +.uniForm #errorMsg ol li{} +.uniForm .errorField{} +.uniForm #OKMsg{} + +/* Columns */ + +.uniForm .col{ float: left; } +.uniForm .col.first{} +.uniForm .col.last{} + +/* uni-form +-------------------------------------------------------------- */ + +/* Keep in mind that wherever you see "Required property" it means that the property must exist */ + +/* ------------------------------------------------------------------------------ */ + +/* Generals */ +.uniForm fieldset{} +.uniForm fieldset legend{ color: #333; font-weight: bold; font-size: 100%; margin: 0; padding: 1.5em 1.5em 1.5em 0; } + +/* This is the main unit that contains our form elements */ +.uniForm .ctrlHolder{ padding: 3px; border-bottom: 1px dotted #dfdfdf; } + +.uniForm .buttonHolder{ + text-align: left; + background: #CEDEEF url("../images/buttonHolder_bg.gif") no-repeat right; + margin: 3em 0 1em; + padding: 8px; +} +.uniForm .resetButton{ float: left; } +.uniForm .primaryAction{ font-weight: bold; } + +/* This class gets added to div.ctrlHolder to highlight the row */ +.uniForm .focused{ background: #fffcdf; } + +/* .inlineLabel is used for inputs within labels - checkboxes and radio buttons */ +.uniForm .inlineLabel input, +.uniForm .inlineLabels .inlineLabel input, +.uniForm .blockLabels .inlineLabel input{ float: left; margin: 0 .4em 0 0; } +.uniForm .inlineLabel span{ float: left; width: 90%; } + +/* ------------------------------------------------------------------------------ */ + +/* .blockLabels (default style, will be applied even if you don"t class the parent element) */ +.uniForm .blockLabels .ctrlHolder{} + +.uniForm label, +.uniForm .blockLabels label, +.uniForm .blockLabels .label{ margin: 0 0 .5em 0; } + +.uniForm .textInput, +.uniForm .blockLabels .textInput, +.uniForm .blockLabels .fileUpload{ width: 43%; /* <- Required property */ } + +.uniForm .selectInput, +.uniForm select, +.uniForm .blockLabels .selectInput, +.uniForm .blockLabels select{ width: 43.5%; /* <- Required property */ } +.uniForm textarea, +.uniForm .blockLabels textarea{ width: 43%; /* <- Required property */ height: 12em; } + +.uniForm .formHint, +.uniForm .blockLabels .formHint{ width: 55%; /* <- Required property */ font-size: .9em; color: #777; position: relative; top: -.5em; } + +.uniForm .multiField, +.uniForm .blockLabels .multiField{ width: 43%; } +.uniForm .multiField .inlineLabel, +.uniForm .blockLabels .multiField .inlineLabel{ display: block; margin: 0 0 .5em 0; } +.uniForm .multiField .blockLabel, +.uniForm .blockLabels .multiField .blockLabel{ width: 30%; margin: 0 10px 0 0; } +.uniForm .multiField .blockLabel .textInput, +.uniForm .multiField .blockLabel .selectInput, +.uniForm .multiField .blockLabel select, +.uniForm .blockLabels .multiField .blockLabel .textInput, +.uniForm .blockLabels .multiField .blockLabel .selectInput, +.uniForm .blockLabels .multiField .blockLabel select{ width: 100%; margin: .3em 0 0 0; } + +/* ------------------------------------------------------------------------------ */ + +/* .inlineLabels */ +.uniForm .inlineLabels .ctrlHolder{} + +.uniForm .inlineLabels label, +.uniForm .inlineLabels .label{ width: 20%; /* <- Required property */ margin: .3em 2% 0 0; /* <- Required property */ } + +.uniForm .inlineLabels .textInput, +.uniForm .inlineLabels .fileUpload{ width: 35%; /* <- Required property */ } + +.uniForm .inlineLabels .selectInput, +.uniForm .inlineLabels select{ width: 35%; /* <- Required property */ } + +.uniForm .inlineLabels textarea{ width: 35%; /* <- Required property */ height: 12em; } + +.uniForm .inlineLabels .formHint{ margin-top: 0; margin-left: 22%; font-size: .9em; color: #777; position: static; } + +.uniForm .inlineLabels .multiField{ width: 60%; /* <- Required property */ margin: 0 0 .3em 0; } +.uniForm .inlineLabels .multiField .inlineLabel{ display: block; margin: 0 0 .5em 0; } +.uniForm .inlineLabels .multiField .blockLabel{ float: left; width: 26%; margin: 0 3% 0 0; } +.uniForm .inlineLabels .multiField .blockLabel .textInput, +.uniForm .inlineLabels .multiField .blockLabel .selectInput, +.uniForm .inlineLabels .multiField .blockLabel select{ width: 100%; margin: .3em 0 0 0; } + +/* Focus pseudoclasses */ +.uniForm .ctrlHolder .textInput:focus{ outline: none; /* Get rid of the "glow" effect in WebKit, optional */ } +.uniForm .ctrlHolder textarea:focus{ outline: none; /* Get rid of the "glow" effect in WebKit, optional */ } +.uniForm div.focused .formHint{ color: #333; } + +/* Columns (they are floated left by default) */ +.uniForm .col{ width: 37.9%; /* <- Required property */ margin: 0 2% 20px 0; } +/* Use .first and .last classes to control the layout/spacing of your columns */ +.uniForm .col.first{ width: 39%; /* <- Required property */ float: left; clear: none; } +.uniForm .col.last{ width: 39%; /* <- Required property */ float: right; clear: none; margin-right: 0; } + +/* Messages */ +.uniForm #errorMsg, .confirmpassworderror{ background: #ffdfdf; border: 1px solid #df7d7d; border-width: 1px 0; margin: 1.5em 0 1.5em 0; padding: 7px; } +.uniForm .error{ background: #ffdfdf; border: 1px solid #df7d7d; border-width: 1px 0; } + +.uniForm #errorMsg dt, .uniForm #errorMsg h3{ margin: 0 0 .5em 0; font-size: 100%; line-height: 100%; font-weight: bold; } +.uniForm #errorMsg dd{ margin: 0; padding: 0; } +.uniForm #errorMsg ol{ margin: 0; padding: 0; list-style:none;} +.uniForm #errorMsg ol li{ margin: 0; padding: 2px; list-style-position: inside; border-bottom: 1px dotted #df7d7d; position: relative; } +.uniForm .errorField{ color: #af4c4c; margin: 0 0 6px 0; padding: 4px; background: #ffbfbf; } + +.uniForm #OKMsg, .confirmpasswordok{ background: #C8FFBF; border: 1px solid #A2EF95; border-width: 1px 0; margin: 1.5em 0 1.5em 0; padding: 7px; } +.uniForm #OKMsg p{ margin: 0; } + +/* ------------------------------------------------------------------------------ */ + +/* This is the main unit that contains our form elements */ + +.uniForm .textInput, .uniForm .selectInput, .uniForm textarea { + background:#FFFFFF none repeat scroll 0 0; + color: #000000; + border: 1px solid #DFDFDF; + padding: 1px; +} + +/* jquery-ui-custom +-------------------------------------------------------------- */ +.ui-datepicker-calendar thead tr th { + background-image:none; + background-color:#FFFFFF; + color:#000000; +} +.ui-widget { font-family: "Trebuchet MS", Arial, sans-serif; font-size: 100%; } +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: "Trebuchet MS", Arial, sans-serif; font-size: 100%; } +ul.ui-autocomplete { max-height: 250px; overflow-y: auto; min-width: 85px;} +.ui-combobox { position: relative; display: inline-block; margin-right: 17px; } +.ui-combobox-toggle { position: absolute !important; top: 0; bottom: 0; margin-left: -1px; padding: 1px !important; background: none repeat scroll 0 0 #FFFFFF !important; border: 1px solid #DFDFDF !important;} +.ui-combobox-input { background: none repeat scroll 0 0 #FFFFFF !important; border: 1px solid #DFDFDF !important; padding: 1px; font-weight: normal !important; } +.panel_install_package .ui-combobox { float: left; } +.clear-float { clear: both; } + +a.link-page, span.page-spacer { + display: inline-block; + text-align: center; + padding: 2px; + line-height: 16px; + text-decoration: none !important; + color: inherit !important; + min-width: 16px; +} +a.link-page { + border: 1px solid #FFFFFF; + margin: 0 5px; +} + +a.link-page:hover { + background-color: #DFDFDF; +} + +span.page-spacer { + margin: 0 -5px; +} + +a.link-page.current-page { + background-color: #DFDFDF; + font-weight: bold; +} + +.command { + padding: 1em; + border: 1px dashed #2f6fab; + color: black; + background-color: #f9f9f9; + line-height: 1.1em; + font-family: Courier New, Courier, mono; + font-size: 12px; + font-style: italic; +} +.system { + color: black; + font-family: Courier New, Courier, mono; + font-size: 12px; + font-style: italic; +} +.highlight { + color: #FF0000; + font-family: Georgia, "Times New Roman", Times, serif; + font-size: 12px; + text-decoration: underline; } \ No newline at end of file diff --git a/interface/web/tools/lib/interface.d/tpl_default.menu.php b/interface/web/tools/lib/interface.d/tpl_default.menu.php index 7b8555c609cd8ce36f9b5bbeb4f432f93726bc20..f55b480e8c8bc813d4bffc9396e711e651483297 100644 --- a/interface/web/tools/lib/interface.d/tpl_default.menu.php +++ b/interface/web/tools/lib/interface.d/tpl_default.menu.php @@ -1,8 +1,8 @@ -<?php - -// No settings yet -//$items[] = array( 'title' => 'Default Theme', -// 'target' => 'content', -// 'link' => 'tools/tpl_default.php', -// 'html_id' => 'tpl_default'); -?> +<?php + +// No settings yet +//$items[] = array( 'title' => 'Default Theme', +// 'target' => 'content', +// 'link' => 'tools/tpl_default.php', +// 'html_id' => 'tpl_default'); +?> diff --git a/server/lib/classes/aps_base.inc.php b/server/lib/classes/aps_base.inc.php index b8f6ad9232275d3ec5135002307c8e4629f82b13..4c1512ba2a018e45f9aee6ef758be1c65e767b70 100644 --- a/server/lib/classes/aps_base.inc.php +++ b/server/lib/classes/aps_base.inc.php @@ -1,103 +1,103 @@ -<?php -/* -Copyright (c) 2012, ISPConfig UG -Contributors: web wack creations, http://www.web-wack.at -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of ISPConfig nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -// Constants describing instances -define('INSTANCE_PENDING', 0); -define('INSTANCE_INSTALL', 1); -define('INSTANCE_ERROR', 2); -define('INSTANCE_SUCCESS', 3); -define('INSTANCE_REMOVE', 4); - -// Constants describing packages -define('PACKAGE_LOCKED', 1); -define('PACKAGE_ENABLED', 2); -define('PACKAGE_OUTDATED', 3); -define('PACKAGE_ERROR_NOMETA', 4); - -class ApsBase -{ - protected $log_prefix = ''; - protected $fetch_url = ''; - protected $aps_version = ''; - protected $packages_dir = ''; - protected $temp_pkg_dir = ''; - protected $interface_pkg_dir = ''; - protected $interface_mode = false; // server mode by default - - /** - * Constructor - * - * @param $app the application instance (db handle + log method) - * @param $interface_mode act in interface (true) or server mode (false) - * @param $log_prefix a prefix to set before all log entries - */ - public function __construct($app, $log_prefix = 'APS: ', $interface_mode = false) - { - $this->log_prefix = $log_prefix; - $this->interface_mode = $interface_mode; - $this->fetch_url = 'apscatalog.com'; - $this->aps_version = '1'; - $this->packages_dir = ISPC_ROOT_PATH.'/aps_packages'; - $this->interface_pkg_dir = ISPC_ROOT_PATH.'/web/sites/aps_meta_packages'; - } - - /** - * Converts a given value to it's native representation in 1024 units - * - * @param $value the size to convert - * @return integer and string - */ - public function convertSize($value) - { - $unit = array('Bytes', 'KB', 'MB', 'GB', 'TB'); - return @round($value/pow(1024, ($i = floor(log($value, 1024)))), 2).' '.$unit[$i]; - } - - /** - * Determine a specific xpath from a given SimpleXMLElement handle. If the - * element is found, it's string representation is returned. If not, - * the return value will stay empty - * - * @param $xml_handle the SimpleXMLElement handle - * @param $query the XPath query - * @param $array define whether to return an array or a string - * @return $ret the return string - */ - protected function getXPathValue($xml_handle, $query, $array = false) - { - $ret = ''; - - $xp_result = @($xml_handle->xpath($query)) ? $xml_handle->xpath($query) : false; - if($xp_result !== false) $ret = (($array === false) ? (string)$xp_result[0] : $xp_result); - - return $ret; - } -} +<?php +/* +Copyright (c) 2012, ISPConfig UG +Contributors: web wack creations, http://www.web-wack.at +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of ISPConfig nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +// Constants describing instances +define('INSTANCE_PENDING', 0); +define('INSTANCE_INSTALL', 1); +define('INSTANCE_ERROR', 2); +define('INSTANCE_SUCCESS', 3); +define('INSTANCE_REMOVE', 4); + +// Constants describing packages +define('PACKAGE_LOCKED', 1); +define('PACKAGE_ENABLED', 2); +define('PACKAGE_OUTDATED', 3); +define('PACKAGE_ERROR_NOMETA', 4); + +class ApsBase +{ + protected $log_prefix = ''; + protected $fetch_url = ''; + protected $aps_version = ''; + protected $packages_dir = ''; + protected $temp_pkg_dir = ''; + protected $interface_pkg_dir = ''; + protected $interface_mode = false; // server mode by default + + /** + * Constructor + * + * @param $app the application instance (db handle + log method) + * @param $interface_mode act in interface (true) or server mode (false) + * @param $log_prefix a prefix to set before all log entries + */ + public function __construct($app, $log_prefix = 'APS: ', $interface_mode = false) + { + $this->log_prefix = $log_prefix; + $this->interface_mode = $interface_mode; + $this->fetch_url = 'apscatalog.com'; + $this->aps_version = '1'; + $this->packages_dir = ISPC_ROOT_PATH.'/aps_packages'; + $this->interface_pkg_dir = ISPC_ROOT_PATH.'/web/sites/aps_meta_packages'; + } + + /** + * Converts a given value to it's native representation in 1024 units + * + * @param $value the size to convert + * @return integer and string + */ + public function convertSize($value) + { + $unit = array('Bytes', 'KB', 'MB', 'GB', 'TB'); + return @round($value/pow(1024, ($i = floor(log($value, 1024)))), 2).' '.$unit[$i]; + } + + /** + * Determine a specific xpath from a given SimpleXMLElement handle. If the + * element is found, it's string representation is returned. If not, + * the return value will stay empty + * + * @param $xml_handle the SimpleXMLElement handle + * @param $query the XPath query + * @param $array define whether to return an array or a string + * @return $ret the return string + */ + protected function getXPathValue($xml_handle, $query, $array = false) + { + $ret = ''; + + $xp_result = @($xml_handle->xpath($query)) ? $xml_handle->xpath($query) : false; + if($xp_result !== false) $ret = (($array === false) ? (string)$xp_result[0] : $xp_result); + + return $ret; + } +} ?> \ No newline at end of file diff --git a/server/lib/classes/aps_installer.inc.php b/server/lib/classes/aps_installer.inc.php index 6cb922f67462666d3ee2599eec28e45cb5533fa5..f52355f372ce5ff12ec7e3456cee6b383be4803f 100644 --- a/server/lib/classes/aps_installer.inc.php +++ b/server/lib/classes/aps_installer.inc.php @@ -1,720 +1,720 @@ -<?php -/* -Copyright (c) 2012, ISPConfig UG -Contributors: web wack creations, http://www.web-wack.at -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of ISPConfig nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -require_once('aps_base.inc.php'); - -@set_time_limit(0); -@ignore_user_abort(1); - -class ApsInstaller extends ApsBase -{ - private $handle_type = ''; - private $domain = ''; - private $document_root = ''; - private $sublocation = ''; - private $local_installpath = ''; - private $dbhost = ''; - private $newdb_name = ''; - private $newdb_user = ''; - private $file_owner_user = ''; - private $file_owner_group = ''; - private $putenv = array(); - - /** - * Constructor - * - * @param $app the application instance (db handle + log method) - * @param $interface_mode act in interface (true) or server mode (false) - */ - public function __construct($app, $interface_mode = false) - { - parent::__construct($app, 'APS installer: ', $interface_mode); - } - - /** - * Before the cron is executed, make sure all necessary options are set - * and all functions are available - */ - private function checkRequirements() - { - global $app; - try - { - // Check if exec() is not disabled - $disabled_func = explode(',', @ini_get('disable_functions')); - if(in_array('exec', $disabled_func)) throw new Exception('the call of exec() is disabled'); - - // Check if safe_mode is disabled (needed for correct putenv, chmod, chown handling) - if(@ini_get('safe_mode')) throw new Exception('the safe_mode restriction is on'); - - return true; - } - catch(Exception $e) - { - $app->log('Aborting execution because '.$e->getMessage(), 1); - return false; - } - } - - /** - * Get a file from a ZIP archive and either return it's content or - * extract it to a given destination - * - * @param $zipfile the ZIP file to work with - * @param $subfile the file from which to get the content - * @param $destfolder the optional extraction destination - * @param $destname the optional target file name when extracting - * @return string or boolean - */ - private function getContentFromZIP($zipfile, $subfile, $destfolder = '', $destname = '') - { - try - { - $zip = new ZipArchive; - $res = $zip->open(realpath($zipfile)); - if(!$res) throw new Exception('Cannot open ZIP file '.$zipfile); - - // If no destination is given, the content is returned, otherwise - // the $subfile is extracted to $destination - if($destfolder == '') - { - $fh = $zip->getStream($subfile); - if(!$fh) throw new Exception('Cannot read '.$subfile.' from '.$zipfile); - - $subfile_content = ''; - while(!feof($fh)) $subfile_content .= fread($fh, 8192); - - fclose($fh); - - return $subfile_content; - } - else - { - // extractTo would be suitable but has no target name parameter - //$ind = $zip->locateName($subfile); - //$ex = $zip->extractTo($destination, array($zip->getNameIndex($ind))); - if($destname == '') $destname = basename($subfile); - $ex = @copy('zip://'.$zipfile.'#'.$subfile, $destfolder.$destname); - if(!$ex) throw new Exception('Cannot extract '.$subfile.' to '.$destfolder); - } - - $zip->close(); - - } - catch(Exception $e) - { - // The exception message is only interesting for debugging reasons - // echo $e->getMessage(); - return false; - } - } - - /** - * Extract the complete directory of a ZIP file - * - * @param $filename the file to unzip - * @param $directory the ZIP inside directory to unzip - * @param $destination the place where to extract the data - * @return boolean - */ - private function extractZip($filename, $directory, $destination) - { - if(!file_exists($filename)) return false; - - // Fix the paths - if(substr($directory, -1) == '/') $directory = substr($directory, 0, strlen($directory) - 1); - if(substr($destination, -1) != '/') $destination .= '/'; - - // Read and extract the ZIP file - $ziphandle = zip_open(realpath($filename)); - if(is_resource($ziphandle)) - { - while($entry = zip_read($ziphandle)) - { - if(substr(zip_entry_name($entry), 0, strlen($directory)) == $directory) - { - // Modify the relative ZIP file path - $new_path = substr(zip_entry_name($entry), strlen($directory)); - - if(substr($new_path, -1) == '/') // Identifier for directories - { - if(!file_exists($destination.$new_path)) mkdir($destination.$new_path, 0777, true); - } - else // Handle files - { - if(zip_entry_open($ziphandle, $entry)) - { - $new_dir = dirname($destination.$new_path); - if(!file_exists($new_dir)) mkdir($new_dir, 0777, true); - - $file = fopen($destination.$new_path, 'wb'); - if($file) - { - while($line = zip_entry_read($entry)) fwrite($file, $line); - fclose($file); - } - else return false; - } - } - } - } - - zip_close($ziphandle); - return true; - } - - return false; - } - - /** - * Setup the path environment variables for the install script - * - * @param $parent_mapping the SimpleXML instance with the current mapping position - * @param $url the relative path within the mapping tree - * @param $path the absolute path within the mapping tree - */ - private function processMappings($parent_mapping, $url, $path) - { - if($parent_mapping && $parent_mapping != null) - { - $writable = parent::getXPathValue($parent_mapping, 'php:permissions/@writable'); - $readable = parent::getXPathValue($parent_mapping, 'php:permissions/@readable'); - - // set the write permission - if($writable == 'true') - { - if(is_dir($path)) chmod($path, 0775); - else chmod($path, 0664); - } - - // set non-readable permission - if($readable == 'false') - { - if(is_dir($path)) chmod($path, 0333); - else chmod($path, 0222); - } - } - - // Set the environment variables - $env = str_replace('/', '_', $url); - $this->putenv[] = 'WEB_'.$env.'_DIR='.$path; - - // Step recursively into further mappings - if($parent_mapping && $parent_mapping != null) - { - foreach($parent_mapping->mapping as $mapping) - { - if($url == '/') $this->processMappings($mapping, $url.$mapping['url'], $path.$mapping['url']); - else $this->processMappings($mapping, $url.'/'.$mapping['url'], $path.'/'.$mapping['url']); - } - } - } - - /** - * Setup the environment with data for the install location - * - * @param $task an array containing all install related data - */ - private function prepareLocation($task) - { - global $app; - - // Get the domain name to use for the installation - // Would be possible in one query too, but we use 2 for easier debugging - $main_domain = $app->db->queryOneRecord("SELECT value FROM aps_instances_settings - WHERE name = 'main_domain' AND instance_id = '".$app->db->quote($task['instance_id'])."';"); - $this->domain = $main_domain['value']; - - // Get the document root - $domain_res = $app->db->queryOneRecord("SELECT document_root, web_folder, type FROM web_domain - WHERE domain = '".$app->db->quote($this->domain)."';"); - $this->document_root = $domain_res['document_root']; - - // Get the sub location - $location_res = $app->db->queryOneRecord("SELECT value FROM aps_instances_settings - WHERE name = 'main_location' AND instance_id = '".$app->db->quote($task['instance_id'])."';"); - $this->sublocation = $location_res['value']; - - // Make sure the document_root ends with / - if(substr($this->document_root, -1) != '/') $this->document_root .= '/'; - - // Attention: ISPConfig Special: web files are in subfolder 'web' -> append it: - if($domain_res['type'] == 'vhostsubdomain') $this->document_root .= $domain_res['web_folder'] . '/'; - else $this->document_root .= 'web/'; - - // If a subfolder is given, make sure it's path doesn't begin with / i.e. /phpbb - if(substr($this->sublocation, 0, 1) == '/') $this->sublocation = substr($this->sublocation, 1); - - // If the package isn't installed to a subfolder, remove the / at the end of the document root - if(empty($this->sublocation)) $this->document_root = substr($this->document_root, 0, strlen($this->document_root) - 1); - - // Set environment variables, later processed by the package install script - $this->putenv[] = 'BASE_URL_SCHEME=http'; - // putenv('BASE_URL_PORT') -> omitted as it's 80 by default - $this->putenv[] = 'BASE_URL_HOST='.$this->domain; - $this->putenv[] = 'BASE_URL_PATH='.$this->sublocation.'/'; - } - - /** - * Setup a database (if needed) and the appropriate environment variables - * - * @param $task an array containing all install related data - * @param $sxe a SimpleXMLElement handle, holding APP-META.xml - */ - private function prepareDatabase($task, $sxe) - { - global $app; - - $db_id = parent::getXPathValue($sxe, '//db:id'); - if(empty($db_id)) return; // No database needed - - /* WARNING: if this will ever be uncommented please check the updated prefix handling for user and db names!!! - * - // Set the database owner to the domain owner - // ISPConfig identifies the owner by the sys_groupid (not sys_userid!) - // so sys_userid can be set to any value - $perm = $app->db->queryOneRecord("SELECT sys_groupid, server_id FROM web_domain - WHERE domain = '".$this->domain."';"); - $task['sys_groupid'] = $perm['sys_groupid']; - $serverid = $perm['server_id']; - - // Get the database prefix and db user prefix - $app->uses('getconf'); - $global_config = $app->getconf->get_global_config('sites'); - $dbname_prefix = str_replace('[CLIENTID]', '', $global_config['dbname_prefix']); - $dbuser_prefix = str_replace('[CLIENTID]', '', $global_config['dbuser_prefix']); - $this->dbhost = DB_HOST; // Taken from config.inc.php - if(empty($this->dbhost)) $this->dbhost = 'localhost'; // Just to ensure any hostname... ;) - - $this->newdb_name = $dbname_prefix.$task['CustomerID'].'aps'.$task['InstanceID']; - $this->newdb_user = $dbuser_prefix.$task['CustomerID'].'aps'.$task['InstanceID']; - $dbpw_res = $app->db->queryOneRecord("SELECT Value FROM aps_instances_settings - WHERE Name = 'main_database_password' AND InstanceID = '".$app->db->quote($task['InstanceID'])."';"); - $newdb_pw = $dbpw_res['Value']; - - // In any case delete an existing database (install and removal procedure) - $app->db->query('DROP DATABASE IF EXISTS `'.$app->db->quote($this->newdb_name).'`;'); - // Delete an already existing database with this name - $app->db->query("DELETE FROM web_database WHERE database_name = '".$app->db->quote($this->newdb_name)."';"); - - - // Create the new database and assign it to a user - if($this->handle_type == 'install') - { - $app->db->query('CREATE DATABASE IF NOT EXISTS `'.$app->db->quote($this->newdb_name).'`;'); - $app->db->query('GRANT ALL PRIVILEGES ON '.$app->db->quote($this->newdb_name).'.* TO '.$app->db->quote($this->newdb_user).'@'.$app->db->quote($this->dbhost).' IDENTIFIED BY \'password\';'); - $app->db->query('SET PASSWORD FOR '.$app->db->quote($this->newdb_user).'@'.$app->db->quote($this->dbhost).' = PASSWORD(\''.$newdb_pw.'\');'); - $app->db->query('FLUSH PRIVILEGES;'); - - // Add the new database to the customer databases - // Assumes: charset = utf8 - $app->db->query('INSERT INTO web_database (sys_userid, sys_groupid, sys_perm_user, sys_perm_group, sys_perm_other, server_id, - type, database_name, database_user, database_password, database_charset, remote_access, remote_ips, active) - VALUES ('.$task['sys_userid'].', '.$task['sys_groupid'].', "'.$task['sys_perm_user'].'", "'.$task['sys_perm_group'].'", - "'.$task['sys_perm_other'].'", '.$app->db->quote($serverid).', "mysql", "'.$app->db->quote($this->newdb_name).'", - "'.$app->db->quote($this->newdb_user).'", "'.$app->db->quote($newdb_pw).'", "utf8", "n", "", "y");'); - } - */ - - $mysqlver_res = $app->db->queryOneRecord('SELECT VERSION() as ver;'); - $mysqlver = $mysqlver_res['ver']; - - $tmp = $app->db->queryOneRecord("SELECT value FROM aps_instances_settings WHERE name = 'main_database_password' AND instance_id = '".$app->db->quote($task['instance_id'])."';"); - $newdb_pw = $tmp['value']; - - $tmp = $app->db->queryOneRecord("SELECT value FROM aps_instances_settings WHERE name = 'main_database_host' AND instance_id = '".$app->db->quote($task['instance_id'])."';"); - $newdb_host = $tmp['value']; - - $tmp = $app->db->queryOneRecord("SELECT value FROM aps_instances_settings WHERE name = 'main_database_name' AND instance_id = '".$app->db->quote($task['instance_id'])."';"); - $newdb_name = $tmp['value']; - - $tmp = $app->db->queryOneRecord("SELECT value FROM aps_instances_settings WHERE name = 'main_database_login' AND instance_id = '".$app->db->quote($task['instance_id'])."';"); - $newdb_login = $tmp['value']; - - $this->putenv[] = 'DB_'.$db_id.'_TYPE=mysql'; - $this->putenv[] = 'DB_'.$db_id.'_NAME='.$newdb_name; - $this->putenv[] = 'DB_'.$db_id.'_LOGIN='.$newdb_login; - $this->putenv[] = 'DB_'.$db_id.'_PASSWORD='.$newdb_pw; - $this->putenv[] = 'DB_'.$db_id.'_HOST='.$newdb_host; - $this->putenv[] = 'DB_'.$db_id.'_PORT=3306'; - $this->putenv[] = 'DB_'.$db_id.'_VERSION='.$mysqlver; - } - - /** - * Extract all needed files from the package - * - * @param $task an array containing all install related data - * @param $sxe a SimpleXMLElement handle, holding APP-META.xml - * @return boolean - */ - private function prepareFiles($task, $sxe) - { - global $app; - - // Basically set the mapping for APS version 1.0, if not available -> newer way - $mapping = $sxe->mapping; - $mapping_path = $sxe->mapping['path']; - $mapping_url = $sxe->mapping['url']; - if(empty($mapping)) - { - $mapping = $sxe->service->provision->{'url-mapping'}->mapping; - $mapping_path = $sxe->service->provision->{'url-mapping'}->mapping['path']; - $mapping_url = $sxe->service->provision->{'url-mapping'}->mapping['url']; - } - - try - { - // Make sure we have a valid mapping path (at least /) - if(empty($mapping_path)) throw new Exception('Unable to determine a mapping path'); - - $this->local_installpath = $this->document_root.$this->sublocation.'/'; - - // Now delete an existing folder (affects install and removal in the same way) - @chdir($this->local_installpath); - if(file_exists($this->local_installpath)){ - // make sure we don't delete error and stats folders - if($this->local_installpath == $this->document_root.'/'){ - if(is_dir($this->document_root)){ - $files = array_diff(scandir($this->document_root), array('.','..','error','stats')); - foreach($files as $file){ - if(is_dir($this->document_root.'/'.$file)){ - $app->file->removeDirectory($this->document_root.'/'.$file); - } else { - @unlink($this->document_root.'/'.$file); - } - } - } else { - @unlink($this->document_root); - mkdir($this->document_root, 0777, true); - } - } else { - exec("rm -Rf ".escapeshellarg($this->local_installpath).'*'); - } - } else { - mkdir($this->local_installpath, 0777, true); - } - - if($this->handle_type == 'install') - { - // Now check if the needed folder is there - if(!file_exists($this->local_installpath)) - throw new Exception('Unable to create a new folder for the package '.$task['path']); - - // Extract all files and assign them a new owner - if( ($this->extractZip($this->packages_dir.'/'.$task['path'], $mapping_path, $this->local_installpath) === false) - || ($this->extractZip($this->packages_dir.'/'.$task['path'], 'scripts', $this->local_installpath.'install_scripts/') === false) ) - { - // Clean already extracted data - exec("rm -Rf ".escapeshellarg($this->local_installpath).'*'); - throw new Exception('Unable to extract the package '.$task['path']); - } - - $this->processMappings($mapping, $mapping_url, $this->local_installpath); - - // Set the appropriate file owner - $main_domain = $app->db->queryOneRecord("SELECT value FROM aps_instances_settings - WHERE name = 'main_domain' AND instance_id = '".$app->db->quote($task['instance_id'])."';"); - $owner_res = $app->db->queryOneRecord("SELECT system_user, system_group FROM web_domain - WHERE domain = '".$app->db->quote($main_domain['value'])."';"); - $this->file_owner_user = $owner_res['system_user']; - $this->file_owner_group = $owner_res['system_group']; - exec('chown -R '.$this->file_owner_user.':'.$this->file_owner_group.' '.escapeshellarg($this->local_installpath)); - - //* Chown stats directory back - if(is_dir($this->local_installpath.'stats')) { - exec('chown -R root:root '.escapeshellarg($this->local_installpath.'stats')); - } - } - } - catch(Exception $e) - { - $app->dbmaster->query('UPDATE aps_instances SET instance_status = "'.INSTANCE_ERROR.'" - WHERE id = "'.$app->db->quote($task['instance_id']).'";'); - $app->log($e->getMessage(), 1); - return false; - } - - return true; - } - - /** - * Get all user config variables and set them to environment variables - * - * @param $task an array containing all install related data - */ - private function prepareUserInputData($task) - { - global $app; - - $userdata = $app->db->queryAllRecords("SELECT name, value FROM aps_instances_settings - WHERE instance_id = '".$app->db->quote($task['instance_id'])."';"); - if(empty($userdata)) return false; - - foreach($userdata as $data) - { - // Skip unnecessary data - if($data['name'] == 'main_location' - || $data['name'] == 'main_domain' - || $data['name'] == 'main_database_password' - || $data['name'] == 'main_database_name' - || $data['name'] == 'main_database_host' - || $data['name'] == 'main_database_login' - || $data['name'] == 'license') continue; - - $this->putenv[] = 'SETTINGS_'.$data['name'].'='.$data['value']; - } - } - - /** - * Fetch binary data from a given array - * The data is retrieved in binary mode and - * then directly written to an output file - * - * @param $input a specially structed array - * @see $this->startUpdate() - */ - private function fetchFiles($input) - { - $fh = array(); - $url = array(); - $conn = array(); - - // Build the single cURL handles and add them to a multi handle - $mh = curl_multi_init(); - - // Process each app - for($i = 0; $i < count($input); $i++) - { - $conn[$i] = curl_init($input[$i]['url']); - $fh[$i] = fopen($input[$i]['localtarget'], 'wb'); - - curl_setopt($conn[$i], CURLOPT_BINARYTRANSFER, true); - curl_setopt($conn[$i], CURLOPT_FILE, $fh[$i]); - curl_setopt($conn[$i], CURLOPT_TIMEOUT, 0); - curl_setopt($conn[$i], CURLOPT_FAILONERROR, 1); - curl_setopt($conn[$i], CURLOPT_FOLLOWLOCATION, 1); - - curl_multi_add_handle($mh, $conn[$i]); - } - - $active = 0; - do curl_multi_exec($mh, $active); - while($active > 0); - - // Close the handles - for($i = 0; $i < count($input); $i++) - { - fclose($fh[$i]); - curl_multi_remove_handle($mh, $conn[$i]); - curl_close($conn[$i]); - } - curl_multi_close($mh); - } - - /** - * The installation script should be executed - * - * @param $task an array containing all install related data - * @param $sxe a SimpleXMLElement handle, holding APP-META.xml - * @return boolean - */ - private function doInstallation($task, $sxe) - { - global $app; - - try - { - // Check if the install directory exists - if(!is_dir($this->local_installpath.'install_scripts/')) - throw new Exception('The install directory '.$this->local_installpath.' is not existing'); - - // Set the executable bit to the configure script - $cfgscript = @(string)$sxe->service->provision->{'configuration-script'}['name']; - if(!$cfgscript) $cfgscript = 'configure'; - chmod($this->local_installpath.'install_scripts/'.$cfgscript, 0755); - - // Change to the install folder (import for the exec() below!) - //exec('chown -R '.$this->file_owner_user.':'.$this->file_owner_group.' '.escapeshellarg($this->local_installpath)); - chdir($this->local_installpath.'install_scripts/'); - - // Set the enviroment variables - foreach($this->putenv as $var) { - putenv($var); - } - - $shell_retcode = true; - $shell_ret = array(); - exec('php '.escapeshellarg($this->local_installpath.'install_scripts/'.$cfgscript).' install 2>&1', $shell_ret, $shell_retcode); - $shell_ret = array_filter($shell_ret); - $shell_ret_str = implode("\n", $shell_ret); - - // Although $shell_retcode might be 0, there can be PHP errors. Filter them: - if(substr_count($shell_ret_str, 'Warning: ') > 0) $shell_retcode = 1; - - // If an error has occurred, the return code is != 0 - if($shell_retcode != 0) throw new Exception($shell_ret_str); - else - { - // The install succeeded, chown newly created files too - exec('chown -R '.$this->file_owner_user.':'.$this->file_owner_group.' '.escapeshellarg($this->local_installpath)); - - //* Chown stats directory back - if(is_dir($this->local_installpath.'stats')) { - exec('chown -R root:root '.escapeshellarg($this->local_installpath.'stats')); - } - - $app->dbmaster->query('UPDATE aps_instances SET instance_status = "'.INSTANCE_SUCCESS.'" - WHERE id = "'.$app->db->quote($task['instance_id']).'";'); - } - } - catch(Exception $e) - { - $app->dbmaster->query('UPDATE aps_instances SET instance_status = "'.INSTANCE_ERROR.'" - WHERE id = "'.$app->db->quote($task['instance_id']).'";'); - $app->log($e->getMessage(), 1); - return false; - } - - return true; - } - - /** - * Cleanup: Remove install scripts, remove tasks and update the database - * - * @param $task an array containing all install related data - * @param $sxe a SimpleXMLElement handle, holding APP-META.xml - */ - private function cleanup($task, $sxe) - { - chdir($this->local_installpath); - exec("rm -Rf ".escapeshellarg($this->local_installpath).'install_scripts'); - } - - /** - * The main method which performs the actual package installation - * - * @param $instanceid the instanceID to install - * @param $type the type of task to perform (installation, removal) - */ - public function installHandler($instanceid, $type) - { - global $app; - - // Set the given handle type, currently supported: install, delete - if($type == 'install' || $type == 'delete') $this->handle_type = $type; - else return false; - - // Get all instance metadata - /* - $task = $app->db->queryOneRecord("SELECT * FROM aps_instances AS i - INNER JOIN aps_packages AS p ON i.package_id = p.id - INNER JOIN client AS c ON i.customer_id = c.client_id - WHERE i.id = ".$instanceid.";"); - */ - $task = $app->db->queryOneRecord("SELECT * FROM aps_instances AS i - INNER JOIN aps_packages AS p ON i.package_id = p.id - WHERE i.id = ".$instanceid.";"); - if(!$task) return false; // formerly: throw new Exception('The InstanceID doesn\'t exist.'); - if(!isset($task['instance_id'])) $task['instance_id'] = $instanceid; - - // Download aps package - if(!file_exists($this->packages_dir.'/'.$task['path']) || filesize($this->packages_dir.'/'.$task['path']) == 0) { - $ch = curl_init(); - $fh = fopen($this->packages_dir.'/'.$task['path'], 'wb'); - curl_setopt($ch, CURLOPT_FILE, $fh); - //curl_setopt($ch, CURLOPT_HEADER, 0); - curl_setopt($ch, CURLOPT_URL, $task['package_url']); - curl_setopt($ch, CURLOPT_BINARYTRANSFER, true); - curl_setopt($ch, CURLOPT_TIMEOUT, 0); - curl_setopt($ch, CURLOPT_FAILONERROR, 1); - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); - if(curl_exec($ch) === false) $app->log(curl_error ($ch),1); - fclose($fh); - curl_close($ch); - } - - /* - $app_to_dl[] = array('name' => $task['path'], - 'url' => $task['package_url'], - 'filesize' => 0, - 'localtarget' => $this->packages_dir.'/'.$task['path']); - - $this->fetchFiles($app_to_dl); - */ - - // Make sure the requirements are given so that this script can execute - $req_ret = $this->checkRequirements(); - if(!$req_ret) return false; - - $metafile = $this->getContentFromZIP($this->packages_dir.'/'.$task['path'], 'APP-META.xml'); - // Check if the meta file is existing - if(!$metafile) - { - $app->dbmaster->query('UPDATE aps_instances SET instance_status = "'.INSTANCE_ERROR.'" - WHERE id = "'.$app->db->quote($task['instance_id']).'";'); - $app->log('Unable to find the meta data file of package '.$task['path'], 1); - return false; - } - - // Rename namespaces and register them - $metadata = str_replace("xmlns=", "ns=", $metafile); - $sxe = new SimpleXMLElement($metadata); - $namespaces = $sxe->getDocNamespaces(true); - foreach($namespaces as $ns => $url) $sxe->registerXPathNamespace($ns, $url); - - // Setup the environment with data for the install location - $this->prepareLocation($task); - - // Create the database if necessary - $this->prepareDatabase($task, $sxe); - - // Unpack the install scripts from the packages - if($this->prepareFiles($task, $sxe) && $this->handle_type == 'install') - { - // Setup the variables from the install script - $this->prepareUserInputData($task); - - // Do the actual installation - $this->doInstallation($task, $sxe); - - // Remove temporary files - $this->cleanup($task, $sxe); - } - - // Finally delete the instance entry + settings - if($this->handle_type == 'delete') - { - $app->db->query('DELETE FROM aps_instances WHERE id = "'.$app->db->quote($task['instance_id']).'";'); - $app->db->query('DELETE FROM aps_instances_settings WHERE instance_id = "'.$app->db->quote($task['instance_id']).'";'); - } - - unset($sxe); - } -} +<?php +/* +Copyright (c) 2012, ISPConfig UG +Contributors: web wack creations, http://www.web-wack.at +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of ISPConfig nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +require_once('aps_base.inc.php'); + +@set_time_limit(0); +@ignore_user_abort(1); + +class ApsInstaller extends ApsBase +{ + private $handle_type = ''; + private $domain = ''; + private $document_root = ''; + private $sublocation = ''; + private $local_installpath = ''; + private $dbhost = ''; + private $newdb_name = ''; + private $newdb_user = ''; + private $file_owner_user = ''; + private $file_owner_group = ''; + private $putenv = array(); + + /** + * Constructor + * + * @param $app the application instance (db handle + log method) + * @param $interface_mode act in interface (true) or server mode (false) + */ + public function __construct($app, $interface_mode = false) + { + parent::__construct($app, 'APS installer: ', $interface_mode); + } + + /** + * Before the cron is executed, make sure all necessary options are set + * and all functions are available + */ + private function checkRequirements() + { + global $app; + try + { + // Check if exec() is not disabled + $disabled_func = explode(',', @ini_get('disable_functions')); + if(in_array('exec', $disabled_func)) throw new Exception('the call of exec() is disabled'); + + // Check if safe_mode is disabled (needed for correct putenv, chmod, chown handling) + if(@ini_get('safe_mode')) throw new Exception('the safe_mode restriction is on'); + + return true; + } + catch(Exception $e) + { + $app->log('Aborting execution because '.$e->getMessage(), 1); + return false; + } + } + + /** + * Get a file from a ZIP archive and either return it's content or + * extract it to a given destination + * + * @param $zipfile the ZIP file to work with + * @param $subfile the file from which to get the content + * @param $destfolder the optional extraction destination + * @param $destname the optional target file name when extracting + * @return string or boolean + */ + private function getContentFromZIP($zipfile, $subfile, $destfolder = '', $destname = '') + { + try + { + $zip = new ZipArchive; + $res = $zip->open(realpath($zipfile)); + if(!$res) throw new Exception('Cannot open ZIP file '.$zipfile); + + // If no destination is given, the content is returned, otherwise + // the $subfile is extracted to $destination + if($destfolder == '') + { + $fh = $zip->getStream($subfile); + if(!$fh) throw new Exception('Cannot read '.$subfile.' from '.$zipfile); + + $subfile_content = ''; + while(!feof($fh)) $subfile_content .= fread($fh, 8192); + + fclose($fh); + + return $subfile_content; + } + else + { + // extractTo would be suitable but has no target name parameter + //$ind = $zip->locateName($subfile); + //$ex = $zip->extractTo($destination, array($zip->getNameIndex($ind))); + if($destname == '') $destname = basename($subfile); + $ex = @copy('zip://'.$zipfile.'#'.$subfile, $destfolder.$destname); + if(!$ex) throw new Exception('Cannot extract '.$subfile.' to '.$destfolder); + } + + $zip->close(); + + } + catch(Exception $e) + { + // The exception message is only interesting for debugging reasons + // echo $e->getMessage(); + return false; + } + } + + /** + * Extract the complete directory of a ZIP file + * + * @param $filename the file to unzip + * @param $directory the ZIP inside directory to unzip + * @param $destination the place where to extract the data + * @return boolean + */ + private function extractZip($filename, $directory, $destination) + { + if(!file_exists($filename)) return false; + + // Fix the paths + if(substr($directory, -1) == '/') $directory = substr($directory, 0, strlen($directory) - 1); + if(substr($destination, -1) != '/') $destination .= '/'; + + // Read and extract the ZIP file + $ziphandle = zip_open(realpath($filename)); + if(is_resource($ziphandle)) + { + while($entry = zip_read($ziphandle)) + { + if(substr(zip_entry_name($entry), 0, strlen($directory)) == $directory) + { + // Modify the relative ZIP file path + $new_path = substr(zip_entry_name($entry), strlen($directory)); + + if(substr($new_path, -1) == '/') // Identifier for directories + { + if(!file_exists($destination.$new_path)) mkdir($destination.$new_path, 0777, true); + } + else // Handle files + { + if(zip_entry_open($ziphandle, $entry)) + { + $new_dir = dirname($destination.$new_path); + if(!file_exists($new_dir)) mkdir($new_dir, 0777, true); + + $file = fopen($destination.$new_path, 'wb'); + if($file) + { + while($line = zip_entry_read($entry)) fwrite($file, $line); + fclose($file); + } + else return false; + } + } + } + } + + zip_close($ziphandle); + return true; + } + + return false; + } + + /** + * Setup the path environment variables for the install script + * + * @param $parent_mapping the SimpleXML instance with the current mapping position + * @param $url the relative path within the mapping tree + * @param $path the absolute path within the mapping tree + */ + private function processMappings($parent_mapping, $url, $path) + { + if($parent_mapping && $parent_mapping != null) + { + $writable = parent::getXPathValue($parent_mapping, 'php:permissions/@writable'); + $readable = parent::getXPathValue($parent_mapping, 'php:permissions/@readable'); + + // set the write permission + if($writable == 'true') + { + if(is_dir($path)) chmod($path, 0775); + else chmod($path, 0664); + } + + // set non-readable permission + if($readable == 'false') + { + if(is_dir($path)) chmod($path, 0333); + else chmod($path, 0222); + } + } + + // Set the environment variables + $env = str_replace('/', '_', $url); + $this->putenv[] = 'WEB_'.$env.'_DIR='.$path; + + // Step recursively into further mappings + if($parent_mapping && $parent_mapping != null) + { + foreach($parent_mapping->mapping as $mapping) + { + if($url == '/') $this->processMappings($mapping, $url.$mapping['url'], $path.$mapping['url']); + else $this->processMappings($mapping, $url.'/'.$mapping['url'], $path.'/'.$mapping['url']); + } + } + } + + /** + * Setup the environment with data for the install location + * + * @param $task an array containing all install related data + */ + private function prepareLocation($task) + { + global $app; + + // Get the domain name to use for the installation + // Would be possible in one query too, but we use 2 for easier debugging + $main_domain = $app->db->queryOneRecord("SELECT value FROM aps_instances_settings + WHERE name = 'main_domain' AND instance_id = '".$app->db->quote($task['instance_id'])."';"); + $this->domain = $main_domain['value']; + + // Get the document root + $domain_res = $app->db->queryOneRecord("SELECT document_root, web_folder, type FROM web_domain + WHERE domain = '".$app->db->quote($this->domain)."';"); + $this->document_root = $domain_res['document_root']; + + // Get the sub location + $location_res = $app->db->queryOneRecord("SELECT value FROM aps_instances_settings + WHERE name = 'main_location' AND instance_id = '".$app->db->quote($task['instance_id'])."';"); + $this->sublocation = $location_res['value']; + + // Make sure the document_root ends with / + if(substr($this->document_root, -1) != '/') $this->document_root .= '/'; + + // Attention: ISPConfig Special: web files are in subfolder 'web' -> append it: + if($domain_res['type'] == 'vhostsubdomain') $this->document_root .= $domain_res['web_folder'] . '/'; + else $this->document_root .= 'web/'; + + // If a subfolder is given, make sure it's path doesn't begin with / i.e. /phpbb + if(substr($this->sublocation, 0, 1) == '/') $this->sublocation = substr($this->sublocation, 1); + + // If the package isn't installed to a subfolder, remove the / at the end of the document root + if(empty($this->sublocation)) $this->document_root = substr($this->document_root, 0, strlen($this->document_root) - 1); + + // Set environment variables, later processed by the package install script + $this->putenv[] = 'BASE_URL_SCHEME=http'; + // putenv('BASE_URL_PORT') -> omitted as it's 80 by default + $this->putenv[] = 'BASE_URL_HOST='.$this->domain; + $this->putenv[] = 'BASE_URL_PATH='.$this->sublocation.'/'; + } + + /** + * Setup a database (if needed) and the appropriate environment variables + * + * @param $task an array containing all install related data + * @param $sxe a SimpleXMLElement handle, holding APP-META.xml + */ + private function prepareDatabase($task, $sxe) + { + global $app; + + $db_id = parent::getXPathValue($sxe, '//db:id'); + if(empty($db_id)) return; // No database needed + + /* WARNING: if this will ever be uncommented please check the updated prefix handling for user and db names!!! + * + // Set the database owner to the domain owner + // ISPConfig identifies the owner by the sys_groupid (not sys_userid!) + // so sys_userid can be set to any value + $perm = $app->db->queryOneRecord("SELECT sys_groupid, server_id FROM web_domain + WHERE domain = '".$this->domain."';"); + $task['sys_groupid'] = $perm['sys_groupid']; + $serverid = $perm['server_id']; + + // Get the database prefix and db user prefix + $app->uses('getconf'); + $global_config = $app->getconf->get_global_config('sites'); + $dbname_prefix = str_replace('[CLIENTID]', '', $global_config['dbname_prefix']); + $dbuser_prefix = str_replace('[CLIENTID]', '', $global_config['dbuser_prefix']); + $this->dbhost = DB_HOST; // Taken from config.inc.php + if(empty($this->dbhost)) $this->dbhost = 'localhost'; // Just to ensure any hostname... ;) + + $this->newdb_name = $dbname_prefix.$task['CustomerID'].'aps'.$task['InstanceID']; + $this->newdb_user = $dbuser_prefix.$task['CustomerID'].'aps'.$task['InstanceID']; + $dbpw_res = $app->db->queryOneRecord("SELECT Value FROM aps_instances_settings + WHERE Name = 'main_database_password' AND InstanceID = '".$app->db->quote($task['InstanceID'])."';"); + $newdb_pw = $dbpw_res['Value']; + + // In any case delete an existing database (install and removal procedure) + $app->db->query('DROP DATABASE IF EXISTS `'.$app->db->quote($this->newdb_name).'`;'); + // Delete an already existing database with this name + $app->db->query("DELETE FROM web_database WHERE database_name = '".$app->db->quote($this->newdb_name)."';"); + + + // Create the new database and assign it to a user + if($this->handle_type == 'install') + { + $app->db->query('CREATE DATABASE IF NOT EXISTS `'.$app->db->quote($this->newdb_name).'`;'); + $app->db->query('GRANT ALL PRIVILEGES ON '.$app->db->quote($this->newdb_name).'.* TO '.$app->db->quote($this->newdb_user).'@'.$app->db->quote($this->dbhost).' IDENTIFIED BY \'password\';'); + $app->db->query('SET PASSWORD FOR '.$app->db->quote($this->newdb_user).'@'.$app->db->quote($this->dbhost).' = PASSWORD(\''.$newdb_pw.'\');'); + $app->db->query('FLUSH PRIVILEGES;'); + + // Add the new database to the customer databases + // Assumes: charset = utf8 + $app->db->query('INSERT INTO web_database (sys_userid, sys_groupid, sys_perm_user, sys_perm_group, sys_perm_other, server_id, + type, database_name, database_user, database_password, database_charset, remote_access, remote_ips, active) + VALUES ('.$task['sys_userid'].', '.$task['sys_groupid'].', "'.$task['sys_perm_user'].'", "'.$task['sys_perm_group'].'", + "'.$task['sys_perm_other'].'", '.$app->db->quote($serverid).', "mysql", "'.$app->db->quote($this->newdb_name).'", + "'.$app->db->quote($this->newdb_user).'", "'.$app->db->quote($newdb_pw).'", "utf8", "n", "", "y");'); + } + */ + + $mysqlver_res = $app->db->queryOneRecord('SELECT VERSION() as ver;'); + $mysqlver = $mysqlver_res['ver']; + + $tmp = $app->db->queryOneRecord("SELECT value FROM aps_instances_settings WHERE name = 'main_database_password' AND instance_id = '".$app->db->quote($task['instance_id'])."';"); + $newdb_pw = $tmp['value']; + + $tmp = $app->db->queryOneRecord("SELECT value FROM aps_instances_settings WHERE name = 'main_database_host' AND instance_id = '".$app->db->quote($task['instance_id'])."';"); + $newdb_host = $tmp['value']; + + $tmp = $app->db->queryOneRecord("SELECT value FROM aps_instances_settings WHERE name = 'main_database_name' AND instance_id = '".$app->db->quote($task['instance_id'])."';"); + $newdb_name = $tmp['value']; + + $tmp = $app->db->queryOneRecord("SELECT value FROM aps_instances_settings WHERE name = 'main_database_login' AND instance_id = '".$app->db->quote($task['instance_id'])."';"); + $newdb_login = $tmp['value']; + + $this->putenv[] = 'DB_'.$db_id.'_TYPE=mysql'; + $this->putenv[] = 'DB_'.$db_id.'_NAME='.$newdb_name; + $this->putenv[] = 'DB_'.$db_id.'_LOGIN='.$newdb_login; + $this->putenv[] = 'DB_'.$db_id.'_PASSWORD='.$newdb_pw; + $this->putenv[] = 'DB_'.$db_id.'_HOST='.$newdb_host; + $this->putenv[] = 'DB_'.$db_id.'_PORT=3306'; + $this->putenv[] = 'DB_'.$db_id.'_VERSION='.$mysqlver; + } + + /** + * Extract all needed files from the package + * + * @param $task an array containing all install related data + * @param $sxe a SimpleXMLElement handle, holding APP-META.xml + * @return boolean + */ + private function prepareFiles($task, $sxe) + { + global $app; + + // Basically set the mapping for APS version 1.0, if not available -> newer way + $mapping = $sxe->mapping; + $mapping_path = $sxe->mapping['path']; + $mapping_url = $sxe->mapping['url']; + if(empty($mapping)) + { + $mapping = $sxe->service->provision->{'url-mapping'}->mapping; + $mapping_path = $sxe->service->provision->{'url-mapping'}->mapping['path']; + $mapping_url = $sxe->service->provision->{'url-mapping'}->mapping['url']; + } + + try + { + // Make sure we have a valid mapping path (at least /) + if(empty($mapping_path)) throw new Exception('Unable to determine a mapping path'); + + $this->local_installpath = $this->document_root.$this->sublocation.'/'; + + // Now delete an existing folder (affects install and removal in the same way) + @chdir($this->local_installpath); + if(file_exists($this->local_installpath)){ + // make sure we don't delete error and stats folders + if($this->local_installpath == $this->document_root.'/'){ + if(is_dir($this->document_root)){ + $files = array_diff(scandir($this->document_root), array('.','..','error','stats')); + foreach($files as $file){ + if(is_dir($this->document_root.'/'.$file)){ + $app->file->removeDirectory($this->document_root.'/'.$file); + } else { + @unlink($this->document_root.'/'.$file); + } + } + } else { + @unlink($this->document_root); + mkdir($this->document_root, 0777, true); + } + } else { + exec("rm -Rf ".escapeshellarg($this->local_installpath).'*'); + } + } else { + mkdir($this->local_installpath, 0777, true); + } + + if($this->handle_type == 'install') + { + // Now check if the needed folder is there + if(!file_exists($this->local_installpath)) + throw new Exception('Unable to create a new folder for the package '.$task['path']); + + // Extract all files and assign them a new owner + if( ($this->extractZip($this->packages_dir.'/'.$task['path'], $mapping_path, $this->local_installpath) === false) + || ($this->extractZip($this->packages_dir.'/'.$task['path'], 'scripts', $this->local_installpath.'install_scripts/') === false) ) + { + // Clean already extracted data + exec("rm -Rf ".escapeshellarg($this->local_installpath).'*'); + throw new Exception('Unable to extract the package '.$task['path']); + } + + $this->processMappings($mapping, $mapping_url, $this->local_installpath); + + // Set the appropriate file owner + $main_domain = $app->db->queryOneRecord("SELECT value FROM aps_instances_settings + WHERE name = 'main_domain' AND instance_id = '".$app->db->quote($task['instance_id'])."';"); + $owner_res = $app->db->queryOneRecord("SELECT system_user, system_group FROM web_domain + WHERE domain = '".$app->db->quote($main_domain['value'])."';"); + $this->file_owner_user = $owner_res['system_user']; + $this->file_owner_group = $owner_res['system_group']; + exec('chown -R '.$this->file_owner_user.':'.$this->file_owner_group.' '.escapeshellarg($this->local_installpath)); + + //* Chown stats directory back + if(is_dir($this->local_installpath.'stats')) { + exec('chown -R root:root '.escapeshellarg($this->local_installpath.'stats')); + } + } + } + catch(Exception $e) + { + $app->dbmaster->query('UPDATE aps_instances SET instance_status = "'.INSTANCE_ERROR.'" + WHERE id = "'.$app->db->quote($task['instance_id']).'";'); + $app->log($e->getMessage(), 1); + return false; + } + + return true; + } + + /** + * Get all user config variables and set them to environment variables + * + * @param $task an array containing all install related data + */ + private function prepareUserInputData($task) + { + global $app; + + $userdata = $app->db->queryAllRecords("SELECT name, value FROM aps_instances_settings + WHERE instance_id = '".$app->db->quote($task['instance_id'])."';"); + if(empty($userdata)) return false; + + foreach($userdata as $data) + { + // Skip unnecessary data + if($data['name'] == 'main_location' + || $data['name'] == 'main_domain' + || $data['name'] == 'main_database_password' + || $data['name'] == 'main_database_name' + || $data['name'] == 'main_database_host' + || $data['name'] == 'main_database_login' + || $data['name'] == 'license') continue; + + $this->putenv[] = 'SETTINGS_'.$data['name'].'='.$data['value']; + } + } + + /** + * Fetch binary data from a given array + * The data is retrieved in binary mode and + * then directly written to an output file + * + * @param $input a specially structed array + * @see $this->startUpdate() + */ + private function fetchFiles($input) + { + $fh = array(); + $url = array(); + $conn = array(); + + // Build the single cURL handles and add them to a multi handle + $mh = curl_multi_init(); + + // Process each app + for($i = 0; $i < count($input); $i++) + { + $conn[$i] = curl_init($input[$i]['url']); + $fh[$i] = fopen($input[$i]['localtarget'], 'wb'); + + curl_setopt($conn[$i], CURLOPT_BINARYTRANSFER, true); + curl_setopt($conn[$i], CURLOPT_FILE, $fh[$i]); + curl_setopt($conn[$i], CURLOPT_TIMEOUT, 0); + curl_setopt($conn[$i], CURLOPT_FAILONERROR, 1); + curl_setopt($conn[$i], CURLOPT_FOLLOWLOCATION, 1); + + curl_multi_add_handle($mh, $conn[$i]); + } + + $active = 0; + do curl_multi_exec($mh, $active); + while($active > 0); + + // Close the handles + for($i = 0; $i < count($input); $i++) + { + fclose($fh[$i]); + curl_multi_remove_handle($mh, $conn[$i]); + curl_close($conn[$i]); + } + curl_multi_close($mh); + } + + /** + * The installation script should be executed + * + * @param $task an array containing all install related data + * @param $sxe a SimpleXMLElement handle, holding APP-META.xml + * @return boolean + */ + private function doInstallation($task, $sxe) + { + global $app; + + try + { + // Check if the install directory exists + if(!is_dir($this->local_installpath.'install_scripts/')) + throw new Exception('The install directory '.$this->local_installpath.' is not existing'); + + // Set the executable bit to the configure script + $cfgscript = @(string)$sxe->service->provision->{'configuration-script'}['name']; + if(!$cfgscript) $cfgscript = 'configure'; + chmod($this->local_installpath.'install_scripts/'.$cfgscript, 0755); + + // Change to the install folder (import for the exec() below!) + //exec('chown -R '.$this->file_owner_user.':'.$this->file_owner_group.' '.escapeshellarg($this->local_installpath)); + chdir($this->local_installpath.'install_scripts/'); + + // Set the enviroment variables + foreach($this->putenv as $var) { + putenv($var); + } + + $shell_retcode = true; + $shell_ret = array(); + exec('php '.escapeshellarg($this->local_installpath.'install_scripts/'.$cfgscript).' install 2>&1', $shell_ret, $shell_retcode); + $shell_ret = array_filter($shell_ret); + $shell_ret_str = implode("\n", $shell_ret); + + // Although $shell_retcode might be 0, there can be PHP errors. Filter them: + if(substr_count($shell_ret_str, 'Warning: ') > 0) $shell_retcode = 1; + + // If an error has occurred, the return code is != 0 + if($shell_retcode != 0) throw new Exception($shell_ret_str); + else + { + // The install succeeded, chown newly created files too + exec('chown -R '.$this->file_owner_user.':'.$this->file_owner_group.' '.escapeshellarg($this->local_installpath)); + + //* Chown stats directory back + if(is_dir($this->local_installpath.'stats')) { + exec('chown -R root:root '.escapeshellarg($this->local_installpath.'stats')); + } + + $app->dbmaster->query('UPDATE aps_instances SET instance_status = "'.INSTANCE_SUCCESS.'" + WHERE id = "'.$app->db->quote($task['instance_id']).'";'); + } + } + catch(Exception $e) + { + $app->dbmaster->query('UPDATE aps_instances SET instance_status = "'.INSTANCE_ERROR.'" + WHERE id = "'.$app->db->quote($task['instance_id']).'";'); + $app->log($e->getMessage(), 1); + return false; + } + + return true; + } + + /** + * Cleanup: Remove install scripts, remove tasks and update the database + * + * @param $task an array containing all install related data + * @param $sxe a SimpleXMLElement handle, holding APP-META.xml + */ + private function cleanup($task, $sxe) + { + chdir($this->local_installpath); + exec("rm -Rf ".escapeshellarg($this->local_installpath).'install_scripts'); + } + + /** + * The main method which performs the actual package installation + * + * @param $instanceid the instanceID to install + * @param $type the type of task to perform (installation, removal) + */ + public function installHandler($instanceid, $type) + { + global $app; + + // Set the given handle type, currently supported: install, delete + if($type == 'install' || $type == 'delete') $this->handle_type = $type; + else return false; + + // Get all instance metadata + /* + $task = $app->db->queryOneRecord("SELECT * FROM aps_instances AS i + INNER JOIN aps_packages AS p ON i.package_id = p.id + INNER JOIN client AS c ON i.customer_id = c.client_id + WHERE i.id = ".$instanceid.";"); + */ + $task = $app->db->queryOneRecord("SELECT * FROM aps_instances AS i + INNER JOIN aps_packages AS p ON i.package_id = p.id + WHERE i.id = ".$instanceid.";"); + if(!$task) return false; // formerly: throw new Exception('The InstanceID doesn\'t exist.'); + if(!isset($task['instance_id'])) $task['instance_id'] = $instanceid; + + // Download aps package + if(!file_exists($this->packages_dir.'/'.$task['path']) || filesize($this->packages_dir.'/'.$task['path']) == 0) { + $ch = curl_init(); + $fh = fopen($this->packages_dir.'/'.$task['path'], 'wb'); + curl_setopt($ch, CURLOPT_FILE, $fh); + //curl_setopt($ch, CURLOPT_HEADER, 0); + curl_setopt($ch, CURLOPT_URL, $task['package_url']); + curl_setopt($ch, CURLOPT_BINARYTRANSFER, true); + curl_setopt($ch, CURLOPT_TIMEOUT, 0); + curl_setopt($ch, CURLOPT_FAILONERROR, 1); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); + if(curl_exec($ch) === false) $app->log(curl_error ($ch),1); + fclose($fh); + curl_close($ch); + } + + /* + $app_to_dl[] = array('name' => $task['path'], + 'url' => $task['package_url'], + 'filesize' => 0, + 'localtarget' => $this->packages_dir.'/'.$task['path']); + + $this->fetchFiles($app_to_dl); + */ + + // Make sure the requirements are given so that this script can execute + $req_ret = $this->checkRequirements(); + if(!$req_ret) return false; + + $metafile = $this->getContentFromZIP($this->packages_dir.'/'.$task['path'], 'APP-META.xml'); + // Check if the meta file is existing + if(!$metafile) + { + $app->dbmaster->query('UPDATE aps_instances SET instance_status = "'.INSTANCE_ERROR.'" + WHERE id = "'.$app->db->quote($task['instance_id']).'";'); + $app->log('Unable to find the meta data file of package '.$task['path'], 1); + return false; + } + + // Rename namespaces and register them + $metadata = str_replace("xmlns=", "ns=", $metafile); + $sxe = new SimpleXMLElement($metadata); + $namespaces = $sxe->getDocNamespaces(true); + foreach($namespaces as $ns => $url) $sxe->registerXPathNamespace($ns, $url); + + // Setup the environment with data for the install location + $this->prepareLocation($task); + + // Create the database if necessary + $this->prepareDatabase($task, $sxe); + + // Unpack the install scripts from the packages + if($this->prepareFiles($task, $sxe) && $this->handle_type == 'install') + { + // Setup the variables from the install script + $this->prepareUserInputData($task); + + // Do the actual installation + $this->doInstallation($task, $sxe); + + // Remove temporary files + $this->cleanup($task, $sxe); + } + + // Finally delete the instance entry + settings + if($this->handle_type == 'delete') + { + $app->db->query('DELETE FROM aps_instances WHERE id = "'.$app->db->quote($task['instance_id']).'";'); + $app->db->query('DELETE FROM aps_instances_settings WHERE instance_id = "'.$app->db->quote($task['instance_id']).'";'); + } + + unset($sxe); + } +} ?> \ No newline at end of file diff --git a/server/plugins-available/apache2_plugin.inc.php b/server/plugins-available/apache2_plugin.inc.php index 2e1e80ce85ce455d87f34147707fa65a74ed4477..d99eb44526f7c06d5c48a36738e69a567cc2c33e 100644 --- a/server/plugins-available/apache2_plugin.inc.php +++ b/server/plugins-available/apache2_plugin.inc.php @@ -1339,23 +1339,23 @@ class apache2_plugin { if(count($ipv4_ssl_alias_seo_redirects) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $ipv4_ssl_alias_seo_redirects); $vhosts[] = $tmp_vhost_arr; unset($tmp_vhost_arr, $ipv4_ssl_alias_seo_redirects); - $app->log('Enable SSL for: '.$domain,LOGLEVEL_DEBUG); - } - - //* Add vhost for IPv6 IP - if($data['new']['ipv6_address'] != '') { - if ($conf['serverconfig']['web']['vhost_rewrite_v6'] == 'y') { - if (isset($conf['serverconfig']['server']['v6_prefix']) && $conf['serverconfig']['server']['v6_prefix'] <> '') { - $explode_v6prefix=explode(':',$conf['serverconfig']['server']['v6_prefix']); - $explode_v6=explode(':',$data['new']['ipv6_address']); - - for ( $i = 0; $i <= count($explode_v6prefix)-3; $i++ ) { - $explode_v6[$i] = $explode_v6prefix[$i]; - } - $data['new']['ipv6_address'] = implode(':',$explode_v6); - } - } - + $app->log('Enable SSL for: '.$domain,LOGLEVEL_DEBUG); + } + + //* Add vhost for IPv6 IP + if($data['new']['ipv6_address'] != '') { + if ($conf['serverconfig']['web']['vhost_rewrite_v6'] == 'y') { + if (isset($conf['serverconfig']['server']['v6_prefix']) && $conf['serverconfig']['server']['v6_prefix'] <> '') { + $explode_v6prefix=explode(':',$conf['serverconfig']['server']['v6_prefix']); + $explode_v6=explode(':',$data['new']['ipv6_address']); + + for ( $i = 0; $i <= count($explode_v6prefix)-3; $i++ ) { + $explode_v6[$i] = $explode_v6prefix[$i]; + } + $data['new']['ipv6_address'] = implode(':',$explode_v6); + } + } + $tmp_vhost_arr = array('ip_address' => '['.$data['new']['ipv6_address'].']', 'ssl_enabled' => 0, 'port' => 80); if(count($rewrite_rules) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $rewrite_rules); if(count($alias_seo_redirects) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $alias_seo_redirects); diff --git a/server/plugins-available/aps_plugin.inc.php b/server/plugins-available/aps_plugin.inc.php index dbbbfb944a1ba8ce90ccfcf24b81a3c6cc3b323b..e529b12b207aab48fd9ddc8100133cf1f2c21206 100644 --- a/server/plugins-available/aps_plugin.inc.php +++ b/server/plugins-available/aps_plugin.inc.php @@ -1,118 +1,118 @@ -<?php -/* -Copyright (c) 2012, ISPConfig UG -Contributors: web wack creations, http://www.web-wack.at -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of ISPConfig nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -if(defined('ISPC_ROOT_PATH')) include_once(ISPC_ROOT_PATH.'/lib/classes/aps_installer.inc.php'); -//require_once(ISPC_ROOT_PATH.'/lib/classes/class.installer.php'); - -class aps_plugin -{ - public $plugin_name = 'aps_plugin'; - public $class_name = 'aps_plugin'; - - //* This function is called during ispconfig installation to determine - // if a symlink shall be created for this plugin. - function onInstall() { - global $conf; - - if($conf['services']['web'] == true) { - return true; - } else { - return false; - } - - } - - /** - * This method gets called when the plugin is loaded - */ - public function onLoad() - { - global $app; - - // Register the available events - $app->plugins->registerEvent('aps_instance_insert', $this->plugin_name, 'install'); - $app->plugins->registerEvent('aps_instance_update', $this->plugin_name, 'install'); - $app->plugins->registerEvent('aps_instance_delete', $this->plugin_name, 'delete'); - } - - /** - * (Re-)install a package - */ - public function install($event_name, $data) - { - global $app, $conf; - - //* dont run the installer on a mirror server to prevent - // that the pplication gets installed twice. - if($conf['mirror_server_id'] > 0) return true; - - $app->log("Starting APS install",LOGLEVEL_DEBUG); - if(!isset($data['new']['id'])) return false; - $instanceid = $data['new']['id']; - - if($data['new']['instance_status'] == INSTANCE_INSTALL) { - $aps = new ApsInstaller($app); - $app->log("Running installHandler",LOGLEVEL_DEBUG); - $aps->installHandler($instanceid, 'install'); - } - - if($data['new']['instance_status'] == INSTANCE_REMOVE) { - $aps = new ApsInstaller($app); - $app->log("Running installHandler",LOGLEVEL_DEBUG); - $aps->installHandler($instanceid, 'delete'); - } - } - - /** - * Update an existing instance (currently unused) - */ - /* - public function update($event_name, $data) - { - } - */ - - /** - * Uninstall an instance - */ - public function delete($event_name, $data) - { - global $app, $conf; - - if(!isset($data['new']['id'])) return false; - $instanceid = $data['new']['id']; - - if($data['new']['instance_status'] == INSTANCE_REMOVE) { - $aps = new ApsInstaller($app); - $aps->installHandler($instanceid, 'install'); - } - } -} +<?php +/* +Copyright (c) 2012, ISPConfig UG +Contributors: web wack creations, http://www.web-wack.at +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of ISPConfig nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +if(defined('ISPC_ROOT_PATH')) include_once(ISPC_ROOT_PATH.'/lib/classes/aps_installer.inc.php'); +//require_once(ISPC_ROOT_PATH.'/lib/classes/class.installer.php'); + +class aps_plugin +{ + public $plugin_name = 'aps_plugin'; + public $class_name = 'aps_plugin'; + + //* This function is called during ispconfig installation to determine + // if a symlink shall be created for this plugin. + function onInstall() { + global $conf; + + if($conf['services']['web'] == true) { + return true; + } else { + return false; + } + + } + + /** + * This method gets called when the plugin is loaded + */ + public function onLoad() + { + global $app; + + // Register the available events + $app->plugins->registerEvent('aps_instance_insert', $this->plugin_name, 'install'); + $app->plugins->registerEvent('aps_instance_update', $this->plugin_name, 'install'); + $app->plugins->registerEvent('aps_instance_delete', $this->plugin_name, 'delete'); + } + + /** + * (Re-)install a package + */ + public function install($event_name, $data) + { + global $app, $conf; + + //* dont run the installer on a mirror server to prevent + // that the pplication gets installed twice. + if($conf['mirror_server_id'] > 0) return true; + + $app->log("Starting APS install",LOGLEVEL_DEBUG); + if(!isset($data['new']['id'])) return false; + $instanceid = $data['new']['id']; + + if($data['new']['instance_status'] == INSTANCE_INSTALL) { + $aps = new ApsInstaller($app); + $app->log("Running installHandler",LOGLEVEL_DEBUG); + $aps->installHandler($instanceid, 'install'); + } + + if($data['new']['instance_status'] == INSTANCE_REMOVE) { + $aps = new ApsInstaller($app); + $app->log("Running installHandler",LOGLEVEL_DEBUG); + $aps->installHandler($instanceid, 'delete'); + } + } + + /** + * Update an existing instance (currently unused) + */ + /* + public function update($event_name, $data) + { + } + */ + + /** + * Uninstall an instance + */ + public function delete($event_name, $data) + { + global $app, $conf; + + if(!isset($data['new']['id'])) return false; + $instanceid = $data['new']['id']; + + if($data['new']['instance_status'] == INSTANCE_REMOVE) { + $aps = new ApsInstaller($app); + $aps->installHandler($instanceid, 'install'); + } + } +} ?> \ No newline at end of file diff --git a/server/plugins-available/nginx_plugin.inc.php b/server/plugins-available/nginx_plugin.inc.php index e2d927f1bf34eeb32e3ce12870d1d1305b0e9006..3cd366363f69beef7beb06ed215b5365c365bf3f 100644 --- a/server/plugins-available/nginx_plugin.inc.php +++ b/server/plugins-available/nginx_plugin.inc.php @@ -1,2815 +1,2815 @@ -<?php - -/* -Copyright (c) 2007 - 2012, Till Brehm, projektfarm Gmbh -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of ISPConfig nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -class nginx_plugin { - - var $plugin_name = 'nginx_plugin'; - var $class_name = 'nginx_plugin'; - - // private variables - var $action = ''; - var $ssl_certificate_changed = false; - - //* This function is called during ispconfig installation to determine - // if a symlink shall be created for this plugin. - function onInstall() { - global $conf; - - if($conf['services']['web'] == true && !@is_link('/usr/local/ispconfig/server/plugins-enabled/apache2_plugin.inc.php')) { - return true; - } else { - return false; - } - - } - - - /* - This function is called when the plugin is loaded - */ - - function onLoad() { - global $app; - - /* - Register for the events - */ - $app->plugins->registerEvent('web_domain_insert',$this->plugin_name,'ssl'); - $app->plugins->registerEvent('web_domain_update',$this->plugin_name,'ssl'); - $app->plugins->registerEvent('web_domain_delete',$this->plugin_name,'ssl'); - - $app->plugins->registerEvent('web_domain_insert',$this->plugin_name,'insert'); - $app->plugins->registerEvent('web_domain_update',$this->plugin_name,'update'); - $app->plugins->registerEvent('web_domain_delete',$this->plugin_name,'delete'); - - $app->plugins->registerEvent('server_ip_insert',$this->plugin_name,'server_ip'); - $app->plugins->registerEvent('server_ip_update',$this->plugin_name,'server_ip'); - $app->plugins->registerEvent('server_ip_delete',$this->plugin_name,'server_ip'); - - /* - $app->plugins->registerEvent('webdav_user_insert',$this->plugin_name,'webdav'); - $app->plugins->registerEvent('webdav_user_update',$this->plugin_name,'webdav'); - $app->plugins->registerEvent('webdav_user_delete',$this->plugin_name,'webdav'); - */ - - $app->plugins->registerEvent('client_delete',$this->plugin_name,'client_delete'); - - $app->plugins->registerEvent('web_folder_user_insert',$this->plugin_name,'web_folder_user'); - $app->plugins->registerEvent('web_folder_user_update',$this->plugin_name,'web_folder_user'); - $app->plugins->registerEvent('web_folder_user_delete',$this->plugin_name,'web_folder_user'); - - $app->plugins->registerEvent('web_folder_update',$this->plugin_name,'web_folder_update'); - $app->plugins->registerEvent('web_folder_delete',$this->plugin_name,'web_folder_delete'); - } - - // Handle the creation of SSL certificates - function ssl($event_name,$data) { - global $app, $conf; - - $app->uses('system'); - - // load the server configuration options - $app->uses('getconf'); - $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); - if ($web_config['CA_path']!='' && !file_exists($web_config['CA_path'].'/openssl.cnf')) - $app->log("CA path error, file does not exist:".$web_config['CA_path'].'/openssl.cnf',LOGLEVEL_ERROR); - - //* Only vhosts can have a ssl cert - if($data["new"]["type"] != "vhost" && $data["new"]["type"] != "vhostsubdomain") return; - - // if(!is_dir($data['new']['document_root'].'/ssl')) exec('mkdir -p '.$data['new']['document_root'].'/ssl'); - if(!is_dir($data['new']['document_root'].'/ssl')) $app->system->mkdirpath($data['new']['document_root'].'/ssl'); - - $ssl_dir = $data['new']['document_root'].'/ssl'; - $domain = $data['new']['ssl_domain']; - $key_file = $ssl_dir.'/'.$domain.'.key.org'; - $key_file2 = $ssl_dir.'/'.$domain.'.key'; - $csr_file = $ssl_dir.'/'.$domain.'.csr'; - $crt_file = $ssl_dir.'/'.$domain.'.crt'; - - //* Create a SSL Certificate - if($data['new']['ssl_action'] == 'create' && $conf['mirror_server_id'] == 0) { - - $this->ssl_certificate_changed = true; - - //* Rename files if they exist - if(file_exists($key_file)){ - $app->system->rename($key_file,$key_file.'.bak'); - $app->system->chmod($key_file.'.bak',0400); - } - if(file_exists($key_file2)){ - $app->system->rename($key_file2,$key_file2.'.bak'); - $app->system->chmod($key_file2.'.bak',0400); - } - if(file_exists($csr_file)) $app->system->rename($csr_file,$csr_file.'.bak'); - if(file_exists($crt_file)) $app->system->rename($crt_file,$crt_file.'.bak'); - - $rand_file = $ssl_dir.'/random_file'; - $rand_data = md5(uniqid(microtime(),1)); - for($i=0; $i<1000; $i++) { - $rand_data .= md5(uniqid(microtime(),1)); - $rand_data .= md5(uniqid(microtime(),1)); - $rand_data .= md5(uniqid(microtime(),1)); - $rand_data .= md5(uniqid(microtime(),1)); - } - $app->system->file_put_contents($rand_file, $rand_data); - - $ssl_password = substr(md5(uniqid(microtime(),1)), 0, 15); - - $ssl_cnf = " RANDFILE = $rand_file - - [ req ] - default_bits = 2048 - default_keyfile = keyfile.pem - distinguished_name = req_distinguished_name - attributes = req_attributes - prompt = no - output_password = $ssl_password - - [ req_distinguished_name ] - C = ".trim($data['new']['ssl_country'])." - ST = ".trim($data['new']['ssl_state'])." - L = ".trim($data['new']['ssl_locality'])." - O = ".trim($data['new']['ssl_organisation'])." - OU = ".trim($data['new']['ssl_organisation_unit'])." - CN = $domain - emailAddress = webmaster@".$data['new']['domain']." - - [ req_attributes ] - challengePassword = A challenge password"; - - $ssl_cnf_file = $ssl_dir.'/openssl.conf'; - $app->system->file_put_contents($ssl_cnf_file,$ssl_cnf); - - $rand_file = escapeshellcmd($rand_file); - $key_file = escapeshellcmd($key_file); - if(substr($domain, 0, 2) == '*.' && strpos($key_file, '/ssl/\*.') !== false) $key_file = str_replace('/ssl/\*.', '/ssl/*.', $key_file); // wildcard certificate - $key_file2 = escapeshellcmd($key_file2); - if(substr($domain, 0, 2) == '*.' && strpos($key_file2, '/ssl/\*.') !== false) $key_file2 = str_replace('/ssl/\*.', '/ssl/*.', $key_file2); // wildcard certificate - $ssl_days = 3650; - $csr_file = escapeshellcmd($csr_file); - if(substr($domain, 0, 2) == '*.' && strpos($csr_file, '/ssl/\*.') !== false) $csr_file = str_replace('/ssl/\*.', '/ssl/*.', $csr_file); // wildcard certificate - $config_file = escapeshellcmd($ssl_cnf_file); - $crt_file = escapeshellcmd($crt_file); - if(substr($domain, 0, 2) == '*.' && strpos($crt_file, '/ssl/\*.') !== false) $crt_file = str_replace('/ssl/\*.', '/ssl/*.', $crt_file); // wildcard certificate - - if(is_file($ssl_cnf_file) && !is_link($ssl_cnf_file)) { - - exec("openssl genrsa -des3 -rand $rand_file -passout pass:$ssl_password -out $key_file 2048"); - exec("openssl req -new -passin pass:$ssl_password -passout pass:$ssl_password -key $key_file -out $csr_file -days $ssl_days -config $config_file"); - exec("openssl rsa -passin pass:$ssl_password -in $key_file -out $key_file2"); - - if(file_exists($web_config['CA_path'].'/openssl.cnf')) - { - exec("openssl ca -batch -out $crt_file -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -in $csr_file"); - $app->log("Creating CA-signed SSL Cert for: $domain",LOGLEVEL_DEBUG); - if (filesize($crt_file)==0 || !file_exists($crt_file)) $app->log("CA-Certificate signing failed. openssl ca -out $crt_file -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -in $csr_file",LOGLEVEL_ERROR); - }; - if (@filesize($crt_file)==0 || !file_exists($crt_file)){ - exec("openssl req -x509 -passin pass:$ssl_password -passout pass:$ssl_password -key $key_file -in $csr_file -out $crt_file -days $ssl_days -config $config_file "); - $app->log("Creating self-signed SSL Cert for: $domain",LOGLEVEL_DEBUG); - }; - - } - - $app->system->chmod($key_file,0400); - $app->system->chmod($key_file2,0400); - @$app->system->unlink($config_file); - @$app->system->unlink($rand_file); - $ssl_request = $app->db->quote($app->system->file_get_contents($csr_file)); - $ssl_cert = $app->db->quote($app->system->file_get_contents($crt_file)); - $ssl_key2 = $app->db->quote($app->system->file_get_contents($key_file2)); - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET ssl_request = '$ssl_request', ssl_cert = '$ssl_cert', ssl_key = '$ssl_key2' WHERE domain = '".$data['new']['domain']."'"); - $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'"); - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET ssl_request = '$ssl_request', ssl_cert = '$ssl_cert', ssl_key = '$ssl_key2' WHERE domain = '".$data['new']['domain']."'"); - $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'"); - } - - //* Save a SSL certificate to disk - if($data["new"]["ssl_action"] == 'save') { - $this->ssl_certificate_changed = true; - $ssl_dir = $data["new"]["document_root"]."/ssl"; - $domain = ($data["new"]["ssl_domain"] != '')?$data["new"]["ssl_domain"]:$data["new"]["domain"]; - $key_file = $ssl_dir.'/'.$domain.'.key.org'; - $key_file2 = $ssl_dir.'/'.$domain.'.key'; - $csr_file = $ssl_dir.'/'.$domain.".csr"; - $crt_file = $ssl_dir.'/'.$domain.".crt"; - //$bundle_file = $ssl_dir.'/'.$domain.".bundle"; - - //* Backup files - if(file_exists($key_file)){ - $app->system->copy($key_file,$key_file.'~'); - $app->system->chmod($key_file.'~',0400); - } - if(file_exists($key_file2)){ - $app->system->copy($key_file2,$key_file2.'~'); - $app->system->chmod($key_file2.'~',0400); - } - if(file_exists($csr_file)) $app->system->copy($csr_file,$csr_file.'~'); - if(file_exists($crt_file)) $app->system->copy($crt_file,$crt_file.'~'); - //if(file_exists($bundle_file)) $app->system->copy($bundle_file,$bundle_file.'~'); - - //* Write new ssl files - if(trim($data["new"]["ssl_request"]) != '') $app->system->file_put_contents($csr_file,$data["new"]["ssl_request"]); - if(trim($data["new"]["ssl_cert"]) != '') $app->system->file_put_contents($crt_file,$data["new"]["ssl_cert"]); - //if(trim($data["new"]["ssl_bundle"]) != '') $app->system->file_put_contents($bundle_file,$data["new"]["ssl_bundle"]); - if(trim($data["new"]["ssl_key"]) != '') $app->system->file_put_contents($key_file2,$data["new"]["ssl_key"]); - $app->system->chmod($key_file2,0400); - - // for nginx, bundle files have to be appended to the certificate file - if(trim($data["new"]["ssl_bundle"]) != ''){ - if(file_exists($crt_file)){ - $crt_file_contents = trim($app->system->file_get_contents($crt_file)); - } else { - $crt_file_contents = ''; - } - if($crt_file_contents != '') $crt_file_contents .= "\n"; - $crt_file_contents .= $data["new"]["ssl_bundle"]; - $app->system->file_put_contents($crt_file,$app->file->unix_nl($crt_file_contents)); - unset($crt_file_contents); - } - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'"); - - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'"); - $app->log('Saving SSL Cert for: '.$domain,LOGLEVEL_DEBUG); - } - - //* Delete a SSL certificate - if($data['new']['ssl_action'] == 'del') { - $ssl_dir = $data['new']['document_root'].'/ssl'; - $domain = ($data["new"]["ssl_domain"] != '')?$data["new"]["ssl_domain"]:$data["new"]["domain"]; - $csr_file = $ssl_dir.'/'.$domain.'.csr'; - $crt_file = $ssl_dir.'/'.$domain.'.crt'; - //$bundle_file = $ssl_dir.'/'.$domain.'.bundle'; - if(file_exists($web_config['CA_path'].'/openssl.cnf') && !is_link($web_config['CA_path'].'/openssl.cnf')) - { - exec("openssl ca -batch -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -revoke $crt_file"); - $app->log("Revoking CA-signed SSL Cert for: $domain",LOGLEVEL_DEBUG); - }; - $app->system->unlink($csr_file); - $app->system->unlink($crt_file); - //$app->system->unlink($bundle_file); - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = '".$data['new']['domain']."'"); - $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'"); - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = '".$data['new']['domain']."'"); - $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'"); - $app->log('Deleting SSL Cert for: '.$domain,LOGLEVEL_DEBUG); - } - - } - - - function insert($event_name,$data) { - global $app, $conf; - - $this->action = 'insert'; - // just run the update function - $this->update($event_name,$data); - - - } - - - function update($event_name,$data) { - global $app, $conf; - - //* Check if the apache plugin is enabled - if(@is_link('/usr/local/ispconfig/server/plugins-enabled/apache2_plugin.inc.php')) { - $app->log('The nginx plugin cannot be used together with the apache2 plugin.',LOGLEVEL_WARN); - return 0; - } - - if($this->action != 'insert') $this->action = 'update'; - - if($data['new']['type'] != 'vhost' && $data['new']['type'] != 'vhostsubdomain' && $data['new']['parent_domain_id'] > 0) { - - $old_parent_domain_id = intval($data['old']['parent_domain_id']); - $new_parent_domain_id = intval($data['new']['parent_domain_id']); - - // If the parent_domain_id has been changed, we will have to update the old site as well. - if($this->action == 'update' && $data['new']['parent_domain_id'] != $data['old']['parent_domain_id']) { - $tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = '.$old_parent_domain_id." AND active = 'y'"); - $data['new'] = $tmp; - $data['old'] = $tmp; - $this->action = 'update'; - $this->update($event_name,$data); - } - - // This is not a vhost, so we need to update the parent record instead. - $tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = '.$new_parent_domain_id." AND active = 'y'"); - $data['new'] = $tmp; - $data['old'] = $tmp; - $this->action = 'update'; - } - - // load the server configuration options - $app->uses('getconf'); - $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); - - //* Check if this is a chrooted setup - if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) { - $nginx_chrooted = true; - $app->log('Info: nginx is chrooted.',LOGLEVEL_DEBUG); - } else { - $nginx_chrooted = false; - } - - if($data['new']['document_root'] == '') { - if($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain') $app->log('document_root not set',LOGLEVEL_WARN); - return 0; - } - if($data['new']['system_user'] == 'root' or $data['new']['system_group'] == 'root') { - $app->log('Websites cannot be owned by the root user or group.',LOGLEVEL_WARN); - return 0; - } - if(trim($data['new']['domain']) == '') { - $app->log('domain is empty',LOGLEVEL_WARN); - return 0; - } - - $web_folder = 'web'; - $log_folder = 'log'; - if($data['new']['type'] == 'vhostsubdomain') { - $tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = '.intval($data['new']['parent_domain_id'])); - $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['new']['domain']); - if($subdomain_host == '') $subdomain_host = 'web'.$data['new']['domain_id']; - $web_folder = $data['new']['web_folder']; - $log_folder .= '/' . $subdomain_host; - unset($tmp); - } - - // Create group and user, if not exist - $app->uses('system'); - - if($web_config['connect_userid_to_webid'] == 'y') { - //* Calculate the uid and gid - $connect_userid_to_webid_start = ($web_config['connect_userid_to_webid_start'] < 1000)?1000:intval($web_config['connect_userid_to_webid_start']); - $fixed_uid_gid = intval($connect_userid_to_webid_start + $data['new']['domain_id']); - $fixed_uid_param = '--uid '.$fixed_uid_gid; - $fixed_gid_param = '--gid '.$fixed_uid_gid; - - //* Check if a ispconfigend user and group exists and create them - if(!$app->system->is_group('ispconfigend')) { - exec('groupadd --gid '.($connect_userid_to_webid_start + 10000).' ispconfigend'); - } - if(!$app->system->is_user('ispconfigend')) { - exec('useradd -g ispconfigend -d /usr/local/ispconfig --uid '.($connect_userid_to_webid_start + 10000).' ispconfigend'); - } - } else { - $fixed_uid_param = ''; - $fixed_gid_param = ''; - } - - $groupname = escapeshellcmd($data['new']['system_group']); - if($data['new']['system_group'] != '' && !$app->system->is_group($data['new']['system_group'])) { - exec('groupadd '.$fixed_gid_param.' '.$groupname); - if($nginx_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' groupadd '.$groupname); - $app->log('Adding the group: '.$groupname,LOGLEVEL_DEBUG); - } - - $username = escapeshellcmd($data['new']['system_user']); - if($data['new']['system_user'] != '' && !$app->system->is_user($data['new']['system_user'])) { - if($web_config['add_web_users_to_sshusers_group'] == 'y') { - exec('useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param -G sshusers $username -s /bin/false"); - if($nginx_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param -G sshusers $username -s /bin/false"); - } else { - exec('useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param $username -s /bin/false"); - if($nginx_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param $username -s /bin/false"); - } - $app->log('Adding the user: '.$username,LOGLEVEL_DEBUG); - } - - //* If the client of the site has been changed, we have a change of the document root - if($this->action == 'update' && $data['new']['document_root'] != $data['old']['document_root']) { - - //* Get the old client ID - $old_client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = '.intval($data['old']['sys_groupid'])); - $old_client_id = intval($old_client['client_id']); - unset($old_client); - - //* Remove the old symlinks - $tmp_symlinks_array = explode(':',$web_config['website_symlinks']); - if(is_array($tmp_symlinks_array)) { - foreach($tmp_symlinks_array as $tmp_symlink) { - $tmp_symlink = str_replace('[client_id]',$old_client_id,$tmp_symlink); - $tmp_symlink = str_replace('[website_domain]',$data['old']['domain'],$tmp_symlink); - // Remove trailing slash - if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); - // create the symlinks, if not exist - if(is_link($tmp_symlink)) { - exec('rm -f '.escapeshellcmd($tmp_symlink)); - $app->log('Removed symlink: rm -f '.$tmp_symlink,LOGLEVEL_DEBUG); - } - } - } - - if($data["new"]["type"] != "vhostsubdomain") { - //* Move the site data - $tmp_docroot = explode('/',$data['new']['document_root']); - unset($tmp_docroot[count($tmp_docroot)-1]); - $new_dir = implode('/',$tmp_docroot); - - $tmp_docroot = explode('/',$data['old']['document_root']); - unset($tmp_docroot[count($tmp_docroot)-1]); - $old_dir = implode('/',$tmp_docroot); - - //* Check if there is already some data in the new docroot and rename it as we need a clean path to move the existing site to the new path - if(@is_dir($data['new']['document_root'])) { - $app->system->web_folder_protection($data['new']['document_root'],false); - $app->system->rename($data['new']['document_root'],$data['new']['document_root'].'_bak_'.date('Y_m_d_H_i_s')); - $app->log('Renaming existing directory in new docroot location. mv '.$data['new']['document_root'].' '.$data['new']['document_root'].'_bak_'.date('Y_m_d_H_i_s'),LOGLEVEL_DEBUG); - } - - //* Create new base directory, if it does not exist yet - if(!is_dir($new_dir)) $app->system->mkdirpath($new_dir); - $app->system->web_folder_protection($data['old']['document_root'],false); - exec('mv '.escapeshellarg($data['old']['document_root']).' '.escapeshellarg($new_dir)); - //$app->system->rename($data['old']['document_root'],$new_dir); - $app->log('Moving site to new document root: mv '.$data['old']['document_root'].' '.$new_dir,LOGLEVEL_DEBUG); - - // Handle the change in php_open_basedir - $data['new']['php_open_basedir'] = str_replace($data['old']['document_root'],$data['new']['document_root'],$data['old']['php_open_basedir']); - - //* Change the owner of the website files to the new website owner - exec('chown --recursive --from='.escapeshellcmd($data['old']['system_user']).':'.escapeshellcmd($data['old']['system_group']).' '.escapeshellcmd($data['new']['system_user']).':'.escapeshellcmd($data['new']['system_group']).' '.$new_dir); - - //* Change the home directory and group of the website user - $command = 'killall -u '.escapeshellcmd($data['new']['system_user']).' ; usermod'; - $command .= ' --home '.escapeshellcmd($data['new']['document_root']); - $command .= ' --gid '.escapeshellcmd($data['new']['system_group']); - $command .= ' '.escapeshellcmd($data['new']['system_user']).' 2>/dev/null'; - exec($command); - } - - if($nginx_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command); - - //* Change the log mount - $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.' none bind'; - $app->system->removeLine('/etc/fstab',$fstab_line); - $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.' none bind,nobootwait 0 0'; - $app->system->replaceLine('/etc/fstab',$fstab_line,$fstab_line,1,1); - - } - - //print_r($data); - - // Check if the directories are there and create them if necessary. - $app->system->web_folder_protection($data['new']['document_root'],false); - - if(!is_dir($data['new']['document_root'].'/' . $web_folder)) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder); - if(!is_dir($data['new']['document_root'].'/' . $web_folder . '/error') and $data['new']['errordocs']) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder . '/error'); - //if(!is_dir($data['new']['document_root'].'/'.$log_folder)) exec('mkdir -p '.$data['new']['document_root'].'/'.$log_folder); - if(!is_dir($data['new']['document_root'].'/ssl')) $app->system->mkdirpath($data['new']['document_root'].'/ssl'); - if(!is_dir($data['new']['document_root'].'/cgi-bin')) $app->system->mkdirpath($data['new']['document_root'].'/cgi-bin'); - if(!is_dir($data['new']['document_root'].'/tmp')) $app->system->mkdirpath($data['new']['document_root'].'/tmp'); - //if(!is_dir($data['new']['document_root'].'/webdav')) $app->system->mkdirpath($data['new']['document_root'].'/webdav'); - - //* Create the new private directory - if(!is_dir($data['new']['document_root'].'/private')) { - $app->system->mkdirpath($data['new']['document_root'].'/private'); - $app->system->chmod($data['new']['document_root'].'/private',0710); - $app->system->chown($data['new']['document_root'].'/private',$username); - $app->system->chgrp($data['new']['document_root'].'/private',$groupname); - } - - - // Remove the symlink for the site, if site is renamed - if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) { - if(is_dir('/var/log/ispconfig/httpd/'.$data['old']['domain'])) exec('rm -rf /var/log/ispconfig/httpd/'.$data['old']['domain']); - if(is_link($data['old']['document_root'].'/'.$log_folder)) $app->system->unlink($data['old']['document_root'].'/'.$log_folder); - - //* remove old log mount - $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.' none bind'; - $app->system->removeLine('/etc/fstab',$fstab_line); - - //* Unmount log directory - exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder)); - } - - //* Create the log dir if nescessary and mount it - if(!is_dir($data['new']['document_root'].'/'.$log_folder) || !is_dir('/var/log/ispconfig/httpd/'.$data['new']['domain']) || is_link($data['new']['document_root'].'/'.$log_folder)) { - if(is_link($data['new']['document_root'].'/'.$log_folder)) unlink($data['new']['document_root'].'/'.$log_folder); - if(!is_dir('/var/log/ispconfig/httpd/'.$data['new']['domain'])) exec('mkdir -p /var/log/ispconfig/httpd/'.$data['new']['domain']); - $app->system->mkdirpath($data['new']['document_root'].'/'.$log_folder); - $app->system->chown($data['new']['document_root'].'/'.$log_folder,'root'); - $app->system->chgrp($data['new']['document_root'].'/'.$log_folder,'root'); - $app->system->chmod($data['new']['document_root'].'/'.$log_folder,0755); - exec('mount --bind '.escapeshellarg('/var/log/ispconfig/httpd/'.$data['new']['domain']).' '.escapeshellarg($data['new']['document_root'].'/'.$log_folder)); - //* add mountpoint to fstab - $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.' none bind,nobootwait 0 0'; - $app->system->replaceLine('/etc/fstab',$fstab_line,$fstab_line,1,1); - } - - $app->system->web_folder_protection($data['new']['document_root'],true); - - // Get the client ID - $client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = '.intval($data['new']['sys_groupid'])); - $client_id = intval($client['client_id']); - unset($client); - - // Remove old symlinks, if site is renamed - if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) { - $tmp_symlinks_array = explode(':',$web_config['website_symlinks']); - if(is_array($tmp_symlinks_array)) { - foreach($tmp_symlinks_array as $tmp_symlink) { - $tmp_symlink = str_replace('[client_id]',$client_id,$tmp_symlink); - $tmp_symlink = str_replace('[website_domain]',$data['old']['domain'],$tmp_symlink); - // Remove trailing slash - if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); - // remove the symlinks, if not exist - if(is_link($tmp_symlink)) { - exec('rm -f '.escapeshellcmd($tmp_symlink)); - $app->log('Removed symlink: rm -f '.$tmp_symlink,LOGLEVEL_DEBUG); - } - } - } - } - - // Create the symlinks for the sites - $tmp_symlinks_array = explode(':',$web_config['website_symlinks']); - if(is_array($tmp_symlinks_array)) { - foreach($tmp_symlinks_array as $tmp_symlink) { - $tmp_symlink = str_replace('[client_id]',$client_id,$tmp_symlink); - $tmp_symlink = str_replace('[website_domain]',$data['new']['domain'],$tmp_symlink); - // Remove trailing slash - if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); - //* Remove symlink if target folder has been changed. - if($data['old']['document_root'] != '' && $data['old']['document_root'] != $data['new']['document_root'] && is_link($tmp_symlink)) { - $app->system->unlink($tmp_symlink); - } - // create the symlinks, if not exist - if(!is_link($tmp_symlink)) { -// exec("ln -s ".escapeshellcmd($data["new"]["document_root"])."/ ".escapeshellcmd($tmp_symlink)); - if ($web_config["website_symlinks_rel"] == 'y') { - $this->create_relative_link(escapeshellcmd($data["new"]["document_root"]), escapeshellcmd($tmp_symlink)); - } else { - exec("ln -s ".escapeshellcmd($data["new"]["document_root"])."/ ".escapeshellcmd($tmp_symlink)); - } - - $app->log('Creating symlink: ln -s '.$data['new']['document_root'].'/ '.$tmp_symlink,LOGLEVEL_DEBUG); - } - } - } - - - - // Install the Standard or Custom Error, Index and other related files - // /usr/local/ispconfig/server/conf is for the standard files - // /usr/local/ispconfig/server/conf-custom is for the custom files - // setting a local var here - - // normally $conf['templates'] = "/usr/local/ispconfig/server/conf"; - if($this->action == 'insert' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain')) { - - // Copy the error pages - if($data['new']['errordocs']) { - $error_page_path = escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/error/'; - if (file_exists($conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']),0,2))) { - exec('cp ' . $conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']),0,2).'/* '.$error_page_path); - } - else { - if (file_exists($conf['rootpath'] . '/conf-custom/error/400.html')) { - exec('cp '. $conf['rootpath'] . '/conf-custom/error/*.html '.$error_page_path); - } - else { - exec('cp ' . $conf['rootpath'] . '/conf/error/'.substr(escapeshellcmd($conf['language']),0,2).'/* '.$error_page_path); - } - } - exec('chmod -R a+r '.$error_page_path); - } - - if (file_exists($conf['rootpath'] . '/conf-custom/index/standard_index.html_'.substr(escapeshellcmd($conf['language']),0,2))) { - exec('cp ' . $conf['rootpath'] . '/conf-custom/index/standard_index.html_'.substr(escapeshellcmd($conf['language']),0,2).' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html'); - - if(is_file($conf['rootpath'] . '/conf-custom/index/favicon.ico')) { - exec('cp ' . $conf['rootpath'] . '/conf-custom/index/favicon.ico '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - } - if(is_file($conf['rootpath'] . '/conf-custom/index/robots.txt')) { - exec('cp ' . $conf['rootpath'] . '/conf-custom/index/robots.txt '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - } - if(is_file($conf['rootpath'] . '/conf-custom/index/.htaccess')) { - exec('cp ' . $conf['rootpath'] . '/conf-custom/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - } - } - else { - if (file_exists($conf['rootpath'] . '/conf-custom/index/standard_index.html')) { - exec('cp ' . $conf['rootpath'] . '/conf-custom/index/standard_index.html '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html'); - } - else { - exec('cp ' . $conf['rootpath'] . '/conf/index/standard_index.html_'.substr(escapeshellcmd($conf['language']),0,2).' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html'); - if(is_file($conf['rootpath'] . '/conf/index/favicon.ico')) exec('cp ' . $conf['rootpath'] . '/conf/index/favicon.ico '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - if(is_file($conf['rootpath'] . '/conf/index/robots.txt')) exec('cp ' . $conf['rootpath'] . '/conf/index/robots.txt '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - if(is_file($conf['rootpath'] . '/conf/index/.htaccess')) exec('cp ' . $conf['rootpath'] . '/conf/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - } - } - exec('chmod -R a+r '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - - //** Copy the error documents on update when the error document checkbox has been activated and was deactivated before - } elseif ($this->action == 'update' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain') && $data['old']['errordocs'] == 0 && $data['new']['errordocs'] == 1) { - - $error_page_path = escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/error/'; - if (file_exists($conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']),0,2))) { - exec('cp ' . $conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']),0,2).'/* '.$error_page_path); - } - else { - if (file_exists($conf['rootpath'] . '/conf-custom/error/400.html')) { - exec('cp ' . $conf['rootpath'] . '/conf-custom/error/*.html '.$error_page_path); - } - else { - exec('cp ' . $conf['rootpath'] . '/conf/error/'.substr(escapeshellcmd($conf['language']),0,2).'/* '.$error_page_path); - } - } - exec('chmod -R a+r '.$error_page_path); - exec('chown -R '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.$error_page_path); - } // end copy error docs - - // Set the quota for the user, but only for vhosts, not vhostsubdomains - if($username != '' && $app->system->is_user($username) && $data['new']['type'] == 'vhost') { - if($data['new']['hd_quota'] > 0) { - $blocks_soft = $data['new']['hd_quota'] * 1024; - $blocks_hard = $blocks_soft + 1024; - } else { - $blocks_soft = $blocks_hard = 0; - } - exec("setquota -u $username $blocks_soft $blocks_hard 0 0 -a &> /dev/null"); - exec('setquota -T -u '.$username.' 604800 604800 -a &> /dev/null'); - } - - if($this->action == 'insert' || $data["new"]["system_user"] != $data["old"]["system_user"]) { - // Chown and chmod the directories below the document root - $this->_exec('chown -R '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder); - // The document root itself has to be owned by root in normal level and by the web owner in security level 20 - if($web_config['security_level'] == 20) { - $this->_exec('chown '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder); - } else { - $this->_exec('chown root:root '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder); - } - } - - //* add the nginx user to the client group if this is a vhost and security level is set to high, no matter if this is an insert or update and regardless of set_folder_permissions_on_update - if($data['new']['type'] == 'vhost' && $web_config['security_level'] == 20) $app->system->add_user_to_group($groupname, escapeshellcmd($web_config['nginx_user'])); - - //* If the security level is set to high - if(($this->action == 'insert' && $data['new']['type'] == 'vhost') or ($web_config['set_folder_permissions_on_update'] == 'y' && $data['new']['type'] == 'vhost')) { - - $app->system->web_folder_protection($data['new']['document_root'],false); - - //* Check if we have the new private folder and create it if nescessary - if(!is_dir($data['new']['document_root'].'/private')) $app->system->mkdir($data['new']['document_root'].'/private'); - - if($web_config['security_level'] == 20) { - - $app->system->chmod($data['new']['document_root'],0755); - $app->system->chmod($data['new']['document_root'].'/web',0710); - //$app->system->chmod($data['new']['document_root'].'/webdav',0710); - $app->system->chmod($data['new']['document_root'].'/private',0710); - $app->system->chmod($data['new']['document_root'].'/ssl',0755); - - // make tmp directory writable for nginx and the website users - $app->system->chmod($data['new']['document_root'].'/tmp',0777); - - // Set Log directory to 755 to make the logs accessible by the FTP user - if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { - $app->system->chmod($data['new']['document_root'].'/'.$log_folder,0755); - } - - if($web_config['add_web_users_to_sshusers_group'] == 'y') { - $command = 'usermod'; - $command .= ' --groups sshusers'; - $command .= ' '.escapeshellcmd($data['new']['system_user']).' 2>/dev/null'; - $this->_exec($command); - } - - //* if we have a chrooted nginx environment - if($nginx_chrooted) { - $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command); - - //* add the nginx user to the client group in the chroot environment - $tmp_groupfile = $app->system->server_conf['group_datei']; - $app->system->server_conf['group_datei'] = $web_config['website_basedir'].'/etc/group'; - $app->system->add_user_to_group($groupname, escapeshellcmd($web_config['nginx_user'])); - $app->system->server_conf['group_datei'] = $tmp_groupfile; - unset($tmp_groupfile); - } - - //* Chown all default directories - $app->system->chown($data['new']['document_root'],'root'); - $app->system->chgrp($data['new']['document_root'],'root'); - $app->system->chown($data['new']['document_root'].'/cgi-bin',$username); - $app->system->chgrp($data['new']['document_root'].'/cgi-bin',$groupname); - if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { - $app->system->chown($data['new']['document_root'].'/'.$log_folder,'root',false); - $app->system->chgrp($data['new']['document_root'].'/'.$log_folder,$groupname,false); - } - $app->system->chown($data['new']['document_root'].'/ssl','root'); - $app->system->chgrp($data['new']['document_root'].'/ssl','root'); - $app->system->chown($data['new']['document_root'].'/tmp',$username); - $app->system->chgrp($data['new']['document_root'].'/tmp',$groupname); - $app->system->chown($data['new']['document_root'].'/web',$username); - $app->system->chgrp($data['new']['document_root'].'/web',$groupname); - $app->system->chown($data['new']['document_root'].'/web/error',$username); - $app->system->chgrp($data['new']['document_root'].'/web/error',$groupname); - $app->system->chown($data['new']['document_root'].'/web/stats',$username); - $app->system->chgrp($data['new']['document_root'].'/web/stats',$groupname); - //$app->system->chown($data['new']['document_root'].'/webdav',$username); - //$app->system->chgrp($data['new']['document_root'].'/webdav',$groupname); - $app->system->chown($data['new']['document_root'].'/private',$username); - $app->system->chgrp($data['new']['document_root'].'/private',$groupname); - - // If the security Level is set to medium - } else { - - $app->system->chmod($data['new']['document_root'],0755); - $app->system->chmod($data['new']['document_root'].'/web',0755); - //$app->system->chmod($data['new']['document_root'].'/webdav',0755); - $app->system->chmod($data['new']['document_root'].'/ssl',0755); - $app->system->chmod($data['new']['document_root'].'/cgi-bin',0755); - - // make temp directory writable for nginx and the website users - $app->system->chmod($data['new']['document_root'].'/tmp',0777); - - // Set Log directory to 755 to make the logs accessible by the FTP user - if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { - $app->system->chmod($data['new']['document_root'].'/'.$log_folder,0755); - } - - $app->system->chown($data['new']['document_root'],'root'); - $app->system->chgrp($data['new']['document_root'],'root'); - $app->system->chown($data['new']['document_root'].'/cgi-bin',$username); - $app->system->chgrp($data['new']['document_root'].'/cgi-bin',$groupname); - if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { - $app->system->chown($data['new']['document_root'].'/'.$log_folder,'root',false); - $app->system->chgrp($data['new']['document_root'].'/'.$log_folder,$groupname,false); - } - - $app->system->chown($data['new']['document_root'].'/ssl','root'); - $app->system->chgrp($data['new']['document_root'].'/ssl','root'); - $app->system->chown($data['new']['document_root'].'/tmp',$username); - $app->system->chgrp($data['new']['document_root'].'/tmp',$groupname); - $app->system->chown($data['new']['document_root'].'/web',$username); - $app->system->chgrp($data['new']['document_root'].'/web',$groupname); - $app->system->chown($data['new']['document_root'].'/web/error',$username); - $app->system->chgrp($data['new']['document_root'].'/web/error',$groupname); - $app->system->chown($data['new']['document_root'].'/web/stats',$username); - $app->system->chgrp($data['new']['document_root'].'/web/stats',$groupname); - //$app->system->chown($data['new']['document_root'].'/webdav',$username); - //$app->system->chgrp($data['new']['document_root'].'/webdav',$groupname); - } - } elseif(($this->action == 'insert' && $data['new']['type'] == 'vhostsubdomain') or ($web_config['set_folder_permissions_on_update'] == 'y' && $data['new']['type'] == 'vhostsubdomain')) { - if($web_config['security_level'] == 20) { - $app->system->chmod($data['new']['document_root'].'/' . $web_folder,0710); - $app->system->chown($data['new']['document_root'].'/' . $web_folder,$username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder,$groupname); - $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/error',$username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/error',$groupname); - $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/stats',$username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/stats',$groupname); - } else { - $app->system->chmod($data['new']['document_root'].'/' . $web_folder,0755); - $app->system->chown($data['new']['document_root'].'/' . $web_folder,$username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder,$groupname); - $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/error',$username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/error',$groupname); - $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/stats',$username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/stats',$groupname); - } - } - - //* Protect web folders - $app->system->web_folder_protection($data['new']['document_root'],true); - - if($data['new']['type'] == 'vhost') { - // Change the ownership of the error log to the root user - if(!@is_file('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log')) exec('touch '.escapeshellcmd('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log')); - $app->system->chown('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log','root'); - $app->system->chgrp('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log','root'); - } - - // Change the ownership of the error log to the owner of the website - /* - if(!@is_file($data['new']['document_root'].'/log/error.log')) exec('touch '.escapeshellcmd($data['new']['document_root']).'/log/error.log'); - $app->system->chown($data['new']['document_root'].'/log/error.log',$username); - $app->system->chgrp($data['new']['document_root'].'/log/error.log',$groupname); - */ - - - /* - //* Write the custom php.ini file, if custom_php_ini filed is not empty - $custom_php_ini_dir = $web_config['website_basedir'].'/conf/'.$data['new']['system_user']; - if(!is_dir($web_config['website_basedir'].'/conf')) mkdir($web_config['website_basedir'].'/conf'); - if(trim($data['new']['custom_php_ini']) != '') { - $has_custom_php_ini = true; - if(!is_dir($custom_php_ini_dir)) $app->system->mkdirpath($custom_php_ini_dir); - $php_ini_content = ''; - if($data['new']['php'] == 'mod') { - $master_php_ini_path = $web_config['php_ini_path_apache']; - } else { - if($data["new"]['php'] == 'fast-cgi' && file_exists($fastcgi_config["fastcgi_phpini_path"])) { - $master_php_ini_path = $fastcgi_config["fastcgi_phpini_path"]; - } else { - $master_php_ini_path = $web_config['php_ini_path_cgi']; - } - } - if($master_php_ini_path != '' && substr($master_php_ini_path,-7) == 'php.ini' && is_file($master_php_ini_path)) { - $php_ini_content .= $app->system->file_get_contents($master_php_ini_path)."\n"; - } - $php_ini_content .= str_replace("\r",'',trim($data['new']['custom_php_ini'])); - $app->system->file_put_contents($custom_php_ini_dir.'/php.ini',$php_ini_content); - } else { - $has_custom_php_ini = false; - if(is_file($custom_php_ini_dir.'/php.ini')) $app->system->unlink($custom_php_ini_dir.'/php.ini'); - } - */ - - //* Create the vhost config file - $app->load('tpl'); - - $tpl = new tpl(); - $tpl->newTemplate('nginx_vhost.conf.master'); - - $vhost_data = $data['new']; - //unset($vhost_data['ip_address']); - $vhost_data['web_document_root'] = $data['new']['document_root'].'/' . $web_folder; - $vhost_data['web_document_root_www'] = $web_config['website_basedir'].'/'.$data['new']['domain'].'/' . $web_folder; - $vhost_data['web_basedir'] = $web_config['website_basedir']; - - // IPv6 - if($data['new']['ipv6_address'] != ''){ - $tpl->setVar('ipv6_enabled', 1); - if ($conf['serverconfig']['web']['vhost_rewrite_v6'] == 'y') { - if (isset($conf['serverconfig']['server']['v6_prefix']) && $conf['serverconfig']['server']['v6_prefix'] <> '') { - $explode_v6prefix=explode(':',$conf['serverconfig']['server']['v6_prefix']); - $explode_v6=explode(':',$data['new']['ipv6_address']); - - for ( $i = 0; $i <= count($explode_v6prefix)-3; $i++ ) { - $explode_v6[$i] = $explode_v6prefix[$i]; - } - $data['new']['ipv6_address'] = implode(':',$explode_v6); - $vhost_data['ipv6_address'] = $data['new']['ipv6_address']; - } - } - } - - // PHP-FPM - // Support for multiple PHP versions - /* - if(trim($data['new']['fastcgi_php_version']) != ''){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir,-1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - */ - if($data['new']['php'] != 'no'){ - if(trim($data['new']['fastcgi_php_version']) != ''){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir,-1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - } else { - if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] != 'no'){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir,-1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - } - - if($default_php_fpm){ - $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']); - } else { - $pool_dir = $custom_php_fpm_pool_dir; - } - if(substr($pool_dir,-1) != '/') $pool_dir .= '/'; - $pool_name = 'web'.$data['new']['domain_id']; - $socket_dir = escapeshellcmd($web_config['php_fpm_socket_dir']); - if(substr($socket_dir,-1) != '/') $socket_dir .= '/'; - - if($data['new']['php_fpm_use_socket'] == 'y'){ - $use_tcp = 0; - $use_socket = 1; - } else { - $use_tcp = 1; - $use_socket = 0; - } - $tpl->setVar('use_tcp', $use_tcp); - $tpl->setVar('use_socket', $use_socket); - $fpm_socket = $socket_dir.$pool_name.'.sock'; - $tpl->setVar('fpm_socket', $fpm_socket); - $tpl->setVar('rnd_php_dummy_file', '/'.md5(uniqid(microtime(),1)).'.htm'); - $vhost_data['fpm_port'] = $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1; - - // backwards compatibility; since ISPConfig 3.0.5, the PHP mode for nginx is called 'php-fpm' instead of 'fast-cgi'. The following line makes sure that old web sites that have 'fast-cgi' in the database still get PHP-FPM support. - if($vhost_data['php'] == 'fast-cgi') $vhost_data['php'] = 'php-fpm'; - - // Custom rewrite rules - /* - $final_rewrite_rules = array(); - $custom_rewrite_rules = $data['new']['rewrite_rules']; - // Make sure we only have Unix linebreaks - $custom_rewrite_rules = str_replace("\r\n", "\n", $custom_rewrite_rules); - $custom_rewrite_rules = str_replace("\r", "\n", $custom_rewrite_rules); - $custom_rewrite_rule_lines = explode("\n", $custom_rewrite_rules); - if(is_array($custom_rewrite_rule_lines) && !empty($custom_rewrite_rule_lines)){ - foreach($custom_rewrite_rule_lines as $custom_rewrite_rule_line){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - } - } - $tpl->setLoop('rewrite_rules', $final_rewrite_rules); - */ - - // Custom rewrite rules - $final_rewrite_rules = array(); - - if(isset($data['new']['rewrite_rules']) && trim($data['new']['rewrite_rules']) != '') { - $custom_rewrite_rules = trim($data['new']['rewrite_rules']); - $custom_rewrites_are_valid = true; - // use this counter to make sure all curly brackets are properly closed - $if_level = 0; - // Make sure we only have Unix linebreaks - $custom_rewrite_rules = str_replace("\r\n", "\n", $custom_rewrite_rules); - $custom_rewrite_rules = str_replace("\r", "\n", $custom_rewrite_rules); - $custom_rewrite_rule_lines = explode("\n", $custom_rewrite_rules); - if(is_array($custom_rewrite_rule_lines) && !empty($custom_rewrite_rule_lines)){ - foreach($custom_rewrite_rule_lines as $custom_rewrite_rule_line){ - // ignore comments - if(substr(ltrim($custom_rewrite_rule_line),0,1) == '#'){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - // empty lines - if(trim($custom_rewrite_rule_line) == ''){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - // rewrite - if(preg_match('@^\s*rewrite\s+(^/)?\S+(\$)?\s+\S+(\s+(last|break|redirect|permanent|))?\s*;\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - // if - if(preg_match('@^\s*if\s+\(\s*\$\S+(\s+(\!?(=|~|~\*))\s+(\S+|\".+\"))?\s*\)\s*\{\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - $if_level += 1; - continue; - } - // if - check for files, directories, etc. - if(preg_match('@^\s*if\s+\(\s*\!?-(f|d|e|x)\s+\S+\s*\)\s*\{\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - $if_level += 1; - continue; - } - // break - if(preg_match('@^\s*break\s*;\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - // return code [ text ] - if(preg_match('@^\s*return\s+\d\d\d.*;\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - // return code URL - // return URL - if(preg_match('@^\s*return(\s+\d\d\d)?\s+(http|https|ftp)\://([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&%\$\-]+)*\@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|localhost|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(\:[0-9]+)*(/($|[a-zA-Z0-9\.\,\?\'\\\+&%\$#\=~_\-]+))*\s*;\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - // set - if(preg_match('@^\s*set\s+\$\S+\s+\S+\s*;\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - // closing curly bracket - if(trim($custom_rewrite_rule_line) == '}'){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - $if_level -= 1; - continue; - } - $custom_rewrites_are_valid = false; - break; - } - } - if(!$custom_rewrites_are_valid || $if_level != 0){ - $final_rewrite_rules = array(); - } - } - $tpl->setLoop('rewrite_rules', $final_rewrite_rules); - - // Custom nginx directives - $final_nginx_directives = array(); - $nginx_directives = $data['new']['nginx_directives']; - // Make sure we only have Unix linebreaks - $nginx_directives = str_replace("\r\n", "\n", $nginx_directives); - $nginx_directives = str_replace("\r", "\n", $nginx_directives); - $nginx_directive_lines = explode("\n", $nginx_directives); - if(is_array($nginx_directive_lines) && !empty($nginx_directive_lines)){ - foreach($nginx_directive_lines as $nginx_directive_line){ - $final_nginx_directives[] = array('nginx_directive' => $nginx_directive_line); - } - } - $tpl->setLoop('nginx_directives', $final_nginx_directives); - - // Check if a SSL cert exists - $ssl_dir = $data['new']['document_root'].'/ssl'; - $domain = $data['new']['ssl_domain']; - $key_file = $ssl_dir.'/'.$domain.'.key'; - $crt_file = $ssl_dir.'/'.$domain.'.crt'; - - if($domain!='' && $data['new']['ssl'] == 'y' && @is_file($crt_file) && @is_file($key_file) && (@filesize($crt_file)>0) && (@filesize($key_file)>0)) { - $vhost_data['ssl_enabled'] = 1; - $app->log('Enable SSL for: '.$domain,LOGLEVEL_DEBUG); - } else { - $vhost_data['ssl_enabled'] = 0; - $app->log('SSL Disabled. '.$domain,LOGLEVEL_DEBUG); - } - - // Set SEO Redirect - if($data['new']['seo_redirect'] != ''){ - $vhost_data['seo_redirect_enabled'] = 1; - $tmp_seo_redirects = $this->get_seo_redirects($data['new']); - if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ - foreach($tmp_seo_redirects as $key => $val){ - $vhost_data[$key] = $val; - } - } else { - $vhost_data['seo_redirect_enabled'] = 0; - } - } else { - $vhost_data['seo_redirect_enabled'] = 0; - } - - - - // Rewrite rules - $own_rewrite_rules = array(); - $rewrite_rules = array(); - $local_rewrite_rules = array(); - if($data['new']['redirect_type'] != '' && $data['new']['redirect_path'] != '') { - if(substr($data['new']['redirect_path'],-1) != '/') $data['new']['redirect_path'] .= '/'; - if(substr($data['new']['redirect_path'],0,8) == '[scheme]'){ - if($data['new']['redirect_type'] != 'proxy'){ - $data['new']['redirect_path'] = '$scheme'.substr($data['new']['redirect_path'],8); - } else { - $data['new']['redirect_path'] = 'http'.substr($data['new']['redirect_path'],8); - } - } - - // Custom proxy directives - if($data['new']['redirect_type'] == 'proxy' && trim($data['new']['proxy_directives'] != '')){ - $final_proxy_directives = array(); - $proxy_directives = $data['new']['proxy_directives']; - // Make sure we only have Unix linebreaks - $proxy_directives = str_replace("\r\n", "\n", $proxy_directives); - $proxy_directives = str_replace("\r", "\n", $proxy_directives); - $proxy_directive_lines = explode("\n", $proxy_directives); - if(is_array($proxy_directive_lines) && !empty($proxy_directive_lines)){ - foreach($proxy_directive_lines as $proxy_directive_line){ - $final_proxy_directives[] = array('proxy_directive' => $proxy_directive_line); - } - } - } else { - $final_proxy_directives = false; - } - - switch($data['new']['subdomain']) { - case 'www': - $exclude_own_hostname = ''; - if(substr($data['new']['redirect_path'],0,1) == '/'){ // relative path - if($data['new']['redirect_type'] == 'proxy'){ - $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; - $vhost_data['web_document_root_www'] .= substr($data['new']['redirect_path'],0,-1); - break; - } - $rewrite_exclude = '(?!/\b('.substr($data['new']['redirect_path'],1,-1).(substr($data['new']['redirect_path'],1,-1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').')\b)/'; - } else { // URL - check if URL is local - $tmp_redirect_path = $data['new']['redirect_path']; - if(substr($tmp_redirect_path,0,7) == '$scheme') $tmp_redirect_path = 'http'.substr($tmp_redirect_path,7); - $tmp_redirect_path_parts = parse_url($tmp_redirect_path); - if(($tmp_redirect_path_parts['host'] == $data['new']['domain'] || $tmp_redirect_path_parts['host'] == 'www.'.$data['new']['domain']) && ($tmp_redirect_path_parts['port'] == '80' || $tmp_redirect_path_parts['port'] == '443' || !isset($tmp_redirect_path_parts['port']))){ - // URL is local - if(substr($tmp_redirect_path_parts['path'],-1) == '/') $tmp_redirect_path_parts['path'] = substr($tmp_redirect_path_parts['path'],0,-1); - if(substr($tmp_redirect_path_parts['path'],0,1) != '/') $tmp_redirect_path_parts['path'] = '/'.$tmp_redirect_path_parts['path']; - //$rewrite_exclude = '((?!'.$tmp_redirect_path_parts['path'].'))'; - if($data['new']['redirect_type'] == 'proxy'){ - $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; - $vhost_data['web_document_root_www'] .= $tmp_redirect_path_parts['path']; - break; - } else { - $rewrite_exclude = '(?!/\b('.substr($tmp_redirect_path_parts['path'],1).(substr($tmp_redirect_path_parts['path'],1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').')\b)/'; - $exclude_own_hostname = $tmp_redirect_path_parts['host']; - } - } else { - // external URL - $rewrite_exclude = '(.?)/'; - if($data['new']['redirect_type'] == 'proxy'){ - $vhost_data['use_proxy'] = 'y'; - $rewrite_subdir = $tmp_redirect_path_parts['path']; - if(substr($rewrite_subdir,0,1) == '/') $rewrite_subdir = substr($rewrite_subdir,1); - if(substr($rewrite_subdir,-1) != '/') $rewrite_subdir .= '/'; - if($rewrite_subdir == '/') $rewrite_subdir = ''; - } - } - unset($tmp_redirect_path); - unset($tmp_redirect_path_parts); - } - $own_rewrite_rules[] = array( 'rewrite_domain' => '^'.$this->_rewrite_quote($data['new']['domain']), - 'rewrite_type' => ($data['new']['redirect_type'] == 'no')?'':$data['new']['redirect_type'], - 'rewrite_target' => $data['new']['redirect_path'], - 'rewrite_exclude' => $rewrite_exclude, - 'rewrite_subdir' => $rewrite_subdir, - 'exclude_own_hostname' => $exclude_own_hostname, - 'proxy_directives' => $final_proxy_directives, - 'use_rewrite' => ($data['new']['redirect_type'] == 'proxy' ? false:true), - 'use_proxy' => ($data['new']['redirect_type'] == 'proxy' ? true:false)); - break; - case '*': - $exclude_own_hostname = ''; - if(substr($data['new']['redirect_path'],0,1) == '/'){ // relative path - if($data['new']['redirect_type'] == 'proxy'){ - $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; - $vhost_data['web_document_root_www'] .= substr($data['new']['redirect_path'],0,-1); - break; - } - $rewrite_exclude = '(?!/\b('.substr($data['new']['redirect_path'],1,-1).(substr($data['new']['redirect_path'],1,-1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').')\b)/'; - } else { // URL - check if URL is local - $tmp_redirect_path = $data['new']['redirect_path']; - if(substr($tmp_redirect_path,0,7) == '$scheme') $tmp_redirect_path = 'http'.substr($tmp_redirect_path,7); - $tmp_redirect_path_parts = parse_url($tmp_redirect_path); - - //if($is_serveralias && ($tmp_redirect_path_parts['port'] == '80' || $tmp_redirect_path_parts['port'] == '443' || !isset($tmp_redirect_path_parts['port']))){ - if($this->url_is_local($tmp_redirect_path_parts['host'], $data['new']['domain_id']) && ($tmp_redirect_path_parts['port'] == '80' || $tmp_redirect_path_parts['port'] == '443' || !isset($tmp_redirect_path_parts['port']))){ - // URL is local - if(substr($tmp_redirect_path_parts['path'],-1) == '/') $tmp_redirect_path_parts['path'] = substr($tmp_redirect_path_parts['path'],0,-1); - if(substr($tmp_redirect_path_parts['path'],0,1) != '/') $tmp_redirect_path_parts['path'] = '/'.$tmp_redirect_path_parts['path']; - //$rewrite_exclude = '((?!'.$tmp_redirect_path_parts['path'].'))'; - if($data['new']['redirect_type'] == 'proxy'){ - $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; - $vhost_data['web_document_root_www'] .= $tmp_redirect_path_parts['path']; - break; - } else { - $rewrite_exclude = '(?!/\b('.substr($tmp_redirect_path_parts['path'],1).(substr($tmp_redirect_path_parts['path'],1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').')\b)/'; - $exclude_own_hostname = $tmp_redirect_path_parts['host']; - } - } else { - // external URL - $rewrite_exclude = '(.?)/'; - if($data['new']['redirect_type'] == 'proxy'){ - $vhost_data['use_proxy'] = 'y'; - $rewrite_subdir = $tmp_redirect_path_parts['path']; - if(substr($rewrite_subdir,0,1) == '/') $rewrite_subdir = substr($rewrite_subdir,1); - if(substr($rewrite_subdir,-1) != '/') $rewrite_subdir .= '/'; - if($rewrite_subdir == '/') $rewrite_subdir = ''; - } - } - unset($tmp_redirect_path); - unset($tmp_redirect_path_parts); - } - $own_rewrite_rules[] = array( 'rewrite_domain' => '(^|\.)'.$this->_rewrite_quote($data['new']['domain']), - 'rewrite_type' => ($data['new']['redirect_type'] == 'no')?'':$data['new']['redirect_type'], - 'rewrite_target' => $data['new']['redirect_path'], - 'rewrite_exclude' => $rewrite_exclude, - 'rewrite_subdir' => $rewrite_subdir, - 'exclude_own_hostname' => $exclude_own_hostname, - 'proxy_directives' => $final_proxy_directives, - 'use_rewrite' => ($data['new']['redirect_type'] == 'proxy' ? false:true), - 'use_proxy' => ($data['new']['redirect_type'] == 'proxy' ? true:false)); - break; - default: - if(substr($data['new']['redirect_path'],0,1) == '/'){ // relative path - $exclude_own_hostname = ''; - if($data['new']['redirect_type'] == 'proxy'){ - $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; - $vhost_data['web_document_root_www'] .= substr($data['new']['redirect_path'],0,-1); - break; - } - $rewrite_exclude = '(?!/\b('.substr($data['new']['redirect_path'],1,-1).(substr($data['new']['redirect_path'],1,-1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').')\b)/'; - } else { // URL - check if URL is local - $tmp_redirect_path = $data['new']['redirect_path']; - if(substr($tmp_redirect_path,0,7) == '$scheme') $tmp_redirect_path = 'http'.substr($tmp_redirect_path,7); - $tmp_redirect_path_parts = parse_url($tmp_redirect_path); - if($tmp_redirect_path_parts['host'] == $data['new']['domain'] && ($tmp_redirect_path_parts['port'] == '80' || $tmp_redirect_path_parts['port'] == '443' || !isset($tmp_redirect_path_parts['port']))){ - // URL is local - if(substr($tmp_redirect_path_parts['path'],-1) == '/') $tmp_redirect_path_parts['path'] = substr($tmp_redirect_path_parts['path'],0,-1); - if(substr($tmp_redirect_path_parts['path'],0,1) != '/') $tmp_redirect_path_parts['path'] = '/'.$tmp_redirect_path_parts['path']; - //$rewrite_exclude = '((?!'.$tmp_redirect_path_parts['path'].'))'; - if($data['new']['redirect_type'] == 'proxy'){ - $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; - $vhost_data['web_document_root_www'] .= $tmp_redirect_path_parts['path']; - break; - } else { - $rewrite_exclude = '(?!/\b('.substr($tmp_redirect_path_parts['path'],1).(substr($tmp_redirect_path_parts['path'],1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').')\b)/'; - $exclude_own_hostname = $tmp_redirect_path_parts['host']; - } - } else { - // external URL - $rewrite_exclude = '(.?)/'; - if($data['new']['redirect_type'] == 'proxy'){ - $vhost_data['use_proxy'] = 'y'; - $rewrite_subdir = $tmp_redirect_path_parts['path']; - if(substr($rewrite_subdir,0,1) == '/') $rewrite_subdir = substr($rewrite_subdir,1); - if(substr($rewrite_subdir,-1) != '/') $rewrite_subdir .= '/'; - if($rewrite_subdir == '/') $rewrite_subdir = ''; - } - } - unset($tmp_redirect_path); - unset($tmp_redirect_path_parts); - } - $own_rewrite_rules[] = array( 'rewrite_domain' => '^'.$this->_rewrite_quote($data['new']['domain']), - 'rewrite_type' => ($data['new']['redirect_type'] == 'no')?'':$data['new']['redirect_type'], - 'rewrite_target' => $data['new']['redirect_path'], - 'rewrite_exclude' => $rewrite_exclude, - 'rewrite_subdir' => $rewrite_subdir, - 'exclude_own_hostname' => $exclude_own_hostname, - 'proxy_directives' => $final_proxy_directives, - 'use_rewrite' => ($data['new']['redirect_type'] == 'proxy' ? false:true), - 'use_proxy' => ($data['new']['redirect_type'] == 'proxy' ? true:false)); - } - } - - $tpl->setVar($vhost_data); - - $server_alias = array(); - - // get autoalias - $auto_alias = $web_config['website_autoalias']; - if($auto_alias != '') { - // get the client username - $client = $app->db->queryOneRecord("SELECT `username` FROM `client` WHERE `client_id` = '" . intval($client_id) . "'"); - $aa_search = array('[client_id]', '[website_id]', '[client_username]', '[website_domain]'); - $aa_replace = array($client_id, $data['new']['domain_id'], $client['username'], $data['new']['domain']); - $auto_alias = str_replace($aa_search, $aa_replace, $auto_alias); - unset($client); - unset($aa_search); - unset($aa_replace); - $server_alias[] .= $auto_alias.' '; - } - - switch($data['new']['subdomain']) { - case 'www': - $server_alias[] = 'www.'.$data['new']['domain'].' '; - break; - case '*': - $server_alias[] = '*.'.$data['new']['domain'].' '; - break; - } - - // get alias domains (co-domains and subdomains) - $aliases = $app->db->queryAllRecords('SELECT * FROM web_domain WHERE parent_domain_id = '.$data['new']['domain_id']." AND active = 'y' AND type != 'vhostsubdomain'"); - $alias_seo_redirects = array(); - if(is_array($aliases)) { - foreach($aliases as $alias) { - - // Custom proxy directives - if($alias['redirect_type'] == 'proxy' && trim($alias['proxy_directives'] != '')){ - $final_proxy_directives = array(); - $proxy_directives = $alias['proxy_directives']; - // Make sure we only have Unix linebreaks - $proxy_directives = str_replace("\r\n", "\n", $proxy_directives); - $proxy_directives = str_replace("\r", "\n", $proxy_directives); - $proxy_directive_lines = explode("\n", $proxy_directives); - if(is_array($proxy_directive_lines) && !empty($proxy_directive_lines)){ - foreach($proxy_directive_lines as $proxy_directive_line){ - $final_proxy_directives[] = array('proxy_directive' => $proxy_directive_line); - } - } - } else { - $final_proxy_directives = false; - } - - if($alias['redirect_type'] == '' || $alias['redirect_path'] == '' || substr($alias['redirect_path'],0,1) == '/') { - switch($alias['subdomain']) { - case 'www': - $server_alias[] = 'www.'.$alias['domain'].' '.$alias['domain'].' '; - break; - case '*': - $server_alias[] = '*.'.$alias['domain'].' '.$alias['domain'].' '; - break; - default: - $server_alias[] = $alias['domain'].' '; - break; - } - $app->log('Add server alias: '.$alias['domain'],LOGLEVEL_DEBUG); - - // Add SEO redirects for alias domains - if($alias['seo_redirect'] != '' && $data['new']['seo_redirect'] != '*_to_www_domain_tld' && $data['new']['seo_redirect'] != '*_to_domain_tld' && ($alias['type'] == 'alias' || ($alias['type'] == 'subdomain' && $data['new']['seo_redirect'] != '*_domain_tld_to_www_domain_tld' && $data['new']['seo_redirect'] != '*_domain_tld_to_domain_tld'))){ - $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_'); - if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ - $alias_seo_redirects[] = $tmp_seo_redirects; - } - } - } - - // Local Rewriting (inside vhost server {} container) - if($alias['redirect_type'] != '' && substr($alias['redirect_path'],0,1) == '/' && $alias['redirect_type'] != 'proxy') { // proxy makes no sense with local path - if(substr($alias['redirect_path'],-1) != '/') $alias['redirect_path'] .= '/'; - $rewrite_exclude = '(?!/\b('.substr($alias['redirect_path'],1,-1).(substr($alias['redirect_path'],1,-1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').')\b)/'; - switch($alias['subdomain']) { - case 'www': - // example.com - $local_rewrite_rules[] = array( 'local_redirect_origin_domain' => $alias['domain'], - 'local_redirect_operator' => '=', - 'local_redirect_exclude' => $rewrite_exclude, - 'local_redirect_target' => $alias['redirect_path'], - 'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']); - - // www.example.com - $local_rewrite_rules[] = array( 'local_redirect_origin_domain' => 'www.'.$alias['domain'], - 'local_redirect_operator' => '=', - 'local_redirect_exclude' => $rewrite_exclude, - 'local_redirect_target' => $alias['redirect_path'], - 'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']); - break; - case '*': - $local_rewrite_rules[] = array( 'local_redirect_origin_domain' => '^('.str_replace('.', '\.', $alias['domain']).'|.+\.'.str_replace('.', '\.', $alias['domain']).')$', - 'local_redirect_operator' => '~*', - 'local_redirect_exclude' => $rewrite_exclude, - 'local_redirect_target' => $alias['redirect_path'], - 'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']); - break; - default: - $local_rewrite_rules[] = array( 'local_redirect_origin_domain' => $alias['domain'], - 'local_redirect_operator' => '=', - 'local_redirect_exclude' => $rewrite_exclude, - 'local_redirect_target' => $alias['redirect_path'], - 'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']); - } - } - - // External Rewriting (extra server {} containers) - if($alias['redirect_type'] != '' && $alias['redirect_path'] != '' && substr($alias['redirect_path'],0,1) != '/') { - if(substr($alias['redirect_path'],-1) != '/') $alias['redirect_path'] .= '/'; - if(substr($alias['redirect_path'],0,8) == '[scheme]'){ - if($alias['redirect_type'] != 'proxy'){ - $alias['redirect_path'] = '$scheme'.substr($alias['redirect_path'],8); - } else { - $alias['redirect_path'] = 'http'.substr($alias['redirect_path'],8); - } - } - - switch($alias['subdomain']) { - case 'www': - if($alias['redirect_type'] == 'proxy'){ - $tmp_redirect_path = $alias['redirect_path']; - $tmp_redirect_path_parts = parse_url($tmp_redirect_path); - $rewrite_subdir = $tmp_redirect_path_parts['path']; - if(substr($rewrite_subdir,0,1) == '/') $rewrite_subdir = substr($rewrite_subdir,1); - if(substr($rewrite_subdir,-1) != '/') $rewrite_subdir .= '/'; - if($rewrite_subdir == '/') $rewrite_subdir = ''; - } - - if($alias['redirect_type'] != 'proxy'){ - if(substr($alias['redirect_path'],-1) == '/') $alias['redirect_path'] = substr($alias['redirect_path'],0,-1); - } - // Add SEO redirects for alias domains - $alias_seo_redirects2 = array(); - if($alias['seo_redirect'] != ''){ - $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', 'none'); - if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ - $alias_seo_redirects2[] = $tmp_seo_redirects; - } - } - $rewrite_rules[] = array( 'rewrite_domain' => $alias['domain'], - 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type'], - 'rewrite_target' => $alias['redirect_path'], - 'rewrite_subdir' => $rewrite_subdir, - 'proxy_directives' => $final_proxy_directives, - 'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true), - 'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false), - 'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false)); - - // Add SEO redirects for alias domains - $alias_seo_redirects2 = array(); - if($alias['seo_redirect'] != ''){ - $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', 'www'); - if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ - $alias_seo_redirects2[] = $tmp_seo_redirects; - } - } - $rewrite_rules[] = array( 'rewrite_domain' => 'www.'.$alias['domain'], - 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type'], - 'rewrite_target' => $alias['redirect_path'], - 'rewrite_subdir' => $rewrite_subdir, - 'proxy_directives' => $final_proxy_directives, - 'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true), - 'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false), - 'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false)); - break; - case '*': - if($alias['redirect_type'] == 'proxy'){ - $tmp_redirect_path = $alias['redirect_path']; - $tmp_redirect_path_parts = parse_url($tmp_redirect_path); - $rewrite_subdir = $tmp_redirect_path_parts['path']; - if(substr($rewrite_subdir,0,1) == '/') $rewrite_subdir = substr($rewrite_subdir,1); - if(substr($rewrite_subdir,-1) != '/') $rewrite_subdir .= '/'; - if($rewrite_subdir == '/') $rewrite_subdir = ''; - } - - if($alias['redirect_type'] != 'proxy'){ - if(substr($alias['redirect_path'],-1) == '/') $alias['redirect_path'] = substr($alias['redirect_path'],0,-1); - } - // Add SEO redirects for alias domains - $alias_seo_redirects2 = array(); - if($alias['seo_redirect'] != ''){ - $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_'); - if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ - $alias_seo_redirects2[] = $tmp_seo_redirects; - } - } - $rewrite_rules[] = array( 'rewrite_domain' => $alias['domain'].' *.'.$alias['domain'], - 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type'], - 'rewrite_target' => $alias['redirect_path'], - 'rewrite_subdir' => $rewrite_subdir, - 'proxy_directives' => $final_proxy_directives, - 'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true), - 'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false), - 'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false)); - break; - default: - if($alias['redirect_type'] == 'proxy'){ - $tmp_redirect_path = $alias['redirect_path']; - $tmp_redirect_path_parts = parse_url($tmp_redirect_path); - $rewrite_subdir = $tmp_redirect_path_parts['path']; - if(substr($rewrite_subdir,0,1) == '/') $rewrite_subdir = substr($rewrite_subdir,1); - if(substr($rewrite_subdir,-1) != '/') $rewrite_subdir .= '/'; - if($rewrite_subdir == '/') $rewrite_subdir = ''; - } - - if($alias['redirect_type'] != 'proxy'){ - if(substr($alias['redirect_path'],-1) == '/') $alias['redirect_path'] = substr($alias['redirect_path'],0,-1); - } - if(substr($alias['domain'], 0, 2) === '*.') $domain_rule = '*.'.substr($alias['domain'], 2); - else $domain_rule = $alias['domain']; - // Add SEO redirects for alias domains - $alias_seo_redirects2 = array(); - if($alias['seo_redirect'] != ''){ - if(substr($alias['domain'], 0, 2) === '*.'){ - $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_'); - } else { - $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', 'none'); - } - if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ - $alias_seo_redirects2[] = $tmp_seo_redirects; - } - } - $rewrite_rules[] = array( 'rewrite_domain' => $domain_rule, - 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type'], - 'rewrite_target' => $alias['redirect_path'], - 'rewrite_subdir' => $rewrite_subdir, - 'proxy_directives' => $final_proxy_directives, - 'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true), - 'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false), - 'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false)); - } - } - } - } - - //* If we have some alias records - if(count($server_alias) > 0) { - $server_alias_str = ''; - $n = 0; - - foreach($server_alias as $tmp_alias) { - $server_alias_str .= $tmp_alias; - } - unset($tmp_alias); - - $tpl->setVar('alias',trim($server_alias_str)); - } else { - $tpl->setVar('alias',''); - } - - if(count($rewrite_rules) > 0) { - $tpl->setLoop('redirects',$rewrite_rules); - } - if(count($own_rewrite_rules) > 0) { - $tpl->setLoop('own_redirects',$own_rewrite_rules); - } - if(count($local_rewrite_rules) > 0) { - $tpl->setLoop('local_redirects',$local_rewrite_rules); - } - if(count($alias_seo_redirects) > 0) { - $tpl->setLoop('alias_seo_redirects',$alias_seo_redirects); - } - - //* Create basic http auth for website statistics - $tpl->setVar('stats_auth_passwd_file', $data['new']['document_root']."/web/stats/.htpasswd_stats"); - - // Create basic http auth for other directories - $basic_auth_locations = $this->_create_web_folder_auth_configuration($data['new']); - if(is_array($basic_auth_locations) && !empty($basic_auth_locations)) $tpl->setLoop('basic_auth_locations', $basic_auth_locations); - - $vhost_file = escapeshellcmd($web_config['nginx_vhost_conf_dir'].'/'.$data['new']['domain'].'.vhost'); - //* Make a backup copy of vhost file - if(file_exists($vhost_file)) copy($vhost_file,$vhost_file.'~'); - - //* Write vhost file - $app->system->file_put_contents($vhost_file,$this->nginx_merge_locations($tpl->grab())); - $app->log('Writing the vhost file: '.$vhost_file,LOGLEVEL_DEBUG); - unset($tpl); - - //* Set the symlink to enable the vhost - //* First we check if there is a old type of symlink and remove it - $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/'.$data['new']['domain'].'.vhost'); - if(is_link($vhost_symlink)) unlink($vhost_symlink); - - //* Remove old or changed symlinks - if($data['new']['subdomain'] != $data['old']['subdomain'] or $data['new']['active'] == 'n') { - $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/900-'.$data['new']['domain'].'.vhost'); - if(is_link($vhost_symlink)) { - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG); - } - $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/100-'.$data['new']['domain'].'.vhost'); - if(is_link($vhost_symlink)) { - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG); - } - } - - //* New symlink - if($data['new']['subdomain'] == '*') { - $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/900-'.$data['new']['domain'].'.vhost'); - } else { - $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/100-'.$data['new']['domain'].'.vhost'); - } - if($data['new']['active'] == 'y' && !is_link($vhost_symlink)) { - symlink($vhost_file,$vhost_symlink); - $app->log('Creating symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG); - } - - // remove old symlink and vhost file, if domain name of the site has changed - if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) { - $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost'); - if(is_link($vhost_symlink)) { - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG); - } - $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost'); - if(is_link($vhost_symlink)) { - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG); - } - $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost'); - if(is_link($vhost_symlink)) { - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG); - } - $vhost_file = escapeshellcmd($web_config['nginx_vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost'); - $app->system->unlink($vhost_file); - $app->log('Removing file: '.$vhost_file,LOGLEVEL_DEBUG); - } - - // create password file for stats directory - if(!is_file($data['new']['document_root'].'/web/stats/.htpasswd_stats') || $data['new']['stats_password'] != $data['old']['stats_password']) { - if(trim($data['new']['stats_password']) != '') { - $htp_file = 'admin:'.trim($data['new']['stats_password']); - $app->system->file_put_contents($data['new']['document_root'].'/web/stats/.htpasswd_stats',$htp_file); - $app->system->chmod($data['new']['document_root'].'/web/stats/.htpasswd_stats',0755); - unset($htp_file); - } - } - - //* Create awstats configuration - if($data['new']['stats_type'] == 'awstats' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain')) { - $this->awstats_update($data,$web_config); - } - - $this->php_fpm_pool_update($data,$web_config,$pool_dir,$pool_name,$socket_dir); - - if($web_config['check_apache_config'] == 'y') { - //* Test if nginx starts with the new configuration file - $nginx_online_status_before_restart = $this->_checkTcp('localhost',80); - $app->log('nginx status is: '.($nginx_online_status_before_restart === true? 'running' : 'down'),LOGLEVEL_DEBUG); - - $retval = $app->services->restartService('httpd','restart'); // $retval['retval'] is 0 on success and > 0 on failure - $app->log('nginx restart return value is: '.$retval['retval'],LOGLEVEL_DEBUG); - - // wait a few seconds, before we test the apache status again - sleep(2); - - //* Check if nginx restarted successfully if it was online before - $nginx_online_status_after_restart = $this->_checkTcp('localhost',80); - $app->log('nginx online status after restart is: '.($nginx_online_status_after_restart === true? 'running' : 'down'),LOGLEVEL_DEBUG); - if($nginx_online_status_before_restart && !$nginx_online_status_after_restart || $retval['retval'] > 0) { - $app->log('nginx did not restart after the configuration change for website '.$data['new']['domain'].'. Reverting the configuration. Saved non-working config as '.$vhost_file.'.err',LOGLEVEL_WARN); - if(is_array($retval['output']) && !empty($retval['output'])){ - $app->log('Reason for nginx restart failure: '.implode("\n", $retval['output']),LOGLEVEL_WARN); - $app->dbmaster->datalogError(implode("\n", $retval['output'])); - } else { - // if no output is given, check again - exec('nginx -t 2>&1', $tmp_output, $tmp_retval); - if($tmp_retval > 0 && is_array($tmp_output) && !empty($tmp_output)){ - $app->log('Reason for nginx restart failure: '.implode("\n", $tmp_output),LOGLEVEL_WARN); - $app->dbmaster->datalogError(implode("\n", $tmp_output)); - } - unset($tmp_output, $tmp_retval); - } - $app->system->copy($vhost_file,$vhost_file.'.err'); - - if(is_file($vhost_file.'~')) { - //* Copy back the last backup file - $app->system->copy($vhost_file.'~',$vhost_file); - } else { - //* There is no backup file, so we create a empty vhost file with a warning message inside - $app->system->file_put_contents($vhost_file,"# nginx did not start after modifying this vhost file.\n# Please check file $vhost_file.err for syntax errors."); - } - - if($this->ssl_certificate_changed === true) { - - $ssl_dir = $data['new']['document_root'].'/ssl'; - $domain = $data['new']['ssl_domain']; - $key_file = $ssl_dir.'/'.$domain.'.key.org'; - $key_file2 = $ssl_dir.'/'.$domain.'.key'; - $csr_file = $ssl_dir.'/'.$domain.'.csr'; - $crt_file = $ssl_dir.'/'.$domain.'.crt'; - //$bundle_file = $ssl_dir.'/'.$domain.'.bundle'; - - //* Backup the files that might have caused the error - if(is_file($key_file)){ - $app->system->copy($key_file,$key_file.'.err'); - $app->system->chmod($key_file.'.err',0400); - } - if(is_file($key_file2)){ - $app->system->copy($key_file2,$key_file2.'.err'); - $app->system->chmod($key_file2.'.err',0400); - } - if(is_file($csr_file)) $app->system->copy($csr_file,$csr_file.'.err'); - if(is_file($crt_file)) $app->system->copy($crt_file,$crt_file.'.err'); - //if(is_file($bundle_file)) $app->system->copy($bundle_file,$bundle_file.'.err'); - - //* Restore the ~ backup files - if(is_file($key_file.'~')) $app->system->copy($key_file.'~',$key_file); - if(is_file($key_file2.'~')) $app->system->copy($key_file2.'~',$key_file2); - if(is_file($crt_file.'~')) $app->system->copy($crt_file.'~',$crt_file); - if(is_file($csr_file.'~')) $app->system->copy($csr_file.'~',$csr_file); - //if(is_file($bundle_file.'~')) $app->system->copy($bundle_file.'~',$bundle_file); - - $app->log('nginx did not restart after the configuration change for website '.$data['new']['domain'].' Reverting the SSL configuration. Saved non-working SSL files with .err extension.',LOGLEVEL_WARN); - } - - $app->services->restartService('httpd','restart'); - } - } else { - //* We do not check the nginx config after changes (is faster) - $app->services->restartServiceDelayed('httpd','reload'); - } - - //* The vhost is written and apache has been restarted, so we - // can reset the ssl changed var to false and cleanup some files - $this->ssl_certificate_changed = false; - - $ssl_dir = $data['new']['document_root'].'/ssl'; - $domain = $data['new']['ssl_domain']; - $key_file = $ssl_dir.'/'.$domain.'.key.org'; - $key_file2 = $ssl_dir.'/'.$domain.'.key'; - $csr_file = $ssl_dir.'/'.$domain.'.csr'; - $crt_file = $ssl_dir.'/'.$domain.'.crt'; - //$bundle_file = $ssl_dir.'/'.$domain.'.bundle'; - - if(@is_file($key_file.'~')) $app->system->unlink($key_file.'~'); - if(@is_file($key2_file.'~')) $app->system->unlink($key2_file.'~'); - if(@is_file($crt_file.'~')) $app->system->unlink($crt_file.'~'); - if(@is_file($csr_file.'~')) $app->system->unlink($csr_file.'~'); - //if(@is_file($bundle_file.'~')) $app->system->unlink($bundle_file.'~'); - - // Remove the backup copy of the config file. - if(@is_file($vhost_file.'~')) $app->system->unlink($vhost_file.'~'); - - //* Unset action to clean it for next processed vhost. - $this->action = ''; - - } - - function delete($event_name,$data) { - global $app, $conf; - - // load the server configuration options - $app->uses('getconf'); - $app->uses('system'); - $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); - - if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain') $app->system->web_folder_protection($data['old']['document_root'],false); - - //* Check if this is a chrooted setup - if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) { - $nginx_chrooted = true; - } else { - $nginx_chrooted = false; - } - - //* Remove the mounts - $log_folder = 'log'; - $web_folder = ''; - if($data['old']['type'] == 'vhostsubdomain') { - $tmp = $app->db->queryOneRecord('SELECT `domain`,`document_root` FROM web_domain WHERE domain_id = '.intval($data['old']['parent_domain_id'])); - if($tmp['domain'] != ''){ - $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['old']['domain']); - } else { - // get log folder from /etc/fstab - /* - $bind_mounts = $app->system->file_get_contents('/etc/fstab'); - $bind_mount_lines = explode("\n", $bind_mounts); - if(is_array($bind_mount_lines) && !empty($bind_mount_lines)){ - foreach($bind_mount_lines as $bind_mount_line){ - $bind_mount_line = preg_replace('/\s+/', ' ', $bind_mount_line); - $bind_mount_parts = explode(' ', $bind_mount_line); - if(is_array($bind_mount_parts) && !empty($bind_mount_parts)){ - if($bind_mount_parts[0] == '/var/log/ispconfig/httpd/'.$data['old']['domain'] && $bind_mount_parts[2] == 'none' && strpos($bind_mount_parts[3], 'bind') !== false){ - $subdomain_host = str_replace($data['old']['document_root'].'/log/', '', $bind_mount_parts[1]); - } - } - } - } - */ - // we are deleting the parent domain, so we can delete everything in the log directory - $subdomain_hosts = array(); - $files = array_diff(scandir($data['old']['document_root'].'/'.$log_folder), array('.','..')); - if(is_array($files) && !empty($files)){ - foreach($files as $file){ - if(is_dir($data['old']['document_root'].'/'.$log_folder.'/'.$file)){ - $subdomain_hosts[] = $file; - } - } - } - } - if(is_array($subdomain_hosts) && !empty($subdomain_hosts)){ - $log_folders = array(); - foreach($subdomain_hosts as $subdomain_host){ - $log_folders[] = $log_folder.'/'.$subdomain_host; - } - } else { - if($subdomain_host == '') $subdomain_host = 'web'.$data['old']['domain_id']; - $log_folder .= '/' . $subdomain_host; - } - $web_folder = $data['old']['web_folder']; - unset($tmp); - unset($subdomain_hosts); - } - - if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain'){ - if(is_array($log_folders) && !empty($log_folders)){ - foreach($log_folders as $log_folder){ - //if($app->system->is_mounted($data['old']['document_root'].'/'.$log_folder)) exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder)); - exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null'); - } - } else { - //if($app->system->is_mounted($data['old']['document_root'].'/'.$log_folder)) exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder)); - exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null'); - } - } - - //* remove mountpoint from fstab - if(is_array($log_folders) && !empty($log_folders)){ - foreach($log_folders as $log_folder){ - $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.' none bind'; - $app->system->removeLine('/etc/fstab',$fstab_line); - } - } else { - $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.' none bind'; - $app->system->removeLine('/etc/fstab',$fstab_line); - } - unset($log_folders); - - if($data['old']['type'] != 'vhost' && $data['old']['type'] != 'vhostsubdomain' && $data['old']['parent_domain_id'] > 0) { - //* This is a alias domain or subdomain, so we have to update the website instead - $parent_domain_id = intval($data['old']['parent_domain_id']); - $tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = '.$parent_domain_id." AND active = 'y'"); - $data['new'] = $tmp; - $data['old'] = $tmp; - $this->action = 'update'; - // just run the update function - $this->update($event_name,$data); - - } else { - //* This is a website - // Deleting the vhost file, symlink and the data directory - $vhost_file = escapeshellcmd($web_config['nginx_vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost'); - - $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost'); - if(is_link($vhost_symlink)){ - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG); - } - $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost'); - if(is_link($vhost_symlink)){ - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG); - } - $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost'); - if(is_link($vhost_symlink)){ - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG); - } - - $app->system->unlink($vhost_file); - $app->log('Removing vhost file: '.$vhost_file,LOGLEVEL_DEBUG); - - if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain') { - $docroot = escapeshellcmd($data['old']['document_root']); - if($docroot != '' && !stristr($docroot,'..')) { - if($data['old']['type'] == 'vhost') { - // this is a vhost - we delete everything in here. - exec('rm -rf '.$docroot); - } elseif(!stristr($data['old']['web_folder'], '..')) { - // this is a vhost subdomain - // IMPORTANT: do some folder checks before we delete this! - $do_delete = true; - $delete_folder = preg_replace('/[\/]{2,}/', '/', $web_folder); // replace / occuring multiple times - if(substr($delete_folder, 0, 1) === '/') $delete_folder = substr($delete_folder, 1); - if(substr($delete_folder, -1) === '/') $delete_folder = substr($delete_folder, 0, -1); - - $path_elements = explode('/', $delete_folder); - - if($path_elements[0] == 'web' || $path_elements[0] === '') { - // paths beginning with /web should NEVER EVER be deleted, empty paths should NEVER occur - but for safety reasons we check it here! - // we use strict check as otherwise directories named '0' may not be deleted - $do_delete = false; - } else { - // read all vhost subdomains with same parent domain - $used_paths = array(); - $tmp = $app->db->queryAllRecords("SELECT `web_folder` FROM web_domain WHERE type = 'vhostsubdomain' AND parent_domain_id = ".intval($data['old']['parent_domain_id'])." AND domain_id != ".intval($data['old']['domain_id'])); - foreach($tmp as $tmprec) { - // we normalize the folder entries because we need to compare them - $tmp_folder = preg_replace('/[\/]{2,}/', '/', $tmprec['web_folder']); // replace / occuring multiple times - if(substr($tmp_folder, 0, 1) === '/') $tmp_folder = substr($tmp_folder, 1); - if(substr($tmp_folder, -1) === '/') $tmp_folder = substr($tmp_folder, 0, -1); - - // add this path and it's parent paths to used_paths array - while(strpos($tmp_folder, '/') !== false) { - if(in_array($tmp_folder, $used_paths) == false) $used_paths[] = $tmp_folder; - $tmp_folder = substr($tmp_folder, 0, strrpos($tmp_folder, '/')); - } - if(in_array($tmp_folder, $used_paths) == false) $used_paths[] = $tmp_folder; - } - unset($tmp); - - // loop and check if the path is still used and stop at first used one - // set do_delete to false so nothing gets deleted if the web_folder itself is still used - $do_delete = false; - while(count($path_elements) > 0) { - $tmp_folder = implode('/', $path_elements); - if(in_array($tmp_folder, $used_paths) == true) break; - - // this path is not used - set it as path to delete, strip the last element from the array and set do_delete to true - $delete_folder = $tmp_folder; - $do_delete = true; - array_pop($path_elements); - } - unset($tmp_folder); - unset($used_paths); - } - - if($do_delete === true && $delete_folder !== '') exec('rm -rf '.$docroot.'/'.$delete_folder); - - unset($delete_folder); - unset($path_elements); - } - } - - //remove the php fastgi starter script if available - if ($data['old']['php'] == 'fast-cgi') { - $this->php_fpm_pool_delete($data,$web_config); - $fastcgi_starter_path = str_replace('[system_user]',$data['old']['system_user'],$web_config['fastcgi_starter_path']); - if($data['old']['type'] == 'vhost') { - if (is_dir($fastcgi_starter_path)) { - exec('rm -rf '.$fastcgi_starter_path); - } - } else { - $fcgi_starter_script = $fastcgi_starter_path.$web_config['fastcgi_starter_script'].'_web'.$data['old']['domain_id']; - if (file_exists($fcgi_starter_script)) { - exec('rm -f '.$fcgi_starter_script); - } - } - } - - // remove PHP-FPM pool - if ($data['old']['php'] == 'php-fpm') { - $this->php_fpm_pool_delete($data,$web_config); - } - - //remove the php cgi starter script if available - if ($data['old']['php'] == 'cgi') { - // TODO: fetch the date from the server-settings - $web_config['cgi_starter_path'] = $web_config['website_basedir'].'/php-cgi-scripts/[system_user]/'; - - $cgi_starter_path = str_replace('[system_user]',$data['old']['system_user'],$web_config['cgi_starter_path']); - if($data['old']['type'] == 'vhost') { - if (is_dir($cgi_starter_path)) { - exec('rm -rf '.$cgi_starter_path); - } - } else { - $cgi_starter_script = $cgi_starter_path.'php-cgi-starter_web'.$data['old']['domain_id']; - if (file_exists($cgi_starter_script)) { - exec('rm -f '.$cgi_starter_script); - } - } - } - - $app->log('Removing website: '.$docroot,LOGLEVEL_DEBUG); - - // Delete the symlinks for the sites - $client = $app->db->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = '.intval($data['old']['sys_groupid'])); - $client_id = intval($client['client_id']); - unset($client); - $tmp_symlinks_array = explode(':',$web_config['website_symlinks']); - if(is_array($tmp_symlinks_array)) { - foreach($tmp_symlinks_array as $tmp_symlink) { - $tmp_symlink = str_replace('[client_id]',$client_id,$tmp_symlink); - $tmp_symlink = str_replace('[website_domain]',$data['old']['domain'],$tmp_symlink); - // Remove trailing slash - if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); - // create the symlinks, if not exist - if(is_link($tmp_symlink)) { - $app->system->unlink($tmp_symlink); - $app->log('Removing symlink: '.$tmp_symlink,LOGLEVEL_DEBUG); - } - } - } - // end removing symlinks - } else { - // vhost subdomain - } - - // Delete the log file directory - $vhost_logfile_dir = escapeshellcmd('/var/log/ispconfig/httpd/'.$data['old']['domain']); - if($data['old']['domain'] != '' && !stristr($vhost_logfile_dir,'..')) exec('rm -rf '.$vhost_logfile_dir); - $app->log('Removing website logfile directory: '.$vhost_logfile_dir,LOGLEVEL_DEBUG); - - if($data['old']['type'] == 'vhost') { - //delete the web user - $command = 'killall -u '.escapeshellcmd($data['old']['system_user']).' ; userdel'; - $command .= ' '.escapeshellcmd($data['old']['system_user']); - exec($command); - if($nginx_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command); - - } - - //* Remove the awstats configuration file - if($data['old']['stats_type'] == 'awstats') { - $this->awstats_delete($data,$web_config); - } - - $app->services->restartServiceDelayed('httpd','reload'); - - } - - - if($data['old']['type'] != 'vhost') $app->system->web_folder_protection($data['old']['document_root'],true); - } - - //* This function is called when a IP on the server is inserted, updated or deleted - function server_ip($event_name,$data) { - return; - } - - //* Create or update the .htaccess folder protection - function web_folder_user($event_name,$data) { - global $app, $conf; - - $app->uses('system'); - - if($event_name == 'web_folder_user_delete') { - $folder_id = $data['old']['web_folder_id']; - } else { - $folder_id = $data['new']['web_folder_id']; - } - - $folder = $app->db->queryOneRecord("SELECT * FROM web_folder WHERE web_folder_id = ".intval($folder_id)); - $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($folder['parent_domain_id'])); - - if(!is_array($folder) or !is_array($website)) { - $app->log('Not able to retrieve folder or website record.',LOGLEVEL_DEBUG); - return false; - } - - $web_folder = 'web'; - if($website['type'] == 'vhostsubdomain') $web_folder = $website['web_folder']; - - //* Get the folder path. - if(substr($folder['path'],0,1) == '/') $folder['path'] = substr($folder['path'],1); - if(substr($folder['path'],-1) == '/') $folder['path'] = substr($folder['path'],0,-1); - $folder_path = escapeshellcmd($website['document_root'].'/' . $web_folder . '/'.$folder['path']); - if(substr($folder_path,-1) != '/') $folder_path .= '/'; - - //* Check if the resulting path is inside the docroot - if(stristr($folder_path,'..') || stristr($folder_path,'./') || stristr($folder_path,'\\')) { - $app->log('Folder path "'.$folder_path.'" contains .. or ./.',LOGLEVEL_DEBUG); - return false; - } - - //* Create the folder path, if it does not exist - if(!is_dir($folder_path)) { - $app->system->mkdirpath($folder_path); - $app->system->chown($folder_path,$website['system_user']); - $app->system->chgrp($folder_path,$website['system_group']); - } - - //* Create empty .htpasswd file, if it does not exist - if(!is_file($folder_path.'.htpasswd')) { - touch($folder_path.'.htpasswd'); - $app->system->chmod($folder_path.'.htpasswd',0755); - $app->system->chown($folder_path.'.htpasswd',$website['system_user']); - $app->system->chgrp($folder_path.'.htpasswd',$website['system_group']); - $app->log('Created file '.$folder_path.'.htpasswd',LOGLEVEL_DEBUG); - } - - /* - $auth_users = $app->db->queryAllRecords("SELECT * FROM web_folder_user WHERE active = 'y' AND web_folder_id = ".intval($folder_id)); - $htpasswd_content = ''; - if(is_array($auth_users) && !empty($auth_users)){ - foreach($auth_users as $auth_user){ - $htpasswd_content .= $auth_user['username'].':'.$auth_user['password']."\n"; - } - } - $htpasswd_content = trim($htpasswd_content); - @file_put_contents($folder_path.'.htpasswd', $htpasswd_content); - $app->log('Changed .htpasswd file: '.$folder_path.'.htpasswd',LOGLEVEL_DEBUG); - */ - - if(($data['new']['username'] != $data['old']['username'] || $data['new']['active'] == 'n') && $data['old']['username'] != '') { - $app->system->removeLine($folder_path.'.htpasswd',$data['old']['username'].':'); - $app->log('Removed user: '.$data['old']['username'],LOGLEVEL_DEBUG); - } - - //* Add or remove the user from .htpasswd file - if($event_name == 'web_folder_user_delete') { - $app->system->removeLine($folder_path.'.htpasswd',$data['old']['username'].':'); - $app->log('Removed user: '.$data['old']['username'],LOGLEVEL_DEBUG); - } else { - if($data['new']['active'] == 'y') { - $app->system->replaceLine($folder_path.'.htpasswd',$data['new']['username'].':',$data['new']['username'].':'.$data['new']['password'],0,1); - $app->log('Added or updated user: '.$data['new']['username'],LOGLEVEL_DEBUG); - } - } - - // write basic auth configuration to vhost file because nginx does not support .htaccess - $webdata['new'] = $webdata['old'] = $website; - $this->update('web_domain_update', $webdata); - } - - //* Remove .htpasswd file, when folder protection is removed - function web_folder_delete($event_name,$data) { - global $app, $conf; - - $folder_id = $data['old']['web_folder_id']; - - $folder = $data['old']; - $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($folder['parent_domain_id'])); - - if(!is_array($folder) or !is_array($website)) { - $app->log('Not able to retrieve folder or website record.',LOGLEVEL_DEBUG); - return false; - } - - $web_folder = 'web'; - if($website['type'] == 'vhostsubdomain') $web_folder = $website['web_folder']; - - //* Get the folder path. - if(substr($folder['path'],0,1) == '/') $folder['path'] = substr($folder['path'],1); - if(substr($folder['path'],-1) == '/') $folder['path'] = substr($folder['path'],0,-1); - $folder_path = realpath($website['document_root'].'/' . $web_folder . '/'.$folder['path']); - if(substr($folder_path,-1) != '/') $folder_path .= '/'; - - //* Check if the resulting path is inside the docroot - if(substr($folder_path,0,strlen($website['document_root'])) != $website['document_root']) { - $app->log('Folder path is outside of docroot.',LOGLEVEL_DEBUG); - return false; - } - - //* Remove .htpasswd file - if(is_file($folder_path.'.htpasswd')) { - $app->system->unlink($folder_path.'.htpasswd'); - $app->log('Removed file '.$folder_path.'.htpasswd',LOGLEVEL_DEBUG); - } - - // write basic auth configuration to vhost file because nginx does not support .htaccess - $webdata['new'] = $webdata['old'] = $website; - $this->update('web_domain_update', $webdata); - } - - //* Update folder protection, when path has been changed - function web_folder_update($event_name,$data) { - global $app, $conf; - - $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($data['new']['parent_domain_id'])); - - if(!is_array($website)) { - $app->log('Not able to retrieve folder or website record.',LOGLEVEL_DEBUG); - return false; - } - - $web_folder = 'web'; - if($website['type'] == 'vhostsubdomain') $web_folder = $website['web_folder']; - - //* Get the folder path. - if(substr($data['old']['path'],0,1) == '/') $data['old']['path'] = substr($data['old']['path'],1); - if(substr($data['old']['path'],-1) == '/') $data['old']['path'] = substr($data['old']['path'],0,-1); - $old_folder_path = realpath($website['document_root'].'/' . $web_folder . '/'.$data['old']['path']); - if(substr($old_folder_path,-1) != '/') $old_folder_path .= '/'; - - if(substr($data['new']['path'],0,1) == '/') $data['new']['path'] = substr($data['new']['path'],1); - if(substr($data['new']['path'],-1) == '/') $data['new']['path'] = substr($data['new']['path'],0,-1); - $new_folder_path = escapeshellcmd($website['document_root'].'/' . $web_folder . '/'.$data['new']['path']); - if(substr($new_folder_path,-1) != '/') $new_folder_path .= '/'; - - //* Check if the resulting path is inside the docroot - if(stristr($new_folder_path,'..') || stristr($new_folder_path,'./') || stristr($new_folder_path,'\\')) { - $app->log('Folder path "'.$new_folder_path.'" contains .. or ./.',LOGLEVEL_DEBUG); - return false; - } - if(stristr($old_folder_path,'..') || stristr($old_folder_path,'./') || stristr($old_folder_path,'\\')) { - $app->log('Folder path "'.$old_folder_path.'" contains .. or ./.',LOGLEVEL_DEBUG); - return false; - } - - //* Check if the resulting path is inside the docroot - if(substr($old_folder_path,0,strlen($website['document_root'])) != $website['document_root']) { - $app->log('Old folder path '.$old_folder_path.' is outside of docroot.',LOGLEVEL_DEBUG); - return false; - } - if(substr($new_folder_path,0,strlen($website['document_root'])) != $website['document_root']) { - $app->log('New folder path '.$new_folder_path.' is outside of docroot.',LOGLEVEL_DEBUG); - return false; - } - - //* Create the folder path, if it does not exist - if(!is_dir($new_folder_path)) $app->system->mkdirpath($new_folder_path); - - if($data['old']['path'] != $data['new']['path']) { - - - //* move .htpasswd file - if(is_file($old_folder_path.'.htpasswd')) { - $app->system->rename($old_folder_path.'.htpasswd',$new_folder_path.'.htpasswd'); - $app->log('Moved file '.$old_folder_path.'.htpasswd to '.$new_folder_path.'.htpasswd',LOGLEVEL_DEBUG); - } - - } - - // write basic auth configuration to vhost file because nginx does not support .htaccess - $webdata['new'] = $webdata['old'] = $website; - $this->update('web_domain_update', $webdata); - } - - function _create_web_folder_auth_configuration($website){ - global $app, $conf; - //* Create the domain.auth file which is included in the vhost configuration file - $app->uses('getconf'); - $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); - $basic_auth_file = escapeshellcmd($web_config['nginx_vhost_conf_dir'].'/'.$website['domain'].'.auth'); - //$app->load('tpl'); - //$tpl = new tpl(); - //$tpl->newTemplate('nginx_http_authentication.auth.master'); - $website_auth_locations = $app->db->queryAllRecords("SELECT * FROM web_folder WHERE active = 'y' AND parent_domain_id = ".intval($website['domain_id'])); - $basic_auth_locations = array(); - if(is_array($website_auth_locations) && !empty($website_auth_locations)){ - foreach($website_auth_locations as $website_auth_location){ - if(substr($website_auth_location['path'],0,1) == '/') $website_auth_location['path'] = substr($website_auth_location['path'],1); - if(substr($website_auth_location['path'],-1) == '/') $website_auth_location['path'] = substr($website_auth_location['path'],0,-1); - if($website_auth_location['path'] != ''){ - $website_auth_location['path'] .= '/'; - } - $basic_auth_locations[] = array('htpasswd_location' => '/'.$website_auth_location['path'], - 'htpasswd_path' => $website['document_root'].'/' . ($website['type'] == 'vhostsubdomain' ? $website['web_folder'] : 'web') . '/'.$website_auth_location['path']); - } - } - return $basic_auth_locations; - //$tpl->setLoop('basic_auth_locations', $basic_auth_locations); - //file_put_contents($basic_auth_file,$tpl->grab()); - //$app->log('Writing the http basic authentication file: '.$basic_auth_file,LOGLEVEL_DEBUG); - //unset($tpl); - //$app->services->restartServiceDelayed('httpd','reload'); - } - - //* Update the awstats configuration file - private function awstats_update ($data,$web_config) { - global $app; - - $web_folder = $data['new']['web_folder']; - if($data['new']['type'] == 'vhost') $web_folder = 'web'; - $awstats_conf_dir = $web_config['awstats_conf_dir']; - - if(!is_dir($data['new']['document_root']."/" . $web_folder . "/stats/")) mkdir($data['new']['document_root']."/" . $web_folder . "/stats"); - if(!@is_file($awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf') || ($data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain'])) { - if ( @is_file($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf') ) { - $app->system->unlink($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf'); - } - - $content = ''; - $content .= "Include \"".$awstats_conf_dir."/awstats.conf\"\n"; - $content .= "LogFile=\"/var/log/ispconfig/httpd/".$data['new']['domain']."/access.log\"\n"; - $content .= "SiteDomain=\"".$data['new']['domain']."\"\n"; - $content .= "HostAliases=\"www.".$data['new']['domain']." localhost 127.0.0.1\"\n"; - - $app->system->file_put_contents($awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf',$content); - $app->log('Created AWStats config file: '.$awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf',LOGLEVEL_DEBUG); - } - - if(is_file($data['new']['document_root']."/" . $web_folder . "/stats/index.html")) $app->system->unlink($data['new']['document_root']."/" . $web_folder . "/stats/index.html"); - if(file_exists("/usr/local/ispconfig/server/conf-custom/awstats_index.php.master")) { - $app->system->copy("/usr/local/ispconfig/server/conf-custom/awstats_index.php.master",$data['new']['document_root']."/" . $web_folder . "/stats/index.php"); - } else { - $app->system->copy("/usr/local/ispconfig/server/conf/awstats_index.php.master",$data['new']['document_root']."/" . $web_folder . "/stats/index.php"); - } - } - - //* Delete the awstats configuration file - private function awstats_delete ($data,$web_config) { - global $app; - - $awstats_conf_dir = $web_config['awstats_conf_dir']; - - if ( @is_file($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf') ) { - $app->system->unlink($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf'); - $app->log('Removed AWStats config file: '.$awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf',LOGLEVEL_DEBUG); - } - } - - //* Update the PHP-FPM pool configuration file - private function php_fpm_pool_update ($data,$web_config,$pool_dir,$pool_name,$socket_dir) { - global $app, $conf; - /* - if(trim($data['new']['fastcgi_php_version']) != ''){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir,-1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - */ - if($data['new']['php'] != 'no'){ - if(trim($data['new']['fastcgi_php_version']) != ''){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir,-1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - } else { - if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] != 'no'){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir,-1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - } - - $app->uses("getconf"); - $web_config = $app->getconf->get_server_config($conf["server_id"], 'web'); - - if($data['new']['php'] == 'no'){ - if(@is_file($pool_dir.$pool_name.'.conf')){ - $app->system->unlink($pool_dir.$pool_name.'.conf'); - //$reload = true; - } - if($data['old']['php'] != 'no'){ - if(!$default_php_fpm){ - $app->services->restartService('php-fpm','reload:'.$custom_php_fpm_init_script); - } else { - $app->services->restartService('php-fpm','reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); - } - } - return; - } - - $app->load('tpl'); - $tpl = new tpl(); - $tpl->newTemplate('php_fpm_pool.conf.master'); - - if($data['new']['php_fpm_use_socket'] == 'y'){ - $use_tcp = 0; - $use_socket = 1; - if(!is_dir($socket_dir)) $app->system->mkdirpath($socket_dir); - } else { - $use_tcp = 1; - $use_socket = 0; - } - $tpl->setVar('use_tcp', $use_tcp); - $tpl->setVar('use_socket', $use_socket); - - $fpm_socket = $socket_dir.$pool_name.'.sock'; - $tpl->setVar('fpm_socket', $fpm_socket); - - $tpl->setVar('fpm_pool', $pool_name); - $tpl->setVar('fpm_port', $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1); - $tpl->setVar('fpm_user', $data['new']['system_user']); - $tpl->setVar('fpm_group', $data['new']['system_group']); - $tpl->setVar('pm', $data['new']['pm']); - $tpl->setVar('pm_max_children', $data['new']['pm_max_children']); - $tpl->setVar('pm_start_servers', $data['new']['pm_start_servers']); - $tpl->setVar('pm_min_spare_servers', $data['new']['pm_min_spare_servers']); - $tpl->setVar('pm_max_spare_servers', $data['new']['pm_max_spare_servers']); - $tpl->setVar('pm_process_idle_timeout', $data['new']['pm_process_idle_timeout']); - $tpl->setVar('pm_max_requests', $data['new']['pm_max_requests']); - $tpl->setVar('document_root', $data['new']['document_root']); - $tpl->setVar('security_level',$web_config['security_level']); - $php_open_basedir = ($data['new']['php_open_basedir'] == '')?escapeshellcmd($data['new']['document_root']):escapeshellcmd($data['new']['php_open_basedir']); - $tpl->setVar('php_open_basedir', $php_open_basedir); - if($php_open_basedir != ''){ - $tpl->setVar('enable_php_open_basedir', ''); - } else { - $tpl->setVar('enable_php_open_basedir', ';'); - } - - // Custom php.ini settings - $final_php_ini_settings = array(); - $custom_php_ini_settings = trim($data['new']['custom_php_ini']); - if($custom_php_ini_settings != ''){ - // Make sure we only have Unix linebreaks - $custom_php_ini_settings = str_replace("\r\n", "\n", $custom_php_ini_settings); - $custom_php_ini_settings = str_replace("\r", "\n", $custom_php_ini_settings); - $ini_settings = explode("\n", $custom_php_ini_settings); - if(is_array($ini_settings) && !empty($ini_settings)){ - foreach($ini_settings as $ini_setting){ - $ini_setting = trim($ini_setting); - if(substr($ini_setting,0,1) == ';') continue; - if(substr($ini_setting,0,1) == '#') continue; - if(substr($ini_setting,0,2) == '//') continue; - list($key, $value) = explode('=', $ini_setting); - if($value){ - $value = trim($value); - $key = trim($key); - switch (strtolower($value)) { - case '0': - // PHP-FPM might complain about invalid boolean value if you use 0 - $value = 'off'; - case '1': - case 'on': - case 'off': - case 'true': - case 'false': - case 'yes': - case 'no': - $final_php_ini_settings[] = array('ini_setting' => 'php_admin_flag['.$key.'] = '.$value); - break; - default: - $final_php_ini_settings[] = array('ini_setting' => 'php_admin_value['.$key.'] = '.$value); - } - } - } - } - } - - $tpl->setLoop('custom_php_ini_settings', $final_php_ini_settings); - - $app->system->file_put_contents($pool_dir.$pool_name.'.conf',$tpl->grab()); - $app->log('Writing the PHP-FPM config file: '.$pool_dir.$pool_name.'.conf',LOGLEVEL_DEBUG); - unset($tpl); - - // delete pool in all other PHP versions - $default_pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']); - if(substr($default_pool_dir,-1) != '/') $default_pool_dir .= '/'; - if($default_pool_dir != $pool_dir){ - if ( @is_file($default_pool_dir.$pool_name.'.conf') ) { - $app->system->unlink($default_pool_dir.$pool_name.'.conf'); - $app->log('Removed PHP-FPM config file: '.$default_pool_dir.$pool_name.'.conf',LOGLEVEL_DEBUG); - $app->services->restartService('php-fpm','reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); - } - } - $php_versions = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fpm_init_script != '' AND php_fpm_ini_dir != '' AND php_fpm_pool_dir != '' AND server_id = ".$conf["server_id"]); - if(is_array($php_versions) && !empty($php_versions)){ - foreach($php_versions as $php_version){ - if(substr($php_version['php_fpm_pool_dir'],-1) != '/') $php_version['php_fpm_pool_dir'] .= '/'; - if($php_version['php_fpm_pool_dir'] != $pool_dir){ - if ( @is_file($php_version['php_fpm_pool_dir'].$pool_name.'.conf') ) { - $app->system->unlink($php_version['php_fpm_pool_dir'].$pool_name.'.conf'); - $app->log('Removed PHP-FPM config file: '.$php_version['php_fpm_pool_dir'].$pool_name.'.conf',LOGLEVEL_DEBUG); - $app->services->restartService('php-fpm','reload:'.$php_version['php_fpm_init_script']); - } - } - } - } - // Reload current PHP-FPM after all others - sleep(1); - if(!$default_php_fpm){ - $app->services->restartService('php-fpm','reload:'.$custom_php_fpm_init_script); - } else { - $app->services->restartService('php-fpm','reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); - } - } - - //* Delete the PHP-FPM pool configuration file - private function php_fpm_pool_delete ($data,$web_config) { - global $app, $conf; - - if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] != 'no'){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir,-1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - - if($default_php_fpm){ - $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']); - } else { - $pool_dir = $custom_php_fpm_pool_dir; - } - - if(substr($pool_dir,-1) != '/') $pool_dir .= '/'; - $pool_name = 'web'.$data['old']['domain_id']; - - if ( @is_file($pool_dir.$pool_name.'.conf') ) { - $app->system->unlink($pool_dir.$pool_name.'.conf'); - $app->log('Removed PHP-FPM config file: '.$pool_dir.$pool_name.'.conf',LOGLEVEL_DEBUG); - } - - // delete pool in all other PHP versions - $default_pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']); - if(substr($default_pool_dir,-1) != '/') $default_pool_dir .= '/'; - if($default_pool_dir != $pool_dir){ - if ( @is_file($default_pool_dir.$pool_name.'.conf') ) { - $app->system->unlink($default_pool_dir.$pool_name.'.conf'); - $app->log('Removed PHP-FPM config file: '.$default_pool_dir.$pool_name.'.conf',LOGLEVEL_DEBUG); - $app->services->restartService('php-fpm','reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); - } - } - $php_versions = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fpm_init_script != '' AND php_fpm_ini_dir != '' AND php_fpm_pool_dir != '' AND server_id = ".$data['old']['server_id']); - if(is_array($php_versions) && !empty($php_versions)){ - foreach($php_versions as $php_version){ - if(substr($php_version['php_fpm_pool_dir'],-1) != '/') $php_version['php_fpm_pool_dir'] .= '/'; - if($php_version['php_fpm_pool_dir'] != $pool_dir){ - if ( @is_file($php_version['php_fpm_pool_dir'].$pool_name.'.conf') ) { - $app->system->unlink($php_version['php_fpm_pool_dir'].$pool_name.'.conf'); - $app->log('Removed PHP-FPM config file: '.$php_version['php_fpm_pool_dir'].$pool_name.'.conf',LOGLEVEL_DEBUG); - $app->services->restartService('php-fpm','reload:'.$php_version['php_fpm_init_script']); - } - } - } - } - - // Reload current PHP-FPM after all others - sleep(1); - if(!$default_php_fpm){ - $app->services->restartService('php-fpm','reload:'.$custom_php_fpm_init_script); - } else { - $app->services->restartService('php-fpm','reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); - } - } - - private function nginx_replace($matches){ - $location = 'location'.($matches[1] != '' ? ' '.$matches[1] : '').' '.$matches[2].' '.$matches[3]; - if($matches[4] == '##merge##' || $matches[7] == '##merge##') $location .= ' ##merge##'; - if($matches[4] == '##delete##' || $matches[7] == '##delete##') $location .= ' ##delete##'; - $location .= "\n"; - $location .= $matches[5]."\n"; - $location .= $matches[6]; - return $location; - } - - private function nginx_merge_locations($vhost_conf){ - - $lines = explode("\n", $vhost_conf); - - // if whole location block is in one line, split it up into multiple lines - if(is_array($lines) && !empty($lines)){ - $linecount = sizeof($lines); - for($h=0;$h<$linecount;$h++){ - // remove comments - if(substr(trim($lines[$h]),0,1) == '#'){ - unset($lines[$h]); - continue; - } - - $lines[$h] = rtrim($lines[$h]); - /* - if(substr(ltrim($lines[$h]), 0, 8) == 'location' && strpos($lines[$h], '{') !== false && strpos($lines[$h], ';') !== false){ - $lines[$h] = str_replace("{", "{\n", $lines[$h]); - $lines[$h] = str_replace(";", ";\n", $lines[$h]); - if(strpos($lines[$h], '##merge##') !== false){ - $lines[$h] = str_replace('##merge##', '', $lines[$h]); - $lines[$h] = substr($lines[$h],0,strpos($lines[$h], '{')).' ##merge##'.substr($lines[$h],strpos($lines[$h], '{')+1); - } - } - if(substr(ltrim($lines[$h]), 0, 8) == 'location' && strpos($lines[$h], '{') !== false && strpos($lines[$h], '}') !== false && strpos($lines[$h], ';') === false){ - $lines[$h] = str_replace("{", "{\n", $lines[$h]); - if(strpos($lines[$h], '##merge##') !== false){ - $lines[$h] = str_replace('##merge##', '', $lines[$h]); - $lines[$h] = substr($lines[$h],0,strpos($lines[$h], '{')).' ##merge##'.substr($lines[$h],strpos($lines[$h], '{')+1); - } - } - */ - $pattern = '/^[^\S\n]*location[^\S\n]+(?:(.+)[^\S\n]+)?(.+)[^\S\n]*(\{)[^\S\n]*(##merge##|##delete##)?[^\S\n]*(.+)[^\S\n]*(\})[^\S\n]*(##merge##|##delete##)?[^\S\n]*$/'; - $lines[$h] = preg_replace_callback($pattern, array($this, 'nginx_replace') ,$lines[$h]); - } - } - $vhost_conf = implode("\n", $lines); - unset($lines); - unset($linecount); - - $lines = explode("\n", $vhost_conf); - - if(is_array($lines) && !empty($lines)){ - $locations = array(); - $locations_to_delete = array(); - $islocation = false; - $linecount = sizeof($lines); - $server_count = 0; - - for($i=0;$i<$linecount;$i++){ - $l = trim($lines[$i]); - if(substr($l, 0, 8) == 'server {') $server_count += 1; - if($server_count > 1) break; - if(substr($l, 0, 8) == 'location' && !$islocation){ - - $islocation = true; - $level = 0; - - // Remove unnecessary whitespace - $l = preg_replace('/\s\s+/', ' ', $l); - - $loc_parts = explode(' ', $l); - // see http://wiki.nginx.org/HttpCoreModule#location - if($loc_parts[1] == '=' || $loc_parts[1] == '~' || $loc_parts[1] == '~*' || $loc_parts[1] == '^~'){ - $location = $loc_parts[1].' '.$loc_parts[2]; - } else { - $location = $loc_parts[1]; - } - unset($loc_parts); - - if(!isset($locations[$location]['action'])) $locations[$location]['action'] = 'replace'; - if(substr($l, -9) == '##merge##') $locations[$location]['action'] = 'merge'; - if(substr($l, -10) == '##delete##') $locations[$location]['action'] = 'delete'; - - if(!isset($locations[$location]['open_tag'])) $locations[$location]['open_tag'] = ' location '.$location.' {'; - if(!isset($locations[$location]['location']) || $locations[$location]['action'] == 'replace') $locations[$location]['location'] = ''; - if($locations[$location]['action'] == 'delete') $locations_to_delete[] = $location; - if(!isset($locations[$location]['end_tag'])) $locations[$location]['end_tag'] = ' }'; - if(!isset($locations[$location]['start_line'])) $locations[$location]['start_line'] = $i; - - unset($lines[$i]); - - } else { - - if($islocation){ - if(strpos($l, '{') !== false){ - $level += 1; - } - if(strpos($l, '}') !== false && $level > 0){ - $level -= 1; - $locations[$location]['location'] .= $lines[$i]."\n"; - } elseif(strpos($l, '}') !== false && $level == 0){ - $islocation = false; - } else { - $locations[$location]['location'] .= $lines[$i]."\n"; - } - unset($lines[$i]); - } - - } - } - - if(is_array($locations) && !empty($locations)){ - if(is_array($locations_to_delete) && !empty($locations_to_delete)){ - foreach($locations_to_delete as $location_to_delete){ - if(isset($locations[$location_to_delete])) unset($locations[$location_to_delete]); - } - } - - foreach($locations as $key => $val){ - $new_location = $val['open_tag']."\n".$val['location'].$val['end_tag']; - $lines[$val['start_line']] = $new_location; - } - } - ksort($lines); - $vhost_conf = implode("\n", $lines); - } - - return trim($vhost_conf); - } - - function client_delete($event_name,$data) { - global $app, $conf; - - $app->uses("getconf"); - $web_config = $app->getconf->get_server_config($conf["server_id"], 'web'); - - $client_id = intval($data['old']['client_id']); - if($client_id > 0) { - - $client_dir = $web_config['website_basedir'].'/clients/client'.$client_id; - if(is_dir($client_dir) && !stristr($client_dir,'..')) { - // remove symlinks from $client_dir - $files = array_diff(scandir($client_dir), array('.','..')); - if(is_array($files) && !empty($files)){ - foreach($files as $file){ - if(is_link($client_dir.'/'.$file)){ - unlink($client_dir.'/'.$file); - $app->log('Removed symlink: '.$client_dir.'/'.$file,LOGLEVEL_DEBUG); - } - } - } - - @rmdir($client_dir); - $app->log('Removed client directory: '.$client_dir,LOGLEVEL_DEBUG); - } - - if($app->system->is_group('client'.$client_id)){ - $this->_exec('groupdel client'.$client_id); - $app->log('Removed group client'.$client_id,LOGLEVEL_DEBUG); - } - } - - } - - //* Wrapper for exec function for easier debugging - private function _exec($command) { - global $app; - $app->log('exec: '.$command,LOGLEVEL_DEBUG); - exec($command); - } - - private function _checkTcp ($host,$port) { - - $fp = @fsockopen ($host, $port, $errno, $errstr, 2); - - if ($fp) { - fclose($fp); - return true; - } else { - return false; - } - } - - public function create_relative_link($f, $t) { - global $app; - // $from already exists - $from = realpath($f); - - // realpath requires the traced file to exist - so, lets touch it first, then remove - @$app->system->unlink($t); touch($t); - $to = realpath($t); - @$app->system->unlink($t); - - // Remove from the left side matching path elements from $from and $to - // and get path elements counts - $a1 = explode('/', $from); $a2 = explode('/', $to); - for ($c = 0; $a1[$c] == $a2[$c]; $c++) { - unset($a1[$c]); unset($a2[$c]); - } - $cfrom = implode('/', $a1); - - // Check if a path is fully a subpath of another - no way to create symlink in the case - if (count($a1) == 0 || count($a2) == 0) return false; - - // Add ($cnt_to-1) number of "../" elements to left side of $cfrom - for ($c = 0; $c < (count($a2)-1); $c++) { $cfrom = '../'.$cfrom; } - - return symlink($cfrom, $to); - } - - private function _rewrite_quote($string) { - return str_replace(array('.', '*', '?', '+'), array('\\.', '\\*', '\\?', '\\+'), $string); - } - - private function url_is_local($hostname, $domain_id){ - global $app; - - // ORDER BY clause makes sure wildcard subdomains (*) are listed last in the result array so that we can find direct matches first - $webs = $app->db->queryAllRecords("SELECT * FROM web_domain WHERE active = 'y' ORDER BY subdomain ASC"); - if(is_array($webs) && !empty($webs)){ - foreach($webs as $web){ - // web domain doesn't match hostname - if(substr($hostname,-strlen($web['domain'])) != $web['domain']) continue; - // own vhost and therefore server {} container of its own - //if($web['type'] == 'vhostsubdomain') continue; - // alias domains/subdomains using rewrites and therefore a server {} container of their own - //if(($web['type'] == 'alias' || $web['type'] == 'subdomain') && $web['redirect_type'] != '' && $web['redirect_path'] != '') continue; - - if($web['subdomain'] == '*'){ - $pattern = '/\.?'.str_replace('.', '\.', $web['domain']).'$/i'; - } - if($web['subdomain'] == 'none'){ - if($web['domain'] == $hostname){ - if($web['domain_id'] == $domain_id || $web['parent_domain_id'] == $domain_id){ - // own vhost and therefore server {} container of its own - if($web['type'] == 'vhostsubdomain') return false; - // alias domains/subdomains using rewrites and therefore a server {} container of their own - if(($web['type'] == 'alias' || $web['type'] == 'subdomain') && $web['redirect_type'] != '' && $web['redirect_path'] != '') return false; - return true; - } else { - return false; - } - } - $pattern = '/^'.str_replace('.', '\.', $web['domain']).'$/i'; - } - if($web['subdomain'] == 'www'){ - if($web['domain'] == $hostname || $web['subdomain'].'.'.$web['domain'] == $hostname){ - if($web['domain_id'] == $domain_id || $web['parent_domain_id'] == $domain_id){ - // own vhost and therefore server {} container of its own - if($web['type'] == 'vhostsubdomain') return false; - // alias domains/subdomains using rewrites and therefore a server {} container of their own - if(($web['type'] == 'alias' || $web['type'] == 'subdomain') && $web['redirect_type'] != '' && $web['redirect_path'] != '') return false; - return true; - } else { - return false; - } - } - $pattern = '/^(www\.)?'.str_replace('.', '\.', $web['domain']).'$/i'; - } - if(preg_match($pattern, $hostname)){ - if($web['domain_id'] == $domain_id || $web['parent_domain_id'] == $domain_id){ - // own vhost and therefore server {} container of its own - if($web['type'] == 'vhostsubdomain') return false; - // alias domains/subdomains using rewrites and therefore a server {} container of their own - if(($web['type'] == 'alias' || $web['type'] == 'subdomain') && $web['redirect_type'] != '' && $web['redirect_path'] != '') return false; - return true; - } else { - return false; - } - } - } - } - - return false; - } - - private function get_seo_redirects($web, $prefix = '', $force_subdomain = false){ - // $force_subdomain = 'none|www' - $seo_redirects = array(); - - if(substr($web['domain'], 0, 2) === '*.') $web['subdomain'] = '*'; - - if(($web['subdomain'] == 'www' || $web['subdomain'] == '*') && $force_subdomain != 'www'){ - if($web['seo_redirect'] == 'non_www_to_www'){ - $seo_redirects[$prefix.'seo_redirect_origin_domain'] = $web['domain']; - $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain']; - $seo_redirects[$prefix.'seo_redirect_operator'] = '='; - } - if($web['seo_redirect'] == '*_domain_tld_to_www_domain_tld'){ - // ^(example\.com|(?!\bwww\b)\.example\.com)$ - // ^(example\.com|((?:\w+(?:-\w+)*\.)*)((?!www\.)\w+(?:-\w+)*)(\.example\.com))$ - $seo_redirects[$prefix.'seo_redirect_origin_domain'] = '^('.str_replace('.', '\.', $web['domain']).'|((?:\w+(?:-\w+)*\.)*)((?!www\.)\w+(?:-\w+)*)(\.'.str_replace('.', '\.', $web['domain']).'))$'; - $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain']; - $seo_redirects[$prefix.'seo_redirect_operator'] = '~*'; - } - if($web['seo_redirect'] == '*_to_www_domain_tld'){ - $seo_redirects[$prefix.'seo_redirect_origin_domain'] = 'www.'.$web['domain']; - $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain']; - $seo_redirects[$prefix.'seo_redirect_operator'] = '!='; - } - } - if($force_subdomain != 'none'){ - if($web['seo_redirect'] == 'www_to_non_www'){ - $seo_redirects[$prefix.'seo_redirect_origin_domain'] = 'www.'.$web['domain']; - $seo_redirects[$prefix.'seo_redirect_target_domain'] = $web['domain']; - $seo_redirects[$prefix.'seo_redirect_operator'] = '='; - } - if($web['seo_redirect'] == '*_domain_tld_to_domain_tld'){ - // ^(.+)\.example\.com$ - $seo_redirects[$prefix.'seo_redirect_origin_domain'] = '^(.+)\.'.str_replace('.', '\.', $web['domain']).'$'; - $seo_redirects[$prefix.'seo_redirect_target_domain'] = $web['domain']; - $seo_redirects[$prefix.'seo_redirect_operator'] = '~*'; - } - if($web['seo_redirect'] == '*_to_domain_tld'){ - $seo_redirects[$prefix.'seo_redirect_origin_domain'] = $web['domain']; - $seo_redirects[$prefix.'seo_redirect_target_domain'] = $web['domain']; - $seo_redirects[$prefix.'seo_redirect_operator'] = '!='; - } - } - return $seo_redirects; - } - -} // end class - -?> +<?php + +/* +Copyright (c) 2007 - 2012, Till Brehm, projektfarm Gmbh +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of ISPConfig nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +class nginx_plugin { + + var $plugin_name = 'nginx_plugin'; + var $class_name = 'nginx_plugin'; + + // private variables + var $action = ''; + var $ssl_certificate_changed = false; + + //* This function is called during ispconfig installation to determine + // if a symlink shall be created for this plugin. + function onInstall() { + global $conf; + + if($conf['services']['web'] == true && !@is_link('/usr/local/ispconfig/server/plugins-enabled/apache2_plugin.inc.php')) { + return true; + } else { + return false; + } + + } + + + /* + This function is called when the plugin is loaded + */ + + function onLoad() { + global $app; + + /* + Register for the events + */ + $app->plugins->registerEvent('web_domain_insert',$this->plugin_name,'ssl'); + $app->plugins->registerEvent('web_domain_update',$this->plugin_name,'ssl'); + $app->plugins->registerEvent('web_domain_delete',$this->plugin_name,'ssl'); + + $app->plugins->registerEvent('web_domain_insert',$this->plugin_name,'insert'); + $app->plugins->registerEvent('web_domain_update',$this->plugin_name,'update'); + $app->plugins->registerEvent('web_domain_delete',$this->plugin_name,'delete'); + + $app->plugins->registerEvent('server_ip_insert',$this->plugin_name,'server_ip'); + $app->plugins->registerEvent('server_ip_update',$this->plugin_name,'server_ip'); + $app->plugins->registerEvent('server_ip_delete',$this->plugin_name,'server_ip'); + + /* + $app->plugins->registerEvent('webdav_user_insert',$this->plugin_name,'webdav'); + $app->plugins->registerEvent('webdav_user_update',$this->plugin_name,'webdav'); + $app->plugins->registerEvent('webdav_user_delete',$this->plugin_name,'webdav'); + */ + + $app->plugins->registerEvent('client_delete',$this->plugin_name,'client_delete'); + + $app->plugins->registerEvent('web_folder_user_insert',$this->plugin_name,'web_folder_user'); + $app->plugins->registerEvent('web_folder_user_update',$this->plugin_name,'web_folder_user'); + $app->plugins->registerEvent('web_folder_user_delete',$this->plugin_name,'web_folder_user'); + + $app->plugins->registerEvent('web_folder_update',$this->plugin_name,'web_folder_update'); + $app->plugins->registerEvent('web_folder_delete',$this->plugin_name,'web_folder_delete'); + } + + // Handle the creation of SSL certificates + function ssl($event_name,$data) { + global $app, $conf; + + $app->uses('system'); + + // load the server configuration options + $app->uses('getconf'); + $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); + if ($web_config['CA_path']!='' && !file_exists($web_config['CA_path'].'/openssl.cnf')) + $app->log("CA path error, file does not exist:".$web_config['CA_path'].'/openssl.cnf',LOGLEVEL_ERROR); + + //* Only vhosts can have a ssl cert + if($data["new"]["type"] != "vhost" && $data["new"]["type"] != "vhostsubdomain") return; + + // if(!is_dir($data['new']['document_root'].'/ssl')) exec('mkdir -p '.$data['new']['document_root'].'/ssl'); + if(!is_dir($data['new']['document_root'].'/ssl')) $app->system->mkdirpath($data['new']['document_root'].'/ssl'); + + $ssl_dir = $data['new']['document_root'].'/ssl'; + $domain = $data['new']['ssl_domain']; + $key_file = $ssl_dir.'/'.$domain.'.key.org'; + $key_file2 = $ssl_dir.'/'.$domain.'.key'; + $csr_file = $ssl_dir.'/'.$domain.'.csr'; + $crt_file = $ssl_dir.'/'.$domain.'.crt'; + + //* Create a SSL Certificate + if($data['new']['ssl_action'] == 'create' && $conf['mirror_server_id'] == 0) { + + $this->ssl_certificate_changed = true; + + //* Rename files if they exist + if(file_exists($key_file)){ + $app->system->rename($key_file,$key_file.'.bak'); + $app->system->chmod($key_file.'.bak',0400); + } + if(file_exists($key_file2)){ + $app->system->rename($key_file2,$key_file2.'.bak'); + $app->system->chmod($key_file2.'.bak',0400); + } + if(file_exists($csr_file)) $app->system->rename($csr_file,$csr_file.'.bak'); + if(file_exists($crt_file)) $app->system->rename($crt_file,$crt_file.'.bak'); + + $rand_file = $ssl_dir.'/random_file'; + $rand_data = md5(uniqid(microtime(),1)); + for($i=0; $i<1000; $i++) { + $rand_data .= md5(uniqid(microtime(),1)); + $rand_data .= md5(uniqid(microtime(),1)); + $rand_data .= md5(uniqid(microtime(),1)); + $rand_data .= md5(uniqid(microtime(),1)); + } + $app->system->file_put_contents($rand_file, $rand_data); + + $ssl_password = substr(md5(uniqid(microtime(),1)), 0, 15); + + $ssl_cnf = " RANDFILE = $rand_file + + [ req ] + default_bits = 2048 + default_keyfile = keyfile.pem + distinguished_name = req_distinguished_name + attributes = req_attributes + prompt = no + output_password = $ssl_password + + [ req_distinguished_name ] + C = ".trim($data['new']['ssl_country'])." + ST = ".trim($data['new']['ssl_state'])." + L = ".trim($data['new']['ssl_locality'])." + O = ".trim($data['new']['ssl_organisation'])." + OU = ".trim($data['new']['ssl_organisation_unit'])." + CN = $domain + emailAddress = webmaster@".$data['new']['domain']." + + [ req_attributes ] + challengePassword = A challenge password"; + + $ssl_cnf_file = $ssl_dir.'/openssl.conf'; + $app->system->file_put_contents($ssl_cnf_file,$ssl_cnf); + + $rand_file = escapeshellcmd($rand_file); + $key_file = escapeshellcmd($key_file); + if(substr($domain, 0, 2) == '*.' && strpos($key_file, '/ssl/\*.') !== false) $key_file = str_replace('/ssl/\*.', '/ssl/*.', $key_file); // wildcard certificate + $key_file2 = escapeshellcmd($key_file2); + if(substr($domain, 0, 2) == '*.' && strpos($key_file2, '/ssl/\*.') !== false) $key_file2 = str_replace('/ssl/\*.', '/ssl/*.', $key_file2); // wildcard certificate + $ssl_days = 3650; + $csr_file = escapeshellcmd($csr_file); + if(substr($domain, 0, 2) == '*.' && strpos($csr_file, '/ssl/\*.') !== false) $csr_file = str_replace('/ssl/\*.', '/ssl/*.', $csr_file); // wildcard certificate + $config_file = escapeshellcmd($ssl_cnf_file); + $crt_file = escapeshellcmd($crt_file); + if(substr($domain, 0, 2) == '*.' && strpos($crt_file, '/ssl/\*.') !== false) $crt_file = str_replace('/ssl/\*.', '/ssl/*.', $crt_file); // wildcard certificate + + if(is_file($ssl_cnf_file) && !is_link($ssl_cnf_file)) { + + exec("openssl genrsa -des3 -rand $rand_file -passout pass:$ssl_password -out $key_file 2048"); + exec("openssl req -new -passin pass:$ssl_password -passout pass:$ssl_password -key $key_file -out $csr_file -days $ssl_days -config $config_file"); + exec("openssl rsa -passin pass:$ssl_password -in $key_file -out $key_file2"); + + if(file_exists($web_config['CA_path'].'/openssl.cnf')) + { + exec("openssl ca -batch -out $crt_file -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -in $csr_file"); + $app->log("Creating CA-signed SSL Cert for: $domain",LOGLEVEL_DEBUG); + if (filesize($crt_file)==0 || !file_exists($crt_file)) $app->log("CA-Certificate signing failed. openssl ca -out $crt_file -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -in $csr_file",LOGLEVEL_ERROR); + }; + if (@filesize($crt_file)==0 || !file_exists($crt_file)){ + exec("openssl req -x509 -passin pass:$ssl_password -passout pass:$ssl_password -key $key_file -in $csr_file -out $crt_file -days $ssl_days -config $config_file "); + $app->log("Creating self-signed SSL Cert for: $domain",LOGLEVEL_DEBUG); + }; + + } + + $app->system->chmod($key_file,0400); + $app->system->chmod($key_file2,0400); + @$app->system->unlink($config_file); + @$app->system->unlink($rand_file); + $ssl_request = $app->db->quote($app->system->file_get_contents($csr_file)); + $ssl_cert = $app->db->quote($app->system->file_get_contents($crt_file)); + $ssl_key2 = $app->db->quote($app->system->file_get_contents($key_file2)); + /* Update the DB of the (local) Server */ + $app->db->query("UPDATE web_domain SET ssl_request = '$ssl_request', ssl_cert = '$ssl_cert', ssl_key = '$ssl_key2' WHERE domain = '".$data['new']['domain']."'"); + $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'"); + /* Update also the master-DB of the Server-Farm */ + $app->dbmaster->query("UPDATE web_domain SET ssl_request = '$ssl_request', ssl_cert = '$ssl_cert', ssl_key = '$ssl_key2' WHERE domain = '".$data['new']['domain']."'"); + $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'"); + } + + //* Save a SSL certificate to disk + if($data["new"]["ssl_action"] == 'save') { + $this->ssl_certificate_changed = true; + $ssl_dir = $data["new"]["document_root"]."/ssl"; + $domain = ($data["new"]["ssl_domain"] != '')?$data["new"]["ssl_domain"]:$data["new"]["domain"]; + $key_file = $ssl_dir.'/'.$domain.'.key.org'; + $key_file2 = $ssl_dir.'/'.$domain.'.key'; + $csr_file = $ssl_dir.'/'.$domain.".csr"; + $crt_file = $ssl_dir.'/'.$domain.".crt"; + //$bundle_file = $ssl_dir.'/'.$domain.".bundle"; + + //* Backup files + if(file_exists($key_file)){ + $app->system->copy($key_file,$key_file.'~'); + $app->system->chmod($key_file.'~',0400); + } + if(file_exists($key_file2)){ + $app->system->copy($key_file2,$key_file2.'~'); + $app->system->chmod($key_file2.'~',0400); + } + if(file_exists($csr_file)) $app->system->copy($csr_file,$csr_file.'~'); + if(file_exists($crt_file)) $app->system->copy($crt_file,$crt_file.'~'); + //if(file_exists($bundle_file)) $app->system->copy($bundle_file,$bundle_file.'~'); + + //* Write new ssl files + if(trim($data["new"]["ssl_request"]) != '') $app->system->file_put_contents($csr_file,$data["new"]["ssl_request"]); + if(trim($data["new"]["ssl_cert"]) != '') $app->system->file_put_contents($crt_file,$data["new"]["ssl_cert"]); + //if(trim($data["new"]["ssl_bundle"]) != '') $app->system->file_put_contents($bundle_file,$data["new"]["ssl_bundle"]); + if(trim($data["new"]["ssl_key"]) != '') $app->system->file_put_contents($key_file2,$data["new"]["ssl_key"]); + $app->system->chmod($key_file2,0400); + + // for nginx, bundle files have to be appended to the certificate file + if(trim($data["new"]["ssl_bundle"]) != ''){ + if(file_exists($crt_file)){ + $crt_file_contents = trim($app->system->file_get_contents($crt_file)); + } else { + $crt_file_contents = ''; + } + if($crt_file_contents != '') $crt_file_contents .= "\n"; + $crt_file_contents .= $data["new"]["ssl_bundle"]; + $app->system->file_put_contents($crt_file,$app->file->unix_nl($crt_file_contents)); + unset($crt_file_contents); + } + /* Update the DB of the (local) Server */ + $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'"); + + /* Update also the master-DB of the Server-Farm */ + $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'"); + $app->log('Saving SSL Cert for: '.$domain,LOGLEVEL_DEBUG); + } + + //* Delete a SSL certificate + if($data['new']['ssl_action'] == 'del') { + $ssl_dir = $data['new']['document_root'].'/ssl'; + $domain = ($data["new"]["ssl_domain"] != '')?$data["new"]["ssl_domain"]:$data["new"]["domain"]; + $csr_file = $ssl_dir.'/'.$domain.'.csr'; + $crt_file = $ssl_dir.'/'.$domain.'.crt'; + //$bundle_file = $ssl_dir.'/'.$domain.'.bundle'; + if(file_exists($web_config['CA_path'].'/openssl.cnf') && !is_link($web_config['CA_path'].'/openssl.cnf')) + { + exec("openssl ca -batch -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -revoke $crt_file"); + $app->log("Revoking CA-signed SSL Cert for: $domain",LOGLEVEL_DEBUG); + }; + $app->system->unlink($csr_file); + $app->system->unlink($crt_file); + //$app->system->unlink($bundle_file); + /* Update the DB of the (local) Server */ + $app->db->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = '".$data['new']['domain']."'"); + $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'"); + /* Update also the master-DB of the Server-Farm */ + $app->dbmaster->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = '".$data['new']['domain']."'"); + $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'"); + $app->log('Deleting SSL Cert for: '.$domain,LOGLEVEL_DEBUG); + } + + } + + + function insert($event_name,$data) { + global $app, $conf; + + $this->action = 'insert'; + // just run the update function + $this->update($event_name,$data); + + + } + + + function update($event_name,$data) { + global $app, $conf; + + //* Check if the apache plugin is enabled + if(@is_link('/usr/local/ispconfig/server/plugins-enabled/apache2_plugin.inc.php')) { + $app->log('The nginx plugin cannot be used together with the apache2 plugin.',LOGLEVEL_WARN); + return 0; + } + + if($this->action != 'insert') $this->action = 'update'; + + if($data['new']['type'] != 'vhost' && $data['new']['type'] != 'vhostsubdomain' && $data['new']['parent_domain_id'] > 0) { + + $old_parent_domain_id = intval($data['old']['parent_domain_id']); + $new_parent_domain_id = intval($data['new']['parent_domain_id']); + + // If the parent_domain_id has been changed, we will have to update the old site as well. + if($this->action == 'update' && $data['new']['parent_domain_id'] != $data['old']['parent_domain_id']) { + $tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = '.$old_parent_domain_id." AND active = 'y'"); + $data['new'] = $tmp; + $data['old'] = $tmp; + $this->action = 'update'; + $this->update($event_name,$data); + } + + // This is not a vhost, so we need to update the parent record instead. + $tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = '.$new_parent_domain_id." AND active = 'y'"); + $data['new'] = $tmp; + $data['old'] = $tmp; + $this->action = 'update'; + } + + // load the server configuration options + $app->uses('getconf'); + $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); + + //* Check if this is a chrooted setup + if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) { + $nginx_chrooted = true; + $app->log('Info: nginx is chrooted.',LOGLEVEL_DEBUG); + } else { + $nginx_chrooted = false; + } + + if($data['new']['document_root'] == '') { + if($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain') $app->log('document_root not set',LOGLEVEL_WARN); + return 0; + } + if($data['new']['system_user'] == 'root' or $data['new']['system_group'] == 'root') { + $app->log('Websites cannot be owned by the root user or group.',LOGLEVEL_WARN); + return 0; + } + if(trim($data['new']['domain']) == '') { + $app->log('domain is empty',LOGLEVEL_WARN); + return 0; + } + + $web_folder = 'web'; + $log_folder = 'log'; + if($data['new']['type'] == 'vhostsubdomain') { + $tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = '.intval($data['new']['parent_domain_id'])); + $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['new']['domain']); + if($subdomain_host == '') $subdomain_host = 'web'.$data['new']['domain_id']; + $web_folder = $data['new']['web_folder']; + $log_folder .= '/' . $subdomain_host; + unset($tmp); + } + + // Create group and user, if not exist + $app->uses('system'); + + if($web_config['connect_userid_to_webid'] == 'y') { + //* Calculate the uid and gid + $connect_userid_to_webid_start = ($web_config['connect_userid_to_webid_start'] < 1000)?1000:intval($web_config['connect_userid_to_webid_start']); + $fixed_uid_gid = intval($connect_userid_to_webid_start + $data['new']['domain_id']); + $fixed_uid_param = '--uid '.$fixed_uid_gid; + $fixed_gid_param = '--gid '.$fixed_uid_gid; + + //* Check if a ispconfigend user and group exists and create them + if(!$app->system->is_group('ispconfigend')) { + exec('groupadd --gid '.($connect_userid_to_webid_start + 10000).' ispconfigend'); + } + if(!$app->system->is_user('ispconfigend')) { + exec('useradd -g ispconfigend -d /usr/local/ispconfig --uid '.($connect_userid_to_webid_start + 10000).' ispconfigend'); + } + } else { + $fixed_uid_param = ''; + $fixed_gid_param = ''; + } + + $groupname = escapeshellcmd($data['new']['system_group']); + if($data['new']['system_group'] != '' && !$app->system->is_group($data['new']['system_group'])) { + exec('groupadd '.$fixed_gid_param.' '.$groupname); + if($nginx_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' groupadd '.$groupname); + $app->log('Adding the group: '.$groupname,LOGLEVEL_DEBUG); + } + + $username = escapeshellcmd($data['new']['system_user']); + if($data['new']['system_user'] != '' && !$app->system->is_user($data['new']['system_user'])) { + if($web_config['add_web_users_to_sshusers_group'] == 'y') { + exec('useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param -G sshusers $username -s /bin/false"); + if($nginx_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param -G sshusers $username -s /bin/false"); + } else { + exec('useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param $username -s /bin/false"); + if($nginx_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param $username -s /bin/false"); + } + $app->log('Adding the user: '.$username,LOGLEVEL_DEBUG); + } + + //* If the client of the site has been changed, we have a change of the document root + if($this->action == 'update' && $data['new']['document_root'] != $data['old']['document_root']) { + + //* Get the old client ID + $old_client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = '.intval($data['old']['sys_groupid'])); + $old_client_id = intval($old_client['client_id']); + unset($old_client); + + //* Remove the old symlinks + $tmp_symlinks_array = explode(':',$web_config['website_symlinks']); + if(is_array($tmp_symlinks_array)) { + foreach($tmp_symlinks_array as $tmp_symlink) { + $tmp_symlink = str_replace('[client_id]',$old_client_id,$tmp_symlink); + $tmp_symlink = str_replace('[website_domain]',$data['old']['domain'],$tmp_symlink); + // Remove trailing slash + if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); + // create the symlinks, if not exist + if(is_link($tmp_symlink)) { + exec('rm -f '.escapeshellcmd($tmp_symlink)); + $app->log('Removed symlink: rm -f '.$tmp_symlink,LOGLEVEL_DEBUG); + } + } + } + + if($data["new"]["type"] != "vhostsubdomain") { + //* Move the site data + $tmp_docroot = explode('/',$data['new']['document_root']); + unset($tmp_docroot[count($tmp_docroot)-1]); + $new_dir = implode('/',$tmp_docroot); + + $tmp_docroot = explode('/',$data['old']['document_root']); + unset($tmp_docroot[count($tmp_docroot)-1]); + $old_dir = implode('/',$tmp_docroot); + + //* Check if there is already some data in the new docroot and rename it as we need a clean path to move the existing site to the new path + if(@is_dir($data['new']['document_root'])) { + $app->system->web_folder_protection($data['new']['document_root'],false); + $app->system->rename($data['new']['document_root'],$data['new']['document_root'].'_bak_'.date('Y_m_d_H_i_s')); + $app->log('Renaming existing directory in new docroot location. mv '.$data['new']['document_root'].' '.$data['new']['document_root'].'_bak_'.date('Y_m_d_H_i_s'),LOGLEVEL_DEBUG); + } + + //* Create new base directory, if it does not exist yet + if(!is_dir($new_dir)) $app->system->mkdirpath($new_dir); + $app->system->web_folder_protection($data['old']['document_root'],false); + exec('mv '.escapeshellarg($data['old']['document_root']).' '.escapeshellarg($new_dir)); + //$app->system->rename($data['old']['document_root'],$new_dir); + $app->log('Moving site to new document root: mv '.$data['old']['document_root'].' '.$new_dir,LOGLEVEL_DEBUG); + + // Handle the change in php_open_basedir + $data['new']['php_open_basedir'] = str_replace($data['old']['document_root'],$data['new']['document_root'],$data['old']['php_open_basedir']); + + //* Change the owner of the website files to the new website owner + exec('chown --recursive --from='.escapeshellcmd($data['old']['system_user']).':'.escapeshellcmd($data['old']['system_group']).' '.escapeshellcmd($data['new']['system_user']).':'.escapeshellcmd($data['new']['system_group']).' '.$new_dir); + + //* Change the home directory and group of the website user + $command = 'killall -u '.escapeshellcmd($data['new']['system_user']).' ; usermod'; + $command .= ' --home '.escapeshellcmd($data['new']['document_root']); + $command .= ' --gid '.escapeshellcmd($data['new']['system_group']); + $command .= ' '.escapeshellcmd($data['new']['system_user']).' 2>/dev/null'; + exec($command); + } + + if($nginx_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command); + + //* Change the log mount + $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.' none bind'; + $app->system->removeLine('/etc/fstab',$fstab_line); + $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.' none bind,nobootwait 0 0'; + $app->system->replaceLine('/etc/fstab',$fstab_line,$fstab_line,1,1); + + } + + //print_r($data); + + // Check if the directories are there and create them if necessary. + $app->system->web_folder_protection($data['new']['document_root'],false); + + if(!is_dir($data['new']['document_root'].'/' . $web_folder)) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder); + if(!is_dir($data['new']['document_root'].'/' . $web_folder . '/error') and $data['new']['errordocs']) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder . '/error'); + //if(!is_dir($data['new']['document_root'].'/'.$log_folder)) exec('mkdir -p '.$data['new']['document_root'].'/'.$log_folder); + if(!is_dir($data['new']['document_root'].'/ssl')) $app->system->mkdirpath($data['new']['document_root'].'/ssl'); + if(!is_dir($data['new']['document_root'].'/cgi-bin')) $app->system->mkdirpath($data['new']['document_root'].'/cgi-bin'); + if(!is_dir($data['new']['document_root'].'/tmp')) $app->system->mkdirpath($data['new']['document_root'].'/tmp'); + //if(!is_dir($data['new']['document_root'].'/webdav')) $app->system->mkdirpath($data['new']['document_root'].'/webdav'); + + //* Create the new private directory + if(!is_dir($data['new']['document_root'].'/private')) { + $app->system->mkdirpath($data['new']['document_root'].'/private'); + $app->system->chmod($data['new']['document_root'].'/private',0710); + $app->system->chown($data['new']['document_root'].'/private',$username); + $app->system->chgrp($data['new']['document_root'].'/private',$groupname); + } + + + // Remove the symlink for the site, if site is renamed + if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) { + if(is_dir('/var/log/ispconfig/httpd/'.$data['old']['domain'])) exec('rm -rf /var/log/ispconfig/httpd/'.$data['old']['domain']); + if(is_link($data['old']['document_root'].'/'.$log_folder)) $app->system->unlink($data['old']['document_root'].'/'.$log_folder); + + //* remove old log mount + $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.' none bind'; + $app->system->removeLine('/etc/fstab',$fstab_line); + + //* Unmount log directory + exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder)); + } + + //* Create the log dir if nescessary and mount it + if(!is_dir($data['new']['document_root'].'/'.$log_folder) || !is_dir('/var/log/ispconfig/httpd/'.$data['new']['domain']) || is_link($data['new']['document_root'].'/'.$log_folder)) { + if(is_link($data['new']['document_root'].'/'.$log_folder)) unlink($data['new']['document_root'].'/'.$log_folder); + if(!is_dir('/var/log/ispconfig/httpd/'.$data['new']['domain'])) exec('mkdir -p /var/log/ispconfig/httpd/'.$data['new']['domain']); + $app->system->mkdirpath($data['new']['document_root'].'/'.$log_folder); + $app->system->chown($data['new']['document_root'].'/'.$log_folder,'root'); + $app->system->chgrp($data['new']['document_root'].'/'.$log_folder,'root'); + $app->system->chmod($data['new']['document_root'].'/'.$log_folder,0755); + exec('mount --bind '.escapeshellarg('/var/log/ispconfig/httpd/'.$data['new']['domain']).' '.escapeshellarg($data['new']['document_root'].'/'.$log_folder)); + //* add mountpoint to fstab + $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.' none bind,nobootwait 0 0'; + $app->system->replaceLine('/etc/fstab',$fstab_line,$fstab_line,1,1); + } + + $app->system->web_folder_protection($data['new']['document_root'],true); + + // Get the client ID + $client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = '.intval($data['new']['sys_groupid'])); + $client_id = intval($client['client_id']); + unset($client); + + // Remove old symlinks, if site is renamed + if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) { + $tmp_symlinks_array = explode(':',$web_config['website_symlinks']); + if(is_array($tmp_symlinks_array)) { + foreach($tmp_symlinks_array as $tmp_symlink) { + $tmp_symlink = str_replace('[client_id]',$client_id,$tmp_symlink); + $tmp_symlink = str_replace('[website_domain]',$data['old']['domain'],$tmp_symlink); + // Remove trailing slash + if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); + // remove the symlinks, if not exist + if(is_link($tmp_symlink)) { + exec('rm -f '.escapeshellcmd($tmp_symlink)); + $app->log('Removed symlink: rm -f '.$tmp_symlink,LOGLEVEL_DEBUG); + } + } + } + } + + // Create the symlinks for the sites + $tmp_symlinks_array = explode(':',$web_config['website_symlinks']); + if(is_array($tmp_symlinks_array)) { + foreach($tmp_symlinks_array as $tmp_symlink) { + $tmp_symlink = str_replace('[client_id]',$client_id,$tmp_symlink); + $tmp_symlink = str_replace('[website_domain]',$data['new']['domain'],$tmp_symlink); + // Remove trailing slash + if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); + //* Remove symlink if target folder has been changed. + if($data['old']['document_root'] != '' && $data['old']['document_root'] != $data['new']['document_root'] && is_link($tmp_symlink)) { + $app->system->unlink($tmp_symlink); + } + // create the symlinks, if not exist + if(!is_link($tmp_symlink)) { +// exec("ln -s ".escapeshellcmd($data["new"]["document_root"])."/ ".escapeshellcmd($tmp_symlink)); + if ($web_config["website_symlinks_rel"] == 'y') { + $this->create_relative_link(escapeshellcmd($data["new"]["document_root"]), escapeshellcmd($tmp_symlink)); + } else { + exec("ln -s ".escapeshellcmd($data["new"]["document_root"])."/ ".escapeshellcmd($tmp_symlink)); + } + + $app->log('Creating symlink: ln -s '.$data['new']['document_root'].'/ '.$tmp_symlink,LOGLEVEL_DEBUG); + } + } + } + + + + // Install the Standard or Custom Error, Index and other related files + // /usr/local/ispconfig/server/conf is for the standard files + // /usr/local/ispconfig/server/conf-custom is for the custom files + // setting a local var here + + // normally $conf['templates'] = "/usr/local/ispconfig/server/conf"; + if($this->action == 'insert' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain')) { + + // Copy the error pages + if($data['new']['errordocs']) { + $error_page_path = escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/error/'; + if (file_exists($conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']),0,2))) { + exec('cp ' . $conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']),0,2).'/* '.$error_page_path); + } + else { + if (file_exists($conf['rootpath'] . '/conf-custom/error/400.html')) { + exec('cp '. $conf['rootpath'] . '/conf-custom/error/*.html '.$error_page_path); + } + else { + exec('cp ' . $conf['rootpath'] . '/conf/error/'.substr(escapeshellcmd($conf['language']),0,2).'/* '.$error_page_path); + } + } + exec('chmod -R a+r '.$error_page_path); + } + + if (file_exists($conf['rootpath'] . '/conf-custom/index/standard_index.html_'.substr(escapeshellcmd($conf['language']),0,2))) { + exec('cp ' . $conf['rootpath'] . '/conf-custom/index/standard_index.html_'.substr(escapeshellcmd($conf['language']),0,2).' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html'); + + if(is_file($conf['rootpath'] . '/conf-custom/index/favicon.ico')) { + exec('cp ' . $conf['rootpath'] . '/conf-custom/index/favicon.ico '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); + } + if(is_file($conf['rootpath'] . '/conf-custom/index/robots.txt')) { + exec('cp ' . $conf['rootpath'] . '/conf-custom/index/robots.txt '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); + } + if(is_file($conf['rootpath'] . '/conf-custom/index/.htaccess')) { + exec('cp ' . $conf['rootpath'] . '/conf-custom/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); + } + } + else { + if (file_exists($conf['rootpath'] . '/conf-custom/index/standard_index.html')) { + exec('cp ' . $conf['rootpath'] . '/conf-custom/index/standard_index.html '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html'); + } + else { + exec('cp ' . $conf['rootpath'] . '/conf/index/standard_index.html_'.substr(escapeshellcmd($conf['language']),0,2).' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html'); + if(is_file($conf['rootpath'] . '/conf/index/favicon.ico')) exec('cp ' . $conf['rootpath'] . '/conf/index/favicon.ico '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); + if(is_file($conf['rootpath'] . '/conf/index/robots.txt')) exec('cp ' . $conf['rootpath'] . '/conf/index/robots.txt '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); + if(is_file($conf['rootpath'] . '/conf/index/.htaccess')) exec('cp ' . $conf['rootpath'] . '/conf/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); + } + } + exec('chmod -R a+r '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); + + //** Copy the error documents on update when the error document checkbox has been activated and was deactivated before + } elseif ($this->action == 'update' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain') && $data['old']['errordocs'] == 0 && $data['new']['errordocs'] == 1) { + + $error_page_path = escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/error/'; + if (file_exists($conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']),0,2))) { + exec('cp ' . $conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']),0,2).'/* '.$error_page_path); + } + else { + if (file_exists($conf['rootpath'] . '/conf-custom/error/400.html')) { + exec('cp ' . $conf['rootpath'] . '/conf-custom/error/*.html '.$error_page_path); + } + else { + exec('cp ' . $conf['rootpath'] . '/conf/error/'.substr(escapeshellcmd($conf['language']),0,2).'/* '.$error_page_path); + } + } + exec('chmod -R a+r '.$error_page_path); + exec('chown -R '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.$error_page_path); + } // end copy error docs + + // Set the quota for the user, but only for vhosts, not vhostsubdomains + if($username != '' && $app->system->is_user($username) && $data['new']['type'] == 'vhost') { + if($data['new']['hd_quota'] > 0) { + $blocks_soft = $data['new']['hd_quota'] * 1024; + $blocks_hard = $blocks_soft + 1024; + } else { + $blocks_soft = $blocks_hard = 0; + } + exec("setquota -u $username $blocks_soft $blocks_hard 0 0 -a &> /dev/null"); + exec('setquota -T -u '.$username.' 604800 604800 -a &> /dev/null'); + } + + if($this->action == 'insert' || $data["new"]["system_user"] != $data["old"]["system_user"]) { + // Chown and chmod the directories below the document root + $this->_exec('chown -R '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder); + // The document root itself has to be owned by root in normal level and by the web owner in security level 20 + if($web_config['security_level'] == 20) { + $this->_exec('chown '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder); + } else { + $this->_exec('chown root:root '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder); + } + } + + //* add the nginx user to the client group if this is a vhost and security level is set to high, no matter if this is an insert or update and regardless of set_folder_permissions_on_update + if($data['new']['type'] == 'vhost' && $web_config['security_level'] == 20) $app->system->add_user_to_group($groupname, escapeshellcmd($web_config['nginx_user'])); + + //* If the security level is set to high + if(($this->action == 'insert' && $data['new']['type'] == 'vhost') or ($web_config['set_folder_permissions_on_update'] == 'y' && $data['new']['type'] == 'vhost')) { + + $app->system->web_folder_protection($data['new']['document_root'],false); + + //* Check if we have the new private folder and create it if nescessary + if(!is_dir($data['new']['document_root'].'/private')) $app->system->mkdir($data['new']['document_root'].'/private'); + + if($web_config['security_level'] == 20) { + + $app->system->chmod($data['new']['document_root'],0755); + $app->system->chmod($data['new']['document_root'].'/web',0710); + //$app->system->chmod($data['new']['document_root'].'/webdav',0710); + $app->system->chmod($data['new']['document_root'].'/private',0710); + $app->system->chmod($data['new']['document_root'].'/ssl',0755); + + // make tmp directory writable for nginx and the website users + $app->system->chmod($data['new']['document_root'].'/tmp',0777); + + // Set Log directory to 755 to make the logs accessible by the FTP user + if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { + $app->system->chmod($data['new']['document_root'].'/'.$log_folder,0755); + } + + if($web_config['add_web_users_to_sshusers_group'] == 'y') { + $command = 'usermod'; + $command .= ' --groups sshusers'; + $command .= ' '.escapeshellcmd($data['new']['system_user']).' 2>/dev/null'; + $this->_exec($command); + } + + //* if we have a chrooted nginx environment + if($nginx_chrooted) { + $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command); + + //* add the nginx user to the client group in the chroot environment + $tmp_groupfile = $app->system->server_conf['group_datei']; + $app->system->server_conf['group_datei'] = $web_config['website_basedir'].'/etc/group'; + $app->system->add_user_to_group($groupname, escapeshellcmd($web_config['nginx_user'])); + $app->system->server_conf['group_datei'] = $tmp_groupfile; + unset($tmp_groupfile); + } + + //* Chown all default directories + $app->system->chown($data['new']['document_root'],'root'); + $app->system->chgrp($data['new']['document_root'],'root'); + $app->system->chown($data['new']['document_root'].'/cgi-bin',$username); + $app->system->chgrp($data['new']['document_root'].'/cgi-bin',$groupname); + if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { + $app->system->chown($data['new']['document_root'].'/'.$log_folder,'root',false); + $app->system->chgrp($data['new']['document_root'].'/'.$log_folder,$groupname,false); + } + $app->system->chown($data['new']['document_root'].'/ssl','root'); + $app->system->chgrp($data['new']['document_root'].'/ssl','root'); + $app->system->chown($data['new']['document_root'].'/tmp',$username); + $app->system->chgrp($data['new']['document_root'].'/tmp',$groupname); + $app->system->chown($data['new']['document_root'].'/web',$username); + $app->system->chgrp($data['new']['document_root'].'/web',$groupname); + $app->system->chown($data['new']['document_root'].'/web/error',$username); + $app->system->chgrp($data['new']['document_root'].'/web/error',$groupname); + $app->system->chown($data['new']['document_root'].'/web/stats',$username); + $app->system->chgrp($data['new']['document_root'].'/web/stats',$groupname); + //$app->system->chown($data['new']['document_root'].'/webdav',$username); + //$app->system->chgrp($data['new']['document_root'].'/webdav',$groupname); + $app->system->chown($data['new']['document_root'].'/private',$username); + $app->system->chgrp($data['new']['document_root'].'/private',$groupname); + + // If the security Level is set to medium + } else { + + $app->system->chmod($data['new']['document_root'],0755); + $app->system->chmod($data['new']['document_root'].'/web',0755); + //$app->system->chmod($data['new']['document_root'].'/webdav',0755); + $app->system->chmod($data['new']['document_root'].'/ssl',0755); + $app->system->chmod($data['new']['document_root'].'/cgi-bin',0755); + + // make temp directory writable for nginx and the website users + $app->system->chmod($data['new']['document_root'].'/tmp',0777); + + // Set Log directory to 755 to make the logs accessible by the FTP user + if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { + $app->system->chmod($data['new']['document_root'].'/'.$log_folder,0755); + } + + $app->system->chown($data['new']['document_root'],'root'); + $app->system->chgrp($data['new']['document_root'],'root'); + $app->system->chown($data['new']['document_root'].'/cgi-bin',$username); + $app->system->chgrp($data['new']['document_root'].'/cgi-bin',$groupname); + if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { + $app->system->chown($data['new']['document_root'].'/'.$log_folder,'root',false); + $app->system->chgrp($data['new']['document_root'].'/'.$log_folder,$groupname,false); + } + + $app->system->chown($data['new']['document_root'].'/ssl','root'); + $app->system->chgrp($data['new']['document_root'].'/ssl','root'); + $app->system->chown($data['new']['document_root'].'/tmp',$username); + $app->system->chgrp($data['new']['document_root'].'/tmp',$groupname); + $app->system->chown($data['new']['document_root'].'/web',$username); + $app->system->chgrp($data['new']['document_root'].'/web',$groupname); + $app->system->chown($data['new']['document_root'].'/web/error',$username); + $app->system->chgrp($data['new']['document_root'].'/web/error',$groupname); + $app->system->chown($data['new']['document_root'].'/web/stats',$username); + $app->system->chgrp($data['new']['document_root'].'/web/stats',$groupname); + //$app->system->chown($data['new']['document_root'].'/webdav',$username); + //$app->system->chgrp($data['new']['document_root'].'/webdav',$groupname); + } + } elseif(($this->action == 'insert' && $data['new']['type'] == 'vhostsubdomain') or ($web_config['set_folder_permissions_on_update'] == 'y' && $data['new']['type'] == 'vhostsubdomain')) { + if($web_config['security_level'] == 20) { + $app->system->chmod($data['new']['document_root'].'/' . $web_folder,0710); + $app->system->chown($data['new']['document_root'].'/' . $web_folder,$username); + $app->system->chgrp($data['new']['document_root'].'/' . $web_folder,$groupname); + $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/error',$username); + $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/error',$groupname); + $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/stats',$username); + $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/stats',$groupname); + } else { + $app->system->chmod($data['new']['document_root'].'/' . $web_folder,0755); + $app->system->chown($data['new']['document_root'].'/' . $web_folder,$username); + $app->system->chgrp($data['new']['document_root'].'/' . $web_folder,$groupname); + $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/error',$username); + $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/error',$groupname); + $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/stats',$username); + $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/stats',$groupname); + } + } + + //* Protect web folders + $app->system->web_folder_protection($data['new']['document_root'],true); + + if($data['new']['type'] == 'vhost') { + // Change the ownership of the error log to the root user + if(!@is_file('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log')) exec('touch '.escapeshellcmd('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log')); + $app->system->chown('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log','root'); + $app->system->chgrp('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log','root'); + } + + // Change the ownership of the error log to the owner of the website + /* + if(!@is_file($data['new']['document_root'].'/log/error.log')) exec('touch '.escapeshellcmd($data['new']['document_root']).'/log/error.log'); + $app->system->chown($data['new']['document_root'].'/log/error.log',$username); + $app->system->chgrp($data['new']['document_root'].'/log/error.log',$groupname); + */ + + + /* + //* Write the custom php.ini file, if custom_php_ini filed is not empty + $custom_php_ini_dir = $web_config['website_basedir'].'/conf/'.$data['new']['system_user']; + if(!is_dir($web_config['website_basedir'].'/conf')) mkdir($web_config['website_basedir'].'/conf'); + if(trim($data['new']['custom_php_ini']) != '') { + $has_custom_php_ini = true; + if(!is_dir($custom_php_ini_dir)) $app->system->mkdirpath($custom_php_ini_dir); + $php_ini_content = ''; + if($data['new']['php'] == 'mod') { + $master_php_ini_path = $web_config['php_ini_path_apache']; + } else { + if($data["new"]['php'] == 'fast-cgi' && file_exists($fastcgi_config["fastcgi_phpini_path"])) { + $master_php_ini_path = $fastcgi_config["fastcgi_phpini_path"]; + } else { + $master_php_ini_path = $web_config['php_ini_path_cgi']; + } + } + if($master_php_ini_path != '' && substr($master_php_ini_path,-7) == 'php.ini' && is_file($master_php_ini_path)) { + $php_ini_content .= $app->system->file_get_contents($master_php_ini_path)."\n"; + } + $php_ini_content .= str_replace("\r",'',trim($data['new']['custom_php_ini'])); + $app->system->file_put_contents($custom_php_ini_dir.'/php.ini',$php_ini_content); + } else { + $has_custom_php_ini = false; + if(is_file($custom_php_ini_dir.'/php.ini')) $app->system->unlink($custom_php_ini_dir.'/php.ini'); + } + */ + + //* Create the vhost config file + $app->load('tpl'); + + $tpl = new tpl(); + $tpl->newTemplate('nginx_vhost.conf.master'); + + $vhost_data = $data['new']; + //unset($vhost_data['ip_address']); + $vhost_data['web_document_root'] = $data['new']['document_root'].'/' . $web_folder; + $vhost_data['web_document_root_www'] = $web_config['website_basedir'].'/'.$data['new']['domain'].'/' . $web_folder; + $vhost_data['web_basedir'] = $web_config['website_basedir']; + + // IPv6 + if($data['new']['ipv6_address'] != ''){ + $tpl->setVar('ipv6_enabled', 1); + if ($conf['serverconfig']['web']['vhost_rewrite_v6'] == 'y') { + if (isset($conf['serverconfig']['server']['v6_prefix']) && $conf['serverconfig']['server']['v6_prefix'] <> '') { + $explode_v6prefix=explode(':',$conf['serverconfig']['server']['v6_prefix']); + $explode_v6=explode(':',$data['new']['ipv6_address']); + + for ( $i = 0; $i <= count($explode_v6prefix)-3; $i++ ) { + $explode_v6[$i] = $explode_v6prefix[$i]; + } + $data['new']['ipv6_address'] = implode(':',$explode_v6); + $vhost_data['ipv6_address'] = $data['new']['ipv6_address']; + } + } + } + + // PHP-FPM + // Support for multiple PHP versions + /* + if(trim($data['new']['fastcgi_php_version']) != ''){ + $default_php_fpm = false; + list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); + if(substr($custom_php_fpm_ini_dir,-1) != '/') $custom_php_fpm_ini_dir .= '/'; + } else { + $default_php_fpm = true; + } + */ + if($data['new']['php'] != 'no'){ + if(trim($data['new']['fastcgi_php_version']) != ''){ + $default_php_fpm = false; + list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); + if(substr($custom_php_fpm_ini_dir,-1) != '/') $custom_php_fpm_ini_dir .= '/'; + } else { + $default_php_fpm = true; + } + } else { + if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] != 'no'){ + $default_php_fpm = false; + list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version'])); + if(substr($custom_php_fpm_ini_dir,-1) != '/') $custom_php_fpm_ini_dir .= '/'; + } else { + $default_php_fpm = true; + } + } + + if($default_php_fpm){ + $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']); + } else { + $pool_dir = $custom_php_fpm_pool_dir; + } + if(substr($pool_dir,-1) != '/') $pool_dir .= '/'; + $pool_name = 'web'.$data['new']['domain_id']; + $socket_dir = escapeshellcmd($web_config['php_fpm_socket_dir']); + if(substr($socket_dir,-1) != '/') $socket_dir .= '/'; + + if($data['new']['php_fpm_use_socket'] == 'y'){ + $use_tcp = 0; + $use_socket = 1; + } else { + $use_tcp = 1; + $use_socket = 0; + } + $tpl->setVar('use_tcp', $use_tcp); + $tpl->setVar('use_socket', $use_socket); + $fpm_socket = $socket_dir.$pool_name.'.sock'; + $tpl->setVar('fpm_socket', $fpm_socket); + $tpl->setVar('rnd_php_dummy_file', '/'.md5(uniqid(microtime(),1)).'.htm'); + $vhost_data['fpm_port'] = $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1; + + // backwards compatibility; since ISPConfig 3.0.5, the PHP mode for nginx is called 'php-fpm' instead of 'fast-cgi'. The following line makes sure that old web sites that have 'fast-cgi' in the database still get PHP-FPM support. + if($vhost_data['php'] == 'fast-cgi') $vhost_data['php'] = 'php-fpm'; + + // Custom rewrite rules + /* + $final_rewrite_rules = array(); + $custom_rewrite_rules = $data['new']['rewrite_rules']; + // Make sure we only have Unix linebreaks + $custom_rewrite_rules = str_replace("\r\n", "\n", $custom_rewrite_rules); + $custom_rewrite_rules = str_replace("\r", "\n", $custom_rewrite_rules); + $custom_rewrite_rule_lines = explode("\n", $custom_rewrite_rules); + if(is_array($custom_rewrite_rule_lines) && !empty($custom_rewrite_rule_lines)){ + foreach($custom_rewrite_rule_lines as $custom_rewrite_rule_line){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + } + } + $tpl->setLoop('rewrite_rules', $final_rewrite_rules); + */ + + // Custom rewrite rules + $final_rewrite_rules = array(); + + if(isset($data['new']['rewrite_rules']) && trim($data['new']['rewrite_rules']) != '') { + $custom_rewrite_rules = trim($data['new']['rewrite_rules']); + $custom_rewrites_are_valid = true; + // use this counter to make sure all curly brackets are properly closed + $if_level = 0; + // Make sure we only have Unix linebreaks + $custom_rewrite_rules = str_replace("\r\n", "\n", $custom_rewrite_rules); + $custom_rewrite_rules = str_replace("\r", "\n", $custom_rewrite_rules); + $custom_rewrite_rule_lines = explode("\n", $custom_rewrite_rules); + if(is_array($custom_rewrite_rule_lines) && !empty($custom_rewrite_rule_lines)){ + foreach($custom_rewrite_rule_lines as $custom_rewrite_rule_line){ + // ignore comments + if(substr(ltrim($custom_rewrite_rule_line),0,1) == '#'){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + // empty lines + if(trim($custom_rewrite_rule_line) == ''){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + // rewrite + if(preg_match('@^\s*rewrite\s+(^/)?\S+(\$)?\s+\S+(\s+(last|break|redirect|permanent|))?\s*;\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + // if + if(preg_match('@^\s*if\s+\(\s*\$\S+(\s+(\!?(=|~|~\*))\s+(\S+|\".+\"))?\s*\)\s*\{\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + $if_level += 1; + continue; + } + // if - check for files, directories, etc. + if(preg_match('@^\s*if\s+\(\s*\!?-(f|d|e|x)\s+\S+\s*\)\s*\{\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + $if_level += 1; + continue; + } + // break + if(preg_match('@^\s*break\s*;\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + // return code [ text ] + if(preg_match('@^\s*return\s+\d\d\d.*;\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + // return code URL + // return URL + if(preg_match('@^\s*return(\s+\d\d\d)?\s+(http|https|ftp)\://([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&%\$\-]+)*\@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|localhost|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(\:[0-9]+)*(/($|[a-zA-Z0-9\.\,\?\'\\\+&%\$#\=~_\-]+))*\s*;\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + // set + if(preg_match('@^\s*set\s+\$\S+\s+\S+\s*;\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + // closing curly bracket + if(trim($custom_rewrite_rule_line) == '}'){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + $if_level -= 1; + continue; + } + $custom_rewrites_are_valid = false; + break; + } + } + if(!$custom_rewrites_are_valid || $if_level != 0){ + $final_rewrite_rules = array(); + } + } + $tpl->setLoop('rewrite_rules', $final_rewrite_rules); + + // Custom nginx directives + $final_nginx_directives = array(); + $nginx_directives = $data['new']['nginx_directives']; + // Make sure we only have Unix linebreaks + $nginx_directives = str_replace("\r\n", "\n", $nginx_directives); + $nginx_directives = str_replace("\r", "\n", $nginx_directives); + $nginx_directive_lines = explode("\n", $nginx_directives); + if(is_array($nginx_directive_lines) && !empty($nginx_directive_lines)){ + foreach($nginx_directive_lines as $nginx_directive_line){ + $final_nginx_directives[] = array('nginx_directive' => $nginx_directive_line); + } + } + $tpl->setLoop('nginx_directives', $final_nginx_directives); + + // Check if a SSL cert exists + $ssl_dir = $data['new']['document_root'].'/ssl'; + $domain = $data['new']['ssl_domain']; + $key_file = $ssl_dir.'/'.$domain.'.key'; + $crt_file = $ssl_dir.'/'.$domain.'.crt'; + + if($domain!='' && $data['new']['ssl'] == 'y' && @is_file($crt_file) && @is_file($key_file) && (@filesize($crt_file)>0) && (@filesize($key_file)>0)) { + $vhost_data['ssl_enabled'] = 1; + $app->log('Enable SSL for: '.$domain,LOGLEVEL_DEBUG); + } else { + $vhost_data['ssl_enabled'] = 0; + $app->log('SSL Disabled. '.$domain,LOGLEVEL_DEBUG); + } + + // Set SEO Redirect + if($data['new']['seo_redirect'] != ''){ + $vhost_data['seo_redirect_enabled'] = 1; + $tmp_seo_redirects = $this->get_seo_redirects($data['new']); + if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ + foreach($tmp_seo_redirects as $key => $val){ + $vhost_data[$key] = $val; + } + } else { + $vhost_data['seo_redirect_enabled'] = 0; + } + } else { + $vhost_data['seo_redirect_enabled'] = 0; + } + + + + // Rewrite rules + $own_rewrite_rules = array(); + $rewrite_rules = array(); + $local_rewrite_rules = array(); + if($data['new']['redirect_type'] != '' && $data['new']['redirect_path'] != '') { + if(substr($data['new']['redirect_path'],-1) != '/') $data['new']['redirect_path'] .= '/'; + if(substr($data['new']['redirect_path'],0,8) == '[scheme]'){ + if($data['new']['redirect_type'] != 'proxy'){ + $data['new']['redirect_path'] = '$scheme'.substr($data['new']['redirect_path'],8); + } else { + $data['new']['redirect_path'] = 'http'.substr($data['new']['redirect_path'],8); + } + } + + // Custom proxy directives + if($data['new']['redirect_type'] == 'proxy' && trim($data['new']['proxy_directives'] != '')){ + $final_proxy_directives = array(); + $proxy_directives = $data['new']['proxy_directives']; + // Make sure we only have Unix linebreaks + $proxy_directives = str_replace("\r\n", "\n", $proxy_directives); + $proxy_directives = str_replace("\r", "\n", $proxy_directives); + $proxy_directive_lines = explode("\n", $proxy_directives); + if(is_array($proxy_directive_lines) && !empty($proxy_directive_lines)){ + foreach($proxy_directive_lines as $proxy_directive_line){ + $final_proxy_directives[] = array('proxy_directive' => $proxy_directive_line); + } + } + } else { + $final_proxy_directives = false; + } + + switch($data['new']['subdomain']) { + case 'www': + $exclude_own_hostname = ''; + if(substr($data['new']['redirect_path'],0,1) == '/'){ // relative path + if($data['new']['redirect_type'] == 'proxy'){ + $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; + $vhost_data['web_document_root_www'] .= substr($data['new']['redirect_path'],0,-1); + break; + } + $rewrite_exclude = '(?!/\b('.substr($data['new']['redirect_path'],1,-1).(substr($data['new']['redirect_path'],1,-1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').')\b)/'; + } else { // URL - check if URL is local + $tmp_redirect_path = $data['new']['redirect_path']; + if(substr($tmp_redirect_path,0,7) == '$scheme') $tmp_redirect_path = 'http'.substr($tmp_redirect_path,7); + $tmp_redirect_path_parts = parse_url($tmp_redirect_path); + if(($tmp_redirect_path_parts['host'] == $data['new']['domain'] || $tmp_redirect_path_parts['host'] == 'www.'.$data['new']['domain']) && ($tmp_redirect_path_parts['port'] == '80' || $tmp_redirect_path_parts['port'] == '443' || !isset($tmp_redirect_path_parts['port']))){ + // URL is local + if(substr($tmp_redirect_path_parts['path'],-1) == '/') $tmp_redirect_path_parts['path'] = substr($tmp_redirect_path_parts['path'],0,-1); + if(substr($tmp_redirect_path_parts['path'],0,1) != '/') $tmp_redirect_path_parts['path'] = '/'.$tmp_redirect_path_parts['path']; + //$rewrite_exclude = '((?!'.$tmp_redirect_path_parts['path'].'))'; + if($data['new']['redirect_type'] == 'proxy'){ + $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; + $vhost_data['web_document_root_www'] .= $tmp_redirect_path_parts['path']; + break; + } else { + $rewrite_exclude = '(?!/\b('.substr($tmp_redirect_path_parts['path'],1).(substr($tmp_redirect_path_parts['path'],1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').')\b)/'; + $exclude_own_hostname = $tmp_redirect_path_parts['host']; + } + } else { + // external URL + $rewrite_exclude = '(.?)/'; + if($data['new']['redirect_type'] == 'proxy'){ + $vhost_data['use_proxy'] = 'y'; + $rewrite_subdir = $tmp_redirect_path_parts['path']; + if(substr($rewrite_subdir,0,1) == '/') $rewrite_subdir = substr($rewrite_subdir,1); + if(substr($rewrite_subdir,-1) != '/') $rewrite_subdir .= '/'; + if($rewrite_subdir == '/') $rewrite_subdir = ''; + } + } + unset($tmp_redirect_path); + unset($tmp_redirect_path_parts); + } + $own_rewrite_rules[] = array( 'rewrite_domain' => '^'.$this->_rewrite_quote($data['new']['domain']), + 'rewrite_type' => ($data['new']['redirect_type'] == 'no')?'':$data['new']['redirect_type'], + 'rewrite_target' => $data['new']['redirect_path'], + 'rewrite_exclude' => $rewrite_exclude, + 'rewrite_subdir' => $rewrite_subdir, + 'exclude_own_hostname' => $exclude_own_hostname, + 'proxy_directives' => $final_proxy_directives, + 'use_rewrite' => ($data['new']['redirect_type'] == 'proxy' ? false:true), + 'use_proxy' => ($data['new']['redirect_type'] == 'proxy' ? true:false)); + break; + case '*': + $exclude_own_hostname = ''; + if(substr($data['new']['redirect_path'],0,1) == '/'){ // relative path + if($data['new']['redirect_type'] == 'proxy'){ + $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; + $vhost_data['web_document_root_www'] .= substr($data['new']['redirect_path'],0,-1); + break; + } + $rewrite_exclude = '(?!/\b('.substr($data['new']['redirect_path'],1,-1).(substr($data['new']['redirect_path'],1,-1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').')\b)/'; + } else { // URL - check if URL is local + $tmp_redirect_path = $data['new']['redirect_path']; + if(substr($tmp_redirect_path,0,7) == '$scheme') $tmp_redirect_path = 'http'.substr($tmp_redirect_path,7); + $tmp_redirect_path_parts = parse_url($tmp_redirect_path); + + //if($is_serveralias && ($tmp_redirect_path_parts['port'] == '80' || $tmp_redirect_path_parts['port'] == '443' || !isset($tmp_redirect_path_parts['port']))){ + if($this->url_is_local($tmp_redirect_path_parts['host'], $data['new']['domain_id']) && ($tmp_redirect_path_parts['port'] == '80' || $tmp_redirect_path_parts['port'] == '443' || !isset($tmp_redirect_path_parts['port']))){ + // URL is local + if(substr($tmp_redirect_path_parts['path'],-1) == '/') $tmp_redirect_path_parts['path'] = substr($tmp_redirect_path_parts['path'],0,-1); + if(substr($tmp_redirect_path_parts['path'],0,1) != '/') $tmp_redirect_path_parts['path'] = '/'.$tmp_redirect_path_parts['path']; + //$rewrite_exclude = '((?!'.$tmp_redirect_path_parts['path'].'))'; + if($data['new']['redirect_type'] == 'proxy'){ + $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; + $vhost_data['web_document_root_www'] .= $tmp_redirect_path_parts['path']; + break; + } else { + $rewrite_exclude = '(?!/\b('.substr($tmp_redirect_path_parts['path'],1).(substr($tmp_redirect_path_parts['path'],1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').')\b)/'; + $exclude_own_hostname = $tmp_redirect_path_parts['host']; + } + } else { + // external URL + $rewrite_exclude = '(.?)/'; + if($data['new']['redirect_type'] == 'proxy'){ + $vhost_data['use_proxy'] = 'y'; + $rewrite_subdir = $tmp_redirect_path_parts['path']; + if(substr($rewrite_subdir,0,1) == '/') $rewrite_subdir = substr($rewrite_subdir,1); + if(substr($rewrite_subdir,-1) != '/') $rewrite_subdir .= '/'; + if($rewrite_subdir == '/') $rewrite_subdir = ''; + } + } + unset($tmp_redirect_path); + unset($tmp_redirect_path_parts); + } + $own_rewrite_rules[] = array( 'rewrite_domain' => '(^|\.)'.$this->_rewrite_quote($data['new']['domain']), + 'rewrite_type' => ($data['new']['redirect_type'] == 'no')?'':$data['new']['redirect_type'], + 'rewrite_target' => $data['new']['redirect_path'], + 'rewrite_exclude' => $rewrite_exclude, + 'rewrite_subdir' => $rewrite_subdir, + 'exclude_own_hostname' => $exclude_own_hostname, + 'proxy_directives' => $final_proxy_directives, + 'use_rewrite' => ($data['new']['redirect_type'] == 'proxy' ? false:true), + 'use_proxy' => ($data['new']['redirect_type'] == 'proxy' ? true:false)); + break; + default: + if(substr($data['new']['redirect_path'],0,1) == '/'){ // relative path + $exclude_own_hostname = ''; + if($data['new']['redirect_type'] == 'proxy'){ + $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; + $vhost_data['web_document_root_www'] .= substr($data['new']['redirect_path'],0,-1); + break; + } + $rewrite_exclude = '(?!/\b('.substr($data['new']['redirect_path'],1,-1).(substr($data['new']['redirect_path'],1,-1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').')\b)/'; + } else { // URL - check if URL is local + $tmp_redirect_path = $data['new']['redirect_path']; + if(substr($tmp_redirect_path,0,7) == '$scheme') $tmp_redirect_path = 'http'.substr($tmp_redirect_path,7); + $tmp_redirect_path_parts = parse_url($tmp_redirect_path); + if($tmp_redirect_path_parts['host'] == $data['new']['domain'] && ($tmp_redirect_path_parts['port'] == '80' || $tmp_redirect_path_parts['port'] == '443' || !isset($tmp_redirect_path_parts['port']))){ + // URL is local + if(substr($tmp_redirect_path_parts['path'],-1) == '/') $tmp_redirect_path_parts['path'] = substr($tmp_redirect_path_parts['path'],0,-1); + if(substr($tmp_redirect_path_parts['path'],0,1) != '/') $tmp_redirect_path_parts['path'] = '/'.$tmp_redirect_path_parts['path']; + //$rewrite_exclude = '((?!'.$tmp_redirect_path_parts['path'].'))'; + if($data['new']['redirect_type'] == 'proxy'){ + $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; + $vhost_data['web_document_root_www'] .= $tmp_redirect_path_parts['path']; + break; + } else { + $rewrite_exclude = '(?!/\b('.substr($tmp_redirect_path_parts['path'],1).(substr($tmp_redirect_path_parts['path'],1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').')\b)/'; + $exclude_own_hostname = $tmp_redirect_path_parts['host']; + } + } else { + // external URL + $rewrite_exclude = '(.?)/'; + if($data['new']['redirect_type'] == 'proxy'){ + $vhost_data['use_proxy'] = 'y'; + $rewrite_subdir = $tmp_redirect_path_parts['path']; + if(substr($rewrite_subdir,0,1) == '/') $rewrite_subdir = substr($rewrite_subdir,1); + if(substr($rewrite_subdir,-1) != '/') $rewrite_subdir .= '/'; + if($rewrite_subdir == '/') $rewrite_subdir = ''; + } + } + unset($tmp_redirect_path); + unset($tmp_redirect_path_parts); + } + $own_rewrite_rules[] = array( 'rewrite_domain' => '^'.$this->_rewrite_quote($data['new']['domain']), + 'rewrite_type' => ($data['new']['redirect_type'] == 'no')?'':$data['new']['redirect_type'], + 'rewrite_target' => $data['new']['redirect_path'], + 'rewrite_exclude' => $rewrite_exclude, + 'rewrite_subdir' => $rewrite_subdir, + 'exclude_own_hostname' => $exclude_own_hostname, + 'proxy_directives' => $final_proxy_directives, + 'use_rewrite' => ($data['new']['redirect_type'] == 'proxy' ? false:true), + 'use_proxy' => ($data['new']['redirect_type'] == 'proxy' ? true:false)); + } + } + + $tpl->setVar($vhost_data); + + $server_alias = array(); + + // get autoalias + $auto_alias = $web_config['website_autoalias']; + if($auto_alias != '') { + // get the client username + $client = $app->db->queryOneRecord("SELECT `username` FROM `client` WHERE `client_id` = '" . intval($client_id) . "'"); + $aa_search = array('[client_id]', '[website_id]', '[client_username]', '[website_domain]'); + $aa_replace = array($client_id, $data['new']['domain_id'], $client['username'], $data['new']['domain']); + $auto_alias = str_replace($aa_search, $aa_replace, $auto_alias); + unset($client); + unset($aa_search); + unset($aa_replace); + $server_alias[] .= $auto_alias.' '; + } + + switch($data['new']['subdomain']) { + case 'www': + $server_alias[] = 'www.'.$data['new']['domain'].' '; + break; + case '*': + $server_alias[] = '*.'.$data['new']['domain'].' '; + break; + } + + // get alias domains (co-domains and subdomains) + $aliases = $app->db->queryAllRecords('SELECT * FROM web_domain WHERE parent_domain_id = '.$data['new']['domain_id']." AND active = 'y' AND type != 'vhostsubdomain'"); + $alias_seo_redirects = array(); + if(is_array($aliases)) { + foreach($aliases as $alias) { + + // Custom proxy directives + if($alias['redirect_type'] == 'proxy' && trim($alias['proxy_directives'] != '')){ + $final_proxy_directives = array(); + $proxy_directives = $alias['proxy_directives']; + // Make sure we only have Unix linebreaks + $proxy_directives = str_replace("\r\n", "\n", $proxy_directives); + $proxy_directives = str_replace("\r", "\n", $proxy_directives); + $proxy_directive_lines = explode("\n", $proxy_directives); + if(is_array($proxy_directive_lines) && !empty($proxy_directive_lines)){ + foreach($proxy_directive_lines as $proxy_directive_line){ + $final_proxy_directives[] = array('proxy_directive' => $proxy_directive_line); + } + } + } else { + $final_proxy_directives = false; + } + + if($alias['redirect_type'] == '' || $alias['redirect_path'] == '' || substr($alias['redirect_path'],0,1) == '/') { + switch($alias['subdomain']) { + case 'www': + $server_alias[] = 'www.'.$alias['domain'].' '.$alias['domain'].' '; + break; + case '*': + $server_alias[] = '*.'.$alias['domain'].' '.$alias['domain'].' '; + break; + default: + $server_alias[] = $alias['domain'].' '; + break; + } + $app->log('Add server alias: '.$alias['domain'],LOGLEVEL_DEBUG); + + // Add SEO redirects for alias domains + if($alias['seo_redirect'] != '' && $data['new']['seo_redirect'] != '*_to_www_domain_tld' && $data['new']['seo_redirect'] != '*_to_domain_tld' && ($alias['type'] == 'alias' || ($alias['type'] == 'subdomain' && $data['new']['seo_redirect'] != '*_domain_tld_to_www_domain_tld' && $data['new']['seo_redirect'] != '*_domain_tld_to_domain_tld'))){ + $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_'); + if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ + $alias_seo_redirects[] = $tmp_seo_redirects; + } + } + } + + // Local Rewriting (inside vhost server {} container) + if($alias['redirect_type'] != '' && substr($alias['redirect_path'],0,1) == '/' && $alias['redirect_type'] != 'proxy') { // proxy makes no sense with local path + if(substr($alias['redirect_path'],-1) != '/') $alias['redirect_path'] .= '/'; + $rewrite_exclude = '(?!/\b('.substr($alias['redirect_path'],1,-1).(substr($alias['redirect_path'],1,-1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').')\b)/'; + switch($alias['subdomain']) { + case 'www': + // example.com + $local_rewrite_rules[] = array( 'local_redirect_origin_domain' => $alias['domain'], + 'local_redirect_operator' => '=', + 'local_redirect_exclude' => $rewrite_exclude, + 'local_redirect_target' => $alias['redirect_path'], + 'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']); + + // www.example.com + $local_rewrite_rules[] = array( 'local_redirect_origin_domain' => 'www.'.$alias['domain'], + 'local_redirect_operator' => '=', + 'local_redirect_exclude' => $rewrite_exclude, + 'local_redirect_target' => $alias['redirect_path'], + 'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']); + break; + case '*': + $local_rewrite_rules[] = array( 'local_redirect_origin_domain' => '^('.str_replace('.', '\.', $alias['domain']).'|.+\.'.str_replace('.', '\.', $alias['domain']).')$', + 'local_redirect_operator' => '~*', + 'local_redirect_exclude' => $rewrite_exclude, + 'local_redirect_target' => $alias['redirect_path'], + 'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']); + break; + default: + $local_rewrite_rules[] = array( 'local_redirect_origin_domain' => $alias['domain'], + 'local_redirect_operator' => '=', + 'local_redirect_exclude' => $rewrite_exclude, + 'local_redirect_target' => $alias['redirect_path'], + 'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']); + } + } + + // External Rewriting (extra server {} containers) + if($alias['redirect_type'] != '' && $alias['redirect_path'] != '' && substr($alias['redirect_path'],0,1) != '/') { + if(substr($alias['redirect_path'],-1) != '/') $alias['redirect_path'] .= '/'; + if(substr($alias['redirect_path'],0,8) == '[scheme]'){ + if($alias['redirect_type'] != 'proxy'){ + $alias['redirect_path'] = '$scheme'.substr($alias['redirect_path'],8); + } else { + $alias['redirect_path'] = 'http'.substr($alias['redirect_path'],8); + } + } + + switch($alias['subdomain']) { + case 'www': + if($alias['redirect_type'] == 'proxy'){ + $tmp_redirect_path = $alias['redirect_path']; + $tmp_redirect_path_parts = parse_url($tmp_redirect_path); + $rewrite_subdir = $tmp_redirect_path_parts['path']; + if(substr($rewrite_subdir,0,1) == '/') $rewrite_subdir = substr($rewrite_subdir,1); + if(substr($rewrite_subdir,-1) != '/') $rewrite_subdir .= '/'; + if($rewrite_subdir == '/') $rewrite_subdir = ''; + } + + if($alias['redirect_type'] != 'proxy'){ + if(substr($alias['redirect_path'],-1) == '/') $alias['redirect_path'] = substr($alias['redirect_path'],0,-1); + } + // Add SEO redirects for alias domains + $alias_seo_redirects2 = array(); + if($alias['seo_redirect'] != ''){ + $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', 'none'); + if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ + $alias_seo_redirects2[] = $tmp_seo_redirects; + } + } + $rewrite_rules[] = array( 'rewrite_domain' => $alias['domain'], + 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type'], + 'rewrite_target' => $alias['redirect_path'], + 'rewrite_subdir' => $rewrite_subdir, + 'proxy_directives' => $final_proxy_directives, + 'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true), + 'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false), + 'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false)); + + // Add SEO redirects for alias domains + $alias_seo_redirects2 = array(); + if($alias['seo_redirect'] != ''){ + $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', 'www'); + if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ + $alias_seo_redirects2[] = $tmp_seo_redirects; + } + } + $rewrite_rules[] = array( 'rewrite_domain' => 'www.'.$alias['domain'], + 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type'], + 'rewrite_target' => $alias['redirect_path'], + 'rewrite_subdir' => $rewrite_subdir, + 'proxy_directives' => $final_proxy_directives, + 'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true), + 'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false), + 'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false)); + break; + case '*': + if($alias['redirect_type'] == 'proxy'){ + $tmp_redirect_path = $alias['redirect_path']; + $tmp_redirect_path_parts = parse_url($tmp_redirect_path); + $rewrite_subdir = $tmp_redirect_path_parts['path']; + if(substr($rewrite_subdir,0,1) == '/') $rewrite_subdir = substr($rewrite_subdir,1); + if(substr($rewrite_subdir,-1) != '/') $rewrite_subdir .= '/'; + if($rewrite_subdir == '/') $rewrite_subdir = ''; + } + + if($alias['redirect_type'] != 'proxy'){ + if(substr($alias['redirect_path'],-1) == '/') $alias['redirect_path'] = substr($alias['redirect_path'],0,-1); + } + // Add SEO redirects for alias domains + $alias_seo_redirects2 = array(); + if($alias['seo_redirect'] != ''){ + $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_'); + if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ + $alias_seo_redirects2[] = $tmp_seo_redirects; + } + } + $rewrite_rules[] = array( 'rewrite_domain' => $alias['domain'].' *.'.$alias['domain'], + 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type'], + 'rewrite_target' => $alias['redirect_path'], + 'rewrite_subdir' => $rewrite_subdir, + 'proxy_directives' => $final_proxy_directives, + 'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true), + 'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false), + 'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false)); + break; + default: + if($alias['redirect_type'] == 'proxy'){ + $tmp_redirect_path = $alias['redirect_path']; + $tmp_redirect_path_parts = parse_url($tmp_redirect_path); + $rewrite_subdir = $tmp_redirect_path_parts['path']; + if(substr($rewrite_subdir,0,1) == '/') $rewrite_subdir = substr($rewrite_subdir,1); + if(substr($rewrite_subdir,-1) != '/') $rewrite_subdir .= '/'; + if($rewrite_subdir == '/') $rewrite_subdir = ''; + } + + if($alias['redirect_type'] != 'proxy'){ + if(substr($alias['redirect_path'],-1) == '/') $alias['redirect_path'] = substr($alias['redirect_path'],0,-1); + } + if(substr($alias['domain'], 0, 2) === '*.') $domain_rule = '*.'.substr($alias['domain'], 2); + else $domain_rule = $alias['domain']; + // Add SEO redirects for alias domains + $alias_seo_redirects2 = array(); + if($alias['seo_redirect'] != ''){ + if(substr($alias['domain'], 0, 2) === '*.'){ + $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_'); + } else { + $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', 'none'); + } + if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ + $alias_seo_redirects2[] = $tmp_seo_redirects; + } + } + $rewrite_rules[] = array( 'rewrite_domain' => $domain_rule, + 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type'], + 'rewrite_target' => $alias['redirect_path'], + 'rewrite_subdir' => $rewrite_subdir, + 'proxy_directives' => $final_proxy_directives, + 'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true), + 'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false), + 'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false)); + } + } + } + } + + //* If we have some alias records + if(count($server_alias) > 0) { + $server_alias_str = ''; + $n = 0; + + foreach($server_alias as $tmp_alias) { + $server_alias_str .= $tmp_alias; + } + unset($tmp_alias); + + $tpl->setVar('alias',trim($server_alias_str)); + } else { + $tpl->setVar('alias',''); + } + + if(count($rewrite_rules) > 0) { + $tpl->setLoop('redirects',$rewrite_rules); + } + if(count($own_rewrite_rules) > 0) { + $tpl->setLoop('own_redirects',$own_rewrite_rules); + } + if(count($local_rewrite_rules) > 0) { + $tpl->setLoop('local_redirects',$local_rewrite_rules); + } + if(count($alias_seo_redirects) > 0) { + $tpl->setLoop('alias_seo_redirects',$alias_seo_redirects); + } + + //* Create basic http auth for website statistics + $tpl->setVar('stats_auth_passwd_file', $data['new']['document_root']."/web/stats/.htpasswd_stats"); + + // Create basic http auth for other directories + $basic_auth_locations = $this->_create_web_folder_auth_configuration($data['new']); + if(is_array($basic_auth_locations) && !empty($basic_auth_locations)) $tpl->setLoop('basic_auth_locations', $basic_auth_locations); + + $vhost_file = escapeshellcmd($web_config['nginx_vhost_conf_dir'].'/'.$data['new']['domain'].'.vhost'); + //* Make a backup copy of vhost file + if(file_exists($vhost_file)) copy($vhost_file,$vhost_file.'~'); + + //* Write vhost file + $app->system->file_put_contents($vhost_file,$this->nginx_merge_locations($tpl->grab())); + $app->log('Writing the vhost file: '.$vhost_file,LOGLEVEL_DEBUG); + unset($tpl); + + //* Set the symlink to enable the vhost + //* First we check if there is a old type of symlink and remove it + $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/'.$data['new']['domain'].'.vhost'); + if(is_link($vhost_symlink)) unlink($vhost_symlink); + + //* Remove old or changed symlinks + if($data['new']['subdomain'] != $data['old']['subdomain'] or $data['new']['active'] == 'n') { + $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/900-'.$data['new']['domain'].'.vhost'); + if(is_link($vhost_symlink)) { + $app->system->unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG); + } + $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/100-'.$data['new']['domain'].'.vhost'); + if(is_link($vhost_symlink)) { + $app->system->unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG); + } + } + + //* New symlink + if($data['new']['subdomain'] == '*') { + $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/900-'.$data['new']['domain'].'.vhost'); + } else { + $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/100-'.$data['new']['domain'].'.vhost'); + } + if($data['new']['active'] == 'y' && !is_link($vhost_symlink)) { + symlink($vhost_file,$vhost_symlink); + $app->log('Creating symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG); + } + + // remove old symlink and vhost file, if domain name of the site has changed + if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) { + $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost'); + if(is_link($vhost_symlink)) { + $app->system->unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG); + } + $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost'); + if(is_link($vhost_symlink)) { + $app->system->unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG); + } + $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost'); + if(is_link($vhost_symlink)) { + $app->system->unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG); + } + $vhost_file = escapeshellcmd($web_config['nginx_vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost'); + $app->system->unlink($vhost_file); + $app->log('Removing file: '.$vhost_file,LOGLEVEL_DEBUG); + } + + // create password file for stats directory + if(!is_file($data['new']['document_root'].'/web/stats/.htpasswd_stats') || $data['new']['stats_password'] != $data['old']['stats_password']) { + if(trim($data['new']['stats_password']) != '') { + $htp_file = 'admin:'.trim($data['new']['stats_password']); + $app->system->file_put_contents($data['new']['document_root'].'/web/stats/.htpasswd_stats',$htp_file); + $app->system->chmod($data['new']['document_root'].'/web/stats/.htpasswd_stats',0755); + unset($htp_file); + } + } + + //* Create awstats configuration + if($data['new']['stats_type'] == 'awstats' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain')) { + $this->awstats_update($data,$web_config); + } + + $this->php_fpm_pool_update($data,$web_config,$pool_dir,$pool_name,$socket_dir); + + if($web_config['check_apache_config'] == 'y') { + //* Test if nginx starts with the new configuration file + $nginx_online_status_before_restart = $this->_checkTcp('localhost',80); + $app->log('nginx status is: '.($nginx_online_status_before_restart === true? 'running' : 'down'),LOGLEVEL_DEBUG); + + $retval = $app->services->restartService('httpd','restart'); // $retval['retval'] is 0 on success and > 0 on failure + $app->log('nginx restart return value is: '.$retval['retval'],LOGLEVEL_DEBUG); + + // wait a few seconds, before we test the apache status again + sleep(2); + + //* Check if nginx restarted successfully if it was online before + $nginx_online_status_after_restart = $this->_checkTcp('localhost',80); + $app->log('nginx online status after restart is: '.($nginx_online_status_after_restart === true? 'running' : 'down'),LOGLEVEL_DEBUG); + if($nginx_online_status_before_restart && !$nginx_online_status_after_restart || $retval['retval'] > 0) { + $app->log('nginx did not restart after the configuration change for website '.$data['new']['domain'].'. Reverting the configuration. Saved non-working config as '.$vhost_file.'.err',LOGLEVEL_WARN); + if(is_array($retval['output']) && !empty($retval['output'])){ + $app->log('Reason for nginx restart failure: '.implode("\n", $retval['output']),LOGLEVEL_WARN); + $app->dbmaster->datalogError(implode("\n", $retval['output'])); + } else { + // if no output is given, check again + exec('nginx -t 2>&1', $tmp_output, $tmp_retval); + if($tmp_retval > 0 && is_array($tmp_output) && !empty($tmp_output)){ + $app->log('Reason for nginx restart failure: '.implode("\n", $tmp_output),LOGLEVEL_WARN); + $app->dbmaster->datalogError(implode("\n", $tmp_output)); + } + unset($tmp_output, $tmp_retval); + } + $app->system->copy($vhost_file,$vhost_file.'.err'); + + if(is_file($vhost_file.'~')) { + //* Copy back the last backup file + $app->system->copy($vhost_file.'~',$vhost_file); + } else { + //* There is no backup file, so we create a empty vhost file with a warning message inside + $app->system->file_put_contents($vhost_file,"# nginx did not start after modifying this vhost file.\n# Please check file $vhost_file.err for syntax errors."); + } + + if($this->ssl_certificate_changed === true) { + + $ssl_dir = $data['new']['document_root'].'/ssl'; + $domain = $data['new']['ssl_domain']; + $key_file = $ssl_dir.'/'.$domain.'.key.org'; + $key_file2 = $ssl_dir.'/'.$domain.'.key'; + $csr_file = $ssl_dir.'/'.$domain.'.csr'; + $crt_file = $ssl_dir.'/'.$domain.'.crt'; + //$bundle_file = $ssl_dir.'/'.$domain.'.bundle'; + + //* Backup the files that might have caused the error + if(is_file($key_file)){ + $app->system->copy($key_file,$key_file.'.err'); + $app->system->chmod($key_file.'.err',0400); + } + if(is_file($key_file2)){ + $app->system->copy($key_file2,$key_file2.'.err'); + $app->system->chmod($key_file2.'.err',0400); + } + if(is_file($csr_file)) $app->system->copy($csr_file,$csr_file.'.err'); + if(is_file($crt_file)) $app->system->copy($crt_file,$crt_file.'.err'); + //if(is_file($bundle_file)) $app->system->copy($bundle_file,$bundle_file.'.err'); + + //* Restore the ~ backup files + if(is_file($key_file.'~')) $app->system->copy($key_file.'~',$key_file); + if(is_file($key_file2.'~')) $app->system->copy($key_file2.'~',$key_file2); + if(is_file($crt_file.'~')) $app->system->copy($crt_file.'~',$crt_file); + if(is_file($csr_file.'~')) $app->system->copy($csr_file.'~',$csr_file); + //if(is_file($bundle_file.'~')) $app->system->copy($bundle_file.'~',$bundle_file); + + $app->log('nginx did not restart after the configuration change for website '.$data['new']['domain'].' Reverting the SSL configuration. Saved non-working SSL files with .err extension.',LOGLEVEL_WARN); + } + + $app->services->restartService('httpd','restart'); + } + } else { + //* We do not check the nginx config after changes (is faster) + $app->services->restartServiceDelayed('httpd','reload'); + } + + //* The vhost is written and apache has been restarted, so we + // can reset the ssl changed var to false and cleanup some files + $this->ssl_certificate_changed = false; + + $ssl_dir = $data['new']['document_root'].'/ssl'; + $domain = $data['new']['ssl_domain']; + $key_file = $ssl_dir.'/'.$domain.'.key.org'; + $key_file2 = $ssl_dir.'/'.$domain.'.key'; + $csr_file = $ssl_dir.'/'.$domain.'.csr'; + $crt_file = $ssl_dir.'/'.$domain.'.crt'; + //$bundle_file = $ssl_dir.'/'.$domain.'.bundle'; + + if(@is_file($key_file.'~')) $app->system->unlink($key_file.'~'); + if(@is_file($key2_file.'~')) $app->system->unlink($key2_file.'~'); + if(@is_file($crt_file.'~')) $app->system->unlink($crt_file.'~'); + if(@is_file($csr_file.'~')) $app->system->unlink($csr_file.'~'); + //if(@is_file($bundle_file.'~')) $app->system->unlink($bundle_file.'~'); + + // Remove the backup copy of the config file. + if(@is_file($vhost_file.'~')) $app->system->unlink($vhost_file.'~'); + + //* Unset action to clean it for next processed vhost. + $this->action = ''; + + } + + function delete($event_name,$data) { + global $app, $conf; + + // load the server configuration options + $app->uses('getconf'); + $app->uses('system'); + $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); + + if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain') $app->system->web_folder_protection($data['old']['document_root'],false); + + //* Check if this is a chrooted setup + if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) { + $nginx_chrooted = true; + } else { + $nginx_chrooted = false; + } + + //* Remove the mounts + $log_folder = 'log'; + $web_folder = ''; + if($data['old']['type'] == 'vhostsubdomain') { + $tmp = $app->db->queryOneRecord('SELECT `domain`,`document_root` FROM web_domain WHERE domain_id = '.intval($data['old']['parent_domain_id'])); + if($tmp['domain'] != ''){ + $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['old']['domain']); + } else { + // get log folder from /etc/fstab + /* + $bind_mounts = $app->system->file_get_contents('/etc/fstab'); + $bind_mount_lines = explode("\n", $bind_mounts); + if(is_array($bind_mount_lines) && !empty($bind_mount_lines)){ + foreach($bind_mount_lines as $bind_mount_line){ + $bind_mount_line = preg_replace('/\s+/', ' ', $bind_mount_line); + $bind_mount_parts = explode(' ', $bind_mount_line); + if(is_array($bind_mount_parts) && !empty($bind_mount_parts)){ + if($bind_mount_parts[0] == '/var/log/ispconfig/httpd/'.$data['old']['domain'] && $bind_mount_parts[2] == 'none' && strpos($bind_mount_parts[3], 'bind') !== false){ + $subdomain_host = str_replace($data['old']['document_root'].'/log/', '', $bind_mount_parts[1]); + } + } + } + } + */ + // we are deleting the parent domain, so we can delete everything in the log directory + $subdomain_hosts = array(); + $files = array_diff(scandir($data['old']['document_root'].'/'.$log_folder), array('.','..')); + if(is_array($files) && !empty($files)){ + foreach($files as $file){ + if(is_dir($data['old']['document_root'].'/'.$log_folder.'/'.$file)){ + $subdomain_hosts[] = $file; + } + } + } + } + if(is_array($subdomain_hosts) && !empty($subdomain_hosts)){ + $log_folders = array(); + foreach($subdomain_hosts as $subdomain_host){ + $log_folders[] = $log_folder.'/'.$subdomain_host; + } + } else { + if($subdomain_host == '') $subdomain_host = 'web'.$data['old']['domain_id']; + $log_folder .= '/' . $subdomain_host; + } + $web_folder = $data['old']['web_folder']; + unset($tmp); + unset($subdomain_hosts); + } + + if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain'){ + if(is_array($log_folders) && !empty($log_folders)){ + foreach($log_folders as $log_folder){ + //if($app->system->is_mounted($data['old']['document_root'].'/'.$log_folder)) exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder)); + exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null'); + } + } else { + //if($app->system->is_mounted($data['old']['document_root'].'/'.$log_folder)) exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder)); + exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null'); + } + } + + //* remove mountpoint from fstab + if(is_array($log_folders) && !empty($log_folders)){ + foreach($log_folders as $log_folder){ + $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.' none bind'; + $app->system->removeLine('/etc/fstab',$fstab_line); + } + } else { + $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.' none bind'; + $app->system->removeLine('/etc/fstab',$fstab_line); + } + unset($log_folders); + + if($data['old']['type'] != 'vhost' && $data['old']['type'] != 'vhostsubdomain' && $data['old']['parent_domain_id'] > 0) { + //* This is a alias domain or subdomain, so we have to update the website instead + $parent_domain_id = intval($data['old']['parent_domain_id']); + $tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = '.$parent_domain_id." AND active = 'y'"); + $data['new'] = $tmp; + $data['old'] = $tmp; + $this->action = 'update'; + // just run the update function + $this->update($event_name,$data); + + } else { + //* This is a website + // Deleting the vhost file, symlink and the data directory + $vhost_file = escapeshellcmd($web_config['nginx_vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost'); + + $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost'); + if(is_link($vhost_symlink)){ + $app->system->unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG); + } + $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost'); + if(is_link($vhost_symlink)){ + $app->system->unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG); + } + $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost'); + if(is_link($vhost_symlink)){ + $app->system->unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG); + } + + $app->system->unlink($vhost_file); + $app->log('Removing vhost file: '.$vhost_file,LOGLEVEL_DEBUG); + + if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain') { + $docroot = escapeshellcmd($data['old']['document_root']); + if($docroot != '' && !stristr($docroot,'..')) { + if($data['old']['type'] == 'vhost') { + // this is a vhost - we delete everything in here. + exec('rm -rf '.$docroot); + } elseif(!stristr($data['old']['web_folder'], '..')) { + // this is a vhost subdomain + // IMPORTANT: do some folder checks before we delete this! + $do_delete = true; + $delete_folder = preg_replace('/[\/]{2,}/', '/', $web_folder); // replace / occuring multiple times + if(substr($delete_folder, 0, 1) === '/') $delete_folder = substr($delete_folder, 1); + if(substr($delete_folder, -1) === '/') $delete_folder = substr($delete_folder, 0, -1); + + $path_elements = explode('/', $delete_folder); + + if($path_elements[0] == 'web' || $path_elements[0] === '') { + // paths beginning with /web should NEVER EVER be deleted, empty paths should NEVER occur - but for safety reasons we check it here! + // we use strict check as otherwise directories named '0' may not be deleted + $do_delete = false; + } else { + // read all vhost subdomains with same parent domain + $used_paths = array(); + $tmp = $app->db->queryAllRecords("SELECT `web_folder` FROM web_domain WHERE type = 'vhostsubdomain' AND parent_domain_id = ".intval($data['old']['parent_domain_id'])." AND domain_id != ".intval($data['old']['domain_id'])); + foreach($tmp as $tmprec) { + // we normalize the folder entries because we need to compare them + $tmp_folder = preg_replace('/[\/]{2,}/', '/', $tmprec['web_folder']); // replace / occuring multiple times + if(substr($tmp_folder, 0, 1) === '/') $tmp_folder = substr($tmp_folder, 1); + if(substr($tmp_folder, -1) === '/') $tmp_folder = substr($tmp_folder, 0, -1); + + // add this path and it's parent paths to used_paths array + while(strpos($tmp_folder, '/') !== false) { + if(in_array($tmp_folder, $used_paths) == false) $used_paths[] = $tmp_folder; + $tmp_folder = substr($tmp_folder, 0, strrpos($tmp_folder, '/')); + } + if(in_array($tmp_folder, $used_paths) == false) $used_paths[] = $tmp_folder; + } + unset($tmp); + + // loop and check if the path is still used and stop at first used one + // set do_delete to false so nothing gets deleted if the web_folder itself is still used + $do_delete = false; + while(count($path_elements) > 0) { + $tmp_folder = implode('/', $path_elements); + if(in_array($tmp_folder, $used_paths) == true) break; + + // this path is not used - set it as path to delete, strip the last element from the array and set do_delete to true + $delete_folder = $tmp_folder; + $do_delete = true; + array_pop($path_elements); + } + unset($tmp_folder); + unset($used_paths); + } + + if($do_delete === true && $delete_folder !== '') exec('rm -rf '.$docroot.'/'.$delete_folder); + + unset($delete_folder); + unset($path_elements); + } + } + + //remove the php fastgi starter script if available + if ($data['old']['php'] == 'fast-cgi') { + $this->php_fpm_pool_delete($data,$web_config); + $fastcgi_starter_path = str_replace('[system_user]',$data['old']['system_user'],$web_config['fastcgi_starter_path']); + if($data['old']['type'] == 'vhost') { + if (is_dir($fastcgi_starter_path)) { + exec('rm -rf '.$fastcgi_starter_path); + } + } else { + $fcgi_starter_script = $fastcgi_starter_path.$web_config['fastcgi_starter_script'].'_web'.$data['old']['domain_id']; + if (file_exists($fcgi_starter_script)) { + exec('rm -f '.$fcgi_starter_script); + } + } + } + + // remove PHP-FPM pool + if ($data['old']['php'] == 'php-fpm') { + $this->php_fpm_pool_delete($data,$web_config); + } + + //remove the php cgi starter script if available + if ($data['old']['php'] == 'cgi') { + // TODO: fetch the date from the server-settings + $web_config['cgi_starter_path'] = $web_config['website_basedir'].'/php-cgi-scripts/[system_user]/'; + + $cgi_starter_path = str_replace('[system_user]',$data['old']['system_user'],$web_config['cgi_starter_path']); + if($data['old']['type'] == 'vhost') { + if (is_dir($cgi_starter_path)) { + exec('rm -rf '.$cgi_starter_path); + } + } else { + $cgi_starter_script = $cgi_starter_path.'php-cgi-starter_web'.$data['old']['domain_id']; + if (file_exists($cgi_starter_script)) { + exec('rm -f '.$cgi_starter_script); + } + } + } + + $app->log('Removing website: '.$docroot,LOGLEVEL_DEBUG); + + // Delete the symlinks for the sites + $client = $app->db->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = '.intval($data['old']['sys_groupid'])); + $client_id = intval($client['client_id']); + unset($client); + $tmp_symlinks_array = explode(':',$web_config['website_symlinks']); + if(is_array($tmp_symlinks_array)) { + foreach($tmp_symlinks_array as $tmp_symlink) { + $tmp_symlink = str_replace('[client_id]',$client_id,$tmp_symlink); + $tmp_symlink = str_replace('[website_domain]',$data['old']['domain'],$tmp_symlink); + // Remove trailing slash + if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); + // create the symlinks, if not exist + if(is_link($tmp_symlink)) { + $app->system->unlink($tmp_symlink); + $app->log('Removing symlink: '.$tmp_symlink,LOGLEVEL_DEBUG); + } + } + } + // end removing symlinks + } else { + // vhost subdomain + } + + // Delete the log file directory + $vhost_logfile_dir = escapeshellcmd('/var/log/ispconfig/httpd/'.$data['old']['domain']); + if($data['old']['domain'] != '' && !stristr($vhost_logfile_dir,'..')) exec('rm -rf '.$vhost_logfile_dir); + $app->log('Removing website logfile directory: '.$vhost_logfile_dir,LOGLEVEL_DEBUG); + + if($data['old']['type'] == 'vhost') { + //delete the web user + $command = 'killall -u '.escapeshellcmd($data['old']['system_user']).' ; userdel'; + $command .= ' '.escapeshellcmd($data['old']['system_user']); + exec($command); + if($nginx_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command); + + } + + //* Remove the awstats configuration file + if($data['old']['stats_type'] == 'awstats') { + $this->awstats_delete($data,$web_config); + } + + $app->services->restartServiceDelayed('httpd','reload'); + + } + + + if($data['old']['type'] != 'vhost') $app->system->web_folder_protection($data['old']['document_root'],true); + } + + //* This function is called when a IP on the server is inserted, updated or deleted + function server_ip($event_name,$data) { + return; + } + + //* Create or update the .htaccess folder protection + function web_folder_user($event_name,$data) { + global $app, $conf; + + $app->uses('system'); + + if($event_name == 'web_folder_user_delete') { + $folder_id = $data['old']['web_folder_id']; + } else { + $folder_id = $data['new']['web_folder_id']; + } + + $folder = $app->db->queryOneRecord("SELECT * FROM web_folder WHERE web_folder_id = ".intval($folder_id)); + $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($folder['parent_domain_id'])); + + if(!is_array($folder) or !is_array($website)) { + $app->log('Not able to retrieve folder or website record.',LOGLEVEL_DEBUG); + return false; + } + + $web_folder = 'web'; + if($website['type'] == 'vhostsubdomain') $web_folder = $website['web_folder']; + + //* Get the folder path. + if(substr($folder['path'],0,1) == '/') $folder['path'] = substr($folder['path'],1); + if(substr($folder['path'],-1) == '/') $folder['path'] = substr($folder['path'],0,-1); + $folder_path = escapeshellcmd($website['document_root'].'/' . $web_folder . '/'.$folder['path']); + if(substr($folder_path,-1) != '/') $folder_path .= '/'; + + //* Check if the resulting path is inside the docroot + if(stristr($folder_path,'..') || stristr($folder_path,'./') || stristr($folder_path,'\\')) { + $app->log('Folder path "'.$folder_path.'" contains .. or ./.',LOGLEVEL_DEBUG); + return false; + } + + //* Create the folder path, if it does not exist + if(!is_dir($folder_path)) { + $app->system->mkdirpath($folder_path); + $app->system->chown($folder_path,$website['system_user']); + $app->system->chgrp($folder_path,$website['system_group']); + } + + //* Create empty .htpasswd file, if it does not exist + if(!is_file($folder_path.'.htpasswd')) { + touch($folder_path.'.htpasswd'); + $app->system->chmod($folder_path.'.htpasswd',0755); + $app->system->chown($folder_path.'.htpasswd',$website['system_user']); + $app->system->chgrp($folder_path.'.htpasswd',$website['system_group']); + $app->log('Created file '.$folder_path.'.htpasswd',LOGLEVEL_DEBUG); + } + + /* + $auth_users = $app->db->queryAllRecords("SELECT * FROM web_folder_user WHERE active = 'y' AND web_folder_id = ".intval($folder_id)); + $htpasswd_content = ''; + if(is_array($auth_users) && !empty($auth_users)){ + foreach($auth_users as $auth_user){ + $htpasswd_content .= $auth_user['username'].':'.$auth_user['password']."\n"; + } + } + $htpasswd_content = trim($htpasswd_content); + @file_put_contents($folder_path.'.htpasswd', $htpasswd_content); + $app->log('Changed .htpasswd file: '.$folder_path.'.htpasswd',LOGLEVEL_DEBUG); + */ + + if(($data['new']['username'] != $data['old']['username'] || $data['new']['active'] == 'n') && $data['old']['username'] != '') { + $app->system->removeLine($folder_path.'.htpasswd',$data['old']['username'].':'); + $app->log('Removed user: '.$data['old']['username'],LOGLEVEL_DEBUG); + } + + //* Add or remove the user from .htpasswd file + if($event_name == 'web_folder_user_delete') { + $app->system->removeLine($folder_path.'.htpasswd',$data['old']['username'].':'); + $app->log('Removed user: '.$data['old']['username'],LOGLEVEL_DEBUG); + } else { + if($data['new']['active'] == 'y') { + $app->system->replaceLine($folder_path.'.htpasswd',$data['new']['username'].':',$data['new']['username'].':'.$data['new']['password'],0,1); + $app->log('Added or updated user: '.$data['new']['username'],LOGLEVEL_DEBUG); + } + } + + // write basic auth configuration to vhost file because nginx does not support .htaccess + $webdata['new'] = $webdata['old'] = $website; + $this->update('web_domain_update', $webdata); + } + + //* Remove .htpasswd file, when folder protection is removed + function web_folder_delete($event_name,$data) { + global $app, $conf; + + $folder_id = $data['old']['web_folder_id']; + + $folder = $data['old']; + $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($folder['parent_domain_id'])); + + if(!is_array($folder) or !is_array($website)) { + $app->log('Not able to retrieve folder or website record.',LOGLEVEL_DEBUG); + return false; + } + + $web_folder = 'web'; + if($website['type'] == 'vhostsubdomain') $web_folder = $website['web_folder']; + + //* Get the folder path. + if(substr($folder['path'],0,1) == '/') $folder['path'] = substr($folder['path'],1); + if(substr($folder['path'],-1) == '/') $folder['path'] = substr($folder['path'],0,-1); + $folder_path = realpath($website['document_root'].'/' . $web_folder . '/'.$folder['path']); + if(substr($folder_path,-1) != '/') $folder_path .= '/'; + + //* Check if the resulting path is inside the docroot + if(substr($folder_path,0,strlen($website['document_root'])) != $website['document_root']) { + $app->log('Folder path is outside of docroot.',LOGLEVEL_DEBUG); + return false; + } + + //* Remove .htpasswd file + if(is_file($folder_path.'.htpasswd')) { + $app->system->unlink($folder_path.'.htpasswd'); + $app->log('Removed file '.$folder_path.'.htpasswd',LOGLEVEL_DEBUG); + } + + // write basic auth configuration to vhost file because nginx does not support .htaccess + $webdata['new'] = $webdata['old'] = $website; + $this->update('web_domain_update', $webdata); + } + + //* Update folder protection, when path has been changed + function web_folder_update($event_name,$data) { + global $app, $conf; + + $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($data['new']['parent_domain_id'])); + + if(!is_array($website)) { + $app->log('Not able to retrieve folder or website record.',LOGLEVEL_DEBUG); + return false; + } + + $web_folder = 'web'; + if($website['type'] == 'vhostsubdomain') $web_folder = $website['web_folder']; + + //* Get the folder path. + if(substr($data['old']['path'],0,1) == '/') $data['old']['path'] = substr($data['old']['path'],1); + if(substr($data['old']['path'],-1) == '/') $data['old']['path'] = substr($data['old']['path'],0,-1); + $old_folder_path = realpath($website['document_root'].'/' . $web_folder . '/'.$data['old']['path']); + if(substr($old_folder_path,-1) != '/') $old_folder_path .= '/'; + + if(substr($data['new']['path'],0,1) == '/') $data['new']['path'] = substr($data['new']['path'],1); + if(substr($data['new']['path'],-1) == '/') $data['new']['path'] = substr($data['new']['path'],0,-1); + $new_folder_path = escapeshellcmd($website['document_root'].'/' . $web_folder . '/'.$data['new']['path']); + if(substr($new_folder_path,-1) != '/') $new_folder_path .= '/'; + + //* Check if the resulting path is inside the docroot + if(stristr($new_folder_path,'..') || stristr($new_folder_path,'./') || stristr($new_folder_path,'\\')) { + $app->log('Folder path "'.$new_folder_path.'" contains .. or ./.',LOGLEVEL_DEBUG); + return false; + } + if(stristr($old_folder_path,'..') || stristr($old_folder_path,'./') || stristr($old_folder_path,'\\')) { + $app->log('Folder path "'.$old_folder_path.'" contains .. or ./.',LOGLEVEL_DEBUG); + return false; + } + + //* Check if the resulting path is inside the docroot + if(substr($old_folder_path,0,strlen($website['document_root'])) != $website['document_root']) { + $app->log('Old folder path '.$old_folder_path.' is outside of docroot.',LOGLEVEL_DEBUG); + return false; + } + if(substr($new_folder_path,0,strlen($website['document_root'])) != $website['document_root']) { + $app->log('New folder path '.$new_folder_path.' is outside of docroot.',LOGLEVEL_DEBUG); + return false; + } + + //* Create the folder path, if it does not exist + if(!is_dir($new_folder_path)) $app->system->mkdirpath($new_folder_path); + + if($data['old']['path'] != $data['new']['path']) { + + + //* move .htpasswd file + if(is_file($old_folder_path.'.htpasswd')) { + $app->system->rename($old_folder_path.'.htpasswd',$new_folder_path.'.htpasswd'); + $app->log('Moved file '.$old_folder_path.'.htpasswd to '.$new_folder_path.'.htpasswd',LOGLEVEL_DEBUG); + } + + } + + // write basic auth configuration to vhost file because nginx does not support .htaccess + $webdata['new'] = $webdata['old'] = $website; + $this->update('web_domain_update', $webdata); + } + + function _create_web_folder_auth_configuration($website){ + global $app, $conf; + //* Create the domain.auth file which is included in the vhost configuration file + $app->uses('getconf'); + $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); + $basic_auth_file = escapeshellcmd($web_config['nginx_vhost_conf_dir'].'/'.$website['domain'].'.auth'); + //$app->load('tpl'); + //$tpl = new tpl(); + //$tpl->newTemplate('nginx_http_authentication.auth.master'); + $website_auth_locations = $app->db->queryAllRecords("SELECT * FROM web_folder WHERE active = 'y' AND parent_domain_id = ".intval($website['domain_id'])); + $basic_auth_locations = array(); + if(is_array($website_auth_locations) && !empty($website_auth_locations)){ + foreach($website_auth_locations as $website_auth_location){ + if(substr($website_auth_location['path'],0,1) == '/') $website_auth_location['path'] = substr($website_auth_location['path'],1); + if(substr($website_auth_location['path'],-1) == '/') $website_auth_location['path'] = substr($website_auth_location['path'],0,-1); + if($website_auth_location['path'] != ''){ + $website_auth_location['path'] .= '/'; + } + $basic_auth_locations[] = array('htpasswd_location' => '/'.$website_auth_location['path'], + 'htpasswd_path' => $website['document_root'].'/' . ($website['type'] == 'vhostsubdomain' ? $website['web_folder'] : 'web') . '/'.$website_auth_location['path']); + } + } + return $basic_auth_locations; + //$tpl->setLoop('basic_auth_locations', $basic_auth_locations); + //file_put_contents($basic_auth_file,$tpl->grab()); + //$app->log('Writing the http basic authentication file: '.$basic_auth_file,LOGLEVEL_DEBUG); + //unset($tpl); + //$app->services->restartServiceDelayed('httpd','reload'); + } + + //* Update the awstats configuration file + private function awstats_update ($data,$web_config) { + global $app; + + $web_folder = $data['new']['web_folder']; + if($data['new']['type'] == 'vhost') $web_folder = 'web'; + $awstats_conf_dir = $web_config['awstats_conf_dir']; + + if(!is_dir($data['new']['document_root']."/" . $web_folder . "/stats/")) mkdir($data['new']['document_root']."/" . $web_folder . "/stats"); + if(!@is_file($awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf') || ($data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain'])) { + if ( @is_file($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf') ) { + $app->system->unlink($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf'); + } + + $content = ''; + $content .= "Include \"".$awstats_conf_dir."/awstats.conf\"\n"; + $content .= "LogFile=\"/var/log/ispconfig/httpd/".$data['new']['domain']."/access.log\"\n"; + $content .= "SiteDomain=\"".$data['new']['domain']."\"\n"; + $content .= "HostAliases=\"www.".$data['new']['domain']." localhost 127.0.0.1\"\n"; + + $app->system->file_put_contents($awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf',$content); + $app->log('Created AWStats config file: '.$awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf',LOGLEVEL_DEBUG); + } + + if(is_file($data['new']['document_root']."/" . $web_folder . "/stats/index.html")) $app->system->unlink($data['new']['document_root']."/" . $web_folder . "/stats/index.html"); + if(file_exists("/usr/local/ispconfig/server/conf-custom/awstats_index.php.master")) { + $app->system->copy("/usr/local/ispconfig/server/conf-custom/awstats_index.php.master",$data['new']['document_root']."/" . $web_folder . "/stats/index.php"); + } else { + $app->system->copy("/usr/local/ispconfig/server/conf/awstats_index.php.master",$data['new']['document_root']."/" . $web_folder . "/stats/index.php"); + } + } + + //* Delete the awstats configuration file + private function awstats_delete ($data,$web_config) { + global $app; + + $awstats_conf_dir = $web_config['awstats_conf_dir']; + + if ( @is_file($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf') ) { + $app->system->unlink($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf'); + $app->log('Removed AWStats config file: '.$awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf',LOGLEVEL_DEBUG); + } + } + + //* Update the PHP-FPM pool configuration file + private function php_fpm_pool_update ($data,$web_config,$pool_dir,$pool_name,$socket_dir) { + global $app, $conf; + /* + if(trim($data['new']['fastcgi_php_version']) != ''){ + $default_php_fpm = false; + list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); + if(substr($custom_php_fpm_ini_dir,-1) != '/') $custom_php_fpm_ini_dir .= '/'; + } else { + $default_php_fpm = true; + } + */ + if($data['new']['php'] != 'no'){ + if(trim($data['new']['fastcgi_php_version']) != ''){ + $default_php_fpm = false; + list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); + if(substr($custom_php_fpm_ini_dir,-1) != '/') $custom_php_fpm_ini_dir .= '/'; + } else { + $default_php_fpm = true; + } + } else { + if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] != 'no'){ + $default_php_fpm = false; + list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version'])); + if(substr($custom_php_fpm_ini_dir,-1) != '/') $custom_php_fpm_ini_dir .= '/'; + } else { + $default_php_fpm = true; + } + } + + $app->uses("getconf"); + $web_config = $app->getconf->get_server_config($conf["server_id"], 'web'); + + if($data['new']['php'] == 'no'){ + if(@is_file($pool_dir.$pool_name.'.conf')){ + $app->system->unlink($pool_dir.$pool_name.'.conf'); + //$reload = true; + } + if($data['old']['php'] != 'no'){ + if(!$default_php_fpm){ + $app->services->restartService('php-fpm','reload:'.$custom_php_fpm_init_script); + } else { + $app->services->restartService('php-fpm','reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); + } + } + return; + } + + $app->load('tpl'); + $tpl = new tpl(); + $tpl->newTemplate('php_fpm_pool.conf.master'); + + if($data['new']['php_fpm_use_socket'] == 'y'){ + $use_tcp = 0; + $use_socket = 1; + if(!is_dir($socket_dir)) $app->system->mkdirpath($socket_dir); + } else { + $use_tcp = 1; + $use_socket = 0; + } + $tpl->setVar('use_tcp', $use_tcp); + $tpl->setVar('use_socket', $use_socket); + + $fpm_socket = $socket_dir.$pool_name.'.sock'; + $tpl->setVar('fpm_socket', $fpm_socket); + + $tpl->setVar('fpm_pool', $pool_name); + $tpl->setVar('fpm_port', $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1); + $tpl->setVar('fpm_user', $data['new']['system_user']); + $tpl->setVar('fpm_group', $data['new']['system_group']); + $tpl->setVar('pm', $data['new']['pm']); + $tpl->setVar('pm_max_children', $data['new']['pm_max_children']); + $tpl->setVar('pm_start_servers', $data['new']['pm_start_servers']); + $tpl->setVar('pm_min_spare_servers', $data['new']['pm_min_spare_servers']); + $tpl->setVar('pm_max_spare_servers', $data['new']['pm_max_spare_servers']); + $tpl->setVar('pm_process_idle_timeout', $data['new']['pm_process_idle_timeout']); + $tpl->setVar('pm_max_requests', $data['new']['pm_max_requests']); + $tpl->setVar('document_root', $data['new']['document_root']); + $tpl->setVar('security_level',$web_config['security_level']); + $php_open_basedir = ($data['new']['php_open_basedir'] == '')?escapeshellcmd($data['new']['document_root']):escapeshellcmd($data['new']['php_open_basedir']); + $tpl->setVar('php_open_basedir', $php_open_basedir); + if($php_open_basedir != ''){ + $tpl->setVar('enable_php_open_basedir', ''); + } else { + $tpl->setVar('enable_php_open_basedir', ';'); + } + + // Custom php.ini settings + $final_php_ini_settings = array(); + $custom_php_ini_settings = trim($data['new']['custom_php_ini']); + if($custom_php_ini_settings != ''){ + // Make sure we only have Unix linebreaks + $custom_php_ini_settings = str_replace("\r\n", "\n", $custom_php_ini_settings); + $custom_php_ini_settings = str_replace("\r", "\n", $custom_php_ini_settings); + $ini_settings = explode("\n", $custom_php_ini_settings); + if(is_array($ini_settings) && !empty($ini_settings)){ + foreach($ini_settings as $ini_setting){ + $ini_setting = trim($ini_setting); + if(substr($ini_setting,0,1) == ';') continue; + if(substr($ini_setting,0,1) == '#') continue; + if(substr($ini_setting,0,2) == '//') continue; + list($key, $value) = explode('=', $ini_setting); + if($value){ + $value = trim($value); + $key = trim($key); + switch (strtolower($value)) { + case '0': + // PHP-FPM might complain about invalid boolean value if you use 0 + $value = 'off'; + case '1': + case 'on': + case 'off': + case 'true': + case 'false': + case 'yes': + case 'no': + $final_php_ini_settings[] = array('ini_setting' => 'php_admin_flag['.$key.'] = '.$value); + break; + default: + $final_php_ini_settings[] = array('ini_setting' => 'php_admin_value['.$key.'] = '.$value); + } + } + } + } + } + + $tpl->setLoop('custom_php_ini_settings', $final_php_ini_settings); + + $app->system->file_put_contents($pool_dir.$pool_name.'.conf',$tpl->grab()); + $app->log('Writing the PHP-FPM config file: '.$pool_dir.$pool_name.'.conf',LOGLEVEL_DEBUG); + unset($tpl); + + // delete pool in all other PHP versions + $default_pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']); + if(substr($default_pool_dir,-1) != '/') $default_pool_dir .= '/'; + if($default_pool_dir != $pool_dir){ + if ( @is_file($default_pool_dir.$pool_name.'.conf') ) { + $app->system->unlink($default_pool_dir.$pool_name.'.conf'); + $app->log('Removed PHP-FPM config file: '.$default_pool_dir.$pool_name.'.conf',LOGLEVEL_DEBUG); + $app->services->restartService('php-fpm','reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); + } + } + $php_versions = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fpm_init_script != '' AND php_fpm_ini_dir != '' AND php_fpm_pool_dir != '' AND server_id = ".$conf["server_id"]); + if(is_array($php_versions) && !empty($php_versions)){ + foreach($php_versions as $php_version){ + if(substr($php_version['php_fpm_pool_dir'],-1) != '/') $php_version['php_fpm_pool_dir'] .= '/'; + if($php_version['php_fpm_pool_dir'] != $pool_dir){ + if ( @is_file($php_version['php_fpm_pool_dir'].$pool_name.'.conf') ) { + $app->system->unlink($php_version['php_fpm_pool_dir'].$pool_name.'.conf'); + $app->log('Removed PHP-FPM config file: '.$php_version['php_fpm_pool_dir'].$pool_name.'.conf',LOGLEVEL_DEBUG); + $app->services->restartService('php-fpm','reload:'.$php_version['php_fpm_init_script']); + } + } + } + } + // Reload current PHP-FPM after all others + sleep(1); + if(!$default_php_fpm){ + $app->services->restartService('php-fpm','reload:'.$custom_php_fpm_init_script); + } else { + $app->services->restartService('php-fpm','reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); + } + } + + //* Delete the PHP-FPM pool configuration file + private function php_fpm_pool_delete ($data,$web_config) { + global $app, $conf; + + if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] != 'no'){ + $default_php_fpm = false; + list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version'])); + if(substr($custom_php_fpm_ini_dir,-1) != '/') $custom_php_fpm_ini_dir .= '/'; + } else { + $default_php_fpm = true; + } + + if($default_php_fpm){ + $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']); + } else { + $pool_dir = $custom_php_fpm_pool_dir; + } + + if(substr($pool_dir,-1) != '/') $pool_dir .= '/'; + $pool_name = 'web'.$data['old']['domain_id']; + + if ( @is_file($pool_dir.$pool_name.'.conf') ) { + $app->system->unlink($pool_dir.$pool_name.'.conf'); + $app->log('Removed PHP-FPM config file: '.$pool_dir.$pool_name.'.conf',LOGLEVEL_DEBUG); + } + + // delete pool in all other PHP versions + $default_pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']); + if(substr($default_pool_dir,-1) != '/') $default_pool_dir .= '/'; + if($default_pool_dir != $pool_dir){ + if ( @is_file($default_pool_dir.$pool_name.'.conf') ) { + $app->system->unlink($default_pool_dir.$pool_name.'.conf'); + $app->log('Removed PHP-FPM config file: '.$default_pool_dir.$pool_name.'.conf',LOGLEVEL_DEBUG); + $app->services->restartService('php-fpm','reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); + } + } + $php_versions = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fpm_init_script != '' AND php_fpm_ini_dir != '' AND php_fpm_pool_dir != '' AND server_id = ".$data['old']['server_id']); + if(is_array($php_versions) && !empty($php_versions)){ + foreach($php_versions as $php_version){ + if(substr($php_version['php_fpm_pool_dir'],-1) != '/') $php_version['php_fpm_pool_dir'] .= '/'; + if($php_version['php_fpm_pool_dir'] != $pool_dir){ + if ( @is_file($php_version['php_fpm_pool_dir'].$pool_name.'.conf') ) { + $app->system->unlink($php_version['php_fpm_pool_dir'].$pool_name.'.conf'); + $app->log('Removed PHP-FPM config file: '.$php_version['php_fpm_pool_dir'].$pool_name.'.conf',LOGLEVEL_DEBUG); + $app->services->restartService('php-fpm','reload:'.$php_version['php_fpm_init_script']); + } + } + } + } + + // Reload current PHP-FPM after all others + sleep(1); + if(!$default_php_fpm){ + $app->services->restartService('php-fpm','reload:'.$custom_php_fpm_init_script); + } else { + $app->services->restartService('php-fpm','reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); + } + } + + private function nginx_replace($matches){ + $location = 'location'.($matches[1] != '' ? ' '.$matches[1] : '').' '.$matches[2].' '.$matches[3]; + if($matches[4] == '##merge##' || $matches[7] == '##merge##') $location .= ' ##merge##'; + if($matches[4] == '##delete##' || $matches[7] == '##delete##') $location .= ' ##delete##'; + $location .= "\n"; + $location .= $matches[5]."\n"; + $location .= $matches[6]; + return $location; + } + + private function nginx_merge_locations($vhost_conf){ + + $lines = explode("\n", $vhost_conf); + + // if whole location block is in one line, split it up into multiple lines + if(is_array($lines) && !empty($lines)){ + $linecount = sizeof($lines); + for($h=0;$h<$linecount;$h++){ + // remove comments + if(substr(trim($lines[$h]),0,1) == '#'){ + unset($lines[$h]); + continue; + } + + $lines[$h] = rtrim($lines[$h]); + /* + if(substr(ltrim($lines[$h]), 0, 8) == 'location' && strpos($lines[$h], '{') !== false && strpos($lines[$h], ';') !== false){ + $lines[$h] = str_replace("{", "{\n", $lines[$h]); + $lines[$h] = str_replace(";", ";\n", $lines[$h]); + if(strpos($lines[$h], '##merge##') !== false){ + $lines[$h] = str_replace('##merge##', '', $lines[$h]); + $lines[$h] = substr($lines[$h],0,strpos($lines[$h], '{')).' ##merge##'.substr($lines[$h],strpos($lines[$h], '{')+1); + } + } + if(substr(ltrim($lines[$h]), 0, 8) == 'location' && strpos($lines[$h], '{') !== false && strpos($lines[$h], '}') !== false && strpos($lines[$h], ';') === false){ + $lines[$h] = str_replace("{", "{\n", $lines[$h]); + if(strpos($lines[$h], '##merge##') !== false){ + $lines[$h] = str_replace('##merge##', '', $lines[$h]); + $lines[$h] = substr($lines[$h],0,strpos($lines[$h], '{')).' ##merge##'.substr($lines[$h],strpos($lines[$h], '{')+1); + } + } + */ + $pattern = '/^[^\S\n]*location[^\S\n]+(?:(.+)[^\S\n]+)?(.+)[^\S\n]*(\{)[^\S\n]*(##merge##|##delete##)?[^\S\n]*(.+)[^\S\n]*(\})[^\S\n]*(##merge##|##delete##)?[^\S\n]*$/'; + $lines[$h] = preg_replace_callback($pattern, array($this, 'nginx_replace') ,$lines[$h]); + } + } + $vhost_conf = implode("\n", $lines); + unset($lines); + unset($linecount); + + $lines = explode("\n", $vhost_conf); + + if(is_array($lines) && !empty($lines)){ + $locations = array(); + $locations_to_delete = array(); + $islocation = false; + $linecount = sizeof($lines); + $server_count = 0; + + for($i=0;$i<$linecount;$i++){ + $l = trim($lines[$i]); + if(substr($l, 0, 8) == 'server {') $server_count += 1; + if($server_count > 1) break; + if(substr($l, 0, 8) == 'location' && !$islocation){ + + $islocation = true; + $level = 0; + + // Remove unnecessary whitespace + $l = preg_replace('/\s\s+/', ' ', $l); + + $loc_parts = explode(' ', $l); + // see http://wiki.nginx.org/HttpCoreModule#location + if($loc_parts[1] == '=' || $loc_parts[1] == '~' || $loc_parts[1] == '~*' || $loc_parts[1] == '^~'){ + $location = $loc_parts[1].' '.$loc_parts[2]; + } else { + $location = $loc_parts[1]; + } + unset($loc_parts); + + if(!isset($locations[$location]['action'])) $locations[$location]['action'] = 'replace'; + if(substr($l, -9) == '##merge##') $locations[$location]['action'] = 'merge'; + if(substr($l, -10) == '##delete##') $locations[$location]['action'] = 'delete'; + + if(!isset($locations[$location]['open_tag'])) $locations[$location]['open_tag'] = ' location '.$location.' {'; + if(!isset($locations[$location]['location']) || $locations[$location]['action'] == 'replace') $locations[$location]['location'] = ''; + if($locations[$location]['action'] == 'delete') $locations_to_delete[] = $location; + if(!isset($locations[$location]['end_tag'])) $locations[$location]['end_tag'] = ' }'; + if(!isset($locations[$location]['start_line'])) $locations[$location]['start_line'] = $i; + + unset($lines[$i]); + + } else { + + if($islocation){ + if(strpos($l, '{') !== false){ + $level += 1; + } + if(strpos($l, '}') !== false && $level > 0){ + $level -= 1; + $locations[$location]['location'] .= $lines[$i]."\n"; + } elseif(strpos($l, '}') !== false && $level == 0){ + $islocation = false; + } else { + $locations[$location]['location'] .= $lines[$i]."\n"; + } + unset($lines[$i]); + } + + } + } + + if(is_array($locations) && !empty($locations)){ + if(is_array($locations_to_delete) && !empty($locations_to_delete)){ + foreach($locations_to_delete as $location_to_delete){ + if(isset($locations[$location_to_delete])) unset($locations[$location_to_delete]); + } + } + + foreach($locations as $key => $val){ + $new_location = $val['open_tag']."\n".$val['location'].$val['end_tag']; + $lines[$val['start_line']] = $new_location; + } + } + ksort($lines); + $vhost_conf = implode("\n", $lines); + } + + return trim($vhost_conf); + } + + function client_delete($event_name,$data) { + global $app, $conf; + + $app->uses("getconf"); + $web_config = $app->getconf->get_server_config($conf["server_id"], 'web'); + + $client_id = intval($data['old']['client_id']); + if($client_id > 0) { + + $client_dir = $web_config['website_basedir'].'/clients/client'.$client_id; + if(is_dir($client_dir) && !stristr($client_dir,'..')) { + // remove symlinks from $client_dir + $files = array_diff(scandir($client_dir), array('.','..')); + if(is_array($files) && !empty($files)){ + foreach($files as $file){ + if(is_link($client_dir.'/'.$file)){ + unlink($client_dir.'/'.$file); + $app->log('Removed symlink: '.$client_dir.'/'.$file,LOGLEVEL_DEBUG); + } + } + } + + @rmdir($client_dir); + $app->log('Removed client directory: '.$client_dir,LOGLEVEL_DEBUG); + } + + if($app->system->is_group('client'.$client_id)){ + $this->_exec('groupdel client'.$client_id); + $app->log('Removed group client'.$client_id,LOGLEVEL_DEBUG); + } + } + + } + + //* Wrapper for exec function for easier debugging + private function _exec($command) { + global $app; + $app->log('exec: '.$command,LOGLEVEL_DEBUG); + exec($command); + } + + private function _checkTcp ($host,$port) { + + $fp = @fsockopen ($host, $port, $errno, $errstr, 2); + + if ($fp) { + fclose($fp); + return true; + } else { + return false; + } + } + + public function create_relative_link($f, $t) { + global $app; + // $from already exists + $from = realpath($f); + + // realpath requires the traced file to exist - so, lets touch it first, then remove + @$app->system->unlink($t); touch($t); + $to = realpath($t); + @$app->system->unlink($t); + + // Remove from the left side matching path elements from $from and $to + // and get path elements counts + $a1 = explode('/', $from); $a2 = explode('/', $to); + for ($c = 0; $a1[$c] == $a2[$c]; $c++) { + unset($a1[$c]); unset($a2[$c]); + } + $cfrom = implode('/', $a1); + + // Check if a path is fully a subpath of another - no way to create symlink in the case + if (count($a1) == 0 || count($a2) == 0) return false; + + // Add ($cnt_to-1) number of "../" elements to left side of $cfrom + for ($c = 0; $c < (count($a2)-1); $c++) { $cfrom = '../'.$cfrom; } + + return symlink($cfrom, $to); + } + + private function _rewrite_quote($string) { + return str_replace(array('.', '*', '?', '+'), array('\\.', '\\*', '\\?', '\\+'), $string); + } + + private function url_is_local($hostname, $domain_id){ + global $app; + + // ORDER BY clause makes sure wildcard subdomains (*) are listed last in the result array so that we can find direct matches first + $webs = $app->db->queryAllRecords("SELECT * FROM web_domain WHERE active = 'y' ORDER BY subdomain ASC"); + if(is_array($webs) && !empty($webs)){ + foreach($webs as $web){ + // web domain doesn't match hostname + if(substr($hostname,-strlen($web['domain'])) != $web['domain']) continue; + // own vhost and therefore server {} container of its own + //if($web['type'] == 'vhostsubdomain') continue; + // alias domains/subdomains using rewrites and therefore a server {} container of their own + //if(($web['type'] == 'alias' || $web['type'] == 'subdomain') && $web['redirect_type'] != '' && $web['redirect_path'] != '') continue; + + if($web['subdomain'] == '*'){ + $pattern = '/\.?'.str_replace('.', '\.', $web['domain']).'$/i'; + } + if($web['subdomain'] == 'none'){ + if($web['domain'] == $hostname){ + if($web['domain_id'] == $domain_id || $web['parent_domain_id'] == $domain_id){ + // own vhost and therefore server {} container of its own + if($web['type'] == 'vhostsubdomain') return false; + // alias domains/subdomains using rewrites and therefore a server {} container of their own + if(($web['type'] == 'alias' || $web['type'] == 'subdomain') && $web['redirect_type'] != '' && $web['redirect_path'] != '') return false; + return true; + } else { + return false; + } + } + $pattern = '/^'.str_replace('.', '\.', $web['domain']).'$/i'; + } + if($web['subdomain'] == 'www'){ + if($web['domain'] == $hostname || $web['subdomain'].'.'.$web['domain'] == $hostname){ + if($web['domain_id'] == $domain_id || $web['parent_domain_id'] == $domain_id){ + // own vhost and therefore server {} container of its own + if($web['type'] == 'vhostsubdomain') return false; + // alias domains/subdomains using rewrites and therefore a server {} container of their own + if(($web['type'] == 'alias' || $web['type'] == 'subdomain') && $web['redirect_type'] != '' && $web['redirect_path'] != '') return false; + return true; + } else { + return false; + } + } + $pattern = '/^(www\.)?'.str_replace('.', '\.', $web['domain']).'$/i'; + } + if(preg_match($pattern, $hostname)){ + if($web['domain_id'] == $domain_id || $web['parent_domain_id'] == $domain_id){ + // own vhost and therefore server {} container of its own + if($web['type'] == 'vhostsubdomain') return false; + // alias domains/subdomains using rewrites and therefore a server {} container of their own + if(($web['type'] == 'alias' || $web['type'] == 'subdomain') && $web['redirect_type'] != '' && $web['redirect_path'] != '') return false; + return true; + } else { + return false; + } + } + } + } + + return false; + } + + private function get_seo_redirects($web, $prefix = '', $force_subdomain = false){ + // $force_subdomain = 'none|www' + $seo_redirects = array(); + + if(substr($web['domain'], 0, 2) === '*.') $web['subdomain'] = '*'; + + if(($web['subdomain'] == 'www' || $web['subdomain'] == '*') && $force_subdomain != 'www'){ + if($web['seo_redirect'] == 'non_www_to_www'){ + $seo_redirects[$prefix.'seo_redirect_origin_domain'] = $web['domain']; + $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain']; + $seo_redirects[$prefix.'seo_redirect_operator'] = '='; + } + if($web['seo_redirect'] == '*_domain_tld_to_www_domain_tld'){ + // ^(example\.com|(?!\bwww\b)\.example\.com)$ + // ^(example\.com|((?:\w+(?:-\w+)*\.)*)((?!www\.)\w+(?:-\w+)*)(\.example\.com))$ + $seo_redirects[$prefix.'seo_redirect_origin_domain'] = '^('.str_replace('.', '\.', $web['domain']).'|((?:\w+(?:-\w+)*\.)*)((?!www\.)\w+(?:-\w+)*)(\.'.str_replace('.', '\.', $web['domain']).'))$'; + $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain']; + $seo_redirects[$prefix.'seo_redirect_operator'] = '~*'; + } + if($web['seo_redirect'] == '*_to_www_domain_tld'){ + $seo_redirects[$prefix.'seo_redirect_origin_domain'] = 'www.'.$web['domain']; + $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain']; + $seo_redirects[$prefix.'seo_redirect_operator'] = '!='; + } + } + if($force_subdomain != 'none'){ + if($web['seo_redirect'] == 'www_to_non_www'){ + $seo_redirects[$prefix.'seo_redirect_origin_domain'] = 'www.'.$web['domain']; + $seo_redirects[$prefix.'seo_redirect_target_domain'] = $web['domain']; + $seo_redirects[$prefix.'seo_redirect_operator'] = '='; + } + if($web['seo_redirect'] == '*_domain_tld_to_domain_tld'){ + // ^(.+)\.example\.com$ + $seo_redirects[$prefix.'seo_redirect_origin_domain'] = '^(.+)\.'.str_replace('.', '\.', $web['domain']).'$'; + $seo_redirects[$prefix.'seo_redirect_target_domain'] = $web['domain']; + $seo_redirects[$prefix.'seo_redirect_operator'] = '~*'; + } + if($web['seo_redirect'] == '*_to_domain_tld'){ + $seo_redirects[$prefix.'seo_redirect_origin_domain'] = $web['domain']; + $seo_redirects[$prefix.'seo_redirect_target_domain'] = $web['domain']; + $seo_redirects[$prefix.'seo_redirect_operator'] = '!='; + } + } + return $seo_redirects; + } + +} // end class + +?>