Merge branch 'develop' into pr/csrf-token

This commit is contained in:
Kijin Sung 2017-03-13 16:35:24 +09:00
commit a3ef122b57
68 changed files with 2115 additions and 1361 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 !== false && $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

@ -3,7 +3,7 @@
/**
* RX_VERSION is the version number of the Rhymix CMS.
*/
define('RX_VERSION', '1.8.33');
define('RX_VERSION', '1.8.34');
/**
* RX_MICROTIME is the startup time of the current script, in microseconds since the Unix epoch.

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

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

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

@ -4,8 +4,8 @@
<title xml:lang="en">Rectangular World</title>
<description xml:lang="ko">깔끔한 면과 그림자 레이아웃</description>
<description xml:lang="en">Simple rectangular planes and shadows</description>
<version>1.0.1</version>
<date>2016-09-25</date>
<version>1.1.0</version>
<date>2017-03-10</date>
<author email_address="misol.kr@gmail.com" link="https://github.com/misol">
<name xml:lang="ko">misol</name>
<name xml:lang="en">misol</name>
@ -35,6 +35,24 @@
<title xml:lang="en">Top left</title>
</options>
</var>
<var name="left_space" type="select">
<title xml:lang="ko">죄측 공간 만들기</title>
<title xml:lang="en">Make a space on the left</title>
<description xml:lang="ko">본문 좌측에 공간을 만듭니다. 모바일 화면에서는 나타나지 않습니다.</description>
<description xml:lang="en">Make a space on the left of contents area.</description>
<options value="N">
<title xml:lang="ko">만들지 않습니다.</title>
<title xml:lang="en">I don't need it.</title>
</options>
<options value="Y">
<title xml:lang="ko">공간을 만듭니다.</title>
<title xml:lang="en">I need it.</title>
</options>
<options value="YM">
<title xml:lang="ko">공간을 만들고, 서브 메뉴를 나타냅니다.</title>
<title xml:lang="en">I need it, and place there submenus.</title>
</options>
</var>
<var name="LOGO_IMG" type="image">
<title xml:lang="ko">사이트 로고 이미지</title>
<title xml:lang="en">Site logo image</title>
@ -52,6 +70,16 @@
<title xml:lang="en">Before the content area content</title>
<description xml:lang="ko">사이트 본문 영역 상단에 내용을 입력할 수 있습니다.</description>
</var>
<var name="left_content" type="textarea">
<title xml:lang="ko">사이트 본문 좌측 내용</title>
<title xml:lang="en">The contents of the left of contents area</title>
<description xml:lang="ko">사이트 본문 영역 좌측 영역이 나타나게 선택되었을 경우 추가될 내용을 입력할 수 있습니다. 모바일 화면에서는 나타나지 않습니다. 상단 옵션 중 '죄측 공간 만들기'를 먼저 설정해주십시오.</description>
</var>
<var name="right_content" type="textarea">
<title xml:lang="ko">레이아웃 틀 오른쪽 내용 (width: 160px)</title>
<title xml:lang="en">The right area of the layout frame (width: 160px)</title>
<description xml:lang="ko">레이아웃 상-하단이 만들어내는 직사각형 영역 바깥 오른편에 나타낼 내용을 입력합니다. 공간 폭은 160px 입니다. 작은 화면에서는 나타나지 않습니다.</description>
</var>
<var name="after_content" type="textarea">
<title xml:lang="ko">사이트 본문 하단 내용</title>
<title xml:lang="en">After the content area content</title>

View file

@ -103,7 +103,12 @@
<li loop="$GNB->list=>$key1,$val1" class="<!--@if($val1['selected'])-->active <!--@endif--><!--@if($val1['list'])-->layout_dropdown<!--@endif-->">
<a href="{$val1['href']}" target="_blank"|cond="$val1['open_window']=='Y'"><span>{$val1['link']}</span></a>
<ul cond="$val1['list']" class="layout_dropdown-content">
<li loop="$val1['list']=>$key2,$val2" class="active"|cond="$val2['selected']"><a href="{$val2['href']}" target="_blank"|cond="$val2['open_window']=='Y'">{$val2['link']}</a></li>
<li loop="$val1['list']=>$key2,$val2" class="active"|cond="$val2['selected']">
<a href="{$val2['href']}" target="_blank"|cond="$val2['open_window']=='Y'">{$val2['link']}</a>
<ul cond="$val2['list']">
<li loop="$val2['list']=>$key3,$val3" class="active"|cond="$val3['selected']"><a href="{$val3['href']}" target="_blank"|cond="$val3['open_window']=='Y'">{$val3['link']}</a></li>
</ul>
</li>
</ul>
</li>
<li id="layout_search_link">
@ -113,16 +118,34 @@
</nav>
<!--// Menu -->
</header>
<div class="layout_frame layout_body">
<div class="layout_frame layout_body<!--@if(in_array($layout_info->left_space, array('Y', 'YM')))--> layout_left_content<!--@end-->">
<!--// VISUAL -->
<div class="layout_body layout_canvas">
<!--// CONTENT -->
<div class="layout_content" id="content">
<div class="layout_content layout_left_content" cond="in_array($layout_info->left_space, array('Y', 'YM'))">
<section class="layout_left layout_dropdown" loop="$GNB->list=>$key1,$val1" cond="$layout_info->left_space == 'YM' && $val1['selected']">
<h1><a href="{$val1['href']}" target="_blank"|cond="$val1['open_window']=='Y'">{$val1['link']}</a></h1>
<ul class="layout_dropdown-content" cond="$val1['list']">
<li loop="$val1['list']=>$key2,$val2"><a href="{$val2['href']}" class="active"|cond="$val2['selected']" target="_blank"|cond="$val2['open_window']=='Y'">{$val2['link']}</a>
<ul cond="$val2['list']">
<li loop="$val2['list']=>$key3,$val3" class="active"|cond="$val3['selected']"><a href="{$val3['href']}" target="_blank"|cond="$val3['open_window']=='Y'">{$val3['link']}</a></li>
</ul>
</li>
</ul>
</section>
<section class="layout_left" cond="trim($layout_info->left_content)">
{$layout_info->left_content}
</section>
</div>
<div class="layout_content" id="content">
{$layout_info->before_content}
{$content}
{$layout_info->after_content}
</div>
<!--// CONTENT -->
<div class="layout_outright" cond="trim($layout_info->right_content)">
{$layout_info->right_content}
</div>
</div>
</div>
<footer class="layout_frame layout_footer">

View file

@ -81,6 +81,7 @@ $(function()
{
$( this ).focusin( function( event )
{
$('*[data-dropdown="active"]').css('display', '').attr('data-dropdown', '').parents('li.layout_dropdown').removeClass('layout_focus');
$( this ).addClass('layout_focus');
$( this ).find("ul.layout_dropdown-content").css('display', 'block').attr('data-dropdown', 'active');
});

View file

@ -12,6 +12,11 @@
@return rgb($return, $return, $return);
}
@mixin layout_box($shadow){
background: #fff;
box-shadow: 0 $shadow/2 $shadow rgba(0,0,0,0.16), 0 $shadow/2 $shadow rgba(0,0,0,0.23);
}
body {
margin:0;
padding:0;
@ -43,7 +48,10 @@ body {
width:100%;
margin:0 auto;
}
header.layout_frame, footer.layout_frame, .layout_frame.layout_left_content .layout_left_content{
font-family: "맑은 고딕", "Apple SD Gothic Neo","나눔고딕",NanumGothic,'Nanum Gothic',Arial,Helvetica,sans-serif;
font-size: 14px;
}
.layout_header {
padding:0;
}
@ -56,10 +64,75 @@ body {
.layout_body.layout_frame {
background-color: $content_color;
overflow: hidden;
}
.layout_body {
position: relative;
}
.layout_outright{
position: absolute;
top: 15px;
right: 0;
box-sizing: border-box;
width: 160px;
@include layout_box(2px);
margin-right:-170px;
}
.layout_left_content.layout_frame>.layout_canvas {
div.layout_content {
float:left;
width: 20%;
box-sizing: border-box;
padding-right:5px;
section.layout_left{
margin: 2px 2px 10px;
@include layout_box(2px);
h1 {
border-bottom: 1px solid #e0e0e0;
font-weight: 400;
margin: 0;
position: relative;
a {
display: block;
margin: 0;
padding: 14px 16px;
font-size: 14px;
color: $primary-color;
text-decoration: none;
}
}
ul{
list-style: none;
&.layout_dropdown-content {
display: block;
position: relative;
z-index: none;
padding: 0;
margin: 0;
a {
display: block;
padding: 14px 16px;
text-decoration: none;
color: #000;
&.active {
background: #e0e0e0;
}
&:hover, &:active, &:focus {
background: #eeeeee;
}
}
ul {
padding-left: 10px;
}
}
}
}
}
#content {
width: 80%;
}
}
.layout_header:after,
.layout_body:after {
@ -71,36 +144,35 @@ body {
.layout_content {
overflow: auto;
padding:10px 0px;
img {
max-width:100%;
height: auto
}
}
.layout_content>*:first-child {
margin-top:0
}
.layout_content img {
max-width:100%;
height: auto
}
/* Header */
header.layout_frame {
position:relative;
background-color: lighten($primary-color, 10%);
z-index: 1;
box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
}
.layout_header>h1 {
margin:0 auto;
padding:20px 5px;
box-sizing: border-box;
color: layoutGrayContrast(lighten($primary-color, 10%), 0.710);
}
.layout_header>h1>a {
font-size:32px;
text-decoration: none;
color: layoutGrayContrast(lighten($primary-color, 10%), 0.710);
padding:0 5px;
.layout_header>h1 {
margin:0 auto;
padding:20px 5px;
box-sizing: border-box;
color: layoutGrayContrast(lighten($primary-color, 10%), 0.710);
a {
font-size:32px;
text-decoration: none;
color: layoutGrayContrast(lighten($primary-color, 10%), 0.710);
padding:0 5px;
}
}
}
#layout_menu_toggle {
@ -114,83 +186,88 @@ header.layout_frame {
padding: 13px 7px;
background-color: darken($grey, 35%);
color: lighten($grey, 30%);
}
.layout_footer p {
font-size:12px
}
.layout_footer a {
font-weight: bold;
text-decoration: none;
color: lighten($primary_color, 31%);
}
.layout_footer a:hover,
.layout_footer a:focus {
text-decoration: underline
p {
font-size:12px
}
a {
font-weight: bold;
text-decoration: none;
color: lighten($primary_color, 31%);
&:hover, &:active, &:focus {
text-decoration: underline
}
}
}
/* Search */
.layout_header .layout_search {
display: inline-block;
vertical-align: bottom;
margin:0
}
.layout_header .layout_search>input {
font-size:12px;
-webkit-appearance: none;
border-radius: 0;
}
.layout_header .layout_search>input[type="text"] {
width: 126px;
line-height: 18px;
font-size: 14px;
margin: 0;
padding: 8px 8px 6px 8px;
position: relative;
display: inline-block;
outline: none;
border-radius: 0;
border: none;
background: lighten($primary-color, 20%);
color: layoutGrayContrast(lighten($primary-color, 20%), 0.710);
}
.layout_header .layout_search>input[type="text"]:hover,
.layout_header .layout_search>input[type="text"]:focus {
background: lighten($primary-color, 50%);
color: layoutGrayContrast(lighten($primary-color, 50%), 0.710);
}
.layout_header .layout_search>input[type="submit"] {
vertical-align: bottom;
background: lighten($primary-color,15%);
color: layoutGrayContrast(lighten($primary-color, 15%), 0.710);
border: none;
height:32px;
padding:0 15px;
margin:0;
}
.layout_header .layout_search>input[type="submit"]:hover,
.layout_header .layout_search>input[type="submit"]:focus {
background:$primary-color;
color: layoutGrayContrast($primary-color, 0.710);
.layout_header{
.layout_search {
display: inline-block;
vertical-align: bottom;
margin:0
}
input {
font-size:12px;
-webkit-appearance: none;
border-radius: 0;
}
input[type="text"] {
width: 126px;
line-height: 18px;
margin: 0;
padding: 8px 8px 6px 8px;
position: relative;
display: inline-block;
outline: none;
border-radius: 0;
border: none;
background: lighten($primary-color, 20%);
color: layoutGrayContrast(lighten($primary-color, 20%), 0.710);
&:hover, &:active, &:focus {
background: lighten($primary-color, 50%);
color: layoutGrayContrast(lighten($primary-color, 50%), 0.710);
}
}
input[type="submit"] {
vertical-align: bottom;
background: lighten($primary-color,15%);
color: layoutGrayContrast(lighten($primary-color, 15%), 0.710);
border: none;
height:32px;
padding:0 15px;
margin:0;
&:hover, &:active, &:focus {
background:$primary-color;
color: layoutGrayContrast($primary-color, 0.710);
}
}
}
/* GNB */
.layout_menu {
background-color: lighten($grey, 31%);
}
.layout_menu ul {
list-style-type: none;
padding: 0;
overflow: hidden;
max-width:1050px;
margin:0 auto;
ul {
list-style-type: none;
overflow: hidden;
max-width:1050px;
margin:0 auto;
padding: 0;
&.layout_dropdown-content ul{
padding-left:10px;
}
}
li a, .dropbtn {
display: inline-block;
color: black;
text-align: center;
padding: 14px 16px;
text-decoration: none;
line-height: 1;
}
li.active>a {
background-color: lighten($primary-color, 15%);
color: layoutGrayContrast(lighten($primary-color, 15%), 0.710);
}
}
.layout_menu>ul{
width:100%;
@ -203,26 +280,13 @@ header.layout_frame {
float: right;
}
.layout_menu li a, .dropbtn {
display: inline-block;
color: black;
text-align: center;
padding: 14px 16px;
text-decoration: none;
font-size: 13px;
line-height: 1;
}
.layout_menu li.active>a {
background-color: lighten($primary-color, 15%);
color: layoutGrayContrast(lighten($primary-color, 15%), 0.710);
}
header .layout_menu li:hover,
header .layout_menu li:focus,
header .layout_menu li:active,
header .layout_menu .layout_focus {
background-color: lighten($grey, 40%);
header.layout_frame .layout_menu{
li:hover,
li:focus,
li:active,
.layout_focus {
background-color: lighten($grey, 40%);
}
}
.layout_menu li a:hover,
.layout_menu li a:focus,
@ -236,78 +300,81 @@ header .layout_menu .layout_focus {
background-color: $primary-color;
color: layoutGrayContrast($primary-color, 0.710);
}
.layout_menu {
li.layout_dropdown {
display: block;
}
.layout_menu li.layout_dropdown {
display: block;
.layout_dropdown-content {
display: none;
position: absolute;
background-color: lighten($grey, 40%);
z-index: 1000;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
}
.layout_dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
min-width: 160px;
display: block;
text-align: left;
box-sizing: border-box;
}
.
.layout_dropdown-content a:hover,
.layout_dropdown-content a:active,
.layout_dropdown-content a:focus {
display: block;
background-color: lighten($primary-color, 10%);
color: layoutGrayContrast(lighten($primary-color, 10%), 0.710);
}
.layout_dropdown:hover .layout_dropdown-content,
.layout_dropdown:active .layout_dropdown-content,
.layout_dropdown:focus .layout_dropdown-content,
.layout_dropdown a:hover ~ .layout_dropdown-content,
.layout_dropdown a:active ~ .layout_dropdown-content,
.layout_dropdown a:focus ~ .layout_dropdown-content,
.layout_dropdown layout_dropdown-content:hover,
.layout_dropdown layout_dropdown-content:active,
.layout_dropdown layout_dropdown-content:focus {
display: block;
}
}
.layout_menu .layout_dropdown-content {
display: none;
position: absolute;
background-color: lighten($grey, 40%);
z-index: 1000;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
}
.layout_menu .layout_dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
min-width: 160px;
display: block;
text-align: left;
box-sizing: border-box;
}
.
.layout_menu .layout_dropdown-content a:hover,
.layout_menu .layout_dropdown-content a:active,
.layout_menu .layout_dropdown-content a:focus {
display: block;
background-color: lighten($primary-color, 10%);
color: layoutGrayContrast(lighten($primary-color, 10%), 0.710);
}
.layout_menu .layout_dropdown:hover .layout_dropdown-content,
.layout_menu .layout_dropdown:active .layout_dropdown-content,
.layout_menu .layout_dropdown:focus .layout_dropdown-content,
.layout_menu .layout_dropdown a:hover ~ .layout_dropdown-content,
.layout_menu .layout_dropdown a:active ~ .layout_dropdown-content,
.layout_menu .layout_dropdown a:focus ~ .layout_dropdown-content,
.layout_menu .layout_dropdown layout_dropdown-content:hover,
.layout_menu .layout_dropdown layout_dropdown-content:active,
.layout_menu .layout_dropdown layout_dropdown-content:focus/* ,
.layout_menu .layout_dropdown .layout_dropdown-content:has(> a:hover),
.layout_menu .layout_dropdown .layout_dropdown-content:has(> a:focus) */ {
display: block;
}
#layout_fnb{
background-color: transparent;
}
.layout_footer .layout_menu li a, .layout_footer .dropbtn {
color: lighten($grey, 10%);
font-weight: normal;
text-decoration: none;
padding: 14px 0px;
}
.layout_footer .layout_menu li a>span {
padding: 0px 16px;
border-right: 1px solid lighten($grey, 10%);
}
.layout_footer .layout_menu li:first-child{
margin-left:-16px;
}
.layout_footer .layout_menu li:last-child a>span {
border-right: none;
.layout_footer {
.layout_menu li a, .dropbtn {
color: lighten($grey, 10%);
font-weight: normal;
text-decoration: none;
padding: 14px 0px;
}
.layout_menu li a>span {
padding: 0px 16px;
border-right: 1px solid lighten($grey, 10%);
}
.layout_menu li:first-child{
margin-left:-16px;
}
.layout_menu li:last-child a>span {
border-right: none;
}
.layout_menu li a:hover,
.layout_menu li a:focus,
.layout_menu li a:active{
background-color: transparent;
color: #fff;
}
}
.layout_footer .layout_menu li a:hover,
.layout_footer .layout_menu li a:focus,
.layout_footer .layout_menu li a:active{
background-color: transparent;
color: #fff;
}
/* Language */
.layout_language{
@ -350,19 +417,19 @@ header .layout_menu .layout_focus {
.layout_language li{
list-style:none;
background: lighten($grey, 40%);
}
.layout_language li button {
display:block;
color: black;
background: lighten($grey, 40%);
padding: 12px 16px;
text-decoration: none;
width: 100%;
display: block;
text-align: left;
box-sizing: border-box;
border:0;
cursor:pointer;
button {
display:block;
color: black;
background: lighten($grey, 40%);
padding: 12px 16px;
text-decoration: none;
width: 100%;
display: block;
text-align: left;
box-sizing: border-box;
border:0;
cursor:pointer;
}
}
/* Hamberger menu http://callmenick.com/post/animating-css-only-hamburger-menu-icons Licensed under the MIT license, http://www.opensource.org/licenses/mit-license.php Copyright 2014, Call Me Nick http://callmenick.com */
@ -382,62 +449,62 @@ header .layout_menu .layout_focus {
border: none;
cursor: pointer;
transition: background 0.3s;
span {
display: block;
position: absolute;
top: 41px;
left: 17px;
right: 17px;
height: 8px;
background: white;
}
span::before,
span::after {
position: absolute;
display: block;
left: 0;
width: 100%;
height: 8px;
background-color: #fff;
content: "";
}
span::before {
top: -19px;
}
span::after {
bottom: -19px;
}
&:focus {
outline: none;
}
}
.layout_mobile_menu:focus {
outline: none;
}
.layout_mobile_menu span {
display: block;
position: absolute;
top: 41px;
left: 17px;
right: 17px;
height: 8px;
background: white;
}
.layout_mobile_menu span::before,
.layout_mobile_menu span::after {
position: absolute;
display: block;
left: 0;
width: 100%;
height: 8px;
background-color: #fff;
content: "";
}
.layout_mobile_menu span::before {
top: -19px;
}
.layout_mobile_menu span::after {
bottom: -19px;
}
.layout_mobile_menu--htx {
background-color: $primary-color;
span {
transition: background 0s 0.3s;
}
span::before,
span::after {
transition-duration: 0.3s, 0.3s;
transition-delay: 0.3s, 0s;
}
span::before {
transition-property: top, transform;
}
span::after {
transition-property: bottom, transform;
}
}
.layout_mobile_menu--htx span {
transition: background 0s 0.3s;
}
.layout_mobile_menu--htx span::before,
.layout_mobile_menu--htx span::after {
transition-duration: 0.3s, 0.3s;
transition-delay: 0.3s, 0s;
}
.layout_mobile_menu--htx span::before {
transition-property: top, transform;
}
.layout_mobile_menu--htx span::after {
transition-property: bottom, transform;
}
/* active state, i.e. menu open */
.layout_mobile_menu--htx.is-active {
@ -499,7 +566,14 @@ header .layout_menu .layout_focus {
opacity: 0.9;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
}
.layout_left_content.layout_frame>.layout_canvas {
div.layout_left_content {
display:none;
}
#content{
width:100%;
}
}
/* GNB */
.layout_menu {
display: none;
@ -507,14 +581,13 @@ header .layout_menu .layout_focus {
width:100%;
height: auto;
clear: both;
}
.layout_menu ul {
list-style-type: none;
margin: 0;
padding: 0;
width: 100%;
height: auto;
ul {
list-style-type: none;
margin: 0;
padding: 0;
width: 100%;
height: auto;
}
}
.layout_menu>ul>li, #layout_gnb>ul>li:first-child {
@ -553,15 +626,14 @@ header .layout_menu .layout_focus {
min-width: 100%;
box-shadow: none;
z-index:1;
}
.layout_menu .layout_dropdown-content a {
background-color: lighten($grey, 35%);
color: layoutGrayContrast(lighten($grey, 35%), 0.710);
padding: 15px 30px;
text-decoration: none;
display: block;
text-align: left;
a {
background-color: lighten($grey, 35%);
color: layoutGrayContrast(lighten($grey, 35%), 0.710);
padding: 15px 30px;
text-decoration: none;
display: block;
text-align: left;
}
}
.layout_footer .layout_menu {
@ -582,16 +654,16 @@ header .layout_menu .layout_focus {
.layout_language {
margin-top: 15px;
}
.layout_language ul {
display: none;
float:none;
width:100%;
}
.layout_language .toggle{
display: block;
float: none;
width:100%;
ul {
display: none;
float:none;
width:100%;
}
.toggle{
display: block;
float: none;
width:100%;
}
}
/* PC only */
.layout_pc {

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,262 @@ 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;
if (isset($vars->is_default_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 +1285,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 +1299,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 +1326,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
@ -827,7 +881,7 @@ class adminAdminView extends admin
// Widgets
$info[] = '[Widgets]';
$info['widget'] = "";
$info['widget'] = array();
$oWidgetModel = getModel('widget');
$widget_list = $oWidgetModel->getDownloadedWidgetList() ?: array();
foreach ($widget_list as $widget)

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

@ -527,9 +527,15 @@ class boardController extends board
// generate comment controller object
$oCommentController = getController('comment');
$updateComment = false;
if($this->module_info->comment_delete_message === 'yes' && $instant_delete != 'Y')
{
$output = $oCommentController->updateCommentByDelete($comment, $this->grant->manager);
$updateComment = true;
if($this->module_info->trash_use == 'Y')
{
$output = $oCommentController->moveCommentToTrash($comment, $updateComment);
}
}
elseif(starts_with('only_comm', $this->module_info->comment_delete_message) && $instant_delete != 'Y')
{
@ -537,22 +543,41 @@ class boardController extends board
if(count($childs) > 0)
{
$output = $oCommentController->updateCommentByDelete($comment, $this->grant->manager);
$updateComment = true;
if($this->module_info->trash_use == 'Y')
{
$output = $oCommentController->moveCommentToTrash($comment, $updateComment);
}
}
else
{
$output = $oCommentController->deleteComment($comment_srl, $this->grant->manager, FALSE, $childs);
if(!$output->toBool())
if($this->module_info->trash_use == 'Y')
{
return $output;
$output = $oCommentController->moveCommentToTrash($comment, $updateComment);
}
else
{
$output = $oCommentController->deleteComment($comment_srl, $this->grant->manager, FALSE, $childs);
if(!$output->toBool())
{
return $output;
}
}
}
}
else
{
$output = $oCommentController->deleteComment($comment_srl, $this->grant->manager);
if(!$output->toBool())
if($this->module_info->trash_use == 'Y')
{
return $output;
$output = $oCommentController->moveCommentToTrash($comment, $this->module_info->comment_delete_message);
}
else
{
$output = $oCommentController->deleteComment($comment_srl, $this->grant->manager);
if(!$output->toBool())
{
return $output;
}
}
}

View file

@ -467,7 +467,18 @@ class commentAdminController extends comment
$obj->module_srl = $originObject->module_srl;
$oCommentController = getController('comment');
$output = $oCommentController->insertComment($obj, true);
$oCommentModel = getModel('comment');
$oComment = $oCommentModel->getComment($originObject->comment_srl);
if($oComment->isExists())
{
$output = $oCommentController->updateCommentByRestore($obj);
}
else
{
$output = $oCommentController->insertComment($obj, true);
}
return $output;
}

View file

@ -990,6 +990,50 @@ class commentController extends comment
return $output;
}
function updateCommentByRestore($obj)
{
if (!$obj->comment_srl)
{
return new Object(-1, 'msg_invalid_request');
}
// begin transaction
$oDB = DB::getInstance();
$oDB->begin();
$obj->status = RX_STATUS_PUBLIC;
// use to query default
unset($obj->last_update);
$output = executeQuery('comment.updateCommentByRestore', $obj);
if(!$output->toBool())
{
$oDB->rollback();
return $output;
}
// update the number of comments
$oCommentModel = getModel('comment');
$comment_count = $oCommentModel->getCommentCount($obj->document_srl);
// only document is exists
if(isset($comment_count))
{
// create the controller object of the document
$oDocumentController = getController('document');
// update comment count of the article posting
$output = $oDocumentController->updateCommentCount($obj->document_srl, $comment_count, NULL, FALSE);
if(!$output->toBool())
{
$oDB->rollback();
return $output;
}
}
$oDB->commit();
return $output;
}
/**
* Delete comment
* @param int $comment_srl
@ -1153,6 +1197,123 @@ class commentController extends comment
return $output;
}
/**
* Comment move to trash
* @param $obj
* @return object
*/
function moveCommentToTrash($obj, $updateComment = false)
{
$logged_info = Context::get('logged_info');
$trash_args = new stdClass();
if(!$obj->trash_srl)
{
$trash_args->trash_srl = getNextSequence();
}
else
{
$trash_args->trash_srl = $obj->trash_srl;
}
$oCommentModel = getModel('comment');
$oComment = $oCommentModel->getComment($obj->comment_srl);
$oMemberModel = getModel('member');
$member_info = $oMemberModel->getMemberInfoByMemberSrl($oComment->get('member_srl'));
if($member_info->is_admin == 'Y' && $logged_info->is_admin != 'Y')
{
return new Object(-1, 'msg_admin_comment_no_move_to_trash');
}
$trash_args->module_srl = $oComment->variables['module_srl'];
$obj->module_srl = $oComment->variables['module_srl'];
if($trash_args->module_srl === 0)
{
return new Object(-1, 'msg_module_srl_not_exists');
}
$trash_args->document_srl = $obj->document_srl;
$trash_args->comment_srl = $obj->comment_srl;
$trash_args->description = $obj->description;
if(!Context::get('is_logged'))
{
$trash_args->member_Srl = $logged_info->member_srl;
$trash_args->user_id = htmlspecialchars_decode($logged_info->user_id);
$trash_args->user_name = htmlspecialchars_decode($logged_info->user_name);
$trash_args->nick_name = htmlspecialchars_decode($logged_info->nick_name);
}
$oDB = &DB::getInstance();
$oDB->begin();
require_once(RX_BASEDIR.'modules/trash/model/TrashVO.php');
$oTrashVO = new TrashVO();
$oTrashVO->setTrashSrl(getNextSequence());
$oTrashVO->setTitle(trim(strip_tags($obj->variables['content'])));
$oTrashVO->setOriginModule('comment');
$oTrashVO->setSerializedObject(serialize($obj->variables));
$oTrashVO->setDescription($obj->description);
$oTrashAdminController = getAdminController('trash');
$output = $oTrashAdminController->insertTrash($oTrashVO);
if(!$output->toBool())
{
$oDB->rollback();
return $output;
}
if($updateComment !== true)
{
$output = executeQuery('comment.deleteComment', $trash_args);
if(!$output->toBool())
{
$oDB->rollback();
return $output;
}
}
$args = new stdClass();
$args->comment_srl = $obj->comment_srl;
$output = executeQuery('comment.deleteCommentList', $args);
// update the number of comments
$comment_count = $oCommentModel->getCommentCount($obj->document_srl);
// only document is exists
if(isset($comment_count))
{
// create the controller object of the document
$oDocumentController = getController('document');
// update comment count of the article posting
$output = $oDocumentController->updateCommentCount($obj->document_srl, $comment_count, NULL, FALSE);
if(!$output->toBool())
{
$oDB->rollback();
return $output;
}
}
if($oComment->hasUploadedFiles())
{
$args = new stdClass();
$args->upload_target_srl = $oComment->comment_srl;
$args->isvalid = 'N';
executeQuery('file.updateFileValid', $args);
}
ModuleHandler::triggerCall('comment.moveCommentToTrash', 'after', $obj);
$oDB->commit();
Rhymix\Framework\Storage::deleteEmptyDirectory(RX_BASEDIR . sprintf('files/thumbnails/%s', getNumberingPath($comment_srl, 3)), true);
$output->add('document_srl', $obj->document_srl);
return $output;
}
/**
* Remove all comment relation log
* @return Object

View file

@ -55,3 +55,5 @@ $lang->msg_deleted_comment = '삭제된 댓글입니다.';
$lang->msg_admin_deleted_comment = '관리자가 삭제한 댓글입니다.';
$lang->msg_no_text_comment = '글자가 없는 댓글입니다.';
$lang->msg_comment_notify_mail = '[%s] 새로운 댓글이 등록되었습니다 : %s';
$lang->msg_admin_comment_no_move_to_trash = '최고관리자의 댓글을 휴지통으로 이동시킬 권한이 없습니다.';
$lang->msg_module_srl_not_exists = '모듈 번호가 존재하지 않습니다.';

View file

@ -0,0 +1,14 @@
<query id="updateCommentByRestore" action="update">
<tables>
<table name="comments" />
</tables>
<columns>
<column name="member_srl" var="member_srl" />
<column name="content" var="content" notnull="notnull" />
<column name="last_update" var="last_update" default="curdate()" />
<column name="status" var="status" default="1" />
</columns>
<conditions>
<condition operation="equal" column="comment_srl" var="comment_srl" filter="number" notnull="notnull" />
</conditions>
</query>

View file

@ -2,6 +2,7 @@
<module>
<grants />
<permissions>
<permission action="procFileGetList" target="manager" />
<permission action="procFileAdminInsertModuleConfig" target="manager" />
</permissions>
<actions>

View file

@ -170,7 +170,16 @@ class fileController extends file
if(!$upload_target_srl) $_SESSION['upload_info'][$editor_sequence]->upload_target_srl = $upload_target_srl = getNextSequence();
// Delete and then attempt to re-upload if file_srl is requested
$file_srl = Context::get('file_srl');
if($file_srl) $this->deleteFile($file_srl);
if($file_srl)
{
$oFileModel = getModel('file');
$logged_info = Context::get('logged_info');
$file_info = $oFileModel->getFile($file_srl);
if($file_info->file_srl == $file_srl && $oFileModel->getFileGrant($file_info, $logged_info)->is_deletable)
{
$this->deleteFile($file_srl);
}
}
$file_info = Context::get('Filedata');
// An error appears if not a normally uploaded file
@ -546,6 +555,12 @@ class fileController extends file
function procFileGetList()
{
if(!Context::get('is_logged')) return new Object(-1,'msg_not_permitted');
$logged_info = Context::get('logged_info');
if($logged_info->is_admin !== 'Y' && !getModel('module')->isSiteAdmin($logged_info))
{
return new Object(-1,'msg_not_permitted');
}
$fileSrls = Context::get('file_srls');
if($fileSrls) $fileSrlList = explode(',', $fileSrls);

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

@ -121,6 +121,7 @@ $lang->cmd_view_saved_document = '저장함 보기';
$lang->cmd_send_email = '메일 보내기';
$lang->cmd_modify_nickname_log = '닉네임 변경 기록';
$lang->cmd_member_file_upload = '서명에 파일 첨부 사용';
$lang->cmd_member_profile_view = '회원 프로필사진 보이기';
$lang->msg_email_not_exists = '이메일 주소가 존재하지 않습니다.';
$lang->msg_alreay_scrapped = '이미 스크랩된 게시물입니다.';
$lang->msg_cart_is_null = '대상을 선택해주세요.';
@ -228,6 +229,7 @@ $lang->about_reset_auth_mail = '현재등록된 이메일 주소는 %s입니다.
$lang->about_resend_auth_mail = '인증 메일을 받지 못한 경우 다시 받을 수 있습니다.';
$lang->about_reset_auth_mail_submit = '이메일을 로그인 계정으로 사용할 경우 신규 메일주소로 로그인해야 합니다.';
$lang->about_update_nickname_log = '닉네임 로그를 기록합니다. 이 옵션을 사용하게 되면, 닉네임변경이력을 남기도록 할 수 있습니다.';
$lang->about_member_profile_view = '관리자 회원목록 페이지에서 프로필 이미지를 볼 수 있는 옵션입니다. 회원목록을 보기 원치 않을 경우에는 아니요를 선택하세요.';
$lang->no_article = '글이 없습니다.';
$lang->find_account_question = '비밀번호 찾기 질문/답변';
$lang->find_account_answer = '비밀번호 찾기 답변';

View file

@ -186,7 +186,8 @@ class memberAdminController extends member
'password_hashing_auto_upgrade',
'password_change_invalidate_other_sessions',
'update_nickname_log',
'member_allow_fileupload'
'member_allow_fileupload',
'member_profile_view'
);
if(!array_key_exists($args->password_hashing_algorithm, Rhymix\Framework\Password::getSupportedAlgorithms()))

View file

@ -91,6 +91,7 @@ class memberAdminView extends member
foreach($output->data as $key => $member)
{
$output->data[$key]->group_list = $oMemberModel->getMemberGroups($member->member_srl,0);
$output->data[$key]->profile_image = $oMemberModel->getProfileImage($member->member_srl);
}
}
$config = $this->memberConfig;
@ -115,6 +116,7 @@ class memberAdminView extends member
Context::set('member_list', $output->data);
Context::set('usedIdentifiers', $usedIdentifiers);
Context::set('page_navigation', $output->page_navigation);
Context::set('profileImageConfig', $config->profile_image);
$security = new Security();
$security->encodeHTML('member_list..user_name', 'member_list..nick_name', 'member_list..group_list..');

View file

@ -2987,7 +2987,7 @@ class memberController extends member
function _clearMemberCache($member_srl, $site_srl = 0)
{
$member_srl = getNumberingPath($member_srl) . $member_srl;
$member_srl = intval($member_srl);
Rhymix\Framework\Cache::delete("member:member_info:$member_srl");
Rhymix\Framework\Cache::delete("member:member_groups:$member_srl:site:$site_srl");
if ($site_srl != 0)

View file

@ -74,6 +74,7 @@ class memberModel extends member
if(!$config->signature_editor_skin || $config->signature_editor_skin == 'default') $config->signature_editor_skin = 'ckeditor';
if(!$config->sel_editor_colorset) $config->sel_editor_colorset = 'moono-lisa';
if(!$config->member_allow_fileupload) $config->member_allow_fileupload = 'N';
if(!$config->member_profile_view) $config->member_profile_view = 'N';
if($config->redirect_mid)
{

View file

@ -491,9 +491,7 @@ class memberView extends member
{
if(Context::get('is_logged'))
{
Context::set('redirect_url', getNotEncodedUrl('act',''));
$this->setTemplatePath($this->module_path.'tpl');
$this->setTemplateFile('redirect.html');
$this->setRedirectUrl(getNotEncodedUrl('act',''));
return;
}

View file

@ -62,6 +62,7 @@ script, style
{
font-family: "맑은 고딕", "Apple SD Gothic Neo","나눔고딕",NanumGothic,'Nanum Gothic',Arial,Helvetica,sans-serif;
font-size: 14px;
text-align: justify;
margin: 8px 0px;
padding: 0 5px;
}

View file

@ -0,0 +1,2 @@
.profile_img {border-radius: 50%;border:1px solid #e0e0e0;padding:1px;width:40px;height:40px}
.no_profile {display:block;font-style:normal;border:1px solid #ddd;width:40px;height:40px;line-height:40px;font-size:16px;font-weight:bold;background:#fff;color:#666;border-radius:50%;text-align:center;}

View file

@ -20,6 +20,14 @@
<p class="x_help-block">{$lang->about_enable_confirm}</p>
</div>
</div>
<div class="x_control-group">
<div class="x_control-label">{$lang->cmd_member_profile_view}</div>
<div class="x_controls">
<label class="x_inline" for="member_profile_view_yes"><input type="radio" name="member_profile_view" id="member_profile_view_yes" value="Y" checked="checked"|cond="$config->member_profile_view == 'Y'" /> {$lang->cmd_yes}</label>
<label class="x_inline" for="member_profile_view_no"><input type="radio" name="member_profile_view" id="member_profile_view_no" value="N" checked="checked"|cond="$config->member_profile_view != 'Y'"/> {$lang->cmd_no}</label>
<p class="x_help-block">{$lang->about_member_profile_view}</p>
</div>
</div>
<div class="x_control-group">
<div class="x_control-label">{$lang->cmd_modify_nickname_log}</div>
<div class="x_controls">

View file

@ -1,3 +1,4 @@
<load target="css/member.css" />
<load target="js/member_admin_list.js" type="body" />
<script>
xe.lang.msg_select_user = '{$lang->msg_select_user}';
@ -28,6 +29,7 @@
</caption>
<thead>
<tr>
<th scope="col" class="nowr" cond="$profileImageConfig == 'Y' && $config->member_profile_view == 'Y'">{$lang->profile_image}</th>
<th scope="col" class="nowr">{$lang->email}</th>
<th scope="col" class="nowr" loop="$usedIdentifiers=>$name,$title">{$title}</th>
<th scope="col" class="nowr">{$lang->status}</th>
@ -43,6 +45,13 @@
<tbody>
<tr loop="$member_list=>$no,$member_info">
{@$member_info = get_object_vars($member_info)}
<td class="nowr" cond="$profileImageConfig == 'Y' && $config->member_profile_view == 'Y'">
<!--@if($member_info['profile_image'])-->
<img src="{$member_info['profile_image']->src}" class="profile_img" />
<!--@else-->
<i class="no_profile">?</i>
<!--@end-->
</td>
<td class="nowr">
<a href="#popup_menu_area" class="member_{$member_info['member_srl']}" title="Info">{getEncodeEmailAddress($member_info['email_address'])}</a>
</td>

View file

@ -1,3 +0,0 @@
<script>
location.href = "{$redirect_url}";
</script>

View file

@ -65,6 +65,7 @@ script, style
box-sizing:border-box;
font-family: "맑은 고딕", "Apple SD Gothic Neo","나눔고딕",NanumGothic,'Nanum Gothic',Arial,Helvetica,sans-serif;
font-size: 14px;
text-align: justify;
padding: 0 5px;
}

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 (strpos($domain, 'xn--') !== false)
{
$domain = Rhymix\Framework\URL::decodeIdna($domain);
}
if (strval($domain) === '')
{
return false;
}
$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

@ -2,36 +2,33 @@
class ncenterliteAdminModel extends ncenterlite
{
function getAdminNotifyList($member_srl=null, $page=1, $readed='N')
function getAdminNotifyList()
{
$oNcenterliteModel = getModel('ncenterlite');
$config = $oNcenterliteModel->getConfig();
global $lang;
$act = Context::get('act');
$output = $oNcenterliteModel->getNcenterliteAdminList();
$oMemberModel = getModel('member');
$list = $output->data;
foreach($list as $k => $v)
foreach($list as $key => $value)
{
$v->text = $oNcenterliteModel->getNotificationText($v);
$v->ago = $oNcenterliteModel->getAgo($v->regdate);
$v->url = getUrl('','act','procNcenterliteRedirect', 'notify', $v->notify, 'url', $v->target_url);
if($v->target_member_srl)
$value->text = $oNcenterliteModel->getNotificationText($value);
$value->ago = $oNcenterliteModel->getAgo($value->regdate);
$value->url = getUrl('','act','procNcenterliteRedirect', 'notify', $value->notify, 'url', $value->target_url);
if($value->target_member_srl)
{
$profileImage = $oMemberModel->getProfileImage($v->target_member_srl);
$v->profileImage = $profileImage->src;
$profileImage = $oMemberModel->getProfileImage($value->target_member_srl);
$value->profileImage = $profileImage->src;
}
$list[$k] = $v;
$list[$key] = $value;
$member_info = $oMemberModel->getMemberInfoByMemberSrl($value->member_srl);
$list[$key]->nick_name = $member_info->nick_name;
}
$output->data = $list;
return $output;
}
}

View file

@ -105,8 +105,6 @@ class ncenterliteAdminView extends ncenterlite
Context::set('page', $output->page);
Context::set('ncenterlite_list', $output->data);
Context::set('page_navigation', $output->page_navigation);
$this->setTemplateFile('ncenter_list');
}
function dispNcenterliteAdminTest()

View file

@ -31,13 +31,9 @@
</thead>
<tbody>
<!--@foreach($ncenterlite_list as $no => $val)-->
{@
$oMemberModel = getModel('member');
$member_info = $oMemberModel->getMemberInfoByMemberSrl($val->member_srl);
}
<tr>
<td>{$val->target_nick_name}</td>
<td cond="$member_info->member_srl">{$member_info->nick_name}</td> <td cond="!$member_info->member_srl">타겟없음</td>
<td cond="$val->member_srl">{$val->nick_name}</td>
<td><a href="{$val->target_url}">{$val->text}</a></td>
<td>
<span cond="$val->readed == 'Y'" style="color:#8582E6">{$lang->ncenterlite_read_y}</span>

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

View file

@ -56,6 +56,7 @@ div.simple_content
{
font-family: "맑은 고딕", "Apple SD Gothic Neo","나눔고딕",NanumGothic,'Nanum Gothic',Arial,Helvetica,sans-serif;
font-size: 14px;
text-align: justify;
padding: 3px;
}
section.simple_content