Merge pull request #728 from kijin/pr/multidomain

코어에서 멀티도메인 지원
This commit is contained in:
Kijin Sung 2017-03-13 15:46:34 +09:00 committed by GitHub
commit 08eb9779a5
41 changed files with 1444 additions and 1060 deletions

View file

@ -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]

View file

@ -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;
}
/**

View file

@ -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)

View file

@ -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);
}
}
}

View file

@ -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,

View file

@ -44,6 +44,7 @@ return array(
),
'url' => array(
'default' => null,
'unregistered_domain_action' => 'redirect_301',
'http_port' => null,
'https_port' => null,
'ssl' => 'none',

View file

@ -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;

View file

@ -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);

View file

@ -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;
}
/**

View file

@ -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')

View file

@ -98,7 +98,7 @@ class URL
return true;
}
if ($domain === self::getDomainFromURL(\Context::getDefaultUrl()))
if (getModel('module')->getSiteInfoByDomain($domain))
{
return true;
}

View file

@ -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();
}
/**

View file

@ -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;

View file

@ -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;

View file

@ -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;
</script>
</head>

View file

@ -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();

View file

@ -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,
));

View file

@ -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
{

View file

@ -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

View file

@ -11,6 +11,7 @@
<action name="dispAdminConfigDebug" type="view" menu_name="adminConfigurationGeneral" />
<action name="dispAdminConfigSEO" type="view" menu_name="adminConfigurationGeneral" />
<action name="dispAdminConfigSitelock" type="view" menu_name="adminConfigurationGeneral" />
<action name="dispAdminInsertDomain" type="view" menu_name="adminConfigurationGeneral" />
<action name="dispAdminConfigFtp" type="view" menu_name="adminConfigurationFtp" menu_index="true" />
<action name="dispAdminSetup" type="view" menu_name="adminMenuSetup" menu_index="true" />
<action name="dispAdminViewServerEnv" type="view" />
@ -24,13 +25,15 @@
<action name="procAdminUpdateConfig" type="controller" />
<action name="procAdminDeleteLogo" type="controller" />
<action name="procAdminMenuReset" type="controller" />
<action name="procAdminUpdateConfigGeneral" type="controller" />
<action name="procAdminUpdateDomains" type="controller" />
<action name="procAdminUpdateNotification" type="controller" />
<action name="procAdminUpdateSecurity" type="controller" />
<action name="procAdminUpdateAdvanced" type="controller" />
<action name="procAdminUpdateDebug" type="controller" />
<action name="procAdminUpdateSEO" type="controller" />
<action name="procAdminUpdateSitelock" type="controller" />
<action name="procAdminInsertDomain" type="controller" />
<action name="procAdminDeleteDomain" type="controller" />
<action name="procAdminUpdateFTPInfo" type="controller" />
<action name="procAdminRemoveFTPInfo" type="controller" />
<action name="procAdminFaviconUpload" type="controller" />

View file

@ -1,11 +1,12 @@
<?php
$lang->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 <a href="./index.php?module=admin&act=dispAdminConfigDebug">Debug Settings</a> 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 <a href="./index.php?module=admin&act=dispAdminConfigSEO">SEO Settings</a> 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 <abbr title="Secure Sockets Layer">SSL</abbr>';
$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 = '<p>Selecting \'Optional\' is to use SSL for the specified actions such as signing up and changing information.<br />Selecting \'Always\' is to use SSL for the entire pages, generated by Rhymix.</p><p>Please be careful! You may not be able to access to the site, before installing SSL certificate.</p>';
$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.<br />Selecting \'Always\' is to use SSL for the entire pages, generated by Rhymix.<br>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.<br>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 <abbr title="Single Sign On">SSO</abbr>?';
$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';

View file

@ -1,7 +1,7 @@
<?php
$lang->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'] = '이 모듈에서 제공하던 기능은 <a href="./index.php?module=admin&act=dispAdminConfigDebug">디버그 설정</a> 페이지에서 관리할 수 있습니다.';
$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'] = '이 모듈에서 제공하던 기능은 <a href="./index.php?module=admin&act=dispAdminConfigSEO">SEO 설정</a> 페이지에서 관리할 수 있습니다.';
$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 = '<abbr title="Secure Sockets Layer">SSL</abbr> 사용';
$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 = '<p>\'선택적으로\'는 회원가입, 정보수정 등의 일부 동작에서만 선택적으로 보안접속(SSL)을 사용합니다.<br />\'항상 사용\'은 모든 서비스에 SSL을 사용 합니다.</p><p>SSL 환경이 갖춰지지 않은 상태에서 SSL을 사용할 경우, 접속이 되지 않을 수 있습니다. SSL 인증서가 정상적으로 설치되었는지 반드시 확인하고 설정하시기 바랍니다.</p>';
$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)을 사용합니다.<br>\'항상 사용\'은 사이트 전체에 HTTPS를 사용합니다.<br>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에 저장합니다. 현재 접속자를 파악하려면 이 기능을 켜야 합니다.<br>불필요하게 사용하면 서버 성능에 악영향을 줄 수 있으니 주의하십시오.';
$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 = '<abbr title="Single Sign On">SSO</abbr> 사용';
$lang->about_use_sso = '여러 도메인을 사용하는 사이트에서 한 번만 로그인하면 모든 도메인에 로그인되도록 합니다.';
$lang->about_use_sso = '한 번만 로그인하면 모든 도메인에 로그인되도록 합니다.';
$lang->about_arrange_session = '세션을 정리하시겠습니까?';
$lang->cmd_clear_session = '세션 정리';
$lang->save = '저장';

View file

@ -7,28 +7,6 @@
<input type="hidden" name="module" value="admin" />
<input type="hidden" name="act" value="procAdminUpdateAdvanced" />
<input type="hidden" name="xe_validator_id" value="modules/admin/tpl/config_advanced/1" />
<div class="x_control-group">
<label class="x_control-label" for="default_url">{$lang->default_url} <a class="x_icon-question-sign" href="./common/manual/admin/index.html#UMAN_config_general_default_url" target="_blank">{$lang->help}</a></label>
<div class="x_controls">
<input type="url" name="default_url" id="default_url" style="min-width:90%" value="{$default_url}"/>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{lang('admin.use_ssl')} <a class="x_icon-question-sign" href="./common/manual/admin/index.html#UMAN_config_general_ssl" target="_blank">{$lang->help}</a></label>
<div class="x_controls">
<!--@foreach($lang->ssl_options as $key => $val)-->
<label for="ssl_{$key}" class="x_inline"><input type="radio" name="use_ssl" id="ssl_{$key}" value="{$key}" checked="checked"|cond="$use_ssl==$key" /> {$val}</label>
<!--@endforeach-->
<div class="x_help-block">{lang('admin.about_use_ssl')}</div>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->server_ports}</label>
<div class="x_controls">
<label for="http_port" class="x_inline" style="margin-bottom:0;padding-top:0">HTTP: <input type="number" name="http_port" id="http_port" size="5" value="{$http_port}" /></label>
<label for="https_port" class="x_inline" style="margin-bottom:0;padding-top:0">HTTPS: <input type="number" name="https_port" id="https_port" size="5" value="{$https_port}" /></label>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->use_rewrite}</label>
<div class="x_controls">
@ -36,6 +14,72 @@
<label for="use_rewrite_n" class="x_inline"><input type="radio" name="use_rewrite" id="use_rewrite_n" value="N" checked="checked"|cond="!$use_rewrite" /> {$lang->cmd_no}</label>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->use_mobile_view}</label>
<div class="x_controls">
<label for="use_mobile_view_y" class="x_inline">
<input type="radio" name="use_mobile_view" id="use_mobile_view_y" value="Y" checked="checked"|cond="$use_mobile_view" />
{$lang->cmd_yes}
</label>
<label for="use_mobile_view_n" class="x_inline">
<input type="radio" name="use_mobile_view" id="use_mobile_view_n" value="N" checked="checked"|cond="!$use_mobile_view" />
{$lang->cmd_no}
</label>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->tablets_as_mobile}</label>
<div class="x_controls">
<label for="tablets_as_mobile_y" class="x_inline">
<input type="radio" name="tablets_as_mobile" id="tablets_as_mobile_y" value="Y" checked="checked"|cond="$tablets_as_mobile" />
{$lang->cmd_yes}
</label>
<label for="tablets_as_mobile_n" class="x_inline">
<input type="radio" name="tablets_as_mobile" id="tablets_as_mobile_n" value="N" checked="checked"|cond="!$tablets_as_mobile" />
{$lang->cmd_no}
</label>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->auto_select_lang}</label>
<div class="x_controls">
<label for="auto_select_lang_y" class="x_inline">
<input type="radio" name="auto_select_lang" id="auto_select_lang_y" value="Y" checked="checked"|cond="$auto_select_lang" />
{$lang->cmd_yes}
</label>
<label for="auto_select_lang_n" class="x_inline">
<input type="radio" name="auto_select_lang" id="auto_select_lang_n" value="N" checked="checked"|cond="!$auto_select_lang" />
{$lang->cmd_no}
</label>
<br />
<p class="x_help-block">{$lang->about_auto_select_lang}</p>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->lang_select}</label>
<div class="x_controls">
<label for="lang_{$key}" class="x_inline" loop="$supported_lang=>$key,$val">
<input type="checkbox" name="enabled_lang[]" id="lang_{$key}" value="{$key}" disabled="disabled"|cond="$key==$default_lang" checked="checked"|cond="in_array($key, $enabled_lang)" />
{$val['name']}
</label>
</div>
</div>
<div class="x_control-group">
<label for="default_lang" class="x_control-label">{$lang->default_lang}</label>
<div class="x_controls">
<select name="default_lang" id="default_lang">
<option value="{$key}" loop="$enabled_lang=>$key" selected="selected"|cond="$key==$default_lang">{$supported_lang[$key]['name']}</option>
</select>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label" for="default_timezone">{$lang->timezone}</label>
<div class="x_controls">
<select name="default_timezone">
<option loop="$timezones => $key,$val" value="{$key}" selected="selected"|cond="$key==$selected_timezone">{$val}</option>
</select>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->use_db_session}</label>
<div class="x_controls">
@ -72,15 +116,6 @@
<p class="x_help-block">{$lang->about_use_session_ssl}</p>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->use_sso}</label>
<div class="x_controls">
<label for="use_sso_y" class="x_inline"><input type="radio" name="use_sso" id="use_sso_y" value="Y" checked="checked"|cond="$use_sso" /> {$lang->cmd_yes}</label>
<label for="use_sso_n" class="x_inline"><input type="radio" name="use_sso" id="use_sso_n" value="N" checked="checked"|cond="!$use_sso" /> {$lang->cmd_no}</label>
<br />
<p class="x_help-block">{$lang->about_use_sso}</p>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->thumbnail_type}</label>
<div class="x_controls">

View file

@ -0,0 +1,124 @@
<include target="config_header.html" />
<div cond="$XE_VALIDATOR_MESSAGE && $XE_VALIDATOR_ID == 'modules/admin/tpl/config_domains/1'" class="message {$XE_VALIDATOR_MESSAGE_TYPE}">
<p>{$XE_VALIDATOR_MESSAGE}</p>
</div>
<section class="section">
<table id="domain_list" class="x_table x_table-striped x_table-hover">
<thead>
<tr>
<th scope="col" class="nowr">{$lang->site_title}</th>
<th scope="col" class="nowr">{$lang->domain}</th>
<th scope="col" class="nowr">{$lang->use_ssl}</th>
<th scope="col" class="nowr">{$lang->cmd_index_module_srl}</th>
<th scope="col" class="nowr">{$lang->cmd_index_document_srl}</th>
<th scope="col" class="nowr">{$lang->cmd_modify} / {$lang->cmd_delete}</th>
</tr>
</thead>
<tbody>
<tr loop="$domain_list->data => $domain">
<td class="nowr">
{$domain->settings->title}
<i cond="$domain->is_default_domain === 'Y'" class="x_icon-home" title="{$lang->cmd_is_default_domain}">{$lang->cmd_is_default_domain}</i>
</td>
<td class="nowr">{$domain->domain}</td>
<td class="nowr">{preg_replace('/\\(.+$/', '', $lang->ssl_options[$domain->security ?: 'none'])}</td>
<td class="nowr">
<a href="{getSiteUrl($domain->domain, '', 'mid', $module_list[$domain->index_module_srl]->mid)}" cond="$domain->index_module_srl && $module_list[$domain->index_module_srl]" target="_blank">
{($domain->index_module_srl && $module_list[$domain->index_module_srl]) ? $module_list[$domain->index_module_srl]->browser_title : ''}</td>
</a>
<td class="nowr">
<a href="{getSiteUrl($domain->domain, '', 'mid', $module_list[$domain->index_module_srl]->mid, 'document_srl', $domain->index_document_srl)}" cond="$domain->index_document_srl" target="_blank">
{$domain->index_document_srl ?: ''}
</a>
</td>
<td class="nowr">
<a href="{getUrl('', 'module', 'admin', 'act', 'dispAdminInsertDomain', 'domain_srl', $domain->domain_srl)}">{$lang->cmd_modify}</a>
/
<block cond="$domain->is_default_domain !== 'Y'">
<a href="#" data-domain="{$domain->domain}" data-domain-srl="{$domain->domain_srl}" class="delete_domain">{$lang->cmd_delete}</a>
</block>
<block cond="$domain->is_default_domain === 'Y'">
<span style="color:#aaa">{$lang->cmd_delete}</span>
</block>
</td>
</tr>
<tr cond="$page_navigation->total_count == 0">
<td>{$lang->msg_no_result}</td>
</tr>
</tbody>
</table>
<div class="x_clearfix">
<div class="x_pull-left x_pagination" style="margin:0">
<ul>
<li class="x_disabled"|cond="$page == 1"><a href="{getUrl('page', '')}">&laquo; {$lang->first_page}</a></li>
<!--@while($page_no = $page_navigation->getNextPage())-->
<li class="x_active"|cond="$page_no == $page"><a href="{getUrl('page', $page_no)}">{$page_no}</a></li>
<!--@end-->
<li class="x_disabled"|cond="$page == $page_navigation->last_page"><a href="{getUrl('page', $page_navigation->last_page)}">{$lang->last_page} &raquo;</a></li>
</ul>
</div>
<div class="x_pull-right x_btn-group">
<a class="x_btn x_btn-inverse" href="{getUrl('', 'module', 'admin', 'act', 'dispAdminInsertDomain')}">{$lang->cmd_new_domain}</a>
</div>
</div>
</section>
<section class="section">
<h2>{$lang->cmd_multidomain_configuration}</h2>
<form action="./" method="post" class="x_form-horizontal">
<input type="hidden" name="module" value="admin" />
<input type="hidden" name="act" value="procAdminUpdateDomains" />
<input type="hidden" name="xe_validator_id" value="modules/admin/tpl/config_domains/1" />
<div class="x_control-group">
<label class="x_control-label">{$lang->cmd_unregistered_domain_action}</label>
<div class="x_controls">
<label for="unregistered_domain_redirect_301">
<input type="radio" name="unregistered_domain_action" id="unregistered_domain_redirect_301" value="redirect_301" checked="checked"|cond="config('url.unregistered_domain_action') === 'redirect_301' || !config('url.unregistered_domain_action')" />
{$lang->cmd_unregistered_domain_redirect_301}
</label>
<label for="unregistered_domain_redirect_302">
<input type="radio" name="unregistered_domain_action" id="unregistered_domain_redirect_302" value="redirect_302" checked="checked"|cond="config('url.unregistered_domain_action') === 'redirect_302'" />
{$lang->cmd_unregistered_domain_redirect_302}
</label>
<label for="unregistered_domain_display">
<input type="radio" name="unregistered_domain_action" id="unregistered_domain_display" value="display" checked="checked"|cond="config('url.unregistered_domain_action') === 'display'" />
{$lang->cmd_unregistered_domain_display}
</label>
<label for="unregistered_domain_block">
<input type="radio" name="unregistered_domain_action" id="unregistered_domain_block" value="block" checked="checked"|cond="config('url.unregistered_domain_action') === 'block'" />
{$lang->cmd_unregistered_domain_block}
</label>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->use_sso}</label>
<div class="x_controls">
<label for="use_sso_y" class="x_inline"><input type="radio" name="use_sso" id="use_sso_y" value="Y" checked="checked"|cond="config('use_sso')" /> {$lang->cmd_yes}</label>
<label for="use_sso_n" class="x_inline"><input type="radio" name="use_sso" id="use_sso_n" value="N" checked="checked"|cond="!config('use_sso')" /> {$lang->cmd_no}</label>
<br />
<p class="x_help-block">{$lang->about_use_sso}</p>
</div>
</div>
<div class="x_clearfix btnArea">
<div class="x_pull-right">
<button type="submit" class="x_btn x_btn-primary">{$lang->cmd_save}</button>
</div>
</div>
</form>
</section>
<script>
$(function() {
$("a.delete_domain").on("click", function(event) {
event.preventDefault();
var domain = $(this).data("domain");
var domain_srl = $(this).data("domain-srl");
if (confirm({$lang->cmd_delete_domain|json} + "\n" + domain)) {
exec_json('admin.procAdminDeleteDomain', { domain_srl: domain_srl }, function() {
window.location.reload();
});
}
});
});
</script>

View file

@ -0,0 +1,154 @@
<include target="config_header.html" />
<div cond="$XE_VALIDATOR_MESSAGE && $XE_VALIDATOR_ID == 'modules/admin/tpl/config_domains_edit/1'" class="message {$XE_VALIDATOR_MESSAGE_TYPE}">
<p>{$XE_VALIDATOR_MESSAGE}</p>
</div>
<section class="section">
<form action="./" method="post" class="x_form-horizontal" enctype="multipart/form-data">
<input type="hidden" name="module" value="admin" />
<input type="hidden" name="act" value="procAdminInsertDomain" />
<input type="hidden" name="xe_validator_id" value="modules/admin/tpl/config_domains_edit/1" />
<input type="hidden" name="domain_srl" value="{$domain_info ? $domain_info->domain_srl : ''}" />
<div class="x_control-group">
<label class="x_control-label">{$lang->site_title}</label>
<div class="x_controls">
<input type="text" name="title" value="{$domain_info ? escape($domain_info->settings->title) : ''}" class="lang_code" />
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->site_subtitle}</label>
<div class="x_controls">
<input type="text" name="subtitle" value="{$domain_info ? escape($domain_info->settings->subtitle) : ''}" class="lang_code" />
</div>
</div>
<div class="x_control-group">
<label class="x_control-label" for="domain">{$lang->domain}</label>
<div class="x_controls">
<input type="text" name="domain" id="domain" value="{$domain_info ? escape($domain_info->domain) : ''}"/>
&nbsp;
<label for="is_default_domain" class="x_inline">
<input type="checkbox" name="is_default_domain" id="is_default_domain" value="Y" checked="checked"|cond="$domain_info && $domain_info->is_default_domain === 'Y'" disabled="disabled"|cond="$domain_info && $domain_info->is_default_domain === 'Y'" /> {$lang->cmd_is_default_domain}
</label>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label" for="http_port">{$lang->cmd_http_port}</label>
<div class="x_controls">
<input type="number" name="http_port" id="http_port" size="5" value="{($domain_info && $domain_info->http_port) ? $domain_info->http_port : ''}" />
</div>
</div>
<div class="x_control-group">
<label class="x_control-label" for="https_port">{$lang->cmd_https_port}</label>
<div class="x_controls">
<input type="number" name="https_port" id="https_port" size="5" value="{($domain_info && $domain_info->https_port) ? $domain_info->https_port : ''}" />
</div>
</div>
<div class="x_control-group">
<label class="x_control-label" for="domain_security">{$lang->use_ssl}</label>
<div class="x_controls">
<select id="domain_security" name="domain_security">
<!--@foreach($lang->ssl_options as $key => $val)-->
<option value="{$key}" selected="selected"|cond="$domain_info && $domain_info->security == $key" />{$val}</option>
<!--@endforeach-->
</select>
<div class="x_help-block">{lang('admin.about_use_ssl')}</div>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label" for="index_module_srl">{$lang->cmd_index_module_srl}</label>
<div class="x_controls">
<input class="module_search" type="text" id="index_module_srl" name="index_module_srl" value="{$index_module_srl}" />
</div>
</div>
<div class="x_control-group">
<label class="x_control-label" for="index_document_srl">{$lang->cmd_index_document_srl}</label>
<div class="x_controls">
<input type="number" name="index_document_srl" id="index_document_srl" value="{($domain_info && $domain_info->index_document_srl) ? $domain_info->index_document_srl : ''}"/>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label" for="default_lang">{$lang->default_lang}</label>
<div class="x_controls">
<select name="default_lang" id="default_lang">
<option value="{$key}" loop="$enabled_lang => $key" selected="selected"|cond="$key == $domain_lang">{$supported_lang[$key]['name']}</option>
</select>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label" for="default_timezone">{$lang->timezone}</label>
<div class="x_controls">
<select name="default_timezone">
<option loop="$timezones => $key,$val" value="{$key}" selected="selected"|cond="$key == $domain_timezone">{$val}</option>
</select>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label" for="html_footer">{$lang->input_footer_script}</label>
<div class="x_controls" style="margin-right:14px">
<textarea name="html_footer" id="html_footer" rows="6" style="width:100%">{$domain_info ? $domain_info->settings->html_footer : ''}</textarea>
<div class="x_help-block">{$lang->detail_input_footer_script}</div>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->allow_use_favicon}</label>
<div class="x_controls">
<p id="faviconPreview">
<img src="{$favicon_url ?: (\RX_BASEURL . 'modules/admin/tpl/img/faviconSample.png')}" alt="Favicon" class="fn1" style="width:16px;height:16px">
<img src="{$favicon_url ?: (\RX_BASEURL . 'modules/admin/tpl/img/faviconSample.png')}" alt="Favicon" class="fn2" style="width:16px;height:16px">
</p>
<label for="delete_favicon" cond="$favicon_url">
<input type="checkbox" name="delete_favicon" id="delete_favicon" value="1" /> {$lang->cmd_delete}
</label>
<input type="file" name="favicon" id="favicon" title="Favicon" />
<span class="x_help-block">{$lang->about_use_favicon}</span>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->allow_use_mobile_icon}</label>
<div class="x_controls">
<p id="mobiconPreview">
<img src="{$mobicon_url ?: (\RX_BASEURL . 'modules/admin/tpl/img/mobiconSample.png')}" alt="Mobile Home Icon" width="32" height="32" />
<span>Rhymix</span>
</p>
<label for="delete_mobicon" cond="$mobicon_url">
<input type="checkbox" name="delete_mobicon" id="delete_mobicon" value="1" /> {$lang->cmd_delete}
</label>
<input type="file" name="mobicon" id="mobicon" title="Mobile Home Icon" />
<span class="x_help-block">{$lang->detail_use_mobile_icon}</span>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->cmd_site_default_image}</label>
<div class="x_controls">
<p id="default_imagePreview" cond="$default_image_url">
<img src="{$default_image_url}" alt="Default Image" style="width:200px;height:auto" />
</p>
<label for="delete_default_image" cond="$default_image_url">
<input type="checkbox" name="delete_default_image" id="delete_default_image" value="1" /> {$lang->cmd_delete}
</label>
<input type="file" name="default_image" id="default_image" title="Default Image" />
<span class="x_help-block">{$lang->about_site_default_image}</span>
</div>
</div>
<div class="x_clearfix btnArea">
<div class="x_pull-right">
<button type="submit" class="x_btn x_btn-primary">{$lang->cmd_save}</button>
</div>
</div>
</form>
</section>

View file

@ -1,206 +0,0 @@
<include target="config_header.html" />
<div cond="$XE_VALIDATOR_MESSAGE && $XE_VALIDATOR_ID == 'modules/admin/tpl/config_general/1'" class="message {$XE_VALIDATOR_MESSAGE_TYPE}">
<p>{$XE_VALIDATOR_MESSAGE}</p>
</div>
<section class="section">
<form action="./" method="post" enctype="multipart/form-data" id="config_form" class="x_form-horizontal">
<input type="hidden" name="module" value="admin" />
<input type="hidden" name="act" value="procAdminUpdateConfigGeneral" />
<input type="hidden" name="xe_validator_id" value="modules/admin/tpl/config_general/1" />
<div></div>
</form>
<div class="x_form-horizontal" id="admin_config">
<div class="x_control-group">
<label class="x_control-label">{$lang->site_title}</label>
<div class="x_controls">
<input type="text" name="site_title" value="{$var_site_title}" class="lang_code" />
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->site_subtitle}</label>
<div class="x_controls">
<input type="text" name="site_subtitle" value="{$var_site_subtitle}" class="lang_code" />
</div>
</div>
<div class="x_control-group">
<label class="x_control-label" for="_target_module">{$lang->start_module}</label>
<div class="x_controls">
<input class="module_search" type="text" name="index_module_srl" value="{$start_module->index_module_srl}" />
</div>
</div>
<div class="x_control-group">
<label class="x_control-label" for="html_footer">{$lang->input_footer_script}</label>
<div class="x_controls" style="margin-right:14px">
<textarea name="html_footer" id="html_footer" rows="6" style="width:100%" placeholder="{$lang->detail_input_footer_script}" title="{$lang->detail_input_footer_script}">{$all_html_footer}</textarea>
</div>
</div>
<div class="x_control-group">
<label for="default_lang" class="x_control-label">{$lang->default_lang}</label>
<div class="x_controls">
<select name="default_lang" id="default_lang">
<option value="{$key}" loop="$enabled_lang=>$key" selected="selected"|cond="$key==$default_lang">{$supported_lang[$key]['name']}</option>
</select>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->lang_select}</label>
<div class="x_controls">
<label for="lang_{$key}" class="x_inline" loop="$supported_lang=>$key,$val">
<input type="checkbox" name="enabled_lang[]" id="lang_{$key}" value="{$key}" disabled="disabled"|cond="$key==$default_lang" checked="checked"|cond="in_array($key, $enabled_lang)" />
{$val['name']}
</label>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->auto_select_lang}</label>
<div class="x_controls">
<label for="auto_select_lang_y" class="x_inline">
<input type="radio" name="auto_select_lang" id="auto_select_lang_y" value="Y" checked="checked"|cond="$auto_select_lang" />
{$lang->cmd_yes}
</label>
<label for="auto_select_lang_n" class="x_inline">
<input type="radio" name="auto_select_lang" id="auto_select_lang_n" value="N" checked="checked"|cond="!$auto_select_lang" />
{$lang->cmd_no}
</label>
<br />
<p class="x_help-block">{$lang->about_auto_select_lang}</p>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label" for="default_timezone">{$lang->timezone}</label>
<div class="x_controls">
<select name="default_timezone">
<option loop="$timezones => $key,$val" value="{$key}" selected="selected"|cond="$key==$selected_timezone">{$val}</option>
</select>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->use_mobile_view}</label>
<div class="x_controls">
<label for="use_mobile_view_y" class="x_inline">
<input type="radio" name="use_mobile_view" id="use_mobile_view_y" value="Y" checked="checked"|cond="$use_mobile_view" />
{$lang->cmd_yes}
</label>
<label for="use_mobile_view_n" class="x_inline">
<input type="radio" name="use_mobile_view" id="use_mobile_view_n" value="N" checked="checked"|cond="!$use_mobile_view" />
{$lang->cmd_no}
</label>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->tablets_as_mobile}</label>
<div class="x_controls">
<label for="tablets_as_mobile_y" class="x_inline">
<input type="radio" name="tablets_as_mobile" id="tablets_as_mobile_y" value="Y" checked="checked"|cond="$tablets_as_mobile" />
{$lang->cmd_yes}
</label>
<label for="tablets_as_mobile_n" class="x_inline">
<input type="radio" name="tablets_as_mobile" id="tablets_as_mobile_n" value="N" checked="checked"|cond="!$tablets_as_mobile" />
{$lang->cmd_no}
</label>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->allow_use_favicon}</label>
<div class="x_controls">
<p id="faviconPreview">
<img src="{$favicon_url}" alt="Favicon" class="fn1" style="width:16px;height:16px">
<img src="{$favicon_url}" alt="Favicon" class="fn2" style="width:16px;height:16px">
</p>
<label><input type="checkbox" name="is_delete_favicon" value="1" /> {$lang->cmd_delete}</label>
<form action="./" enctype="multipart/form-data" method="post" target="hiddenIframe" class="imageUpload" style="margin:0">
<input type="hidden" name="module" value="admin">
<input type="hidden" name="act" value="procAdminFaviconUpload">
<p>
<input type="file" name="favicon" id="favicon" title="Favicon"/>
<input class="x_btn" type="submit" value="{$lang->cmd_upload}" style="vertical-align:top">
</p>
</form>
<span class="x_help-block">{$lang->about_use_favicon}</span>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->allow_use_mobile_icon}</label>
<div class="x_controls">
<p id="mobiconPreview">
<img src="{$mobicon_url}" alt="Mobile Home Icon" width="32" height="32" />
<span>Rhymix</span>
</p>
<label><input type="checkbox" name="is_delete_mobicon" value="1" /> {$lang->cmd_delete}</label>
<form action="./" enctype="multipart/form-data" method="post" target="hiddenIframe" class="imageUpload" style="margin:0">
<input type="hidden" name="module" value="admin">
<input type="hidden" name="act" value="procAdminFaviconUpload">
<p>
<input type="file" name="mobicon" id="mobicon" title="Mobile Home Icon"/>
<input class="x_btn" type="submit" value="{$lang->cmd_upload}" style="vertical-align:top">
</p>
</form>
<span class="x_help-block">{$lang->detail_use_mobile_icon}</span>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->cmd_site_default_image}</label>
<div class="x_controls">
<p id="default_imagePreview">
<img src="{$site_default_image_url}" alt="Default Image" style="width:200px;height:auto" />
</p>
<label><input type="checkbox" name="is_delete_default_image" value="1" /> {$lang->cmd_delete}</label>
<form action="./" enctype="multipart/form-data" method="post" target="hiddenIframe" class="imageUpload" style="margin:0">
<input type="hidden" name="module" value="admin">
<input type="hidden" name="act" value="procAdminFaviconUpload">
<p>
<input type="file" name="default_image" id="default_image" title="Site default image"/>
<input class="x_btn" type="submit" value="{$lang->cmd_upload}" style="vertical-align:top">
</p>
</form>
<span class="x_help-block">{$lang->about_site_default_image}</span>
</div>
</div>
<div class="x_clearfix btnArea">
<div class="x_pull-right">
<button type="submit" class="x_btn x_btn-primary" onclick="doSubmitConfig()">{$lang->cmd_save}</button>
</div>
</div>
</div>
</section>
<iframe name="hiddenIframe" src="about:blank" hidden></iframe>
<script>
jQuery(function() {
if (jQuery("#default_imagePreview img").attr("src") == "") {
jQuery("#default_imagePreview").hide();
jQuery("input[name='is_delete_default_image']").parent().hide();
}
});
function afterUploadConfigImage(name, tmpFileName) {
jQuery('#' + name + 'Preview img').attr('src', tmpFileName).parent().show();
jQuery('#' + name).val('');
jQuery("input[name='is_delete_" + name + "']").prop('checked', false).parent().show();
}
function alertUploadMessage(msg) {
alert(msg);
}
function doSubmitConfig()
{
var $forms = jQuery('#admin_config').find('input[name][type="hidden"], input[name][type="text"], input[name][type="checkbox"]:checked, select[name], textarea[name], input[name][type="radio"]:checked');
var $configForm = jQuery('#config_form');
var $container = $configForm.children('div');
$container.empty();
$forms.each(function($)
{
var $this = jQuery(this);
if($this.parents('.imageUpload').length) return;
var $input = jQuery('<input>').attr('type', 'hidden').attr('name', $this.attr('name')).val($this.val());
$container.append($input);
});
$configForm.submit();
}
</script>

View file

@ -4,7 +4,7 @@
<h1>{$lang->menu_gnb_sub['adminConfigurationGeneral']} <a class="x_icon-question-sign" href="./common/manual/admin/index.html#UMAN_config_general" target="_blank">{$lang->help}</a></h1>
</div>
<ul class="x_nav x_nav-tabs">
<li class="x_active"|cond="$act == 'dispAdminConfigGeneral'"><a href="{getUrl('', 'module', 'admin', 'act', 'dispAdminConfigGeneral')}">{$lang->subtitle_primary}</a></li>
<li class="x_active"|cond="$act == 'dispAdminConfigGeneral' || preg_match('/^dispAdmin.+Domain/', $act)"><a href="{getUrl('', 'module', 'admin', 'act', 'dispAdminConfigGeneral')}">{$lang->subtitle_site_info}</a></li>
<li class="x_active"|cond="$act == 'dispAdminConfigNotification'"><a href="{getUrl('', 'module', 'admin', 'act', 'dispAdminConfigNotification')}">{$lang->subtitle_notification}</a></li>
<li class="x_active"|cond="$act == 'dispAdminConfigSecurity'"><a href="{getUrl('', 'module', 'admin', 'act', 'dispAdminConfigSecurity')}">{$lang->subtitle_security}</a></li>
<li class="x_active"|cond="$act == 'dispAdminConfigAdvanced'"><a href="{getUrl('', 'module', 'admin', 'act', 'dispAdminConfigAdvanced')}">{$lang->subtitle_advanced}</a></li>

View file

@ -434,7 +434,7 @@ margin-bottom: 10px;
height: 25px;
}
.x input[type="number"] {
width: 50px;
width: 90px;
}
.x select {
padding: 0;

View file

@ -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']);

View file

@ -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;
}
/**

View file

@ -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);

View file

@ -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))

View file

@ -0,0 +1,8 @@
<query id="deleteDomain" action="delete">
<tables>
<table name="domains" />
</tables>
<conditions>
<condition operation="equal" column="domain_srl" var="domain_srl" filter="number" notnull="notnull" />
</conditions>
</query>

View file

@ -0,0 +1,16 @@
<query id="getDomainInfo" action="select">
<tables>
<table name="domains" />
<table name="modules" />
</tables>
<columns>
<column name="domains.*" />
<column name="modules.*" />
</columns>
<conditions>
<condition operation="equal" column="modules.module_srl" default="domains.index_module_srl" notnull="notnull" />
<condition operation="equal" column="domain_srl" var="domain_srl" pipe="and" />
<condition operation="equal" column="domain" var="domain" pipe="and" />
<condition operation="equal" column="is_default_domain" var="is_default_domain" pipe="and" />
</conditions>
</query>

View file

@ -0,0 +1,14 @@
<query id="getDomains" action="select">
<tables>
<table name="domains" />
</tables>
<columns>
<column name="*" />
</columns>
<navigation>
<index var="sort_index" default="domain_srl" order="asc" />
<list_count var="list_count" default="20" />
<page_count var="page_count" default="10" />
<page var="page" default="1" />
</navigation>
</query>

View file

@ -0,0 +1,11 @@
<query id="getSites" action="select">
<tables>
<table name="sites" />
</tables>
<columns>
<column name="*" />
</columns>
<navigation>
<index var="sort_index" default="site_srl" order="asc" />
</navigation>
</query>

View file

@ -0,0 +1,21 @@
<query id="insertDomain" action="insert">
<tables>
<table name="domains" />
</tables>
<columns>
<column name="domain_srl" var="domain_srl" notnull="notnull" filter="number" />
<column name="domain" var="domain" notnull="notnull" />
<column name="is_default_domain" var="is_default_domain" notnull="notnull" default="N" />
<column name="index_module_srl" var="index_module_srl" notnull="notnull" />
<column name="index_document_srl" var="index_document_srl" notnull="notnull" />
<column name="default_layout_srl" var="default_layout_srl" notnull="notnull" default="0" />
<column name="default_mlayout_srl" var="default_mlayout_srl" notnull="notnull" default="0" />
<column name="default_menu_srl" var="default_menu_srl" notnull="notnull" default="0" />
<column name="http_port" var="http_port" />
<column name="https_port" var="https_port" />
<column name="security" var="security" notnull="notnull" default="none" />
<column name="description" var="description" />
<column name="settings" var="settings" />
<column name="regdate" var="regdate" default="curdate()" />
</columns>
</query>

View file

@ -0,0 +1,12 @@
<query id="updateDefaultDomain" action="update">
<tables>
<table name="domains" />
</tables>
<columns>
<column name="is_default_domain" var="is_default_domain" notnull="notnull" default="N" />
</columns>
<conditions>
<condition operation="equal" column="domain_srl" var="domain_srl" filter="number" />
<condition operation="notequal" column="domain_srl" var="not_domain_srl" filter="number" pipe="and" />
</conditions>
</query>

View file

@ -0,0 +1,23 @@
<query id="updateDomain" action="update">
<tables>
<table name="domains" />
</tables>
<columns>
<column name="domain" var="domain" />
<column name="is_default_domain" var="is_default_domain" />
<column name="index_module_srl" var="index_module_srl" />
<column name="index_document_srl" var="index_document_srl" />
<column name="default_layout_srl" var="default_layout_srl" />
<column name="default_mlayout_srl" var="default_mlayout_srl" />
<column name="default_menu_srl" var="default_menu_srl" />
<column name="http_port" var="http_port" />
<column name="https_port" var="https_port" />
<column name="security" var="security" />
<column name="description" var="description" />
<column name="settings" var="settings" />
<column name="regdate" var="regdate" />
</columns>
<conditions>
<condition operation="equal" column="domain_srl" var="domain_srl" filter="number" notnull="notnull" />
</conditions>
</query>

View file

@ -0,0 +1,16 @@
<table name="domains">
<column name="domain_srl" type="number" notnull="notnull" primary_key="primary_key" />
<column name="domain" type="varchar" size="80" notnull="notnull" index="idx_domain" />
<column name="is_default_domain" type="char" size="1" notnull="notnull" default="N" index="idx_is_default_domain" />
<column name="index_module_srl" type="number" notnull="notnull" index="idx_index_module_srl" />
<column name="index_document_srl" type="number" notnull="notnull" index="idx_index_document_srl" />
<column name="default_layout_srl" type="number" notnull="notnull" default="0" />
<column name="default_mlayout_srl" type="number" notnull="notnull" default="0" />
<column name="default_menu_srl" type="number" notnull="notnull" default="0" />
<column name="http_port" type="number" />
<column name="https_port" type="number" />
<column name="security" type="varchar" size="20" notnull="notnull" default="none" />
<column name="description" type="text" />
<column name="settings" type="text" />
<column name="regdate" type="date" />
</table>

View file

@ -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()