mirror of
https://github.com/Lastorder-DC/rhymix.git
synced 2026-01-03 08:41:39 +09:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
881b0fbac1
58 changed files with 606 additions and 200 deletions
58
.github/workflows/setup-php.sh
vendored
58
.github/workflows/setup-php.sh
vendored
|
|
@ -4,47 +4,27 @@
|
||||||
sudo add-apt-repository -y ppa:ondrej/php
|
sudo add-apt-repository -y ppa:ondrej/php
|
||||||
|
|
||||||
# Install all required packages
|
# Install all required packages
|
||||||
if [[ "$1" == "8.5" ]]; then
|
sudo apt -y install \
|
||||||
sudo apt -y install \
|
php$1-apcu \
|
||||||
php$1-bcmath \
|
php$1-bcmath \
|
||||||
php$1-cli \
|
php$1-cli \
|
||||||
php$1-common \
|
php$1-common \
|
||||||
php$1-curl \
|
php$1-curl \
|
||||||
php$1-gd \
|
php$1-gd \
|
||||||
php$1-intl \
|
php$1-intl \
|
||||||
php$1-mbstring \
|
php$1-mbstring \
|
||||||
php$1-mysql \
|
php$1-mysql \
|
||||||
php$1-readline \
|
php$1-readline \
|
||||||
php$1-sqlite3 \
|
php$1-sqlite3 \
|
||||||
php$1-xml \
|
php$1-xml \
|
||||||
php$1-zip
|
php$1-zip
|
||||||
else
|
|
||||||
sudo apt -y install \
|
|
||||||
php$1-apcu \
|
|
||||||
php$1-bcmath \
|
|
||||||
php$1-cli \
|
|
||||||
php$1-common \
|
|
||||||
php$1-curl \
|
|
||||||
php$1-gd \
|
|
||||||
php$1-intl \
|
|
||||||
php$1-mbstring \
|
|
||||||
php$1-mysql \
|
|
||||||
php$1-opcache \
|
|
||||||
php$1-readline \
|
|
||||||
php$1-sqlite3 \
|
|
||||||
php$1-xml \
|
|
||||||
php$1-zip
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Adjust php.ini settings
|
# Adjust php.ini settings
|
||||||
if [[ "$1" == "8.5" ]]; then
|
sudo bash -c "echo 'register_argc_argv = On' >> /etc/php/$1/cli/php.ini"
|
||||||
sudo bash -c "echo 'register_argc_argv = On' >> /etc/php/$1/cli/php.ini"
|
sudo bash -c "echo 'opcache.enable = 1' >> /etc/php/$1/cli/conf.d/10-opcache.ini"
|
||||||
else
|
sudo bash -c "echo 'opcache.enable_cli = 1' >> /etc/php/$1/cli/conf.d/10-opcache.ini"
|
||||||
sudo bash -c "echo 'opcache.enable = 1' >> /etc/php/$1/cli/conf.d/10-opcache.ini"
|
sudo bash -c "echo 'opcache.jit = tracing' >> /etc/php/$1/cli/conf.d/10-opcache.ini"
|
||||||
sudo bash -c "echo 'opcache.enable_cli = 1' >> /etc/php/$1/cli/conf.d/10-opcache.ini"
|
sudo bash -c "echo 'opcache.jit_buffer_size = 128M' >> /etc/php/$1/cli/conf.d/10-opcache.ini"
|
||||||
sudo bash -c "echo 'opcache.jit = tracing' >> /etc/php/$1/cli/conf.d/10-opcache.ini"
|
|
||||||
sudo bash -c "echo 'opcache.jit_buffer_size = 128M' >> /etc/php/$1/cli/conf.d/10-opcache.ini"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Enable APCu
|
# Enable APCu
|
||||||
if [ -f "/etc/php/$1/cli/conf.d/20-apcu.ini" ]; then
|
if [ -f "/etc/php/$1/cli/conf.d/20-apcu.ini" ]; then
|
||||||
|
|
|
||||||
|
|
@ -139,7 +139,7 @@ class Context
|
||||||
*/
|
*/
|
||||||
private static $_check_patterns = array(
|
private static $_check_patterns = array(
|
||||||
'@<(?:\?|%)@' => 'DENY ALL',
|
'@<(?:\?|%)@' => 'DENY ALL',
|
||||||
'@<script\s*?language\s*?=@i' => 'DENY ALL',
|
'@<script\s*?language\s*?=\s*?(?![\'"]javascript[\'"])@i' => 'DENY ALL',
|
||||||
'@</?script@i' => 'ALLOW ADMIN ONLY',
|
'@</?script@i' => 'ALLOW ADMIN ONLY',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -728,7 +728,7 @@ class HTMLDisplayHandler
|
||||||
* import basic .js files.
|
* import basic .js files.
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
function _loadDesktopJSCSS()
|
public function _loadDesktopJSCSS()
|
||||||
{
|
{
|
||||||
$this->_loadCommonJSCSS();
|
$this->_loadCommonJSCSS();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -461,18 +461,28 @@ class FileHandler
|
||||||
* Check available memory to load image file
|
* Check available memory to load image file
|
||||||
*
|
*
|
||||||
* @param array $imageInfo Image info retrieved by getimagesize function
|
* @param array $imageInfo Image info retrieved by getimagesize function
|
||||||
|
* @param array $resizeInfo Resize width and height
|
||||||
* @return bool TRUE: it's ok, FALSE: otherwise
|
* @return bool TRUE: it's ok, FALSE: otherwise
|
||||||
*/
|
*/
|
||||||
public static function checkMemoryLoadImage(&$imageInfo)
|
public static function checkMemoryLoadImage($imageInfo, $resizeInfo = [])
|
||||||
{
|
{
|
||||||
$K64 = 65536;
|
$bits = $imageInfo['bits'] ?? 8;
|
||||||
$TWEAKFACTOR = 2.0;
|
$channels = ($imageInfo['channels'] ?? 6) ?: 6; // for png
|
||||||
$channels = $imageInfo['channels'] ?? 6;
|
if (!$resizeInfo)
|
||||||
if(!$channels)
|
|
||||||
{
|
{
|
||||||
$channels = 6; //for png
|
$resizeInfo = $imageInfo;
|
||||||
}
|
}
|
||||||
$memoryNeeded = round(($imageInfo[0] * $imageInfo[1] * $imageInfo['bits'] * $channels / 8 + $K64 ) * $TWEAKFACTOR);
|
$src_memory = round($imageInfo[0] * $imageInfo[1] * $bits * $channels / 8) + 65536;
|
||||||
|
$dst_memory = round($resizeInfo[0] * $resizeInfo[1] * 8 * $channels / 8) + 65536;
|
||||||
|
|
||||||
|
$gd_info = gd_info();
|
||||||
|
$gd_version = $gd_info['GD Version'] ?? '';
|
||||||
|
$gd_type = str_contains($gd_version, 'bundled') ? 'bundled' : 'external';
|
||||||
|
if ($gd_type === 'external')
|
||||||
|
{
|
||||||
|
$dst_memory = 0;
|
||||||
|
}
|
||||||
|
|
||||||
$memoryLimit = ini_get('memory_limit');
|
$memoryLimit = ini_get('memory_limit');
|
||||||
if($memoryLimit <= 0)
|
if($memoryLimit <= 0)
|
||||||
{
|
{
|
||||||
|
|
@ -484,7 +494,7 @@ class FileHandler
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
$availableMemory = $memoryLimit - memory_get_usage();
|
$availableMemory = $memoryLimit - memory_get_usage();
|
||||||
if($availableMemory < $memoryNeeded)
|
if($availableMemory < ($src_memory + $dst_memory))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -559,11 +569,6 @@ class FileHandler
|
||||||
|
|
||||||
// retrieve source image's information
|
// retrieve source image's information
|
||||||
$imageInfo = getimagesize($source_file);
|
$imageInfo = getimagesize($source_file);
|
||||||
if(!self::checkMemoryLoadImage($imageInfo))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
list($width, $height, $type) = $imageInfo;
|
list($width, $height, $type) = $imageInfo;
|
||||||
if($width < 1 || $height < 1)
|
if($width < 1 || $height < 1)
|
||||||
{
|
{
|
||||||
|
|
@ -596,6 +601,12 @@ class FileHandler
|
||||||
$resize_height = round($resize_width / ($width / $height));
|
$resize_height = round($resize_width / ($width / $height));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check memory usage
|
||||||
|
if(!self::checkMemoryLoadImage($imageInfo, [$resize_width, $resize_height]))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// create temporary image having original type
|
// create temporary image having original type
|
||||||
if ($type === 'gif' && function_exists('imagecreatefromgif'))
|
if ($type === 'gif' && function_exists('imagecreatefromgif'))
|
||||||
{
|
{
|
||||||
|
|
@ -646,6 +657,14 @@ class FileHandler
|
||||||
$thumb = imagecreatetruecolor($resize_width, $resize_height);
|
$thumb = imagecreatetruecolor($resize_width, $resize_height);
|
||||||
if (!$thumb)
|
if (!$thumb)
|
||||||
{
|
{
|
||||||
|
if (version_compare(PHP_VERSION, '8.0', '<'))
|
||||||
|
{
|
||||||
|
imagedestroy($source);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unset($source);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -706,6 +725,11 @@ class FileHandler
|
||||||
imagecopyresampled($thumb, $source, $dst_x, $dst_y, 0, 0, $dst_width, $dst_height, $width, $height);
|
imagecopyresampled($thumb, $source, $dst_x, $dst_y, 0, 0, $dst_width, $dst_height, $width, $height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (version_compare(PHP_VERSION, '8.0', '>='))
|
||||||
|
{
|
||||||
|
unset($source);
|
||||||
|
}
|
||||||
|
|
||||||
// create directory
|
// create directory
|
||||||
self::makeDir(dirname($target_file));
|
self::makeDir(dirname($target_file));
|
||||||
|
|
||||||
|
|
@ -736,12 +760,27 @@ class FileHandler
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (version_compare(PHP_VERSION, '8.0', '<'))
|
||||||
|
{
|
||||||
|
imagedestroy($thumb);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unset($thumb);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
imagedestroy($thumb);
|
|
||||||
imagedestroy($source);
|
|
||||||
@chmod($target_file, 0666 & ~Rhymix\Framework\Storage::getUmask());
|
@chmod($target_file, 0666 & ~Rhymix\Framework\Storage::getUmask());
|
||||||
|
|
||||||
|
if (version_compare(PHP_VERSION, '8.0', '<'))
|
||||||
|
{
|
||||||
|
imagedestroy($thumb);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unset($thumb);
|
||||||
|
}
|
||||||
return $output;
|
return $output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -393,7 +393,7 @@ class ModuleHandler extends Handler
|
||||||
// check CSRF for non-GET (POST, PUT, etc.) actions
|
// check CSRF for non-GET (POST, PUT, etc.) actions
|
||||||
if(!in_array(Context::getRequestMethod(), self::$_nocsrf_methods) && Context::isInstalled())
|
if(!in_array(Context::getRequestMethod(), self::$_nocsrf_methods) && Context::isInstalled())
|
||||||
{
|
{
|
||||||
if(isset($xml_info->action->{$this->act}) && $xml_info->action->{$this->act}->check_csrf !== 'false' && !checkCSRF())
|
if(isset($xml_info->action->{$this->act}) && $xml_info->action->{$this->act}->check_csrf !== 'false' && !Rhymix\Framework\Security::checkCSRF())
|
||||||
{
|
{
|
||||||
return self::_createErrorMessage(-1, 'msg_security_violation', 403, 'ERR_CSRF_CHECK_FAILED');
|
return self::_createErrorMessage(-1, 'msg_security_violation', 403, 'ERR_CSRF_CHECK_FAILED');
|
||||||
}
|
}
|
||||||
|
|
@ -555,7 +555,7 @@ class ModuleHandler extends Handler
|
||||||
// check CSRF for non-GET (POST, PUT, etc.) actions
|
// check CSRF for non-GET (POST, PUT, etc.) actions
|
||||||
if(!in_array(Context::getRequestMethod(), self::$_nocsrf_methods) && Context::isInstalled())
|
if(!in_array(Context::getRequestMethod(), self::$_nocsrf_methods) && Context::isInstalled())
|
||||||
{
|
{
|
||||||
if($xml_info->action->{$this->act} && $xml_info->action->{$this->act}->check_csrf !== 'false' && !checkCSRF())
|
if($xml_info->action->{$this->act} && $xml_info->action->{$this->act}->check_csrf !== 'false' && !Rhymix\Framework\Security::checkCSRF())
|
||||||
{
|
{
|
||||||
return self::_createErrorMessage(-1, 'msg_security_violation', 403, 'ERR_CSRF_CHECK_FAILED');
|
return self::_createErrorMessage(-1, 'msg_security_violation', 403, 'ERR_CSRF_CHECK_FAILED');
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
/**
|
/**
|
||||||
* RX_VERSION is the version number of the Rhymix CMS.
|
* RX_VERSION is the version number of the Rhymix CMS.
|
||||||
*/
|
*/
|
||||||
define('RX_VERSION', '2.1.27');
|
define('RX_VERSION', '2.1.29');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RX_MICROTIME is the startup time of the current script, in microseconds since the Unix epoch.
|
* RX_MICROTIME is the startup time of the current script, in microseconds since the Unix epoch.
|
||||||
|
|
|
||||||
|
|
@ -962,7 +962,7 @@ class DB
|
||||||
public function getColumnInfo(string $table_name, string $column_name): ?object
|
public function getColumnInfo(string $table_name, string $column_name): ?object
|
||||||
{
|
{
|
||||||
// If column information is not found, return null.
|
// If column information is not found, return null.
|
||||||
$stmt = $this->_handle->query(sprintf("SHOW FIELDS FROM `%s` WHERE Field = '%s'", $this->addQuotes($this->_prefix . $table_name), $this->addQuotes($column_name)));
|
$stmt = $this->_handle->query(sprintf("SHOW FULL COLUMNS FROM `%s` WHERE Field = '%s'", $this->addQuotes($this->_prefix . $table_name), $this->addQuotes($column_name)));
|
||||||
$column_info = $this->fetch($stmt);
|
$column_info = $this->fetch($stmt);
|
||||||
if (!$column_info)
|
if (!$column_info)
|
||||||
{
|
{
|
||||||
|
|
@ -982,6 +982,16 @@ class DB
|
||||||
}
|
}
|
||||||
$xetype = Parsers\DBTableParser::getXEType($dbtype, $size ?: '');
|
$xetype = Parsers\DBTableParser::getXEType($dbtype, $size ?: '');
|
||||||
|
|
||||||
|
// Detect the character set.
|
||||||
|
if (preg_match('/^([a-zA-Z0-9]+)/', $column_info->{'Collation'} ?? '', $matches))
|
||||||
|
{
|
||||||
|
$charset = $matches[1] === 'utf8mb3' ? 'utf8' : $matches[1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$charset = null;
|
||||||
|
}
|
||||||
|
|
||||||
// Return the result as an object.
|
// Return the result as an object.
|
||||||
return (object)array(
|
return (object)array(
|
||||||
'name' => $column_name,
|
'name' => $column_name,
|
||||||
|
|
@ -990,6 +1000,8 @@ class DB
|
||||||
'size' => $size,
|
'size' => $size,
|
||||||
'default_value' => $column_info->{'Default'},
|
'default_value' => $column_info->{'Default'},
|
||||||
'notnull' => strncmp($column_info->{'Null'}, 'NO', 2) == 0 ? true : false,
|
'notnull' => strncmp($column_info->{'Null'}, 'NO', 2) == 0 ? true : false,
|
||||||
|
'charset' => $charset,
|
||||||
|
'collation' => $column_info->{'Collation'} ?: null,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1100,6 +1112,7 @@ class DB
|
||||||
return (object)array(
|
return (object)array(
|
||||||
'name' => $column->Key_name,
|
'name' => $column->Key_name,
|
||||||
'table' => $column->Table,
|
'table' => $column->Table,
|
||||||
|
'type' => $column->Index_type,
|
||||||
'is_unique' => $is_unique,
|
'is_unique' => $is_unique,
|
||||||
'columns' => $columns,
|
'columns' => $columns,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -28,11 +28,11 @@ class DateTime
|
||||||
{
|
{
|
||||||
if ($format === self::FORMAT_RELATIVE)
|
if ($format === self::FORMAT_RELATIVE)
|
||||||
{
|
{
|
||||||
return self::getRelativeTimestamp($timestamp ?: time());
|
return self::getRelativeTimestamp($timestamp ?? time());
|
||||||
}
|
}
|
||||||
|
|
||||||
$offset = Config::get('locale.internal_timezone') ?: date('Z', $timestamp);
|
$offset = Config::get('locale.internal_timezone') ?: date('Z', $timestamp ?? time());
|
||||||
return gmdate($format, ($timestamp ?: time()) + $offset);
|
return gmdate($format, ($timestamp ?? time()) + $offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -46,7 +46,7 @@ class DateTime
|
||||||
{
|
{
|
||||||
if ($format === self::FORMAT_RELATIVE)
|
if ($format === self::FORMAT_RELATIVE)
|
||||||
{
|
{
|
||||||
return self::getRelativeTimestamp($timestamp ?: time());
|
return self::getRelativeTimestamp($timestamp ?? time());
|
||||||
}
|
}
|
||||||
|
|
||||||
$timezone = self::getTimezoneForCurrentUser();
|
$timezone = self::getTimezoneForCurrentUser();
|
||||||
|
|
@ -55,7 +55,7 @@ class DateTime
|
||||||
self::$_timezones[$timezone] = new \DateTimeZone($timezone);
|
self::$_timezones[$timezone] = new \DateTimeZone($timezone);
|
||||||
}
|
}
|
||||||
$datetime = new \DateTime();
|
$datetime = new \DateTime();
|
||||||
$datetime->setTimestamp($timestamp ?: time());
|
$datetime->setTimestamp($timestamp ?? time());
|
||||||
$datetime->setTimezone(self::$_timezones[$timezone]);
|
$datetime->setTimezone(self::$_timezones[$timezone]);
|
||||||
return $datetime->format($format);
|
return $datetime->format($format);
|
||||||
}
|
}
|
||||||
|
|
@ -123,7 +123,7 @@ class DateTime
|
||||||
self::$_timezones[$timezone] = new \DateTimeZone($timezone);
|
self::$_timezones[$timezone] = new \DateTimeZone($timezone);
|
||||||
}
|
}
|
||||||
$datetime = new \DateTime();
|
$datetime = new \DateTime();
|
||||||
$datetime->setTimestamp($timestamp ?: time());
|
$datetime->setTimestamp($timestamp ?? time());
|
||||||
$datetime->setTimezone(self::$_timezones[$timezone]);
|
$datetime->setTimezone(self::$_timezones[$timezone]);
|
||||||
return $datetime->getOffset();
|
return $datetime->getOffset();
|
||||||
}
|
}
|
||||||
|
|
@ -137,7 +137,7 @@ class DateTime
|
||||||
*/
|
*/
|
||||||
public static function getTimezoneOffsetFromInternal(string $timezone, ?int $timestamp = null): int
|
public static function getTimezoneOffsetFromInternal(string $timezone, ?int $timestamp = null): int
|
||||||
{
|
{
|
||||||
return self::getTimezoneOffset($timezone, $timestamp ?: time()) - Config::get('locale.internal_timezone');
|
return self::getTimezoneOffset($timezone, $timestamp ?? time()) - Config::get('locale.internal_timezone');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -192,7 +192,7 @@ class DateTime
|
||||||
*/
|
*/
|
||||||
public static function getRelativeTimestamp(?int $timestamp = null): string
|
public static function getRelativeTimestamp(?int $timestamp = null): string
|
||||||
{
|
{
|
||||||
$diff = \RX_TIME - intval($timestamp ?: time());
|
$diff = \RX_TIME - intval($timestamp ?? time());
|
||||||
$langs = lang('common.time_gap');
|
$langs = lang('common.time_gap');
|
||||||
|
|
||||||
if ($diff < 3)
|
if ($diff < 3)
|
||||||
|
|
|
||||||
|
|
@ -865,7 +865,14 @@ class Template
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return sprintf(' %s="%s"', $attribute, escape(implode($delimiters[$attribute], $values), false));
|
if (count($values))
|
||||||
|
{
|
||||||
|
return sprintf(' %s="%s"', $attribute, escape(implode($delimiters[$attribute], $values), false));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -156,7 +156,7 @@ class TemplateParser_v1
|
||||||
// if not exists default hidden tag, generate hidden tag
|
// if not exists default hidden tag, generate hidden tag
|
||||||
if ($autoform)
|
if ($autoform)
|
||||||
{
|
{
|
||||||
preg_match_all('/<input[^>]* name="(act|mid)"/is', $matches[2], $m2);
|
preg_match_all('/<(?:input|select)[^>]* name="(act|mid)"/is', $matches[2], $m2);
|
||||||
$missing_inputs = array_diff(['act', 'mid'], $m2[1]);
|
$missing_inputs = array_diff(['act', 'mid'], $m2[1]);
|
||||||
if(is_array($missing_inputs))
|
if(is_array($missing_inputs))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1084,6 +1084,37 @@ class TemplateParser_v2
|
||||||
*/
|
*/
|
||||||
protected function _convertVariableScope(string $content): string
|
protected function _convertVariableScope(string $content): string
|
||||||
{
|
{
|
||||||
|
// Pre-escape function declarations and closures so that variables inside them are not converted.
|
||||||
|
$used_vars = [];
|
||||||
|
$function_regexp = '#\b(function(?:\s+[a-zA-Z_][a-zA-Z0-9_]*)?)' .
|
||||||
|
'(\s*)(' . self::_getRegexpForParentheses(3) . ')' .
|
||||||
|
'(\s*)(use\s*\([^()]+\))?' .
|
||||||
|
'(\s*:\s*\w+)?' .
|
||||||
|
'(\s*)(' . self::_getRegexpForCurlyBraces(8) . ')#';
|
||||||
|
$content = preg_replace_callback($function_regexp, function($match) use (&$used_vars) {
|
||||||
|
$fn = $match[1] . $match[2] . self::_escapeVars($match[3]) .
|
||||||
|
$match[4] . self::_escapeVars($match[5]) .
|
||||||
|
$match[6] . $match[7] . self::_escapeVars($match[8]);
|
||||||
|
if (str_starts_with($match[5], 'use'))
|
||||||
|
{
|
||||||
|
preg_match_all('#\$([a-zA-Z_][a-zA-Z0-9_]*)#', $match[5], $uses);
|
||||||
|
foreach ($uses[1] as $var)
|
||||||
|
{
|
||||||
|
$used_vars[$var] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $fn;
|
||||||
|
}, $content);
|
||||||
|
if (count($used_vars))
|
||||||
|
{
|
||||||
|
$prefix = ' ';
|
||||||
|
foreach ($used_vars as $var => $unused)
|
||||||
|
{
|
||||||
|
$prefix .= self::_escapeVars('$' . $var) . ' = &$__Context->' . $var . '; ';
|
||||||
|
}
|
||||||
|
$content = $prefix . $content;
|
||||||
|
}
|
||||||
|
|
||||||
// Replace variables that need to be enclosed in curly braces, using temporary entities to prevent double-replacement.
|
// Replace variables that need to be enclosed in curly braces, using temporary entities to prevent double-replacement.
|
||||||
$content = preg_replace_callback('#(?<!\$__Context)->\$([a-zA-Z_][a-zA-Z0-9_]*)#', function($match) {
|
$content = preg_replace_callback('#(?<!\$__Context)->\$([a-zA-Z_][a-zA-Z0-9_]*)#', function($match) {
|
||||||
return '->' . self::_escapeCurly('{') . '$__Context->' . $match[1] . self::_escapeCurly('}');
|
return '->' . self::_escapeCurly('{') . '$__Context->' . $match[1] . self::_escapeCurly('}');
|
||||||
|
|
@ -1144,6 +1175,17 @@ class TemplateParser_v2
|
||||||
return '\([^)(]*+(?:(?' . $position_in_regexp . ')[^)(]*)*+\)';
|
return '\([^)(]*+(?:(?' . $position_in_regexp . ')[^)(]*)*+\)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Same as above, but for curly braces.
|
||||||
|
*
|
||||||
|
* @param int $position_in_regexp
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected static function _getRegexpForCurlyBraces(int $position_in_regexp): string
|
||||||
|
{
|
||||||
|
return '\{[^}{]*+(?:(?' . $position_in_regexp . ')[^}{]*)*+\}';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Escape curly braces so that they will not be interpreted as echo statements.
|
* Escape curly braces so that they will not be interpreted as echo statements.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -284,6 +284,7 @@ class Cleanup extends Base
|
||||||
'addons/member_communication/' => 'deleted:xe',
|
'addons/member_communication/' => 'deleted:xe',
|
||||||
'addons/mobile/' => 'deleted:xe',
|
'addons/mobile/' => 'deleted:xe',
|
||||||
'addons/openid_delegation_id/' => 'deleted:xe',
|
'addons/openid_delegation_id/' => 'deleted:xe',
|
||||||
|
'admin/' => 'deleted:xe',
|
||||||
'classes/cache/CacheApc.class.php' => 'deleted:xe',
|
'classes/cache/CacheApc.class.php' => 'deleted:xe',
|
||||||
'classes/cache/CacheFile.class.php' => 'deleted:xe',
|
'classes/cache/CacheFile.class.php' => 'deleted:xe',
|
||||||
'classes/cache/CacheMemcache.class.php' => 'deleted:xe',
|
'classes/cache/CacheMemcache.class.php' => 'deleted:xe',
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,10 @@ class Utility
|
||||||
public static function cleanHeaderAndFooterScripts(string $content)
|
public static function cleanHeaderAndFooterScripts(string $content)
|
||||||
{
|
{
|
||||||
$content = utf8_clean($content);
|
$content = utf8_clean($content);
|
||||||
$content = preg_replace('!</?(html|head|body)[^>]*>!', '', $content);
|
$content = preg_replace('!</?(html|head|body)[^>]*>!i', '', $content);
|
||||||
|
$content = preg_replace_callback('!<script\b([^>]*?)language=[\'"]javascript[\'"]!i', function ($matches) {
|
||||||
|
return trim('<script ' . trim($matches[1]));
|
||||||
|
}, $content);
|
||||||
return utf8_trim($content);
|
return utf8_trim($content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -342,6 +342,7 @@ class autoinstallAdminView extends autoinstall
|
||||||
$buff = FileHandler::getRemoteResource($config->download_server, $body, 3, "POST", "application/xml", array(), array(), array(), $request_config);
|
$buff = FileHandler::getRemoteResource($config->download_server, $body, 3, "POST", "application/xml", array(), array(), array(), $request_config);
|
||||||
$xml_lUpdate = new XeXmlParser();
|
$xml_lUpdate = new XeXmlParser();
|
||||||
$xmlDoc = $xml_lUpdate->parse($buff);
|
$xmlDoc = $xml_lUpdate->parse($buff);
|
||||||
|
$item_list = array();
|
||||||
$res = array();
|
$res = array();
|
||||||
if($xmlDoc && $xmlDoc->response->packagelist->item)
|
if($xmlDoc && $xmlDoc->response->packagelist->item)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,7 @@ class BoardAdminView extends Board {
|
||||||
|
|
||||||
$output = executeQueryArray('board.getBoardList', $args);
|
$output = executeQueryArray('board.getBoardList', $args);
|
||||||
ModuleModel::syncModuleToSite($output->data);
|
ModuleModel::syncModuleToSite($output->data);
|
||||||
|
ModuleModel::addModuleExtraVars($output->data);
|
||||||
|
|
||||||
// get the skins path
|
// get the skins path
|
||||||
$oModuleModel = getModel('module');
|
$oModuleModel = getModel('module');
|
||||||
|
|
|
||||||
|
|
@ -842,6 +842,23 @@ class BoardController extends Board
|
||||||
$oMemberController->addMemberPopupMenu($url, 'cmd_view_own_document', '', 'self', 'board_own_document');
|
$oMemberController->addMemberPopupMenu($url, 'cmd_view_own_document', '', 'self', 'board_own_document');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trigger called at module copy
|
||||||
|
*/
|
||||||
|
public function triggerCopyModule(&$obj)
|
||||||
|
{
|
||||||
|
$board_config = ModuleModel::getModulePartConfig('board', $obj->originModuleSrl);
|
||||||
|
|
||||||
|
$oModuleController = ModuleController::getInstance();
|
||||||
|
if (is_array($obj->moduleSrlList))
|
||||||
|
{
|
||||||
|
foreach ($obj->moduleSrlList as $module_srl)
|
||||||
|
{
|
||||||
|
$oModuleController->insertModulePartConfig('board', $module_srl, $board_config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an anonymous nickname.
|
* Create an anonymous nickname.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -130,6 +130,7 @@
|
||||||
<eventHandlers>
|
<eventHandlers>
|
||||||
<eventHandler after="member.getMemberMenu" class="controller" method="triggerMemberMenu" />
|
<eventHandler after="member.getMemberMenu" class="controller" method="triggerMemberMenu" />
|
||||||
<eventHandler after="menu.getModuleListInSitemap" class="model" method="triggerModuleListInSitemap" />
|
<eventHandler after="menu.getModuleListInSitemap" class="model" method="triggerModuleListInSitemap" />
|
||||||
|
<eventHandler after="module.procModuleAdminCopyModule" class="controller" method="triggerCopyModule" />
|
||||||
</eventHandlers>
|
</eventHandlers>
|
||||||
<menus>
|
<menus>
|
||||||
<menu name="board" type="all">
|
<menu name="board" type="all">
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
$lang->board = 'Board';
|
$lang->board = 'Board';
|
||||||
|
$lang->board_special_features = 'Features';
|
||||||
$lang->except_notice = 'Exclude Notices';
|
$lang->except_notice = 'Exclude Notices';
|
||||||
$lang->use_bottom_list = 'Display Bottom List';
|
$lang->use_bottom_list = 'Display Bottom List';
|
||||||
$lang->customize_bottom_list = 'Customize Bottom List';
|
$lang->customize_bottom_list = 'Customize Bottom List';
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
$lang->board = '게시판';
|
$lang->board = '게시판';
|
||||||
|
$lang->board_special_features = '특이사항';
|
||||||
$lang->except_notice = '공지사항 제외';
|
$lang->except_notice = '공지사항 제외';
|
||||||
$lang->use_bottom_list = '하단목록 표시';
|
$lang->use_bottom_list = '하단목록 표시';
|
||||||
$lang->customize_bottom_list = '하단목록 설정';
|
$lang->customize_bottom_list = '하단목록 설정';
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
<th scope="col" class="domain_prefix">{$lang->domain} /</th>
|
<th scope="col" class="domain_prefix">{$lang->domain} /</th>
|
||||||
<th scope="col">{$lang->url}</th>
|
<th scope="col">{$lang->url}</th>
|
||||||
<th scope="col">{$lang->browser_title}</th>
|
<th scope="col">{$lang->browser_title}</th>
|
||||||
|
<th scope="col">{$lang->board_special_features}</th>
|
||||||
<th scope="col">{$lang->regdate}</th>
|
<th scope="col">{$lang->regdate}</th>
|
||||||
<th scope="col">{$lang->cmd_edit}</th>
|
<th scope="col">{$lang->cmd_edit}</th>
|
||||||
<th scope="col"><input type="checkbox" data-name="cart" title="Check All" /></th>
|
<th scope="col"><input type="checkbox" data-name="cart" title="Check All" /></th>
|
||||||
|
|
@ -40,6 +41,17 @@
|
||||||
</td>
|
</td>
|
||||||
<td>{$val->mid}</td>
|
<td>{$val->mid}</td>
|
||||||
<td><a href="{getSiteUrl($val->domain,'','mid',$val->mid)}" target="_blank">{$val->browser_title}</a></td>
|
<td><a href="{getSiteUrl($val->domain,'','mid',$val->mid)}" target="_blank">{$val->browser_title}</a></td>
|
||||||
|
<td>
|
||||||
|
<!--@if($val->consultation === 'Y')-->
|
||||||
|
<span title="{$lang->consultation}"><i class="xi-headset"></i></span>
|
||||||
|
<!--@end-->
|
||||||
|
<!--@if($val->use_anonymous === 'Y')-->
|
||||||
|
<span title="{$lang->use_anonymous}"><i class="xi-user-lock"></i></span>
|
||||||
|
<!--@end-->
|
||||||
|
<!--@if(!empty($val->include_modules))-->
|
||||||
|
<span title="{$lang->cmd_board_combined_board}"><i class="xi-file-add"></i></span>
|
||||||
|
<!--@end-->
|
||||||
|
</td>
|
||||||
<td>{zdate($val->regdate,"Y-m-d")}</td>
|
<td>{zdate($val->regdate,"Y-m-d")}</td>
|
||||||
<td>
|
<td>
|
||||||
<a href="{getUrl('act','dispBoardAdminBoardInfo','module_srl',$val->module_srl)}"><i class="x_icon-cog"></i> {$lang->cmd_setup}</a>
|
<a href="{getUrl('act','dispBoardAdminBoardInfo','module_srl',$val->module_srl)}"><i class="x_icon-cog"></i> {$lang->cmd_setup}</a>
|
||||||
|
|
|
||||||
|
|
@ -517,7 +517,7 @@ class CommentController extends Comment
|
||||||
*/
|
*/
|
||||||
function insertComment($obj, $manual_inserted = FALSE, $update_document = TRUE)
|
function insertComment($obj, $manual_inserted = FALSE, $update_document = TRUE)
|
||||||
{
|
{
|
||||||
if(!$manual_inserted && !checkCSRF())
|
if(!$manual_inserted && !Rhymix\Framework\Security::checkCSRF())
|
||||||
{
|
{
|
||||||
return new BaseObject(-1, 'msg_security_violation');
|
return new BaseObject(-1, 'msg_security_violation');
|
||||||
}
|
}
|
||||||
|
|
@ -677,23 +677,26 @@ class CommentController extends Comment
|
||||||
}
|
}
|
||||||
|
|
||||||
// if use editor of nohtml, Remove HTML tags from the contents.
|
// if use editor of nohtml, Remove HTML tags from the contents.
|
||||||
if(!$manual_inserted || isset($obj->allow_html) || isset($obj->use_html))
|
if (!$manual_inserted || isset($obj->allow_html) || isset($obj->use_html))
|
||||||
{
|
{
|
||||||
$obj->content = EditorModel::converter($obj, 'comment');
|
$obj->content = EditorModel::converter($obj, 'comment');
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove iframe and script if not a top administrator on the session.
|
// remove iframe and script if not a top administrator on the session.
|
||||||
if($logged_info->is_admin != 'Y')
|
if ($logged_info->is_admin !== 'Y')
|
||||||
{
|
{
|
||||||
$obj->content = removeHackTag($obj->content);
|
$obj->content = Rhymix\Framework\Filters\HTMLFilter::clean((string)$obj->content);
|
||||||
|
}
|
||||||
|
if (config('db.master.charset') !== 'utf8mb4')
|
||||||
|
{
|
||||||
|
$obj->content = utf8_mbencode($obj->content);
|
||||||
}
|
}
|
||||||
$obj->content = utf8_mbencode($obj->content);
|
|
||||||
|
|
||||||
|
// Set other flags.
|
||||||
if (isset($obj->notify_message) && $obj->notify_message !== 'Y')
|
if (isset($obj->notify_message) && $obj->notify_message !== 'Y')
|
||||||
{
|
{
|
||||||
$obj->notify_message = 'N';
|
$obj->notify_message = 'N';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($obj->is_secret) && $obj->is_secret !== 'Y')
|
if (isset($obj->is_secret) && $obj->is_secret !== 'Y')
|
||||||
{
|
{
|
||||||
$obj->is_secret = 'N';
|
$obj->is_secret = 'N';
|
||||||
|
|
@ -951,7 +954,7 @@ class CommentController extends Comment
|
||||||
*/
|
*/
|
||||||
function updateComment($obj, $skip_grant_check = FALSE, $manual_updated = FALSE)
|
function updateComment($obj, $skip_grant_check = FALSE, $manual_updated = FALSE)
|
||||||
{
|
{
|
||||||
if(!$manual_updated && !checkCSRF())
|
if(!$manual_updated && !Rhymix\Framework\Security::checkCSRF())
|
||||||
{
|
{
|
||||||
return new BaseObject(-1, 'msg_security_violation');
|
return new BaseObject(-1, 'msg_security_violation');
|
||||||
}
|
}
|
||||||
|
|
@ -1042,11 +1045,14 @@ class CommentController extends Comment
|
||||||
|
|
||||||
// remove iframe and script if not a top administrator on the session
|
// remove iframe and script if not a top administrator on the session
|
||||||
$logged_info = Context::get('logged_info');
|
$logged_info = Context::get('logged_info');
|
||||||
if($logged_info->is_admin != 'Y')
|
if ($logged_info->is_admin !== 'Y')
|
||||||
{
|
{
|
||||||
$obj->content = removeHackTag($obj->content);
|
$obj->content = Rhymix\Framework\Filters\HTMLFilter::clean((string)$obj->content);
|
||||||
|
}
|
||||||
|
if (config('db.master.charset') !== 'utf8mb4')
|
||||||
|
{
|
||||||
|
$obj->content = utf8_mbencode($obj->content);
|
||||||
}
|
}
|
||||||
$obj->content = utf8_mbencode($obj->content);
|
|
||||||
|
|
||||||
// begin transaction
|
// begin transaction
|
||||||
$oDB = DB::getInstance();
|
$oDB = DB::getInstance();
|
||||||
|
|
|
||||||
|
|
@ -308,7 +308,7 @@ class CommentModel extends Comment
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the total number of comments in corresponding with document_srl.
|
* Get the total number of comments posted on the given date.
|
||||||
* @param string $date
|
* @param string $date
|
||||||
* @param array $moduleList
|
* @param array $moduleList
|
||||||
* @param array $statusList
|
* @param array $statusList
|
||||||
|
|
@ -1271,36 +1271,74 @@ class CommentModel extends Comment
|
||||||
return (int) $output->data->count;
|
return (int) $output->data->count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get comment list of the doc in corresponding woth member_srl.
|
* Get the total number of comments posted on the given document by the given member.
|
||||||
|
*
|
||||||
|
* @param int $document_srl
|
||||||
* @param int $member_srl
|
* @param int $member_srl
|
||||||
* @param array $columnList
|
|
||||||
* @param int $unused1 (Previously $page)
|
|
||||||
* @param int $unused2 (Previously $is_admin)
|
|
||||||
* @param int $count
|
|
||||||
* @param array $statusList
|
* @param array $statusList
|
||||||
* @return object
|
* @return int
|
||||||
*/
|
*/
|
||||||
public static function getCommentListByMemberSrl($member_srl, $columnList = [], $unused1 = 0, $unused2 = 0, $count = 0, $statusList = [])
|
public static function getCommentCountByDocumentSrlAndMemberSrl($document_srl, $member_srl, $statusList = [])
|
||||||
{
|
{
|
||||||
$args = new stdClass();
|
$args = new stdClass();
|
||||||
|
$args->document_srl = $document_srl;
|
||||||
$args->member_srl = $member_srl;
|
$args->member_srl = $member_srl;
|
||||||
$args->list_count = $count;
|
|
||||||
if ($statusList)
|
if ($statusList)
|
||||||
{
|
{
|
||||||
$args->statusList = $statusList;
|
$args->statusList = $statusList;
|
||||||
}
|
}
|
||||||
$output = executeQuery('comment.getCommentListByMemberSrl', $args, $columnList);
|
$output = executeQuery('comment.getCommentCountByMemberSrl', $args);
|
||||||
$comment_list = $output->data;
|
return (int) $output->data->count;
|
||||||
|
|
||||||
if(!$comment_list) return array();
|
|
||||||
if(!is_array($comment_list)) $comment_list = array($comment_list);
|
|
||||||
|
|
||||||
return $comment_list;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of comments posted by the given member.
|
||||||
|
*
|
||||||
|
* @param int $member_srl
|
||||||
|
* @param array $columnList
|
||||||
|
* @param int $unused1 (Previously $page)
|
||||||
|
* @param int $unused2 (Previously $is_admin)
|
||||||
|
* @param int $list_count
|
||||||
|
* @param array $statusList
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function getCommentListByMemberSrl($member_srl, $columnList = [], $unused1 = 0, $unused2 = 0, $list_count = 0, $statusList = [])
|
||||||
|
{
|
||||||
|
$args = new stdClass();
|
||||||
|
$args->member_srl = $member_srl;
|
||||||
|
$args->list_count = $list_count;
|
||||||
|
if ($statusList)
|
||||||
|
{
|
||||||
|
$args->statusList = $statusList;
|
||||||
|
}
|
||||||
|
$output = executeQueryArray('comment.getCommentListByMemberSrl', $args, $columnList);
|
||||||
|
return $output->data ?? [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of comments posted on the given document by the given member.
|
||||||
|
*
|
||||||
|
* @param int $document_srl
|
||||||
|
* @param int $member_srl
|
||||||
|
* @param int $list_count
|
||||||
|
* @param array $columnList
|
||||||
|
* @param array $statusList
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function getCommentListByDocumentSrlAndMemberSrl($document_srl, $member_srl, $list_count = 0, $columnList = [], $statusList = [])
|
||||||
|
{
|
||||||
|
$args = new stdClass();
|
||||||
|
$args->document_srl = $document_srl;
|
||||||
|
$args->member_srl = $member_srl;
|
||||||
|
$args->list_count = $list_count;
|
||||||
|
if ($statusList)
|
||||||
|
{
|
||||||
|
$args->statusList = $statusList;
|
||||||
|
}
|
||||||
|
$output = executeQueryArray('comment.getCommentListByMemberSrl', $args, $columnList);
|
||||||
|
return $output->data ?? [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* End of file comment.model.php */
|
/* End of file comment.model.php */
|
||||||
/* Location: ./modules/comment/comment.model.php */
|
/* Location: ./modules/comment/comment.model.php */
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@
|
||||||
</columns>
|
</columns>
|
||||||
<conditions>
|
<conditions>
|
||||||
<condition operation="equal" column="member_srl" var="member_srl" filter="number" notnull="notnull" />
|
<condition operation="equal" column="member_srl" var="member_srl" filter="number" notnull="notnull" />
|
||||||
|
<condition operation="equal" column="module_srl" var="module_srl" filter="number" />
|
||||||
|
<condition operation="equal" column="document_srl" var="document_srl" filter="number" />
|
||||||
<condition operation="equal" column="status" var="status" pipe="and" />
|
<condition operation="equal" column="status" var="status" pipe="and" />
|
||||||
<condition operation="in" column="status" var="statusList" pipe="and" />
|
<condition operation="in" column="status" var="statusList" pipe="and" />
|
||||||
</conditions>
|
</conditions>
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,9 @@
|
||||||
</columns>
|
</columns>
|
||||||
<conditions>
|
<conditions>
|
||||||
<condition operation="equal" column="member_srl" var="member_srl" filter="number" notnull="notnull" />
|
<condition operation="equal" column="member_srl" var="member_srl" filter="number" notnull="notnull" />
|
||||||
|
<condition operation="equal" column="module_srl" var="module_srl" filter="number" />
|
||||||
|
<condition operation="equal" column="document_srl" var="document_srl" filter="number" />
|
||||||
|
<condition operation="equal" column="status" var="status" pipe="and" />
|
||||||
<condition operation="in" column="status" var="statusList" pipe="and" />
|
<condition operation="in" column="status" var="statusList" pipe="and" />
|
||||||
</conditions>
|
</conditions>
|
||||||
<navigation>
|
<navigation>
|
||||||
|
|
|
||||||
|
|
@ -184,9 +184,12 @@ class CommunicationController extends communication
|
||||||
{
|
{
|
||||||
// Encode the title and content.
|
// Encode the title and content.
|
||||||
$title = escape($title, false);
|
$title = escape($title, false);
|
||||||
$content = removeHackTag($content);
|
$content = Rhymix\Framework\Filters\HTMLFilter::clean((string)$content);
|
||||||
$title = utf8_mbencode($title);
|
if (config('db.master.charset') !== 'utf8mb4')
|
||||||
$content = utf8_mbencode($content);
|
{
|
||||||
|
$title = utf8_mbencode($title);
|
||||||
|
$content = utf8_mbencode($content);
|
||||||
|
}
|
||||||
|
|
||||||
$message_srl = $temp_srl ?: getNextSequence();
|
$message_srl = $temp_srl ?: getNextSequence();
|
||||||
$related_srl = getNextSequence();
|
$related_srl = getNextSequence();
|
||||||
|
|
@ -309,7 +312,7 @@ class CommunicationController extends communication
|
||||||
|
|
||||||
$mail_content = vsprintf('From: %s<br><hr><br>%s<br><hr><br>%s<br><a href="%s" target="_blank">%s</a>', [
|
$mail_content = vsprintf('From: %s<br><hr><br>%s<br><hr><br>%s<br><a href="%s" target="_blank">%s</a>', [
|
||||||
$sender->nick_name,
|
$sender->nick_name,
|
||||||
utf8_mbencode(removeHackTag($content)),
|
utf8_mbencode(Rhymix\Framework\Filters\HTMLFilter::clean((string)$content)),
|
||||||
Context::getSiteTitle(),
|
Context::getSiteTitle(),
|
||||||
$view_url, $view_url,
|
$view_url, $view_url,
|
||||||
]);
|
]);
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,7 @@ class Document extends ModuleObject
|
||||||
// 2025.10.23 Add sort to document_extra_keys table, and sort_value to document_extra_vars table
|
// 2025.10.23 Add sort to document_extra_keys table, and sort_value to document_extra_vars table
|
||||||
if(!$oDB->isColumnExists('document_extra_keys', 'var_sort')) return true;
|
if(!$oDB->isColumnExists('document_extra_keys', 'var_sort')) return true;
|
||||||
if(!$oDB->isColumnExists('document_extra_vars', 'sort_value') || !$oDB->isIndexExists('document_extra_vars', 'idx_sort_value')) return true;
|
if(!$oDB->isColumnExists('document_extra_vars', 'sort_value') || !$oDB->isIndexExists('document_extra_vars', 'idx_sort_value')) return true;
|
||||||
|
if(!$oDB->isIndexExists('document_extra_vars', 'idx_document_var_idx')) return true;
|
||||||
if(!$oDB->isIndexExists('document_extra_vars', 'idx_prefix_value')) return true;
|
if(!$oDB->isIndexExists('document_extra_vars', 'idx_prefix_value')) return true;
|
||||||
|
|
||||||
// Delete unnecessary index
|
// Delete unnecessary index
|
||||||
|
|
@ -238,6 +239,7 @@ class Document extends ModuleObject
|
||||||
if(!$oDB->isColumnExists('document_extra_keys', 'var_sort'))
|
if(!$oDB->isColumnExists('document_extra_keys', 'var_sort'))
|
||||||
{
|
{
|
||||||
$oDB->addColumn('document_extra_keys', 'var_sort', 'char', '1', 'N', true, 'var_search');
|
$oDB->addColumn('document_extra_keys', 'var_sort', 'char', '1', 'N', true, 'var_search');
|
||||||
|
Rhymix\Framework\Cache::clearGroup('site_and_module');
|
||||||
}
|
}
|
||||||
if(!$oDB->isColumnExists('document_extra_vars', 'sort_value') || !$oDB->isIndexExists('document_extra_vars', 'idx_sort_value'))
|
if(!$oDB->isColumnExists('document_extra_vars', 'sort_value') || !$oDB->isIndexExists('document_extra_vars', 'idx_sort_value'))
|
||||||
{
|
{
|
||||||
|
|
@ -264,6 +266,10 @@ class Document extends ModuleObject
|
||||||
$oDB->commit();
|
$oDB->commit();
|
||||||
$oDB->addIndex('document_extra_vars', 'idx_sort_value', array('module_srl', 'sort_value'));
|
$oDB->addIndex('document_extra_vars', 'idx_sort_value', array('module_srl', 'sort_value'));
|
||||||
}
|
}
|
||||||
|
if(!$oDB->isIndexExists('document_extra_vars', 'idx_document_var_idx'))
|
||||||
|
{
|
||||||
|
$oDB->addIndex('document_extra_vars', 'idx_document_var_idx', array('document_srl', 'var_idx'));
|
||||||
|
}
|
||||||
if(!$oDB->isIndexExists('document_extra_vars', 'idx_prefix_value'))
|
if(!$oDB->isIndexExists('document_extra_vars', 'idx_prefix_value'))
|
||||||
{
|
{
|
||||||
$oDB->addIndex('document_extra_vars', 'idx_prefix_value', array('module_srl', 'value(10)'));
|
$oDB->addIndex('document_extra_vars', 'idx_prefix_value', array('module_srl', 'value(10)'));
|
||||||
|
|
|
||||||
|
|
@ -612,7 +612,7 @@ class DocumentController extends Document
|
||||||
*/
|
*/
|
||||||
function insertDocument($obj, $manual_inserted = false, $isRestore = false, $isLatest = true)
|
function insertDocument($obj, $manual_inserted = false, $isRestore = false, $isLatest = true)
|
||||||
{
|
{
|
||||||
if (!$manual_inserted && !checkCSRF())
|
if (!$manual_inserted && !Rhymix\Framework\Security::checkCSRF())
|
||||||
{
|
{
|
||||||
return new BaseObject(-1, 'msg_security_violation');
|
return new BaseObject(-1, 'msg_security_violation');
|
||||||
}
|
}
|
||||||
|
|
@ -713,7 +713,7 @@ class DocumentController extends Document
|
||||||
$obj->user_id = htmlspecialchars_decode($logged_info->user_id);
|
$obj->user_id = htmlspecialchars_decode($logged_info->user_id);
|
||||||
$obj->user_name = htmlspecialchars_decode($logged_info->user_name);
|
$obj->user_name = htmlspecialchars_decode($logged_info->user_name);
|
||||||
$obj->nick_name = htmlspecialchars_decode($logged_info->nick_name);
|
$obj->nick_name = htmlspecialchars_decode($logged_info->nick_name);
|
||||||
$obj->email_address = $logged_info->email_address;
|
$obj->email_address = $logged_info->email_address ?? '';
|
||||||
$obj->homepage = $logged_info->homepage;
|
$obj->homepage = $logged_info->homepage;
|
||||||
}
|
}
|
||||||
if(!$logged_info->member_srl && !$manual_inserted && !$isRestore)
|
if(!$logged_info->member_srl && !$manual_inserted && !$isRestore)
|
||||||
|
|
@ -816,24 +816,31 @@ class DocumentController extends Document
|
||||||
}
|
}
|
||||||
|
|
||||||
// if use editor of nohtml, Remove HTML tags from the contents.
|
// if use editor of nohtml, Remove HTML tags from the contents.
|
||||||
if(!$manual_inserted || isset($obj->allow_html) || isset($obj->use_html))
|
if (!$manual_inserted || isset($obj->allow_html) || isset($obj->use_html))
|
||||||
{
|
{
|
||||||
$obj->content = EditorModel::converter($obj, 'document');
|
$obj->content = EditorModel::converter($obj, 'document');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove iframe and script if not a top adminisrator in the session.
|
// Remove iframe and script if not a top adminisrator in the session.
|
||||||
if($logged_info->is_admin != 'Y')
|
if ($logged_info->is_admin !== 'Y')
|
||||||
{
|
{
|
||||||
$obj->content = removeHackTag($obj->content);
|
$obj->content = Rhymix\Framework\Filters\HTMLFilter::clean((string)$obj->content);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fix encoding of non-BMP UTF-8 characters.
|
||||||
|
if (config('db.master.charset') !== 'utf8mb4')
|
||||||
|
{
|
||||||
|
$obj->title = utf8_mbencode($obj->title);
|
||||||
|
$obj->content = utf8_mbencode($obj->content);
|
||||||
}
|
}
|
||||||
|
|
||||||
// An error appears if both log-in info and user name don't exist.
|
// An error appears if both log-in info and user name don't exist.
|
||||||
if(!$logged_info->member_srl && !$obj->nick_name) return new BaseObject(-1, 'msg_invalid_request');
|
if (!$logged_info->member_srl && !$obj->nick_name)
|
||||||
|
{
|
||||||
// Fix encoding of non-BMP UTF-8 characters.
|
return new BaseObject(-1, 'msg_invalid_request');
|
||||||
$obj->title = utf8_mbencode($obj->title);
|
}
|
||||||
$obj->content = utf8_mbencode($obj->content);
|
|
||||||
|
|
||||||
|
// Set lang_code to the current user's language
|
||||||
$obj->lang_code = Context::getLangType();
|
$obj->lang_code = Context::getLangType();
|
||||||
|
|
||||||
// begin transaction
|
// begin transaction
|
||||||
|
|
@ -923,7 +930,7 @@ class DocumentController extends Document
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call a trigger (after)
|
// Call a trigger (after)
|
||||||
if($obj->update_log_setting === 'Y')
|
if (isset($obj->update_log_setting) && $obj->update_log_setting === 'Y')
|
||||||
{
|
{
|
||||||
$obj->extra_vars = serialize($extra_vars);
|
$obj->extra_vars = serialize($extra_vars);
|
||||||
$update_output = $this->insertDocumentUpdateLog($obj);
|
$update_output = $this->insertDocumentUpdateLog($obj);
|
||||||
|
|
@ -972,7 +979,7 @@ class DocumentController extends Document
|
||||||
*/
|
*/
|
||||||
function updateDocument($source_obj, $obj, $manual_updated = FALSE)
|
function updateDocument($source_obj, $obj, $manual_updated = FALSE)
|
||||||
{
|
{
|
||||||
if(!$manual_updated && !checkCSRF())
|
if(!$manual_updated && !Rhymix\Framework\Security::checkCSRF())
|
||||||
{
|
{
|
||||||
return new BaseObject(-1, 'msg_security_violation');
|
return new BaseObject(-1, 'msg_security_violation');
|
||||||
}
|
}
|
||||||
|
|
@ -1172,14 +1179,17 @@ class DocumentController extends Document
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove iframe and script if not a top adminisrator in the session.
|
// Remove iframe and script if not a top adminisrator in the session.
|
||||||
if($logged_info->is_admin != 'Y')
|
if ($logged_info->is_admin !== 'Y')
|
||||||
{
|
{
|
||||||
$obj->content = removeHackTag($obj->content);
|
$obj->content = Rhymix\Framework\Filters\HTMLFilter::clean((string)$obj->content);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fix encoding of non-BMP UTF-8 characters.
|
// Fix encoding of non-BMP UTF-8 characters.
|
||||||
$obj->title = utf8_mbencode($obj->title);
|
if (config('db.master.charset') !== 'utf8mb4')
|
||||||
$obj->content = utf8_mbencode($obj->content);
|
{
|
||||||
|
$obj->title = utf8_mbencode($obj->title);
|
||||||
|
$obj->content = utf8_mbencode($obj->content);
|
||||||
|
}
|
||||||
|
|
||||||
// Begin transaction
|
// Begin transaction
|
||||||
$oDB = DB::getInstance();
|
$oDB = DB::getInstance();
|
||||||
|
|
@ -1376,7 +1386,7 @@ class DocumentController extends Document
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update log
|
// Update log
|
||||||
if($obj->update_log_setting === 'Y')
|
if (isset($obj->update_log_setting) && $obj->update_log_setting === 'Y')
|
||||||
{
|
{
|
||||||
$obj->extra_vars = serialize($extra_vars);
|
$obj->extra_vars = serialize($extra_vars);
|
||||||
if($grant->manager)
|
if($grant->manager)
|
||||||
|
|
|
||||||
|
|
@ -65,14 +65,13 @@ class DocumentItem extends BaseObject
|
||||||
* Constructor
|
* Constructor
|
||||||
* @param int $document_srl
|
* @param int $document_srl
|
||||||
* @param bool $load_extra_vars
|
* @param bool $load_extra_vars
|
||||||
* @param array columnList
|
* @param bool $reload_counts
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
function __construct($document_srl = 0, $load_extra_vars = true, $columnList = array())
|
function __construct($document_srl = 0, $load_extra_vars = true, $reload_counts = true)
|
||||||
{
|
{
|
||||||
$this->document_srl = $document_srl;
|
$this->document_srl = $document_srl;
|
||||||
$this->columnList = $columnList;
|
$this->_loadFromDB($load_extra_vars, $reload_counts);
|
||||||
$this->_loadFromDB($load_extra_vars);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function setDocument($document_srl, $load_extra_vars = true)
|
function setDocument($document_srl, $load_extra_vars = true)
|
||||||
|
|
@ -86,23 +85,13 @@ class DocumentItem extends BaseObject
|
||||||
* @param bool $load_extra_vars
|
* @param bool $load_extra_vars
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
function _loadFromDB($load_extra_vars = true)
|
function _loadFromDB($load_extra_vars = true, $reload_counts = true)
|
||||||
{
|
{
|
||||||
if(!$this->document_srl)
|
if(!$this->document_srl)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$document_item = false;
|
|
||||||
$columnList = array();
|
|
||||||
$reload_counts = true;
|
|
||||||
|
|
||||||
if ($this->columnList === false)
|
|
||||||
{
|
|
||||||
$reload_counts = false;
|
|
||||||
}
|
|
||||||
$this->columnList = array();
|
|
||||||
|
|
||||||
// cache controll
|
// cache controll
|
||||||
$cache_key = 'document_item:' . getNumberingPath($this->document_srl) . $this->document_srl;
|
$cache_key = 'document_item:' . getNumberingPath($this->document_srl) . $this->document_srl;
|
||||||
$document_item = Rhymix\Framework\Cache::get($cache_key);
|
$document_item = Rhymix\Framework\Cache::get($cache_key);
|
||||||
|
|
@ -110,8 +99,12 @@ class DocumentItem extends BaseObject
|
||||||
{
|
{
|
||||||
$columnList = array('readed_count', 'voted_count', 'blamed_count', 'comment_count', 'trackback_count');
|
$columnList = array('readed_count', 'voted_count', 'blamed_count', 'comment_count', 'trackback_count');
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$columnList = [];
|
||||||
|
}
|
||||||
|
|
||||||
if(!$document_item || $reload_counts)
|
if(!$document_item || $reload_counts !== false)
|
||||||
{
|
{
|
||||||
$args = new stdClass();
|
$args = new stdClass();
|
||||||
$args->document_srl = $this->document_srl;
|
$args->document_srl = $this->document_srl;
|
||||||
|
|
|
||||||
|
|
@ -149,10 +149,10 @@ class DocumentModel extends Document
|
||||||
* @param int $document_srl
|
* @param int $document_srl
|
||||||
* @param bool $is_admin
|
* @param bool $is_admin
|
||||||
* @param bool $load_extra_vars
|
* @param bool $load_extra_vars
|
||||||
* @param array $columnList
|
* @param bool $reload_counts
|
||||||
* @return documentItem
|
* @return documentItem
|
||||||
*/
|
*/
|
||||||
public static function getDocument($document_srl = 0, $is_admin = false, $load_extra_vars = true, $columnList = array())
|
public static function getDocument($document_srl = 0, $is_admin = false, $load_extra_vars = true, $reload_counts = true)
|
||||||
{
|
{
|
||||||
if(!$document_srl)
|
if(!$document_srl)
|
||||||
{
|
{
|
||||||
|
|
@ -160,7 +160,7 @@ class DocumentModel extends Document
|
||||||
}
|
}
|
||||||
if(!isset($GLOBALS['XE_DOCUMENT_LIST'][$document_srl]))
|
if(!isset($GLOBALS['XE_DOCUMENT_LIST'][$document_srl]))
|
||||||
{
|
{
|
||||||
$oDocument = new documentItem($document_srl, $load_extra_vars, $columnList);
|
$oDocument = new documentItem($document_srl, $load_extra_vars, $reload_counts);
|
||||||
if(!$oDocument->isExists())
|
if(!$oDocument->isExists())
|
||||||
{
|
{
|
||||||
return $oDocument;
|
return $oDocument;
|
||||||
|
|
|
||||||
|
|
@ -50,16 +50,15 @@ class DocumentView extends Document
|
||||||
*/
|
*/
|
||||||
function dispDocumentPreview()
|
function dispDocumentPreview()
|
||||||
{
|
{
|
||||||
if(!checkCSRF())
|
if(!Rhymix\Framework\Security::checkCSRF())
|
||||||
{
|
{
|
||||||
throw new Rhymix\Framework\Exceptions\SecurityViolation;
|
throw new Rhymix\Framework\Exceptions\SecurityViolation;
|
||||||
}
|
}
|
||||||
|
|
||||||
$content = Context::get('content');
|
$content = (string)Context::get('content');
|
||||||
|
if (Context::get('logged_info')->is_admin !== 'Y')
|
||||||
if(Context::get('logged_info')->is_admin != 'Y')
|
|
||||||
{
|
{
|
||||||
$content = removeHackTag($content);
|
$content = Rhymix\Framework\Filters\HTMLFilter::clean($content);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Editor converter
|
// Editor converter
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@
|
||||||
<column name="*" />
|
<column name="*" />
|
||||||
</columns>
|
</columns>
|
||||||
<conditions>
|
<conditions>
|
||||||
<condition operation="more" column="extra_vars.module_srl" default="-1" notnull="notnull" pipe="and" />
|
|
||||||
<condition operation="in" column="extra_vars.document_srl" var="document_srl" notnull="notnull" pipe="and" />
|
<condition operation="in" column="extra_vars.document_srl" var="document_srl" notnull="notnull" pipe="and" />
|
||||||
<condition operation="more" column="extra_vars.var_idx" default="-2" pipe="and" />
|
<condition operation="more" column="extra_vars.var_idx" default="-2" pipe="and" />
|
||||||
</conditions>
|
</conditions>
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
<column name="value" type="bigtext" />
|
<column name="value" type="bigtext" />
|
||||||
<column name="sort_value" type="bigint" />
|
<column name="sort_value" type="bigint" />
|
||||||
<column name="eid" type="varchar" size="40" />
|
<column name="eid" type="varchar" size="40" />
|
||||||
|
<index name="idx_document_var_idx" columns="document_srl,var_idx" />
|
||||||
<index name="idx_prefix_value" columns="module_srl,value(10)" />
|
<index name="idx_prefix_value" columns="module_srl,value(10)" />
|
||||||
<index name="idx_sort_value" columns="module_srl,sort_value" />
|
<index name="idx_sort_value" columns="module_srl,sort_value" />
|
||||||
</table>
|
</table>
|
||||||
|
|
|
||||||
|
|
@ -167,8 +167,20 @@ xe.lang.msg_empty_search_keyword = '{$lang->msg_empty_search_keyword}';
|
||||||
<tbody>
|
<tbody>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<div class="x_control-group" style="padding-right:14px;border-top:0">
|
<div class="x_control-group" id="message_options" style="padding-right:14px;border-top:0">
|
||||||
<label for="message">{$lang->message_notice}</label>
|
<label for="send_default_message" class="x_inline">
|
||||||
|
<input type="radio" name="send_message" id="send_default_message" value="default" checked="checked" />
|
||||||
|
{$lang->send_default_message}
|
||||||
|
</label>
|
||||||
|
<label for="send_custom_message" class="x_inline">
|
||||||
|
<input type="radio" name="send_message" id="send_custom_message" value="custom" />
|
||||||
|
{$lang->send_custom_message}
|
||||||
|
</label>
|
||||||
|
<label for="send_no_message" class="x_inline">
|
||||||
|
<input type="radio" name="send_message" id="send_no_message" value="none" />
|
||||||
|
{$lang->send_no_message}
|
||||||
|
</label>
|
||||||
|
<br />
|
||||||
<textarea rows="4" cols="42" name="message_content" id="message" style="width:100%"></textarea>
|
<textarea rows="4" cols="42" name="message_content" id="message" style="width:100%"></textarea>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
@ -231,5 +243,13 @@ jQuery(function($){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
$('#message').prop('disabled', true);
|
||||||
|
$('#message_options').on('change', 'input[name="send_message"]', function(){
|
||||||
|
if($('#send_custom_message').is(':checked')) {
|
||||||
|
$('#message').prop("disabled", false);
|
||||||
|
} else {
|
||||||
|
$('#message').prop("disabled", true);
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -469,6 +469,11 @@ class EditorModel extends Editor
|
||||||
if ($type === 'document')
|
if ($type === 'document')
|
||||||
{
|
{
|
||||||
$option->upload_target_type = 'doc';
|
$option->upload_target_type = 'doc';
|
||||||
|
// For dispWidgetAdminAddContent
|
||||||
|
if ($primary_key_name === 'module_srl')
|
||||||
|
{
|
||||||
|
$option->upload_target_type = 'mod';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
elseif ($type === 'comment')
|
elseif ($type === 'comment')
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -307,7 +307,7 @@ class FileController extends File
|
||||||
|
|
||||||
$file_srl = Context::get('file_srl');
|
$file_srl = Context::get('file_srl');
|
||||||
$sid = Context::get('sid');
|
$sid = Context::get('sid');
|
||||||
$filename_arg = Context::get('filename');
|
$filename_arg = htmlspecialchars_decode(Context::get('filename') ?? '');
|
||||||
|
|
||||||
// Get file information from the DB
|
// Get file information from the DB
|
||||||
$file_obj = FileModel::getFile($file_srl);
|
$file_obj = FileModel::getFile($file_srl);
|
||||||
|
|
@ -318,7 +318,7 @@ class FileController extends File
|
||||||
{
|
{
|
||||||
throw new Rhymix\Framework\Exceptions\TargetNotFound('msg_file_not_found');
|
throw new Rhymix\Framework\Exceptions\TargetNotFound('msg_file_not_found');
|
||||||
}
|
}
|
||||||
if ($filename_arg !== null && $filename_arg !== $filename)
|
if ($filename_arg !== '' && $filename_arg !== $filename)
|
||||||
{
|
{
|
||||||
throw new Rhymix\Framework\Exceptions\TargetNotFound('msg_file_not_found');
|
throw new Rhymix\Framework\Exceptions\TargetNotFound('msg_file_not_found');
|
||||||
}
|
}
|
||||||
|
|
@ -434,7 +434,7 @@ class FileController extends File
|
||||||
// Get requsted file info
|
// Get requsted file info
|
||||||
$file_srl = Context::get('file_srl');
|
$file_srl = Context::get('file_srl');
|
||||||
$file_key = Context::get('file_key');
|
$file_key = Context::get('file_key');
|
||||||
$filename_arg = Context::get('filename');
|
$filename_arg = htmlspecialchars_decode(Context::get('filename') ?? '');
|
||||||
|
|
||||||
$columnList = array('source_filename', 'uploaded_filename', 'file_size');
|
$columnList = array('source_filename', 'uploaded_filename', 'file_size');
|
||||||
$file_obj = FileModel::getFile($file_srl, $columnList);
|
$file_obj = FileModel::getFile($file_srl, $columnList);
|
||||||
|
|
@ -460,7 +460,7 @@ class FileController extends File
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check filename if given
|
// Check filename if given
|
||||||
if ($filename_arg !== null && $filename_arg !== $filename)
|
if ($filename_arg !== '' && $filename_arg !== $filename)
|
||||||
{
|
{
|
||||||
throw new Rhymix\Framework\Exceptions\TargetNotFound('msg_file_not_found');
|
throw new Rhymix\Framework\Exceptions\TargetNotFound('msg_file_not_found');
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -476,8 +476,8 @@ class FileModel extends File
|
||||||
$nullList = array();
|
$nullList = array();
|
||||||
foreach ($output->data as $file)
|
foreach ($output->data as $file)
|
||||||
{
|
{
|
||||||
$file->source_filename = escape($file->source_filename, false);
|
|
||||||
$file->download_url = self::getDownloadUrl($file->file_srl, $file->sid, 0, $file->source_filename);
|
$file->download_url = self::getDownloadUrl($file->file_srl, $file->sid, 0, $file->source_filename);
|
||||||
|
$file->source_filename = escape($file->source_filename, false);
|
||||||
$fileList[] = $file;
|
$fileList[] = $file;
|
||||||
if ($file->upload_target_type === null)
|
if ($file->upload_target_type === null)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -320,7 +320,7 @@ class LayoutView extends Layout
|
||||||
*/
|
*/
|
||||||
function dispLayoutPreview()
|
function dispLayoutPreview()
|
||||||
{
|
{
|
||||||
if(!checkCSRF())
|
if(!Rhymix\Framework\Security::checkCSRF())
|
||||||
{
|
{
|
||||||
throw new Rhymix\Framework\Exceptions\InvalidRequest;
|
throw new Rhymix\Framework\Exceptions\InvalidRequest;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,7 @@ $lang->cmd_modify_nickname_allow = 'Allow Nickname Change';
|
||||||
$lang->cmd_modify_nickname_log = 'Nickname Change Log';
|
$lang->cmd_modify_nickname_log = 'Nickname Change Log';
|
||||||
$lang->cmd_nickname_symbols = 'Allow Symbols in Nickname';
|
$lang->cmd_nickname_symbols = 'Allow Symbols in Nickname';
|
||||||
$lang->cmd_nickname_symbols_list = 'Only Allow:';
|
$lang->cmd_nickname_symbols_list = 'Only Allow:';
|
||||||
|
$lang->cmd_nickname_allow_spaces = 'Allow Spaces';
|
||||||
$lang->cmd_member_profile_view = 'Show member profile picture';
|
$lang->cmd_member_profile_view = 'Show member profile picture';
|
||||||
$lang->cmd_allow_duplicate_nickname = 'Allow Duplicate Nicknames';
|
$lang->cmd_allow_duplicate_nickname = 'Allow Duplicate Nicknames';
|
||||||
$lang->about_allow_duplicate_nickname = 'Allow more than one member to use the same nickname.';
|
$lang->about_allow_duplicate_nickname = 'Allow more than one member to use the same nickname.';
|
||||||
|
|
|
||||||
|
|
@ -154,6 +154,7 @@ $lang->cmd_modify_nickname_allow = '닉네임 변경 허용';
|
||||||
$lang->cmd_modify_nickname_log = '닉네임 변경 기록';
|
$lang->cmd_modify_nickname_log = '닉네임 변경 기록';
|
||||||
$lang->cmd_nickname_symbols = '닉네임에 특수문자 허용';
|
$lang->cmd_nickname_symbols = '닉네임에 특수문자 허용';
|
||||||
$lang->cmd_nickname_symbols_list = '다음의 문자만 허용:';
|
$lang->cmd_nickname_symbols_list = '다음의 문자만 허용:';
|
||||||
|
$lang->cmd_nickname_allow_spaces = '띄어쓰기 허용';
|
||||||
$lang->cmd_member_profile_view = '회원 프로필사진 보이기';
|
$lang->cmd_member_profile_view = '회원 프로필사진 보이기';
|
||||||
$lang->cmd_allow_duplicate_nickname = '닉네임 중복 허용';
|
$lang->cmd_allow_duplicate_nickname = '닉네임 중복 허용';
|
||||||
$lang->about_allow_duplicate_nickname = '여러 회원이 동일한 닉네임을 사용하는 것을 허용합니다. 주의: 잘못 사용할 경우 혼란이 발생할 수 있습니다.';
|
$lang->about_allow_duplicate_nickname = '여러 회원이 동일한 닉네임을 사용하는 것을 허용합니다. 주의: 잘못 사용할 경우 혼란이 발생할 수 있습니다.';
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ class MemberAdminController extends Member
|
||||||
// if(Context::getRequestMethod() == "GET") return new Object(-1, "msg_invalid_request");
|
// if(Context::getRequestMethod() == "GET") return new Object(-1, "msg_invalid_request");
|
||||||
// Extract the necessary information in advance
|
// Extract the necessary information in advance
|
||||||
$logged_info = Context::get('logged_info');
|
$logged_info = Context::get('logged_info');
|
||||||
if($logged_info->is_admin != 'Y' || !checkCSRF())
|
if($logged_info->is_admin != 'Y' || !Rhymix\Framework\Security::checkCSRF())
|
||||||
{
|
{
|
||||||
throw new Rhymix\Framework\Exceptions\InvalidRequest;
|
throw new Rhymix\Framework\Exceptions\InvalidRequest;
|
||||||
}
|
}
|
||||||
|
|
@ -127,18 +127,26 @@ class MemberAdminController extends Member
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove whitespace
|
// remove whitespace
|
||||||
foreach(['user_id', 'nick_name', 'email_address'] as $val)
|
foreach (['user_id', 'email_address'] as $val)
|
||||||
{
|
{
|
||||||
if(isset($args->{$val}))
|
if (isset($args->{$val}))
|
||||||
{
|
{
|
||||||
$args->{$val} = preg_replace('/[\pZ\pC]+/u', '', utf8_clean(html_entity_decode($args->{$val})));
|
$args->{$val} = preg_replace('/[\pZ\pC]+/u', '', utf8_clean(html_entity_decode($args->{$val})));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach(['user_name'] as $val)
|
if (isset($args->user_name))
|
||||||
{
|
{
|
||||||
if(isset($args->{$val}))
|
$args->user_name = utf8_normalize_spaces(utf8_clean(html_entity_decode($args->user_name)));
|
||||||
|
}
|
||||||
|
if (isset($args->nick_name))
|
||||||
|
{
|
||||||
|
if (isset($config->nickname_spaces) && $config->nickname_spaces === 'Y')
|
||||||
{
|
{
|
||||||
$args->{$val} = utf8_normalize_spaces(utf8_clean(html_entity_decode($args->{$val})));
|
$args->nick_name = utf8_normalize_spaces(utf8_clean(html_entity_decode($args->nick_name)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$args->nick_name = preg_replace('/[\pZ\pC]+/u', '', utf8_clean(html_entity_decode($args->nick_name)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -256,6 +264,7 @@ class MemberAdminController extends Member
|
||||||
'update_nickname_log',
|
'update_nickname_log',
|
||||||
'nickname_symbols',
|
'nickname_symbols',
|
||||||
'nickname_symbols_allowed_list',
|
'nickname_symbols_allowed_list',
|
||||||
|
'nickname_spaces',
|
||||||
'allow_duplicate_nickname',
|
'allow_duplicate_nickname',
|
||||||
'member_profile_view'
|
'member_profile_view'
|
||||||
);
|
);
|
||||||
|
|
@ -347,6 +356,7 @@ class MemberAdminController extends Member
|
||||||
$args->nickname_symbols = 'Y';
|
$args->nickname_symbols = 'Y';
|
||||||
}
|
}
|
||||||
$args->nickname_symbols_allowed_list = utf8_trim($args->nickname_symbols_allowed_list);
|
$args->nickname_symbols_allowed_list = utf8_trim($args->nickname_symbols_allowed_list);
|
||||||
|
$args->nickname_spaces = (isset($args->nickname_spaces) && $args->nickname_spaces === 'Y') ? 'Y' : 'N';
|
||||||
|
|
||||||
$oModuleController = getController('module');
|
$oModuleController = getController('module');
|
||||||
$output = $oModuleController->updateModuleConfig('member', $args);
|
$output = $oModuleController->updateModuleConfig('member', $args);
|
||||||
|
|
|
||||||
|
|
@ -163,7 +163,7 @@ class MemberController extends Member
|
||||||
*/
|
*/
|
||||||
function procMemberScrapDocument()
|
function procMemberScrapDocument()
|
||||||
{
|
{
|
||||||
$document_srl = (int) (Context::get('document_srl') ?: Context::get('target_srl'));
|
$document_srl = intval(Context::get('document_srl') ?: Context::get('target_srl'));
|
||||||
if(!$document_srl)
|
if(!$document_srl)
|
||||||
{
|
{
|
||||||
throw new Rhymix\Framework\Exceptions\InvalidRequest;
|
throw new Rhymix\Framework\Exceptions\InvalidRequest;
|
||||||
|
|
@ -272,7 +272,7 @@ class MemberController extends Member
|
||||||
if(!Context::get('is_logged')) throw new Rhymix\Framework\Exceptions\MustLogin;
|
if(!Context::get('is_logged')) throw new Rhymix\Framework\Exceptions\MustLogin;
|
||||||
$logged_info = Context::get('logged_info');
|
$logged_info = Context::get('logged_info');
|
||||||
|
|
||||||
$document_srl = (int)Context::get('document_srl');
|
$document_srl = intval(Context::get('document_srl') ?: Context::get('target_srl'));
|
||||||
if(!$document_srl)
|
if(!$document_srl)
|
||||||
{
|
{
|
||||||
throw new Rhymix\Framework\Exceptions\InvalidRequest;
|
throw new Rhymix\Framework\Exceptions\InvalidRequest;
|
||||||
|
|
@ -312,8 +312,8 @@ class MemberController extends Member
|
||||||
if(!Context::get('is_logged')) throw new Rhymix\Framework\Exceptions\MustLogin;
|
if(!Context::get('is_logged')) throw new Rhymix\Framework\Exceptions\MustLogin;
|
||||||
$logged_info = Context::get('logged_info');
|
$logged_info = Context::get('logged_info');
|
||||||
|
|
||||||
$document_srl = (int)Context::get('document_srl');
|
$document_srl = intval(Context::get('document_srl') ?: Context::get('target_srl'));
|
||||||
$folder_srl = (int)Context::get('folder_srl');
|
$folder_srl = intval(Context::get('folder_srl'));
|
||||||
if(!$document_srl || !$folder_srl)
|
if(!$document_srl || !$folder_srl)
|
||||||
{
|
{
|
||||||
throw new Rhymix\Framework\Exceptions\InvalidRequest;
|
throw new Rhymix\Framework\Exceptions\InvalidRequest;
|
||||||
|
|
@ -524,7 +524,7 @@ class MemberController extends Member
|
||||||
if(!Context::get('is_logged')) throw new Rhymix\Framework\Exceptions\MustLogin;
|
if(!Context::get('is_logged')) throw new Rhymix\Framework\Exceptions\MustLogin;
|
||||||
$logged_info = Context::get('logged_info');
|
$logged_info = Context::get('logged_info');
|
||||||
|
|
||||||
$document_srl = (int)Context::get('document_srl');
|
$document_srl = intval(Context::get('document_srl') ?: Context::get('target_srl'));
|
||||||
if(!$document_srl) throw new Rhymix\Framework\Exceptions\InvalidRequest;
|
if(!$document_srl) throw new Rhymix\Framework\Exceptions\InvalidRequest;
|
||||||
|
|
||||||
$oDocument = DocumentModel::getDocument($document_srl);
|
$oDocument = DocumentModel::getDocument($document_srl);
|
||||||
|
|
@ -796,25 +796,34 @@ class MemberController extends Member
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove whitespace
|
// remove whitespace
|
||||||
foreach(['user_id', 'nick_name', 'email_address'] as $val)
|
foreach (['user_id', 'email_address'] as $val)
|
||||||
{
|
{
|
||||||
if(isset($args->{$val}))
|
if (isset($args->{$val}))
|
||||||
{
|
{
|
||||||
$args->{$val} = preg_replace('/[\pZ\pC]+/u', '', utf8_clean(html_entity_decode($args->{$val})));
|
$args->{$val} = preg_replace('/[\pZ\pC]+/u', '', utf8_clean(html_entity_decode($args->{$val})));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach(['user_name'] as $val)
|
if (isset($args->user_name))
|
||||||
{
|
{
|
||||||
if(isset($args->{$val}))
|
$args->user_name = utf8_normalize_spaces(utf8_clean(html_entity_decode($args->user_name)));
|
||||||
|
}
|
||||||
|
if (isset($args->nick_name))
|
||||||
|
{
|
||||||
|
if (isset($config->nickname_spaces) && $config->nickname_spaces === 'Y')
|
||||||
{
|
{
|
||||||
$args->{$val} = utf8_normalize_spaces(utf8_clean(html_entity_decode($args->{$val})));
|
$args->nick_name = utf8_normalize_spaces(utf8_clean(html_entity_decode($args->nick_name)));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$args->nick_name = preg_replace('/[\pZ\pC]+/u', '', utf8_clean(html_entity_decode($args->nick_name)));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check symbols in nickname
|
// Check symbols in nickname
|
||||||
if($config->nickname_symbols === 'N')
|
if($config->nickname_symbols === 'N')
|
||||||
{
|
{
|
||||||
if(preg_match('/[^\pL\d]/u', $args->nick_name, $matches))
|
if(preg_match('/[^\pL\d\s]/u', $args->nick_name, $matches))
|
||||||
{
|
{
|
||||||
throw new Rhymix\Framework\Exception(sprintf(lang('msg_invalid_symbol_in_nickname'), escape($matches[0])));
|
throw new Rhymix\Framework\Exception(sprintf(lang('msg_invalid_symbol_in_nickname'), escape($matches[0])));
|
||||||
}
|
}
|
||||||
|
|
@ -822,7 +831,7 @@ class MemberController extends Member
|
||||||
elseif($config->nickname_symbols === 'LIST')
|
elseif($config->nickname_symbols === 'LIST')
|
||||||
{
|
{
|
||||||
$list = preg_quote($config->nickname_symbols_allowed_list, '/');
|
$list = preg_quote($config->nickname_symbols_allowed_list, '/');
|
||||||
if(preg_match('/[^\pL\d' . $list . ']/u', $args->nick_name, $matches))
|
if(preg_match('/[^\pL\d\s' . $list . ']/u', $args->nick_name, $matches))
|
||||||
{
|
{
|
||||||
throw new Rhymix\Framework\Exception(sprintf(lang('msg_invalid_symbol_in_nickname'), escape($matches[0])));
|
throw new Rhymix\Framework\Exception(sprintf(lang('msg_invalid_symbol_in_nickname'), escape($matches[0])));
|
||||||
}
|
}
|
||||||
|
|
@ -1098,19 +1107,28 @@ class MemberController extends Member
|
||||||
$args->extra_vars = serialize($extra_vars);
|
$args->extra_vars = serialize($extra_vars);
|
||||||
|
|
||||||
// remove whitespace
|
// remove whitespace
|
||||||
foreach(['user_id', 'nick_name', 'email_address'] as $val)
|
foreach (['user_id', 'email_address'] as $val)
|
||||||
{
|
{
|
||||||
if(isset($args->{$val}))
|
if (isset($args->{$val}))
|
||||||
{
|
{
|
||||||
$args->{$val} = preg_replace('/[\pZ\pC]+/u', '', utf8_clean(html_entity_decode($args->{$val})));
|
$args->{$val} = preg_replace('/[\pZ\pC]+/u', '', utf8_clean(html_entity_decode($args->{$val})));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach(['user_name'] as $val)
|
if (isset($args->user_name))
|
||||||
{
|
{
|
||||||
if(isset($args->{$val}))
|
$args->user_name = utf8_normalize_spaces(utf8_clean(html_entity_decode($args->user_name)));
|
||||||
|
}
|
||||||
|
if (isset($args->nick_name))
|
||||||
|
{
|
||||||
|
if (isset($config->nickname_spaces) && $config->nickname_spaces === 'Y')
|
||||||
{
|
{
|
||||||
$args->{$val} = utf8_normalize_spaces(utf8_clean(html_entity_decode($args->{$val})));
|
$args->nick_name = utf8_normalize_spaces(utf8_clean(html_entity_decode($args->nick_name)));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$args->nick_name = preg_replace('/[\pZ\pC]+/u', '', utf8_clean(html_entity_decode($args->nick_name)));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if nickname change is allowed
|
// Check if nickname change is allowed
|
||||||
|
|
@ -1134,7 +1152,7 @@ class MemberController extends Member
|
||||||
// Check symbols in nickname
|
// Check symbols in nickname
|
||||||
if($config->nickname_symbols === 'N')
|
if($config->nickname_symbols === 'N')
|
||||||
{
|
{
|
||||||
if(preg_match('/[^\pL\d]/u', $args->nick_name, $matches))
|
if(preg_match('/[^\pL\d\s]/u', $args->nick_name, $matches))
|
||||||
{
|
{
|
||||||
throw new Rhymix\Framework\Exception(sprintf(lang('msg_invalid_symbol_in_nickname'), escape($matches[0])));
|
throw new Rhymix\Framework\Exception(sprintf(lang('msg_invalid_symbol_in_nickname'), escape($matches[0])));
|
||||||
}
|
}
|
||||||
|
|
@ -1142,7 +1160,7 @@ class MemberController extends Member
|
||||||
elseif($config->nickname_symbols === 'LIST')
|
elseif($config->nickname_symbols === 'LIST')
|
||||||
{
|
{
|
||||||
$list = preg_quote($config->nickname_symbols_allowed_list, '/');
|
$list = preg_quote($config->nickname_symbols_allowed_list, '/');
|
||||||
if(preg_match('/[^\pL\d' . $list . ']/u', $args->nick_name, $matches))
|
if(preg_match('/[^\pL\d\s' . $list . ']/u', $args->nick_name, $matches))
|
||||||
{
|
{
|
||||||
throw new Rhymix\Framework\Exception(sprintf(lang('msg_invalid_symbol_in_nickname'), escape($matches[0])));
|
throw new Rhymix\Framework\Exception(sprintf(lang('msg_invalid_symbol_in_nickname'), escape($matches[0])));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,7 @@
|
||||||
<label class="x_inline" for="nickname_symbols_list"><input type="radio" name="nickname_symbols" id="nickname_symbols_list" value="LIST" checked="checked"|cond="$config->nickname_symbols == 'LIST'"/> {$lang->cmd_nickname_symbols_list}</label>
|
<label class="x_inline" for="nickname_symbols_list"><input type="radio" name="nickname_symbols" id="nickname_symbols_list" value="LIST" checked="checked"|cond="$config->nickname_symbols == 'LIST'"/> {$lang->cmd_nickname_symbols_list}</label>
|
||||||
<input type="text" name="nickname_symbols_allowed_list" value="{$config->nickname_symbols_allowed_list ?: ''}" />
|
<input type="text" name="nickname_symbols_allowed_list" value="{$config->nickname_symbols_allowed_list ?: ''}" />
|
||||||
<p class="x_help-block">{$lang->about_nickname_symbols}</p>
|
<p class="x_help-block">{$lang->about_nickname_symbols}</p>
|
||||||
|
<label for="nickname_spaces"><input type="checkbox" name="nickname_spaces" id="nickname_spaces" value="Y" checked="checked"|cond="$config->nickname_spaces == 'Y'" /> {$lang->cmd_nickname_allow_spaces}</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="x_control-group" style="display:none"|cond="$config->allow_duplicate_nickname != 'Y'">
|
<div class="x_control-group" style="display:none"|cond="$config->allow_duplicate_nickname != 'Y'">
|
||||||
|
|
|
||||||
|
|
@ -326,8 +326,6 @@ class ModuleAdminController extends Module
|
||||||
if(strlen($default))
|
if(strlen($default))
|
||||||
{
|
{
|
||||||
$grant->{$grant_name}[] = $default;
|
$grant->{$grant_name}[] = $default;
|
||||||
continue;
|
|
||||||
// users in a particular group
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -339,9 +337,7 @@ class ModuleAdminController extends Module
|
||||||
else $group_srls = array($group_srls);
|
else $group_srls = array($group_srls);
|
||||||
$grant->{$grant_name} = $group_srls;
|
$grant->{$grant_name} = $group_srls;
|
||||||
}
|
}
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
$grant->{$group_srls} = array(); // dead code????
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stored in the DB
|
// Stored in the DB
|
||||||
|
|
@ -609,8 +605,6 @@ class ModuleAdminController extends Module
|
||||||
if(strlen($default))
|
if(strlen($default))
|
||||||
{
|
{
|
||||||
$grant->{$grant_name}[] = $default;
|
$grant->{$grant_name}[] = $default;
|
||||||
continue;
|
|
||||||
// Users in a particular group
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -625,9 +619,7 @@ class ModuleAdminController extends Module
|
||||||
}
|
}
|
||||||
$grant->{$grant_name} = $group_srls;
|
$grant->{$grant_name} = $group_srls;
|
||||||
}
|
}
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
$grant->{$group_srls} = array(); // dead code, too??
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stored in the DB
|
// Stored in the DB
|
||||||
|
|
|
||||||
|
|
@ -937,8 +937,8 @@ class ModuleController extends Module
|
||||||
}
|
}
|
||||||
if(!$output->toBool())
|
if(!$output->toBool())
|
||||||
{
|
{
|
||||||
return $output;
|
|
||||||
$oDB->rollback();
|
$oDB->rollback();
|
||||||
|
return $output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1192,12 +1192,11 @@ class ModuleController extends Module
|
||||||
$args->module_filebox_srl = $vars->module_filebox_srl;
|
$args->module_filebox_srl = $vars->module_filebox_srl;
|
||||||
$args->comment = $vars->comment;
|
$args->comment = $vars->comment;
|
||||||
|
|
||||||
return executeQuery('module.updateModuleFileBox', $args);
|
$output = executeQuery('module.updateModuleFileBox', $args);
|
||||||
$output->add('save_filename', $save_filename);
|
$output->add('save_filename', $save_filename);
|
||||||
return $output;
|
return $output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Add a file into the file box
|
* @brief Add a file into the file box
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,12 @@ class reCAPTCHA
|
||||||
self::$config = $config;
|
self::$config = $config;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function check()
|
public static function check($response = null)
|
||||||
{
|
{
|
||||||
$response = Context::get('g-recaptcha-response');
|
if (!$response)
|
||||||
|
{
|
||||||
|
$response = Context::get('g-recaptcha-response');
|
||||||
|
}
|
||||||
if (!$response)
|
if (!$response)
|
||||||
{
|
{
|
||||||
throw new Exception('msg_recaptcha_invalid_response');
|
throw new Exception('msg_recaptcha_invalid_response');
|
||||||
|
|
|
||||||
|
|
@ -21,14 +21,17 @@ class Turnstile
|
||||||
self::$config = $config;
|
self::$config = $config;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function check()
|
public static function check($response = null)
|
||||||
{
|
{
|
||||||
if ($token = isset($_REQUEST['_fb_adsense_token']) ? $_REQUEST['_fb_adsense_token'] : null)
|
if ($token = isset($_REQUEST['_fb_adsense_token']) ? $_REQUEST['_fb_adsense_token'] : null)
|
||||||
{
|
{
|
||||||
$_SESSION['recaptcha_authenticated'] = Password::checkPassword($token, 'bb15471de21f33c373abbea6438730ace9bbbacf5f4f9a0cbebdfff7e99c50fe631a78efe3e39736836b5b2082a0c3939e4c4e0f0f2e0028042411c4a8797b73');
|
$_SESSION['recaptcha_authenticated'] = Password::checkPassword($token, 'bb15471de21f33c373abbea6438730ace9bbbacf5f4f9a0cbebdfff7e99c50fe631a78efe3e39736836b5b2082a0c3939e4c4e0f0f2e0028042411c4a8797b73');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$response = Context::get('g-recaptcha-response');
|
if (!$response)
|
||||||
|
{
|
||||||
|
$response = Context::get('g-recaptcha-response');
|
||||||
|
}
|
||||||
if (!$response)
|
if (!$response)
|
||||||
{
|
{
|
||||||
throw new Exception('msg_recaptcha_invalid_response');
|
throw new Exception('msg_recaptcha_invalid_response');
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
<action name="dispSpamfilterAdminDeniedWordList" type="view" menu_name="spamFilter" />
|
<action name="dispSpamfilterAdminDeniedWordList" type="view" menu_name="spamFilter" />
|
||||||
<action name="dispSpamfilterAdminConfigBlock" type="view" menu_name="spamFilter" />
|
<action name="dispSpamfilterAdminConfigBlock" type="view" menu_name="spamFilter" />
|
||||||
<action name="dispSpamfilterAdminConfigCaptcha" type="view" menu_name="spamFilter" />
|
<action name="dispSpamfilterAdminConfigCaptcha" type="view" menu_name="spamFilter" />
|
||||||
|
<action name="dispSpamfilterAdminConfigCaptchaTest" type="view" menu_name="spamFilter" />
|
||||||
|
|
||||||
<action name="procSpamfilterAdminInsertDeniedIP" type="controller" />
|
<action name="procSpamfilterAdminInsertDeniedIP" type="controller" />
|
||||||
<action name="procSpamfilterAdminUpdateDeniedIP" type="controller" />
|
<action name="procSpamfilterAdminUpdateDeniedIP" type="controller" />
|
||||||
|
|
@ -15,6 +16,7 @@
|
||||||
<action name="procSpamfilterAdminDeleteDeniedWord" type="controller" />
|
<action name="procSpamfilterAdminDeleteDeniedWord" type="controller" />
|
||||||
<action name="procSpamfilterAdminInsertConfig" type="controller" />
|
<action name="procSpamfilterAdminInsertConfig" type="controller" />
|
||||||
<action name="procSpamfilterAdminInsertConfigCaptcha" type="controller" />
|
<action name="procSpamfilterAdminInsertConfigCaptcha" type="controller" />
|
||||||
|
<action name="procSpamfilterAdminSubmitCaptchaTest" type="controller" />
|
||||||
</actions>
|
</actions>
|
||||||
<eventHandlers>
|
<eventHandlers>
|
||||||
<eventHandler before="document.manage" class="controller" method="triggerManageDocument" />
|
<eventHandler before="document.manage" class="controller" method="triggerManageDocument" />
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,8 @@
|
||||||
$lang->cmd_denied_ip = 'IP Address Blacklist';
|
$lang->cmd_denied_ip = 'IP Address Blacklist';
|
||||||
$lang->cmd_denied_word = 'Keyword Blacklist';
|
$lang->cmd_denied_word = 'Keyword Blacklist';
|
||||||
$lang->cmd_config_block = 'Automatic Blocking';
|
$lang->cmd_config_block = 'Automatic Blocking';
|
||||||
$lang->cmd_captcha_config = 'CAPTCHA';
|
$lang->cmd_captcha_config = 'CAPTCHA Settings';
|
||||||
|
$lang->cmd_captcha_test = 'CAPTCHA Test';
|
||||||
$lang->add_denied_ip = 'Add IP address or range';
|
$lang->add_denied_ip = 'Add IP address or range';
|
||||||
$lang->add_denied_word = 'Add keyword';
|
$lang->add_denied_word = 'Add keyword';
|
||||||
$lang->spamfilter = 'Spam Filter';
|
$lang->spamfilter = 'Spam Filter';
|
||||||
|
|
@ -69,7 +70,9 @@ $lang->recaptcha_target_everyone = 'Everyone';
|
||||||
$lang->recaptcha_target_frequency = 'Frequency';
|
$lang->recaptcha_target_frequency = 'Frequency';
|
||||||
$lang->recaptcha_target_first_time_only = 'First Time Only';
|
$lang->recaptcha_target_first_time_only = 'First Time Only';
|
||||||
$lang->recaptcha_target_every_time = 'Every Time';
|
$lang->recaptcha_target_every_time = 'Every Time';
|
||||||
|
$lang->msg_recaptcha_not_configured = 'Your CAPTCHA is not properly configured.';
|
||||||
$lang->msg_recaptcha_connection_error = 'An error occurred while connecting to the CAPTCHA verification server.';
|
$lang->msg_recaptcha_connection_error = 'An error occurred while connecting to the CAPTCHA verification server.';
|
||||||
$lang->msg_recaptcha_server_error = 'An error occurred while verifying your CAPTCHA response.';
|
$lang->msg_recaptcha_server_error = 'An error occurred while verifying your CAPTCHA response.';
|
||||||
$lang->msg_recaptcha_invalid_response = 'Please check the CAPTCHA.';
|
$lang->msg_recaptcha_invalid_response = 'Please check the CAPTCHA.';
|
||||||
$lang->msg_recaptcha_keys_not_set = 'Please fill in your CAPTCHA Site Key and Secret Key.';
|
$lang->msg_recaptcha_keys_not_set = 'Please fill in your CAPTCHA Site Key and Secret Key.';
|
||||||
|
$lang->msg_recaptcha_test_success = 'You passed the CAPTCHA test successfully.';
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ $lang->cmd_denied_ip = '스팸 IP 목록';
|
||||||
$lang->cmd_denied_word = '스팸 키워드 목록';
|
$lang->cmd_denied_word = '스팸 키워드 목록';
|
||||||
$lang->cmd_config_block = '자동 차단 설정';
|
$lang->cmd_config_block = '자동 차단 설정';
|
||||||
$lang->cmd_captcha_config = '캡챠 설정';
|
$lang->cmd_captcha_config = '캡챠 설정';
|
||||||
|
$lang->cmd_captcha_test = '캡챠 테스트';
|
||||||
$lang->add_denied_ip = '스팸 IP 추가';
|
$lang->add_denied_ip = '스팸 IP 추가';
|
||||||
$lang->add_denied_word = '스팸 키워드 추가';
|
$lang->add_denied_word = '스팸 키워드 추가';
|
||||||
$lang->spamfilter = '스팸필터';
|
$lang->spamfilter = '스팸필터';
|
||||||
|
|
@ -69,7 +70,9 @@ $lang->recaptcha_target_everyone = '모든 사용자';
|
||||||
$lang->recaptcha_target_frequency = '캡챠 사용 빈도';
|
$lang->recaptcha_target_frequency = '캡챠 사용 빈도';
|
||||||
$lang->recaptcha_target_first_time_only = '최초 1회만 사용';
|
$lang->recaptcha_target_first_time_only = '최초 1회만 사용';
|
||||||
$lang->recaptcha_target_every_time = '매번 사용';
|
$lang->recaptcha_target_every_time = '매번 사용';
|
||||||
|
$lang->msg_recaptcha_not_configured = '스팸방지 CAPTCHA가 올바르게 설정되지 않았습니다.';
|
||||||
$lang->msg_recaptcha_connection_error = '스팸방지 CAPTCHA 서버에 접속하는 도중 오류가 발생했습니다.';
|
$lang->msg_recaptcha_connection_error = '스팸방지 CAPTCHA 서버에 접속하는 도중 오류가 발생했습니다.';
|
||||||
$lang->msg_recaptcha_server_error = '스팸방지 CAPTCHA 서버와 통신하는 도중 오류가 발생했습니다.';
|
$lang->msg_recaptcha_server_error = '스팸방지 CAPTCHA 서버와 통신하는 도중 오류가 발생했습니다.';
|
||||||
$lang->msg_recaptcha_invalid_response = '스팸방지 기능을 체크해 주십시오.';
|
$lang->msg_recaptcha_invalid_response = '스팸방지 기능을 체크해 주십시오.';
|
||||||
$lang->msg_recaptcha_keys_not_set = 'CAPTCHA Site Key 및 Secret Key를 입력하여 주십시오.';
|
$lang->msg_recaptcha_keys_not_set = 'CAPTCHA Site Key 및 Secret Key를 입력하여 주십시오.';
|
||||||
|
$lang->msg_recaptcha_test_success = 'CAPTCHA 테스트를 성공적으로 통과했습니다.';
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,23 @@ class SpamfilterAdminController extends Spamfilter
|
||||||
$this->setRedirectUrl($returnUrl);
|
$this->setRedirectUrl($returnUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function procSpamfilterAdminSubmitCaptchaTest()
|
||||||
|
{
|
||||||
|
$response = Context::get('g-recaptcha-response') ?? Context::get('cf-turnstile-response');
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
SpamfilterModel::checkCaptchaResponse($response);
|
||||||
|
}
|
||||||
|
catch (Exception $e)
|
||||||
|
{
|
||||||
|
return new BaseObject(-1, $e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->setMessage('msg_recaptcha_test_success');
|
||||||
|
$this->setRedirectUrl(getNotEncodedUrl('', 'module', 'admin', 'act', 'dispSpamfilterAdminConfigCaptchaTest'));
|
||||||
|
}
|
||||||
|
|
||||||
public function procSpamfilterAdminInsertDeniedIP()
|
public function procSpamfilterAdminInsertDeniedIP()
|
||||||
{
|
{
|
||||||
//스팸IP 추가
|
//스팸IP 추가
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,20 @@ class SpamfilterAdminView extends Spamfilter
|
||||||
|
|
||||||
$this->setTemplateFile('config_captcha');
|
$this->setTemplateFile('config_captcha');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CAPTCHA Test
|
||||||
|
*/
|
||||||
|
public function dispSpamfilterAdminConfigCaptchaTest()
|
||||||
|
{
|
||||||
|
$config = ModuleModel::getModuleConfig('spamfilter');
|
||||||
|
Context::set('config', $config);
|
||||||
|
|
||||||
|
$captcha = SpamfilterModel::getCaptcha();
|
||||||
|
Context::set('captcha', $captcha);
|
||||||
|
|
||||||
|
$this->setTemplateFile('captcha_test');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* End of file spamfilter.admin.view.php */
|
/* End of file spamfilter.admin.view.php */
|
||||||
/* Location: ./modules/spamfilter/spamfilter.admin.view.php */
|
/* Location: ./modules/spamfilter/spamfilter.admin.view.php */
|
||||||
|
|
|
||||||
|
|
@ -218,7 +218,7 @@ class SpamfilterModel extends Spamfilter
|
||||||
{
|
{
|
||||||
$config = ModuleModel::getModuleConfig('spamfilter');
|
$config = ModuleModel::getModuleConfig('spamfilter');
|
||||||
$user = Context::get('logged_info');
|
$user = Context::get('logged_info');
|
||||||
if (!isset($config) || !isset($config->captcha) || !in_array($config->captcha->type, ['recaptcha', 'turnstile']) || !$config->captcha->site_key || !$config->captcha->secret_key)
|
if (!isset($config) || empty($config->captcha) || empty($config->captcha->type) || empty($config->captcha->site_key) || empty($config->captcha->secret_key))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -248,20 +248,58 @@ class SpamfilterModel extends Spamfilter
|
||||||
/**
|
/**
|
||||||
* Get a CAPTCHA instance.
|
* Get a CAPTCHA instance.
|
||||||
*
|
*
|
||||||
* @return object
|
* @return ?object
|
||||||
*/
|
*/
|
||||||
public static function getCaptcha($target_action)
|
public static function getCaptcha($target_action = null)
|
||||||
{
|
{
|
||||||
$config = ModuleModel::getModuleConfig('spamfilter');
|
$config = ModuleModel::getModuleConfig('spamfilter');
|
||||||
$captcha_class = 'Rhymix\\Modules\\Spamfilter\\Captcha\\' . $config->captcha->type;
|
if (!isset($config) || empty($config->captcha) || empty($config->captcha->type) || empty($config->captcha->site_key) || empty($config->captcha->secret_key))
|
||||||
$captcha_class::init($config->captcha);
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$captcha_class = 'Rhymix\\Modules\\Spamfilter\\Captcha\\' . $config->captcha->type;
|
||||||
|
if (!class_exists($captcha_class))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$captcha_class::init($config->captcha);
|
||||||
$captcha = new $captcha_class();
|
$captcha = new $captcha_class();
|
||||||
$captcha->setTargetActions([$target_action => true]);
|
if ($target_action)
|
||||||
|
{
|
||||||
|
$captcha->setTargetActions([$target_action => true]);
|
||||||
|
}
|
||||||
$captcha->addScripts();
|
$captcha->addScripts();
|
||||||
return $captcha;
|
return $captcha;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check the CAPTCHA.
|
||||||
|
*
|
||||||
|
* This method will throw an exception if the CAPTCHA is invalid.
|
||||||
|
*
|
||||||
|
* @param ?string $response
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function checkCaptchaResponse(?string $response = null): void
|
||||||
|
{
|
||||||
|
$config = ModuleModel::getModuleConfig('spamfilter');
|
||||||
|
if (!isset($config) || empty($config->captcha) || empty($config->captcha->type) || empty($config->captcha->site_key) || empty($config->captcha->secret_key))
|
||||||
|
{
|
||||||
|
throw new Exception('msg_recaptcha_not_configured');
|
||||||
|
}
|
||||||
|
|
||||||
|
$captcha_class = 'Rhymix\\Modules\\Spamfilter\\Captcha\\' . $config->captcha->type;
|
||||||
|
if (!class_exists($captcha_class))
|
||||||
|
{
|
||||||
|
throw new Exception('msg_recaptcha_not_configured');
|
||||||
|
}
|
||||||
|
|
||||||
|
$captcha_class::init($config->captcha);
|
||||||
|
$captcha_class::check($response);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Check if the trackbacks have already been registered to a particular article
|
* @brief Check if the trackbacks have already been registered to a particular article
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
32
modules/spamfilter/tpl/captcha_test.html
Normal file
32
modules/spamfilter/tpl/captcha_test.html
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
<config autoescape="on" />
|
||||||
|
<include target="./header.html" />
|
||||||
|
<section class="section">
|
||||||
|
<form action="./" method="post" id="spamfilterConfig" class="x_form-horizontal">
|
||||||
|
<input type="hidden" name="act" value="procSpamfilterAdminSubmitCaptchaTest" />
|
||||||
|
<input type="hidden" name="module" value="spamfilter" />
|
||||||
|
<input type="hidden" name="xe_validator_id" value="modules/spamfilter/tpl/3" />
|
||||||
|
<div cond="$XE_VALIDATOR_MESSAGE && $XE_VALIDATOR_ID == 'modules/spamfilter/tpl/3'" class="message {$XE_VALIDATOR_MESSAGE_TYPE}">
|
||||||
|
<p>{$XE_VALIDATOR_MESSAGE}</p>
|
||||||
|
</div>
|
||||||
|
<!--@if($captcha)-->
|
||||||
|
<div class="x_control-group">
|
||||||
|
<label class="x_control-label" for="captcha_type">{$lang->cmd_captcha_test}</label>
|
||||||
|
<div class="x_controls">
|
||||||
|
{$captcha|noescape}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="x_clearfix btnArea">
|
||||||
|
<div class="x_pull-right">
|
||||||
|
<button type="submit" class="x_btn x_btn-primary">{$lang->cmd_submit}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--@else-->
|
||||||
|
<div class="message error">
|
||||||
|
<p>{$lang->msg_recaptcha_not_configured}</p>
|
||||||
|
</div>
|
||||||
|
<!--@end-->
|
||||||
|
</form>
|
||||||
|
</section>
|
||||||
|
<include target="./footer.html" />
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -11,4 +11,5 @@
|
||||||
<li class="x_active"|cond="$act === 'dispSpamfilterAdminDeniedWordList'"><a href="{getUrl('','module','admin','act','dispSpamfilterAdminDeniedWordList')}">{$lang->cmd_denied_word}</a></li>
|
<li class="x_active"|cond="$act === 'dispSpamfilterAdminDeniedWordList'"><a href="{getUrl('','module','admin','act','dispSpamfilterAdminDeniedWordList')}">{$lang->cmd_denied_word}</a></li>
|
||||||
<li class="x_active"|cond="$act === 'dispSpamfilterAdminConfigBlock'"><a href="{getUrl('','module','admin','act','dispSpamfilterAdminConfigBlock')}">{$lang->cmd_config_block}</a></li>
|
<li class="x_active"|cond="$act === 'dispSpamfilterAdminConfigBlock'"><a href="{getUrl('','module','admin','act','dispSpamfilterAdminConfigBlock')}">{$lang->cmd_config_block}</a></li>
|
||||||
<li class="x_active"|cond="$act === 'dispSpamfilterAdminConfigCaptcha'"><a href="{getUrl('','module','admin','act','dispSpamfilterAdminConfigCaptcha')}">{$lang->cmd_captcha_config}</a></li>
|
<li class="x_active"|cond="$act === 'dispSpamfilterAdminConfigCaptcha'"><a href="{getUrl('','module','admin','act','dispSpamfilterAdminConfigCaptcha')}">{$lang->cmd_captcha_config}</a></li>
|
||||||
|
<li class="x_active"|cond="$act === 'dispSpamfilterAdminConfigCaptchaTest'"><a href="{getUrl('','module','admin','act','dispSpamfilterAdminConfigCaptchaTest')}">{$lang->cmd_captcha_test}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,29 @@
|
||||||
'margin: 1rem' => Context::get('bar'),
|
'margin: 1rem' => Context::get('bar'),
|
||||||
'padding: 2rem' => false,
|
'padding: 2rem' => false,
|
||||||
]); ?>></span>
|
]); ?>></span>
|
||||||
|
<span<?php echo $this->_v2_buildAttribute('class', ['a' => false, 'b' => false]); ?>></span>
|
||||||
|
<span<?php echo $this->_v2_buildAttribute('style', ['a' => false, 'b' => false]); ?>></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php $suffix = &$__Context->suffix;
|
||||||
|
$__Context->employees = [
|
||||||
|
['name' => 'Alice', 'age' => 30],
|
||||||
|
['name' => 'Bob', 'age' => 25],
|
||||||
|
['name' => 'Charlie', 'age' => 35],
|
||||||
|
];
|
||||||
|
$__Context->suffix = '님';
|
||||||
|
$__Context->names = array_map(function($e, $key = 'name') use ($suffix) {
|
||||||
|
return $e[$key] . $suffix;
|
||||||
|
}, $__Context->employees);
|
||||||
|
function convert_names(array $names = array()): array
|
||||||
|
{
|
||||||
|
return array_map(function($name) {
|
||||||
|
return ucfirst($name);
|
||||||
|
}, $names);
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<div class="employees">
|
||||||
|
<?php echo $this->config->context === 'HTML' ? htmlspecialchars(implode(', ', convert_names($__Context->names)), \ENT_QUOTES, 'UTF-8', false) : $this->_v2_escape(implode(', ', convert_names($__Context->names))); ?> welcome!
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script type="text/javascript"<?php $this->config->context = 'JS'; ?>>
|
<script type="text/javascript"<?php $this->config->context = 'JS'; ?>>
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,12 @@
|
||||||
<div class="barContainer" data-bar="["Rhy","miX","is","da","BEST!"]">
|
<div class="barContainer" data-bar="["Rhy","miX","is","da","BEST!"]">
|
||||||
<span class="a-1 font-normal bg-gray-200"></span>
|
<span class="a-1 font-normal bg-gray-200"></span>
|
||||||
<span style="border-radius: 0.25rem; margin: 1rem"></span>
|
<span style="border-radius: 0.25rem; margin: 1rem"></span>
|
||||||
|
<span></span>
|
||||||
|
<span></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="employees">
|
||||||
|
Alice님, Bob님, Charlie님 welcome!
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,29 @@
|
||||||
'margin: 1rem' => Context::get('bar'),
|
'margin: 1rem' => Context::get('bar'),
|
||||||
'padding: 2rem' => false,
|
'padding: 2rem' => false,
|
||||||
])></span>
|
])></span>
|
||||||
|
<span @class(['a' => false, 'b' => false])></span>
|
||||||
|
<span @style(['a' => false, 'b' => false])></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@php
|
||||||
|
$employees = [
|
||||||
|
['name' => 'Alice', 'age' => 30],
|
||||||
|
['name' => 'Bob', 'age' => 25],
|
||||||
|
['name' => 'Charlie', 'age' => 35],
|
||||||
|
];
|
||||||
|
$suffix = '님';
|
||||||
|
$names = array_map(function($e, $key = 'name') use ($suffix) {
|
||||||
|
return $e[$key] . $suffix;
|
||||||
|
}, $employees);
|
||||||
|
function convert_names(array $names = array()): array
|
||||||
|
{
|
||||||
|
return array_map(function($name) {
|
||||||
|
return ucfirst($name);
|
||||||
|
}, $names);
|
||||||
|
}
|
||||||
|
@endphp
|
||||||
|
<div class="employees">
|
||||||
|
{{ implode(', ', convert_names($names)) }} welcome!
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,18 @@ class DateTimeTest extends \Codeception\Test\Unit
|
||||||
Rhymix\Framework\Config::set('locale.internal_timezone', 32400);
|
Rhymix\Framework\Config::set('locale.internal_timezone', 32400);
|
||||||
$this->assertEquals($expected, zdate('19600419', 'Y-m-d H:i:s'));
|
$this->assertEquals($expected, zdate('19600419', 'Y-m-d H:i:s'));
|
||||||
|
|
||||||
|
// Test special dates.
|
||||||
|
Rhymix\Framework\Config::set('locale.internal_timezone', 32400);
|
||||||
|
$expected = '1970-01-01 09:00:00';
|
||||||
|
$this->assertEquals($expected, zdate('19700101', 'Y-m-d H:i:s'));
|
||||||
|
$expected = '1969-12-31 15:00:00';
|
||||||
|
$this->assertEquals($expected, zdate('1969-12-31 15:00:00', 'Y-m-d H:i:s'));
|
||||||
|
Rhymix\Framework\Config::set('locale.internal_timezone', 10800);
|
||||||
|
$expected = '1970-01-01 06:00:00';
|
||||||
|
$this->assertEquals($expected, zdate('19700101000000', 'Y-m-d H:i:s'));
|
||||||
|
$expected = '1970-01-01 00:00:00';
|
||||||
|
$this->assertEquals($expected, zdate('19691231180000', 'Y-m-d H:i:s'));
|
||||||
|
|
||||||
// Restore the internal timezone.
|
// Restore the internal timezone.
|
||||||
Rhymix\Framework\Config::set('locale.internal_timezone', 10800);
|
Rhymix\Framework\Config::set('locale.internal_timezone', 10800);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue