diff --git a/classes/db/queryparts/limit/Limit.class.php b/classes/db/queryparts/limit/Limit.class.php
index 5e660c4d6..e84fd3390 100644
--- a/classes/db/queryparts/limit/Limit.class.php
+++ b/classes/db/queryparts/limit/Limit.class.php
@@ -37,10 +37,11 @@ class Limit
* constructor
* @param int $list_count
* @param int $page
- * @param int $page_count
+ * @param int $page_count
+ * @param int $offset
* @return void
*/
- function __construct($list_count, $page = NULL, $page_count = NULL)
+ function __construct($list_count, $page = NULL, $page_count = NULL, $offset = NULL)
{
$this->list_count = $list_count;
if($page)
@@ -50,6 +51,10 @@ class Limit
$this->start = ($page_value - 1) * $list_count_value;
$this->page_count = $page_count;
$this->page = $page;
+ }
+ elseif($offset)
+ {
+ $this->start = $offset->getValue();
}
}
@@ -81,7 +86,7 @@ class Limit
function toString()
{
- if($this->page)
+ if($this->page || $this->start)
{
return $this->start . ' , ' . $this->list_count->getValue();
}
diff --git a/classes/module/ModuleHandler.class.php b/classes/module/ModuleHandler.class.php
index ca736d731..80cb7ad62 100644
--- a/classes/module/ModuleHandler.class.php
+++ b/classes/module/ModuleHandler.class.php
@@ -272,7 +272,7 @@ class ModuleHandler extends Handler
}
// redirect, if site start module
- if(isset($_GET['mid']) && $_GET['mid'] === $site_module_info->mid && count($_GET) === 1)
+ if(Context::getRequestMethod() === 'GET' && isset($_GET['mid']) && $_GET['mid'] === $site_module_info->mid && count($_GET) === 1)
{
Context::setCacheControl(0);
header('location: ' . getNotEncodedSiteUrl($site_module_info->domain), true, 301);
diff --git a/classes/xml/xmlquery/tags/navigation/LimitTag.class.php b/classes/xml/xmlquery/tags/navigation/LimitTag.class.php
index e3ff511dd..6bef36a33 100644
--- a/classes/xml/xmlquery/tags/navigation/LimitTag.class.php
+++ b/classes/xml/xmlquery/tags/navigation/LimitTag.class.php
@@ -35,6 +35,12 @@ class LimitTag
*/
var $list_count;
+ /**
+ * QueryArgument object
+ * @var QueryArgument
+ */
+ var $offset;
+
/**
* constructor
* @param object $index
@@ -58,6 +64,12 @@ class LimitTag
$index->list_count->attrs->default = 0;
$this->list_count = new QueryArgument($index->list_count);
$this->arguments[] = $this->list_count;
+
+ if(isset($index->offset) && isset($index->offset->attrs))
+ {
+ $this->offset = new QueryArgument($index->offset);
+ $this->arguments[] = $this->offset;
+ }
}
function toString()
@@ -66,6 +78,10 @@ class LimitTag
{
return sprintf('new Limit(${\'%s_argument\'}, ${\'%s_argument\'}, ${\'%s_argument\'})', $this->list_count->getArgumentName(), $this->page->getArgumentName(), $this->page_count->getArgumentName());
}
+ elseif($this->offset)
+ {
+ return sprintf('new Limit(${\'%s_argument\'}, NULL, NULL, ${\'%s_argument\'})', $this->list_count->getArgumentName(), $this->offset->getArgumentName());
+ }
else
{
return sprintf('new Limit(${\'%s_argument\'})', $this->list_count->getArgumentName());
diff --git a/common/defaults/config.php b/common/defaults/config.php
index 479119c0d..1afb6a510 100644
--- a/common/defaults/config.php
+++ b/common/defaults/config.php
@@ -88,6 +88,7 @@ return array(
'display_type' => 'comment',
'display_content' => array(),
'display_to' => 'admin',
+ 'write_error_log' => 'fatal',
'allow' => array(),
),
'seo' => array(
diff --git a/common/framework/debug.php b/common/framework/debug.php
index ee366ff3c..5ef7aaf68 100644
--- a/common/framework/debug.php
+++ b/common/framework/debug.php
@@ -22,11 +22,6 @@ class Debug
protected static $_remote_requests = array();
protected static $_slow_remote_requests = array();
- /**
- * Also write to error log.
- */
- public static $write_to_error_log = true;
-
/**
* Get all entries.
*
@@ -166,7 +161,7 @@ class Debug
self::$_entries[] = $entry;
// Add the entry to the error log.
- if (self::$write_to_error_log && self::isEnabledForCurrentUser())
+ if (config('debug.write_error_log') === 'all' && self::isEnabledForCurrentUser())
{
$log_entry = str_replace("\0", '', sprintf('Rhymix Debug: %s in %s on line %d',
var_export($message, true), $entry->file, $entry->line));
@@ -215,7 +210,7 @@ class Debug
);
// Add the entry to the error log.
- if (self::$write_to_error_log)
+ if (config('debug.write_error_log') === 'all')
{
$log_entry = strtr(sprintf('PHP %s: %s in %s on line %d', $errinfo->type, $errstr, $errfile, intval($errline)), "\0\r\n\t\v\e\f", ' ');
error_log($log_entry . \PHP_EOL . self::formatBacktrace($backtrace));
@@ -371,7 +366,10 @@ class Debug
$log_entry = str_replace("\0", '', sprintf('%s #%d "%s" in %s on line %d',
get_class($e), $e->getCode(), $e->getMessage(), $errfile, $e->getLine()));
}
- error_log('PHP Exception: ' . $log_entry . \PHP_EOL . self::formatBacktrace($e->getTrace()));
+ if (config('debug.write_error_log') !== 'none')
+ {
+ error_log('PHP Exception: ' . $log_entry . \PHP_EOL . self::formatBacktrace($e->getTrace()));
+ }
// Display the error screen.
self::displayErrorScreen($log_entry);
@@ -398,7 +396,10 @@ class Debug
// Add the entry to the error log.
$message = sprintf('%s in %s on line %d', $errinfo['message'], $errinfo['file'], intval($errinfo['line']));
$log_entry = str_replace("\0", '', 'PHP ' . self::getErrorType($errinfo['type']) . ': ' . $message);
- error_log($log_entry);
+ if (config('debug.write_error_log') !== 'none')
+ {
+ error_log($log_entry);
+ }
// Display the error screen.
self::displayErrorScreen($log_entry);
diff --git a/layouts/simple_world/conf/info.xml b/layouts/simple_world/conf/info.xml
new file mode 100644
index 000000000..94940f107
--- /dev/null
+++ b/layouts/simple_world/conf/info.xml
@@ -0,0 +1,133 @@
+
+
+ 네모의 꿈
+ Rectangular World
+ 깔끔한 면과 그림자 레이아웃
+ Simple rectangular planes and shadows
+ 1.0
+ 2016-09-04
+
+ misol
+ misol
+
+
+
+
+
+
+
+ 사이트 로고 이미지
+ Site logo image
+
+
+ 사이트 로고 문자
+ Site logo text
+
+
+ 사이트 로고 링크 주소
+ Site logo link URL
+
+
+ 사이트 하단 문자
+ Site footer text
+
+
+ 중심 색상
+ Primary color
+ 분위기를 형성하는데 사용되는 중심 색상입니다.
+ Please type the mood color you want.
+
+
+
+ 붉은 색
+ Red
+
+
+ 크림슨
+ Crimson
+
+
+ 분홍
+ Pink
+
+
+ 보라
+ Purple
+
+
+ 진보라
+ Deep Purple
+
+
+ 인디고
+ Indigo
+
+
+ 짙은 파랑
+ Deep Blue
+
+
+ 파랑
+ Blue
+
+
+ 밝은 파랑
+ Light Blue
+
+
+ 시안
+ Cyan
+
+
+ 틸
+ Teal
+
+
+ 초록
+ Green
+
+
+ 연한 초록
+ Light Green
+
+
+ 라임
+ Lime
+
+
+ 노랑
+ Yellow
+
+
+ 앰버
+ Amber
+
+
+ 주황
+ Orange
+
+
+ 진한 주황
+ Deep Orange
+
+
+ 갈색
+ Brown
+
+
+ 회색
+ Grey
+
+
+ 푸른 회색
+ Blue Grey
+
+
+
+
\ No newline at end of file
diff --git a/layouts/simple_world/lang/lang.xml b/layouts/simple_world/lang/lang.xml
new file mode 100644
index 000000000..0c0dc5d2c
--- /dev/null
+++ b/layouts/simple_world/lang/lang.xml
@@ -0,0 +1,15 @@
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+
\ No newline at end of file
diff --git a/layouts/simple_world/layout.html b/layouts/simple_world/layout.html
new file mode 100644
index 000000000..801578967
--- /dev/null
+++ b/layouts/simple_world/layout.html
@@ -0,0 +1,143 @@
+
+{Context::addMetaTag("viewport", "width=device-width, user-scalable=yes")}
+
+
+
+{@ $material_colors = array(
+ 'red' => '#f44336',
+ 'crimson' => '#66001f',
+ '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'
+);
+
+ $oMemberModel = getModel('member');
+ $member_config = $oMemberModel->getMemberConfig();
+
+}
+
+
+{@ if(!$layout_info->primary_color) $layout_info->primary_color = 'red'}
+{@ if(!$layout_info->secondary_color) $layout_info->secondary_color = 'indigo'}
+
+{@ if($layout_info->primary_color === $layout_info->secondary_color && $layout_info->primary_color === 'indigo') $layout_info->secondary_color = 'red'}
+{@ if($layout_info->primary_color === $layout_info->secondary_color && $layout_info->primary_color !== 'indigo') $layout_info->secondary_color = 'indigo'}
+
+
+{Context::addMetaTag("theme-color", $material_colors[$layout_info->primary_color])}
+
+
+{Context::set('layout_scss_value', array('grey' => $material_colors['grey'], 'primary_color' => $material_colors[$layout_info->primary_color], 'secondary_color' => $layout_info->secondary_color, ))}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/layouts/simple_world/layout.js b/layouts/simple_world/layout.js
new file mode 100644
index 000000000..b7822271c
--- /dev/null
+++ b/layouts/simple_world/layout.js
@@ -0,0 +1,54 @@
+$(function() {
+ "use strict";
+
+ var menu_width = function() {
+ if($('#layout_gnb>ul>li:first-child').width() > 50) {
+ $('#layout_gnb>ul>li:first-child .layout_dropdown-content, #layout_gnb>ul>li:first-child .layout_dropdown-content a').css('width', $('#layout_gnb>ul>li:first-child').width()).css('min-width', $('#layout_gnb>ul>li:first-child').width());
+ }
+ }
+
+ $( window ).resize(function() {
+ if($('#layout_gnb>ul>li:first-child').width() > 50) {
+ menu_width();
+ }
+ });
+
+ menu_width();
+
+ var toggles = document.querySelectorAll(".layout_mobile_menu");
+
+ for (var i = toggles.length - 1; i >= 0; i--) {
+ var toggle = toggles[i];
+ layout_toggleHandler(toggle);
+ };
+
+ function layout_toggleMenuOpener(obj) {
+ if(obj.classList.contains("is-active") === true){
+ var targetMenu = $(obj).attr('data-target');
+ $('#' + targetMenu).slideUp('300', function() {
+ $(this).css('display', '')
+ });
+
+ obj.classList.remove("is-active");
+ }
+ else {
+ $('#layout_gnb>ul>li:first-child .layout_dropdown-content, #layout_gnb>ul>li:first-child .layout_dropdown-content a').css('width', '').css('min-width', '');
+ var targetMenu = $(obj).attr('data-target');
+ $('#' + targetMenu).slideDown('300');
+
+ obj.classList.add("is-active");
+ }
+ }
+
+ function layout_toggleHandler(toggle) {
+ toggle.addEventListener( "click", function(e) {
+ e.preventDefault();
+ layout_toggleMenuOpener(this);
+ });
+ }
+
+ // Language Select
+ $('.language>.toggle').click(function(){
+ $('.selectLang').toggle();
+ });
+});
\ No newline at end of file
diff --git a/layouts/simple_world/layout.scss b/layouts/simple_world/layout.scss
new file mode 100644
index 000000000..3712017d5
--- /dev/null
+++ b/layouts/simple_world/layout.scss
@@ -0,0 +1,553 @@
+@charset "UTF-8";
+@function layoutGrayContrast($color, $ratio) {
+ $grayColor: grayscale($color);
+ $grayValue: red($grayColor);
+
+ @if $grayValue > ($ratio * 255) {
+ $return: 0;
+ } @else {
+ $return: 255;
+ }
+
+ @return rgb($return, $return, $return);
+}
+
+@function layoutLightenSelector($background, $ratio, $lighten, $lighter, $lightest) {
+ $backgroundGrayColor: grayscale($background);
+ $backgroundGrayValue: red($backgroundGrayColor);
+
+ $lightenGrayColor: grayscale($lighten);
+ $lightenGrayValue: red($lightenGrayColor);
+
+ $lighterGrayColor: grayscale($lighter);
+ $lighterGrayValue: red($lighterGrayColor);
+
+ @if (abs($backgroundGrayValue - $lightenGrayValue) > ($ratio * 255)) {
+ $return: $lighten;
+ } @else if (abs($backgroundGrayValue - $lighterGrayValue) > ($ratio * 255)) {
+ $return: $lighter;
+ } @else {
+ $return: $lightest;
+ }
+
+ @return $return;
+}
+
+body {
+ margin:0;
+ background-color: #ffffff;
+}
+/* Skin to content */
+.skip {
+ position: relative;
+ margin:0
+}
+
+.skip>a {
+ display: block;
+ text-align: center;
+ line-height:28px;
+ height:0px;
+ overflow: hidden
+}
+
+.skip>a:focus {
+ height: auto
+}
+
+/* Layout */
+#layout_canvas {
+ position: relative;
+ max-width:960px;
+ width:100%;
+ margin:0 auto;
+}
+
+.layout_header {
+ min-height:90px;
+ padding:0;
+ margin:0 0 17px;
+}
+
+.layout_header>.hside {
+ position: absolute;
+ right:5px;
+ top: 25px
+}
+
+.layout_body {
+ position: relative;
+}
+
+.layout_header:after,
+.layout_body:after {
+ content:"";
+ display: block;
+ clear: both
+}
+
+.layout_content {
+ padding:0 0 40px 0;
+}
+
+.layout_content>*:first-child {
+ margin-top:0
+}
+
+.layout_content img {
+ max-width:100%;
+ height: auto
+}
+
+/* Header */
+.layout_header>h1 {
+ margin:0 auto;
+ padding:20px 95px 20px 5px;
+ box-sizing: border-box;
+ background-color: lighten($primary-color, 10%);
+ color: layoutGrayContrast(lighten($primary-color, 10%), 0.710);
+}
+
+.layout_header>h1>a {
+ font-size:32px;
+ text-decoration: none;
+ color: layoutGrayContrast(lighten($primary-color, 10%), 0.710);
+ padding:0 5px;
+}
+
+#layout_menu_toggle {
+ width:90px;
+ display: none;
+}
+
+/* .layout_footer */
+.layout_footer {
+ padding:10px;
+ border-top:1px solid lighten($grey, 10%);
+ background-color: darken($grey, 35%);
+ color: lighten($grey, 30%);
+}
+
+.layout_footer p {
+ font-size:12px
+}
+
+.layout_footer a {
+ font-weight: bold;
+ text-decoration: none;
+ color: lighten($primary_color, 31%);
+}
+
+.layout_footer a:hover,
+.layout_footer a:focus {
+ text-decoration: underline
+}
+
+/* Search */
+.layout_header .layout_search {
+ display: inline-block;
+ vertical-align: bottom;
+ margin:0
+}
+
+.layout_header .layout_search>input {
+ font-size:12px;
+ -webkit-appearance: none;
+ border-radius: 0;
+}
+
+.layout_header .layout_search>input[type="text"] {
+ width: 126px;
+ line-height: 18px;
+ font-size: 14px;
+ margin: 0;
+ padding: 8px 8px 6px 8px;
+ position: relative;
+ display: inline-block;
+ outline: none;
+ border-radius: 0;
+ border: none;
+ background: lighten($primary-color, 20%);
+ color: layoutGrayContrast(lighten($primary-color, 20%), 0.710);
+}
+
+.layout_header .layout_search>input[type="text"]:hover,
+.layout_header .layout_search>input[type="text"]:focus {
+ background: lighten($primary-color, 50%);
+ color: layoutGrayContrast(lighten($primary-color, 50%), 0.710);
+}
+
+.layout_header .layout_search>input[type="submit"] {
+ vertical-align: bottom;
+ background: lighten($primary-color,15%);
+ color: layoutGrayContrast(lighten($primary-color, 15%), 0.710);
+ border: none;
+ height:32px;
+ padding:0 15px;
+ margin:0;
+}
+
+.layout_header .layout_search>input[type="submit"]:hover,
+ .layout_header .layout_search>input[type="submit"]:focus {
+ background:$primary-color;
+ color: layoutGrayContrast($primary-color, 0.710);
+}
+
+/* GNB */
+.layout_menu ul {
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+ overflow: hidden;
+ background-color: darken($grey, 30%);
+}
+
+.layout_menu>ul>li {
+ float: left;
+}
+
+#layout_gnb>ul>li:first-child {
+ float: right;
+
+}
+
+.layout_menu li a, .dropbtn {
+ display: inline-block;
+ color: white;
+ text-align: center;
+ padding: 14px 16px;
+ text-decoration: none;
+ font-size: 13px;
+ line-height: 1;
+}
+
+.layout_menu li.active>a {
+ background-color: lighten($primary-color, 15%);
+ color: layoutGrayContrast(lighten($primary-color, 15%), 0.710);
+}
+
+.layout_menu li a:hover,
+.layout_menu li a:focus,
+.layout_menu li a:active,
+.layout_dropdown:hover .dropbtn,
+.layout_dropdown:focus .dropbtn,
+.layout_dropdown:active .dropbtn,
+.language li:hover button,
+.language li:focus button,
+.language li:active button {
+ background-color: $primary-color;
+ color: layoutGrayContrast($primary-color, 0.710);
+}
+
+.layout_menu li.layout_dropdown {
+ display: block;
+}
+
+.layout_menu .layout_dropdown-content {
+ display: none;
+ position: absolute;
+ background-color: lighten($grey, 40%);
+ z-index: 9999999;
+ box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
+}
+
+.layout_menu .layout_dropdown-content a {
+ color: black;
+ padding: 12px 16px;
+ text-decoration: none;
+ min-width: 160px;
+ display: block;
+ text-align: left;
+ box-sizing: border-box;
+}
+
+.
+.layout_menu .layout_dropdown-content a:hover {
+ display: block;
+ background-color: lighten($primary-color, 10%);
+ color: layoutGrayContrast(lighten($primary-color, 10%), 0.710);
+}
+
+.layout_menu .layout_dropdown:hover .layout_dropdown-content {
+ display: block;
+}
+.layout_footer .layout_menu li a, .layout_footer .dropbtn {
+ color: #fff;
+ font-weight: normal;
+ text-decoration: none;
+}
+
+/* Language */
+.language{
+ display: inline-block;
+ width: 100%;
+ text-align: right;
+}
+.language button {
+ outline: none;
+}
+.language ul::before {
+ content: "";
+ display: block;
+ clear: both;
+}
+.language ul {
+ display: none;
+ float:right;
+ width:120px;
+ clear:both;
+ margin: 0;
+ padding: 0;
+ z-index: 9999999;
+ box-shadow: 0px 8px 16px 0px rgba(255,255,255,0.2);
+}
+.language .toggle{
+ background:none;
+ display: block;
+ float: right;
+ width:120px;
+ border:0;
+ color:#fff;
+ cursor:pointer;
+ vertical-align:top;
+ text-align:right;
+ padding:0;
+ height:45px;
+}
+
+.language li{
+ list-style:none;
+ background: lighten($grey, 40%);
+}
+.language li button {
+ display:block;
+ color: black;
+ background: lighten($grey, 40%);
+ padding: 12px 16px;
+ text-decoration: none;
+ width: 100%;
+ display: block;
+ text-align: left;
+ box-sizing: border-box;
+ border:0;
+ cursor:pointer;
+}
+
+/* Hamberger menu http://callmenick.com/post/animating-css-only-hamburger-menu-icons Licensed under the MIT license, http://www.opensource.org/licenses/mit-license.php Copyright 2014, Call Me Nick http://callmenick.com */
+.layout_mobile_menu {
+ display: block;
+ position: relative;
+ overflow: hidden;
+ margin: 0;
+ padding: 0;
+ width: 90px;
+ height: 90px;
+ font-size: 0;
+ text-indent: -9999px;
+ appearance: none;
+ box-shadow: none;
+ border-radius: none;
+ border: none;
+ cursor: pointer;
+ transition: background 0.3s;
+}
+
+.layout_mobile_menu:focus {
+ outline: none;
+}
+
+.layout_mobile_menu span {
+ display: block;
+ position: absolute;
+ top: 41px;
+ left: 17px;
+ right: 17px;
+ height: 8px;
+ background: white;
+}
+
+.layout_mobile_menu span::before,
+.layout_mobile_menu span::after {
+ position: absolute;
+ display: block;
+ left: 0;
+ width: 100%;
+ height: 8px;
+ background-color: #fff;
+ content: "";
+}
+
+.layout_mobile_menu span::before {
+ top: -19px;
+}
+
+.layout_mobile_menu span::after {
+ bottom: -19px;
+}
+
+.layout_mobile_menu--htx {
+ background-color: $primary-color;
+}
+
+.layout_mobile_menu--htx span {
+ transition: background 0s 0.3s;
+}
+
+.layout_mobile_menu--htx span::before,
+.layout_mobile_menu--htx span::after {
+ transition-duration: 0.3s, 0.3s;
+ transition-delay: 0.3s, 0s;
+}
+
+.layout_mobile_menu--htx span::before {
+ transition-property: top, transform;
+}
+
+.layout_mobile_menu--htx span::after {
+ transition-property: bottom, transform;
+}
+
+/* active state, i.e. menu open */
+.layout_mobile_menu--htx.is-active {
+ background-color: darken( $primary-color, 10% );
+}
+
+.layout_mobile_menu--htx.is-active span {
+ background: none;
+}
+
+.layout_mobile_menu--htx.is-active span::before {
+ top: 0;
+ transform: rotate(45deg);
+}
+
+.layout_mobile_menu--htx.is-active span::after {
+ bottom: 0;
+ transform: rotate(-45deg);
+}
+
+.layout_mobile_menu--htx.is-active span::before,
+.layout_mobile_menu--htx.is-active span::after {
+ transition-delay: 0s, 0.3s;
+}
+#layout_search_link {
+ display: none;
+}
+
+@media (max-width: 750px) {
+ #layout_menu_toggle, #layout_search_link {
+ display: block;
+ }
+ .layout_header h1 {
+ background-color: lighten($primary-color, 10%);
+ color: layoutGrayContrast(lighten($primary-color, 10%), 0.710);
+ }
+
+ .layout_header>h1>a {
+ color: layoutGrayContrast(lighten($primary-color, 10%), 0.710);
+ }
+
+ .layout_header>*,
+ .layout_container,
+ .layout_footer>p {
+ width:100%;
+ margin:0 auto;
+ }
+
+ #layout_menu_toggle {
+ position: absolute;
+ top:0;
+ right:0;
+ }
+
+ /* GNB */
+ .layout_menu {
+ display: none;
+ font-size:15px;
+ width:100%;
+ height: auto;
+ clear: both;
+ }
+
+ .layout_menu ul {
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+ width: 100%;
+ height: auto;
+ background-color: lighten($grey, 31%);
+ }
+
+ .layout_menu>ul>li, #layout_gnb>ul>li:first-child {
+ float: none;
+ }
+
+ .layout_menu li a, .dropbtn {
+ display: block;
+ color: #000;
+ text-align: left;
+ padding: 15px;
+ text-decoration: none;
+ }
+
+ .layout_menu li.active>a {
+ background-color: lighten($primary-color, 15%);
+ color: layoutGrayContrast(lighten($primary-color, 15%), 0.710);
+ }
+
+ .layout_menu li a:hover, .layout_dropdown:hover .dropbtn {
+ background-color: $primary-color;
+ color: layoutGrayContrast($primary-color, 10%, 0.710);
+ }
+
+ .layout_menu li.layout_dropdown {
+ display: block;
+ }
+
+ .layout_menu .layout_dropdown-content {
+ display: block;
+ position: relative;
+ background-color: lighten($grey, 35%);
+ color: layoutGrayContrast(lighten($grey, 35%), 0.710);
+ width: 100%;
+ min-width: 100%;
+ box-shadow: none;
+ }
+
+ .layout_menu .layout_dropdown-content a {
+ background-color: lighten($grey, 35%);
+ color: layoutGrayContrast(lighten($grey, 35%), 0.710);
+ padding: 15px 30px;
+ text-decoration: none;
+ display: block;
+ text-align: left;
+ }
+
+ .layout_footer .layout_menu {
+ display: block;
+ margin-bottom: 10px;
+ }
+
+ .layout_footer .layout_menu ul {
+ background-color: transparent;
+ }
+
+ .language {
+ margin-top: 30px;
+ }
+ .language ul {
+ display: none;
+ float:none;
+ width:100%;
+ }
+ .language .toggle{
+ display: block;
+ float: none;
+ width:100%;
+ }
+ /* PC only */
+ .layout_pc {
+ display: none;
+ }
+
+}
\ No newline at end of file
diff --git a/layouts/simple_world/thumbnail.png b/layouts/simple_world/thumbnail.png
new file mode 100644
index 000000000..3f5f132a8
Binary files /dev/null and b/layouts/simple_world/thumbnail.png differ
diff --git a/modules/admin/admin.admin.controller.php b/modules/admin/admin.admin.controller.php
index a4006bdee..d38afd50b 100644
--- a/modules/admin/admin.admin.controller.php
+++ b/modules/admin/admin.admin.controller.php
@@ -713,7 +713,7 @@ class adminAdminController extends admin
Rhymix\Framework\Config::set('view.minify_scripts', $vars->minify_scripts ?: 'common');
Rhymix\Framework\Config::set('view.concat_scripts', $vars->concat_scripts ?: 'none');
Rhymix\Framework\Config::set('view.server_push', $vars->use_server_push === 'Y');
- Rhymix\Framework\Config::set('view.gzip', $vars->use_gzip === 'Y');
+ Rhymix\Framework\Config::set('view.use_gzip', $vars->use_gzip === 'Y');
// Save
Rhymix\Framework\Config::save();
@@ -737,6 +737,7 @@ class adminAdminController extends admin
Rhymix\Framework\Config::set('debug.log_slow_remote_requests', max(0, floatval($vars->debug_log_slow_remote_requests)));
Rhymix\Framework\Config::set('debug.display_type', strval($vars->debug_display_type) ?: 'comment');
Rhymix\Framework\Config::set('debug.display_to', strval($vars->debug_display_to) ?: 'admin');
+ Rhymix\Framework\Config::set('debug.write_error_log', strval($vars->debug_write_error_log) ?: 'fatal');
// Debug content
$debug_content = array_values($vars->debug_display_content);
diff --git a/modules/admin/admin.admin.view.php b/modules/admin/admin.admin.view.php
index b9b91b764..f1535af65 100644
--- a/modules/admin/admin.admin.view.php
+++ b/modules/admin/admin.admin.view.php
@@ -538,7 +538,7 @@ class adminAdminView extends admin
Context::set('minify_scripts', Rhymix\Framework\Config::get('view.minify_scripts'));
Context::set('concat_scripts', Rhymix\Framework\Config::get('view.concat_scripts'));
Context::set('use_server_push', Rhymix\Framework\Config::get('view.server_push'));
- Context::set('use_gzip', Rhymix\Framework\Config::get('view.gzip'));
+ Context::set('use_gzip', Rhymix\Framework\Config::get('view.use_gzip'));
$this->setTemplateFile('config_advanced');
}
@@ -559,6 +559,7 @@ class adminAdminView extends admin
Context::set('debug_display_type', Rhymix\Framework\Config::get('debug.display_type'));
Context::set('debug_display_content', Rhymix\Framework\Config::get('debug.display_content'));
Context::set('debug_display_to', Rhymix\Framework\Config::get('debug.display_to'));
+ Context::set('debug_write_error_log', Rhymix\Framework\Config::get('debug.write_error_log'));
// IP access control
$allowed_ip = Rhymix\Framework\Config::get('debug.allow');
diff --git a/modules/admin/lang/en.php b/modules/admin/lang/en.php
index 4e26b9682..d7bd7c2e6 100644
--- a/modules/admin/lang/en.php
+++ b/modules/admin/lang/en.php
@@ -159,6 +159,10 @@ $lang->debug_display_to_admin = 'Administrator only';
$lang->debug_display_to_ip = 'Visitors from IP adresses listed below';
$lang->debug_display_to_everyone = 'Everyone';
$lang->debug_log_filename = 'Log filename';
+$lang->debug_write_error_log = 'Write to Error Log';
+$lang->debug_write_error_log_all = 'All errors';
+$lang->debug_write_error_log_fatal = 'Fatal errors only';
+$lang->debug_write_error_log_none = 'None';
$lang->about_debug_log_filename = 'YYYYMMDD in the filename will be replaced with the current date.
It is recommended to split the log file by date to prevent it from getting too large.';
$lang->msg_debug_log_filename_not_writable = 'Rhymix cannot write log files in the specified path.';
$lang->debug_allowed_ip = 'Allowed IP addresses';
diff --git a/modules/admin/lang/ko.php b/modules/admin/lang/ko.php
index 221dcce35..e1cb5490e 100644
--- a/modules/admin/lang/ko.php
+++ b/modules/admin/lang/ko.php
@@ -154,6 +154,10 @@ $lang->debug_display_to_admin = '관리자에게만 표시';
$lang->debug_display_to_ip = '아래 IP의 방문자에게만 표시';
$lang->debug_display_to_everyone = '모두에게 표시';
$lang->debug_log_filename = '디버그 정보 기록 파일';
+$lang->debug_write_error_log = '에러 로그에 기록';
+$lang->debug_write_error_log_all = '모든 에러를 기록';
+$lang->debug_write_error_log_fatal = '치명적인 에러만 기록';
+$lang->debug_write_error_log_none = '기록하지 않음';
$lang->about_debug_log_filename = '파일명에 YYYYMMDD가 포함된 경우 날짜별로 파일을 분리하여 기록합니다.
파일을 분리하지 않으면 용량이 매우 커질 수 있으니 주의하십시오.';
$lang->msg_debug_log_filename_not_writable = '지정한 경로에 로그 파일을 작성할 수 없습니다.';
$lang->debug_allowed_ip = '디버그 허용 IP';
diff --git a/modules/admin/tpl/config_debug.html b/modules/admin/tpl/config_debug.html
index 7ca92e55b..e8d69062f 100644
--- a/modules/admin/tpl/config_debug.html
+++ b/modules/admin/tpl/config_debug.html
@@ -84,6 +84,14 @@
+
diff --git a/modules/board/board.view.php b/modules/board/board.view.php
index 41af3c945..b64f55926 100644
--- a/modules/board/board.view.php
+++ b/modules/board/board.view.php
@@ -323,7 +323,7 @@ class boardView extends board
Context::setBrowserTitle($seo_title, array(
'site_title' => Context::getSiteTitle(),
'site_subtitle' => Context::getSiteSubtitle(),
- 'subpage_title' => $module_info->browser_title,
+ 'subpage_title' => $this->module_info->browser_title,
'document_title' => $oDocument->getTitleText(),
'page' => Context::get('page') ?: 1,
));
diff --git a/modules/document/document.item.php b/modules/document/document.item.php
index 605703b43..788325118 100644
--- a/modules/document/document.item.php
+++ b/modules/document/document.item.php
@@ -20,6 +20,11 @@ class documentItem extends Object
* @var string
*/
var $lang_code = null;
+ /**
+ * grant
+ * @var bool
+ */
+ var $grant_cache = null;
/**
* Status of allow trackback
* @var bool
@@ -157,25 +162,44 @@ class documentItem extends Object
function isGranted()
{
- if($_SESSION['own_document'][$this->document_srl]) return true;
-
- if(!Context::get('is_logged')) return false;
-
+ if ($this->grant_cache !== null)
+ {
+ return $this->grant_cache;
+ }
+
+ if ($_SESSION['own_document'][$this->document_srl])
+ {
+ return $this->grant_cache = true;
+ }
+
$logged_info = Context::get('logged_info');
- if($logged_info->is_admin == 'Y') return true;
+ if (!$logged_info->member_srl)
+ {
+ return $this->grant_cache = false;
+ }
+ if ($logged_info->is_admin == 'Y')
+ {
+ return $this->grant_cache = true;
+ }
+ if ($this->get('member_srl') && abs($this->get('member_srl')) == $logged_info->member_srl)
+ {
+ return $this->grant_cache = true;
+ }
$oModuleModel = getModel('module');
$grant = $oModuleModel->getGrant($oModuleModel->getModuleInfoByModuleSrl($this->get('module_srl')), $logged_info);
- if($grant->manager) return true;
+ if ($grant->manager)
+ {
+ return $this->grant_cache = true;
+ }
- if($this->get('member_srl') && ($this->get('member_srl') == $logged_info->member_srl || $this->get('member_srl')*-1 == $logged_info->member_srl)) return true;
-
- return false;
+ return $this->grant_cache = false;
}
function setGrant()
{
$_SESSION['own_document'][$this->document_srl] = true;
+ $this->grant_cache = true;
}
function isAccessible()
diff --git a/modules/module/module.model.php b/modules/module/module.model.php
index 9ffafb54a..563d0a4f3 100644
--- a/modules/module/module.model.php
+++ b/modules/module/module.model.php
@@ -1862,6 +1862,13 @@ class moduleModel extends module
*/
function getGrant($module_info, $member_info, $xml_info = '')
{
+ $cache_key = sprintf('site_and_module:module_grant:%d:%d', $module_info->module_srl, $member_info->member_srl);
+ $grant = Rhymix\Framework\Cache::get($cache_key);
+ if ($grant !== null)
+ {
+ return $grant;
+ }
+
$grant = new stdClass();
if(!$xml_info)
@@ -2014,6 +2021,9 @@ class moduleModel extends module
}
}
}
+
+ // Set to cache and return
+ Rhymix\Framework\Cache::set($cache_key, $grant, 0, true);
return $grant;
}
diff --git a/modules/module/queries/getTrigger.xml b/modules/module/queries/getTrigger.xml
index b2be983ca..c7c2dc870 100644
--- a/modules/module/queries/getTrigger.xml
+++ b/modules/module/queries/getTrigger.xml
@@ -12,4 +12,11 @@
+
+
+
+
+
+
+
diff --git a/modules/module/queries/getTriggers.xml b/modules/module/queries/getTriggers.xml
index 4967c88de..e31412776 100644
--- a/modules/module/queries/getTriggers.xml
+++ b/modules/module/queries/getTriggers.xml
@@ -9,4 +9,11 @@
+
+
+
+
+
+
+
diff --git a/modules/ncenterlite/conf/info.xml b/modules/ncenterlite/conf/info.xml
index fd5bf8f8a..76cc4c118 100644
--- a/modules/ncenterlite/conf/info.xml
+++ b/modules/ncenterlite/conf/info.xml
@@ -4,8 +4,8 @@
Notification Center Lite
사이트 사용자간의 커뮤니케이션에 대한 정보를 알려주는 모듈입니다.
This module notify users of information about new documents, comments and/or messages that call them. This module will enhance communication beween site users.
-
3.0.0
-
2016-04-17
+
3.1
+
2016-09-10
content
XE Public
diff --git a/modules/ncenterlite/ncenterlite.controller.php b/modules/ncenterlite/ncenterlite.controller.php
index fb50a53c3..1b8641368 100644
--- a/modules/ncenterlite/ncenterlite.controller.php
+++ b/modules/ncenterlite/ncenterlite.controller.php
@@ -63,6 +63,10 @@ class ncenterliteController extends ncenterlite
{
return $output;
}
+ else
+ {
+ self::removeFlagFile($args->member_srl);
+ }
return new Object();
}
@@ -411,9 +415,30 @@ class ncenterliteController extends ncenterlite
return new Object();
}
+ $notify_list = $oNcenterliteModel->getNotifyMemberSrlByCommentSrl($obj->comment_srl);
+
+ // 대댓글의 대댓글일 경우 혹은 중복적으로 받는 경우 comment_srl 당 2개이상 notify가 생성될 수 있다.
+ $member_srls = array();
+ foreach($notify_list as $value)
+ {
+ if(!in_array($value->member_srl, $member_srls))
+ {
+ $member_srls[] = $value->member_srl;
+ }
+ }
+
$args = new stdClass();
$args->srl = $obj->comment_srl;
$output = executeQuery('ncenterlite.deleteNotifyBySrl', $args);
+ if($output->toBool())
+ {
+ foreach($member_srls as $member_srl)
+ {
+ //Remove flag files
+ self::removeFlagFile($member_srl);
+ }
+ }
+
return new Object();
}
@@ -429,12 +454,27 @@ class ncenterliteController extends ncenterlite
$args = new stdClass();
$args->srl = $obj->document_srl;
$output = executeQuery('ncenterlite.deleteNotifyBySrl', $args);
+ if(!$output->toBool())
+ {
+ return $output;
+ }
return new Object();
}
function triggerAfterMoveToTrash(&$obj)
{
$oNcenterliteModel = getModel('ncenterlite');
+ $notify_list = $oNcenterliteModel->getNotifyListByDocumentSrl($obj->document_srl);
+
+ $member_srls = array();
+ foreach($notify_list as $value)
+ {
+ if(!in_array($value->member_srl, $member_srls))
+ {
+ $member_srls[] = $value->member_srl;
+ }
+ }
+
$config = $oNcenterliteModel->getConfig();
if(empty($config->use))
@@ -445,6 +485,14 @@ class ncenterliteController extends ncenterlite
$args = new stdClass();
$args->srl = $obj->document_srl;
$output = executeQuery('ncenterlite.deleteNotifyBySrl', $args);
+ if($output->toBool())
+ {
+ foreach($member_srls as $member_srl)
+ {
+ //Remove flag files
+ self::removeFlagFile($member_srl);
+ }
+ }
return new Object();
}
@@ -489,6 +537,11 @@ class ncenterliteController extends ncenterlite
$args->target_srl = $comment_srl;
$args->member_srl = $logged_info->member_srl;
$output_update = executeQuery('ncenterlite.updateNotifyReadedByTargetSrl', $args);
+ if($output_update->toBool())
+ {
+ //Remove flag files
+ self::removeFlagFile($args->member_srl);
+ }
}
}
else if($oModule->act == 'dispBoardContent')
@@ -498,11 +551,20 @@ class ncenterliteController extends ncenterlite
$oDocument = Context::get('oDocument');
$logged_info = Context::get('logged_info');
- if($document_srl && $logged_info && $config->document_read == 'Y')
+ if($document_srl && Context::get('is_logged') && $config->document_read == 'Y')
{
- $args->srl = $document_srl;
- $args->member_srl = $logged_info->member_srl;
- $outputs = executeQuery('ncenterlite.updateNotifyReadedBySrl', $args);
+ $notify_count = getModel('ncenterlite')->_getNewCount();
+ if($notify_count)
+ {
+ $args->srl = $document_srl;
+ $args->member_srl = $logged_info->member_srl;
+ $outputs = executeQuery('ncenterlite.updateNotifyReadedBySrl', $args);
+ if($outputs->toBool())
+ {
+ //Remove flag files
+ self::removeFlagFile($args->member_srl);
+ }
+ }
}
if($comment_srl && $document_srl && $oDocument)
@@ -513,7 +575,6 @@ class ncenterliteController extends ncenterlite
if(array_key_exists($comment_srl, $_comment_list))
{
$url = getNotEncodedUrl('_comment_srl', '') . '#comment_' . $comment_srl;
- $need_check_socialxe = true;
}
else
{
@@ -521,7 +582,6 @@ class ncenterliteController extends ncenterlite
if($cpage > 1)
{
$url = getNotEncodedUrl('cpage', $cpage - 1) . '#comment_' . $comment_srl;
- $need_check_socialxe = true;
}
else
{
@@ -529,35 +589,6 @@ class ncenterliteController extends ncenterlite
}
}
- if($need_check_socialxe)
- {
- $oDB = &DB::getInstance();
- if($oDB->isTableExists('socialxe'))
- {
- $args = new stdClass();
- $oModuleModel = getModel('module');
- $module_info = $oModuleModel->getModuleInfoByDocumentSrl($document_srl);
- $args->module_srl = $module_info->module_srl;
- $output = executeQuery('ncenterlite.getSocialxeCount', $args);
- if($output->data->cnt)
- {
- $socialxe_comment_srl = $comment_srl;
-
- $args = new stdClass();
- $args->comment_srl = $comment_srl;
- $oCommentModel = getModel('comment');
- $oComment = $oCommentModel->getComment($comment_srl);
- $parent_srl = $oComment->get('parent_srl');
- if($parent_srl)
- {
- $socialxe_comment_srl = $parent_srl;
- }
-
- $url = getNotEncodedUrl('_comment_srl', '', 'cpage', '', 'comment_srl', $socialxe_comment_srl) . '#comment_' . $comment_srl;
- }
- }
- }
-
$url = str_replace('&', '&', $url);
header('location: ' . $url);
Context::close();
@@ -574,7 +605,12 @@ class ncenterliteController extends ncenterlite
$args = new stdClass();
$args->target_srl = $message_srl;
$args->member_srl = $logged_info->member_srl;
- executeQuery('ncenterlite.updateNotifyReadedByTargetSrl', $args);
+ $update_output = executeQuery('ncenterlite.updateNotifyReadedByTargetSrl', $args);
+ if($update_output->toBool())
+ {
+ //Remove flag files
+ self::removeFlagFile($args->member_srl);
+ }
}
}
@@ -631,6 +667,11 @@ class ncenterliteController extends ncenterlite
$args->srl = $vars->document_srl;
$args->type = $this->_TYPE_DOCUMENT;
$output = executeQuery('ncenterlite.updateNotifyReadedBySrl', $args);
+ if($output->toBool())
+ {
+ //Remove flag files
+ self::removeFlagFile($args->member_srl);
+ }
}
}
else if($oModule->act == 'getKinComments')
@@ -640,6 +681,11 @@ class ncenterliteController extends ncenterlite
$args->member_srl = $logged_info->member_srl;
$args->target_srl = $vars->parent_srl;
$output = executeQuery('ncenterlite.updateNotifyReadedByTargetSrl', $args);
+ if($output->toBool())
+ {
+ //Remove flag files
+ self::removeFlagFile($args->member_srl);
+ }
}
return new Object();
@@ -869,11 +915,7 @@ class ncenterliteController extends ncenterlite
//$output = executeQuery('ncenterlite.deleteNotify', $args);
//Remove flag files
- $flag_path = \RX_BASEDIR . 'files/cache/ncenterlite/new_notify/' . getNumberingPath($args->member_srl) . $args->member_srl . '.php';
- if(file_exists($flag_path))
- {
- FileHandler::removeFile($flag_path);
- }
+ self::removeFlagFile($args->member_srl);
return $output;
}
@@ -886,11 +928,7 @@ class ncenterliteController extends ncenterlite
//$output = executeQuery('ncenterlite.deleteNotifyByTargetSrl', $args);
//Remove flag files
- $flag_path = \RX_BASEDIR . 'files/cache/ncenterlite/new_notify/' . getNumberingPath($args->member_srl) . $args->member_srl . '.php';
- if(file_exists($flag_path))
- {
- FileHandler::removeFile($flag_path);
- }
+ self::removeFlagFile($args->member_srl);
return $output;
}
@@ -902,11 +940,7 @@ class ncenterliteController extends ncenterlite
//$output = executeQuery('ncenterlite.deleteNotifyByMemberSrl', $args);
//Remove flag files
- $flag_path = \RX_BASEDIR . 'files/cache/ncenterlite/new_notify/' . getNumberingPath($args->member_srl) . $args->member_srl . '.php';
- if(file_exists($flag_path))
- {
- FileHandler::removeFile($flag_path);
- }
+ self::removeFlagFile($args->member_srl);
return $output;
}
@@ -1051,12 +1085,7 @@ class ncenterliteController extends ncenterlite
}
}
- $flag_path = \RX_BASEDIR . 'files/cache/ncenterlite/new_notify/' . getNumberingPath($args->member_srl) . $args->member_srl . '.php';
- if(file_exists($flag_path))
- {
- //remove flag files
- FileHandler::removeFile($flag_path);
- }
+ self::removeFlagFile($args->member_srl);
return $output;
}
@@ -1078,6 +1107,19 @@ class ncenterliteController extends ncenterlite
FileHandler::writeFile($flag_path, $buff);
}
+ public static function removeFlagFile($member_srl = null)
+ {
+ if($member_srl === null)
+ {
+ return;
+ }
+
+ $flag_path = \RX_BASEDIR . 'files/cache/ncenterlite/new_notify/' . getNumberingPath($member_srl) . $member_srl . '.php';
+ if(file_exists($flag_path))
+ {
+ FileHandler::removeFile($flag_path);
+ }
+ }
/**
* @brief 노티 ID 반환
diff --git a/modules/ncenterlite/ncenterlite.model.php b/modules/ncenterlite/ncenterlite.model.php
index 7794d386f..73b04d041 100644
--- a/modules/ncenterlite/ncenterlite.model.php
+++ b/modules/ncenterlite/ncenterlite.model.php
@@ -457,4 +457,38 @@ class ncenterliteModel extends ncenterlite
return zdate($datetime, 'Y-m-d');
}
+
+ function getNotifyListByDocumentSrl($document_srl = null)
+ {
+ if($document_srl === null)
+ {
+ return false;
+ }
+ $args = new stdClass();
+ $args->document_srl = $document_srl;
+ $output = executeQueryArray('ncenterlite.getNotifyListByDocumentSrl', $args);
+ if(!$output->toBool())
+ {
+ return $output;
+ }
+
+ return $output->data;
+ }
+
+ function getNotifyMemberSrlByCommentSrl($comment_srl)
+ {
+ if(!$comment_srl === null)
+ {
+ return false;
+ }
+ $args = new stdClass();
+ $args->srl = $comment_srl;
+ $output = executeQueryArray('ncenterlite.getNotifyMemberSrlByCommentSrl', $args);
+ if(!$output->toBool())
+ {
+ return $output;
+ }
+
+ return $output->data;
+ }
}
diff --git a/modules/ncenterlite/queries/getNotifyListByDocumentSrl.xml b/modules/ncenterlite/queries/getNotifyListByDocumentSrl.xml
new file mode 100644
index 000000000..565f223c8
--- /dev/null
+++ b/modules/ncenterlite/queries/getNotifyListByDocumentSrl.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/ncenterlite/queries/getNotifyMemberSrlByCommentSrl.xml b/modules/ncenterlite/queries/getNotifyMemberSrlByCommentSrl.xml
new file mode 100644
index 000000000..7e2727799
--- /dev/null
+++ b/modules/ncenterlite/queries/getNotifyMemberSrlByCommentSrl.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/unit/framework/DebugTest.php b/tests/unit/framework/DebugTest.php
index 444ebac1f..143ebbed7 100644
--- a/tests/unit/framework/DebugTest.php
+++ b/tests/unit/framework/DebugTest.php
@@ -5,8 +5,7 @@ class DebugTest extends \Codeception\TestCase\Test
public function testDebugEntry()
{
$file = __FILE__;
- $line = __LINE__ + 2;
- Rhymix\Framework\Debug::$write_to_error_log = false;
+ $line = __LINE__ + 1;
Rhymix\Framework\Debug::addEntry('foobar entry');
$entries = Rhymix\Framework\Debug::getEntries();
$this->assertEquals(1, count($entries));
@@ -18,8 +17,7 @@ class DebugTest extends \Codeception\TestCase\Test
public function testDebugError()
{
$file = __FILE__;
- $line = __LINE__ + 2;
- Rhymix\Framework\Debug::$write_to_error_log = false;
+ $line = __LINE__ + 1;
Rhymix\Framework\Debug::addError(~0, 'Rhymix', $file, $line, null);
$errors = Rhymix\Framework\Debug::getErrors();
$this->assertGreaterThanOrEqual(1, count($errors));