diff --git a/.htaccess b/.htaccess index 10da8e3b2..fe203659a 100644 --- a/.htaccess +++ b/.htaccess @@ -17,13 +17,10 @@ RewriteRule ^(.+)\.min\.(css|js)$ ./$1.$2 [L] # rss, blogAPI RewriteRule ^(rss|atom)$ ./index.php?module=rss&act=$1 [L] RewriteRule ^([a-zA-Z0-9_]+)/(rss|atom|api)$ ./index.php?mid=$1&act=$2 [L] -RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/(rss|atom|api)$ ./index.php?vid=$1&mid=$2&act=$3 [L] # trackback RewriteRule ^([0-9]+)/(.+)/trackback$ ./index.php?document_srl=$1&key=$2&act=trackback [L] RewriteRule ^([a-zA-Z0-9_]+)/([0-9]+)/(.+)/trackback$ ./index.php?mid=$1&document_srl=$2&key=$3&act=trackback [L] -RewriteRule ^([a-zA-Z0-9_]+)/([0-9]+)/(.+)/trackback$ ./index.php?vid=$1&document_srl=$2&key=$3&act=trackback [L] -RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([0-9]+)/(.+)/trackback$ ./index.php?vid=$1&mid=$2&document_srl=$3&key=$4&act=trackback [L] # document category RewriteRule ^([a-zA-Z0-9_]+)/category/([0-9]+)$ ./index.php?mid=$1&category=$2 [L,QSA] @@ -39,15 +36,5 @@ RewriteRule ^([a-zA-Z0-9_]+)/?$ ./index.php?mid=$1 [L,QSA] # mid + document link RewriteRule ^([a-zA-Z0-9_]+)/([0-9]+)$ ./index.php?mid=$1&document_srl=$2 [L,QSA] -# vid + mid link -RewriteCond %{SCRIPT_FILENAME} !-d -RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/?$ ./index.php?vid=$1&mid=$2 [L,QSA] - -# vid + mid + document link -RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([0-9]+)$ ./index.php?vid=$1&mid=$2&document_srl=$3 [L,QSA] - # mid + entry title RewriteRule ^([a-zA-Z0-9_]+)/entry/(.+)$ ./index.php?mid=$1&entry=$2 [L,QSA] - -# vid + mid + entry title -RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/entry/(.+)$ ./index.php?vid=$1&mid=$2&entry=$3 [L,QSA] diff --git a/classes/context/Context.class.php b/classes/context/Context.class.php index b4b5b3582..b1e2658c3 100644 --- a/classes/context/Context.class.php +++ b/classes/context/Context.class.php @@ -238,7 +238,6 @@ class Context // Set global variables for backward compatibility. $GLOBALS['__Context__'] = $this; - $this->_COOKIE = $_COOKIE; // Set information about the current request. $this->setRequestMethod(); @@ -261,23 +260,26 @@ class Context { $oModuleModel = getModel('module'); $site_module_info = $oModuleModel->getDefaultMid() ?: new stdClass; - - // if site_srl of site_module_info is 0 (default site), compare the domain to default_url of db_config - if($site_module_info->site_srl == 0 && $site_module_info->domain != $this->db_info->default_url) - { - $site_module_info->domain = $this->db_info->default_url; - } - self::set('site_module_info', $site_module_info); - if($site_module_info->site_srl && isSiteID($site_module_info->domain)) - { - self::set('vid', $site_module_info->domain, TRUE); - } + self::set('_default_timezone', ($site_module_info->settings && $site_module_info->settings->timezone) ? $site_module_info->settings->timezone : null); + self::set('_default_url', self::$_instance->db_info->default_url = self::getDefaultUrl($site_module_info)); + self::set('_http_port', self::$_instance->db_info->http_port = $site_module_info->http_port ?: null); + self::set('_https_port', self::$_instance->db_info->https_port = $site_module_info->https_port ?: null); + self::set('_use_ssl', self::$_instance->db_info->use_ssl = $site_module_info->security ?: 'none'); } else { $site_module_info = new stdClass; } + + // Redirect to SSL if the current domain always uses SSL. + if ($site_module_info->security === 'always' && !RX_SSL && PHP_SAPI !== 'cli' && !$site_module_info->is_default_replaced) + { + $ssl_url = self::getDefaultUrl($site_module_info) . RX_REQUEST_URL; + self::setCacheControl(0); + header('Location: ' . $ssl_url, true, 301); + exit; + } // Load language support. $enabled_langs = self::loadLangSelected(); @@ -311,9 +313,9 @@ class Context if(!$this->lang_type || !isset($enabled_langs[$this->lang_type])) { - if($site_module_info->default_language) + if($site_module_info->settings->language) { - $this->lang_type = $this->db_info->lang_type = $site_module_info->default_language; + $this->lang_type = $this->db_info->lang_type = $site_module_info->settings->language; } else { @@ -340,7 +342,9 @@ class Context // start session $relax_key_checks = ($this->act === 'procFileUpload' && preg_match('/shockwave\s?flash/i', $_SERVER['HTTP_USER_AGENT'])); + Rhymix\Framework\Session::checkSSO($site_module_info); Rhymix\Framework\Session::start(false, $relax_key_checks); + $this->_COOKIE = $_COOKIE; // start output buffer ob_start(); @@ -474,9 +478,6 @@ class Context // Copy to old format for backward compatibility. self::$_instance->db_info = self::convertDBInfo($config); self::$_instance->allow_rewrite = self::$_instance->db_info->use_rewrite === 'Y'; - self::set('_http_port', self::$_instance->db_info->http_port ?: null); - self::set('_https_port', self::$_instance->db_info->https_port ?: null); - self::set('_use_ssl', self::$_instance->db_info->use_ssl); $GLOBALS['_time_zone'] = self::$_instance->db_info->time_zone; } @@ -528,14 +529,6 @@ class Context $db_info->ftp_info->ftp_pasv = $config['ftp']['pasv'] ? 'Y' : 'N'; $db_info->ftp_info->ftp_root_path = $config['ftp']['path']; $db_info->ftp_info->sftp = $config['ftp']['sftp'] ? 'Y' : 'N'; - $db_info->default_url = $config['url']['default']; - if (!$db_info->default_url) - { - $db_info->default_url = (RX_SSL ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . RX_BASEURL; - } - $db_info->http_port = $config['url']['http_port']; - $db_info->https_port = $config['url']['https_port']; - $db_info->use_ssl = $config['url']['ssl']; $db_info->lang_type = $config['locale']['default_lang']; $db_info->time_zone = $config['locale']['internal_timezone']; $db_info->time_zone = sprintf('%s%02d%02d', $db_info->time_zone >= 0 ? '+' : '-', abs($db_info->time_zone) / 3600, (abs($db_info->time_zone) % 3600 / 60)); @@ -607,11 +600,26 @@ class Context /** * Return default URL * + * @param object $site_module_info (optional) * @return string Default URL */ - public static function getDefaultUrl() + public static function getDefaultUrl($site_module_info = null) { - return self::$_instance->db_info->default_url; + if ($site_module_info === null && ($default_url = self::get('_default_url'))) + { + return $default_url; + } + + if ($site_module_info === null) + { + $site_module_info === self::get('site_module_info'); + } + + $prefix = $site_module_info->security === 'always' ? 'https://' : 'http://'; + $hostname = $site_module_info->domain; + $port = $site_module_info->security === 'always' ? $site_module_info->https_port : $site_module_info->http_port; + $result = $prefix . $hostname . ($port ? sprintf(':%d', $port) : '') . RX_BASEURL; + return $result; } /** @@ -659,7 +667,7 @@ class Context */ public function checkSSO() { - return !Rhymix\Framework\Session::checkSSO(); + return true; } /** @@ -776,10 +784,10 @@ class Context */ public static function getSiteTitle() { - $moduleConfig = getModel('module')->getModuleConfig('module'); - if (isset($moduleConfig->siteTitle)) + $domain_info = self::get('site_module_info'); + if ($domain_info && $domain_info->settings && $domain_info->settings->title) { - $title = trim($moduleConfig->siteTitle); + $title = trim($domain_info->settings->title); getController('module')->replaceDefinedLangCode($title); return $title; } @@ -796,10 +804,10 @@ class Context */ public static function getSiteSubtitle() { - $moduleConfig = getModel('module')->getModuleConfig('module'); - if (isset($moduleConfig->siteSubtitle)) + $domain_info = self::get('site_module_info'); + if ($domain_info && $domain_info->settings && $domain_info->settings->subtitle) { - $subtitle = trim($moduleConfig->siteSubtitle); + $subtitle = trim($domain_info->settings->subtitle); getController('module')->replaceDefinedLangCode($subtitle); return $subtitle; } @@ -1540,76 +1548,59 @@ class Context */ public static function getUrl($num_args = 0, $args_list = array(), $domain = null, $encode = TRUE, $autoEncode = FALSE) { + static $current_domain = null; static $site_module_info = null; - static $current_info = null; - - // retrieve virtual site information - if(is_null($site_module_info)) + if ($site_module_info === null) { $site_module_info = self::get('site_module_info'); } - - // If $domain is set, handle it (if $domain is vid type, remove $domain and handle with $vid) - if($domain && isSiteID($domain)) + if ($current_domain === null) { - $vid = $domain; - $domain = ''; + $current_domain = parse_url(Rhymix\Framework\URL::getCurrentDomainURL(), PHP_URL_HOST); } - // If $domain, $vid are not set, use current site information - if(!$domain && !$vid) + // Find the canonical form of the domain. + if ($domain) { - if($site_module_info->domain && isSiteID($site_module_info->domain)) + if (strpos($domain, '/') !== false) { - $vid = $site_module_info->domain; + $domain = Rhymix\Framework\URL::getDomainFromURL($domain); } - else + if (strpos($domain, 'xn--') !== false) { - $domain = $site_module_info->domain; + $domain = Rhymix\Framework\URL::decodeIdna($domain); } } - - // if $domain is set, compare current URL. If they are same, remove the domain, otherwise link to the domain. - if($domain) + else { - $domain_info = parse_url($domain); - if(is_null($current_info)) - { - $current_info = parse_url((RX_SSL ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'] . RX_BASEURL); - } - if($domain_info['host'] . $domain_info['path'] == $current_info['host'] . $current_info['path']) - { - unset($domain); - } - else - { - $domain = rtrim(preg_replace('/^(http|https):\/\//i', '', trim($domain)), '/') . '/'; - } + $domain = $site_module_info->domain; } - $get_vars = array(); - - // If there is no GET variables or first argument is '' to reset variables - if(!self::$_instance->get_vars || $args_list[0] == '') + // If the domain is the same as the current domain, do not use it. + if ($domain && $domain === $current_domain) { - // rearrange args_list - if(is_array($args_list) && $args_list[0] == '') + $domain = null; + } + + // Get URL parameters. If the first argument is '', reset existing parameters. + if (!self::$_instance->get_vars || strval($args_list[0]) === '') + { + $get_vars = array(); + if(is_array($args_list) && strval($args_list[0]) === '') { array_shift($args_list); } } else { - // Otherwise, make GET variables into array $get_vars = get_object_vars(self::$_instance->get_vars); } - + // arrange args_list for($i = 0, $c = count($args_list); $i < $c; $i += 2) { $key = $args_list[$i]; $val = trim($args_list[$i + 1]); - // If value is not set, remove the key if(!isset($val) || !strlen($val)) { @@ -1619,18 +1610,11 @@ class Context // set new variables $get_vars[$key] = $val; } - + // remove vid, rnd unset($get_vars['rnd']); - if($vid) - { - $get_vars['vid'] = $vid; - } - else - { - unset($get_vars['vid']); - } - + unset($get_vars['vid']); + // for compatibility to lower versions $act = $get_vars['act']; $act_alias = array( @@ -1643,7 +1627,7 @@ class Context { $get_vars['act'] = $act_alias[$act]; } - + // organize URL $query = ''; if(count($get_vars) > 0) @@ -1653,47 +1637,32 @@ class Context { $var_keys = array_keys($get_vars); sort($var_keys); - $target = join('.', $var_keys); - $act = $get_vars['act']; - $vid = $get_vars['vid']; $mid = $get_vars['mid']; $key = $get_vars['key']; $srl = $get_vars['document_srl']; - $tmpArray = array('rss' => 1, 'atom' => 1, 'api' => 1); $is_feed = isset($tmpArray[$act]); - $target_map = array( - 'vid' => $vid, 'mid' => $mid, - 'mid.vid' => "$vid/$mid", 'category.mid' => "$mid/category/" . $get_vars['category'], 'entry.mid' => "$mid/entry/" . $get_vars['entry'], - 'entry.mid.vid' => "$vid/$mid/entry/" . $get_vars['entry'], 'document_srl' => $srl, 'document_srl.mid' => "$mid/$srl", - 'document_srl.vid' => "$vid/$srl", - 'document_srl.mid.vid' => "$vid/$mid/$srl", 'act' => ($is_feed && $act !== 'api') ? $act : '', 'act.mid' => $is_feed ? "$mid/$act" : '', - 'act.mid.vid' => $is_feed ? "$vid/$mid/$act" : '', 'act.document_srl.key' => ($act == 'trackback') ? "$srl/$key/$act" : '', 'act.document_srl.key.mid' => ($act == 'trackback') ? "$mid/$srl/$key/$act" : '', - 'act.document_srl.key.vid' => ($act == 'trackback') ? "$vid/$srl/$key/$act" : '', - 'act.document_srl.key.mid.vid' => ($act == 'trackback') ? "$vid/$mid/$srl/$key/$act" : '' ); - $query = $target_map[$target]; } - if(!$query && count($get_vars) > 0) { $query = 'index.php?' . http_build_query($get_vars); } } - + // If using SSL always $_use_ssl = self::get('_use_ssl'); if($_use_ssl == 'always') @@ -1759,7 +1728,7 @@ class Context */ public static function getRequestUri($ssl_mode = FOLLOW_REQUEST_SSL, $domain = null) { - static $url = array(); + static $domain_infos = array(); // Check HTTP Request if(!isset($_SERVER['SERVER_PROTOCOL'])) @@ -1772,20 +1741,6 @@ class Context $ssl_mode = ENFORCE_SSL; } - if($domain) - { - $domain_key = md5($domain); - } - else - { - $domain_key = 'default'; - } - - if(isset($url[$ssl_mode][$domain_key])) - { - return $url[$ssl_mode][$domain_key]; - } - switch($ssl_mode) { case FOLLOW_REQUEST_SSL: $use_ssl = RX_SSL; @@ -1796,50 +1751,21 @@ class Context break; } - if($domain) + $site_module_info = self::get('site_module_info'); + if ($domain !== null && $domain !== $site_module_info->domain) { - $target_url = rtrim(trim($domain), '/') . '/'; - } - else - { - $target_url = $_SERVER['HTTP_HOST'] . RX_BASEURL; - } - - $url_info = parse_url('http://' . $target_url); - - if($use_ssl != RX_SSL) - { - unset($url_info['port']); - } - - if($use_ssl) - { - $port = self::get('_https_port'); - if($port && $port != 443) + if (!isset($domain_infos[$domain])) { - $url_info['port'] = $port; - } - elseif($url_info['port'] == 443) - { - unset($url_info['port']); + $domain_infos[$domain] = getModel('module')->getSiteInfoByDomain($domain); } + $site_module_info = $domain_infos[$domain] ?: $site_module_info; } - else - { - $port = self::get('_http_port'); - if($port && $port != 80) - { - $url_info['port'] = $port; - } - elseif($url_info['port'] == 80) - { - unset($url_info['port']); - } - } - - $url[$ssl_mode][$domain_key] = sprintf('%s://%s%s%s', $use_ssl ? 'https' : $url_info['scheme'], $url_info['host'], $url_info['port'] && $url_info['port'] != 80 ? ':' . $url_info['port'] : '', $url_info['path']); - - return $url[$ssl_mode][$domain_key]; + + $prefix = ($use_ssl && $site_module_info->security !== 'none') ? 'https://' : 'http://'; + $hostname = $site_module_info->domain; + $port = ($use_ssl && $site_module_info->security !== 'none') ? $site_module_info->https_port : $site_module_info->http_port; + $result = $prefix . $hostname . ($port ? sprintf(':%d', $port) : '') . RX_BASEURL; + return $result; } /** diff --git a/classes/display/HTMLDisplayHandler.php b/classes/display/HTMLDisplayHandler.php index aa67124a2..0e6360ace 100644 --- a/classes/display/HTMLDisplayHandler.php +++ b/classes/display/HTMLDisplayHandler.php @@ -221,9 +221,10 @@ class HTMLDisplayHandler } // set icon + $site_module_info = Context::get('site_module_info'); $oAdminModel = getAdminModel('admin'); - $favicon_url = $oAdminModel->getFaviconUrl(false); - $mobicon_url = $oAdminModel->getMobileIconUrl(false); + $favicon_url = $oAdminModel->getFaviconUrl($site_module_info->domain_srl); + $mobicon_url = $oAdminModel->getMobileIconUrl($site_module_info->domain_srl); Context::set('favicon_url', $favicon_url); Context::set('mobicon_url', $mobicon_url); @@ -500,7 +501,7 @@ class HTMLDisplayHandler Context::addOpenGraphData('og:image:width', $first_image['width']); Context::addOpenGraphData('og:image:height', $first_image['height']); } - elseif ($default_image = getAdminModel('admin')->getSiteDefaultImageUrl($width, $height)) + elseif ($default_image = getAdminModel('admin')->getSiteDefaultImageUrl($site_module_info->domain_srl, $width, $height)) { Context::addOpenGraphData('og:image', Rhymix\Framework\URL::getCurrentDomainURL($default_image)); if ($width && $height) diff --git a/classes/module/ModuleHandler.class.php b/classes/module/ModuleHandler.class.php index 983892843..e0eec9d44 100644 --- a/classes/module/ModuleHandler.class.php +++ b/classes/module/ModuleHandler.class.php @@ -126,6 +126,34 @@ class ModuleHandler extends Handler { $oModuleModel = getModel('module'); $site_module_info = Context::get('site_module_info'); + + // Check unregistered domain action. + if (!$site_module_info || !isset($site_module_info->domain_srl) || $site_module_info->is_default_replaced) + { + $site_module_info = getModel('module')->getDefaultDomainInfo(); + if ($site_module_info) + { + $domain_action = config('url.unregistered_domain_action') ?: 'redirect_301'; + switch ($domain_action) + { + case 'redirect_301': + header('Location: ' . Context::getDefaultUrl($site_module_info) . RX_REQUEST_URL, true, 301); + return false; + + case 'redirect_302': + header('Location: ' . Context::getDefaultUrl($site_module_info) . RX_REQUEST_URL, true, 302); + return false; + + case 'block': + $this->error = 'The site does not exist'; + $this->httpStatusCode = 404; + return true; + + case 'display': + // pass + } + } + } // if success_return_url and error_return_url is incorrect $urls = array(Context::get('success_return_url'), Context::get('error_return_url')); @@ -155,6 +183,7 @@ class ModuleHandler extends Handler } } + // Convert document alias (entry) to document_srl if(!$this->document_srl && $this->mid && $this->entry) { $oDocumentModel = getModel('document'); @@ -231,15 +260,6 @@ class ModuleHandler extends Handler //if($this->module && $module_info->module != $this->module) unset($module_info); } - // redirect, if module_site_srl and site_srl are different - if(!$this->module && !$module_info && $site_module_info->site_srl == 0 && $site_module_info->module_site_srl > 0) - { - Context::setCacheControl(0); - $site_info = $oModuleModel->getSiteInfo($site_module_info->module_site_srl); - header('location: ' . getNotEncodedSiteUrl($site_info->domain, 'mid', $site_module_info->mid), true, 301); - return false; - } - // If module_info is not set still, and $module does not exist, find the default module if(!$module_info && !$this->module && !$this->mid) { @@ -251,28 +271,14 @@ class ModuleHandler extends Handler $module_info = $site_module_info; } - // redirect, if site_srl of module_info is different from one of site's module_info - if($module_info && $module_info->site_srl != $site_module_info->site_srl && !Rhymix\Framework\UA::isRobot()) + // Set index document + if($site_module_info->index_document_srl && !$this->module && !$this->mid && !$this->document_srl && Context::getRequestMethod() === 'GET' && !count($_GET)) { - // If the module is of virtual site - if($module_info->site_srl) - { - $site_info = $oModuleModel->getSiteInfo($module_info->site_srl); - $redirect_url = getNotEncodedSiteUrl($site_info->domain, 'mid', Context::get('mid'), 'document_srl', Context::get('document_srl'), 'module_srl', Context::get('module_srl'), 'entry', Context::get('entry')); - // If it's called from a virtual site, though it's not a module of the virtual site - } - else - { - $redirect_url = getNotEncodedSiteUrl(Context::getDefaultUrl(), 'mid', Context::get('mid'), 'document_srl', Context::get('document_srl'), 'module_srl', Context::get('module_srl'), 'entry', Context::get('entry')); - } - - Context::setCacheControl(0); - header("Location: $redirect_url", true, 301); - return false; + Context::set('document_srl', $this->document_srl = $site_module_info->index_document_srl, true); } - + // redirect, if site start module - if(Context::getRequestMethod() === 'GET' && isset($_GET['mid']) && $_GET['mid'] === $site_module_info->mid && count($_GET) === 1) + if(!$site_module_info->index_document_srl && Context::getRequestMethod() === 'GET' && isset($_GET['mid']) && $_GET['mid'] === $site_module_info->mid && count($_GET) === 1) { Context::setCacheControl(0); header('location: ' . getNotEncodedSiteUrl($site_module_info->domain), true, 301); @@ -794,16 +800,16 @@ class ModuleHandler extends Handler if($type == "view" && $kind != 'admin') { - $module_config = $oModuleModel->getModuleConfig('module'); - if($module_config->htmlFooter) + $domain_info = Context::get('site_module_info'); + if ($domain_info && $domain_info->settings && $domain_info->settings->html_footer) { - Context::addHtmlFooter($module_config->htmlFooter); + Context::addHtmlFooter($domain_info->settings->html_footer); } - if($module_config->siteTitle) + if ($domain_info && $domain_info->settings && $domain_info->settings->title) { if(!Context::getBrowserTitle()) { - Context::setBrowserTitle($module_config->siteTitle); + Context::setBrowserTitle($domain_info->settings->title); } } } diff --git a/common/defaults/blacklist.php b/common/defaults/blacklist.php index b3add3eaf..a234750bf 100644 --- a/common/defaults/blacklist.php +++ b/common/defaults/blacklist.php @@ -10,7 +10,9 @@ return array( 'auto_login' => true, 'errorlogger' => true, 'fix_mysql_utf8' => true, + 'homepage' => true, 'member_communication' => true, + 'multidomain' => true, 'seo' => true, 'session_shield' => true, 'smartphone' => true, diff --git a/common/defaults/config.php b/common/defaults/config.php index 684824a7b..8a9f620ef 100644 --- a/common/defaults/config.php +++ b/common/defaults/config.php @@ -44,6 +44,7 @@ return array( ), 'url' => array( 'default' => null, + 'unregistered_domain_action' => 'redirect_301', 'http_port' => null, 'https_port' => null, 'ssl' => 'none', diff --git a/common/framework/datetime.php b/common/framework/datetime.php index 66511d2ba..c4df3a7ea 100644 --- a/common/framework/datetime.php +++ b/common/framework/datetime.php @@ -66,6 +66,10 @@ class DateTime { return $_SESSION['RHYMIX']['timezone']; } + elseif ($default = \Context::get('_default_timezone')) + { + return $default; + } elseif ($default = Config::get('locale.default_timezone')) { return $default; diff --git a/common/framework/security.php b/common/framework/security.php index f0eb05fb3..751a8c4b0 100644 --- a/common/framework/security.php +++ b/common/framework/security.php @@ -310,10 +310,10 @@ class Security if (!$referer) { $referer = strval($_SERVER['HTTP_REFERER']); - if ($referer === '') - { - return true; - } + } + if (strval($referer) === '') + { + return true; } return URL::isInternalURL($referer); diff --git a/common/framework/session.php b/common/framework/session.php index 4379f8e56..b3643473c 100644 --- a/common/framework/session.php +++ b/common/framework/session.php @@ -270,87 +270,92 @@ class Session * This method uses more or less the same logic as XE's SSO mechanism. * It may need to be changed to a more secure mechanism later. * - * @return bool + * @param object $site_module_info + * @return void */ - public static function checkSSO() + public static function checkSSO($site_module_info) { // Abort if SSO is disabled, the visitor is a robot, or this is not a typical GET request. if ($_SERVER['REQUEST_METHOD'] !== 'GET' || !config('use_sso') || UA::isRobot() || in_array(\Context::get('act'), array('rss', 'atom'))) { - return false; - } - - // Abort of the default URL is not set. - $default_url = \Context::getDefaultUrl(); - if (!$default_url) - { - return false; + return; } // Get the current site information. - $current_url = URL::getCurrentURL(); - $current_host = parse_url($current_url, \PHP_URL_HOST); - $default_host = parse_url($default_url, \PHP_URL_HOST); + $is_default_domain = ($site_module_info->domain_srl == 0); + if (!$is_default_domain) + { + $current_domain = $site_module_info->domain; + $current_url = URL::getCurrentUrl(); + $default_domain = getModel('module')->getDefaultDomainInfo(); + $default_url = \Context::getDefaultUrl($default_domain); + } // Step 1: if the current site is not the default site, send SSO validation request to the default site. - if($default_host !== $current_host && !\Context::get('sso_response') && $_COOKIE['sso'] !== md5($current_host)) + if(!$is_default_domain && !\Context::get('sso_response') && $_COOKIE['sso'] !== md5($current_domain)) { // Set sso cookie to prevent multiple simultaneous SSO validation requests. - setcookie('sso', md5($current_host), 0, '/'); + setcookie('sso', md5($current_domain), 0, '/'); // Redirect to the default site. $sso_request = Security::encrypt($current_url); header('Location:' . URL::modifyURL($default_url, array('sso_request' => $sso_request))); - return true; + exit; } // Step 2: receive and process SSO validation request at the default site. - if($default_host === $current_host && \Context::get('sso_request')) + if($is_default_domain && \Context::get('sso_request')) { // Get the URL of the origin site $sso_request = Security::decrypt(\Context::get('sso_request')); if (!$sso_request || !preg_match('!^https?://!', $sso_request)) { \Context::displayErrorPage('SSO Error', 'Invalid SSO Request', 400); - return true; + exit; + } + if (!URL::isInternalUrl($sso_request) || !Security::checkCSRF()) + { + \Context::displayErrorPage('SSO Error', 'Invalid SSO Request', 400); + exit; } - // Redirect back to the origin site. + // Encrypt the session ID. + self::start(true); $sso_response = Security::encrypt(session_id()); + + // Redirect back to the origin site. header('Location: ' . URL::modifyURL($sso_request, array('sso_response' => $sso_response))); - return true; + self::close(); + exit; } // Step 3: back at the origin site, set session ID to be the same as the default site. - if($default_host !== $current_host && \Context::get('sso_response')) + if(!$is_default_domain && \Context::get('sso_response')) { // Check SSO response $sso_response = Security::decrypt(\Context::get('sso_response')); if ($sso_response === false) { \Context::displayErrorPage('SSO Error', 'Invalid SSO Response', 400); - return true; + exit; } // Check that the response was given by the default site (to prevent session fixation CSRF). - if(isset($_SERVER['HTTP_REFERER']) && strpos($_SERVER['HTTP_REFERER'], $default_url) !== 0) + if(isset($_SERVER['HTTP_REFERER']) && strpos(URL::decodeIdna($_SERVER['HTTP_REFERER']), $default_url) !== 0) { \Context::displayErrorPage('SSO Error', 'Invalid SSO Response', 400); - return true; + exit; } - // Set session ID. - self::close(); + // Set the session ID. session_id($sso_response); - self::start(); + self::start(true, false); // Finally, redirect to the originally requested URL. header('Location: ' . URL::getCurrentURL(array('sso_response' => null))); - return true; + self::close(); + exit; } - - // If none of the conditions above apply, proceed normally. - return false; } /** diff --git a/common/framework/storage.php b/common/framework/storage.php index 86bcadffc..a9ff297be 100644 --- a/common/framework/storage.php +++ b/common/framework/storage.php @@ -456,6 +456,11 @@ class Storage return false; } + if (is_uploaded_file($source)) + { + @chmod($destination, 0666 & ~self::getUmask()); + } + if (function_exists('opcache_invalidate')) { if (substr($source, -4) === '.php') diff --git a/common/framework/url.php b/common/framework/url.php index f41c5dc09..05775cee5 100644 --- a/common/framework/url.php +++ b/common/framework/url.php @@ -98,7 +98,7 @@ class URL return true; } - if ($domain === self::getDomainFromURL(\Context::getDefaultUrl())) + if (getModel('module')->getSiteInfoByDomain($domain)) { return true; } diff --git a/common/legacy.php b/common/legacy.php index a976c5a6f..f41ef8d9d 100644 --- a/common/legacy.php +++ b/common/legacy.php @@ -1051,24 +1051,7 @@ function requirePear() */ function checkCSRF() { - // Use Rhymix Security class first. - if (Rhymix\Framework\Security::checkCSRF()) - { - return true; - } - - // Check if we have a virtual site with a matching domain. - $oModuleModel = getModel('module'); - $siteModuleInfo = $oModuleModel->getDefaultMid(); - $virtualSiteInfo = $oModuleModel->getSiteInfo($siteModuleInfo->site_srl); - if (strcasecmp($virtualSiteInfo->domain, Context::get('vid')) && stristr($virtualSiteInfo->domain, $referer_host)) - { - return true; - } - else - { - return false; - } + return Rhymix\Framework\Security::checkCSRF(); } /** diff --git a/common/manual/server_config/rhymix-nginx-subdir.conf b/common/manual/server_config/rhymix-nginx-subdir.conf index 3559ccb9c..3524fa495 100644 --- a/common/manual/server_config/rhymix-nginx-subdir.conf +++ b/common/manual/server_config/rhymix-nginx-subdir.conf @@ -31,11 +31,10 @@ location ~ ^/rhymix/(.+)\.min\.(css|js)$ { # rss, blogAPI rewrite ^/rhymix/(rss|atom)$ /rhymix/index.php?module=rss&act=$1 last; rewrite ^/rhymix/([a-zA-Z0-9_]+)/(rss|atom|api)$ /rhymix/index.php?mid=$1&act=$2 last; -rewrite ^/rhymix/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/(rss|atom|api)$ /rhymix/index.php?vid=$1&mid=$2&act=$3 last; # trackback rewrite ^/rhymix/([0-9]+)/(.+)/trackback$ /rhymix/index.php?document_srl=$1&key=$2&act=trackback last; -rewrite ^/rhymix/([a-zA-Z0-9_]+)/([0-9]+)/(.+)/trackback$ /rhymix/index.php?vid=$1&document_srl=$2&key=$3&act=trackback last; +rewrite ^/rhymix/([a-zA-Z0-9_]+)/([0-9]+)/(.+)/trackback$ /rhymix/index.php?mid=$1&document_srl=$2&key=$3&act=trackback last; # administrator page rewrite ^/rhymix/admin/?$ /rhymix/index.php?module=admin last; @@ -52,14 +51,5 @@ rewrite ^/rhymix/([a-zA-Z0-9_]+)/?$ /rhymix/index.php?mid=$1 last; # mid + document link rewrite ^/rhymix/([a-zA-Z0-9_]+)/([0-9]+)$ /rhymix/index.php?mid=$1&document_srl=$2 last; -# vid + mid link -rewrite ^/rhymix/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/?$ /rhymix/index.php?vid=$1&mid=$2 last; - -# vid + mid + document link -rewrite ^/rhymix/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([0-9]+)$ /rhymix/index.php?vid=$1&mid=$2&document_srl=$3 last; - # mid + entry title rewrite ^/rhymix/([a-zA-Z0-9_]+)/entry/(.+)$ /rhymix/index.php?mid=$1&entry=$2 last; - -# vid + mid + entry title -rewrite ^/rhymix/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/entry/(.+)$ /rhymix/index.php?vid=$1&mid=$2&entry=$3 last; diff --git a/common/manual/server_config/rhymix-nginx.conf b/common/manual/server_config/rhymix-nginx.conf index 5ea8ab1e0..6edcf6922 100644 --- a/common/manual/server_config/rhymix-nginx.conf +++ b/common/manual/server_config/rhymix-nginx.conf @@ -31,11 +31,10 @@ location ~ ^/(.+)\.min\.(css|js)$ { # rss, blogAPI rewrite ^/(rss|atom)$ /index.php?module=rss&act=$1 last; rewrite ^/([a-zA-Z0-9_]+)/(rss|atom|api)$ /index.php?mid=$1&act=$2 last; -rewrite ^/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/(rss|atom|api)$ /index.php?vid=$1&mid=$2&act=$3 last; # trackback rewrite ^/([0-9]+)/(.+)/trackback$ /index.php?document_srl=$1&key=$2&act=trackback last; -rewrite ^/([a-zA-Z0-9_]+)/([0-9]+)/(.+)/trackback$ /index.php?vid=$1&document_srl=$2&key=$3&act=trackback last; +rewrite ^/([a-zA-Z0-9_]+)/([0-9]+)/(.+)/trackback$ /index.php?mid=$1&document_srl=$2&key=$3&act=trackback last; # administrator page rewrite ^/admin/?$ /index.php?module=admin last; @@ -52,14 +51,5 @@ rewrite ^/([a-zA-Z0-9_]+)/?$ /index.php?mid=$1 last; # mid + document link rewrite ^/([a-zA-Z0-9_]+)/([0-9]+)$ /index.php?mid=$1&document_srl=$2 last; -# vid + mid link -rewrite ^/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/?$ /index.php?vid=$1&mid=$2 last; - -# vid + mid + document link -rewrite ^/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([0-9]+)$ /index.php?vid=$1&mid=$2&document_srl=$3 last; - # mid + entry title rewrite ^/([a-zA-Z0-9_]+)/entry/(.+)$ /index.php?mid=$1&entry=$2 last; - -# vid + mid + entry title -rewrite ^/([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/entry/(.+)$ /index.php?vid=$1&mid=$2&entry=$3 last; diff --git a/common/tpl/common_layout.html b/common/tpl/common_layout.html index e6350e4c2..05b95716e 100644 --- a/common/tpl/common_layout.html +++ b/common/tpl/common_layout.html @@ -56,7 +56,7 @@ var https_port = {Context::get("_https_port") ?: 'null'}; var enforce_ssl = {Context::get('_use_ssl') === 'always' ? 'true' : 'false'}; var ssl_actions = {json_encode(array_keys(Context::getSSLActions()))}; - var xeVid = {json_encode($vid ?: null)}; + var xeVid = null; diff --git a/index.php b/index.php index bd0e2d53b..27aaa6a15 100644 --- a/index.php +++ b/index.php @@ -47,17 +47,10 @@ $oContext = Context::getInstance(); $oContext->init(); /** - * @brief If default_url is set and it is different from the current url, attempt to redirect for SSO authentication and then process the module + * @brief Initialize and execute Module Handler **/ -if($oContext->checkSSO()) -{ - $oModuleHandler = new ModuleHandler(); - - if($oModuleHandler->init()) - { - $oModuleHandler->displayContent($oModuleHandler->procModule()); - } -} +$oModuleHandler = new ModuleHandler(); +$oModuleHandler->init() && $oModuleHandler->displayContent($oModuleHandler->procModule()); Context::close(); diff --git a/modules/admin/admin.admin.controller.php b/modules/admin/admin.admin.controller.php index 6183e5913..ac0c2b78b 100644 --- a/modules/admin/admin.admin.controller.php +++ b/modules/admin/admin.admin.controller.php @@ -501,61 +501,29 @@ class adminAdminController extends admin } /** - * Update general configuration. + * Update domains configuration. */ - function procAdminUpdateConfigGeneral() + function procAdminUpdateDomains() { - $oModuleController = getController('module'); $vars = Context::getRequestVars(); - // Site title and HTML footer - $args = new stdClass; - $args->siteTitle = $vars->site_title; - $args->siteSubtitle = $vars->site_subtitle; - $args->htmlFooter = $vars->html_footer; - $oModuleController->updateModuleConfig('module', $args); - - // Index module - $site_args = new stdClass(); - $site_args->site_srl = 0; - $site_args->index_module_srl = $vars->index_module_srl; - $site_args->default_language = $vars->default_lang; - $oModuleController->updateSite($site_args); - - // Default and enabled languages - $enabled_lang = $vars->enabled_lang; - if (!in_array($vars->default_lang, $enabled_lang)) + // Validate the unregistered domain action. + $valid_actions = array('redirect_301', 'redirect_302', 'display', 'block'); + if (!in_array($vars->unregistered_domain_action, $valid_actions)) { - $enabled_lang[] = $vars->default_lang; - } - Rhymix\Framework\Config::set('locale.default_lang', $vars->default_lang); - Rhymix\Framework\Config::set('locale.enabled_lang', array_values($enabled_lang)); - Rhymix\Framework\Config::set('locale.auto_select_lang', $vars->auto_select_lang === 'Y'); - - // Default time zone - Rhymix\Framework\Config::set('locale.default_timezone', $vars->default_timezone); - - // Mobile view - Rhymix\Framework\Config::set('mobile.enabled', $vars->use_mobile_view === 'Y'); - Rhymix\Framework\Config::set('mobile.tablets', $vars->tablets_as_mobile === 'Y'); - if (Rhymix\Framework\Config::get('use_mobile_view') !== null) - { - Rhymix\Framework\Config::set('use_mobile_view', $vars->use_mobile_view === 'Y'); + $vars->unregistered_domain_action = 'redirect_301'; } - // Favicon and mobicon - $this->_saveFavicon('favicon.ico', $vars->is_delete_favicon); - $this->_saveFavicon('mobicon.png', $vars->is_delete_mobicon); - $this->_saveDefaultImage($vars->is_delete_default_image); - - // Save + // Save system config. + Rhymix\Framework\Config::set('url.unregistered_domain_action', $vars->unregistered_domain_action); + Rhymix\Framework\Config::set('use_sso', $vars->use_sso === 'Y'); if (!Rhymix\Framework\Config::save()) { return new Object(-1, 'msg_failed_to_save_config'); } $this->setMessage('success_updated'); - $this->setRedirectUrl(Context::get('success_return_url') ?: getNotEncodedUrl('', 'module', 'admin', 'act', 'dispAdminConfigGeneral')); + $this->setRedirectUrl(Context::get('success_return_url') ?: getNotEncodedUrl('', 'module', 'admin', 'act', 'dispAdminConfigGeneral')); } /** @@ -752,46 +720,6 @@ class adminAdminController extends admin { $vars = Context::getRequestVars(); - // Default URL - $default_url = rtrim(trim($vars->default_url), '/\\') . '/'; - if (!filter_var(Rhymix\Framework\URL::encodeIdna($default_url), FILTER_VALIDATE_URL) || !preg_match('@^https?://@', $default_url)) - { - return new Object(-1, 'msg_invalid_default_url'); - } - if (parse_url($default_url, PHP_URL_PATH) !== RX_BASEURL) - { - return new Object(-1, 'msg_invalid_default_url'); - } - - // SSL and ports - if ($vars->http_port == 80) $vars->http_port = null; - if ($vars->https_port == 443) $vars->https_port = null; - $use_ssl = $vars->use_ssl ?: 'none'; - - // Check if all URL configuration is consistent - if ($use_ssl === 'always' && !preg_match('@^https://@', $default_url)) - { - return new Object(-1, 'msg_default_url_ssl_inconsistent'); - } - if ($vars->http_port && preg_match('@^http://@', $default_url) && parse_url($default_url, PHP_URL_PORT) != $vars->http_port) - { - return new Object(-1, 'msg_default_url_http_port_inconsistent'); - } - if ($vars->https_port && preg_match('@^https://@', $default_url) && parse_url($default_url, PHP_URL_PORT) != $vars->https_port) - { - return new Object(-1, 'msg_default_url_https_port_inconsistent'); - } - - // Set all URL configuration - Rhymix\Framework\Config::set('url.default', $default_url); - Rhymix\Framework\Config::set('url.http_port', $vars->http_port ?: null); - Rhymix\Framework\Config::set('url.https_port', $vars->https_port ?: null); - Rhymix\Framework\Config::set('url.ssl', $use_ssl); - getController('module')->updateSite((object)array( - 'site_srl' => 0, - 'domain' => preg_replace('@^https?://@', '', $default_url), - )); - // Object cache if ($vars->object_cache_type) { @@ -829,9 +757,27 @@ class adminAdminController extends admin $oModuleController = getController('module'); $oModuleController->insertModuleConfig('document', $document_config); + // Mobile view + Rhymix\Framework\Config::set('mobile.enabled', $vars->use_mobile_view === 'Y'); + Rhymix\Framework\Config::set('mobile.tablets', $vars->tablets_as_mobile === 'Y'); + if (Rhymix\Framework\Config::get('use_mobile_view') !== null) + { + Rhymix\Framework\Config::set('use_mobile_view', $vars->use_mobile_view === 'Y'); + } + + // Languages and time zone + $enabled_lang = $vars->enabled_lang; + if (!in_array($vars->default_lang, $enabled_lang)) + { + $enabled_lang[] = $vars->default_lang; + } + Rhymix\Framework\Config::set('locale.default_lang', $vars->default_lang); + Rhymix\Framework\Config::set('locale.enabled_lang', array_values($enabled_lang)); + Rhymix\Framework\Config::set('locale.auto_select_lang', $vars->auto_select_lang === 'Y'); + Rhymix\Framework\Config::set('locale.default_timezone', $vars->default_timezone); + // Other settings Rhymix\Framework\Config::set('use_rewrite', $vars->use_rewrite === 'Y'); - Rhymix\Framework\Config::set('use_sso', $vars->use_sso === 'Y'); Rhymix\Framework\Config::set('session.delay', $vars->delay_session === 'Y'); Rhymix\Framework\Config::set('session.use_db', $vars->use_db_session === 'Y'); Rhymix\Framework\Config::set('session.use_keys', $vars->use_session_keys === 'Y'); @@ -988,6 +934,259 @@ class adminAdminController extends admin $this->setRedirectUrl(Context::get('success_return_url') ?: getNotEncodedUrl('', 'module', 'admin', 'act', 'dispAdminConfigSitelock')); } + /** + * Insert or update domain info + * @return void + */ + function procAdminInsertDomain() + { + $vars = Context::getRequestVars(); + $domain_srl = strval($vars->domain_srl); + $domain_info = null; + if ($domain_srl !== '') + { + $domain_info = getModel('module')->getSiteInfo($domain_srl); + if ($domain_info->domain_srl != $domain_srl) + { + return new Object(-1, 'msg_domain_not_found'); + } + } + + // Validate the title and subtitle. + $vars->title = utf8_trim($vars->title); + $vars->subtitle = utf8_trim($vars->subtitle); + if ($vars->title === '') + { + return new Object(-1, 'msg_site_title_is_empty'); + } + + // Validate the domain. + if (!preg_match('@^https?://@', $vars->domain)) + { + $vars->domain = 'http://' . $vars->domain; + } + try + { + $vars->domain = Rhymix\Framework\URL::getDomainFromUrl(strtolower($vars->domain)); + } + catch (Exception $e) + { + $vars->domain = ''; + } + if (!$vars->domain) + { + return new Object(-1, 'msg_invalid_domain'); + } + $existing_domain = getModel('module')->getSiteInfoByDomain($vars->domain); + if ($existing_domain && $existing_domain->domain == $vars->domain && (!$domain_info || $existing_domain->domain_srl != $domain_info->domain_srl)) + { + return new Object(-1, 'msg_domain_already_exists'); + } + + // Validate the ports. + if ($vars->http_port == 80 || !$vars->http_port) + { + $vars->http_port = 0; + } + if ($vars->https_port == 443 || !$vars->https_port) + { + $vars->https_port = 0; + } + if ($vars->http_port !== 0 && ($vars->http_port < 1 || $vars->http_port > 65535 || $vars->http_port == 443)) + { + return new Object(-1, 'msg_invalid_http_port'); + } + if ($vars->https_port !== 0 && ($vars->https_port < 1 || $vars->https_port > 65535 || $vars->https_port == 80)) + { + return new Object(-1, 'msg_invalid_https_port'); + } + + // Validate the security setting. + $valid_security_options = array('none', 'optional', 'always'); + if (!in_array($vars->domain_security, $valid_security_options)) + { + $vars->domain_security = 'none'; + } + + // Validate the index module setting. + $module_info = getModel('module')->getModuleInfoByModuleSrl(intval($vars->index_module_srl)); + if (!$module_info || $module_info->module_srl != $vars->index_module_srl) + { + return new Object(-1, 'msg_invalid_index_module_srl'); + } + + // Validate the index document setting. + if ($vars->index_document_srl) + { + $oDocument = getModel('document')->getDocument($vars->index_document_srl); + if (!$oDocument || !$oDocument->isExists()) + { + return new Object(-1, 'msg_invalid_index_document_srl'); + } + if (intval($oDocument->get('module_srl')) !== intval($vars->index_module_srl)) + { + return new Object(-1, 'msg_invalid_index_document_srl_module_srl'); + } + } + else + { + $vars->index_document_srl = 0; + } + + // Validate the default language. + $enabled_lang = Rhymix\Framework\Config::get('locale.enabled_lang'); + if (!in_array($vars->default_lang, $enabled_lang)) + { + return new Object(-1, 'msg_lang_is_not_enabled'); + } + + // Validate the default time zone. + $timezone_list = Rhymix\Framework\DateTime::getTimezoneList(); + if (!isset($timezone_list[$vars->default_timezone])) + { + return new Object(-1, 'msg_invalid_timezone'); + } + + // Clean up the footer script. + $vars->html_footer = utf8_trim($vars->html_footer); + + // Merge all settings into an array. + $settings = array( + 'title' => $vars->title, + 'subtitle' => $vars->subtitle, + 'language' => $vars->default_lang, + 'timezone' => $vars->default_timezone, + 'html_footer' => $vars->html_footer, + ); + + // Get the DB object and begin a transaction. + $oDB = DB::getInstance(); + $oDB->begin(); + + // Insert or update the domain. + if (!$domain_info) + { + $args = new stdClass(); + $args->domain_srl = $domain_srl = getNextSequence(); + $args->domain = $vars->domain; + $args->is_default_domain = $vars->is_default_domain === 'Y' ? 'Y' : 'N'; + $args->index_module_srl = $vars->index_module_srl; + $args->index_document_srl = $vars->index_document_srl; + $args->http_port = $vars->http_port; + $args->https_port = $vars->https_port; + $args->security = $vars->domain_security; + $args->description = ''; + $args->settings = json_encode($settings); + $output = executeQuery('module.insertDomain', $args); + if (!$output->toBool()) + { + return $output; + } + } + else + { + $args = new stdClass(); + $args->domain_srl = $domain_info->domain_srl; + $args->domain = $vars->domain; + $args->is_default_domain = $vars->is_default_domain === 'Y' ? 'Y' : 'N'; + $args->index_module_srl = $vars->index_module_srl; + $args->index_document_srl = $vars->index_document_srl; + $args->http_port = $vars->http_port; + $args->https_port = $vars->https_port; + $args->security = $vars->domain_security; + $args->settings = json_encode(array_merge(get_object_vars($domain_info->settings), $settings)); + $output = executeQuery('module.updateDomain', $args); + if (!$output->toBool()) + { + return $output; + } + } + + // If changing the default domain, set all other domains as non-default. + if ($vars->is_default_domain === 'Y') + { + $args = new stdClass(); + $args->not_domain_srl = $domain_srl; + $output = executeQuery('module.updateDefaultDomain', $args); + if (!$output->toBool()) + { + return $output; + } + } + + // Save the favicon, mobicon, and default image. + if ($vars->favicon || $vars->delete_favicon) + { + $this->_saveFavicon($domain_srl, $vars->favicon, 'favicon.ico', $vars->delete_favicon); + } + if ($vars->mobicon || $vars->delete_mobicon) + { + $this->_saveFavicon($domain_srl, $vars->mobicon, 'mobicon.png', $vars->delete_mobicon); + } + if ($vars->default_image || $vars->delete_default_image) + { + $this->_saveDefaultImage($domain_srl, $vars->default_image, $vars->delete_default_image); + } + + // Update system configuration to match the default domain. + if ($domain_info && $domain_info->is_default_domain === 'Y') + { + $domain_info->domain = $vars->domain; + $domain_info->http_port = $vars->http_port; + $domain_info->https_port = $vars->https_port; + $domain_info->security = $vars->domain_security; + Rhymix\Framework\Config::set('url.default', Context::getDefaultUrl($domain_info)); + Rhymix\Framework\Config::set('url.http_port', $vars->http_port ?: null); + Rhymix\Framework\Config::set('url.https_port', $vars->https_port ?: null); + Rhymix\Framework\Config::set('url.ssl', $vars->domain_security); + Rhymix\Framework\Config::save(); + } + + // Commit. + $oDB->commit(); + + // Clear cache. + Rhymix\Framework\Cache::clearGroup('site_and_module'); + + // Redirect to the domain list. + $this->setRedirectUrl(Context::get('success_return_url') ?: getNotEncodedUrl('', 'module', 'admin', 'act', 'dispAdminConfigGeneral')); + } + + /** + * Delete domain + * @return void + */ + function procAdminDeleteDomain() + { + // Get selected domain. + $domain_srl = strval(Context::get('domain_srl')); + if ($domain_srl === '') + { + return new Object(-1, 'msg_domain_not_found'); + } + $domain_info = getModel('module')->getSiteInfo($domain_srl); + if ($domain_info->domain_srl != $domain_srl) + { + return new Object(-1, 'msg_domain_not_found'); + } + if ($domain_info->is_default_domain === 'Y') + { + return new Object(-1, 'msg_cannot_delete_default_domain'); + } + + // Delete the domain. + $args = new stdClass(); + $args->domain_srl = $domain_srl; + $output = executeQuery('module.deleteDomain', $args); + if (!$output->toBool()) + { + return $output; + } + + // Clear cache. + Rhymix\Framework\Cache::clearGroup('site_and_module'); + } + /** * Update FTP configuration. */ @@ -1083,69 +1282,12 @@ class adminAdminController extends admin $this->setMessage('success_deleted'); } - /** - * Upload favicon and mobicon. - */ - public function procAdminFaviconUpload() - { - if ($favicon = Context::get('favicon')) - { - $name = 'favicon'; - $tmpFileName = $this->_saveFaviconTemp($favicon, 'favicon.ico'); - } - elseif ($mobicon = Context::get('mobicon')) - { - $name = 'mobicon'; - $tmpFileName = $this->_saveFaviconTemp($mobicon, 'mobicon.png'); - } - elseif ($default_image = Context::get('default_image')) - { - $name = 'default_image'; - $tmpFileName = $this->_saveFaviconTemp($default_image, 'default_image.png'); - } - else - { - $name = $tmpFileName = ''; - Context::set('msg', lang('msg_invalid_format')); - } - - Context::set('name', $name); - Context::set('tmpFileName', $tmpFileName . '?' . time()); - $this->setTemplatePath($this->module_path . 'tpl'); - $this->setTemplateFile("favicon_upload.html"); - } - - protected function _saveFaviconTemp($icon, $iconname) - { - $site_info = Context::get('site_module_info'); - $virtual_site = ''; - if ($site_info->site_srl) - { - $virtual_site = $site_info->site_srl . '/'; - } - - $original_filename = $icon['tmp_name']; - $type = $icon['type']; - $relative_filename = 'files/attach/xeicon/'.$virtual_site.'tmp/'.$iconname; - $target_filename = \RX_BASEDIR . $relative_filename; - - if (!preg_match('/^(favicon|mobicon|default_image)\.(ico|png|jpe?g)$/', $iconname)) - { - Context::set('msg', lang('msg_invalid_format')); - return; - } - - Rhymix\Framework\Storage::copy($original_filename, $target_filename, 0666 & ~umask()); - return $relative_filename; - } - - protected function _saveFavicon($iconname, $deleteIcon = false) + protected function _saveFavicon($domain_srl, $uploaded_fileinfo, $iconname, $deleteIcon = false) { $image_filepath = 'files/attach/xeicon/'; - $site_info = Context::get('site_module_info'); - if ($site_info->site_srl) + if ($domain_srl) { - $image_filepath .= $site_info->site_srl . '/'; + $image_filepath .= intval($domain_srl) . '/'; } if ($deleteIcon) @@ -1154,21 +1296,20 @@ class adminAdminController extends admin return; } - $tmpicon_filepath = $image_filepath . 'tmp/' . $iconname; + $original_filename = $uploaded_fileinfo['tmp_name']; $icon_filepath = $image_filepath . $iconname; - if (file_exists(\RX_BASEDIR . $tmpicon_filepath)) + if (is_uploaded_file($original_filename)) { - Rhymix\Framework\Storage::move(\RX_BASEDIR . $tmpicon_filepath, \RX_BASEDIR . $icon_filepath); + Rhymix\Framework\Storage::move($original_filename, \RX_BASEDIR . $icon_filepath); } } - protected function _saveDefaultImage($deleteIcon = false) + protected function _saveDefaultImage($domain_srl, $uploaded_fileinfo, $deleteIcon = false) { $image_filepath = 'files/attach/xeicon/'; - $site_info = Context::get('site_module_info'); - if ($site_info->site_srl) + if ($domain_srl) { - $image_filepath .= $site_info->site_srl . '/'; + $image_filepath .= intval($domain_srl) . '/'; } if ($deleteIcon) @@ -1182,17 +1323,17 @@ class adminAdminController extends admin return; } - $tmpicon_filepath = \RX_BASEDIR . $image_filepath . 'tmp/default_image.png'; - if (file_exists($tmpicon_filepath)) + $original_filename = $uploaded_fileinfo['tmp_name']; + if (is_uploaded_file($original_filename)) { - list($width, $height, $type) = @getimagesize($tmpicon_filepath); + list($width, $height, $type) = @getimagesize($original_filename); switch ($type) { case 'image/gif': $target_filename = $image_filepath . 'default_image.gif'; break; case 'image/jpeg': $target_filename = $image_filepath . 'default_image.jpg'; break; case 'image/png': default: $target_filename = $image_filepath . 'default_image.png'; } - Rhymix\Framework\Storage::move($tmpicon_filepath, \RX_BASEDIR . $target_filename); + Rhymix\Framework\Storage::move($original_filename, \RX_BASEDIR . $target_filename); Rhymix\Framework\Storage::writePHPData(\RX_BASEDIR . 'files/attach/xeicon/' . $virtual_site . 'default_image.php', array( 'filename' => $target_filename, 'width' => $width, 'height' => $height, )); diff --git a/modules/admin/admin.admin.model.php b/modules/admin/admin.admin.model.php index 8d26d9711..10db01b46 100644 --- a/modules/admin/admin.admin.model.php +++ b/modules/admin/admin.admin.model.php @@ -811,22 +811,22 @@ class adminAdminModel extends admin return $output->data->count; } - function getFaviconUrl($default = true) + function getFaviconUrl($domain_srl = 0) { - return $this->iconUrlCheck('favicon.ico', 'faviconSample.png', $default); + return $this->iconUrlCheck('favicon.ico', 'faviconSample.png', $domain_srl); } - function getMobileIconUrl($default = true) + function getMobileIconUrl($domain_srl = 0) { - return $this->iconUrlCheck('mobicon.png', 'mobiconSample.png', $default); + return $this->iconUrlCheck('mobicon.png', 'mobiconSample.png', $domain_srl); } - function getSiteDefaultImageUrl(&$width = 0, &$height = 0) + function getSiteDefaultImageUrl($domain_srl = 0, &$width = 0, &$height = 0) { - $site_info = Context::get('site_module_info'); - if ($site_info->site_srl) + $domain_srl = intval($domain_srl); + if ($domain_srl) { - $virtual_site = $site_info->site_srl . '/'; + $virtual_site = $domain_srl . '/'; } else { @@ -846,17 +846,12 @@ class adminAdminModel extends admin } } - function iconUrlCheck($iconname, $default_icon_name, $default) + function iconUrlCheck($iconname, $default_icon_name, $domain_srl) { - if ($default) + $domain_srl = intval($domain_srl); + if ($domain_srl) { - return \RX_BASEURL . 'modules/admin/tpl/img/' . $default_icon_name; - } - - $site_info = Context::get('site_module_info'); - if ($site_info->site_srl) - { - $virtual_site = $site_info->site_srl . '/'; + $virtual_site = $domain_srl . '/'; } else { diff --git a/modules/admin/admin.admin.view.php b/modules/admin/admin.admin.view.php index abecff245..06a7bcec2 100644 --- a/modules/admin/admin.admin.view.php +++ b/modules/admin/admin.admin.view.php @@ -407,42 +407,30 @@ class adminAdminView extends admin */ function dispAdminConfigGeneral() { - // Default and enabled languages - Context::set('supported_lang', Rhymix\Framework\Lang::getSupportedList()); - Context::set('default_lang', Rhymix\Framework\Config::get('locale.default_lang')); - Context::set('enabled_lang', Rhymix\Framework\Config::get('locale.enabled_lang')); - Context::set('auto_select_lang', Rhymix\Framework\Config::get('locale.auto_select_lang')); - - // Site title and HTML footer + // Get domain list. $oModuleModel = getModel('module'); - $config = $oModuleModel->getModuleConfig('module'); - Context::set('var_site_title', escape($config->siteTitle)); - Context::set('var_site_subtitle', escape($config->siteSubtitle)); - Context::set('all_html_footer', escape($config->htmlFooter)); + $page = intval(Context::get('page')) ?: 1; + $domain_list = $oModuleModel->getAllDomains(20, $page); + Context::set('domain_list', $domain_list); + Context::set('page_navigation', $domain_list->page_navigation); + Context::set('page', $page); - // Index module - $columnList = array('modules.mid', 'modules.browser_title', 'sites.index_module_srl'); - $start_module = $oModuleModel->getSiteInfo(0, $columnList); - Context::set('start_module', $start_module); + // Get index module info. + $module_list = array(); + $oModuleModel = getModel('module'); + foreach ($domain_list->data as $domain) + { + if ($domain->index_module_srl && !isset($module_list[$domain->index_module_srl])) + { + $module_list[$domain->index_module_srl] = $oModuleModel->getModuleInfoByModuleSrl($domain->index_module_srl); + } + } + Context::set('module_list', $module_list); - // Default time zone - Context::set('timezones', Rhymix\Framework\DateTime::getTimezoneList()); - Context::set('selected_timezone', Rhymix\Framework\Config::get('locale.default_timezone')); + // Get language list. + Context::set('supported_lang', Rhymix\Framework\Lang::getSupportedList()); - // Mobile view - Context::set('use_mobile_view', (config('mobile.enabled') !== null ? config('mobile.enabled') : config('use_mobile_view')) ? true : false); - Context::set('tablets_as_mobile', config('mobile.tablets') ? true : false); - - // Favicon and mobicon and site default image - $oAdminModel = getAdminModel('admin'); - $favicon_url = $oAdminModel->getFaviconUrl(false) ?: $oAdminModel->getFaviconUrl(); - $mobicon_url = $oAdminModel->getMobileIconUrl(false) ?: $oAdminModel->getMobileIconUrl(); - $site_default_image_url = $oAdminModel->getSiteDefaultImageUrl(); - Context::set('favicon_url', $favicon_url); - Context::set('mobicon_url', $mobicon_url); - Context::set('site_default_image_url', $site_default_image_url); - - $this->setTemplateFile('config_general'); + $this->setTemplateFile('config_domains'); } /** @@ -508,19 +496,6 @@ class adminAdminView extends admin */ function dispAdminConfigAdvanced() { - // Default URL - $default_url = Rhymix\Framework\Config::get('url.default'); - if(strpos($default_url, 'xn--') !== FALSE) - { - $default_url = Context::decodeIdna($default_url); - } - Context::set('default_url', $default_url); - - // SSL and ports - Context::set('use_ssl', Rhymix\Framework\Config::get('url.ssl') ?: 'none'); - Context::set('http_port', Rhymix\Framework\Config::get('url.http_port')); - Context::set('https_port', Rhymix\Framework\Config::get('url.https_port')); - // Object cache $object_cache_types = Rhymix\Framework\Cache::getSupportedDrivers(); $object_cache_type = Rhymix\Framework\Config::get('cache.type'); @@ -567,9 +542,21 @@ class adminAdminView extends admin $config = $oDocumentModel->getDocumentConfig(); Context::set('thumbnail_type', $config->thumbnail_type ?: 'crop'); + // Default and enabled languages + Context::set('supported_lang', Rhymix\Framework\Lang::getSupportedList()); + Context::set('default_lang', Rhymix\Framework\Config::get('locale.default_lang')); + Context::set('enabled_lang', Rhymix\Framework\Config::get('locale.enabled_lang')); + Context::set('auto_select_lang', Rhymix\Framework\Config::get('locale.auto_select_lang')); + + // Default time zone + Context::set('timezones', Rhymix\Framework\DateTime::getTimezoneList()); + Context::set('selected_timezone', Rhymix\Framework\Config::get('locale.default_timezone')); + // Other settings Context::set('use_rewrite', Rhymix\Framework\Config::get('use_rewrite')); - Context::set('use_sso', Rhymix\Framework\Config::get('use_sso')); + Context::set('use_mobile_view', (config('mobile.enabled') !== null ? config('mobile.enabled') : config('use_mobile_view')) ? true : false); + Context::set('tablets_as_mobile', config('mobile.tablets') ? true : false); + Context::set('use_ssl', Rhymix\Framework\Config::get('url.ssl')); Context::set('delay_session', Rhymix\Framework\Config::get('session.delay')); Context::set('use_session_keys', Rhymix\Framework\Config::get('session.use_keys')); Context::set('use_session_ssl', Rhymix\Framework\Config::get('session.use_ssl')); @@ -659,6 +646,73 @@ class adminAdminView extends admin $this->setTemplateFile('config_sitelock'); } + /** + * Display domain edit screen + * @return void + */ + function dispAdminInsertDomain() + { + // Get selected domain. + $domain_srl = strval(Context::get('domain_srl')); + $domain_info = null; + if ($domain_srl !== '') + { + $domain_info = getModel('module')->getSiteInfo($domain_srl); + if ($domain_info->domain_srl != $domain_srl) + { + return new Object(-1, 'msg_domain_not_found'); + } + } + Context::set('domain_info', $domain_info); + + // Get modules. + if ($domain_info && $domain_info->index_module_srl) + { + $index_module_srl = $domain_info->index_module_srl; + } + else + { + $index_module_srl = ''; + } + Context::set('index_module_srl', $index_module_srl); + + // Get language list. + Context::set('supported_lang', Rhymix\Framework\Lang::getSupportedList()); + Context::set('enabled_lang', Rhymix\Framework\Config::get('locale.enabled_lang')); + if ($domain_info && $domain_info->settings->language) + { + $domain_lang = $domain_info->settings->language; + } + else + { + $domain_lang = Rhymix\Framework\Config::get('locale.default_lang'); + } + Context::set('domain_lang', $domain_lang); + + // Get timezone list. + Context::set('timezones', Rhymix\Framework\DateTime::getTimezoneList()); + if ($domain_info && $domain_info->settings->timezone) + { + $domain_timezone = $domain_info->settings->timezone; + } + else + { + $domain_timezone = Rhymix\Framework\Config::get('locale.default_timezone'); + } + Context::set('domain_timezone', $domain_timezone); + + // Get favicon and images. + if ($domain_info) + { + $oAdminAdminModel = getAdminModel('admin'); + Context::set('favicon_url', $oAdminAdminModel->getFaviconUrl($domain_info->domain_srl)); + Context::set('mobicon_url', $oAdminAdminModel->getMobileIconUrl($domain_info->domain_srl)); + Context::set('default_image_url', $oAdminAdminModel->getSiteDefaultImageUrl($domain_info->domain_srl)); + } + + $this->setTemplateFile('config_domains_edit'); + } + /** * Display FTP Configuration(settings) page * @return void diff --git a/modules/admin/conf/module.xml b/modules/admin/conf/module.xml index 7b21ba003..3efb17ca9 100644 --- a/modules/admin/conf/module.xml +++ b/modules/admin/conf/module.xml @@ -11,6 +11,7 @@ + @@ -24,13 +25,15 @@ - + + + diff --git a/modules/admin/lang/en.php b/modules/admin/lang/en.php index d233ea1a7..3bd52af71 100644 --- a/modules/admin/lang/en.php +++ b/modules/admin/lang/en.php @@ -1,11 +1,12 @@ admin = 'Admin'; $lang->cmd_configure = 'Configure'; -$lang->subtitle_primary = 'General Settings'; -$lang->subtitle_notification = 'Notification Settings'; -$lang->subtitle_security = 'Security Settings'; -$lang->subtitle_advanced = 'Advanced Settings'; -$lang->subtitle_debug = 'Debug Settings'; +$lang->subtitle_site_info = 'Site'; +$lang->subtitle_notification = 'Notifications'; +$lang->subtitle_security = 'Security'; +$lang->subtitle_advanced = 'Advanced'; +$lang->subtitle_domains = 'Domains'; +$lang->subtitle_debug = 'Debug'; $lang->subtitle_seo = 'SEO Settings'; $lang->subtitle_etc = 'Other Settings'; $lang->current_state = 'Current state'; @@ -70,7 +71,9 @@ $lang->msg_blacklisted_reason['autolang'] = 'Similar functionality can be config $lang->msg_blacklisted_reason['auto_login'] = 'The functionality that this module used to provide is included by default in Rhymix.'; $lang->msg_blacklisted_reason['errorlogger'] = 'Similar functionality can be configured in the Debug Settings page.'; $lang->msg_blacklisted_reason['fix_mysql_utf8'] = 'The functionality that this addon used to provide is included by default in Rhymix.'; +$lang->msg_blacklisted_reason['homepage'] = 'The functionality that this module used to provide must be reimplemented using the multidomain feature of Rhymix.'; $lang->msg_blacklisted_reason['member_communication'] = 'The functionality that this addon used to provide has been moved to the member and ncenterlite modules.'; +$lang->msg_blacklisted_reason['multidomain'] = 'The functionality that this module used to provide is included by default in Rhymix.'; $lang->msg_blacklisted_reason['seo'] = 'Similar functionality can be configured in the SEO Settings page.'; $lang->msg_blacklisted_reason['session_shield'] = 'The functionality that this addon used to provide is included by default in Rhymix.'; $lang->msg_blacklisted_reason['smartphone'] = 'This module was disabled in XE long before Rhymix even existed.'; @@ -104,13 +107,38 @@ $lang->auto_select_lang = 'Auto-select Language'; $lang->about_auto_select_lang = 'Automatically select the language based on the language of each visitor\'s browser.'; $lang->about_recompile_cache = 'Delete useless or invalid cache files?'; $lang->confirm_run = 'It may take a long time. Do you want to run?'; -$lang->use_ssl = 'Use SSL'; -$lang->ssl_options['none'] = 'Never'; +$lang->use_ssl = 'Use HTTPS'; +$lang->ssl_options['none'] = 'None'; $lang->ssl_options['optional'] = 'Optional (not recommended)'; $lang->ssl_options['always'] = 'Always (recommended)'; -$lang->about_use_ssl = '

Selecting \'Optional\' is to use SSL for the specified actions such as signing up and changing information.
Selecting \'Always\' is to use SSL for the entire pages, generated by Rhymix.

Please be careful! You may not be able to access to the site, before installing SSL certificate.

'; +$lang->cmd_http_port = 'HTTP Port'; +$lang->cmd_https_port = 'HTTPS Port'; +$lang->cmd_index_module_srl = 'Main Module'; +$lang->cmd_index_document_srl = 'Main Document'; +$lang->cmd_default_language = 'Default Language'; +$lang->cmd_new_domain = 'Add New Domain'; +$lang->cmd_edit_domain = 'Edit Domain'; +$lang->cmd_is_default_domain = 'Default Domain'; +$lang->cmd_multidomain_configuration = 'Multidomain Configuration'; +$lang->cmd_unregistered_domain_action = 'Unregistered Domains'; +$lang->cmd_unregistered_domain_redirect_301 = '301 Redirect to Default Domain (Recommended)'; +$lang->cmd_unregistered_domain_redirect_302 = '302 Redirect to Default Domain'; +$lang->cmd_unregistered_domain_display = 'Display Main Screen as Usual'; +$lang->cmd_unregistered_domain_block = '404 Not Found'; +$lang->cmd_delete_domain = 'Would you like to delete this domain?'; +$lang->about_use_ssl = 'Selecting \'Optional\' is to use SSL for the specified actions such as signing up and changing information.
Selecting \'Always\' is to use SSL for the entire pages, generated by Rhymix.
Please be careful! You may not be able to access to the site, before installing SSL certificate.'; $lang->server_ports = 'Server Port'; $lang->about_server_ports = 'If your web server does not use 80 for HTTP or 443 for HTTPS port, you should specify server ports.'; +$lang->msg_site_title_is_empty = 'Please enter a title for the domain.'; +$lang->msg_invalid_domain = 'Invalid domain.'; +$lang->msg_domain_already_exists = 'The domain already exists.'; +$lang->msg_invalid_http_port = 'Invalid HTTP port.'; +$lang->msg_invalid_https_port = 'Invalid HTTPS port.'; +$lang->msg_invalid_index_module_srl = 'The main module does not exist.'; +$lang->msg_invalid_index_document_srl = 'The main document number does not exist.'; +$lang->msg_invalid_index_document_srl_module_srl = 'The main module does not match the main document number.'; +$lang->msg_lang_is_not_enabled = 'The language you selected is not enabled in this site.'; +$lang->msg_invalid_timezone = 'The selected time zone is not usable on this server.'; $lang->use_db_session = 'Store Session in DB'; $lang->about_db_session = 'Store PHP sessions in the database. This setting must be turned on if you want to see current users or get detailed statistics.
Unnecessary use may decrease server performance.'; $lang->qmail_compatibility = 'Enable Qmail'; @@ -220,7 +248,7 @@ $lang->about_use_mobile_view = 'Show mobile page when visitors access with mobil $lang->tablets_as_mobile = 'Treat Tablets as Mobile'; $lang->thumbnail_type = 'Select thumbnail type.'; $lang->input_footer_script = 'Footer script'; -$lang->detail_input_footer_script = 'The script is inserted into the bottom of body. It does not work at admin page.'; +$lang->detail_input_footer_script = 'Any content added here will be printed at the bottom of the page, except the admin module.'; $lang->thumbnail_crop = 'Crop'; $lang->thumbnail_ratio = 'Keep aspect ratio (may result in spaces)'; $lang->thumbnail_none = 'Do not create thumbnails'; @@ -237,7 +265,7 @@ $lang->detail_use_mobile_icon = 'The mobile icon should be 57x57 or 114x114, onl $lang->cmd_site_default_image = 'Default Image'; $lang->about_site_default_image = 'This image will be shown when your site is linked to in various social networks. It should be 200x200, either jpg or png format.'; $lang->use_sso = 'Use SSO?'; -$lang->about_use_sso = 'If your site uses multiple domains, logging into one domain will automatically log the user into all domains.'; +$lang->about_use_sso = 'Logging into one domain will automatically log the user into all domains.'; $lang->about_arrange_session = 'Do you want to clean up session?'; $lang->cmd_clear_session = 'Clean up session'; $lang->save = 'Save'; diff --git a/modules/admin/lang/ko.php b/modules/admin/lang/ko.php index 61f307d44..4d15b47d9 100644 --- a/modules/admin/lang/ko.php +++ b/modules/admin/lang/ko.php @@ -1,7 +1,7 @@ admin = 'κ΄€λ¦¬μž'; $lang->cmd_configure = 'μ„€μ •ν•˜κΈ°'; -$lang->subtitle_primary = 'κΈ°λ³Έ μ„€μ •'; +$lang->subtitle_site_info = 'μ‚¬μ΄νŠΈ μ„€μ •'; $lang->subtitle_notification = 'μ•Œλ¦Ό μ„€μ •'; $lang->subtitle_security = 'λ³΄μ•ˆ μ„€μ •'; $lang->subtitle_advanced = 'κ³ κΈ‰ μ„€μ •'; @@ -70,7 +70,9 @@ $lang->msg_blacklisted_reason['autolang'] = '이 μ• λ“œμ˜¨μ—μ„œ μ œκ³΅ν•˜λ˜ $lang->msg_blacklisted_reason['auto_login'] = '이 λͺ¨λ“ˆμ—μ„œ μ œκ³΅ν•˜λ˜ κΈ°λŠ₯은 Rhymix에 ν¬ν•¨λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.'; $lang->msg_blacklisted_reason['errorlogger'] = '이 λͺ¨λ“ˆμ—μ„œ μ œκ³΅ν•˜λ˜ κΈ°λŠ₯은 디버그 μ„€μ • νŽ˜μ΄μ§€μ—μ„œ 관리할 수 μžˆμŠ΅λ‹ˆλ‹€.'; $lang->msg_blacklisted_reason['fix_mysql_utf8'] = '이 μ• λ“œμ˜¨μ—μ„œ μ œκ³΅ν•˜λ˜ κΈ°λŠ₯은 Rhymix에 ν¬ν•¨λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.'; +$lang->msg_blacklisted_reason['homepage'] = '이 λͺ¨λ“ˆμ—μ„œ μ œκ³΅ν•˜λ˜ κΈ°λŠ₯은 Rhymix에 ν¬ν•¨λœ 멀티도메인 κΈ°λŠ₯으둜 λŒ€μ²΄ν•˜μ—¬μ•Ό ν•©λ‹ˆλ‹€.'; $lang->msg_blacklisted_reason['member_communication'] = '이 μ• λ“œμ˜¨μ—μ„œ μ œκ³΅ν•˜λ˜ κΈ°λŠ₯은 μ•Œλ¦Όμ„Όν„° λͺ¨λ“ˆμ—μ„œ 관리할 수 μžˆμŠ΅λ‹ˆλ‹€.'; +$lang->msg_blacklisted_reason['multidomain'] = '이 λͺ¨λ“ˆμ—μ„œ μ œκ³΅ν•˜λ˜ κΈ°λŠ₯은 Rhymix에 ν¬ν•¨λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.'; $lang->msg_blacklisted_reason['seo'] = '이 λͺ¨λ“ˆμ—μ„œ μ œκ³΅ν•˜λ˜ κΈ°λŠ₯은 SEO μ„€μ • νŽ˜μ΄μ§€μ—μ„œ 관리할 수 μžˆμŠ΅λ‹ˆλ‹€.'; $lang->msg_blacklisted_reason['session_shield'] = '이 μ• λ“œμ˜¨μ—μ„œ μ œκ³΅ν•˜λ˜ κΈ°λŠ₯은 Rhymix에 ν¬ν•¨λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.'; $lang->msg_blacklisted_reason['smartphone'] = '이 λͺ¨λ“ˆμ€ XEμ—μ„œλ„ μ‚¬μš©λ˜μ§€ μ•Šκ³  μžˆμ—ˆμŠ΅λ‹ˆλ‹€.'; @@ -104,13 +106,40 @@ $lang->auto_select_lang = 'μ–Έμ–΄ μžλ™ 선택'; $lang->about_auto_select_lang = '방문자의 λΈŒλΌμš°μ € 언어에 따라 μžλ™μœΌλ‘œ μ–Έμ–΄λ₯Ό μ„ νƒν•˜λŠ” κΈ°λŠ₯μž…λ‹ˆλ‹€.'; $lang->about_recompile_cache = 'μ“Έλͺ¨ μ—†μ–΄μ‘Œκ±°λ‚˜ 잘λͺ»λœ μΊμ‹œνŒŒμΌλ“€μ„ μ§€μš°μ‹œκ² μŠ΅λ‹ˆκΉŒ?'; $lang->confirm_run = '였랜 μ‹œκ°„μ΄ 걸릴 수 μžˆμŠ΅λ‹ˆλ‹€. μ‹€ν–‰ν•˜μ‹œκ² μŠ΅λ‹ˆκΉŒ?'; -$lang->use_ssl = 'SSL μ‚¬μš©'; -$lang->ssl_options['none'] = 'μ‚¬μš©μ•ˆν•¨'; -$lang->ssl_options['optional'] = 'μ„ νƒμ μœΌλ‘œ (ꢌμž₯ν•˜μ§€ μ•ŠμŒ)'; +$lang->use_ssl = 'HTTPS μ‚¬μš©'; +$lang->ssl_options['none'] = 'μ‚¬μš©ν•˜μ§€ μ•ŠμŒ'; +$lang->ssl_options['optional'] = 'μ„ νƒμ μœΌλ‘œ μ‚¬μš© (ꢌμž₯ν•˜μ§€ μ•ŠμŒ)'; $lang->ssl_options['always'] = '항상 μ‚¬μš© (ꢌμž₯)'; -$lang->about_use_ssl = '

\'μ„ νƒμ μœΌλ‘œ\'λŠ” νšŒμ›κ°€μž…, μ •λ³΄μˆ˜μ • λ“±μ˜ 일뢀 λ™μž‘μ—μ„œλ§Œ μ„ νƒμ μœΌλ‘œ λ³΄μ•ˆμ ‘μ†(SSL)을 μ‚¬μš©ν•©λ‹ˆλ‹€.
\'항상 μ‚¬μš©\'은 λͺ¨λ“  μ„œλΉ„μŠ€μ— SSL을 μ‚¬μš© ν•©λ‹ˆλ‹€.

SSL ν™˜κ²½μ΄ κ°–μΆ°μ§€μ§€ μ•Šμ€ μƒνƒœμ—μ„œ SSL을 μ‚¬μš©ν•  경우, 접속이 λ˜μ§€ μ•Šμ„ 수 μžˆμŠ΅λ‹ˆλ‹€. SSL μΈμ¦μ„œκ°€ μ •μƒμ μœΌλ‘œ μ„€μΉ˜λ˜μ—ˆλŠ”μ§€ λ°˜λ“œμ‹œ ν™•μΈν•˜κ³  μ„€μ •ν•˜μ‹œκΈ° λ°”λžλ‹ˆλ‹€.

'; -$lang->server_ports = 'μ„œλ²„ 포트 μ§€μ •'; +$lang->cmd_http_port = 'HTTP 포트'; +$lang->cmd_https_port = 'HTTPS 포트'; +$lang->cmd_index_module_srl = '메인 λͺ¨λ“ˆ'; +$lang->cmd_index_document_srl = '메인 λ¬Έμ„œ'; +$lang->cmd_default_language = 'κΈ°λ³Έ μ–Έμ–΄'; +$lang->cmd_new_domain = 'μƒˆ 도메인 μΆ”κ°€'; +$lang->cmd_edit_domain = '도메인 정보 μˆ˜μ •'; +$lang->cmd_is_default_domain = 'κΈ°λ³Έ 도메인'; +$lang->cmd_multidomain_configuration = '멀티도메인 κΈ°λŠ₯ μ„€μ •'; +$lang->cmd_unregistered_domain_action = 'λ“±λ‘λ˜μ§€ μ•Šμ€ 도메인 처리'; +$lang->cmd_unregistered_domain_redirect_301 = 'κΈ°λ³Έ λ„λ©”μΈμœΌλ‘œ 301 Redirect (ꢌμž₯)'; +$lang->cmd_unregistered_domain_redirect_302 = 'κΈ°λ³Έ λ„λ©”μΈμœΌλ‘œ 302 Redirect'; +$lang->cmd_unregistered_domain_display = '메인 ν™”λ©΄ ν‘œμ‹œ'; +$lang->cmd_unregistered_domain_block = '404 Not Found 였λ₯˜ ν‘œμ‹œ'; +$lang->cmd_delete_domain = '이 도메인을 μ‚­μ œν•˜μ‹œκ² μŠ΅λ‹ˆκΉŒ?'; +$lang->about_use_ssl = '\'μ„ νƒμ μœΌλ‘œ μ‚¬μš©\'은 νšŒμ›κ°€μž…, μ •λ³΄μˆ˜μ • λ“±μ˜ μ§€μ •λœ λ™μž‘(action)μ—μ„œλ§Œ λ³΄μ•ˆμ ‘μ†(HTTPS)을 μ‚¬μš©ν•©λ‹ˆλ‹€.
\'항상 μ‚¬μš©\'은 μ‚¬μ΄νŠΈ 전체에 HTTPSλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.
SSL μΈμ¦μ„œκ°€ μ„€μΉ˜λ˜μ§€ μ•Šμ€ μƒνƒœμ—μ„œ HTTPS μ‚¬μš©μ„ μ‹œλ„ν•˜λ©΄ 접속이 λ˜μ§€ μ•Šμ„ 수 μžˆμœΌλ‹ˆ μ£Όμ˜ν•˜μ‹œκΈ° λ°”λžλ‹ˆλ‹€.'; +$lang->server_ports = '포트'; $lang->about_server_ports = 'HTTPλŠ” 80, HTTPSλŠ” 443 이 μ•„λ‹Œ, λ‹€λ₯Έ 포트λ₯Ό μ‚¬μš©ν•  κ²½μš°μ— 포트λ₯Ό μ§€μ •ν•΄ μ£Όμ–΄μ•Ό ν•©λ‹ˆλ‹€.'; +$lang->msg_domain_not_found = '도메인을 찾을 수 μ—†μŠ΅λ‹ˆλ‹€.'; +$lang->msg_cannot_delete_default_domain = 'κΈ°λ³Έ 도메인은 μ‚­μ œν•  수 μ—†μŠ΅λ‹ˆλ‹€.'; +$lang->msg_site_title_is_empty = 'μ‚¬μ΄νŠΈ 제λͺ©μ„ μž…λ ₯ν•΄ μ£Όμ‹­μ‹œμ˜€.'; +$lang->msg_invalid_domain = 'μ˜¬λ°”λ₯΄μ§€ μ•Šμ€ λ„λ©”μΈμž…λ‹ˆλ‹€.'; +$lang->msg_domain_already_exists = '이미 λ“±λ‘λœ λ„λ©”μΈμž…λ‹ˆλ‹€.'; +$lang->msg_invalid_http_port = 'μ˜¬λ°”λ₯΄μ§€ μ•Šμ€ HTTP ν¬νŠΈμž…λ‹ˆλ‹€.'; +$lang->msg_invalid_https_port = 'μ˜¬λ°”λ₯΄μ§€ μ•Šμ€ HTTPS ν¬νŠΈμž…λ‹ˆλ‹€.'; +$lang->msg_invalid_index_module_srl = 'μ„ νƒν•˜μ‹  메인 λͺ¨λ“ˆμ΄ μ‘΄μž¬ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.'; +$lang->msg_invalid_index_document_srl = 'μ„ νƒν•˜μ‹  메인 λ¬Έμ„œ λ²ˆν˜Έκ°€ μ‘΄μž¬ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.'; +$lang->msg_invalid_index_document_srl_module_srl = 'μ„ νƒν•˜μ‹  메인 λͺ¨λ“ˆκ³Ό 메인 λ¬Έμ„œ λ²ˆν˜Έκ°€ μΌμΉ˜ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.'; +$lang->msg_lang_is_not_enabled = 'μ„ νƒν•˜μ‹  μ–Έμ–΄κ°€ ν™œμ„±ν™”λ˜μ–΄ μžˆμ§€ μ•ŠμŠ΅λ‹ˆλ‹€.'; +$lang->msg_invalid_timezone = 'μ‚¬μš©ν•  수 μ—†λŠ” ν‘œμ€€ μ‹œκ°„λŒ€μž…λ‹ˆλ‹€.'; $lang->use_db_session = '인증 μ„Έμ…˜ DB μ‚¬μš©'; $lang->about_db_session = 'μ„Έμ…˜μ„ DB에 μ €μž₯ν•©λ‹ˆλ‹€. ν˜„μž¬ μ ‘μ†μžλ₯Ό νŒŒμ•…ν•˜λ €λ©΄ 이 κΈ°λŠ₯을 μΌœμ•Ό ν•©λ‹ˆλ‹€.
λΆˆν•„μš”ν•˜κ²Œ μ‚¬μš©ν•˜λ©΄ μ„œλ²„ μ„±λŠ₯에 μ•…μ˜ν–₯을 쀄 수 μžˆμœΌλ‹ˆ μ£Όμ˜ν•˜μ‹­μ‹œμ˜€.'; $lang->qmail_compatibility = '큐메일(Qmail) μ‚¬μš©'; @@ -215,7 +244,7 @@ $lang->about_use_mobile_view = 'λͺ¨λ°”일 기기둜 μ ‘μ†μ‹œ λͺ¨λ°”일 페이 $lang->tablets_as_mobile = 'νƒœλΈ”λ¦Ώλ„ λͺ¨λ°”일 μ·¨κΈ‰'; $lang->thumbnail_type = '썸넀일 생성 방식'; $lang->input_footer_script = 'ν•˜λ‹¨(footer) 슀크립트'; -$lang->detail_input_footer_script = 'μ΅œν•˜λ‹¨μ— μ½”λ“œλ₯Ό μ‚½μž…ν•©λ‹ˆλ‹€. κ΄€λ¦¬μž νŽ˜μ΄μ§€μ—μ„œλŠ” μˆ˜ν–‰λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.'; +$lang->detail_input_footer_script = 'μ΅œν•˜λ‹¨μ— μ½”λ“œλ₯Ό μ‚½μž…ν•©λ‹ˆλ‹€. κ΄€λ¦¬μž ν™”λ©΄μ—λŠ” μ μš©λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.'; $lang->thumbnail_crop = '크기에 λ§žμΆ”μ–΄ μž˜λΌλ‚΄κΈ°'; $lang->thumbnail_ratio = 'λΉ„μœ¨ μœ μ§€ (여백이 생길 수 있음)'; $lang->thumbnail_none = '썸넀일 μƒμ„±ν•˜μ§€ μ•ŠμŒ'; @@ -232,7 +261,7 @@ $lang->detail_use_mobile_icon = '57x57 λ˜λŠ” 114x114 크기의 png νŒŒμΌμ„ $lang->cmd_site_default_image = 'μ‚¬μ΄νŠΈ λŒ€ν‘œ 이미지'; $lang->about_site_default_image = 'SNS 등에 이 μ‚¬μ΄νŠΈκ°€ λ§ν¬λ˜μ—ˆμ„ λ•Œ ν‘œμ‹œλ˜λŠ” μ΄λ―Έμ§€μž…λ‹ˆλ‹€. 200x200 크기의 jpg λ˜λŠ” png νŒŒμΌμ„ ꢌμž₯ν•©λ‹ˆλ‹€.'; $lang->use_sso = 'SSO μ‚¬μš©'; -$lang->about_use_sso = 'μ—¬λŸ¬ 도메인을 μ‚¬μš©ν•˜λŠ” μ‚¬μ΄νŠΈμ—μ„œ ν•œ 번만 λ‘œκ·ΈμΈν•˜λ©΄ λͺ¨λ“  도메인에 λ‘œκ·ΈμΈλ˜λ„λ‘ ν•©λ‹ˆλ‹€.'; +$lang->about_use_sso = 'ν•œ 번만 λ‘œκ·ΈμΈν•˜λ©΄ λͺ¨λ“  도메인에 λ‘œκ·ΈμΈλ˜λ„λ‘ ν•©λ‹ˆλ‹€.'; $lang->about_arrange_session = 'μ„Έμ…˜μ„ μ •λ¦¬ν•˜μ‹œκ² μŠ΅λ‹ˆκΉŒ?'; $lang->cmd_clear_session = 'μ„Έμ…˜ 정리'; $lang->save = 'μ €μž₯'; diff --git a/modules/admin/tpl/config_advanced.html b/modules/admin/tpl/config_advanced.html index 8f9586926..62b5b58a3 100644 --- a/modules/admin/tpl/config_advanced.html +++ b/modules/admin/tpl/config_advanced.html @@ -7,28 +7,6 @@ -
- -
- -
-
-
- -
- - - -
{lang('admin.about_use_ssl')}
-
-
-
- -
- - -
-
@@ -36,6 +14,72 @@
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+ + +
+

{$lang->about_auto_select_lang}

+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
@@ -72,15 +116,6 @@

{$lang->about_use_session_ssl}

-
- -
- - -
-

{$lang->about_use_sso}

-
-
diff --git a/modules/admin/tpl/config_domains.html b/modules/admin/tpl/config_domains.html new file mode 100644 index 000000000..463746771 --- /dev/null +++ b/modules/admin/tpl/config_domains.html @@ -0,0 +1,124 @@ + +
+

{$XE_VALIDATOR_MESSAGE}

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
{$lang->site_title}{$lang->domain}{$lang->use_ssl}{$lang->cmd_index_module_srl}{$lang->cmd_index_document_srl}{$lang->cmd_modify} / {$lang->cmd_delete}
+ {$domain->settings->title} + {$lang->cmd_is_default_domain} + {$domain->domain}{preg_replace('/\\(.+$/', '', $lang->ssl_options[$domain->security ?: 'none'])} + + {($domain->index_module_srl && $module_list[$domain->index_module_srl]) ? $module_list[$domain->index_module_srl]->browser_title : ''} + + {$domain->index_document_srl ?: ''} + + + {$lang->cmd_modify} + / + + {$lang->cmd_delete} + + + {$lang->cmd_delete} + +
{$lang->msg_no_result}
+ +
+ +
+

{$lang->cmd_multidomain_configuration}

+
+ + + +
+ +
+ + + + +
+
+
+ +
+ + +
+

{$lang->about_use_sso}

+
+
+
+
+ +
+
+
+
+ + diff --git a/modules/admin/tpl/config_domains_edit.html b/modules/admin/tpl/config_domains_edit.html new file mode 100644 index 000000000..889025d49 --- /dev/null +++ b/modules/admin/tpl/config_domains_edit.html @@ -0,0 +1,154 @@ + +
+

{$XE_VALIDATOR_MESSAGE}

+
+
+
+ + + + + +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +   + +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
{lang('admin.about_use_ssl')}
+
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
{$lang->detail_input_footer_script}
+
+
+ +
+ +
+

+ Favicon + Favicon +

+ + + {$lang->about_use_favicon} +
+
+ +
+ +
+

+ Mobile Home Icon + Rhymix +

+ + + {$lang->detail_use_mobile_icon} +
+
+ +
+ +
+

+ Default Image +

+ + + {$lang->about_site_default_image} +
+
+ +
+
+ +
+
+ +
+
diff --git a/modules/admin/tpl/config_general.html b/modules/admin/tpl/config_general.html deleted file mode 100644 index c04f61ec5..000000000 --- a/modules/admin/tpl/config_general.html +++ /dev/null @@ -1,206 +0,0 @@ - -
-

{$XE_VALIDATOR_MESSAGE}

-
-
-
- - - -
-
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- - -
-

{$lang->about_auto_select_lang}

-
-
-
- -
- -
-
-
- -
- - -
-
-
- -
- - -
-
-
- -
-

- Favicon - Favicon -

- -
- - -

- - -

-
- {$lang->about_use_favicon} -
-
-
- -
-

- Mobile Home Icon - Rhymix -

- -
- - -

- - -

-
- {$lang->detail_use_mobile_icon} -
-
-
- -
-

- Default Image -

- -
- - -

- - -

-
- {$lang->about_site_default_image} -
-
-
-
- -
-
-
-
- - - - diff --git a/modules/admin/tpl/config_header.html b/modules/admin/tpl/config_header.html index 4fea11641..ee02b455c 100644 --- a/modules/admin/tpl/config_header.html +++ b/modules/admin/tpl/config_header.html @@ -4,7 +4,7 @@

{$lang->menu_gnb_sub['adminConfigurationGeneral']} {$lang->help}

    -
  • {$lang->subtitle_primary}
  • +
  • {$lang->subtitle_site_info}
  • {$lang->subtitle_notification}
  • {$lang->subtitle_security}
  • {$lang->subtitle_advanced}
  • diff --git a/modules/admin/tpl/css/admin.css b/modules/admin/tpl/css/admin.css index 77a34ef05..d27ecc967 100644 --- a/modules/admin/tpl/css/admin.css +++ b/modules/admin/tpl/css/admin.css @@ -434,7 +434,7 @@ margin-bottom: 10px; height: 25px; } .x input[type="number"] { - width: 50px; + width: 90px; } .x select { padding: 0; diff --git a/modules/install/script/ko.install.php b/modules/install/script/ko.install.php index d0ea28061..f591ed9a0 100644 --- a/modules/install/script/ko.install.php +++ b/modules/install/script/ko.install.php @@ -293,11 +293,10 @@ $output = $oModuleController->updateModule($module_info); if(!$output->toBool()) return $output; // insertFirstModule -$site_args = new stdClass(); -$site_args->site_srl = 0; -$site_args->index_module_srl = $module_srl; -$oModuleController->updateSite($site_args); - +$domain_args = new stdClass(); +$domain_args->domain_srl = 0; +$domain_args->index_module_srl = $module_srl; +executeQuery('module.updateDomain', $domain_args); // XEIcon page $moduleInfo = $oModuleModel->getModuleInfoByMenuItemSrl($sitemap['GNB']['list'][2]['menu_srl']); diff --git a/modules/module/module.class.php b/modules/module/module.class.php index 59425c718..543f015e2 100644 --- a/modules/module/module.class.php +++ b/modules/module/module.class.php @@ -17,32 +17,34 @@ class module extends ModuleObject $oDB = &DB::getInstance(); $oDB->addIndex("modules","idx_site_mid", array("site_srl","mid"), true); - $oDB->addIndex('sites','unique_domain',array('domain'),true); + + // Insert new domain + if(!getModel('module')->getDefaultDomainInfo()) + { + $current_url = Rhymix\Framework\Url::getCurrentUrl(); + $domain = new stdClass(); + $domain->domain_srl = 0; + $domain->domain = Rhymix\Framework\URL::getDomainFromURL($current_url); + $domain->is_default_domain = 'Y'; + $domain->index_module_srl = 0; + $domain->index_document_srl = 0; + $domain->http_port = null; + $domain->https_port = null; + $domain->security = config('url.ssl') ?: 'none'; + $domain->description = ''; + $domain->settings = json_encode(array('language' => null, 'timezone' => null)); + $output = executeQuery('module.insertDomain', $domain); + if (!$output->toBool()) + { + return $output; + } + } + // Create a directory to use in the module module FileHandler::makeDir('./files/cache/module_info'); FileHandler::makeDir('./files/cache/triggers'); FileHandler::makeDir('./files/ruleset'); - // Insert site information into the sites table - $args = new stdClass; - $args->site_srl = 0; - $output = $oDB->executeQuery('module.getSite', $args); - if(!$output->data || !$output->data->index_module_srl) - { - $domain = Context::getDefaultUrl(); - $url_info = parse_url($domain); - $domain = $url_info['host'].( (!empty($url_info['port'])&&$url_info['port']!=80)?':'.$url_info['port']:'').$url_info['path']; - - $site_args = new stdClass; - $site_args->site_srl = 0; - $site_args->index_module_srl = 0; - $site_args->domain = $domain; - $site_args->default_language = config('locale.default_lang'); - - $output = executeQuery('module.insertSite', $site_args); - if(!$output->toBool()) return $output; - } - return new Object(); } @@ -58,23 +60,13 @@ class module extends ModuleObject if(!$oDB->isIndexExists('modules',"idx_site_mid")) return true; // Move permissions/skin information of all modules to the table, grants. if($oDB->isColumnExists('modules', 'grants')) return true; - // Move permissions/skin information of all modules to the table, grants. - if(!$oDB->isColumnExists('sites', 'default_language')) return true; // Delete extra_vars* column for($i=1;$i<=20;$i++) { if($oDB->isColumnExists("documents","extra_vars".$i)) return true; } - // Insert site information to the table, sites - $args = new stdClass(); - $args->site_srl = 0; - $output = $oDB->executeQuery('module.getSite', $args); - if(!$output->data) return true; - - // If domain index is defined on the table, sites - if($oDB->isIndexExists('sites', 'idx_domain')) return true; - if(!$oDB->isIndexExists('sites','unique_domain')) return true; + // Check indexes if(!$oDB->isColumnExists("modules", "use_mobile")) return true; if(!$oDB->isColumnExists("modules", "mlayout_srl")) return true; if(!$oDB->isColumnExists("modules", "mcontent")) return true; @@ -87,6 +79,7 @@ class module extends ModuleObject if(!is_dir('./files/ruleset')) return true; + $args = new stdClass; $args->skin = '.'; $output = executeQueryArray('module.getModuleSkinDotList', $args); if($output->data && count($output->data) > 0) @@ -99,7 +92,11 @@ class module extends ModuleObject } } - // XE 1.7 + // Check domains + if (!$oDB->isTableExists('domains') || !getModel('module')->getDefaultDomainInfo()) + { + return true; + } // check fix mskin if(!$oDB->isColumnExists("modules", "is_mskin_fix")) return true; @@ -303,11 +300,7 @@ class module extends ModuleObject $oDB->dropColumn('modules','skin_vars'); $oDB->dropColumn('modules','extra_vars'); } - // Rights of all modules/skins transferring the information into a table Update grants - if(!$oDB->isColumnExists('sites', 'default_language')) - { - $oDB->addColumn('sites','default_language','varchar',255,0,false); - } + // extra_vars * Remove Column for($i=1;$i<=20;$i++) { @@ -315,35 +308,10 @@ class module extends ModuleObject $oDB->dropColumn('documents','extra_vars'.$i); } - // Enter the main site information sites on the table - $args = new stdClass; - $args->site_srl = 0; - $output = $oDB->executeQuery('module.getSite', $args); - if(!$output->data) + // Migrate domains + if (!getModel('module')->getDefaultDomainInfo()) { - // Basic mid, language Wanted - $mid_output = $oDB->executeQuery('module.getDefaultMidInfo', $args); - $domain = Context::getDefaultUrl(); - $url_info = parse_url($domain); - $domain = $url_info['host'].( (!empty($url_info['port'])&&$url_info['port']!=80)?':'.$url_info['port']:'').$url_info['path']; - $site_args = new stdClass(); - $site_args->site_srl = 0; - $site_args->index_module_srl = $mid_output->data->module_srl; - $site_args->domain = $domain; - $site_args->default_language = config('locale.default_lang'); - - $output = executeQuery('module.insertSite', $site_args); - if(!$output->toBool()) return $output; - } - - if($oDB->isIndexExists('sites','idx_domain')) - { - $oDB->dropIndex('sites','idx_domain'); - } - if(!$oDB->isIndexExists('sites','unique_domain')) - { - $this->updateForUniqueSiteDomain(); - $oDB->addIndex('sites','unique_domain',array('domain'),true); + $this->migrateDomains(); } if(!$oDB->isColumnExists("modules", "use_mobile")) @@ -414,32 +382,145 @@ class module extends ModuleObject return new Object(0, 'success_updated'); } - function updateForUniqueSiteDomain() + /** + * @brief Migrate old sites and multidomain info to new 'domains' table + */ + function migrateDomains() { - $output = executeQueryArray("module.getNonuniqueDomains"); - if(!$output->data) return; - foreach($output->data as $data) + // Create the domains table. + $oDB = DB::getInstance(); + if (!$oDB->isTableExists('domains')) { - if($data->count == 1) continue; - $domain = $data->domain; - $args = new stdClass; - $args->domain = $domain; - $output2 = executeQueryArray("module.getSiteByDomain", $args); - $bFirst = true; - foreach($output2->data as $site) + $oDB->createTableByXmlFile($this->module_path . 'schemas/domains.xml'); + } + + // Get current site configuration. + $oModuleModel = getModel('module'); + $config = $oModuleModel->getModuleConfig('module'); + + // Initialize domains data. + $domains = array(); + $default_domain = new stdClass; + + // Check XE sites. + $output = executeQueryArray('module.getSites'); + if ($output->data) + { + foreach ($output->data as $site_info) { - if($bFirst) + $site_domain = $site_info->domain; + if (!preg_match('@^https?://@', $site_domain)) { - $bFirst = false; - continue; + $site_domain = 'http://' . $site_domain; + } + + $domain = new stdClass(); + $domain->domain_srl = $site_info->site_srl; + $domain->domain = Rhymix\Framework\URL::getDomainFromURL(strtolower($site_domain)); + $domain->is_default_domain = $site_info->site_srl == 0 ? 'Y' : 'N'; + $domain->index_module_srl = $site_info->index_module_srl; + $domain->index_document_srl = 0; + $domain->http_port = config('url.http_port') ?: null; + $domain->https_port = config('url.https_port') ?: null; + $domain->security = config('url.ssl') ?: 'none'; + $domain->description = ''; + $domain->settings = json_encode(array( + 'title' => $config->siteTitle, + 'subtitle' => $config->siteSubtitle, + 'language' => $site_info->default_language, + 'timezone' => config('locale.default_timezone'), + 'html_footer' => $config->htmlFooter, + )); + $domain->regdate = $site_info->regdate; + $domains[$domain->domain] = $domain; + if ($domain->is_default_domain === 'Y') + { + $default_domain = $domain; } - $domain .= "_"; - $args = new stdClass; - $args->domain = $domain; - $args->site_srl = $site->site_srl; - $output3 = executeQuery("module.updateSite", $args); } } + else + { + $output = executeQuery('module.getDefaultMidInfo', $args); + $default_hostinfo = parse_url(Rhymix\Framework\URL::getCurrentURL()); + + $domain = new stdClass(); + $domain->domain_srl = 0; + $domain->domain = Rhymix\Framework\URL::decodeIdna(strtolower($default_hostinfo['host'])); + $domain->is_default_domain = 'Y'; + $domain->index_module_srl = $output->data ? $output->data->module_srl : 0; + $domain->index_document_srl = 0; + $domain->http_port = isset($default_hostinfo['port']) ? intval($default_hostinfo['port']) : null; + $domain->https_port = null; + $domain->security = config('url.ssl') ?: 'none'; + $domain->description = ''; + $domain->settings = json_encode(array( + 'title' => $config->siteTitle, + 'subtitle' => $config->siteSubtitle, + 'language' => $site_info->default_language, + 'timezone' => config('locale.default_timezone'), + 'html_footer' => $config->htmlFooter, + )); + $domains[$domain->domain] = $domain; + $default_domain = $domain; + } + + // Check multidomain module. + if (getModel('multidomain')) + { + $output = executeQueryArray('multidomain.getMultidomainList', (object)array('order_type' => 'asc', 'list_count' => 100000000)); + if ($output->data) + { + foreach ($output->data as $site_info) + { + $site_domain = $site_info->domain; + if (!preg_match('@^https?://@', $site_domain)) + { + $site_domain = 'http://' . $site_domain; + } + + $domain = new stdClass(); + $domain->domain_srl = $site_info->multidomain_srl; + $domain->domain = Rhymix\Framework\URL::getDomainFromURL(strtolower($site_domain)); + $domain->is_default_domain = isset($domains[$domain->domain]) ? $domains[$domain->domain]->is_default_domain : 'N'; + $domain->index_module_srl = intval($site_info->module_srl); + $domain->index_document_srl = intval($site_info->document_srl); + $domain->http_port = config('url.http_port') ?: null; + $domain->https_port = config('url.https_port') ?: null; + $domain->security = config('url.ssl') ?: 'none'; + $domain->description = ''; + $domain->settings = json_encode(array( + 'title' => $config->siteTitle, + 'subtitle' => $config->siteSubtitle, + 'language' => $site_info->default_language, + 'timezone' => config('locale.default_timezone'), + 'html_footer' => $config->htmlFooter, + )); + $domain->regdate = $site_info->regdate; + $domains[$domain->domain] = $domain; + if ($domain->is_default_domain === 'Y') + { + $default_domain = $domain; + } + } + } + } + + // Insert into DB. + foreach ($domains as $domain) + { + $output = executeQuery('module.insertDomain', $domain); + if (!$output->toBool()) + { + return $output; + } + } + + // Clear cache. + Rhymix\Framework\Cache::clearGroup('site_and_module'); + + // Return the default domain info. + return $default_domain; } /** diff --git a/modules/module/module.controller.php b/modules/module/module.controller.php index f5568f294..279410ebd 100644 --- a/modules/module/module.controller.php +++ b/modules/module/module.controller.php @@ -784,53 +784,6 @@ class moduleController extends module return $output; } - /** - * @brief Change the site administrator - */ - function insertSiteAdmin($site_srl, $arr_admins) - { - // Remove the site administrator - $args = new stdClass; - $args->site_srl = $site_srl; - - $output = executeQuery('module.deleteSiteAdmin', $args); - - if(!$output->toBool()) return $output; - // Get user id of an administrator - if(!is_array($arr_admins) || !count($arr_admins)) return new Object(); - foreach($arr_admins as $key => $user_id) - { - if(!trim($user_id)) continue; - $admins[] = trim($user_id); - } - if(!count($admins)) return new Object(); - - $oMemberModel = getModel('member'); - $member_config = $oMemberModel->getMemberConfig(); - if($member_config->identifier == 'email_address') - { - $args->email_address = '\''.implode('\',\'',$admins).'\''; - } - else - { - $args->user_ids = '\''.implode('\',\'',$admins).'\''; - } - $output = executeQueryArray('module.getAdminSrls', $args); - if(!$output->toBool()||!$output->data) return $output; - - foreach($output->data as $key => $val) - { - unset($args); - $args = new stdClass; - $args->site_srl = $site_srl; - $args->member_srl = $val->member_srl; - $output = executeQueryArray('module.insertSiteAdmin', $args); - if(!$output->toBool()) return $output; - } - Rhymix\Framework\Cache::delete("site_and_module:site_admins:$site_srl"); - return new Object(); - } - /** * @brief Specify the admin ID to a module */ @@ -1087,18 +1040,11 @@ class moduleController extends module if(is_null($lang)) { - $site_module_info = Context::get('site_module_info'); - if(!$site_module_info) - { - $oModuleModel = getModel('module'); - $site_module_info = $oModuleModel->getDefaultMid(); - Context::set('site_module_info', $site_module_info); - } - $cache_file = sprintf('%sfiles/cache/lang_defined/%d.%s.php', _XE_PATH_, $site_module_info->site_srl, Context::getLangType()); + $cache_file = sprintf('%sfiles/cache/lang_defined/%d.%s.php', _XE_PATH_, 0, Context::getLangType()); if(!file_exists($cache_file)) { $oModuleAdminController = getAdminController('module'); - $oModuleAdminController->makeCacheDefinedLangCode($site_module_info->site_srl); + $oModuleAdminController->makeCacheDefinedLangCode(0); } if(file_exists($cache_file)) @@ -1108,7 +1054,7 @@ class moduleController extends module if($cacheFileMtime < $moduleAdminControllerMtime) { $oModuleAdminController = getAdminController('module'); - $oModuleAdminController->makeCacheDefinedLangCode($site_module_info->site_srl); + $oModuleAdminController->makeCacheDefinedLangCode(0); } require_once($cache_file); diff --git a/modules/module/module.model.php b/modules/module/module.model.php index 4d0c427de..06dc31590 100644 --- a/modules/module/module.model.php +++ b/modules/module/module.model.php @@ -44,24 +44,120 @@ class moduleModel extends module return false; } - + /** - * @brief Get site information + * @brief Get all domains */ - function getSiteInfo($site_srl, $columnList = array()) + function getAllDomains($count = 20, $page = 1) { - $args = new stdClass(); - $args->site_srl = $site_srl; - $output = executeQuery('module.getSiteInfo', $args, $columnList); - return $output->data; + $args = new stdClass; + $args->list_count = $count; + $args->page = $page; + $output = executeQueryArray('module.getDomains', $args); + foreach ($output->data as &$domain) + { + $domain->settings = $domain->settings ? json_decode($domain->settings) : new stdClass; + } + return $output; } - function getSiteInfoByDomain($domain, $columnList = array()) + /** + * @brief Get default domain information + */ + function getDefaultDomainInfo() { - $args = new stdClass(); - $args->domain = $domain; - $output = executeQuery('module.getSiteInfoByDomain', $args, $columnList); - return $output->data; + $domain_info = Rhymix\Framework\Cache::get('site_and_module:domain_info:default'); + if ($domain_info === null) + { + $args = new stdClass(); + $args->is_default_domain = 'Y'; + $output = executeQuery('module.getDomainInfo', $args); + if ($output->data) + { + $domain_info = $output->data; + $domain_info->site_srl = 0; + $domain_info->settings = $domain_info->settings ? json_decode($domain_info->settings) : new stdClass; + $domain_info->default_language = $domain_info->settings->language ?: config('locale.default_lang'); + } + else + { + $domain_info = false; + } + Rhymix\Framework\Cache::set('site_and_module:domain_info:default', $domain_info, 0, true); + } + + return $domain_info; + } + + /** + * @brief Get site information by domain_srl + */ + function getSiteInfo($domain_srl) + { + $domain_srl = intval($domain_srl); + $domain_info = Rhymix\Framework\Cache::get('site_and_module:domain_info:srl:' . $domain_srl); + if ($domain_info === null) + { + $args = new stdClass(); + $args->domain_srl = $domain_srl; + $output = executeQuery('module.getDomainInfo', $args); + if ($output->data) + { + $domain_info = $output->data; + $domain_info->site_srl = 0; + $domain_info->settings = $domain_info->settings ? json_decode($domain_info->settings) : new stdClass; + $domain_info->default_language = $domain_info->settings->language ?: config('locale.default_lang'); + } + else + { + $domain_info = false; + } + Rhymix\Framework\Cache::set('site_and_module:domain_info:srl:' . $domain_srl, $domain_info, 0, true); + } + + return $domain_info; + } + + /** + * @brief Get site information by domain name + */ + function getSiteInfoByDomain($domain) + { + if (strpos($domain, '/') !== false) + { + $domain = Rhymix\Framework\URL::getDomainFromURL($domain); + if ($domain === false) + { + return false; + } + } + if (strpos($domain, 'xn--') !== false) + { + $domain = Rhymix\Framework\URL::decodeIdna($domain); + } + + $domain = strtolower($domain); + $domain_info = Rhymix\Framework\Cache::get('site_and_module:domain_info:domain:' . $domain); + if ($domain_info === null) + { + $args = new stdClass(); + $args->domain = $domain; + $output = executeQuery('module.getDomainInfo', $args); + if ($output->data) + { + $domain_info = $output->data; + $domain_info->site_srl = 0; + $domain_info->settings = $domain_info->settings ? json_decode($domain_info->settings) : new stdClass; + $domain_info->default_language = $domain_info->settings->language ?: config('locale.default_lang'); + } + else + { + $domain_info = false; + } + Rhymix\Framework\Cache::set('site_and_module:domain_info:domain:' . $domain, $domain_info, 0, true); + } + + return $domain_info; } /** @@ -82,108 +178,30 @@ class moduleModel extends module */ function getDefaultMid() { - $default_url = Context::getDefaultUrl(); - if($default_url && substr_compare($default_url, '/', -1) === 0) $default_url = substr($default_url, 0, -1); - - $request_url = Context::getRequestUri(); - if($request_url && substr_compare($request_url, '/', -1) === 0) $request_url = substr($request_url, 0, -1); - - $default_url_parse = parse_url($default_url); - $request_url_parse = parse_url($request_url); - $vid = Context::get('vid'); - $mid = Context::get('mid'); - - // Set up - $domain = ''; - $site_info = NULL; - if($default_url && $default_url_parse['host'] != $request_url_parse['host']) + // Get current domain. + $domain = strtolower(preg_replace('/:\d+$/', '', $_SERVER['HTTP_HOST'])); + + // Find the domain information. + $domain_info = $this->getSiteInfoByDomain($domain); + if (!$domain_info) { - $url_info = parse_url($request_url); - $hostname = $url_info['host']; - $path = $url_info['path']; - if(strlen($path) >= 1 && substr_compare($path, '/', -1) === 0) $path = substr($path, 0, -1); - - $domain = sprintf('%s%s%s', $hostname, $url_info['port']&&$url_info['port']!=80?':'.$url_info['port']:'',$path); + $domain_info = $this->getDefaultDomainInfo(); + if (!$domain_info) + { + $domain_info = $this->migrateDomains(); + } + $domain_info->is_default_replaced = true; } - - if($domain === '') + + // Fill in module extra vars and return. + if ($domain_info->module_srl) { - if(!$vid) $vid = $mid; - if($vid) - { - $domain = $vid; - } + return $this->addModuleExtraVars($domain_info); } - - // If domain is set, look for subsite - if($domain !== '') + else { - $site_info = Rhymix\Framework\Cache::get('site_and_module:site_info:' . md5($domain)); - if($site_info === null) - { - $args = new stdClass(); - $args->domain = $domain; - $output = executeQuery('module.getSiteInfoByDomain', $args); - $site_info = $output->data; - Rhymix\Framework\Cache::set('site_and_module:site_info:' . md5($domain), $site_info, 0, true); - } - - if($site_info && $vid) - { - Context::set('vid', $site_info->domain, true); - if(strtolower($mid)==strtolower($site_info->domain)) Context::set('mid', $site_info->mid,true); - } - if(!$site_info || !$site_info->domain) { $domain = ''; unset($site_info); } + return $domain_info; } - - // If no virtual website was found, get default website - if($domain === '') - { - $site_info = Rhymix\Framework\Cache::get('site_and_module:default_site'); - if($site_info === null) - { - $args = new stdClass(); - $args->site_srl = 0; - $output = executeQuery('module.getSiteInfo', $args); - // Update the related informaion if there is no default site info - if(!$output->data) - { - // Create a table if sites table doesn't exist - $oDB = &DB::getInstance(); - if(!$oDB->isTableExists('sites')) $oDB->createTableByXmlFile(_XE_PATH_.'modules/module/schemas/sites.xml'); - if(!$oDB->isTableExists('sites')) return; - - // Get mid, language - $mid_output = $oDB->executeQuery('module.getDefaultMidInfo', $args); - $domain = Context::getDefaultUrl(); - $url_info = parse_url($domain); - $domain = $url_info['host'].( (!empty($url_info['port'])&&$url_info['port']!=80)?':'.$url_info['port']:'').$url_info['path']; - - $site_args = new stdClass; - $site_args->site_srl = 0; - $site_args->index_module_srl = $mid_output->data->module_srl; - $site_args->domain = $domain; - $site_args->default_language = config('locale.default_lang'); - - if($output->data && !$output->data->index_module_srl) - { - $output = executeQuery('module.updateSite', $site_args); - } - else - { - $output = executeQuery('module.insertSite', $site_args); - if(!$output->toBool()) return $output; - } - $output = executeQuery('module.getSiteInfo', $args); - } - $site_info = $output->data; - Rhymix\Framework\Cache::set('site_and_module:default_site', $site_info, 0, true); - } - } - - if(!$site_info->module_srl) return $site_info; - if(is_array($site_info) && $site_info->data[0]) $site_info = $site_info[0]; - return $this->addModuleExtraVars($site_info); } /** @@ -1596,36 +1614,14 @@ class moduleModel extends module */ function isSiteAdmin($member_info, $site_srl = null) { - if (!$member_info || !$member_info->member_srl) - { - return false; - } - if ($member_info->is_admin == 'Y') + if ($member_info && $member_info->is_admin == 'Y') { return true; } - if ($site_srl === null) + else { - $site_module_info = Context::get('site_module_info'); - if(!$site_module_info) return false; - $site_srl = $site_module_info->site_srl; + return false; } - - $site_srl = $site_srl ?: 0; - $site_admins = Rhymix\Framework\Cache::get("site_and_module:site_admins:$site_srl"); - if ($site_admins === null) - { - $args = new stdClass; - $args->site_srl = $site_srl; - $output = executeQueryArray('module.isSiteAdmin', $args); - $site_admins = array(); - foreach ($output->data as $site_admin) - { - $site_admins[$site_admin->member_srl] = true; - } - Rhymix\Framework\Cache::set("site_and_module:site_admins:$site_srl", $site_admins, 0, true); - } - return isset($site_admins[$member_info->member_srl]); } /** @@ -1633,10 +1629,7 @@ class moduleModel extends module */ function getSiteAdmin($site_srl) { - $args = new stdClass; - $args->site_srl = $site_srl; - $output = executeQueryArray('module.getSiteAdmin', $args); - return $output->data; + return array(); } /** @@ -1940,19 +1933,13 @@ class moduleModel extends module if(!$module_srl) { $grant->access = true; - if($this->isSiteAdmin($member_info, $module_info->site_srl)) - { - $grant->access = $grant->manager = $grant->is_site_admin = true; - } - - $grant->is_admin = $grant->manager = ($member_info->is_admin == 'Y') ? true : false; + $grant->is_admin = $grant->manager = $grant->is_site_admin = ($member_info->is_admin == 'Y') ? true : false; } else { // If module_srl exists // Get a type of granted permission - $grant->access = $grant->manager = $grant->is_site_admin = ($member_info->is_admin=='Y'||$this->isSiteAdmin($member_info, $module_info->site_srl))?true:false; - $grant->is_admin = ($member_info->is_admin == 'Y') ? true : false; + $grant->access = $grant->is_admin = $grant->manager = $grant->is_site_admin = ($member_info->is_admin == 'Y') ? true : false; // If a just logged-in member is, check if the member is a module administrator if (!$grant->manager && $member_info->member_srl && $this->isModuleAdmin($member_info, $module_srl)) diff --git a/modules/module/queries/deleteDomain.xml b/modules/module/queries/deleteDomain.xml new file mode 100644 index 000000000..85b47b290 --- /dev/null +++ b/modules/module/queries/deleteDomain.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/modules/module/queries/getDomainInfo.xml b/modules/module/queries/getDomainInfo.xml new file mode 100644 index 000000000..7ee7aba4a --- /dev/null +++ b/modules/module/queries/getDomainInfo.xml @@ -0,0 +1,16 @@ + + +
    +
    + + + + + + + + + + + + diff --git a/modules/module/queries/getDomains.xml b/modules/module/queries/getDomains.xml new file mode 100644 index 000000000..f7a56b65f --- /dev/null +++ b/modules/module/queries/getDomains.xml @@ -0,0 +1,14 @@ + + +
    + + + + + + + + + + + diff --git a/modules/module/queries/getSites.xml b/modules/module/queries/getSites.xml new file mode 100644 index 000000000..788cb1e9e --- /dev/null +++ b/modules/module/queries/getSites.xml @@ -0,0 +1,11 @@ + + +
    + + + + + + + + diff --git a/modules/module/queries/insertDomain.xml b/modules/module/queries/insertDomain.xml new file mode 100644 index 000000000..e42c04291 --- /dev/null +++ b/modules/module/queries/insertDomain.xml @@ -0,0 +1,21 @@ + + +
    + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/modules/module/queries/updateDefaultDomain.xml b/modules/module/queries/updateDefaultDomain.xml new file mode 100644 index 000000000..0b814dee1 --- /dev/null +++ b/modules/module/queries/updateDefaultDomain.xml @@ -0,0 +1,12 @@ + + +
    + + + + + + + + + \ No newline at end of file diff --git a/modules/module/queries/updateDomain.xml b/modules/module/queries/updateDomain.xml new file mode 100644 index 000000000..7861c84ba --- /dev/null +++ b/modules/module/queries/updateDomain.xml @@ -0,0 +1,23 @@ + + +
    + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/modules/module/schemas/domains.xml b/modules/module/schemas/domains.xml new file mode 100644 index 000000000..eb488c96a --- /dev/null +++ b/modules/module/schemas/domains.xml @@ -0,0 +1,16 @@ +
    + + + + + + + + + + + + + + +
    \ No newline at end of file diff --git a/tests/unit/framework/SessionTest.php b/tests/unit/framework/SessionTest.php index 2f6b34f1f..e263ef4ab 100644 --- a/tests/unit/framework/SessionTest.php +++ b/tests/unit/framework/SessionTest.php @@ -134,7 +134,7 @@ class SessionTest extends \Codeception\TestCase\Test public function testCheckSSO() { - $this->assertFalse(Rhymix\Framework\Session::checkSSO()); + $this->assertNull(Rhymix\Framework\Session::checkSSO(new stdClass)); } public function testRefresh()