Merge branch 'develop' into pr/multidomain

This commit is contained in:
Kijin Sung 2017-03-01 21:50:51 +09:00
commit 210b6b4147
75 changed files with 2102 additions and 425 deletions

View file

@ -5,7 +5,7 @@ RewriteCond %{REQUEST_URI} !/modules/editor/(skins|styles)/
RewriteCond %{REQUEST_URI} !/common/manual/
RewriteRule ^(addons|common/tpl|files/ruleset|(m\.)?layouts|modules|plugins|themes|widgets|widgetstyles)/.+\.(html|xml)$ - [L,F]
RewriteRule ^files/(attach|config|cache/store)/.+\.php$ - [L,F]
RewriteRule ^files/env/ - [L,F]
RewriteRule ^files/(env|member_extra_info/(new_message_flags|point))/ - [L,F]
RewriteRule ^(\.git|\.ht|\.travis|codeception\.|composer\.|Gruntfile\.js|package\.json|CONTRIBUTING|COPYRIGHT|LICENSE|README) - [L,F]
# static files

View file

@ -246,7 +246,6 @@ class Context
$this->_setJSONRequestArgument();
$this->_setRequestArgument();
$this->_setUploadedArgument();
if(isset($_POST['_rx_ajax_compat']) && $_POST['_rx_ajax_compat'] === 'XMLRPC')
{
self::$_instance->request_method = 'XMLRPC';
@ -353,6 +352,11 @@ class Context
{
getController('member')->setSessionInfo();
}
else
{
self::set('is_logged', false);
self::set('logged_info', Rhymix\Framework\Session::getMemberInfo());
}
}
// set locations for javascript use

View file

@ -112,6 +112,7 @@ class DB
* @var string
*/
public $db_type;
public $db_version = '';
/**
* flag to decide if class prepared statements or not (when supported); can be changed from db.config.info

View file

@ -87,6 +87,7 @@ class DBCubrid extends DB
return;
}
$this->db_version = __CUBRID_VERSION__;
cubrid_set_autocommit($result, CUBRID_AUTOCOMMIT_TRUE);
return $result;

View file

@ -74,13 +74,13 @@ class DBMssql extends DB
$server_info = sqlsrv_server_info($result);
$server_version = $server_info['SQLServerVersion'];
$this->db_version = $server_version;
if ($server_version && version_compare($server_version, '10', '<'))
{
$this->setError(-1, 'Rhymix requires Microsoft SQL Server 2008 or later. Current version is ' . $server_version);
return;
}
return $result;
}

View file

@ -78,9 +78,10 @@ class DBMysql extends DB
}
// Error appears if the version is lower than 5.0.7
if(version_compare(mysql_get_server_info($result), '5.0.7', '<'))
$this->db_version = mysql_get_server_info($result);
if(version_compare($this->db_version, '5.0.7', '<'))
{
$this->setError(-1, 'Rhymix requires MySQL 5.0.7 or later. Current MySQL version is ' . mysql_get_server_info());
$this->setError(-1, 'Rhymix requires MySQL 5.0.7 or later. Current MySQL version is ' . $this->db_version);
return;
}

View file

@ -39,6 +39,7 @@ class DBMysqli extends DBMysql
return;
}
$this->charset = isset($connection['charset']) ? $connection['charset'] : 'utf8';
$this->db_version = $result->server_info;
mysqli_set_charset($result, $this->charset);
return $result;
}

View file

@ -174,7 +174,7 @@ class HTMLDisplayHandler
$output = preg_replace_callback('!<meta(.*?)(?:\/|)>!is', array($this, '_moveMetaToHeader'), $output);
// change a meta fine(widget often put the tag like <!--Meta:path--> to the content because of caching)
$output = preg_replace_callback('/<!--(#)?Meta:([a-z0-9\_\-\/\.\@\:]+)-->/is', array($this, '_transMeta'), $output);
$output = preg_replace_callback('/<!--(#)?Meta:([a-z0-9\_\-\/\.\@\:]+)(\?\$\_\_Context\-\>[a-z0-9\_\-\/\.\@\:]+)?-->/is', array($this, '_transMeta'), $output);
// handles a relative path generated by using the rewrite module
if(Context::isAllowRewrite())
@ -370,9 +370,17 @@ class HTMLDisplayHandler
{
return '';
}
Context::loadFile($matches[2]);
if($matches[3])
{
$vars = Context::get(str_replace('?$__Context->', '', $matches[3]));
Context::loadFile(array($matches[2], null, null, null, $vars));
}
else
{
Context::loadFile($matches[2]);
}
}
/**
* Add OpenGraph metadata tags.
*

View file

@ -14,8 +14,8 @@ class XMLDisplayHandler
$variables = $oModule->getVariables();
$xmlDoc = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<response>\n";
$xmlDoc .= sprintf("<error>%s</error>\n", $oModule->getError());
$xmlDoc .= sprintf("<message>%s</message>\n", str_replace(array('<', '>', '&'), array('&lt;', '&gt;', '&amp;'), $oModule->getMessage()));
$xmlDoc .= sprintf("<error>%s</error>\n", escape($oModule->getError()));
$xmlDoc .= sprintf("<message>%s</message>\n", escape($oModule->getMessage()));
$xmlDoc .= $this->_makeXmlDoc($variables);
@ -47,11 +47,11 @@ class XMLDisplayHandler
if(is_string($val))
{
$xmlDoc .= sprintf('<%s><![CDATA[%s]]></%s>%s', $key, $val, $key, "\n");
$xmlDoc .= sprintf('<%s>%s</%s>%s', $key, escape($val), $key, "\n");
}
else if(!is_array($val) && !is_object($val))
{
$xmlDoc .= sprintf('<%s>%s</%s>%s', $key, $val, $key, "\n");
$xmlDoc .= sprintf('<%s>%s</%s>%s', $key, escape($val), $key, "\n");
}
else
{

View file

@ -270,11 +270,9 @@ class FrontEndFileHandler extends Handler
{
return;
}
if ($default_font_config = Context::get('default_font_config'))
{
$file->vars = array_merge($file->vars, $default_font_config);
}
$default_font_config = Context::get('default_font_config') ?: getController('editor')->default_font_config;
$file->vars = array_merge($file->vars, $default_font_config);
if ($file->fileExtension === 'less')
{
$file->vars = array_map(function($str) {

View file

@ -554,26 +554,132 @@ class TemplateHandler
}
else
{
$escape_option = $this->config->autoescape !== null ? 'auto' : 'noescape';
if(preg_match('@^(.+)\\|((?:no)?escape)$@', $m[1], $mm))
{
$m[1] = $mm[1];
$escape_option = $mm[2];
}
elseif($m[1] === '$content' && preg_match('@/layouts/.+/layout\.html$@', $this->file))
// Get escape options.
if($m[1] === '$content' && preg_match('@/layouts/.+/layout\.html$@', $this->file))
{
$escape_option = 'noescape';
}
$m[1] = self::_replaceVar($m[1]);
switch($escape_option)
else
{
case 'auto':
return "<?php echo (\$this->config->autoescape === 'on' ? htmlspecialchars({$m[1]}, ENT_COMPAT, 'UTF-8', false) : {$m[1]}) ?>";
case 'escape':
return "<?php echo htmlspecialchars({$m[1]}, ENT_COMPAT, 'UTF-8', true) ?>";
case 'noescape':
return "<?php echo {$m[1]} ?>";
$escape_option = $this->config->autoescape !== null ? 'auto' : 'noescape';
}
// Separate filters from variable.
if (preg_match('@^(.+?)(?<![|\s])((?:\|[a-z]{2}[a-z0-9_]+(?::.+)?)+)$@', $m[1], $mm))
{
$m[1] = $mm[1];
$filters = array_map('trim', explode_with_escape('|', substr($mm[2], 1)));
}
else
{
$filters = array();
}
// Process the variable.
$var = self::_replaceVar($m[1]);
// Apply filters.
foreach ($filters as $filter)
{
// Separate filter option from the filter name.
if (preg_match('/^([a-z0-9_-]+):(.+)$/', $filter, $matches))
{
$filter = $matches[1];
$filter_option = $matches[2];
if (!self::_isVar($filter_option) && !preg_match("/^'.*'$/", $filter_option) && !preg_match('/^".*"$/', $filter_option))
{
$filter_option = "'" . escape_sqstr($filter_option) . "'";
}
else
{
$filter_option = self::_replaceVar($filter_option);
}
}
else
{
$filter_option = null;
}
// Apply each filter.
switch ($filter)
{
case 'auto':
case 'autoescape':
case 'escape':
case 'noescape':
$escape_option = $filter;
break;
case 'escapejs':
$var = "escape_js({$var})";
break;
case 'json':
$var = "json_encode({$var})";
break;
case 'strip':
case 'strip_tags':
$var = $filter_option ? "strip_tags({$var}, {$filter_option})" : "strip_tags({$var})";
break;
case 'trim':
$var = "trim({$var})";
break;
case 'urlencode':
$var = "rawurlencode({$var})";
break;
case 'lower':
$var = "strtolower({$var})";
break;
case 'upper':
$var = "strtoupper({$var})";
break;
case 'nl2br':
$var = $this->_applyEscapeOption($var, $escape_option);
$var = "nl2br({$var})";
$escape_option = 'noescape';
break;
case 'join':
$var = $filter_option ? "implode({$filter_option}, {$var})" : "implode(', ', {$var})";
break;
case 'date':
$var = $filter_option ? "getDisplayDateTime(ztime({$var}), {$filter_option})" : "getDisplayDateTime(ztime({$var}), 'Y-m-d H:i:s')";
break;
case 'format':
case 'number_format':
$var = $filter_option ? "number_format({$var}, {$filter_option})" : "number_format({$var})";
break;
case 'link':
$var = $this->_applyEscapeOption($var, $escape_option);
if ($filter_option)
{
$filter_option = $this->_applyEscapeOption($filter_option, $escape_option);
$var = "'<a href=\"' . {$filter_option} . '\">' . {$var} . '</a>'";
}
else
{
$var = "'<a href=\"' . {$var} . '\">' . {$var} . '</a>'";
}
$escape_option = 'noescape';
break;
default:
$filter = escape_sqstr($filter);
$var = "'INVALID FILTER ({$filter})'";
}
}
// Apply the escape option and return.
return '<?php echo ' . $this->_applyEscapeOption($var, $escape_option) . ' ?>';
}
}
@ -699,6 +805,7 @@ class TemplateHandler
else
{
$metafile = $attr['target'];
$metavars = ($attr['vars'] ? self::_replaceVar($attr['vars']) : '');
$result = "\$__tmp=array('{$attr['target']}','{$attr['media']}','{$attr['targetie']}','{$attr['index']}'," . ($attr['vars'] ? self::_replaceVar($attr['vars']) : 'array()') . ");Context::loadFile(\$__tmp);unset(\$__tmp);";
}
break;
@ -707,7 +814,15 @@ class TemplateHandler
$result = "<?php {$result} ?>";
if($metafile)
{
$result = "<!--#Meta:{$metafile}-->" . $result;
if(!$metavars)
{
$result = "<!--#Meta:{$metafile}-->" . $result;
}
else
{
// LESS or SCSS needs the variables to be substituted.
$result = "<!--#Meta:{$metafile}?{$metavars}-->" . $result;
}
}
return $result;
@ -773,6 +888,25 @@ class TemplateHandler
return $m[0];
}
/**
* Apply escape option to an expression.
*/
private function _applyEscapeOption($str, $escape_option)
{
switch($escape_option)
{
case 'escape':
return "htmlspecialchars({$str}, ENT_COMPAT, 'UTF-8', true)";
case 'noescape':
return "{$str}";
case 'autoescape':
return "htmlspecialchars({$str}, ENT_COMPAT, 'UTF-8', false)";
case 'auto':
default:
return "(\$this->config->autoescape === 'on' ? htmlspecialchars({$str}, ENT_COMPAT, 'UTF-8', false) : {$str})";
}
}
/**
* change relative path
* @param string $path
@ -810,9 +944,21 @@ class TemplateHandler
return $path;
}
/**
* Check if a string seems to contain a variable.
*
* @param string $str
* @return bool
*/
private static function _isVar($str)
{
return preg_match('@(?<!::|\\\\|(?<!eval\()\')\$([a-z_][a-z0-9_]*)@i', $str) ? true : false;
}
/**
* replace PHP variables of $ character
* Replace PHP variables of $ character
*
* @param string $php
* @return string $__Context->varname
*/

View file

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

View file

@ -516,11 +516,16 @@ class HTMLFilter
{
return $attr[0];
}
if (preg_match('/^(?:on|data-|(?:accesskey|class|contextmenu|contenteditable|dir|draggable|dropzone|editor_component|hidden|id|lang|name|style|tabindex|title)$)/', $attrkey))
if (preg_match('/^(?:on|data-|(?:accesskey|class|contextmenu|contenteditable|dir|draggable|dropzone|editor_component|hidden|id|lang|name|style|tabindex|title|rx_encoded_properties)$)/i', $attrkey))
{
return $attr[0];
}
$attrs[$attrkey] = htmlspecialchars_decode($attr[2]);
$attrval = utf8_normalize_spaces(utf8_clean(html_entity_decode($attr[2])));
if (preg_match('/^javascript:/i', preg_replace('/\s+/', '', $attrval)))
{
return '';
}
$attrs[$attrkey] = $attrval;
return '';
}, $match[0]);
if ($tag === 'img' && !preg_match('/\ssrc="/', $html))

View file

@ -1185,15 +1185,6 @@ class Session
public static function destroyCookiesFromConflictingDomains(array $cookies)
{
$override_domains = config('session.override_domains');
if ($override_domains === null && !Config::get('session.domain') && !ini_get('session.cookie_domain'))
{
list($lifetime, $refresh_interval, $domain, $path) = self::_getParams();
if (substr($domain, 0, 4) === 'www.')
{
$override_domains[] = $domain;
$override_domains[] = substr($domain, 4);
}
}
if (!$override_domains)
{
return false;

View file

@ -520,6 +520,11 @@ function ztime($str)
{
return null;
}
if (strlen($str) === 9 || (strlen($str) === 10 && $str <= 2147483647))
{
return intval($str);
}
$year = (int)substr($str, 0, 4);
$month = (int)substr($str, 4, 2) ?: 1;
$day = (int)substr($str, 6, 2) ?: 1;

View file

@ -403,7 +403,13 @@ body,table,input,textarea,select,button{font-family:나눔고딕,NanumGothic,NG,
<li id="UMAN_config_general_mobile_view">모바일 뷰 사용: 모바일 기기로 접속시 모바일 페이지를 보여줍니다.</li>
<li id="UMAN_config_general_admin_iplist">관리자 IP대역: 관리자 페이지로 접근가능한 IP대역을 지정합니다. 해당 IP에 대해서만 관리자 페이지로 접근이 가능하므로 주의 바랍니다. IP대역 정보는 /files/config/db.config.php 파일에 저장됩니다. 여러개의 항목은 줄을 바꾸어 입력하세요.</li>
<li id="UMAN_config_general_default_url">기본 URL: 여러 사이트를 운영할 때 기본 URL이 필요합니다. XE 설치 경로를 포함한 URL을 입력하세요. (예: http://도메인/설치경로)</li>
<li id="UMAN_config_general_ssl">SSL(Secure Socket Layer) 사용: '선택적으로'는 회원가입, 정보수정 등의 지정된 동작(action)에서 보안접속(SSL)을 사용합니다. '항상 사용'은 모든 서비스에 SSL을 사용 합니다. SSL 환경이 갖춰지지 않은 상태에서 SSL을 사용할 경우 접속이 되지 않을 수 있으니 주의 바랍니다.</li>
<li id="UMAN_config_general_ssl">SSL(Secure Socket Layer) 사용: '선택적으로'는 회원가입, 정보수정 등의 지정된 동작(action)에서 보안접속(SSL)을 사용합니다. '항상 사용'은 모든 서비스에 SSL을 사용 합니다. SSL 환경이 갖춰지지 않은 상태에서 SSL을 사용할 경우 접속이 되지 않을 수 있으니 주의 바랍니다.
<blockquote>
<strong>참고</strong>
<p>SSL 은 서버와 클라이언트 사이에 보안통신을 하기 위한 규격입니다. 페이지가 클라이언트에 전달되는 중에 제3자에 의해서 내용이 변조되는 것을 어렵게 하고, 제3자가 훔쳐보는 것을 어렵게 합니다. 인증서 종류에 따라 서버 운영 주체에 대한 인증이 포함되기도 합니다. SSL 사용을 위해서는 서버에 SSL 인증서가 설치되어 있어야 합니다.</p>
<p>SSL 을 사용하는 페이지에 SSL 전송을 지원하지 않는 일반 HTTP 컨텐츠가 포함되어 있을 경우, 페이지가 변조될 가능성이 있기 때문에 '안전하지 않은 페이지' 경고가 뜰 수 있습니다. SSL '선택적으로' 사용을 할 경우 SSL 연결이 아닌 페이지가 변조되어서 SSL 으로 전송되어야 할 정보가 SSL 이 아닌 일반 HTTP 전송 양식으로 전송되거나 제3자에 의해서 탈취될 가능성이 있습니다.</p>
</blockquote>
</li>
<li id="UMAN_config_general_sso">SSO 사용: 사용자가 한 번만 로그인하면 기본 사이트와 가상 사이트에 동시에 로그인이 됩니다. 가상 사이트를 사용할 때만 필요합니다.</li>
<li id="UMAN_config_general_db_session">인증 세션 DB 사용: 인증 시 사용되는 PHP 세션을 DB로 사용하는 기능입니다. 웹서버의 사용률이 낮은 사이트에서는 비활성화시 사이트 응답 속도가 향상될 수 있습니다. 단, 현재 접속자를 구할 수 없어 관련된 기능을 사용할 수 없게 됩니다.</li>
<li id="UMAN_config_general_qmail">Qmail 호환: Qmail등 CRLF를 줄 구분자로 인식하지 못하는 MTA에서 메일이 발송되도록 합니다.</li>

View file

@ -11,7 +11,7 @@ location ~ ^/rhymix/(addons|common/tpl|files/ruleset|(m\.)?layouts|modules|plugi
location ~ ^/rhymix/files/(attach|config|cache/store)/.+\.php$ {
return 403;
}
location ~ ^/rhymix/files/env/ {
location ~ ^/rhymix/files/(env|member_extra_info/(new_message_flags|point))/ {
return 403;
}
location ~ ^/rhymix/(\.git|\.ht|\.travis|codeception\.|composer\.|Gruntfile\.js|package\.json|CONTRIBUTING|COPYRIGHT|LICENSE|README) {

View file

@ -11,7 +11,7 @@ location ~ ^/(addons|common/tpl|files/ruleset|(m\.)?layouts|modules|plugins|them
location ~ ^/files/(attach|config|cache/store)/.+\.php$ {
return 403;
}
location ~ ^/files/env/ {
location ~ ^/files/(env|member_extra_info/(new_message_flags|point))/ {
return 403;
}
location ~ ^/(\.git|\.ht|\.travis|codeception\.|composer\.|Gruntfile\.js|package\.json|CONTRIBUTING|COPYRIGHT|LICENSE|README) {

View file

@ -48,7 +48,7 @@
{Context::addMetaTag("theme-color", $material_colors[$layout_info->primary_color])}
<!--// Load styles -->
{Context::set('layout_scss_value', array('grey' => $material_colors['grey'], 'primary_color' => $material_colors[$layout_info->primary_color], 'menu_position' => $layout_info->menu_position, 'content_color' => $layout_info->content_color))}
{@Context::set('layout_scss_value', array('grey' => $material_colors['grey'], 'primary_color' => $material_colors[$layout_info->primary_color], 'menu_position' => $layout_info->menu_position, 'content_color' => $layout_info->content_color))}
<load target="layout.scss" vars="$layout_scss_value" />
<load target="layout.js" />

View file

@ -67,8 +67,10 @@ $(function()
{
if($("#layout_menu_toggle").css( 'position' ) === 'fixed')
{
$("#layout_menu_toggle").fadeIn();
$("#layout_menu_toggle").css('display', '');
$("#layout_menu_toggle").fadeIn(400, function() {
$("#layout_menu_toggle").css('display', '')
});
;
}
}
previousScroll = currentScroll;

View file

@ -385,126 +385,6 @@ class adminAdminModel extends admin
$this->add('list', $list);
}
/**
* Parameter arrange for send to XE collect server
* @param string $type 'WORKING', 'INSTALL'
* @return string
*/
function getEnv($type = 'WORKING')
{
$skip = array(
'ext' => array('pcre', 'json', 'hash', 'dom', 'session', 'spl', 'standard', 'date', 'ctype', 'tokenizer', 'apache2handler', 'filter', 'posix', 'reflection', 'pdo')
, 'module' => array('addon', 'admin', 'autoinstall', 'comment', 'communication', 'counter', 'document', 'editor', 'file', 'importer', 'install', 'integration_search', 'layout', 'member', 'menu', 'message', 'module', 'opage', 'page', 'point', 'poll', 'rss', 'session', 'spamfilter', 'tag', 'trackback', 'trash', 'widget')
, 'addon' => array('autolink', 'blogapi', 'captcha', 'counter', 'member_communication', 'member_extra_info', 'mobile', 'openid_delegation_id', 'point_level_icon', 'resize_image')
, 'layout' => array('default')
, 'widget' => array('content', 'language_select', 'login_info','mcontent')
, 'widgetstyle' => array(),
);
$info = array();
$info['type'] = ($type != 'INSTALL' ? 'WORKING' : 'INSTALL');
$info['location'] = _XE_LOCATION_;
$info['package'] = _XE_PACKAGE_;
$info['host'] = $db_type->default_url ? $db_type->default_url : getFullUrl();
$info['app'] = $_SERVER['SERVER_SOFTWARE'];
$info['xe_version'] = __XE_VERSION__;
$info['php'] = phpversion();
$info['db_type'] = Context::getDBType();
$info['use_rewrite'] = config('use_rewrite') ? 'Y' : 'N';
$info['use_db_session'] = config('session.use_db') ? 'Y' : 'N';
$info['use_ssl'] = config('url.ssl') ?: 'none';
$info['phpext'] = '';
foreach(get_loaded_extensions() as $ext)
{
$ext = strtolower($ext);
if(in_array($ext, $skip['ext']))
{
continue;
}
$info['phpext'] .= '|' . $ext;
}
$info['phpext'] = substr($info['phpext'], 1);
$info['module'] = '';
$oModuleModel = getModel('module');
$module_list = $oModuleModel->getModuleList();
if($module_list) foreach($module_list as $module)
{
if(in_array($module->module, $skip['module']))
{
continue;
}
$info['module'] .= '|' . $module->module;
}
$info['module'] = substr($info['module'], 1);
$info['addon'] = '';
$oAddonAdminModel = getAdminModel('addon');
$addon_list = $oAddonAdminModel->getAddonList();
if($addon_list) foreach($addon_list as $addon)
{
if(in_array($addon->addon, $skip['addon']))
{
continue;
}
$info['addon'] .= '|' . $addon->addon;
}
$info['addon'] = substr($info['addon'], 1);
$info['layout'] = "";
$oLayoutModel = getModel('layout');
$layout_list = $oLayoutModel->getDownloadedLayoutList();
if($layout_list) foreach($layout_list as $layout)
{
if(in_array($layout->layout, $skip['layout']))
{
continue;
}
$info['layout'] .= '|' . $layout->layout;
}
$info['layout'] = substr($info['layout'], 1);
$info['widget'] = "";
$oWidgetModel = getModel('widget');
$widget_list = $oWidgetModel->getDownloadedWidgetList();
if($widget_list) foreach($widget_list as $widget)
{
if(in_array($widget->widget, $skip['widget']))
{
continue;
}
$info['widget'] .= '|' . $widget->widget;
}
$info['widget'] = substr($info['widget'], 1);
$info['widgetstyle'] = "";
$oWidgetModel = getModel('widget');
$widgetstyle_list = $oWidgetModel->getDownloadedWidgetStyleList();
if($widgetstyle_list) foreach($widgetstyle_list as $widgetstyle)
{
if(in_array($widgetstyle->widgetStyle, $skip['widgetstyle']))
{
continue;
}
$info['widgetstyle'] .= '|' . $widgetstyle->widgetStyle;
}
$info['widgetstyle'] = substr($info['widgetstyle'], 1);
$param = '';
foreach($info as $k => $v)
{
if($v)
{
$param .= sprintf('&%s=%s', $k, urlencode($v));
}
}
$param = substr($param, 1);
return $param;
}
/**
* Return theme info list by theme directory list
* @return array

View file

@ -729,93 +729,181 @@ class adminAdminView extends admin
function dispAdminViewServerEnv()
{
$info = array();
$oAdminModel = getAdminModel('admin');
$envInfo = $oAdminModel->getEnv();
$tmp = explode("&", $envInfo);
$arrInfo = array();
$xe_check_env = array();
foreach($tmp as $value) {
$arr = explode("=", $value);
if($arr[0]=="type") {
continue;
}elseif($arr[0]=="phpext" ) {
$str = urldecode($arr[1]);
$xe_check_env[$arr[0]]= str_replace("|", ", ", $str);
} elseif($arr[0]=="module" ) {
$str = urldecode($arr[1]);
$arrModuleName = explode("|", $str);
$oModuleModel = getModel("module");
$mInfo = array();
foreach($arrModuleName as $moduleName) {
$moduleInfo = $oModuleModel->getModuleInfoXml($moduleName);
$mInfo[] = "{$moduleName}({$moduleInfo->version})";
}
$xe_check_env[$arr[0]]= join(", ", $mInfo);
} elseif($arr[0]=="addon") {
$str = urldecode($arr[1]);
$arrAddonName = explode("|", $str);
$oAddonModel = getAdminModel("addon");
$mInfo = array();
foreach($arrAddonName as $addonName) {
$addonInfo = $oAddonModel->getAddonInfoXml($addonName);
$mInfo[] = "{$addonName}({$addonInfo->version})";
}
$xe_check_env[$arr[0]]= join(", ", $mInfo);
} elseif($arr[0]=="widget") {
$str = urldecode($arr[1]);
$arrWidgetName = explode("|", $str);
$oWidgetModel = getModel("widget");
$mInfo = array();
foreach($arrWidgetName as $widgetName) {
$widgetInfo = $oWidgetModel->getWidgetInfo($widgetName);
$mInfo[] = "{$widgetName}({$widgetInfo->version})";
}
$xe_check_env[$arr[0]]= join(", ", $mInfo);
} elseif($arr[0]=="widgetstyle") {
$str = urldecode($arr[1]);
$arrWidgetstyleName = explode("|", $str);
$oWidgetModel = getModel("widget");
$mInfo = array();
foreach($arrWidgetstyleName as $widgetstyleName) {
$widgetstyleInfo = $oWidgetModel->getWidgetStyleInfo($widgetstyleName);
$mInfo[] = "{$widgetstyleName}({$widgetstyleInfo->version})";
}
$xe_check_env[$arr[0]]= join(", ", $mInfo);
} elseif($arr[0]=="layout") {
$str = urldecode($arr[1]);
$arrLayoutName = explode("|", $str);
$oLayoutModel = getModel("layout");
$mInfo = array();
foreach($arrLayoutName as $layoutName) {
$layoutInfo = $oLayoutModel->getLayoutInfo($layoutName);
$mInfo[] = "{$layoutName}({$layoutInfo->version})";
}
$xe_check_env[$arr[0]]= join(", ", $mInfo);
} else {
$xe_check_env[$arr[0]] = urldecode($arr[1]);
$skip = array(
'phpext' => array('core', 'session', 'spl', 'standard', 'date', 'ctype', 'tokenizer', 'apache2handler', 'filter', 'reflection'),
'module' => array('addon', 'admin', 'autoinstall', 'comment', 'communication', 'counter', 'document', 'editor', 'file', 'importer', 'install', 'integration_search', 'layout', 'member', 'menu', 'message', 'module', 'opage', 'page', 'point', 'poll', 'rss', 'session', 'spamfilter', 'tag', 'trackback', 'trash', 'widget'),
'addon' => array('autolink', 'blogapi', 'captcha', 'counter', 'member_communication', 'member_extra_info', 'mobile', 'openid_delegation_id', 'point_level_icon', 'resize_image'),
'layout' => array('default'),
'widget' => array('content', 'language_select', 'login_info', 'mcontent'),
'widgetstyle' => array(),
);
// Basic environment
$info[] = '[Basic Information]';
$info['rhymix_version'] = RX_VERSION;
$info['date'] = date('Y-m-d H:i:s O');
$info['php'] = sprintf('%s (%d-bit)', phpversion(), PHP_INT_SIZE * 8);
$info['server'] = $_SERVER['SERVER_SOFTWARE'];
$info['os'] = sprintf('%s %s', php_uname('s'), php_uname('r'));
$info['baseurl'] = Context::getRequestUri();
$info['basedir'] = RX_BASEDIR;
$info['owner'] = sprintf('%s (%d:%d)', get_current_user(), getmyuid(), getmygid());
if (function_exists('posix_getpwuid') && function_exists('posix_geteuid') && $user = @posix_getpwuid(posix_geteuid()))
{
$info['user'] = sprintf('%s (%d:%d)', $user['name'], $user['uid'], $user['gid']);
}
else
{
$info['user'] = 'unknown';
}
$info['ssl'] = Context::get('site_module_info')->security ?: Context::getDbInfo()->use_ssl;
$info[] = '';
// System settings
$info[] = '[System Settings]';
$info['db.type'] = config('db.master.type');
$db_extra_info = array();
if (config('db.master.engine')) $db_extra_info[] = config('db.master.engine');
if (config('db.master.charset')) $db_extra_info[] = config('db.master.charset');
if (count($db_extra_info))
{
$info['db.type'] .= ' (' . implode(', ', $db_extra_info) . ')';
}
$info['db.version'] = DB::getInstance()->db_version;
if (preg_match('/\d+\.\d+\.\d+-MariaDB.*$/', $info['db.version'], $matches))
{
$info['db.version'] = $matches[0];
}
$info['cache.type'] = config('cache.type') ?: 'none';
$info['locale.default_lang'] = config('locale.default_lang');
$info['locale.default_timezone'] = config('locale.default_timezone');
$info['locale.internal_timezone'] = config('locale.internal_timezone');
$info['mobile.enabled'] = config('mobile.enabled') ? 'true' : 'false';
$info['mobile.tablets'] = config('mobile.tablets') ? 'true' : 'false';
$info['session.use_db'] = config('session.use_db') ? 'true' : 'false';
$info['session.use_keys'] = config('session.use_keys') ? 'true' : 'false';
$info['session.use_ssl'] = config('session.use_ssl') ? 'true' : 'false';
$info['view.concat_scripts'] = config('view.concat_scripts');
$info['view.minify_scripts'] = config('view.minify_scripts');
$info['use_rewrite'] = config('use_rewrite') ? 'true' : 'false';
$info['use_sso'] = config('use_sso') ? 'true' : 'false';
$info[] = '';
// PHP settings
$ini_info = ini_get_all();
$info[] = '[PHP Settings]';
$info['session.auto_start'] = $ini_info['session.auto_start']['local_value'];
$info['max_file_uploads'] = $ini_info['max_file_uploads']['local_value'];
$info['memory_limit'] = $ini_info['memory_limit']['local_value'];
$info['post_max_size'] = $ini_info['post_max_size']['local_value'];
$info['upload_max_filesize'] = $ini_info['upload_max_filesize']['local_value'];
$info['extensions'] = array();
foreach(get_loaded_extensions() as $ext)
{
$ext = strtolower($ext);
if (!in_array($ext, $skip['phpext']))
{
$info['extensions'][] = $ext;
}
}
$info['XE_Check_Evn'] = $xe_check_env;
$ini_info = ini_get_all();
$php_core = array();
$php_core['max_file_uploads'] = "{$ini_info['max_file_uploads']['local_value']}";
$php_core['post_max_size'] = "{$ini_info['post_max_size']['local_value']}";
$php_core['memory_limit'] = "{$ini_info['memory_limit']['local_value']}";
$info['PHP_Core'] = $php_core;
$str_info = "[Rhymix Server Environment " . date("Y-m-d") . "]\n\n";
$str_info .= "realpath : ".realpath('./')."\n";
foreach( $info as $key=>$value )
natcasesort($info['extensions']);
$info[] = '';
// Modules
$info[] = '[Modules]';
$info['module'] = array();
$oModuleModel = getModel('module');
$module_list = $oModuleModel->getModuleList() ?: array();
foreach ($module_list as $module)
{
if( is_array( $value ) == false ) {
$str_info .= "{$key} : {$value}\n";
} else {
//$str_info .= "\n{$key} \n";
foreach( $value as $key2=>$value2 )
$str_info .= "{$key2} : {$value2}\n";
if (!in_array($module->module, $skip['module']))
{
$moduleInfo = $oModuleModel->getModuleInfoXml($module->module);
$info['module'][] = sprintf('%s (%s)', $module->module, $moduleInfo->version);
}
}
natcasesort($info['module']);
$info[] = '';
// Addons
$info[] = '[Addons]';
$info['addon'] = array();
$oAddonAdminModel = getAdminModel('addon');
$addon_list = $oAddonAdminModel->getAddonList() ?: array();
foreach ($addon_list as $addon)
{
if (!in_array($addon->addon, $skip['addon']))
{
$addonInfo = $oAddonAdminModel->getAddonInfoXml($addon->addon);
$info['addon'][] = sprintf('%s (%s)', $addon->addon, $addonInfo->version);
}
}
natcasesort($info['addon']);
$info[] = '';
// Layouts
$info[] = '[Layouts]';
$info['layout'] = array();
$oLayoutModel = getModel('layout');
$layout_list = $oLayoutModel->getDownloadedLayoutList() ?: array();
foreach($layout_list as $layout)
{
if (!in_array($layout->layout, $skip['layout']))
{
$layoutInfo = $oLayoutModel->getLayoutInfo($layout->layout);
$info['layout'][] = sprintf('%s (%s)', $layout->layout, $layoutInfo->version);
}
}
natcasesort($info['layout']);
$info[] = '';
// Widgets
$info[] = '[Widgets]';
$info['widget'] = "";
$oWidgetModel = getModel('widget');
$widget_list = $oWidgetModel->getDownloadedWidgetList() ?: array();
foreach ($widget_list as $widget)
{
if (!in_array($widget->widget, $skip['widget']))
{
$widgetInfo = $oWidgetModel->getWidgetInfo($widget->widget);
$info['widget'][] = sprintf('%s (%s)', $widget->widget, $widgetInfo->version);
}
}
natcasesort($info['widget']);
$info[] = '';
// Widgetstyles
$info[] = '[Widgetstyles]';
$info['widgetstyle'] = array();
$oWidgetModel = getModel('widget');
$widgetstyle_list = $oWidgetModel->getDownloadedWidgetStyleList() ?: array();
foreach ($widgetstyle_list as $widgetstyle)
{
if (!in_array($widgetstyle->widgetStyle, $skip['widgetstyle']))
{
$widgetstyleInfo = $oWidgetModel->getWidgetStyleInfo($widgetstyle->widgetStyle);
$info['widgetstyle'][] = sprintf('%s (%s)', $widgetstyle->widgetStyle, $widgetstyleInfo->version);
}
}
natcasesort($info['widgetstyle']);
$info[] = '';
// Convert to string.
foreach ($info as $key => $value)
{
if (is_array($value))
{
$value = implode(', ', $value);
}
if (is_int($key) || ctype_digit($key))
{
$str_info .= "$value\n";
}
else
{
$str_info .= "$key : $value\n";
}
}

View file

@ -107,15 +107,15 @@ $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 HTTPS';
$lang->ssl_options['none'] = 'None';
$lang->ssl_options['optional'] = 'Optional';
$lang->ssl_options['always'] = 'Always';
$lang->ssl_options['optional'] = 'Optional (not recommended)';
$lang->ssl_options['always'] = 'Always (recommended)';
$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->about_use_ssl = 'Selecting \'Optional\' is to use SSL for the specified actions such as signing up and changing information. Selecting \'Always\' is to use SSL for all services. Please be careful because you may not be avaliable to access to the site if you use SSL where its environment is not set.';
$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->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->use_db_session = 'Store Session in DB';

View file

@ -35,8 +35,8 @@ $lang->welcome_to_xe = 'Esta es la página del Administrador de Rhymix';
$lang->about_lang_env = 'Para aplicar idioma seleccionado conjunto de los usuarios, como por defecto, haga clic en el botón [Guardar] el cambio.';
$lang->xe_license = 'Rhymix está bajo la Licencia de GPL';
$lang->ssl_options['none'] = 'Desactivar';
$lang->ssl_options['optional'] = 'Opcionalmente el';
$lang->ssl_options['always'] = 'Utilice siempre el';
$lang->ssl_options['optional'] = 'Opcionalmente el (no recomendado)';
$lang->ssl_options['always'] = 'Utilice siempre el (recomendado)';
$lang->about_use_ssl = 'Opcionalmente, la composición de suscripción / editar la información y el uso de SSL especificada en la acción es siempre el uso de SSL para todos los servicios que se utilizarán.';
$lang->server_ports = 'Especifique el puerto del servidor';
$lang->about_server_ports = '80 de HTTP, HTTPS al puerto 443 si se utiliza otro que se especifique lo contrario, el puerto va a necesitar.';

View file

@ -34,8 +34,8 @@ $lang->welcome_to_xe = 'Bienvenue sur la Page d\'Administration du Rhymix';
$lang->about_lang_env = 'Vous pouvez fixer la Langue Par Défaut par cliquer le boutton [Conserver] au-dessous. Les visiteurs vont voir tous les menus et les messages en langue que vous choisissez.';
$lang->xe_license = 'Rhymix s\'applique la GPL';
$lang->ssl_options['none'] = 'Ne Pas utiliser';
$lang->ssl_options['optional'] = 'Optionnel';
$lang->ssl_options['always'] = 'Toujours';
$lang->ssl_options['optional'] = 'Optionnel (non recommandé)';
$lang->ssl_options['always'] = 'Toujours (recommandé)';
$lang->about_use_ssl = 'Si l\'on choisit \'Optionnel\' , on utilise protocole SSL seulement dans quelques services comme inscription ou modification. Si l\'on choisit \'Toujours\', on utilise protocole SSL dans tous les services.';
$lang->server_ports = 'déclarer le port de serveur';
$lang->about_server_ports = 'Si l\'on ne veut pas utiliser le port 80 pour HTTP mais un autre port, ou bien, si l\'on ne veut pas utiliser le port 443 pour HTTPS mais un autre port, on doit déclarer les ports.';

View file

@ -70,8 +70,8 @@ $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->ssl_options['always'] = '常に使う';
$lang->ssl_options['optional'] = '部分的に使う(推奨しない)';
$lang->ssl_options['always'] = '常に使う(推奨)';
$lang->about_use_ssl = '「部分的に使う」は、「会員登録/会員情報変更」など指定されたアクションでSSLを使います。「常に使う」は、すべてのサービスにSSLを使います。SSLサーバ証明書がインストールされてない場合での使用はお控えください。サイトへのアクセスができない場合があります。';
$lang->server_ports = 'サーバーポート指定';
$lang->about_server_ports = '一般的に使われているHTTPの80、HTTPSの443以外の他のポートを使うには、ポートを指定してください。';

View file

@ -107,8 +107,8 @@ $lang->about_recompile_cache = '쓸모 없어졌거나 잘못된 캐시파일들
$lang->confirm_run = '오랜 시간이 걸릴 수 있습니다. 실행하시겠습니까?';
$lang->use_ssl = 'HTTPS 사용';
$lang->ssl_options['none'] = '사용 안함';
$lang->ssl_options['optional'] = '선택적 사용';
$lang->ssl_options['always'] = '항상 사용';
$lang->ssl_options['optional'] = '선택적으로 (권장하지 않음)';
$lang->ssl_options['always'] = '항상 사용 (권장)';
$lang->cmd_http_port = 'HTTP 포트';
$lang->cmd_https_port = 'HTTPS 포트';
$lang->cmd_index_module_srl = '메인 모듈';
@ -116,6 +116,7 @@ $lang->cmd_index_document_srl = '메인 문서';
$lang->cmd_default_language = '기본 언어';
$lang->cmd_new_domain = '새 도메인 추가';
$lang->about_use_ssl = '\'선택적으로\'는 회원가입, 정보수정 등의 지정된 동작(action)에서 보안접속(SSL)을 사용합니다. \'항상 사용\'은 모든 서비스에 SSL을 사용 합니다. SSL 환경이 갖춰지지 않은 상태에서 SSL을 사용할 경우 접속이 되지 않을 수 있으니 주의 바랍니다.';
$lang->about_use_ssl = '<p>\'선택적으로\'는 회원가입, 정보수정 등의 일부 동작에서만 선택적으로 보안접속(SSL)을 사용합니다.<br />\'항상 사용\'은 모든 서비스에 SSL을 사용 합니다.</p><p>SSL 환경이 갖춰지지 않은 상태에서 SSL을 사용할 경우, 접속이 되지 않을 수 있습니다. SSL 인증서가 정상적으로 설치되었는지 반드시 확인하고 설정하시기 바랍니다.</p>';
$lang->server_ports = '서버 포트 지정';
$lang->about_server_ports = 'HTTP는 80, HTTPS는 443 이 아닌, 다른 포트를 사용할 경우에 포트를 지정해 주어야 합니다.';
$lang->use_db_session = '인증 세션 DB 사용';
@ -273,8 +274,8 @@ $lang->admin_menu_setup = '관리자 메뉴 설정';
$lang->no_data = '등록된 데이터가 없습니다.';
$lang->cmd_admin_menu_reset = '관리자 메뉴 초기화';
$lang->confirm_reset_admin_menu = '관리자 메뉴를 초기화하시겠습니까?';
$lang->cmd_view_server_env = '서버정보출력';
$lang->server_env = '서버 정보';
$lang->cmd_view_server_env = '서버 환경 표시';
$lang->server_env = '서버 환경';
$lang->ftp_form_title = 'FTP 계정 정보 입력';
$lang->ftp = 'FTP';
$lang->ftp_host = 'FTP 서버 주소';

View file

@ -57,9 +57,9 @@ $lang->about_recompile_cache = '清空cache缓存?';
$lang->confirm_run = '此过程可能需要耗费一段时间,是否继续?';
$lang->use_ssl = '是否使用<abbr title="Secure Sockets Layer">SSL</abbr>安全连接?';
$lang->ssl_options['none'] = '不使用';
$lang->ssl_options['optional'] = '选择性';
$lang->ssl_options['always'] = '使用';
$lang->about_use_ssl = '选择性使用选项应用于新用户注册/修改用户信息等已指定的action当中使用选项应用于所有服务。 SSL 환경이 갖춰지지 않은 상태에서 SSL을 사용할 경우 접속이 되지 않을 수 있으니 주의 바랍니다.';
$lang->ssl_options['optional'] = '可选(不推荐)';
$lang->ssl_options['always'] = '始终(推荐)';
$lang->about_use_ssl = '<p>选择“可选”是为指定的操作例如注册和更改信息使用SSL。<br />选择“总是”是为Rhymix生成的整个页面使用SSL。</p><p>请小心! 在安装SSL证书之前您可能无法访问该网站。</p>';
$lang->server_ports = '指定服务器端口';
$lang->about_server_ports = '使用除HTTP80, HTTPS443以外的端口时必须得指定该服务器端口号。';
$lang->use_db_session = 'DB储存认证会话';

View file

@ -39,9 +39,9 @@ $lang->xe_license = 'Rhymix遵循 GPL協議';
$lang->yesterday = '昨天';
$lang->today = '今天';
$lang->ssl_options['none'] = '關閉';
$lang->ssl_options['optional'] = '手動';
$lang->ssl_options['always'] = '開啟';
$lang->about_use_ssl = '選擇手動時,在會員註冊或修改資料等動作時才會使用 SSL功能。 選擇開啟時,所有的服務都會使用 SSL功能。 ';
$lang->ssl_options['optional'] = '可選(不推薦)';
$lang->ssl_options['always'] = '始終(推薦)';
$lang->about_use_ssl = '<p>選擇“可選”是為指定的操作例如註冊和更改信息使用SSL。 <br />選擇“總是”是為Rhymix生成的整個頁面使用SSL。 </p><p>請小心在安裝SSL證書之前您可能無法訪問該網站。</p>';
$lang->server_ports = '主機埠口';
$lang->about_server_ports = 'HTTP、HTTPS預設埠口分別是『80』、『443』 如果想使用其他的埠口的話,請自行設定。';
$lang->use_db_session = 'DB session認證';

View file

@ -14,11 +14,12 @@
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->use_ssl} <a class="x_icon-question-sign" href="./common/manual/admin/index.html#UMAN_config_general_ssl" target="_blank">{$lang->help}</a></label>
<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">

View file

@ -2388,6 +2388,10 @@ html[lang="mn"] .x .g11n.active>[disabled],
height: 1px;
overflow: hidden;
}
.server_env {
white-space: pre-wrap;
font-family: Consolas, Courier New, monospace;
}
/* language specific styles */
/* English admin_en.css */

View file

@ -4,5 +4,5 @@
</div>
<section class="section">
<textarea style="width:96%;height:400px;">{$str_info}</textarea>
<div class="server_env">{$str_info}</div>
</section>

View file

@ -488,7 +488,7 @@ class autoinstallAdminView extends autoinstall
$security = new Security();
$security->encodeHTML('package.', 'package.depends..', 'item_list..');
$security->encodeHTML('search_target', 'search_keyword');
$security->encodeHTML('search_target', 'search_keyword', 'order_target', 'order_type');
}
/**

View file

@ -132,12 +132,12 @@
</tbody>
</table>
<div class="x_clearfix" style="margin-top:-10px">
{@
$urlInfo = parse_url(getRequestUriByServerEnviroment());
parse_str($urlInfo['query'], $param);
}
<form cond="$page_navigation" action="./" class="x_pagination x_pull-left" no-error-return-url="true">
<input loop="$param => $key, $val" cond="!in_array($key, array('mid', 'vid', 'act'))" type="hidden" name="{$key}" value="{$val}" />
<input type="hidden" name="module" value="admin" />
<input type="hidden" name="act" value="{$act}" />
<input type="hidden" name="order_target" value="{$order_target}" />
<input type="hidden" name="order_type" value="{$order_type}" />
<input type="hidden" name="search_keyword" value="{$search_keyword}" />
<ul>
<li class="x_disabled"|cond="!$page || $page == 1"><a href="{getUrl('page', '')}">&laquo; {$lang->first_page}</a></li>
<block cond="$page_navigation->first_page != 1 && $page_navigation->first_page + $page_navigation->page_count > $page_navigation->last_page - 1 && $page_navigation->page_count != $page_navigation->total_page">
@ -168,8 +168,11 @@
</ul>
</form>
<form action="./" class="search x_input-append x_pull-right" no-error-return-url="true" cond="$act!=dispAutoinstallAdminInstalledPackages">
<input loop="$param => $key, $val" cond="!in_array($key, array('mid', 'vid', 'act', 'page'))" type="hidden" name="{$key}" value="{$val}" />
<input type="search" name="search_keyword" required title="Search" value="{htmlspecialchars($search_keyword, ENT_COMPAT | ENT_HTML401, 'UTF-8', false)}">
<input type="hidden" name="module" value="admin" />
<input type="hidden" name="act" value="{$act}" />
<input type="hidden" name="order_target" value="{$order_target}" />
<input type="hidden" name="order_type" value="{$order_type}" />
<input type="search" name="search_keyword" required title="Search" value="{$search_keyword}" />
<button class="x_btn x_btn-inverse" type="submit">{$lang->cmd_search}</button>
<a href="{getUrl('page', '', 'search_keyword', '')}" class="x_btn">{$lang->cmd_cancel}</a>
</form>

View file

@ -133,7 +133,7 @@ class commentItem extends Object
{
if(Context::getSessionStatus())
{
$_SESSION['accessibled_comment'][$this->comment_srl] = TRUE;
$_SESSION['accessible'][$this->comment_srl] = $this->get('last_update');
}
}
@ -163,12 +163,12 @@ class commentItem extends Object
function isAccessible()
{
if($_SESSION['accessibled_comment'][$this->comment_srl])
if (isset($_SESSION['accessible'][$this->comment_srl]) && $_SESSION['accessible'][$this->comment_srl] === $this->get('last_update'))
{
return TRUE;
}
if($this->isGranted() || !$this->isSecret())
if (!$this->isSecret() || $this->isGranted())
{
$this->setAccessible();
return TRUE;
@ -176,7 +176,7 @@ class commentItem extends Object
$oDocumentModel = getModel('document');
$oDocument = $oDocumentModel->getDocument($this->get('document_srl'));
if($oDocument->isGranted())
if ($oDocument->isExists() && $oDocument->isGranted())
{
$this->setAccessible();
return TRUE;

View file

@ -16,7 +16,7 @@
<action name="procCommunicationSendMessage" type="controller" ruleset="sendMessage" standalone="true" />
<action name="procCommunicationStoreMessage" type="controller" standalone="true" />
<action name="procCommunicationDeleteMessage" type="controller" standalone="true" />
<action name="procCommunicationDeleteMessages" type="controller" method="GET|POST" standalone="true" />
<action name="procCommunicationDeleteMessages" type="controller" standalone="true" />
<action name="procCommunicationAddFriend" type="controller" ruleset="addFriend" standalone="true" />
<action name="procCommunicationMoveFriend" type="controller" ruleset="deleteCheckedFriend" standalone="true" />

View file

@ -38,7 +38,7 @@
<button class="btn" type="button" onclick="doDeleteMessage('{$message->message_srl}');">{$lang->cmd_delete}</button>
</div>
<form action="./" method="get" id="fo_message_list">
<form action="./" method="post" id="fo_message_list">
<input type="hidden" name="module" value="communication" />
<input type="hidden" name="act" value="procCommunicationDeleteMessages" />
<input type="hidden" name="message_type" value="{$message_type}" />

View file

@ -204,7 +204,55 @@ class documentItem extends Object
function isAccessible()
{
return $_SESSION['accessible'][$this->document_srl]==true?true:false;
if (isset($_SESSION['accessible'][$this->document_srl]) && $_SESSION['accessible'][$this->document_srl] === $this->get('last_update'))
{
return true;
}
if ($this->grant_cache === true)
{
$this->setAccessible();
return true;
}
$logged_info = Context::get('logged_info');
if ($logged_info->is_admin == 'Y')
{
$this->setAccessible();
return true;
}
$status = $this->get('status');
if (empty($status))
{
return false;
}
$configStatusList = getModel('document')->getStatusList();
if ($status == $configStatusList['public'] || $status == $configStatusList['publish'])
{
$this->setAccessible();
return true;
}
elseif ($status == $configStatusList['private'] || $status == $configStatusList['secret'])
{
if ($this->get('member_srl') == $logged_info->member_srl)
{
$this->setAccessible();
return true;
}
}
return false;
}
function setAccessible()
{
if(Context::getSessionStatus())
{
$_SESSION['accessible'][$this->document_srl] = $this->get('last_update');
}
}
function allowComment()
@ -444,7 +492,7 @@ class documentItem extends Object
$result = $this->_checkAccessibleFromStatus();
if($result && Context::getSessionStatus())
{
$_SESSION['accessible'][$this->document_srl] = true;
$this->setAccessible();
}
$content = $this->get('content');
@ -506,9 +554,9 @@ class documentItem extends Object
if($this->isSecret() && !$this->isGranted() && !$this->isAccessible()) return lang('msg_is_secret');
$result = $this->_checkAccessibleFromStatus();
if($result && Context::getSessionStatus())
if($result)
{
$_SESSION['accessible'][$this->document_srl] = true;
$this->setAccessible();
}
$content = $this->get('content');
@ -1252,23 +1300,7 @@ class documentItem extends Object
*/
function _checkAccessibleFromStatus()
{
$logged_info = Context::get('logged_info');
if($logged_info->is_admin == 'Y') return true;
$status = $this->get('status');
if(empty($status)) return false;
$oDocumentModel = getModel('document');
$configStatusList = $oDocumentModel->getStatusList();
if($status == $configStatusList['public'] || $status == $configStatusList['publish'])
return true;
else if($status == $configStatusList['private'] || $status == $configStatusList['secret'])
{
if($this->get('member_srl') == $logged_info->member_srl)
return true;
}
return false;
return $this->isAccessible();
}
function getTranslationLangCodes()

View file

@ -7,6 +7,17 @@
*/
class editor extends ModuleObject
{
/**
* @brief Default font config
*/
public $default_font_config = array(
'default_font_family' => 'inherit',
'default_font_size' => '13px',
'default_line_height' => '160%',
'default_paragraph_spacing' => '0',
'default_word_break' => 'normal',
);
/**
* @brief Implement if additional tasks are necessary when installing
*/

View file

@ -80,10 +80,30 @@ class editorController extends editor
*/
function procEditorInsertModuleConfig()
{
$module_srl = Context::get('target_module_srl');
// To configure many of modules at once
if(preg_match('/^([0-9,]+)$/',$module_srl)) $module_srl = explode(',',$module_srl);
else $module_srl = array($module_srl);
$target_module_srl = Context::get('target_module_srl');
$target_module_srl = array_map('trim', explode(',', $target_module_srl));
$logged_info = Context::get('logged_info');
$module_srl = array();
$oModuleModel = getModel('module');
foreach ($target_module_srl as $srl)
{
if (!$srl) continue;
$module_info = $oModuleModel->getModuleInfoByModuleSrl($srl);
if (!$module_info->module_srl)
{
return new Object(-1, 'msg_invalid_request');
}
$module_grant = $oModuleModel->getGrant($module_info, $logged_info);
if (!$module_grant->manager)
{
return new Object(-1, 'msg_not_permitted');
}
$module_srl[] = $srl;
}
$editor_config = new stdClass;
$editor_config->default_editor_settings = Context::get('default_editor_settings');
@ -134,10 +154,8 @@ class editorController extends editor
if($editor_config->enable_autosave != 'Y') $editor_config->enable_autosave = 'N';
$oModuleController = getController('module');
for($i=0;$i<count($module_srl);$i++)
foreach ($module_srl as $srl)
{
$srl = trim($module_srl[$i]);
if(!$srl) continue;
$oModuleController->insertModulePartConfig('editor',$srl,$editor_config);
}
@ -192,13 +210,13 @@ class editorController extends editor
}
}
Context::set('default_font_config', array(
'default_font_family' => $editor_config->content_font ?: 'inherit',
'default_font_size' => $editor_config->content_font_size ?: '13px',
'default_line_height' => $editor_config->content_line_height ?: '160%',
'default_paragraph_spacing' => $editor_config->content_paragraph_spacing ?: '0',
'default_word_break' => $editor_config->content_word_break ?: 'normal',
));
$default_font_config = $this->default_font_config;
if ($editor_config->content_font) $default_font_config['default_font_family'] = $editor_config->content_font;
if ($editor_config->content_font_size) $default_font_config['default_font_size'] = $editor_config->content_font_size;
if ($editor_config->content_line_height) $default_font_config['default_line_height'] = $editor_config->content_line_height;
if ($editor_config->content_paragraph_spacing) $default_font_config['default_paragraph_spacing'] = $editor_config->content_paragraph_spacing;
if ($editor_config->content_word_break) $default_font_config['default_word_break'] = $editor_config->content_word_break;
Context::set('default_font_config', $default_font_config);
/*
$buff = array();
@ -231,13 +249,7 @@ class editorController extends editor
}
else
{
Context::set('default_font_config', array(
'default_font_family' => 'inherit',
'default_font_size' => '13px',
'default_line_height' => '160%',
'default_paragraph_spacing' => '0',
'default_word_break' => 'normal',
));
Context::set('default_font_config', $this->default_font_config);
}
$content = $this->transComponent($content);

View file

@ -127,7 +127,7 @@ class fileAdminView extends file
}
}
if($file->upload_target_type)
if($file->upload_target_type && is_array(${$file->upload_target_type.'_srls'}))
{
if(!in_array($file->upload_target_srl, ${$file->upload_target_type.'_srls'}))
{

View file

@ -199,9 +199,22 @@ class memberController extends member
$document_srl = (int)Context::get('document_srl');
if(!$document_srl) return new Object(-1,'msg_invalid_request');
$oDocumentModel = getModel('document');
$oDocument = $oDocumentModel->getDocument($document_srl);
if ($oDocument->get('member_srl') != $logged_info->member_srl)
{
return new Object(-1,'msg_invalid_request');
}
$configStatusList = $oDocumentModel->getStatusList();
if ($oDocument->get('status') != $configStatusList['temp'])
{
return new Object(-1,'msg_invalid_request');
}
// Variables
$oDocumentController = getController('document');
$oDocumentController->deleteDocument($document_srl, true);
$oDocumentController->deleteDocument($document_srl);
}
/**
@ -1706,8 +1719,15 @@ class memberController extends member
$output->data = array_first($output->data);
}
// Hash the security key, but allow raw keys for a limited time.
$valid_security_keys = array(base64_encode(hash_hmac('sha256', $security_key, $autologin_key, true)));
if (time() < 1489503600)
{
$valid_security_keys[] = $security_key;
}
// Check the security key.
if ($output->data->security_key !== $security_key || !$output->data->member_srl)
if (!in_array($output->data->security_key, $valid_security_keys) || !$output->data->member_srl)
{
$args = new stdClass;
$args->autologin_key = $autologin_key;
@ -1719,7 +1739,7 @@ class memberController extends member
$new_security_key = Rhymix\Framework\Security::getRandom(24, 'alnum');
$args = new stdClass;
$args->autologin_key = $autologin_key;
$args->security_key = $new_security_key;
$args->security_key = base64_encode(hash_hmac('sha256', $security_key, $autologin_key, true));
$update_output = executeQuery('member.updateAutologin', $args);
if ($update_output->toBool())
{
@ -1892,7 +1912,7 @@ class memberController extends member
$random_key = Rhymix\Framework\Security::getRandom(48, 'alnum');
$autologin_args = new stdClass;
$autologin_args->autologin_key = substr($random_key, 0, 24);
$autologin_args->security_key = substr($random_key, 24, 24);
$autologin_args->security_key = base64_encode(hash_hmac('sha256', substr($random_key, 24, 24), $autologin_args->autologin_key, true));
$autologin_args->member_srl = $this->memberInfo->member_srl;
$autologin_args->user_agent = json_encode(Rhymix\Framework\UA::getBrowserInfo());
$autologin_output = executeQuery('member.insertAutologin', $autologin_args);

View file

@ -133,7 +133,7 @@ class memberModel extends member
$user_id = $member_info->user_id;
$user_name = $member_info->user_name;
ModuleHandler::triggerCall('member.getMemberMenu', 'before', $null);
ModuleHandler::triggerCall('member.getMemberMenu', 'before', new stdClass);
$oMemberController = getController('member');
// Display member information (Don't display to non-logged user)
@ -247,7 +247,7 @@ class memberModel extends member
/**
* @brief Return member information with user_id
*/
function getMemberInfoByUserID($user_id, $columnList = array())
function getMemberInfoByUserID($user_id)
{
if(!$user_id) return;
@ -292,28 +292,27 @@ class memberModel extends member
/**
* @brief Return member information with member_srl
*/
function getMemberInfoByMemberSrl($member_srl, $site_srl = 0, $columnList = array())
function getMemberInfoByMemberSrl($member_srl, $site_srl = 0)
{
if(!$member_srl) return new stdClass;
//columnList size zero... get full member info
if(!$GLOBALS['__member_info__'][$member_srl] || count($columnList) == 0)
if(!$GLOBALS['__member_info__'][$member_srl])
{
$cache_key = 'member:member_info:' . getNumberingPath($member_srl) . $member_srl;
$cache_key = sprintf('member:member_info:%d', $member_srl);
$GLOBALS['__member_info__'][$member_srl] = Rhymix\Framework\Cache::get($cache_key);
if(!$GLOBALS['__member_info__'][$member_srl])
{
$args = new stdClass();
$args->member_srl = $member_srl;
$output = executeQuery('member.getMemberInfoByMemberSrl', $args, $columnList);
$output = executeQuery('member.getMemberInfoByMemberSrl', $args);
if(!$output->data)
{
Rhymix\Framework\Cache::set($cache_key, new stdClass);
return new stdClass;
}
$this->arrangeMemberInfo($output->data, $site_srl);
Rhymix\Framework\Cache::set($cache_key, $GLOBALS['__member_info__'][$member_srl]);
$member_info = $this->arrangeMemberInfo($output->data, $site_srl);
Rhymix\Framework\Cache::set($cache_key, $member_info);
}
}
@ -456,7 +455,7 @@ class memberModel extends member
static $member_groups = array();
// cache controll
$cache_key = 'member:member_groups:' . getNumberingPath($member_srl) . $member_srl . ':site:' . $site_srl;
$cache_key = sprintf('member:member_groups:%d:site:%d', $member_srl, $site_srl);
$group_list = Rhymix\Framework\Cache::get($cache_key);
if(!$member_groups[$member_srl][$site_srl] || $force_reload)
@ -511,17 +510,18 @@ class memberModel extends member
/**
* @brief Get a default group
*/
function getDefaultGroup($site_srl = 0, $columnList = array())
function getDefaultGroup($site_srl = 0)
{
$default_group = Rhymix\Framework\Cache::get("member:default_group:$site_srl");
$cache_key = sprintf('member:default_group:site:%d', $site_srl);
$default_group = Rhymix\Framework\Cache::get($cache_key);
if(!$default_group)
{
$args = new stdClass();
$args->site_srl = $site_srl;
$output = executeQuery('member.getDefaultGroup', $args, $columnList);
$output = executeQuery('member.getDefaultGroup', $args);
$default_group = $output->data;
Rhymix\Framework\Cache::set("member:default_group:$site_srl", $default_group, 0, true);
Rhymix\Framework\Cache::set($cache_key, $default_group, 0, true);
}
return $default_group;
@ -532,6 +532,7 @@ class memberModel extends member
*/
function getAdminGroup($columnList = array())
{
$args = new stdClass;
$output = executeQuery('member.getAdminGroup', $args, $columnList);
return $output->data;
}

View file

@ -41,8 +41,8 @@
<block cond="$layout_info->extra_var->primary_color->type !== 'select' && $layout_info->extra_var->customized_primary_color->type !== 'colorpicker'">
{@$layout_info->primary_color = 'blue';}
</block>
<!--// Load styles -->
{@$colorset = $material_colors[$member_config->colorset];}
{@$skin_color = $material_colors[$layout_info->primary_color];}
<block cond="!$skin_color">
<!--@if(preg_match("/#([a-f0-9]{3}){1,2}/i", $layout_info->primary_color))-->
@ -54,7 +54,10 @@
{@$skin_color = '#f44336'}
<!--@endif-->
</block>
{Context::set('simple_less_value', array('red' => hexdec(substr($skin_color, 1, 2)), 'green' => hexdec(substr($skin_color, 3, 2)), 'blue' => hexdec(substr($skin_color, 5, 2)) ))}
<block cond="$colorset">
{@$skin_color = $colorset}
</block>
{@Context::set('simple_less_value', array('red' => hexdec(substr($skin_color, 1, 2)), 'green' => hexdec(substr($skin_color, 3, 2)), 'blue' => hexdec(substr($skin_color, 5, 2)) ))}
<load target="css/css.less" vars="$simple_less_value" />
<section class="rx_simple_member">
<div class="rx_simple_tab" cond="$is_logged && $logged_info->menu_list && (!$member_srl || $member_srl == $logged_info->member_srl)">

View file

@ -188,9 +188,6 @@ script, style
.rx_simple_member div.rx_simple_tab{
background: #ffffff;
margin: 5px 0;
height: 52px;
overflow: hidden;
white-space: nowrap;
box-shadow: 0 1px 2px rgba(0,0,0,0.16), 0 1px 2px rgba(0,0,0,0.23);
box-sizing: border-box;
}
@ -198,9 +195,7 @@ script, style
list-style: outside none none;
margin: 0;
display: block;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
padding: 6px 0px 100px;
padding: 6px 0;
text-decoration: none;
}

View file

@ -18,18 +18,18 @@
{lang('common.email_address')}
</block>
</label>
<input type="text" cond="$identifier == 'user_id'" name="user_id" id="uid" required title="{lang('common.user_id')}" />
<input type="email" cond="$identifier != 'user_id'" name="user_id" id="uid" required title="{lang('common.email_address')}" />
<input type="text" cond="$identifier == 'user_id'" autocapitalize="off" autocorrect="off" autofocus="autofocus" name="user_id" id="uid" required="required" tabindex="1" title="{lang('common.user_id')}" />
<input type="email" cond="$identifier != 'user_id'" autocapitalize="off" autocorrect="off" autofocus="autofocus" name="user_id" id="uid" required="required" tabindex="1" title="{lang('common.email_address')}" />
<label for="upw">{lang('common.password')}<a class="pos-right" href="{getUrl('act','dispMemberFindAccount')}">{lang('member.cmd_find_member_account')}</a></label>
<input type="password" name="password" id="upw" required title="{lang('common.password')}" />
<input type="password" name="password" id="upw" required="required" tabindex="2" title="{lang('common.password')}" />
<label for="keepid_opt">
<input type="checkbox" name="keep_signed" id="keepid_opt" value="Y" />
<input type="checkbox" name="keep_signed" id="keepid_opt" tabindex="3" value="Y" />
{lang('member.keep_signed')}
</label>
<div id="rx_member-warning" class="rx_member-notice">
{lang('member.about_keep_warning')}
</div>
<input type="submit" value="{lang('member.cmd_login')}" />
<input type="submit" tabindex="4" value="{lang('member.cmd_login')}" />
</div>
</form>
</section>

View file

@ -11,6 +11,94 @@
<name xml:lang="en">misol</name>
</author>
<colorset type="colorpicker">
<colorset>
<color name="theme">
<title xml:lang="ko">사이트 테마 색</title>
<title xml:lang="en">The site theme color</title>
</color>
<color name="red">
<title xml:lang="ko">붉은 색</title>
<title xml:lang="en">Red</title>
</color>
<color name="crimson">
<title xml:lang="ko">크림슨</title>
<title xml:lang="en">Crimson</title>
</color>
<color name="pink">
<title xml:lang="ko">분홍</title>
<title xml:lang="en">Pink</title>
</color>
<color name="purple">
<title xml:lang="ko">보라</title>
<title xml:lang="en">Purple</title>
</color>
<color name="deep-purple">
<title xml:lang="ko">진보라</title>
<title xml:lang="en">Deep Purple</title>
</color>
<color name="indigo">
<title xml:lang="ko">인디고</title>
<title xml:lang="en">Indigo</title>
</color>
<color name="deep-blue">
<title xml:lang="ko">짙은 파랑</title>
<title xml:lang="en">Deep Blue</title>
</color>
<color name="blue">
<title xml:lang="ko">파랑</title>
<title xml:lang="en">Blue</title>
</color>
<color name="light-blue">
<title xml:lang="ko">밝은 파랑</title>
<title xml:lang="en">Light Blue</title>
</color>
<color name="cyan">
<title xml:lang="ko">시안</title>
<title xml:lang="en">Cyan</title>
</color>
<color name="teal">
<title xml:lang="ko"></title>
<title xml:lang="en">Teal</title>
</color>
<color name="green">
<title xml:lang="ko">초록</title>
<title xml:lang="en">Green</title>
</color>
<color name="light-green">
<title xml:lang="ko">연한 초록</title>
<title xml:lang="en">Light Green</title>
</color>
<color name="lime">
<title xml:lang="ko">라임</title>
<title xml:lang="en">Lime</title>
</color>
<color name="yellow">
<title xml:lang="ko">노랑</title>
<title xml:lang="en">Yellow</title>
</color>
<color name="amber">
<title xml:lang="ko">앰버</title>
<title xml:lang="en">Amber</title>
</color>
<color name="orange">
<title xml:lang="ko">주황</title>
<title xml:lang="en">Orange</title>
</color>
<color name="deep-orange">
<title xml:lang="ko">진한 주황</title>
<title xml:lang="en">Deep Orange</title>
</color>
<color name="brown">
<title xml:lang="ko">갈색</title>
<title xml:lang="en">Brown</title>
</color>
<color name="grey">
<title xml:lang="ko">회색</title>
<title xml:lang="en">Grey</title>
</color>
<color name="blue-grey">
<title xml:lang="ko">푸른 회색</title>
<title xml:lang="en">Blue Grey</title>
</color>
</colorset>
</skin>

View file

@ -13,7 +13,7 @@ class messageMobile extends messageView
/**
* @brief Message output
**/
function dispMessage()
function dispMessage($detail = null)
{
// Get configurations (using module model object)
$oModuleModel = getModel('module');
@ -36,8 +36,8 @@ class messageMobile extends messageView
if(strncasecmp('https://', Context::getRequestUri(), 8) === 0) $ssl_mode = true;
}
Context::set('ssl_mode',$ssl_mode);
Context::set('system_message', nl2br($this->getMessage()));
Context::set('system_message_detail', nl2br($detail));
Context::set('act', 'procMemberLogin');
Context::set('mid', '');

View file

@ -1,5 +1,5 @@
<!--// responsible layout -->
{Context::addMetaTag("viewport", "width=device-width, user-scalable=yes")}
{@Context::addMetaTag("viewport", "width=device-width, user-scalable=yes")}
<!--// Check layout. If it is Simple World, select layout primary colors as a primary color of this skin -->
{@
@ -57,6 +57,6 @@
{@$skin_color = '#f44336'}
<!--@endif-->
</block>
{Context::set('simple_less_value', array('red' => hexdec(substr($skin_color, 1, 2)), 'green' => hexdec(substr($skin_color, 3, 2)), 'blue' => hexdec(substr($skin_color, 5, 2)) ))}
{@Context::set('simple_less_value', array('red' => hexdec(substr($skin_color, 1, 2)), 'green' => hexdec(substr($skin_color, 3, 2)), 'blue' => hexdec(substr($skin_color, 5, 2)) ))}
<load target="css/message.less" vars="$simple_less_value" />
<section class="rx_simple_message">

View file

@ -19,18 +19,18 @@
{lang('common.email_address')}
</block>
</label>
<input type="text" cond="$member_config->identifier == 'user_id'" name="user_id" id="uid" required title="{lang('common.user_id')}" />
<input type="email" cond="$member_config->identifier != 'user_id'" name="user_id" id="uid" required title="{lang('common.email_address')}" />
<input type="text" cond="$member_config->identifier == 'user_id'" autocapitalize="off" autocorrect="off" autofocus="autofocus" name="user_id" id="uid" required="required" tabindex="1" title="{lang('common.user_id')}" />
<input type="email" cond="$member_config->identifier != 'user_id'" autocapitalize="off" autocorrect="off" autofocus="autofocus" name="user_id" id="uid" required="required" tabindex="1" title="{lang('common.email_address')}" />
<label for="upw">{lang('common.password')}<a class="pos-right" href="{getUrl('act','dispMemberFindAccount')}">{lang('member.cmd_find_member_account')}</a></label>
<input type="password" name="password" id="upw" required title="{lang('common.password')}" />
<input type="password" name="password" id="upw" required="required" tabindex="2" title="{lang('common.password')}" />
<label for="keepid_opt">
<input type="checkbox" name="keep_signed" id="keepid_opt" value="Y" />
<input type="checkbox" name="keep_signed" id="keepid_opt" tabindex="3" value="Y" />
{lang('member.keep_signed')}
</label>
<div id="rx_message-warning" class="rx_message-notice">
{lang('member.about_keep_warning')}
</div>
<input type="submit" value="{$lang->cmd_login}" />
<input type="submit" tabindex="4" value="{lang('member.cmd_login')}" />
</div>
</form>
</section>

View file

@ -1,5 +1,5 @@
<!--// META -->
{Context::addHtmlHeader('<meta name="viewport" content="width=1240">')}
{@Context::addHtmlHeader('<meta name="viewport" content="width=1240">')}
<!--// CSS -->
<style>
.xedition-error {

View file

@ -449,7 +449,7 @@ class moduleModel extends module
if(!$output->toBool()) return $output;
$list = $output->data;
if(count($args) === 1 && isset($args->site_srl))
if(count($args) === 1 && isset($args->site_srl) && !$columnList)
{
Rhymix\Framework\Cache::set('site_and_module:module:mid_list_' . $args->site_srl, $list, 0, true);
}

View file

@ -11,14 +11,29 @@ class ncenterliteModel extends ncenterlite
{
$oModuleModel = getModel('module');
$config = $oModuleModel->getModuleConfig('ncenterlite');
if(!$config)
{
$config = new stdClass();
}
if(!$config->use)
if(!is_array($config->use))
{
$config->use = array('message' => 1);
if($config->use == 'Y')
{
$config->use = array(
'mention' => array('web' => 1),
'comment' => array('web' => 1),
'comment_comment' => array('web' => 1),
'vote' => array('web' => 1),
'message' => array('web' => 1),
'admin_content' => array('web' => 1),
);
}
else
{
$config->use = array('message' => array('web' => 1));
}
}
else
{
@ -32,8 +47,8 @@ class ncenterliteModel extends ncenterlite
getController('module')->insertModuleConfig('ncenterlite', $config);
}
}
if(!$config->display_use) $config->display_use = 'all';
if(!$config->mention_names) $config->mention_names = 'nick_name';
if(!$config->mention_suffixes)
{

View file

@ -64,7 +64,7 @@ class pageMobile extends pageView
if($mtime + $interval*60 > $_SERVER['REQUEST_TIME'])
{
$page_content = FileHandler::readFile($cache_file);
$page_content = preg_replace('@<\!--#Meta:@', '<!--Meta:', $page_content);
$page_content = str_replace('<!--#Meta:', '<!--Meta:', $page_content);
}
else
{

View file

@ -69,7 +69,7 @@ class pageView extends page
if($mtime + $this->interval*60 > $_SERVER['REQUEST_TIME'])
{
$page_content = FileHandler::readFile($this->cache_file);
$page_content = preg_replace('@<\!--#Meta:@', '<!--Meta:', $page_content);
$page_content = str_replace('<!--#Meta:', '<!--Meta:', $page_content);
}
else
{

View file

@ -75,9 +75,25 @@ class pointModel extends point
function getMembersPointInfo()
{
$member_srls = Context::get('member_srls');
$member_srls = explode(',',$member_srls);
if(count($member_srls)==0) return;
array_unique($member_srls);
$member_srls = array_unique(explode(',', $member_srls));
if (!count($member_srls))
{
return;
}
$logged_info = Context::get('logged_info');
if (!$logged_info->member_srl)
{
return;
}
if (!getModel('module')->isSiteAdmin($logged_info))
{
$member_srls = array_filter($member_srls, function($member_srl) use($logged_info) { return $member_srl == $logged_info->member_srl; });
if (!count($member_srls))
{
return;
}
}
$oModuleModel = getModel('module');
$config = $oModuleModel->getModuleConfig('point');

View file

@ -105,6 +105,7 @@ class widgetController extends widget
$oLayoutModel = getModel('layout');
$layout_info = $oLayoutModel->getLayout($module_srl);
if(!$layout_info || $layout_info->type != 'faceoff') $err++;
// Destination Information Wanted page module
$oModuleModel = getModel('module');
$columnList = array('module_srl', 'module');
@ -112,20 +113,19 @@ class widgetController extends widget
if(!$page_info->module_srl || $page_info->module != 'page') $err++;
if($err > 1) return new Object(-1,'msg_invalid_request');
// Check permissions
$is_logged = Context::get('is_logged');
$logged_info = Context::get('logged_info');
$user_group = $logged_info->group_list;
$is_admin = false;
if(count($user_group)&&count($page_info->grants['manager']))
if (!$logged_info->member_srl)
{
$manager_group = $page_info->grants['manager'];
foreach($user_group as $group_srl => $group_info)
{
if(in_array($group_srl, $manager_group)) $is_admin = true;
}
return new Object(-1,'msg_not_permitted');
}
if(!$is_admin && !$is_logged && $logged_info->is_admin != 'Y' && !$oModuleModel->isSiteAdmin($logged_info) && !(is_array($page_info->admin_id) && in_array($logged_info->user_id, $page_info->admin_id))) return new Object(-1,'msg_not_permitted');
$module_grant = $oModuleModel->getGrant($page_info, $logged_info);
if (!$module_grant->manager)
{
return new Object(-1,'msg_not_permitted');
}
// Enter post
$oDocumentModel = getModel('document');
$oDocumentController = getController('document');
@ -145,8 +145,10 @@ class widgetController extends widget
$output = $oDocumentController->insertDocument($obj);
$obj->document_srl = $output->get('document_srl');
}
// Stop when an error occurs
if(!$output->toBool()) return $output;
// Return results
$this->add('document_srl', $obj->document_srl);
}
@ -166,28 +168,28 @@ class widgetController extends widget
$oDocument = $oDocumentModel->getDocument($document_srl, true);
if(!$oDocument->isExists()) return new Object(-1,'msg_invalid_request');
$module_srl = $oDocument->get('module_srl');
// Destination Information Wanted page module
$oModuleModel = getModel('module');
$columnList = array('module_srl', 'module');
$page_info = $oModuleModel->getModuleInfoByModuleSrl($module_srl, $columnList);
if(!$page_info->module_srl || $page_info->module != 'page') return new Object(-1,'msg_invalid_request');
// Check permissions
$is_logged = Context::get('is_logged');
$logged_info = Context::get('logged_info');
$user_group = $logged_info->group_list;
$is_admin = false;
if(count($user_group)&&count($page_info->grants['manager']))
if (!$logged_info->member_srl)
{
$manager_group = $page_info->grants['manager'];
foreach($user_group as $group_srl => $group_info)
{
if(in_array($group_srl, $manager_group)) $is_admin = true;
}
return new Object(-1,'msg_not_permitted');
}
if(!$is_admin && !$is_logged && $logged_info->is_admin != 'Y' && !$oModuleModel->isSiteAdmin($logged_info) && !(is_array($page_info->admin_id) && in_array($logged_info->user_id, $page_info->admin_id))) return new Object(-1,'msg_not_permitted');
$module_grant = $oModuleModel->getGrant($page_info, $logged_info);
if (!$module_grant->manager)
{
return new Object(-1,'msg_not_permitted');
}
$output = $oDocumentAdminController->copyDocumentModule(array($oDocument->get('document_srl')), $oDocument->get('module_srl'),0);
if(!$output->toBool()) return $output;
// Return results
$copied_srls = $output->get('copied_srls');
$this->add('document_srl', $copied_srls[$oDocument->get('document_srl')]);
@ -207,25 +209,24 @@ class widgetController extends widget
$oDocument = $oDocumentModel->getDocument($document_srl, true);
if(!$oDocument->isExists()) return new Object();
$module_srl = $oDocument->get('module_srl');
// Destination Information Wanted page module
$oModuleModel = getModel('module');
$page_info = $oModuleModel->getModuleInfoByModuleSrl($module_srl);
if(!$page_info->module_srl || $page_info->module != 'page') return new Object(-1,'msg_invalid_request');
// Check permissions
$is_logged = Context::get('is_logged');
$logged_info = Context::get('logged_info');
$user_group = $logged_info->group_list;
$is_admin = false;
if(count($user_group)&&count($page_info->grants['manager']))
if (!$logged_info->member_srl)
{
$manager_group = $page_info->grants['manager'];
foreach($user_group as $group_srl => $group_info)
{
if(in_array($group_srl, $manager_group)) $is_admin = true;
}
return new Object(-1,'msg_not_permitted');
}
if(!$is_admin && !$is_logged && $logged_info->is_admin != 'Y' && !$oModuleModel->isSiteAdmin($logged_info) && !(is_array($page_info->admin_id) && in_array($logged_info->user_id, $page_info->admin_id))) return new Object(-1,'msg_not_permitted');
$module_grant = $oModuleModel->getGrant($page_info, $logged_info);
if (!$module_grant->manager)
{
return new Object(-1,'msg_not_permitted');
}
$output = $oDocumentController->deleteDocument($oDocument->get('document_srl'), true);
if(!$output->toBool()) return $output;
}
@ -395,7 +396,16 @@ class widgetController extends widget
$cache_data = Rhymix\Framework\Cache::get('widget_cache:' . $widget_sequence);
if ($cache_data)
{
return preg_replace('@<\!--#Meta:@', '<!--Meta:', $cache_data);
// Load the variables, need to load the LESS or SCSS files.
if(is_object($cache_data))
{
foreach ($cache_data->variables as $key => $value)
{
Context::set($key, $value);
}
$cache_data = $cache_data->content;
}
return str_replace('<!--#Meta:', '<!--Meta:', $cache_data);
}
$oWidget = $this->getWidgetObject($widget);
@ -404,9 +414,26 @@ class widgetController extends widget
$widget_content = $oWidget->proc($args);
$oModuleController = getController('module');
$oModuleController->replaceDefinedLangCode($widget_content);
Rhymix\Framework\Cache::set('widget_cache:' . $widget_sequence, $widget_content, $widget_cache, true);
// Keep the variables, need to load the LESS or SCSS files.
if(preg_match_all('/<!--#Meta:([a-z0-9\_\-\/\.\@\:]+)(\?\$\_\_Context\-\>[a-z0-9\_\-\/\.\@\:]+)?-->/is', $widget_content, $widget_var_matches, PREG_SET_ORDER))
{
$cache_content = new stdClass();
$cache_content->content = $widget_content;
$cache_content->variables = new stdClass();
foreach($widget_var_matches as $matches)
{
if($matches[2])
{
$key = str_replace('?$__Context->', '', $matches[2]);
$cache_content->variables->{$key} = Context::get($key);
}
}
Rhymix\Framework\Cache::set('widget_cache:' . $widget_sequence, $cache_content, $widget_cache, true);
}
return $widget_content;
}

View file

@ -300,6 +300,165 @@ class TemplateHandlerTest extends \Codeception\TestCase\Test
array(
'<span>{\RX_BASEDIR}</span>',
'?><span><?php echo \RX_BASEDIR ?></span>'
),
// Rhymix autoescape
array(
'<config autoescape="on" />{$foo}',
PHP_EOL . '$this->config->autoescape = \'on\';' . "\n" . 'echo ($this->config->autoescape === \'on\' ? htmlspecialchars($__Context->foo, ENT_COMPAT, \'UTF-8\', false) : $__Context->foo) ?>'
),
array(
'<config autoescape="off" />{$foo}',
PHP_EOL . '$this->config->autoescape = \'off\';' . "\n" . 'echo ($this->config->autoescape === \'on\' ? htmlspecialchars($__Context->foo, ENT_COMPAT, \'UTF-8\', false) : $__Context->foo) ?>'
),
array(
'<config autoescape="on" />{$foo|auto}',
PHP_EOL . '$this->config->autoescape = \'on\';' . "\n" . 'echo ($this->config->autoescape === \'on\' ? htmlspecialchars($__Context->foo, ENT_COMPAT, \'UTF-8\', false) : $__Context->foo) ?>'
),
array(
'<config autoescape="off" />{$foo|auto}',
PHP_EOL . '$this->config->autoescape = \'off\';' . "\n" . 'echo ($this->config->autoescape === \'on\' ? htmlspecialchars($__Context->foo, ENT_COMPAT, \'UTF-8\', false) : $__Context->foo) ?>'
),
array(
'<config autoescape="on" />{$foo|autoescape}',
PHP_EOL . '$this->config->autoescape = \'on\';' . "\n" . 'echo htmlspecialchars($__Context->foo, ENT_COMPAT, \'UTF-8\', false) ?>'
),
array(
'<config autoescape="off" />{$foo|autoescape}',
PHP_EOL . '$this->config->autoescape = \'off\';' . "\n" . 'echo htmlspecialchars($__Context->foo, ENT_COMPAT, \'UTF-8\', false) ?>'
),
array(
'<config autoescape="on" />{$foo|escape}',
PHP_EOL . '$this->config->autoescape = \'on\';' . "\n" . 'echo htmlspecialchars($__Context->foo, ENT_COMPAT, \'UTF-8\', true) ?>'
),
array(
'<config autoescape="off" />{$foo|escape}',
PHP_EOL . '$this->config->autoescape = \'off\';' . "\n" . 'echo htmlspecialchars($__Context->foo, ENT_COMPAT, \'UTF-8\', true) ?>'
),
array(
'<config autoescape="on" />{$foo|noescape}',
PHP_EOL . '$this->config->autoescape = \'on\';' . "\n" . 'echo $__Context->foo ?>'
),
array(
'<config autoescape="off" />{$foo|noescape}',
PHP_EOL . '$this->config->autoescape = \'off\';' . "\n" . 'echo $__Context->foo ?>'
),
// Rhymix filters
array(
'<p>{$foo|escape}</p>',
'?><p><?php echo htmlspecialchars($__Context->foo, ENT_COMPAT, \'UTF-8\', true) ?></p>'
),
array(
'<p>{$foo|json}</p>',
'?><p><?php echo json_encode($__Context->foo) ?></p>'
),
array(
'<p>{$foo|urlencode}</p>',
'?><p><?php echo rawurlencode($__Context->foo) ?></p>'
),
array(
'<p>{$foo|lower|nl2br}</p>',
'?><p><?php echo nl2br(strtolower($__Context->foo)) ?></p>'
),
array(
'<p>{$foo|join:/|upper}</p>',
'?><p><?php echo strtoupper(implode(\'/\', $__Context->foo)) ?></p>'
),
array(
'<p>{$foo|join:\||upper}</p>',
'?><p><?php echo strtoupper(implode(\'|\', $__Context->foo)) ?></p>'
),
array(
'<p>{$foo|join:$separator}</p>',
'?><p><?php echo implode($__Context->separator, $__Context->foo) ?></p>'
),
array(
'<p>{$foo|strip}</p>',
'?><p><?php echo strip_tags($__Context->foo) ?></p>'
),
array(
'<p>{$foo|strip:<br>}</p>',
'?><p><?php echo strip_tags($__Context->foo, \'<br>\') ?></p>'
),
array(
'<p>{$foo|strip:$mytags}</p>',
'?><p><?php echo strip_tags($__Context->foo, $__Context->mytags) ?></p>'
),
array(
'<p>{$foo|strip:myfunc($mytags)}</p>',
'?><p><?php echo strip_tags($__Context->foo, myfunc($__Context->mytags)) ?></p>'
),
array(
'<p>{$foo|trim|date}</p>',
'?><p><?php echo getDisplayDateTime(ztime(trim($__Context->foo)), \'Y-m-d H:i:s\') ?></p>'
),
array(
'<p>{$foo|date:His}</p>',
'?><p><?php echo getDisplayDateTime(ztime($__Context->foo), \'His\') ?></p>'
),
array(
'<p>{$foo|format:2}</p>',
'?><p><?php echo number_format($__Context->foo, \'2\') ?></p>'
),
array(
'<p>{$foo|date:His}</p>',
'?><p><?php echo getDisplayDateTime(ztime($__Context->foo), \'His\') ?></p>'
),
array(
'<p>{$foo|link}</p>',
'?><p><?php echo \'<a href="\' . $__Context->foo . \'">\' . $__Context->foo . \'</a>\' ?></p>'
),
array(
'<p>{$foo|link:http://www.rhymix.org}</p>',
'?><p><?php echo \'<a href="\' . \'http://www.rhymix.org\' . \'">\' . $__Context->foo . \'</a>\' ?></p>'
),
array(
'<p>{$foo|link:$url}</p>',
'?><p><?php echo \'<a href="\' . $__Context->url . \'">\' . $__Context->foo . \'</a>\' ?></p>'
),
array(
'<config autoescape="on" /><p>{$foo|link:$url}</p>',
PHP_EOL . '$this->config->autoescape = \'on\'; ?><p><?php echo \'<a href="\' . ($this->config->autoescape === \'on\' ? htmlspecialchars($__Context->url, ENT_COMPAT, \'UTF-8\', false) : $__Context->url) . \'">\' . ($this->config->autoescape === \'on\' ? htmlspecialchars($__Context->foo, ENT_COMPAT, \'UTF-8\', false) : $__Context->foo) . \'</a>\' ?></p>'
),
// Rhymix filters (reject malformed filters)
array(
'<p>{$foo|dafuq}</p>',
'?><p><?php echo \'INVALID FILTER (dafuq)\' ?></p>'
),
array(
'<p>{$foo|4}</p>',
'?><p><?php echo $__Context->foo|4 ?></p>'
),
array(
'<p>{$foo|a+7|lower}</p>',
'?><p><?php echo strtolower($__Context->foo|a+7) ?></p>'
),
array(
'<p>{$foo|Filter}</p>',
'?><p><?php echo $__Context->foo|Filter ?></p>'
),
array(
'<p>{$foo|filter++}</p>',
'?><p><?php echo $__Context->foo|filter++ ?></p>'
),
array(
'<p>{$foo|filter:}</p>',
'?><p><?php echo $__Context->foo|filter: ?></p>'
),
array(
'<p>{$foo|$bar}</p>',
'?><p><?php echo $__Context->foo|$__Context->bar ?></p>'
),
array(
'<p>{$foo||bar}</p>',
'?><p><?php echo $__Context->foo||bar ?></p>'
),
array(
'<p>{htmlspecialchars($var, ENT_COMPAT | ENT_HTML401)}</p>',
'?><p><?php echo htmlspecialchars($__Context->var, ENT_COMPAT | ENT_HTML401) ?></p>'
),
array(
'<p>{$foo | $bar}</p>',
'?><p><?php echo $__Context->foo | $__Context->bar ?></p>'
),
);

View file

@ -2,6 +2,22 @@
class DebugTest extends \Codeception\TestCase\Test
{
public $error_log;
public function _before()
{
$this->error_log = ini_get('error_log');
ini_set('error_log', '/dev/null');
}
public function _after()
{
if ($this->error_log)
{
ini_set('error_log', $this->error_log);
}
}
public function testDebugEntry()
{
$file = __FILE__;

View file

@ -253,7 +253,7 @@ class SessionTest extends \Codeception\TestCase\Test
$this->assertTrue(is_object($validity_info));
$this->assertTrue(isset($validity_info->invalid_before));
$validity_info->invalid_before = time() - 300;
$validity_info->invalid_before = time() - 3600;
$this->assertTrue(Rhymix\Framework\Session::setValidityInfo($member_srl, $validity_info));
$this->assertTrue(Rhymix\Framework\Session::isValid());
@ -261,7 +261,7 @@ class SessionTest extends \Codeception\TestCase\Test
$this->assertTrue(Rhymix\Framework\Session::setValidityInfo($member_srl, $validity_info));
$this->assertFalse(@Rhymix\Framework\Session::isValid());
$validity_info->invalid_before = time();
$validity_info->invalid_before = time() - 900;
$this->assertTrue(Rhymix\Framework\Session::setValidityInfo($member_srl, $validity_info));
$this->assertTrue(Rhymix\Framework\Session::isValid());

View file

@ -187,6 +187,14 @@ class HTMLFilterTest extends \Codeception\TestCase\Test
$target = '<img src="./foo/bar.jpg" alt="My Picture" style="width:320px;height:240px;" width="320" height="240" />';
$this->assertEquals($target, Rhymix\Framework\Filters\HTMLFilter::clean($source, false, false));
$source = '<img src="./foo/bar.jpg" alt="Picture" editor_component="component_name" editor_component_property="java Script:alert()" />';
$target = '<img src="./foo/bar.jpg" alt="Picture" editor_component="component_name" />';
$this->assertEquals($target, Rhymix\Framework\Filters\HTMLFilter::clean($source));
$source = '<img src="./foo/bar.jpg" alt="Picture" editor_component="component_name" rx_encoded_properties="alert()" />';
$target = '<img src="./foo/bar.jpg" alt="Picture" editor_component="component_name" />';
$this->assertEquals($target, Rhymix\Framework\Filters\HTMLFilter::clean($source));
$source = '<img somekey="somevalue" otherkey="othervalue" onkeypress="alert(\'xss\');" editor_component="component_name" />';
$target = '';
$this->assertEquals($target, Rhymix\Framework\Filters\HTMLFilter::clean($source, false, false));

View file

@ -204,6 +204,7 @@ class content extends WidgetHandler
$attribute = $oComment->getObjectVars();
$title = $oComment->getSummary($args->content_cut_size);
$thumbnail = $oComment->getThumbnail($args->thumbnail_width,$args->thumbnail_height,$args->thumbnail_type);
$thumbnail_x2 = $oComment->getThumbnail($args->thumbnail_width * 2, $args->thumbnail_height * 2, $args->thumbnail_type);
$url = sprintf("%s#comment_%s",getUrl('','document_srl',$oComment->get('document_srl')),$oComment->get('comment_srl'));
$attribute->mid = $args->mid_lists[$attribute->module_srl];
@ -214,6 +215,7 @@ class content extends WidgetHandler
$content_item->adds($attribute);
$content_item->setTitle($title);
$content_item->setThumbnail($thumbnail);
$content_item->setThumbnail($thumbnail_x2, 2);
$content_item->setLink($url);
$content_item->setDomain($domain);
$content_item->add('mid', $args->mid_lists[$attribute->module_srl]);
@ -283,6 +285,7 @@ class content extends WidgetHandler
$module_srl = $oDocument->get('module_srl');
$category_srl = $oDocument->get('category_srl');
$thumbnail = $oDocument->getThumbnail($args->thumbnail_width,$args->thumbnail_height,$args->thumbnail_type);
$thumbnail_x2 = $oDocument->getThumbnail($args->thumbnail_width * 2,$args->thumbnail_height * 2,$args->thumbnail_type);
$content_item = new contentItem( $args->module_srls_info[$module_srl]->browser_title );
$content_item->adds($oDocument->getObjectVars());
@ -293,6 +296,7 @@ class content extends WidgetHandler
$content_item->setContent($oDocument->getSummary($args->content_cut_size));
$content_item->setLink( getSiteUrl($domain,'','document_srl',$document_srl) );
$content_item->setThumbnail($thumbnail);
$content_item->setThumbnail($thumbnail_x2, 2);
$content_item->setExtraImages($oDocument->printExtraImages($args->duration_new * 60 * 60));
$content_item->add('mid', $args->mid_lists[$module_srl]);
if($first_thumbnail_idx==-1 && $thumbnail) $first_thumbnail_idx = $i;
@ -347,6 +351,7 @@ class content extends WidgetHandler
$content = $oDocument->getSummary($args->content_cut_size);
$url = sprintf("%s#%s",$oDocument->getPermanentUrl() ,$oDocument->getCommentCount());
$thumbnail = $oDocument->getThumbnail($args->thumbnail_width,$args->thumbnail_height,$args->thumbnail_type);
$thumbnail_x2 = $oDocument->getThumbnail($args->thumbnail_width * 2, $args->thumbnail_height * 2, $args->thumbnail_type);
$extra_images = $oDocument->printExtraImages($args->duration_new);
$content_item = new contentItem($browser_title);
@ -355,6 +360,7 @@ class content extends WidgetHandler
$content_item->setContent($content);
$content_item->setLink($url);
$content_item->setThumbnail($thumbnail);
$content_item->setThumbnail($thumbnail_x2, 2);
$content_item->setExtraImages($extra_images);
$content_item->setDomain($domain);
$content_item->add('mid', $args->mid_lists[$attribute->module_srl]);
@ -825,9 +831,14 @@ class contentItem extends Object
{
$this->add('title', escape(strip_tags($title), false));
}
function setThumbnail($thumbnail)
function setThumbnail($thumbnail, $source_size = 1)
{
$this->add('thumbnail', $thumbnail);
if($source_size === 1)
{
$this->add('thumbnail', $thumbnail);
} else {
$this->add('thumbnail_x' . $source_size, $thumbnail);
}
}
function setContent($content)
{
@ -931,9 +942,16 @@ class contentItem extends Object
{
return $this->has_first_thumbnail_idx;
}
function getThumbnail()
function getThumbnail($source_size = 1)
{
return $this->get('thumbnail');
if(intval($source_size) === 1)
{
return $this->get('thumbnail');
}
else
{
return $this->get('thumbnail_x' . intval($source_size));
}
}
function getMemberSrl()
{

View file

@ -0,0 +1,38 @@
{@
$misol_contents = array();
$misol_contents_count = 0;
}
{$widget_info->content_type}
<!--@if($widget_info->page_count > 1)-->
{@$misol_contents_count = $widget_info->list_count * $widget_info->page_count}
<!--@else-->
{@$misol_contents_count = $widget_info->list_count}
<!--@end-->
<!--@foreach($widget_info->tab as $module_srl => $tab)-->
{@ $contents_key = ''; }
<block loop="$tab->content_items => $key, $item">
{@
$contents_key = intval(preg_replace("/[^0-9]*/s", '', $item->getLink()));
$misol_contents[$contents_key] = $item;
}
</block>
<!--@end-->
{@ krsort($misol_contents);}
{@$i = 0;}
<!--@foreach($misol_contents as $key => $val)-->
{@$i = $i + 1;}
<!--@if($i > $misol_contents_count)-->
{@ unset($misol_contents[$key])}
<!--@end-->
<!--@end-->
{@
$tab = new stdClass();
$tab->content_items = $misol_contents;
$tab->title = $lang->all;
$tab->url = getUrl('mid',Context::get('mid'));
$tab->tab_type = 'all';
}
{@ array_unshift($widget_info->tab, $tab) }
<!--#include("./_tab_top.html")-->

View file

@ -0,0 +1,15 @@
<h1 class="misolTop" cond="count($widget_info->modules_info) === 1">
{@$soo_module_info = current($widget_info->modules_info);}
<a href="{getUrl('','mid',$soo_module_info->mid)}" target="_blank"|cond="$widget_info->new_window" class="misol_top_a">{$soo_module_info->browser_title}</a>
</h1>
<!--@if($widget_info->list_type == "gallery")-->
<!--#include("./gallery.html")-->
<!--@elseif($widget_info->list_type == "image_title")-->
<!--#include("./image_title.html")-->
<!--@elseif($widget_info->list_type == "image_title_content")-->
<!--#include("./image_title_content.html")-->
<!--@elseif($widget_info->list_type == "title_content")-->
<!--#include("./title_content.html")-->
<!--@else-->
<!--#include("./normal.html")-->
<!--@end-->

View file

@ -0,0 +1,18 @@
<div class="misolTab">
<ul class="simple_contentTabA widgetTab">
{@$i=0}
<li loop="$widget_info->tab => $module_srl, $tab" class="active"|cond="$i==0"><a href="{$tab->url}" onmouseover="content_widget_tab_show(jQuery(this),jQuery(this).parents('div.misolTab').next('dl.simple_columns'),{$i})" onclick="this.onmouseover();return false;"><span>{$tab->title}</span></a>{@$i++}</li>
</ul>
</div>
<dl class="simple_columns">
{@$i=0}
<!--@foreach($widget_info->tab as $module_srl => $tab)-->
<dt>{$tab->title}</dt>
<dd <!--@if($i==0)--> class="open"<!--@end-->>
{@$widget_info->content_items = $tab->content_items}
<!--#include("_tab_none.html")-->
</dd>
{@$i++}
<!--@end-->
</dl>

View file

@ -0,0 +1,79 @@
<load target="./js/content_widget.js" cond="$widget_info->page_count || count($widget_info->tab)" />
<!--// Check layout. If it is Simple World, select layout primary colors as a primary color of this skin -->
{@$layout_info = Context::get('layout_info')}
{@
$material_colors = array(
'red' => '#f44336',
'crimson' => '#aa0000',
'pink' => '#e91e63',
'purple' => '#9c27b0',
'deep-purple' => '#673ab7',
'indigo' => '#3f51b5',
'deep-blue' => '#00397f',
'blue' => '#2196f3',
'light-blue' => '#03a9f4',
'cyan' => '#00bcd4',
'teal' => '#009688',
'green' => '#4caf50',
'light-green' => '#8bc34a',
'lime' => '#cddc39',
'yellow' => '#ffeb3b',
'amber' => '#ffc107',
'orange' => '#ff9800',
'deep-orange' => '#ff5722',
'brown' => '#795548',
'grey' => '#9e9e9e',
'blue-grey' => '#607d8b',
'black' => '#000000',
'white' => '#ffffff',
'customized' => $layout_info->customized_primary_color,
);
}
<block cond="$layout_info->extra_var->primary_color->type === 'select' || $layout_info->extra_var->customized_primary_color->type === 'colorpicker'">
{@
if(!$layout_info->primary_color && $layout_info->customized_primary_color)
$layout_info->primary_color = 'customized';
if(!$layout_info->primary_color)
$layout_info->primary_color = 'red';
if(!$layout_info->customized_primary_color)
$layout_info->customized_primary_color = '#f44336';
}
</block>
<block cond="$layout_info->extra_var->primary_color->type !== 'select' && $layout_info->extra_var->customized_primary_color->type !== 'colorpicker'">
{@$layout_info->primary_color = 'blue';}
</block>
<!--// Load styles -->
{@$colorset = $material_colors[$colorset];}
{@$skin_color = $material_colors[$layout_info->primary_color];}
<block cond="!$skin_color">
<!--@if(preg_match("/#([a-f0-9]{3}){1,2}/i", $layout_info->primary_color))-->
{@$skin_color = $layout_info->primary_color}
<!--@if(strlen($layout_info->primary_color) === 4)-->
{@$skin_color = $layout_info->primary_color[1].$layout_info->primary_color[1].$layout_info->primary_color[2].$layout_info->primary_color[2].$layout_info->primary_color[3].$layout_info->primary_color[3]}
<!--@endif-->
<!--@else-->
{@$skin_color = '#f44336'}
<!--@endif-->
</block>
<block cond="$colorset">
{@$skin_color = $colorset}
</block>
{@Context::set('less_color', array('red' => hexdec(substr($skin_color, 1, 2)), 'green' => hexdec(substr($skin_color, 3, 2)), 'blue' => hexdec(substr($skin_color, 5, 2)), 'thumbnail_height' => intval($widget_info->thumbnail_height), 'thumbnail_width' => intval($widget_info->thumbnail_width)))}
<load target="css/css.less" vars="$less_color" />
<div class="widgetContainer">
<div class="simple_content">
<section class="simple_content">
<!--@if($widget_info->tab_type == "tab_left" && count($widget_info->tab) > 1)-->
<!--#include("./_tab_left.html")-->
<!--@elseif($widget_info->tab_type == "tab_top" && count($widget_info->tab) > 1)-->
<!--#include("./_tab_top.html")-->
<!--@else-->
<!--@if($widget_info->tab_type == "tab_left" || $widget_info->tab_type == "tab_top")-->
{@$widget_info->content_items = $widget_info->tab[0]->content_items}
<!--@end-->
<!--#include("./_tab_none.html")-->
<!--@end-->
</section>
</div>
</div>

View file

@ -0,0 +1,274 @@
@charset "UTF-8";
/* sample code for css.less by misol */
div.simple_content {
font-family: "맑은 고딕", "Apple SD Gothic Neo", "나눔고딕", NanumGothic, 'Nanum Gothic', Arial, Helvetica, sans-serif;
font-size: 14px;
padding: 3px;
}
section.simple_content {
font-size: 14px;
background-color: #fff;
box-shadow: 0 1px 2px rgba(0,0,0,0.16), 0 1px 2px rgba(0,0,0,0.23);
}
.simple_content ul.simple_content_list {
margin: 0;
padding: 0 8px;
}
.simple_content .simple_content_list .cont_a {
color: #222;
display: block;
letter-spacing: -1px;
line-height: 18px;
overflow: hidden;
padding: 0.667em 3px;
text-overflow: ellipsis;
white-space: nowrap;
text-decoration: none;
}
.simple_content .simple_content_list .cont_a:hover {
color: #2196f3;
}
.simple_content .cont_a {
color: #222;
display: block;
letter-spacing: -1px;
overflow: hidden;
padding: 0.467em 0;
text-overflow: ellipsis;
white-space: nowrap;
text-decoration: none;
}
.simple_content .content_image {
display: inline-block;
float: left;
position: relative;
margin-right: 5px;
}
.simple_content .content_basic {
position: relative;
display: inline-block;
max-width: 100%;
vertical-align: middle;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.simple_content .content_category {
color: #2196f3;
font-family: HelveticaNeue-Light, AppleSDGothicNeo-Light, sans-serif-light, sans-serif;
margin: 0 7px 0 3px;
}
.simple_content .simple_gallery_item .content_category {
position: absolute;
top: 0;
right: 0;
background: #fff;
margin: 0;
}
.simple_content .content_nickname,
.simple_content .content_recnt {
color: #616161;
font-size: 12px;
margin: 0 3px 0 7px;
overflow: hidden;
}
.simple_content ul.simple_contentTabA {
list-style: outside none none;
padding: 0;
margin: 0;
}
.simple_content .simple_content_list li {
position: relative;
border-top: 1px solid #e0e0e0;
overflow: hidden;
padding: 0;
}
.simple_content .simple_content_list li:first-child,
.simple_content.simple_content_list li.first-child {
border-top: 0 none;
}
.simple_content .content_recnt {
position: absolute;
height: 18px;
width: 44px;
text-align: right;
font-size: 13px;
margin: 3px;
top: 0.6em;
right: 15px;
}
.simple_content .simple_content_list li.content_reext .cont_a {
padding-right: 70px;
}
.simple_content h1.misolTop {
border-bottom: 1px solid #e0e0e0;
font-weight: 400;
margin: 0;
position: relative;
}
.simple_content h1.misolTop .misol_top_a {
display: block;
margin: 0;
padding: 10px;
text-decoration: none;
}
.simple_content div.simple_gallery {
overflow: hidden;
width: 100%;
height: 137px;
white-space: nowrap;
box-sizing: border-box;
}
div.simple_gallery ul.simple_gallery {
display: block;
list-style: outside none none;
padding: 6px 0px 100px;
margin: 0;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
div.simple_gallery ul.simple_gallery > li {
position: relative;
display: inline-block;
width: 100px;
padding: 7px;
}
div.simple_gallery ul.simple_gallery>li .cont_a {
position: relative;
padding: 0;
width: 100px;
}
div.simple_gallery ul.simple_gallery>li .gallery_text>span {
display: block;
width: 100px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
div.simple_gallery ul.simple_gallery>li .gallery_text>span.content_nickname {
margin: 0;
text-align: right;
}
div.simple_gallery ul.simple_gallery>li .cont_a:hover {
color: #2196f3;
}
.simple_gallery_item .fake_img,
.simple_content_list .content_image {
display: inline-block;
box-sizing: border-box;
background: #fff;
border: 1px solid #e0e0e0;
color: #000;
width: 100px;
height: 75px;
vertical-align: middle;
text-align: center;
line-height: 75px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.simple_content div.misolTab {
overflow: hidden;
width: 100%;
height: 52px;
white-space: nowrap;
border-bottom: 1px solid #e0e0e0;
box-sizing: border-box;
}
.simple_content ul.simple_contentTabA {
display: block;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
padding: 6px 0px 100px;
text-decoration: none;
}
.simple_content ul.simple_contentTabA>li {
display: inline-block;
height: 40px;
line-height: 18px;
position: relative;
}
.simple_content ul.simple_contentTabA>li a {
display: inline-block;
color: #000;
font-weight: 400;
letter-spacing: -1px;
line-height: 40px;
text-decoration: none;
}
.simple_content ul.simple_contentTabA>li a:hover,
.simple_content ul.simple_contentTabA>li.active a,
.simple_content h1.misolTop .misol_top_a {
color: #2196f3;
}
.simple_content ul.simple_contentTabA>li a span {
border-left: 1px solid #e0e0e0;
padding: 0 15px;
}
.simple_content ul.simple_contentTabA>li:first-child a span {
border-left: 0 none;
}
.simple_content dl.simple_columns {
margin: 0;
padding: 0;
}
.simple_content dl.simple_columns dt {
position: absolute;
width: 0;
height: 0;
overflow: hidden;
font-size: 0;
line-height: 0;
}
.simple_content dl.simple_columns dd {
display: none;
margin: 0;
}
.widgetContainer .simple_content .open {
display: block !important;
}
.simple_content .simple_content_nav {
text-align: center;
color: #616161;
margin: 0;
padding: 10px 0;
border-top: 1px solid #e0e0e0;
}
.simple_content .simple_content_nav button {
background-color: transparent;
color: inherit;
border: 0 none;
cursor: pointer;
line-height: 20px;
height: 35px;
width: 100%;
margin: 0;
font-size: 15px;
}
.simple_content .simple_content_nav li button:hover {
color: #2196f3;
}
.simple_content .simple_content_nav li button i {
font-size: 16px;
line-height: 16px;
}
.simple_content_list.simple_content_webzine .simple_gallery_image {
position: relative;
width: 100px;
float: left;
}
.simple_content_list.simple_content_webzine .content_basic {
display: block;
padding: 10px;
margin: 0;
}
.simple_content_list.simple_content_webzine .content_basic .simple_content_longtext {
display: block;
margin: 7px 0;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

View file

@ -0,0 +1,328 @@
@charset "UTF-8";
/*
@method .text-contrast()
@author misol <misol.kr@gmail.com>
@brief Select a text color according to WCAG 2.0 contrast guideline. The calcualtion of contrast follows the formula on the guideline.
*/
.text-contrast(@bg_color; @bright_color:#fff; @dark_color:#000; @multi:1; @i:0) when (@i >= 100) and ( ( (luma(@bg_color) + 0.05) / (luma(@dark_color) + 0.05) ) =< ( ( luma(@bright_color) + 0.05) / ( luma(@bg_color) + 0.05) )) {
color: @bright_color;
}
.text-contrast(@bg_color; @bright_color:#fff; @dark_color:#000; @multi:1; @i:0) when (@i >= 100) and ( ( (luma(@bg_color) + 0.05) / (luma(@dark_color) + 0.05) ) > ( ( luma(@bright_color) + 0.05) / ( luma(@bg_color) + 0.05) )) {
color: @dark_color;
}
.text-contrast(@bg_color; @bright_color:#fff; @dark_color:#000; @multi:1; @i:0) when (@i < 100) and ( ( (luma(@bg_color) + 0.05) / (luma(@dark_color) + 0.05) ) =< ( ( luma(@bright_color) + 0.05) / ( luma(@bg_color) + 0.05) )) and ( ( ( luma(@bright_color) + 0.05) / ( luma(@bg_color) + 0.05) ) > 4.5 * @multi ) {
color: @bright_color;
}
.text-contrast(@bg_color; @bright_color:#fff; @dark_color:#000; @multi:1; @i:0) when (@i < 100) and ( ( (luma(@bg_color) + 0.05) / (luma(@dark_color) + 0.05) ) =< ( ( luma(@bright_color) + 0.05) / ( luma(@bg_color) + 0.05) ) ) and ( ( ( luma(@bright_color) + 0.05) / ( luma(@bg_color) + 0.05) ) =< 4.5 * @multi ) {
.text-contrast(@bg_color; lighten(@bright_color, 5%); @dark_color; @multi; @i + 1);
}
.text-contrast(@bg_color; @bright_color:#fff; @dark_color:#000; @multi:1; @i:0) when (@i < 100) and ( ( (luma(@bg_color) + 0.05) / (luma(@dark_color) + 0.05) ) > ( ( luma(@bright_color) + 0.05) / ( luma(@bg_color) + 0.05) )) and ( ( (luma(@bg_color) + 0.05) / (luma(@dark_color) + 0.05) ) > 4.5 * @multi ) {
color: @dark_color;
}
.text-contrast(@bg_color; @bright_color:#fff; @dark_color:#000; @multi:1; @i:0) when (@i < 100) and (( (luma(@bg_color) + 0.05) / (luma(@dark_color) + 0.05) ) > ( ( luma(@bright_color) + 0.05) / ( luma(@bg_color) + 0.05) )) and ( ( (luma(@bg_color) + 0.05) / (luma(@dark_color) + 0.05) ) =< 4.5 * @multi ) {
.text-contrast(@bg_color; @bright_color; darken(@dark_color, 5%); @multi; @i + 1);
}
/*
@method .bg-contrast()
@author misol <misol.kr@gmail.com>
@brief Select a background color, which has less contrast background color than WCAG 2.0 contrast guideline. On the WCAG 2.0 guideline, bigger string can have less contrast as 3.0.
*/
.bg-contrast(@text_color; @bright_color:#fff; @dark_color:#000; @multi:1; @i:0) when (@i >= 100) and ( ( (luma(@text_color) + 0.05) / (luma(@dark_color) + 0.05) ) =< ( ( luma(@bright_color) + 0.05) / ( luma(@text_color) + 0.05) )) {
background: @bright_color;
}
.bg-contrast(@text_color; @bright_color:#fff; @dark_color:#000; @multi:1; @i:0) when (@i >= 100) and ( ( (luma(@text_color) + 0.05) / (luma(@dark_color) + 0.05) ) > ( ( luma(@bright_color) + 0.05) / ( luma(@text_color) + 0.05) )) {
background: @dark_color;
}
.bg-contrast(@text_color; @bright_color:#fff; @dark_color:#000; @multi:1; @i:0) when (@i < 100) and ( ( (luma(@text_color) + 0.05) / (luma(@dark_color) + 0.05) ) =< ( ( luma(@bright_color) + 0.05) / ( luma(@text_color) + 0.05) )) and ( ( ( luma(@bright_color) + 0.05) / ( luma(@text_color) + 0.05) ) > 3 * @multi ) {
background: @bright_color;
}
.bg-contrast(@text_color; @bright_color:#fff; @dark_color:#000; @multi:1; @i:0) when (@i < 100) and ( ( (luma(@text_color) + 0.05) / (luma(@dark_color) + 0.05) ) =< ( ( luma(@bright_color) + 0.05) / ( luma(@text_color) + 0.05) ) ) and ( ( ( luma(@bright_color) + 0.05) / ( luma(@text_color) + 0.05) ) =< 3 * @multi ) {
.bg-contrast(@text_color; lighten(@bright_color,3%); @dark_color; @multi; @i + 1);
}
.bg-contrast(@text_color; @bright_color:#fff; @dark_color:#000; @multi:1; @i:0) when (@i < 100) and ( ( (luma(@text_color) + 0.05) / (luma(@dark_color) + 0.05) ) > ( ( luma(@bright_color) + 0.05) / ( luma(@text_color) + 0.05) )) and ( ( (luma(@text_color) + 0.05) / (luma(@dark_color) + 0.05) ) > 3 * @multi ) {
background: @dark_color;
}
.bg-contrast(@text_color; @bright_color:#fff; @dark_color:#000; @multi:1; @i:0) when (@i < 100) and (( (luma(@text_color) + 0.05) / (luma(@dark_color) + 0.05) ) > ( ( luma(@bright_color) + 0.05) / ( luma(@text_color) + 0.05) )) and ( ( (luma(@text_color) + 0.05) / (luma(@dark_color) + 0.05) ) =< 3 * @multi ) {
.bg-contrast(@text_color; @bright_color; darken(@dark_color, 3%); @multi; @i + 1);
}
/* As LESS library in Rhymix substitude variables as an strings, convert colors as the color objects of LESS. */
@color: rgb(@red, @green, @blue);
/* 앱 전체 스타일 */
div.simple_content
{
font-family: "맑은 고딕", "Apple SD Gothic Neo","나눔고딕",NanumGothic,'Nanum Gothic',Arial,Helvetica,sans-serif;
font-size: 14px;
padding: 3px;
}
section.simple_content
{
font-size: 14px;
background-color: #fff;
box-shadow: 0 1px 2px rgba(0,0,0,0.16), 0 1px 2px rgba(0,0,0,0.23);
}
/* 글 목록 스타일 */
.simple_content ul.simple_content_list { margin:0; padding:0 8px;}
.simple_content .simple_content_list .cont_a {
color: #222;
display: block;
letter-spacing: -1px;
line-height: 18px;
overflow: hidden;
padding: 0.667em 3px;
text-overflow: ellipsis;
white-space: nowrap;
text-decoration: none;
}
.simple_content .simple_content_list .cont_a:hover {
.text-contrast(#fff; darken(@color,5%); lighten(@color,5%));
}
.simple_content .cont_a {
color: #222;
display: block;
letter-spacing: -1px;
overflow: hidden;
padding: 0.467em 0;
text-overflow: ellipsis;
white-space: nowrap;
text-decoration: none;
}
.simple_content .content_image {
display:block;
left:0;
position:absolute;
}
.simple_content .content_basic{
position:relative;
display:inline-block;
max-width:100%;
box-sizing: border-box;
vertical-align: middle;
overflow:hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.simple_content .content_basic.content_with_thumbnail{
line-height: @thumbnail_height + 0px;
vertical-align:middle;
padding-left: @thumbnail_width + 5px;
}
.simple_content .content_category {
.text-contrast(#fff; darken(@color,5%); lighten(@color,5%));
font-family: HelveticaNeue-Light,AppleSDGothicNeo-Light,sans-serif-light,sans-serif;
margin: 0 7px 0 3px;
}
.simple_content .simple_gallery_item .content_category {
position: absolute;
top: 0;
right: 0;
background: #fff;
margin: 0;
}
.simple_content .content_nickname, .simple_content .content_recnt{
color: #616161;
font-size: 12px;
margin: 0 3px 0 7px;
overflow:hidden;
}
.simple_content ul.simple_contentTabA {
list-style: outside none none;
padding: 0;
margin: 0;
}
.simple_content .simple_content_list li {
position:relative;
border-top: 1px solid #e0e0e0;
overflow: hidden;
padding:0;
}
.simple_content .simple_content_list li:first-child, .simple_content.simple_content_list li.first-child{
border-top: 0 none;
}
.simple_content .content_recnt{ /* 코멘트 */
position:absolute;
height:18px;
width:44px;
text-align:right;
font-size: 13px;
margin:3px;
top:0.6em;
right:15px;
}
.simple_content .content_recnt.content_with_thumbnail{
height: @thumbnail_height + 0px;
line-height: @thumbnail_height + 0px;
vertical-align:middle;
}
.simple_content .simple_content_list li.content_reext .cont_a { /* 코멘트 있는 항목 */
padding-right:70px;
}
/* 상단 제목 스타일 */
.simple_content h1.misolTop {
border-bottom: 1px solid #e0e0e0;
font-weight: 400;
margin: 0;
position: relative;
}
.simple_content h1.misolTop .misol_top_a {
display: block;
margin: 0;
padding: 10px;
text-decoration: none;
}
/* 갤러리 스타일 */
.simple_content div.simple_gallery{
overflow: hidden;
width:100%;
height: @thumbnail_height + 62px;
white-space: nowrap;
box-sizing: border-box;
}
div.simple_gallery ul.simple_gallery{
display: block;
list-style: outside none none;
padding: 6px 0px 100px;
margin: 0;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
div.simple_gallery ul.simple_gallery > li{
position: relative;
display: inline-block;
width: @thumbnail_width + 0px;
padding: 7px;
}
div.simple_gallery ul.simple_gallery>li .cont_a{
position: relative;
padding:0;
width: @thumbnail_width + 0px;
}
div.simple_gallery ul.simple_gallery>li .gallery_text>span
{
display: block;
width: @thumbnail_width + 0px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
div.simple_gallery ul.simple_gallery>li .gallery_text>span.content_nickname
{
margin: 0;
text-align: right;
}
div.simple_gallery ul.simple_gallery>li .cont_a:hover {
.text-contrast(#fff; darken(@color,5%); lighten(@color,5%));
}
.simple_gallery_item .fake_img, .simple_content_list .content_image{
display: inline-block;
box-sizing: border-box;
background: #fff;
border: 1px solid #e0e0e0;
color: #000;
width: @thumbnail_width + 0px;
height: @thumbnail_height + 0px;
vertical-align: middle;
text-align: center;
line-height: @thumbnail_height + 0px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* 상단 탭 스타일 */
.simple_content div.misolTab{
overflow: hidden;
width:100%;
height: 52px;
white-space: nowrap;
border-bottom: 1px solid #e0e0e0;
box-sizing: border-box;
}
.simple_content ul.simple_contentTabA{
display: block;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
padding: 6px 0px 100px;
text-decoration: none;
}
.simple_content ul.simple_contentTabA>li {
display:inline-block;
height: 40px;
line-height: 18px;
position: relative;
}
.simple_content ul.simple_contentTabA>li a {
display:inline-block;
color: #000;
font-weight: 400;
letter-spacing: -1px;
line-height: 40px;
text-decoration: none;
}
.simple_content ul.simple_contentTabA>li a:hover, .simple_content ul.simple_contentTabA>li.active a, .simple_content h1.misolTop .misol_top_a {
.text-contrast(#fff; darken(@color,5%); lighten(@color,5%));
}
.simple_content ul.simple_contentTabA>li a span {
border-left: 1px solid #e0e0e0;
padding: 0 15px;
}
.simple_content ul.simple_contentTabA>li:first-child a span {
border-left: 0 none;
}
.simple_content dl.simple_columns{ margin:0; padding:0}
.simple_content dl.simple_columns dt{ position:absolute; width:0; height:0; overflow:hidden; font-size:0; line-height:0;}
.simple_content dl.simple_columns dd{ display:none; margin:0;}
.widgetContainer .simple_content .open{ display:block !important;}
.simple_content .simple_content_nav {
text-align: center;
color: #616161;
margin: 0;
padding: 10px 0;
border-top: 1px solid #e0e0e0;
}
.simple_content .simple_content_nav button {
background-color:transparent;
color: inherit;
border: 0 none;
cursor: pointer;
line-height: 20px;
height:35px;
width: 100%;
margin:0;
font-size: 15px;
}
.simple_content .simple_content_nav li button:hover{
.text-contrast(#fff; darken(@color,5%); lighten(@color,5%));
}
.simple_content .simple_content_nav li button i{
font-size:16px;
line-height:16px;
}
.simple_content_list.simple_content_webzine .simple_gallery_image
{
position: relative;
width: @thumbnail_width + 0px;
float:left;
}
.simple_content_list.simple_content_webzine .content_basic
{
display: block;
padding: 10px;
margin:0;
}
.simple_content_list.simple_content_webzine .content_basic .simple_content_longtext
{
display: block;
margin: 7px 0;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

View file

@ -0,0 +1,32 @@
<div class="inner">
<div class="simple_gallery">
<ul class="simple_gallery">
{@$_idx=0}
<li class="simple_gallery_item" loop="$widget_info->content_items => $key, $item">
<a href="{$item->getLink()}" class="cont_a">
<span class="content_category" cond="$widget_info->show_category=='Y' && $item->get('category_srl')">{$item->getCategory()}</span>
<img class="up_m fade" cond="array_search('thumbnail', $widget_info->option_view_arr) && $item->getThumbnail()" src="{$item->getThumbnail()}" srcset="{$item->getThumbnail(2)} 2x"|cond="$item->getThumbnail(2)" alt="{str_replace(array('&amp;amp;','&amp;lt;','&amp;gt;','&amp;quot;','&amp;apos;'),array('&amp;','&lt;','&gt;','&quot;','&apos;'),$item->getTitle($widget_info->subject_cut_size))}" width="{$widget_info->thumbnail_width}" height="{$widget_info->thumbnail_height}" />
<div class="fake_img" cond="!array_search('thumbnail', $widget_info->option_view_arr) || !$item->getThumbnail()">{$lang->none_image}</div>
<div class="up_tw"|cond="array_search('thumbnail', $widget_info->option_view_arr) && $item->getThumbnail()">
<span class="gallery_text">
<span class="content_title">
{str_replace(array('&amp;amp;','&amp;lt;','&amp;gt;','&amp;quot;','&amp;apos;'),array('&amp;','&lt;','&gt;','&quot;','&apos;'),$item->getTitle($widget_info->subject_cut_size))}
</span>
<span class="content_nickname">
{$item->getNickName($widget_info->nickname_cut_size)}
</span>
</span>
</div>
</a>
</li>
</ul>
<!--@if($widget_info->page_count > 1 && $widget_info->list_count<$_idx)-->
<ul class="widgetNavigator">
<li><button type="button" class="prev" title="{$lang->cmd_prev}" onclick="content_widget_prev(jQuery(this).parents('ul.widgetNavigator').prev('ul.widgetGalleryA'),{$widget_info->list_count})"><span>{$lang->cmd_prev}</span></button></li>
<li><button type="button" class="next" title="{$lang->cmd_next}" onclick="content_widget_next(jQuery(this).parents('ul.widgetNavigator').prev('ul.widgetGalleryA'),{$widget_info->list_count})"><span>{$lang->cmd_next}</span></button></li>
</ul>
<!--@end-->
</div>
</div>

View file

@ -0,0 +1 @@
<!--#include("gallery.html")-->

View file

@ -0,0 +1,39 @@
<ul class="simple_content_list simple_content_webzine">
{@$_idx=0}
<!--@foreach($widget_info->content_items as $key => $item)-->
<li style="display:none"|cond="$_idx >= $widget_info->list_count">
<a href="{$item->getLink()}" class="cont_a" target="_blank"|cond="$widget_info->new_window">
<p class="simple_gallery_item simple_gallery_image">
<!--@if($item->getThumbnail())-->
<span class="content_category" cond="$widget_info->show_category=='Y' && $item->get('category_srl')">{$item->getCategory()}</span>
<img src="{$item->getThumbnail()}" srcset="{$item->getThumbnail(2)} 2x"|cond="$item->getThumbnail(2)" width="{$widget_info->thumbnail_width}" height="{$widget_info->thumbnail_height}" />
<!--@else-->
<span class="fake_img">{$lang->none_image}</span>
<!--@end-->
</p>
<p class="content_basic <!--@if($widget_info->show_comment_count=='Y' && $item->getCommentCount())-->content_reext<!--@end-->">
<span class="content_title">
<span class="content_category" cond="$widget_info->show_browser_title=='Y' && $item->getBrowserTitle()">{$item->getBrowserTitle()}</span> {str_replace(array('&amp;amp;','&amp;lt;','&amp;gt;','&amp;quot;','&amp;apos;'),array('&amp;','&lt;','&gt;','&quot;','&apos;'),$item->getTitle($widget_info->subject_cut_size))}
</span>
<span class="content_nickname">
{$item->getNickName($widget_info->nickname_cut_size)}
</span>
<span class="content_recnt" cond="$widget_info->show_comment_count=='Y' && $item->getCommentCount()">
<!--@if($item->getCommentCount()<999)-->{$item->getCommentCount()}<!--@else-->999+<!--@end-->
</span>
<span class="simple_content_longtext" cond="in_array('content', $widget_info->option_view_arr)">
{$item->getContent()}
</span>
</p>
</a>
</li>
{@$_idx++}
<!--@end-->
</ul>
<!--@if($widget_info->page_count > 1 && $widget_info->list_count<$_idx)-->
<div class="simple_content_nav">
<button type="button" class="soo_cont_more" title="{$lang->more}" onclick="content_widget_plus(jQuery(this).parents('div.simple_content_nav').prev('ul.simple_content_list'),{$widget_info->list_count})"><span class="page_info">1/{intval(($_idx - 1) / $widget_info->list_count) + 1}</span> {$lang->more}</button>
</div>
<!--@end-->

View file

@ -0,0 +1,42 @@
function content_widget_plus(obj,list_per_page){
var page = 1;
if(obj.is('table')) {
var list = jQuery('>tbody>tr',obj);
}else if(obj.is('ul')) {
var list = jQuery('>li',obj);
}
var total_page = parseInt((list.size()-1) / list_per_page,10)+1;
list.each(function(i){
if(jQuery(this).css('display') !='none'){
page = parseInt((i-1)/list_per_page,10) + 1;
}
});
if(total_page === page+1)
{
if(obj.is('ul.simple_content_list'))
{
obj.next('div.simple_content_nav').css('display','none');
}
}
if(total_page <= page) return;
if(obj.is('ul.simple_content_list')) {
jQuery('button.soo_cont_more>span.page_info',obj.next('div.simple_content_nav')).html(page+1 + '/' + total_page);
}
list.each(function(i){
if(((page+1) * list_per_page) > i){
jQuery(this).show();
}else{
jQuery(this).hide();
}
});
}
function content_widget_tab_show(tab,list,i){
tab.parents('ul.widgetTab').children('li.active').removeClass('active');
tab.parent('li').addClass('active');
jQuery('>dd',list).each(function(j){
if(j==i) jQuery(this).addClass('open');
else jQuery(this).removeClass('open');
});
}

View file

@ -0,0 +1,29 @@
<div class="inner">
<ul class="simple_content_list">
{@$_idx=0}
<li loop="$widget_info->content_items => $key, $item" style="display:none"|cond="$_idx >= $widget_info->list_count" class="content_reext"|cond="$widget_info->show_comment_count=='Y' && $item->getCommentCount()">
<a href="{$item->getLink()}" class="cont_a" target="_blank"|cond="$widget_info->new_window">
<span cond="array_search('thumbnail', $widget_info->option_view_arr) && $item->getThumbnail()" class="content_image">
<img src="{$item->getThumbnail()}" width="{$widget_info->thumbnail_width}" srcset="{$item->getThumbnail(2)} 2x"|cond="$item->getThumbnail(2)" height="{$widget_info->thumbnail_height}" alt="{str_replace(array('&amp;amp;','&amp;lt;','&amp;gt;','&amp;quot;','&amp;apos;'),array('&amp;','&lt;','&gt;','&quot;','&apos;'),$item->getTitle($widget_info->subject_cut_size))}" />
</span>
<span class="content_basic <!--@if(array_search('thumbnail', $widget_info->option_view_arr) && $item->getThumbnail())-->content_with_thumbnail<!--@end-->">
<span class="content_title">
<span class="content_category" cond="$widget_info->tab_type == 'tab_left' && $tab->tab_type == 'all'">{$item->getBrowserTitle()}</span>
<span class="content_category" cond="$widget_info->show_category=='Y' && $item->get('category_srl') && trim($item->getCategory()) && !$tab->tab_type">{$item->getCategory()}</span> {str_replace(array('&amp;amp;','&amp;lt;','&amp;gt;','&amp;quot;','&amp;apos;'),array('&amp;','&lt;','&gt;','&quot;','&apos;'),$item->getTitle($widget_info->subject_cut_size))}
</span>
<span class="content_nickname">
{$item->getNickName($widget_info->nickname_cut_size)}
</span>
</span>
<span class="content_recnt <!--@if(array_search('thumbnail', $widget_info->option_view_arr) && $item->getThumbnail())-->content_with_thumbnail<!--@end-->" cond="$widget_info->show_comment_count=='Y' && $item->getCommentCount()">
<!--@if($item->getCommentCount()<999)-->{$item->getCommentCount()}<!--@else-->999+<!--@end-->
</span>
</a>{@$_idx++}
</li>
</ul>
<!--@if($widget_info->page_count > 1 && $widget_info->list_count<$_idx)-->
<div class="simple_content_nav">
<button type="button" class="soo_cont_more" title="{$lang->more}" onclick="content_widget_plus(jQuery(this).parents('div.simple_content_nav').prev('ul.simple_content_list'),{$widget_info->list_count})"><span class="page_info">1/{intval(($_idx - 1) / $widget_info->list_count) + 1}</span> {$lang->more}</button>
</div>
<!--@end-->
</div>

View file

@ -0,0 +1,107 @@
<?xml version="1.0" encoding="UTF-8"?>
<skin version="0.2">
<title xml:lang="ko">네모의 꿈</title>
<title xml:lang="en">Rectangular World</title>
<description xml:lang="ko">직사각형과 그림자, 테마색상을 활용한 컨텐츠 스킨입니다.</description>
<description xml:lang="en">Rectangles, shadows, theme-color.</description>
<version>1.0</version>
<date>2017-02-26</date>
<link>https://github.com/rhymix/rhymix/</link>
<license link="https://www.gnu.org/licenses/old-licenses/gpl-2.0.html">GPLv2</license>
<author email_address="misol.kr@gmail.com" link="https://github.com/misol/">
<name xml:lang="ko">misol</name>
<name xml:lang="en">misol</name>
</author>
<colorset>
<color name="theme">
<title xml:lang="ko">사이트 테마 색</title>
<title xml:lang="en">The site theme color</title>
</color>
<color name="red">
<title xml:lang="ko">붉은 색</title>
<title xml:lang="en">Red</title>
</color>
<color name="crimson">
<title xml:lang="ko">크림슨</title>
<title xml:lang="en">Crimson</title>
</color>
<color name="pink">
<title xml:lang="ko">분홍</title>
<title xml:lang="en">Pink</title>
</color>
<color name="purple">
<title xml:lang="ko">보라</title>
<title xml:lang="en">Purple</title>
</color>
<color name="deep-purple">
<title xml:lang="ko">진보라</title>
<title xml:lang="en">Deep Purple</title>
</color>
<color name="indigo">
<title xml:lang="ko">인디고</title>
<title xml:lang="en">Indigo</title>
</color>
<color name="deep-blue">
<title xml:lang="ko">짙은 파랑</title>
<title xml:lang="en">Deep Blue</title>
</color>
<color name="blue">
<title xml:lang="ko">파랑</title>
<title xml:lang="en">Blue</title>
</color>
<color name="light-blue">
<title xml:lang="ko">밝은 파랑</title>
<title xml:lang="en">Light Blue</title>
</color>
<color name="cyan">
<title xml:lang="ko">시안</title>
<title xml:lang="en">Cyan</title>
</color>
<color name="teal">
<title xml:lang="ko"></title>
<title xml:lang="en">Teal</title>
</color>
<color name="green">
<title xml:lang="ko">초록</title>
<title xml:lang="en">Green</title>
</color>
<color name="light-green">
<title xml:lang="ko">연한 초록</title>
<title xml:lang="en">Light Green</title>
</color>
<color name="lime">
<title xml:lang="ko">라임</title>
<title xml:lang="en">Lime</title>
</color>
<color name="yellow">
<title xml:lang="ko">노랑</title>
<title xml:lang="en">Yellow</title>
</color>
<color name="amber">
<title xml:lang="ko">앰버</title>
<title xml:lang="en">Amber</title>
</color>
<color name="orange">
<title xml:lang="ko">주황</title>
<title xml:lang="en">Orange</title>
</color>
<color name="deep-orange">
<title xml:lang="ko">진한 주황</title>
<title xml:lang="en">Deep Orange</title>
</color>
<color name="brown">
<title xml:lang="ko">갈색</title>
<title xml:lang="en">Brown</title>
</color>
<color name="grey">
<title xml:lang="ko">회색</title>
<title xml:lang="en">Grey</title>
</color>
<color name="blue-grey">
<title xml:lang="ko">푸른 회색</title>
<title xml:lang="en">Blue Grey</title>
</color>
</colorset>
</skin>

View file

@ -0,0 +1,108 @@
<!--// 목록형 출력 -->
<!--@if($widget_info->markup_type=="list")-->
<ul class="widgetA">
{@$_idx=0}
<!--@foreach($widget_info->content_items as $key => $item)-->
<li<!--@if($_idx >= $widget_info->list_count)--> style="display:none"<!--@end-->>
<!--@foreach($widget_info->option_view_arr as $k => $v)-->
<!--@if($v=='title')-->
<!--@if($widget_info->show_browser_title=='Y' && $item->getBrowserTitle())-->
<a href="<!--@if($item->contents_link)-->{$item->contents_link}<!--@else-->{getSiteUrl($item->domain, '', 'mid', $item->get('mid'))}<!--@end-->" class="board" target="_blank"|cond="$widget_info->new_window"><strong>{$item->getBrowserTitle()}</strong></a>
<!--@end-->
<!--@if($widget_info->show_category=='Y' && $item->get('category_srl') )-->
<a href="{getSiteUrl($item->domain,'','mid',$item->get('mid'),'category',$item->get('category_srl'))}" target="_blank"|cond="$widget_info->new_window"><strong class="category">{$item->getCategory()}</strong></a>
<!--@end-->
<a href="{$item->getLink()}" class="title" target="_blank"|cond="$widget_info->new_window">{$item->getTitle($widget_info->subject_cut_size)}</a>
<!--@if($widget_info->show_comment_count=='Y' && $item->getCommentCount())-->
<em class="replyNum" title="Replies"><a href="{$item->getLink()}#comment" target="_blank"|cond="$widget_info->new_window">{$item->getCommentCount()}</a></em>
<!--@end-->
<!--@if($widget_info->show_trackback_count=='Y' && $item->getTrackbackCount())-->
<em class="trackbackNum" title="Trackbacks"><a href="{$item->getLink()}#trackback" target="_blank"|cond="$widget_info->new_window">{$item->getTrackbackCount()}</a></em>
<!--@end-->
<!--@if($widget_info->show_icon=='Y')-->
<span class="icon">{$item->printExtraImages()}</span>
<!--@end-->
<!--@else if($v=='nickname')-->
<a <!--@if($item->getMemberSrl())-->href="#" onclick="return false;" class="author member_{$item->getMemberSrl()}"<!--@elseif($item->getAuthorSite())-->href="{$item->getAuthorSite()}" onclick="window.open(this.href); return false;" class="author member"<!--@else-->href="#" onclick="return false;" class="author member"<!--@end--> >{$item->getNickName()}</a>
<!--@else if($v=='regdate')-->
<span class="date">{$item->getRegdate("Y-m-d")}</span> <span class="hour">{$item->getRegdate("H:i")}</span>
<!--@else if($v=='content')-->
<p class="summary"><a href="{$item->getLink()}" target="_blank"|cond="$widget_info->new_window">{$item->getContent()}</a></p>
<!--@end-->
<!--@end-->
</li>
{@$_idx++}
<!--@end-->
</ul>
<!--@if($widget_info->page_count > 1 && $widget_info->list_count<$_idx)-->
<ul class="widgetNavigator">
<li><button type="button" class="prev" title="{$lang->cmd_prev}" onclick="content_widget_prev(jQuery(this).parents('ul.widgetNavigator').prev('ul.widgetA'),{$widget_info->list_count})"><span>{$lang->cmd_prev}</span></button></li>
<li><button type="button" class="next" title="{$lang->cmd_next}" onclick="content_widget_next(jQuery(this).parents('ul.widgetNavigator').prev('ul.widgetA'),{$widget_info->list_count})"><span>{$lang->cmd_next}</span></button></li>
</ul>
<!--@end-->
<!--// 테이블형 출력 -->
<!--@else-->
<table class="widgetTableA" border="1" cellspacing="0">
<tbody>
{@$_idx=0}
<!--@foreach($widget_info->content_items as $key => $item)-->
<tr<!--@if($_idx >= $widget_info->list_count)--> style="display:none"<!--@end-->>
<!--@foreach($widget_info->option_view_arr as $k => $v)-->
<!--@if($v=='title')-->
<td class="title">
<!--@if($widget_info->show_browser_title=='Y' && $item->getBrowserTitle())-->
<a href="<!--@if($item->contents_link)-->{$item->contents_link}<!--@else-->{getSiteUrl($item->domain, '', 'mid', $item->get('mid'))}<!--@end-->" target="_blank"|cond="$widget_info->new_window"><strong class="board">{$item->getBrowserTitle()}</strong></a>
<!--@end-->
<!--@if($widget_info->show_category=='Y' && $item->get('category_srl') )-->
<a href="{getSiteUrl($item->domain,'','mid',$item->get('mid'),'category',$item->get('category_srl'))}" target="_blank"|cond="$widget_info->new_window"><strong class="category">{$item->getCategory()}</strong></a>
<!--@end-->
<a href="{$item->getLink()}" target="_blank"|cond="$widget_info->new_window">{$item->getTitle($widget_info->subject_cut_size)}</a>
<!--@if($widget_info->show_comment_count=='Y' && $item->getCommentCount())-->
<em class="replyNum" title="Replies"><a href="{$item->getLink()}#comment" target="_blank"|cond="$widget_info->new_window">{$item->getCommentCount()}</a></em>
<!--@end-->
<!--@if($widget_info->show_trackback_count=='Y' && $item->getTrackbackCount())-->
<em class="trackbackNum" title="Trackbacks"><a href="{$item->getLink()}#trackback" target="_blank"|cond="$widget_info->new_window">{$item->getTrackbackCount()}</a></em>
<!--@end-->
<!--@if($widget_info->show_icon=='Y')-->
<span class="icon">{$item->printExtraImages()}</span>
<!--@end-->
</td>
<!--@else if($v=='nickname')-->
<td><a <!--@if($item->getMemberSrl())-->href="#" onclick="return false;" class="author member_{$item->getMemberSrl()}"<!--@elseif($item->getAuthorSite())-->href="{$item->getAuthorSite()}" onclick="window.open(this.href); return false;" class="author member"<!--@else-->href="#" onclick="return false;" class="author member"<!--@end--> >{$item->getNickName()}</a></td>
<!--@else if($v=='regdate')-->
<td class="time"><span class="date">{$item->getRegdate("Y-m-d")}</span> <span class="hour">{$item->getRegdate("H:i")}</span></td>
<!--@end-->
<!--@end-->
</tr>
<!--@if($v=='content')-->
<tr>
<td colspan="3" class="summary"><a href="{$item->getLink()}" target="_blank"|cond="$widget_info->new_window">{$item->getContent()}</a></td>
</tr>
<!--@end-->
{@$_idx++}
<!--@end-->
</tbody>
</table>
<!--@if($widget_info->page_count > 1 && $widget_info->list_count<$_idx)-->
<ul class="widgetNavigator">
<li><button type="button" class="prev" title="{$lang->cmd_prev}" onclick="content_widget_prev(jQuery(this).parents('ul.widgetNavigator').prev('table.widgetTableA'),{$widget_info->list_count})"><span>{$lang->cmd_prev}</span></button></li>
<li><button type="button" class="next" title="{$lang->cmd_next}" onclick="content_widget_next(jQuery(this).parents('ul.widgetNavigator').prev('table.widgetTableA'),{$widget_info->list_count})"><span>{$lang->cmd_next}</span></button></li>
</ul>
<!--@end-->
<!--@end-->