Merge branch 'develop' into pr/member-phone-number

This commit is contained in:
Kijin Sung 2019-07-27 23:47:24 +09:00
commit c09d2a773d
2041 changed files with 23045 additions and 18189 deletions

View file

@ -2,9 +2,8 @@ RewriteEngine On
# block direct access to templates, XML schema files, config files, dotfiles, environment, etc.
RewriteCond %{REQUEST_URI} !/modules/editor/(skins|styles)/
RewriteCond %{REQUEST_URI} !/common/manual/
RewriteRule ^(addons|common/tpl|files/ruleset|(m\.)?layouts|modules|plugins|themes|widgets|widgetstyles)/.+\.(html|xml)$ - [L,F]
RewriteRule ^files/(attach|config|cache/store)/.+\.php$ - [L,F]
RewriteRule ^files/(attach|config|cache/store)/.+\.(ph(p|t|ar)?[0-9]?|p?html?|cgi|pl|exe|[aj]spx?|inc|bak)$ - [L,F]
RewriteRule ^files/(env|member_extra_info/(new_message_flags|point))/ - [L,F]
RewriteRule ^(\.git|\.ht|\.travis|codeception\.|composer\.|Gruntfile\.js|package\.json|CONTRIBUTING|COPYRIGHT|LICENSE|README) - [L,F]

View file

@ -5,18 +5,15 @@ php:
- 7.0
- 7.1
- 7.2
- nightly
matrix:
allow_failures:
- php: nightly
- 7.3
services:
- mysql
before_script:
- npm install grunt grunt-cli grunt-contrib-jshint grunt-contrib-csslint grunt-phplint --save-dev
- mysql -u root -e "CREATE DATABASE rhymix CHARSET utf8mb4 COLLATE utf8mb4_unicode_ci"
- mysql -u root -e "GRANT ALL PRIVILEGES ON rhymix.* TO travis@localhost"
- mysql -u root -e "UPDATE mysql.user SET Password = PASSWORD('travis') WHERE User = 'travis'; FLUSH PRIVILEGES"
- if [[ $TRAVIS_PHP_VERSION != "nightly" ]]; then phpenv config-rm xdebug.ini; fi
- mysql -u root -e "SET PASSWORD FOR travis@localhost = PASSWORD('travis'); FLUSH PRIVILEGES"
- if [[ $TRAVIS_PHP_VERSION != "7.3" ]]; then phpenv config-rm xdebug.ini; fi
- wget https://codeception.com/releases/2.3.9/codecept.phar
- php -S localhost:8000 &
script:

View file

@ -47,11 +47,11 @@ devops@rhymix.org로 알려 주시면 감사하겠습니다.
### 공식 홈페이지
- Rhymix : https://www.rhymix.org
- Rhymix : https://rhymix.org
### 커뮤니티
- XETOWN : https://www.xetown.com
- XETOWN : https://xetown.com
### 저작권 및 라이선스
@ -118,11 +118,11 @@ If you have found a security vulnerability, please let us know at devops@rhymix.
### Official Website
- Rhymix : https://www.rhymix.org
- Rhymix : https://rhymix.org
### Community
- XETOWN (Korean) : https://www.xetown.com
- XETOWN (Korean) : https://xetown.com
### Copyright and License

View file

@ -20,4 +20,16 @@
<name xml:lang="ko">Rhymix contributors</name>
<name xml:lang="en">Rhymix contributors</name>
</author>
<extra_vars>
<var name="display_name" type="select">
<title xml:lang="ko">파일이름 출력 설정</title>
<description xml:lang="ko">넘겨보기 실행시 하단에 파일이름을 출력할 것인지 여부를 선택합니다. 기본값은 사용하도록 되어있습니다.</description>
<options value="block">
<title xml:lang="ko">사용</title>
</options>
<options value="none">
<title xml:lang="ko">사용 안함</title>
</options>
</var>
</extra_vars>
</addon>

View file

@ -21,7 +21,10 @@ if($called_position == 'after_module_proc' && Context::getResponseMethod() == "H
Context::loadFile(array('./addons/photoswipe/rx_photoswipe.js', 'body', '', null), true);
$footer = FileHandler::readFile('./addons/photoswipe/PhotoSwipe/pswp.html');
Context::addHtmlFooter($footer);
$style_display = isset($addon_info->display_name) ? "<style>.pswp__caption__center { display:{$addon_info->display_name} }</style>" : '<style>.pswp__caption__center { display:block }</style>';
Context::addHtmlFooter($style_display . $footer);
}
/* End of file photoswipe.addon.php */

View file

@ -18,7 +18,7 @@ class reCAPTCHA
$response = Context::get('g-recaptcha-response');
if (!$response)
{
return new BaseObject(-1, 'recaptcha.msg_recaptcha_invalid_response');
throw new Rhymix\Framework\Exception('recaptcha.msg_recaptcha_invalid_response');
}
try
@ -31,17 +31,17 @@ class reCAPTCHA
}
catch (\Requests_Exception $e)
{
return new BaseObject(-1, 'recaptcha.msg_recaptcha_connection_error');
throw new Rhymix\Framework\Exception('recaptcha.msg_recaptcha_connection_error');
}
$verify = @json_decode($verify_request->body, true);
if ($verify && isset($verify['error-codes']) && in_array('invalid-input-response', $verify['error-codes']))
{
return new BaseObject(-1, 'recaptcha.msg_recaptcha_invalid_response');
throw new Rhymix\Framework\Exception('recaptcha.msg_recaptcha_invalid_response');
}
elseif (!$verify || !$verify['success'] || (isset($verify['error-codes']) && $verify['error-codes']))
{
return new BaseObject(-1, 'recaptcha.msg_recaptcha_server_error');
throw new Rhymix\Framework\Exception('recaptcha.msg_recaptcha_server_error');
}
else
{

View file

@ -117,10 +117,10 @@ class Context
public $is_site_locked = FALSE;
/**
* Check init
* @var bool FALSE if init fail
* Result of initial security check
* @var string|bool
*/
public $isSuccessInit = TRUE;
public $security_check = 'OK';
/**
* Singleton instance
@ -173,8 +173,9 @@ class Context
* @var array
*/
private static $_check_patterns = array(
'@<(?:\?|%)@',
'@</?script@i',
'@<(?:\?|%)@' => 'DENY ALL',
'@<script\s*?language\s*?=@i' => 'DENY ALL',
'@</?script@i' => 'ALLOW ADMIN ONLY',
);
/**
@ -256,14 +257,6 @@ class Context
// If Rhymix is installed, get virtual site information.
if(self::isInstalled())
{
$oModuleModel = getModel('module');
$site_module_info = $oModuleModel->getDefaultMid() ?: new stdClass;
self::set('site_module_info', $site_module_info);
self::set('_default_timezone', ($site_module_info->settings && $site_module_info->settings->timezone) ? $site_module_info->settings->timezone : null);
self::set('_default_url', self::$_instance->db_info->default_url = self::getDefaultUrl($site_module_info));
self::set('_http_port', self::$_instance->db_info->http_port = $site_module_info->http_port ?: null);
self::set('_https_port', self::$_instance->db_info->https_port = $site_module_info->https_port ?: null);
self::set('_use_ssl', self::$_instance->db_info->use_ssl = $site_module_info->security ?: 'none');
if (PHP_SAPI === 'cli')
{
self::set('_default_url', $default_url = config('url.default'));
@ -272,6 +265,14 @@ class Context
define('RX_BASEURL', parse_url($default_url, PHP_URL_PATH));
}
}
$oModuleModel = getModel('module');
$site_module_info = $oModuleModel->getDefaultMid() ?: new stdClass;
self::set('site_module_info', $site_module_info);
self::set('_default_timezone', ($site_module_info->settings && $site_module_info->settings->timezone) ? $site_module_info->settings->timezone : null);
self::set('_default_url', self::$_instance->db_info->default_url = self::getDefaultUrl($site_module_info));
self::set('_http_port', self::$_instance->db_info->http_port = $site_module_info->http_port ?: null);
self::set('_https_port', self::$_instance->db_info->https_port = $site_module_info->https_port ?: null);
self::set('_use_ssl', self::$_instance->db_info->use_ssl = $site_module_info->security ?: 'none');
}
else
{
@ -294,13 +295,14 @@ class Context
// Load language support.
$enabled_langs = self::loadLangSelected();
$set_lang_cookie = false;
self::set('lang_supported', $enabled_langs);
if($lang_type = self::get('l'))
{
if($_COOKIE['lang_type'] !== $lang_type)
{
setcookie('lang_type', $lang_type, time() + 86400 * 365, '/', null, !!config('session.use_ssl_cookies'));
$set_lang_cookie = true;
}
}
elseif($_COOKIE['lang_type'])
@ -316,11 +318,17 @@ class Context
if(!strncasecmp($lang_code, $_SERVER['HTTP_ACCEPT_LANGUAGE'], strlen($lang_code)))
{
$lang_type = $lang_code;
$set_lang_cookie = true;
}
}
}
}
$lang_type = preg_replace('/[^a-zA-Z0-9_-]/', '', $lang_type);
if ($set_lang_cookie)
{
setcookie('lang_type', $lang_type, time() + 86400 * 365, '/', null, !!config('session.use_ssl_cookies'));
}
}
}
}
if(!$lang_type || !isset($enabled_langs[$lang_type]))
{
@ -351,6 +359,7 @@ class Context
{
$oSessionModel = getModel('session');
$oSessionController = getController('session');
ini_set('session.serialize_handler', 'php');
session_set_save_handler(
array(&$oSessionController, 'open'), array(&$oSessionController, 'close'), array(&$oSessionModel, 'read'), array(&$oSessionController, 'write'), array(&$oSessionController, 'destroy'), array(&$oSessionController, 'gc')
);
@ -794,7 +803,7 @@ class Context
return '';
}
getController('module')->replaceDefinedLangCode(self::$_instance->browser_title);
return htmlspecialchars(self::$_instance->browser_title, ENT_COMPAT | ENT_HTML401, 'UTF-8', FALSE);
return htmlspecialchars(self::$_instance->browser_title, ENT_QUOTES, 'UTF-8', FALSE);
}
/**
@ -885,6 +894,7 @@ class Context
{
self::$_instance->db_info = new stdClass;
}
self::$_instance->db_info->lang_type = $lang_type;
self::$_instance->lang_type = $lang_type;
self::set('lang_type', $lang_type);
@ -1070,7 +1080,7 @@ class Context
{
if (!self::_recursiveCheckVar($_SERVER['HTTP_HOST']) || preg_match("/[\,\"\'\{\}\[\]\(\);$]/", $_SERVER['HTTP_HOST']))
{
self::$_instance->isSuccessInit = FALSE;
self::$_instance->security_check = 'DENY ALL';
}
}
@ -1205,7 +1215,7 @@ class Context
{
if(self::getRequestMethod() === 'XMLRPC')
{
if(!Rhymix\Framework\Security::checkXEE($GLOBALS['HTTP_RAW_POST_DATA']))
if(!Rhymix\Framework\Security::checkXXE($GLOBALS['HTTP_RAW_POST_DATA']))
{
header("HTTP/1.0 400 Bad Request");
exit;
@ -1261,10 +1271,16 @@ class Context
$tmp_name = $val['tmp_name'];
if(!is_array($tmp_name))
{
if(!$tmp_name || !is_uploaded_file($tmp_name) || $val['size'] <= 0)
if($val['name'] === '' && $val['size'] == 0)
{
continue;
}
if(!UploadFileFilter::check($tmp_name, $val['name']))
{
self::$_instance->security_check = 'DENY ALL';
unset($_FILES[$key]);
continue;
}
$val['name'] = escape($val['name'], false);
self::set($key, $val, true);
self::set('is_uploaded', true);
@ -1275,8 +1291,17 @@ class Context
$files = array();
foreach ($tmp_name as $i => $j)
{
if($val['size'][$i] > 0)
if($val['name'][$i] === '' && $val['size'][$i] == 0)
{
continue;
}
if(!UploadFileFilter::check($val['tmp_name'][$i], $val['name'][$i]))
{
self::$_instance->security_check = 'DENY ALL';
$files = array();
unset($_FILES[$key]);
break;
}
$file = array();
$file['name'] = $val['name'][$i];
$file['type'] = $val['type'][$i];
@ -1285,7 +1310,6 @@ class Context
$file['size'] = $val['size'][$i];
$files[] = $file;
}
}
if(count($files))
{
self::set($key, $files, true);
@ -1304,15 +1328,18 @@ class Context
{
if(is_string($val))
{
foreach(self::$_check_patterns as $pattern)
foreach(self::$_check_patterns as $pattern => $status)
{
if(preg_match($pattern, $val))
{
self::$_instance->isSuccessInit = false;
self::$_instance->security_check = $status;
if($status === 'DENY ALL')
{
return false;
}
}
}
}
else if(is_array($val))
{
foreach($val as $val2)
@ -1403,20 +1430,17 @@ class Context
}
elseif($_val = trim($_val))
{
if(in_array($key, array('page', 'cpage')) || ends_with('srl', $key, false))
{
if(preg_match('/[^0-9,]/', $_val))
if(in_array($key, array('page', 'cpage')) || ends_with('srl', $key, false) && preg_match('/[^0-9,]/', $_val))
{
$_val = (int)$_val;
}
}
elseif(in_array($key, array('mid', 'search_keyword', 'xe_validator_id')))
elseif(in_array($key, array('mid', 'vid', 'search_target', 'search_keyword', 'xe_validator_id')) || $_SERVER['REQUEST_METHOD'] === 'GET')
{
$_val = escape($_val, false);
}
elseif($key === 'vid')
if(ends_with('url', $key, false))
{
$_val = urlencode($_val);
$_val = strtr($_val, array('&amp;' => '&'));
}
}
}
$result[escape($_key)] = $_val;
@ -1698,24 +1722,42 @@ class Context
// If using SSL always
if($site_module_info->security == 'always')
{
if(!$domain && RX_SSL)
{
$query = RX_BASEURL . $query;
}
else
{
$query = self::getRequestUri(ENFORCE_SSL, $domain) . $query;
}
}
// optional SSL use
elseif($site_module_info->security == 'optional')
{
$ssl_mode = ((self::get('module') === 'admin') || ($get_vars['module'] === 'admin') || (isset($get_vars['act']) && self::isExistsSSLAction($get_vars['act']))) ? ENFORCE_SSL : RELEASE_SSL;
if(!$domain && (RX_SSL && ENFORCE_SSL) || (!RX_SSL && RELEASE_SSL))
{
$query = RX_BASEURL . $query;
}
else
{
$query = self::getRequestUri($ssl_mode, $domain) . $query;
}
}
// no SSL
else
{
// currently on SSL but target is not based on SSL
if(RX_SSL)
if(!$domain && RX_SSL)
{
$query = RX_BASEURL . $query;
}
elseif(RX_SSL)
{
$query = self::getRequestUri(ENFORCE_SSL, $domain) . $query;
}
else if($domain) // if $domain is set
elseif($domain)
{
$query = self::getRequestUri(FOLLOW_REQUEST_SSL, $domain) . $query;
}
@ -1732,7 +1774,7 @@ class Context
if(!$autoEncode)
{
return htmlspecialchars($query, ENT_COMPAT | ENT_HTML401, 'UTF-8', FALSE);
return htmlspecialchars($query, ENT_QUOTES, 'UTF-8', FALSE);
}
$output = array();
@ -1748,7 +1790,7 @@ class Context
$encode_queries[] = $key . '=' . $value;
}
return htmlspecialchars($parsedUrl['path'] . '?' . join('&', $encode_queries), ENT_COMPAT | ENT_HTML401, 'UTF-8', FALSE);
return htmlspecialchars($parsedUrl['path'] . '?' . join('&', $encode_queries), ENT_QUOTES, 'UTF-8', FALSE);
}
/**
@ -1810,6 +1852,12 @@ class Context
*/
public static function set($key, $val, $set_to_get_vars = false)
{
if(empty($key))
{
trigger_error('Called Context::set() with an empty key', \E_USER_WARNING);
return;
}
self::$_tpl_vars->{$key} = $val;
if($set_to_get_vars || isset(self::$_get_vars->{$key}))
@ -1833,6 +1881,12 @@ class Context
*/
public static function get($key)
{
if(empty($key))
{
trigger_error('Called Context::get() with an empty key', \E_USER_WARNING);
return;
}
if(isset(self::$_tpl_vars->{$key}))
{
return self::$_tpl_vars->{$key};

View file

@ -122,7 +122,8 @@ class DB
}
if(!$db_type && Context::isInstalled())
{
return new BaseObject(-1, 'msg_db_not_setted');
Rhymix\Framework\Debug::displayError(lang('msg_db_not_setted'));
exit;
}
if(!strncmp($db_type, 'mysql', 5))
{
@ -139,7 +140,8 @@ class DB
$class_file = RX_BASEDIR . "classes/db/$class_name.class.php";
if(!file_exists($class_file))
{
return new BaseObject(-1, 'msg_db_not_setted');
Rhymix\Framework\Debug::displayError(sprintf('DB type "%s" is not supported.', $db_type));
exit;
}
// get a singletone instance of the database driver class

View file

@ -73,16 +73,16 @@ class DBMySQL extends DB
// Check connection error
if($mysqli->connect_errno)
{
$this->setError($mysqli->connect_errno, $mysqli->connect_error());
return;
Rhymix\Framework\Debug::displayError(sprintf('DB ERROR %d : %s', $mysqli->connect_errno, $mysqli->connect_error));
exit;
}
// Check DB version
$this->db_version = $mysqli->server_info;
if (version_compare($this->db_version, '5.0.7', '<'))
{
$this->setError(-1, 'Rhymix requires MySQL 5.0.7 or later. Current MySQL version is ' . $this->db_version);
return;
Rhymix\Framework\Debug::displayError('Rhymix requires MySQL 5.0.7 or later. Current MySQL version is ' . $this->db_version);
exit;
}
// Set DB charset

View file

@ -157,7 +157,7 @@ class Query extends BaseObject
foreach($this->columnList as $columnName)
{
$columnName = $dbParser->escapeColumn($columnName);
$columnName = $dbParser->escapeColumnExpression($columnName);
$selectColumns[] = new SelectExpression($columnName);
}
unset($this->columns);
@ -586,6 +586,11 @@ class Query extends BaseObject
*/
function getHavingString($with_values = TRUE)
{
if(!is_array($this->having))
{
return '';
}
$having = '';
$condition_count = 0;

View file

@ -157,16 +157,22 @@ class DisplayHandler extends Handler
}
// Do not display debugging information if there is no output.
$display_type = config('debug.display_type');
if ($output === null && $display_type !== 'file')
$display_types = config('debug.display_type');
if (!is_array($display_types))
{
$display_types = array($display_types);
}
if ($output === null && !in_array('file', $display_types))
{
return;
}
// Print debug information.
switch ($display_type)
$debug_output = '';
foreach ($display_types as $display_type)
{
if ($display_type === 'panel')
{
case 'panel':
$data = Rhymix\Framework\Debug::getDebugData();
$display_content = array_fill_keys(config('debug.display_content'), true);
if (count($display_content) && !isset($display_content['entries']))
@ -220,7 +226,7 @@ class DisplayHandler extends Handler
$panel_script .= "\n<script>\nvar rhymix_debug_content = " . json_encode($data, $json_options) . ";\n</script>";
$body_end_position = strrpos($output, '</body>') ?: strlen($output);
$output = substr($output, 0, $body_end_position) . "\n$panel_script\n" . substr($output, $body_end_position);
return;
break;
case 'JSON':
if (RX_POST && preg_match('/^proc/', Context::get('act')))
{
@ -236,17 +242,16 @@ class DisplayHandler extends Handler
{
$output = $matches[1] . ',"_rx_debug":' . json_encode($data) . '}';
}
return;
break;
default:
return;
break;
}
case 'comment':
case 'file':
default:
}
else
{
if ($display_type === 'comment' && Context::getResponseMethod() !== 'HTML')
{
return;
break;
}
ob_start();
$data = Rhymix\Framework\Debug::getDebugData();
@ -272,15 +277,18 @@ class DisplayHandler extends Handler
$phpheader = '';
}
FileHandler::writeFile($log_filename, $phpheader . $content . PHP_EOL, 'a');
return '';
$debug_output .= '';
}
else
{
return '<!--' . PHP_EOL . $content . PHP_EOL . '-->';
$debug_output .= '<!--' . PHP_EOL . $content . PHP_EOL . '-->' . PHP_EOL;
}
}
}
return $debug_output;
}
/**
* print a HTTP HEADER for XML, which is encoded in UTF-8
* @return void

View file

@ -19,7 +19,7 @@ class HTMLDisplayHandler
* List of scripts to block loading
*/
public static $blockedScripts = array(
'@(?:^|/)j[Qq]uery(?:-[0-9]+(?:\.[0-9x]+)*)?(?:\.min)?\.js$@',
'@(?:^|/)j[Qq]uery(?:-[0-9]+(?:\.[0-9x]+)*|-latest)?(?:\.min)?\.js$@',
);
/**
@ -157,6 +157,21 @@ class HTMLDisplayHandler
}
}
}
// Add OpenGraph metadata
if (config('seo.og_enabled') && Context::get('module') !== 'admin')
{
$this->_addOpenGraphMetadata();
}
// set icon
$site_module_info = Context::get('site_module_info');
$oAdminModel = getAdminModel('admin');
$favicon_url = $oAdminModel->getFaviconUrl($site_module_info->domain_srl);
$mobicon_url = $oAdminModel->getMobileIconUrl($site_module_info->domain_srl);
Context::set('favicon_url', $favicon_url);
Context::set('mobicon_url', $mobicon_url);
return $output;
}
@ -221,20 +236,6 @@ class HTMLDisplayHandler
// Remove unnecessary information
$output = preg_replace('/member\_\-([0-9]+)/s', 'member_0', $output);
// Add OpenGraph metadata
if (config('seo.og_enabled') && Context::get('module') !== 'admin')
{
$this->_addOpenGraphMetadata();
}
// set icon
$site_module_info = Context::get('site_module_info');
$oAdminModel = getAdminModel('admin');
$favicon_url = $oAdminModel->getFaviconUrl($site_module_info->domain_srl);
$mobicon_url = $oAdminModel->getMobileIconUrl($site_module_info->domain_srl);
Context::set('favicon_url', $favicon_url);
Context::set('mobicon_url', $mobicon_url);
// convert the final layout
Context::set('content', $output);
$oTemplate = TemplateHandler::getInstance();
@ -581,6 +582,7 @@ class HTMLDisplayHandler
Context::loadFile(array('./common/css/rhymix.less', '', '', -1600000000), true);
$original_file_list = array(
'plugins/jquery.migrate/jquery-migrate-1.4.1.min.js',
'plugins/cookie/js.cookie.min.js',
'plugins/blankshield/blankshield.min.js',
'plugins/uri/URI.min.js',
'x.js',

View file

@ -209,7 +209,7 @@ class ExtraItem
{
$value = 'http://' . $value;
}
return htmlspecialchars($value, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);
return escape($value, false);
case 'tel' :
if(is_array($value))
@ -232,7 +232,7 @@ class ExtraItem
$values = array_values($values);
for($i = 0, $c = count($values); $i < $c; $i++)
{
$values[$i] = trim(htmlspecialchars($values[$i], ENT_COMPAT | ENT_HTML401, 'UTF-8', false));
$values[$i] = trim(escape($values[$i], false));
}
return $values;
@ -259,7 +259,7 @@ class ExtraItem
$values = array_values($values);
for($i = 0, $c = count($values); $i < $c; $i++)
{
$values[$i] = trim(htmlspecialchars($values[$i], ENT_COMPAT | ENT_HTML401, 'UTF-8', false));
$values[$i] = trim(escape($values[$i], false));
}
return $values;
@ -280,7 +280,7 @@ class ExtraItem
$values = array_values($values);
for($i = 0, $c = count($values); $i < $c; $i++)
{
$values[$i] = trim(htmlspecialchars($values[$i], ENT_COMPAT | ENT_HTML401, 'UTF-8', false));
$values[$i] = trim(escape($values[$i], false));
}
return $values;
@ -290,7 +290,7 @@ class ExtraItem
//case 'textarea' :
//case 'password' :
default :
return htmlspecialchars($value, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);
return escape($value, false);
}
}
@ -404,7 +404,7 @@ class ExtraItem
// Temporary ID for labeling
$tmp_id = $column_name . '-' . $id_num++;
$buff[] =' <li><input type="checkbox" name="' . $column_name . '[]" id="' . $tmp_id . '" value="' . htmlspecialchars($v, ENT_COMPAT | ENT_HTML401, 'UTF-8', false) . '" ' . $checked . ' /><label for="' . $tmp_id . '">' . $v . '</label></li>';
$buff[] =' <li><input type="checkbox" name="' . $column_name . '[]" id="' . $tmp_id . '" value="' . escape($v, false) . '" ' . $checked . ' /><label for="' . $tmp_id . '">' . $v . '</label></li>';
}
$buff[] = '</ul>';
break;
@ -485,7 +485,7 @@ class ExtraItem
{
$oModuleController = getController('module');
$oModuleController->replaceDefinedLangCode($this->desc);
$buff[] = '<p>' . htmlspecialchars($this->desc, ENT_COMPAT | ENT_HTML401, 'UTF-8', false) . '</p>';
$buff[] = '<p>' . escape($this->desc, false) . '</p>';
}
return join(PHP_EOL, $buff);

View file

@ -217,7 +217,9 @@ class Mail extends Rhymix\Framework\Mail
*/
public static function isVaildMailAddress($email_address)
{
if(preg_match("/([a-z0-9\_\-\.]+)@([a-z0-9\_\-\.]+)/i", $email_address))
$validator = new \Egulias\EmailValidator\EmailValidator;
$rfc = new \Egulias\EmailValidator\Validation\RFCValidation;
if($validator->isValid($email_address, $rfc))
{
return $email_address;
}

View file

@ -42,15 +42,23 @@ class ModuleHandler extends Handler
return;
}
// Check security check status
$oContext = Context::getInstance();
if($oContext->isSuccessInit == FALSE)
switch($oContext->security_check)
{
$logged_info = Context::get('logged_info');
if($logged_info->is_admin != "Y")
case 'OK':
break;
case 'ALLOW ADMIN ONLY':
if(!Context::get('logged_info')->isAdmin())
{
$this->error = 'msg_invalid_request';
$this->error = 'msg_security_violation';
return;
}
break;
case 'DENY ALL':
default:
$this->error = 'msg_security_violation';
return;
}
// Set variables from request arguments
@ -70,26 +78,23 @@ class ModuleHandler extends Handler
}
// Validate variables to prevent XSS
$isInvalid = NULL;
if($this->module && !preg_match("/^([a-z0-9\_\-]+)$/i", $this->module))
$isInvalid = false;
if($this->module && !preg_match('/^[a-zA-Z0-9_-]+$/', $this->module))
{
$isInvalid = TRUE;
$isInvalid = true;
}
if($this->mid && !preg_match("/^([a-z0-9\_\-]+)$/i", $this->mid))
if($this->mid && !preg_match('/^[a-zA-Z0-9_-]+$/', $this->mid))
{
$isInvalid = TRUE;
$isInvalid = true;
}
if($this->act && !preg_match("/^([a-z0-9\_\-]+)$/i", $this->act))
if($this->act && !preg_match('/^[a-zA-Z0-9_-]+$/', $this->act))
{
$isInvalid = TRUE;
$isInvalid = true;
}
if($isInvalid)
{
htmlHeader();
echo lang("msg_invalid_request");
htmlFooter();
Context::close();
exit;
$this->error = 'msg_security_violation';
return;
}
if(isset($this->act) && (strlen($this->act) >= 4 && substr_compare($this->act, 'disp', 0, 4) === 0))
@ -442,7 +447,13 @@ class ModuleHandler extends Handler
// get type, kind
$type = $xml_info->action->{$this->act}->type;
$ruleset = $xml_info->action->{$this->act}->ruleset;
$meta_noindex = $xml_info->action->{$this->act}->meta_noindex;
$kind = stripos($this->act, 'admin') !== FALSE ? 'admin' : '';
if ($meta_noindex === 'true')
{
Context::addMetaTag('robots', 'noindex');
}
if(!$kind && $this->module == 'admin')
{
$kind = 'admin';
@ -464,7 +475,7 @@ class ModuleHandler extends Handler
if(!in_array(strtoupper($_SERVER['REQUEST_METHOD']), $allowedMethodList))
{
$this->error = "msg_invalid_request";
$this->error = 'msg_invalid_request';
$oMessageObject = self::getModuleInstance('message', $display_mode);
$oMessageObject->setError(-1);
$oMessageObject->setMessage($this->error);
@ -559,6 +570,7 @@ class ModuleHandler extends Handler
$forward->module = $module;
$forward->type = $xml_info->action->{$this->act}->type;
$forward->ruleset = $xml_info->action->{$this->act}->ruleset;
$forward->meta_noindex = $xml_info->action->{$this->act}->meta_noindex;
$forward->act = $this->act;
}
else
@ -585,6 +597,10 @@ class ModuleHandler extends Handler
$ruleset = $forward->ruleset;
$tpl_path = $oModule->getTemplatePath();
$orig_module = $oModule;
if($forward->meta_noindex === 'true')
{
Context::addMetaTag('robots', 'noindex');
}
$xml_info = $oModuleModel->getModuleActionXml($forward->module);
@ -620,7 +636,7 @@ class ModuleHandler extends Handler
if(!in_array(strtoupper($_SERVER['REQUEST_METHOD']), $allowedMethodList))
{
$this->error = "msg_invalid_request";
$this->error = 'msg_security_violation';
$oMessageObject = self::getModuleInstance('message', $display_mode);
$oMessageObject->setError(-1);
$oMessageObject->setMessage($this->error);
@ -635,7 +651,7 @@ class ModuleHandler extends Handler
if($xml_info->action->{$this->act} && $xml_info->action->{$this->act}->check_csrf !== 'false' && !checkCSRF())
{
$this->_setInputErrorToContext();
$this->error = 'msg_invalid_request';
$this->error = 'msg_security_violation';
$oMessageObject = ModuleHandler::getModuleInstance('message', $display_mode);
$oMessageObject->setError(-1);
$oMessageObject->setMessage($this->error);
@ -781,6 +797,10 @@ class ModuleHandler extends Handler
}
}
if ($kind === 'admin') {
Context::addMetaTag('robots', 'noindex');
}
// if failed message exists in session, set context
self::_setInputErrorToContext();
@ -1016,14 +1036,24 @@ class ModuleHandler extends Handler
}
// Set menus into context
if($layout_info->menu_count)
{
foreach($layout_info->menu as $menu_id => $menu)
{
// set default menu set(included home menu)
if(!$menu->menu_srl || $menu->menu_srl == -1)
{
$oMenuAdminController = getAdminController('menu');
$homeMenuCacheFile = null;
foreach($layout_info->menu as $menu_id => $menu)
{ // No menu selected
if($menu->menu_srl == 0)
{
$menu->list = array();
}
else
{
if($menu->menu_srl == -1)
{
if ($homeMenuCacheFile === null)
{
$homeMenuCacheFile = $oMenuAdminController->getHomeMenuCacheFile();
}
$homeMenuSrl = 0;
if(FileHandler::exists($homeMenuCacheFile))
@ -1033,23 +1063,21 @@ class ModuleHandler extends Handler
$menu->xml_file = './files/cache/menu/' . $homeMenuSrl . '.xml.php';
$menu->php_file = './files/cache/menu/' . $homeMenuSrl . '.php';
if(!$menu->menu_srl)
{
$layout_info->menu->{$menu_id}->menu_srl = $homeMenuSrl;
}
$menu->menu_srl = $homeMenuSrl;
}
$php_file = FileHandler::exists($menu->php_file);
if(!$php_file)
{
$oMenuAdminController = $oMenuAdminController ?: getAdminController('menu');
$oMenuAdminController->makeXmlFile((isset($homeMenuSrl) && $homeMenuSrl) ? $homeMenuSrl : $menu->menu_srl);
$oMenuAdminController->makeXmlFile($menu->menu_srl);
$php_file = FileHandler::exists($menu->php_file);
}
if($php_file)
{
include($php_file);
}
}
Context::set($menu_id, $menu);
}
}
@ -1267,9 +1295,16 @@ class ModuleHandler extends Handler
continue;
}
try
{
$before_each_trigger_time = microtime(true);
$output = $oModule->{$called_method}($obj);
$after_each_trigger_time = microtime(true);
}
catch (Rhymix\Framework\Exception $e)
{
$output = new BaseObject(-2, $e->getMessage());
}
if ($trigger_name !== 'common.flushDebugInfo')
{
@ -1292,10 +1327,17 @@ class ModuleHandler extends Handler
$trigger_functions = $oModuleModel->getTriggerFunctions($trigger_name, $called_position);
foreach($trigger_functions as $item)
{
try
{
$before_each_trigger_time = microtime(true);
$output = $item($obj);
$after_each_trigger_time = microtime(true);
}
catch (Rhymix\Framework\Exception $e)
{
$output = new BaseObject(-2, $e->getMessage());
}
if ($trigger_name !== 'common.writeSlowlog')
{

View file

@ -136,15 +136,37 @@ class ModuleObject extends BaseObject
// Set privileges(granted) information
if($this->setPrivileges() !== true)
{
$this->stop('msg_invalid_request');
$this->stop('msg_not_permitted');
return;
}
// Set admin layout
if(preg_match('/^disp[A-Z][a-z0-9\_]+Admin/', $this->act))
{
if(config('view.manager_layout') === 'admin')
{
$this->setLayoutPath('modules/admin/tpl');
$this->setLayoutFile('layout');
}
else
{
$oTemplate = TemplateHandler::getInstance();
$oTemplate->compile('modules/admin/tpl', '_admin_common.html');
}
}
// Execute init
if(method_exists($this, 'init'))
{
try
{
$this->init();
}
catch (Rhymix\Framework\Exception $e)
{
$this->stop($e->getMessage());
}
}
}
/**
@ -441,9 +463,7 @@ class ModuleObject extends BaseObject
* */
function setLayoutFile($filename)
{
if(!$filename) return;
if(substr_compare($filename, '.html', -5) !== 0)
if($filename && substr_compare($filename, '.html', -5) !== 0)
{
$filename .= '.html';
}
@ -530,35 +550,55 @@ class ModuleObject extends BaseObject
return FALSE;
}
// integrate skin information of the module(change to sync skin info with the target module only by seperating its table)
// Set module skin
if(isset($this->module_info->skin) && $this->module_info->module === $this->module && strpos($this->act, 'Admin') === false)
{
$oModuleModel = getModel('module');
$default_skin = ((!$is_mobile && $this->module_info->is_skin_fix == 'N') || ($is_mobile && $this->module_info->is_mskin_fix == 'N'));
$disable_skin = ($this->module == 'page' && ($this->module_info->page_type == 'OUTSIDE' || $this->module_info->page_type == 'WIDGET'));
if(!$disable_skin && $default_skin && $this->module != 'admin' && strpos($this->act, 'Admin') === false && $this->module == $this->module_info->module)
$skin_type = $is_mobile ? 'M' : 'P';
$skin_key = $is_mobile ? 'mskin' : 'skin';
$skin_dir = $is_mobile ? 'm.skins' : 'skins';
$module_skin = $this->module_info->{$skin_key} ?: '/USE_DEFAULT/';
$use_default_skin = $this->module_info->{'is_' . $skin_key . '_fix'} === 'N';
// Set default skin
if(!$this->getTemplatePath() || $use_default_skin)
{
$skinType = ($is_mobile && $this->module_info->mskin !== '/USE_RESPONSIVE/') ? 'M' : 'P';
$dir = $skinType === 'M' ? 'm.skins' : 'skins';
$valueName = $skinType === 'M' ? 'mskin' : 'skin';
$skinName = $this->module_info->{$valueName} === '/USE_DEFAULT/' ? $oModuleModel->getModuleDefaultSkin($this->module, $skinType) : $this->module_info->{$valueName};
if($this->module == 'page')
if($module_skin === '/USE_DEFAULT/')
{
$this->module_info->{$valueName} = $skinName;
$module_skin = $oModuleModel->getModuleDefaultSkin($this->module, $skin_type);
$this->module_info->{$skin_key} = $module_skin;
}
else
if($module_skin === '/USE_RESPONSIVE/')
{
$isTemplatPath = (strpos($this->getTemplatePath(), '/tpl/') !== FALSE);
if(!$isTemplatPath)
$skin_dir = 'skins';
$module_skin = $this->module_info->skin ?: '/USE_DEFAULT/';
if($module_skin === '/USE_DEFAULT/')
{
$this->setTemplatePath(sprintf('%s%s/%s/', $this->module_path, $dir, $skinName));
$module_skin = $oModuleModel->getModuleDefaultSkin($this->module, 'P');
}
}
if(!is_dir(sprintf('%s%s/%s', $this->module_path, $skin_dir, $module_skin)))
{
$module_skin = 'default';
}
$this->setTemplatePath(sprintf('%s%s/%s', $this->module_path, $skin_dir, $module_skin));
}
// Set skin variable
$oModuleModel->syncSkinInfoToModuleInfo($this->module_info);
Context::set('module_info', $this->module_info);
}
// Run
try
{
$output = $this->{$this->act}();
}
catch (Rhymix\Framework\Exception $e)
{
$output = new BaseObject(-2, $e->getMessage());
}
}
else
{
return FALSE;

View file

@ -46,6 +46,22 @@ class BaseObject
$this->setMessage($message);
}
/**
* Set state for var_export()
*
* @param array $vars
* @return object
*/
public static function __set_state(array $vars)
{
$instance = new static;
foreach ($vars as $key => $val)
{
$instance->{$key} = $val;
}
return $instance;
}
/**
* Setter to set error code or message
*

View file

@ -115,7 +115,7 @@ class Security
{
if(strncmp('$user_lang->', $var, 12) !== 0)
{
$var = htmlspecialchars($var, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);
$var = escape($var, false);
}
return $var;
@ -185,7 +185,7 @@ class Security
*/
public static function detectingXEE($xml)
{
return !Rhymix\Framework\Security::checkXEE($xml);
return !Rhymix\Framework\Security::checkXXE($xml);
}
}
/* End of file : Security.class.php */

View file

@ -1,11 +1,24 @@
<?php
/* Copyright (C) NAVER <http://www.navercorp.com> */
class UploadFileFilter
{
public function check($file)
/**
* Generic checker
*
* @param string $file
* @param string $filename
* @return bool
*/
public static function check($file, $filename = null)
{
return true;
// Return error if the file is not uploaded.
if (!$file || !file_exists($file) || !is_uploaded_file($file))
{
return false;
}
// Call Rhymix framework filter.
return Rhymix\Framework\Filters\FileContentFilter::check($file, $filename);
}
}

View file

@ -327,7 +327,7 @@ class TemplateHandler
{
preg_match('/<input[^>]*name="error_return_url"[^>]*>/is', $matches[2], $m3);
if(!$m3[0])
$matches[2] = '<input type="hidden" name="error_return_url" value="<?php echo htmlspecialchars(getRequestUriByServerEnviroment(), ENT_COMPAT | ENT_HTML401, \'UTF-8\', false) ?>" />' . $matches[2];
$matches[2] = '<input type="hidden" name="error_return_url" value="<?php echo escape(getRequestUriByServerEnviroment(), false); ?>" />' . $matches[2];
}
else
{
@ -557,6 +557,14 @@ class TemplateHandler
{
$escape_option = 'noescape';
}
elseif(preg_match('/^\$(?:user_)?lang->[a-zA-Z0-9\_]+$/', $m[1]))
{
$escape_option = 'noescape';
}
elseif(preg_match('/^lang\(.+\)$/', $m[1]))
{
$escape_option = 'noescape';
}
else
{
$escape_option = $this->config->autoescape !== null ? 'auto' : 'noescape';
@ -603,6 +611,7 @@ class TemplateHandler
{
case 'auto':
case 'autoescape':
case 'autolang':
case 'escape':
case 'noescape':
$escape_option = $filter;
@ -656,6 +665,11 @@ class TemplateHandler
$var = $filter_option ? "number_format({$var}, {$filter_option})" : "number_format({$var})";
break;
case 'shorten':
case 'number_shorten':
$var = $filter_option ? "number_shorten({$var}, {$filter_option})" : "number_shorten({$var})";
break;
case 'link':
$var = $this->_applyEscapeOption($var, $escape_option);
if ($filter_option)
@ -894,14 +908,16 @@ class TemplateHandler
switch($escape_option)
{
case 'escape':
return "htmlspecialchars({$str}, ENT_COMPAT, 'UTF-8', true)";
return "htmlspecialchars({$str}, ENT_QUOTES, 'UTF-8', true)";
case 'noescape':
return "{$str}";
case 'autoescape':
return "htmlspecialchars({$str}, ENT_COMPAT, 'UTF-8', false)";
return "htmlspecialchars({$str}, ENT_QUOTES, 'UTF-8', false)";
case 'autolang':
return "(preg_match('/^\\$(?:user_)?lang->[a-zA-Z0-9\_]+$/', {$str}) ? ({$str}) : htmlspecialchars({$str}, ENT_QUOTES, 'UTF-8', false))";
case 'auto':
default:
return "(\$this->config->autoescape === 'on' ? htmlspecialchars({$str}, ENT_COMPAT, 'UTF-8', false) : {$str})";
return "(\$this->config->autoescape === 'on' ? htmlspecialchars({$str}, ENT_QUOTES, 'UTF-8', false) : ({$str}))";
}
}

View file

@ -264,7 +264,7 @@ class DBParser
}
if($brackets == $total_brackets)
{
if(!is_numeric($match) && !in_array(strtoupper($match), array('UNSIGNED', 'INTEGER', 'AS')))
if(!is_numeric($match) && !in_array(strtoupper($match), array('UNSIGNED', 'INTEGER', 'AS')) && !preg_match('/^[A-Z]+$/', $match))
{
$match = $this->escapeColumnExpression($match);
}

View file

@ -3,7 +3,7 @@
/**
* RX_VERSION is the version number of the Rhymix CMS.
*/
define('RX_VERSION', '1.9.8');
define('RX_VERSION', '1.9.9.2');
/**
* RX_MICROTIME is the startup time of the current script, in microseconds since the Unix epoch.
@ -129,8 +129,8 @@ define('__XE_VERSION_ALPHA__', false);
define('__XE_VERSION_BETA__', false);
define('__XE_VERSION_RC__', false);
define('__XE_VERSION_STABLE__', true);
define('__XE_MIN_PHP_VERSION__', '5.5.9');
define('__XE_RECOMMEND_PHP_VERSION__', '5.5.9');
define('__XE_MIN_PHP_VERSION__', '7.0.0');
define('__XE_RECOMMEND_PHP_VERSION__', '7.2.0');
define('__ZBXE__', true);
define('__ZBXE_VERSION__', RX_VERSION);
define('_XE_PATH_', RX_BASEDIR);
@ -165,6 +165,8 @@ define('LOWER', 'abcdefghijklmnopqrstuvwxyz');
define('CR', "\r");
define('CRLF', "\r\n");
define('LF', "\n");
define('Y', 'Y');
define('N', 'N');
define('FOLLOW_REQUEST_SSL', 0);
define('ENFORCE_SSL', 1);
define('RELEASE_SSL', 2);

View file

@ -18,4 +18,7 @@ return array(
'session_shield' => true,
'smartphone' => true,
'zipperupper' => true,
'elkha_www' => true,
'autowww' => true,
'fix_domain' => true,
);

View file

@ -63,12 +63,14 @@ return array(
'refresh' => 300,
),
'file' => array(
'folder_structure' => 2,
'umask' => '0022',
),
'mail' => array(
'type' => 'mailfunction',
),
'view' => array(
'manager_layout' => 'module',
'minify_scripts' => 'common',
'concat_scripts' => 'none',
'server_push' => false,
@ -91,7 +93,7 @@ return array(
'log_slow_widgets' => 0,
'log_slow_remote_requests' => 0,
'log_filename' => null,
'display_type' => 'comment',
'display_type' => array('comment'),
'display_content' => array(),
'display_to' => 'admin',
'write_error_log' => 'fatal',
@ -112,6 +114,10 @@ return array(
'object' => array(),
'classes' => array(),
),
'security' => array(
'check_csrf_token' => false,
'nofollow' => false,
),
'mobile' => array(
'enabled' => true,
'tablets' => false,

File diff suppressed because it is too large Load diff

View file

@ -2,7 +2,7 @@
/**
* Source: https://xn--3e0bx5euxnjje69i70af08bea817g.xn--3e0b707e/jsp/infoboard/stats/inProCurIpv6Add.jsp
* Last Updated: 2018-03-07
* Last Updated: 2019-05-04
*/
return array (
0 =>
@ -171,361 +171,366 @@ return array (
1 => '24021a00ffffffff',
),
33 =>
array (
0 => '2402bcc000000000',
1 => '2402bcc0ffffffff',
),
34 =>
array (
0 => '2402be0000000000',
1 => '2402be00ffffffff',
),
34 =>
35 =>
array (
0 => '2402de0000000000',
1 => '2402de00ffffffff',
),
35 =>
36 =>
array (
0 => '2402f40000000000',
1 => '2402f400ffffffff',
),
36 =>
37 =>
array (
0 => '24033e0000000000',
1 => '24033e00ffffffff',
),
37 =>
38 =>
array (
0 => '24053d0000000000',
1 => '24053d00ffffffff',
),
38 =>
39 =>
array (
0 => '24055f0000000000',
1 => '24055f00ffffffff',
),
39 =>
40 =>
array (
0 => '24057b0000000000',
1 => '24057b00ffffffff',
),
40 =>
41 =>
array (
0 => '2405c00000000000',
1 => '2405c000ffffffff',
),
41 =>
42 =>
array (
0 => '2405d88000000000',
1 => '2405d880ffffffff',
),
42 =>
43 =>
array (
0 => '24066a0000000000',
1 => '24066a00ffffffff',
),
43 =>
44 =>
array (
0 => '2406ad0000000000',
1 => '2406ad00ffffffff',
),
44 =>
45 =>
array (
0 => '2406b00000000000',
1 => '2406b000ffffffff',
),
45 =>
46 =>
array (
0 => '2406d00000000000',
1 => '2406d000ffffffff',
),
46 =>
47 =>
array (
0 => '2406d70000000000',
1 => '2406d700ffffffff',
),
47 =>
48 =>
array (
0 => '24070b0000000000',
1 => '24070b00ffffffff',
),
48 =>
49 =>
array (
0 => '24079b8000000000',
1 => '24079b80ffffffff',
),
49 =>
50 =>
array (
0 => '2407b20000000000',
1 => '2407b200ffffffff',
),
50 =>
51 =>
array (
0 => '2407b80000000000',
1 => '2407b800ffffffff',
),
51 =>
52 =>
array (
0 => '2407c00000000000',
1 => '2407c000ffffffff',
),
52 =>
53 =>
array (
0 => '2407c70000000000',
1 => '2407c700ffffffff',
),
53 =>
54 =>
array (
0 => '2001022000000000',
1 => '20010220ffffffff',
),
54 =>
55 =>
array (
0 => '2001023000000000',
1 => '20010230ffffffff',
),
55 =>
56 =>
array (
0 => '2001027000000000',
1 => '20010270ffffffff',
),
56 =>
57 =>
array (
0 => '2001028000000000',
1 => '20010280ffffffff',
),
57 =>
58 =>
array (
0 => '2001029000000000',
1 => '20010290ffffffff',
),
58 =>
59 =>
array (
0 => '2001032000000000',
1 => '20010320ffffffff',
),
59 =>
60 =>
array (
0 => '2001033000000000',
1 => '20010330ffffffff',
),
60 =>
61 =>
array (
0 => '2001037800000000',
1 => '20010378ffffffff',
),
61 =>
62 =>
array (
0 => '2001039000000000',
1 => '20010390ffffffff',
),
62 =>
63 =>
array (
0 => '2001443000000000',
1 => '20014430ffffffff',
),
63 =>
64 =>
array (
0 => '2400000000000000',
1 => '24000fffffffffff',
),
64 =>
65 =>
array (
0 => '2400180000000000',
1 => '24001800ffffffff',
),
65 =>
66 =>
array (
0 => '2400330000000000',
1 => '24003300ffffffff',
),
66 =>
67 =>
array (
0 => '2400478000000000',
1 => '24004780ffffffff',
),
67 =>
68 =>
array (
0 => '2400498000000000',
1 => '24004980ffffffff',
),
68 =>
69 =>
array (
0 => '2401270000000000',
1 => '24012700ffffffff',
),
69 =>
70 =>
array (
0 => '2401400000000000',
1 => '24014000ffffffff',
),
70 =>
71 =>
array (
0 => '2402000000000000',
1 => '240200ffffffffff',
),
71 =>
72 =>
array (
0 => '2402310000000000',
1 => '24023100ffffffff',
),
72 =>
73 =>
array (
0 => '2402580000000000',
1 => '24025800ffffffff',
),
73 =>
74 =>
array (
0 => '2402610000000000',
1 => '24026100ffffffff',
),
74 =>
75 =>
array (
0 => '2402700000000000',
1 => '24027000ffffffff',
),
75 =>
76 =>
array (
0 => '2403370000000000',
1 => '24033700ffffffff',
),
76 =>
77 =>
array (
0 => '2403630000000000',
1 => '24036300ffffffff',
),
77 =>
78 =>
array (
0 => '2403650000000000',
1 => '24036500ffffffff',
),
78 =>
79 =>
array (
0 => '2404018000000000',
1 => '2404018fffffffff',
),
79 =>
80 =>
array (
0 => '2404080000000000',
1 => '24040800ffffffff',
),
80 =>
81 =>
array (
0 => '2404230000000000',
1 => '24042300ffffffff',
),
81 =>
82 =>
array (
0 => '2404460000000000',
1 => '24044600ffffffff',
),
82 =>
83 =>
array (
0 => '2405350000000000',
1 => '24053500ffffffff',
),
83 =>
84 =>
array (
0 => '2405430000000000',
1 => '24054300ffffffff',
),
84 =>
85 =>
array (
0 => '2405580000000000',
1 => '24055800ffffffff',
),
85 =>
86 =>
array (
0 => '2405860000000000',
1 => '24058600ffffffff',
),
86 =>
87 =>
array (
0 => '2405950000000000',
1 => '24059500ffffffff',
),
87 =>
88 =>
array (
0 => '2406400000000000',
1 => '24064000ffffffff',
),
88 =>
89 =>
array (
0 => '2406590000000000',
1 => '24065900ffffffff',
),
89 =>
90 =>
array (
0 => '2406660000000000',
1 => '24066600ffffffff',
),
90 =>
91 =>
array (
0 => '2406680000000000',
1 => '24066800ffffffff',
),
91 =>
92 =>
array (
0 => '2407200000000000',
1 => '24072000ffffffff',
),
92 =>
93 =>
array (
0 => '2407350000000000',
1 => '24073500ffffffff',
),
93 =>
94 =>
array (
0 => '2407508000000000',
1 => '24075080ffffffff',
),
94 =>
95 =>
array (
0 => '2407518000000000',
1 => '24075180ffffffff',
),
95 =>
96 =>
array (
0 => '2407650000000000',
1 => '24076500ffffffff',
),
96 =>
97 =>
array (
0 => '2407670000000000',
1 => '24076700ffffffff',
),
97 =>
98 =>
array (
0 => '2407910000000000',
1 => '24079100ffffffff',
),
98 =>
99 =>
array (
0 => '20010e6000000000',
1 => '20010e60ffffffff',
),
99 =>
100 =>
array (
0 => '20010e7000000000',
1 => '20010e70ffffffff',
),
100 =>
101 =>
array (
0 => '20010e7800000000',
1 => '20010e78ffffffff',
),
101 =>
102 =>
array (
0 => '20010e9800000000',
1 => '20010e98ffffffff',
),
102 =>
103 =>
array (
0 => '24009e8000000000',
1 => '24009e80ffffffff',
),
103 =>
104 =>
array (
0 => '2400e18000000000',
1 => '2400e180ffffffff',
),
104 =>
105 =>
array (
0 => '2401e20000000000',
1 => '2401e200ffffffff',

View file

@ -650,7 +650,7 @@ class Debug
}
// Localize the error message.
$display_error_message = ini_get('display_errors') || Session::isAdmin();
$display_error_message = ini_get('display_errors') || !\Context::isInstalled() || Session::isAdmin();
$message = $display_error_message ? $message : lang('msg_server_error_see_log');
if ($message === 'msg_server_error_see_log')
{
@ -658,8 +658,36 @@ class Debug
}
// Display a generic error page.
try
{
\Context::displayErrorPage($title, $message, 500);
}
catch (\Error $e)
{
self::displayError($message);
}
}
/**
* Display a default error.
*
* @param string $message
* @return void
*/
public static function displayError($message)
{
header('HTTP/1.1 500 Internal Server Error');
if ($_SERVER['REQUEST_METHOD'] === 'GET' || !isset($_SERVER['HTTP_X_REQUESTED_WITH']))
{
header('Content-Type: text/html; charset=UTF-8');
echo sprintf('<html><head><meta charset="UTF-8" /><title>Server Error</title></head><body>%s</body></html>', escape($message, false));
}
else
{
header('Content-Type: application/json; charset=UTF-8');
echo json_encode(array('error' => -1, 'message' => escape($message, false)), \JSON_UNESCAPED_UNICODE);
}
}
/**
* Check if debugging is enabled for the current user.

View file

@ -49,7 +49,7 @@ class APC implements \Rhymix\Framework\Drivers\CacheInterface
*/
public static function isSupported()
{
return function_exists('apc_exists');
return function_exists('apcu_exists');
}
/**
@ -75,7 +75,7 @@ class APC implements \Rhymix\Framework\Drivers\CacheInterface
*/
public function get($key)
{
$value = apc_fetch($key);
$value = apcu_fetch($key);
return $value === false ? null : $value;
}
@ -93,7 +93,7 @@ class APC implements \Rhymix\Framework\Drivers\CacheInterface
*/
public function set($key, $value, $ttl = 0, $force = false)
{
return apc_store($key, $value, $ttl);
return apcu_store($key, $value, $ttl);
}
/**
@ -107,7 +107,7 @@ class APC implements \Rhymix\Framework\Drivers\CacheInterface
*/
public function delete($key)
{
return apc_delete($key);
return apcu_delete($key);
}
/**
@ -120,7 +120,7 @@ class APC implements \Rhymix\Framework\Drivers\CacheInterface
*/
public function exists($key)
{
return apc_exists($key);
return apcu_exists($key);
}
/**
@ -135,10 +135,10 @@ class APC implements \Rhymix\Framework\Drivers\CacheInterface
*/
public function incr($key, $amount)
{
$result = apc_inc($key, $amount);
$result = apcu_inc($key, $amount);
if ($result === false)
{
apc_store($key, $amount);
apcu_store($key, $amount);
$result = $amount;
}
return $result;
@ -156,10 +156,10 @@ class APC implements \Rhymix\Framework\Drivers\CacheInterface
*/
public function decr($key, $amount)
{
$result = apc_dec($key, $amount);
$result = apcu_dec($key, $amount);
if ($result === false)
{
apc_store($key, 0 - $amount);
apcu_store($key, 0 - $amount);
$result = 0 - $amount;
}
return $result;
@ -174,6 +174,6 @@ class APC implements \Rhymix\Framework\Drivers\CacheInterface
*/
public function clear()
{
return apc_clear_cache('user');
return apcu_clear_cache();
}
}

View file

@ -12,7 +12,7 @@ class MailFunction extends Base implements \Rhymix\Framework\Drivers\MailInterfa
*/
protected function __construct()
{
$this->mailer = \Swift_Mailer::newInstance(\Swift_MailTransport::newInstance());
$this->mailer = new \Swift_Mailer(new \Swift_MailTransport);
}
/**

View file

@ -17,10 +17,10 @@ class SES extends Base implements \Rhymix\Framework\Drivers\MailInterface
*/
protected function __construct(array $config)
{
$transport = \Swift_AWSTransport::newInstance($config['api_key'] ?: $config['api_user'], $config['api_secret'] ?: $config['api_pass']);
$transport = new \Swift_AWSTransport($config['api_key'] ?: $config['api_user'], $config['api_secret'] ?: $config['api_pass']);
$transport->setDebug(array($this, 'debugCallback'));
$transport->setEndpoint('https://email.' . strtolower($config['api_type']) . '.amazonaws.com/');
$this->mailer = \Swift_Mailer::newInstance($transport);
$this->mailer = new \Swift_Mailer($transport);
}
/**

View file

@ -12,7 +12,7 @@ class SMTP extends Base implements \Rhymix\Framework\Drivers\MailInterface
*/
protected function __construct(array $config)
{
$transport = \Swift_SmtpTransport::newInstance($config['smtp_host'], $config['smtp_port'], $config['smtp_security']);
$transport = new \Swift_SmtpTransport($config['smtp_host'], $config['smtp_port'], $config['smtp_security']);
$transport->setUsername($config['smtp_user']);
$transport->setPassword($config['smtp_pass']);
$local_domain = $transport->getLocalDomain();
@ -20,7 +20,7 @@ class SMTP extends Base implements \Rhymix\Framework\Drivers\MailInterface
{
$transport->setLocalDomain($matches[1]);
}
$this->mailer = \Swift_Mailer::newInstance($transport);
$this->mailer = new \Swift_Mailer($transport);
}
/**

View file

@ -0,0 +1,18 @@
<?php
namespace Rhymix\Framework\Exceptions;
/**
* The "feature disabled" exception class.
*/
class FeatureDisabled extends \Rhymix\Framework\Exception
{
public function __construct($message = '', $code = 0, $previous = null)
{
if ($message === '')
{
$message = lang('msg_feature_disabled');
}
parent::__construct($message, $code, $previous);
}
}

View file

@ -0,0 +1,18 @@
<?php
namespace Rhymix\Framework\Exceptions;
/**
* The "invalid request" exception class.
*/
class InvalidRequest extends \Rhymix\Framework\Exception
{
public function __construct($message = '', $code = 0, $previous = null)
{
if ($message === '')
{
$message = lang('msg_invalid_request');
}
parent::__construct($message, $code, $previous);
}
}

View file

@ -0,0 +1,18 @@
<?php
namespace Rhymix\Framework\Exceptions;
/**
* The "must login" exception class.
*/
class MustLogin extends \Rhymix\Framework\Exception
{
public function __construct($message = '', $code = 0, $previous = null)
{
if ($message === '')
{
$message = lang('msg_not_logged');
}
parent::__construct($message, $code, $previous);
}
}

View file

@ -0,0 +1,18 @@
<?php
namespace Rhymix\Framework\Exceptions;
/**
* The "not permitted" exception class.
*/
class NotPermitted extends \Rhymix\Framework\Exception
{
public function __construct($message = '', $code = 0, $previous = null)
{
if ($message === '')
{
$message = lang('msg_not_permitted');
}
parent::__construct($message, $code, $previous);
}
}

View file

@ -0,0 +1,18 @@
<?php
namespace Rhymix\Framework\Exceptions;
/**
* The "security violation" exception class.
*/
class SecurityViolation extends \Rhymix\Framework\Exception
{
public function __construct($message = '', $code = 0, $previous = null)
{
if ($message === '')
{
$message = lang('msg_security_violation');
}
parent::__construct($message, $code, $previous);
}
}

View file

@ -0,0 +1,18 @@
<?php
namespace Rhymix\Framework\Exceptions;
/**
* The "target not found" exception class.
*/
class TargetNotFound extends \Rhymix\Framework\Exception
{
public function __construct($message = '', $code = 0, $previous = null)
{
if ($message === '')
{
$message = lang('msg_not_founded');
}
parent::__construct($message, $code, $previous);
}
}

View file

@ -0,0 +1,197 @@
<?php
namespace Rhymix\Framework\Filters;
/**
* The file content filter class.
*/
class FileContentFilter
{
/**
* Fileinfo instance cache
*/
protected static $_finfo = null;
/**
* Generic checker
*
* @param string $file Actual path to the file to be checked
* @param string $filename Filename hint for type detection
* @return bool
*/
public static function check($file, $filename = null)
{
// Return error if the file does not exist.
if (!$file || !file_exists($file))
{
return false;
}
// Return error if the file size is zero.
if (($filesize = filesize($file)) == 0)
{
return false;
}
// Get the extension and MIME type.
$ext = $filename ? strtolower(substr(strrchr($filename, '.'), 1)) : '';
$mime_type = self::_getMimetype($file, true);
// Check the first 4KB of the file for possible XML content.
$fp = fopen($file, 'rb');
$first4kb = fread($fp, 4096);
$is_xml = preg_match('/<(?:\?xml|!DOCTYPE|html|head|body|meta|script|svg)\b/i', $first4kb);
// Check SVG files.
if (($ext === 'svg' || $is_xml) && !self::_checkSVG($fp, 0, $filesize))
{
fclose($fp);
return false;
}
// Check other image files.
if (in_array($ext, array('jpg', 'jpeg', 'png', 'gif')) && $mime_type !== false && $mime_type !== 'image')
{
fclose($fp);
return false;
}
// Check audio and video files.
if (preg_match('/(wm[va]|mpe?g|avi|flv|mp[1-4]|as[fx]|wav|midi?|moo?v|qt|r[am]{1,2}|m4v)$/', $file) && $mime_type !== false && $mime_type !== 'audio' && $mime_type !== 'video')
{
fclose($fp);
return false;
}
// Check XML files.
if (($ext === 'xml' || $is_xml) && !self::_checkXML($fp, 0, $filesize))
{
fclose($fp);
return false;
}
// Check HTML files.
if (($ext === 'html' || $ext === 'shtml' || $ext === 'xhtml' || $ext === 'phtml' || $is_xml) && !self::_checkHTML($fp, 0, $filesize))
{
fclose($fp);
return false;
}
// Return true if everything is OK.
fclose($fp);
return true;
}
/**
* Check SVG file for XSS or SSRF vulnerabilities (#1088, #1089)
*
* @param resource $fp
* @param int $from
* @param int $to
* @return bool
*/
protected static function _checkSVG($fp, $from, $to)
{
if (self::_matchStream('/<script|<handler\b|xlink:href\s*=\s*"(?!data:)/i', $fp, $from, $to))
{
return false;
}
if (self::_matchStream('/\b(?:ev:(?:event|listener|observer)|on[a-z]+)\s*=/i', $fp, $from, $to))
{
return false;
}
return true;
}
/**
* Check XML file for external entity inclusion.
*
* @param resource $fp
* @param int $from
* @param int $to
* @return bool
*/
protected static function _checkXML($fp, $from, $to)
{
if (self::_matchStream('/<!ENTITY/i', $fp, $from, $to))
{
return false;
}
return true;
}
/**
* Check HTML file for PHP code, server-side includes, and other nastiness.
*
* @param resource $fp
* @param int $from
* @param int $to
* @return bool
*/
protected static function _checkHTML($fp, $from, $to)
{
if (self::_matchStream('/<\?(?!xml\b)|<!--#(?:include|exec|echo|config|fsize|flastmod|printenv)\b/i', $fp, $from, $to))
{
return false;
}
return true;
}
/**
* Match a stream against a regular expression.
*
* This method is useful when dealing with large files,
* because we don't need to load the entire file into memory.
* We allow a generous overlap in case the matching string
* occurs across a block boundary.
*
* @param string $regexp
* @param resource $fp
* @param int $from
* @param int $to
* @param int $block_size (optional)
* @param int $overlap_size (optional)
* @return bool
*/
protected static function _matchStream($regexp, $fp, $from, $to, $block_size = 16384, $overlap_size = 1024)
{
fseek($fp, $position = $from);
while (strlen($content = fread($fp, $block_size + $overlap_size)) > 0)
{
if (preg_match($regexp, $content))
{
return true;
}
fseek($fp, min($to, $position += $block_size));
}
return false;
}
/**
* Attempt to detect the MIME type of a file.
*
* @param string $file Path of file to check
* @param bool $trim_subtype Whether to remove the subtype from the return value
* @return string|false
*/
protected static function _getMimetype($file, $trim_subtype = false)
{
if (!class_exists('finfo'))
{
return false;
}
if (!self::$_finfo)
{
self::$_finfo = new \finfo(FILEINFO_MIME_TYPE);
}
$mime_type = self::$_finfo->file($file);
if ($trim_subtype)
{
$mime_type = strstr($mime_type, '/', true);
}
return $mime_type;
}
}

View file

@ -149,6 +149,7 @@ class HTMLFilter
$config->set('Core.Encoding', 'UTF-8');
$config->set('HTML.Doctype', 'XHTML 1.0 Transitional');
$config->set('HTML.FlashAllowFullScreen', true);
$config->set('HTML.Nofollow', config('security.nofollow') ? true : false);
$config->set('HTML.MaxImgLength', null);
$config->set('CSS.MaxImgLength', null);
$config->set('CSS.Proprietary', true);

View file

@ -129,7 +129,6 @@ class Formatter
{
$converter = new \League\HTMLToMarkdown\HtmlConverter();
$converter->getConfig()->setOption('bold_style', '**');
$converter->getConfig()->setOption('italic_style', '_');
$converter->getConfig()->setOption('strip_tags', true);
return trim($converter->convert($html)) . "\n";
}

View file

@ -46,9 +46,16 @@ class Korea
}
default:
if (substr($num, 0, 4) === '0303' || substr($num, 0, 3) === '050')
{
if (strlen($num) === 12)
{
return substr($num, 0, 4) . '-' . substr($num, 4, 4) . '-' . substr($num, 8);
}
else
{
return substr($num, 0, 4) . '-' . substr($num, 4, 3) . '-' . substr($num, 7);
}
}
else
{
return substr($num, 0, 3) . '-' . substr($num, 3, 4) . '-' . substr($num, 7);
@ -77,6 +84,10 @@ class Korea
{
return true;
}
if (preg_match('/^0(?:303|505)[2-9][0-9]{6,7}$/', $num))
{
return true;
}
return false;
}

View file

@ -112,7 +112,7 @@ class Mail
*/
public function __construct()
{
$this->message = \Swift_Message::newInstance();
$this->message = new \Swift_Message;
$this->driver = self::getDefaultDriver();
}

View file

@ -247,6 +247,7 @@ class ConfigParser
}
// Convert miscellaneous configuration.
$config['file']['folder_structure'] = 1;
$config['file']['umask'] = Storage::recommendUmask();
$config['mobile']['enabled'] = $db_info->use_mobile_view === 'N' ? false : true;
$config['use_prepared_statements'] = $db_info->use_prepared_statements === 'Y' ? true : false;

View file

@ -64,8 +64,15 @@ class Security
}
// Otherwise, use the CryptoCompat class.
if (function_exists('mcrypt_encrypt'))
{
return base64_encode(\CryptoCompat::encrypt($plaintext, $key));
}
else
{
throw new Exception('msg_crypto_not_available');
}
}
/**
* Decrypt a string using AES.
@ -102,8 +109,15 @@ class Security
}
// Otherwise, use the CryptoCompat class.
if (function_exists('mcrypt_decrypt'))
{
return \CryptoCompat::decrypt($ciphertext, $key);
}
else
{
throw new Exception('msg_crypto_not_available');
}
}
/**
* Create a digital signature to verify the authenticity of a string.
@ -292,6 +306,11 @@ class Security
*/
public static function compareStrings($a, $b)
{
if(function_exists('hash_equals'))
{
return hash_equals($a, $b);
}
$diff = strlen($a) ^ strlen($b);
$maxlen = min(strlen($a), strlen($b));
for($i = 0; $i < $maxlen; $i++)
@ -326,13 +345,14 @@ class Security
}
else
{
if (Session::getMemberSrl())
$is_logged = Session::getMemberSrl();
if ($is_logged)
{
trigger_error('CSRF token missing in POST request: ' . (\Context::get('act') ?: '(no act)'), \E_USER_WARNING);
}
$referer = strval($referer ?: $_SERVER['HTTP_REFERER']);
if ($referer !== '')
if ($referer !== '' && (!config('security.check_csrf_token') || !$is_logged))
{
return URL::isInternalURL($referer);
}
@ -344,16 +364,17 @@ class Security
}
/**
* Check if the current request seems to be an XEE attack.
* Check if the current request seems to be an XXE (XML external entity) attack.
*
* This method returns true if the request seems to be innocent,
* and false if it seems to be an XEE attack.
* This is the opposite of XE's Security::detectXEE() method.
* and false if it seems to be an XXE attack.
* This is the opposite of XE's Security::detectingXEE() method.
* The name has also been changed to the more accurate acronym XXE.
*
* @param string $xml (optional)
* @return bool
*/
public static function checkXEE($xml = null)
public static function checkXXE($xml = null)
{
// Stop if there is no XML content.
if (!$xml)

View file

@ -381,6 +381,35 @@ function base64_decode_urlsafe($str)
return @base64_decode(str_pad(strtr($str, '-_', '+/'), ceil(strlen($str) / 4) * 4, '=', STR_PAD_RIGHT));
}
/**
* This function shortens a number using common suffixes.
*
* @param int $number The number to shorten
* @param int $significant_digits The number of significant digits to retain
* @return string
*/
function number_shorten($number, $significant_digits = 2)
{
$length = strlen(abs(intval($number)));
switch ($length)
{
case 0: case 1: case 2: case 3: return strval(intval($number));
case 4: return number_format($number / 1000, max(0, $significant_digits - 1)) . 'K';
case 5: return number_format($number / 1000, max(0, $significant_digits - 2)) . 'K';
case 6: return number_format($number / 1000, max(0, $significant_digits - 3)) . 'K';
case 7: return number_format($number / 1000000, max(0, $significant_digits - 1)) . 'M';
case 8: return number_format($number / 1000000, max(0, $significant_digits - 2)) . 'M';
case 9: return number_format($number / 1000000, max(0, $significant_digits - 3)) . 'M';
case 10: return number_format($number / 1000000000, max(0, $significant_digits - 1)) . 'G';
case 11: return number_format($number / 1000000000, max(0, $significant_digits - 2)) . 'G';
case 12: return number_format($number / 1000000000, max(0, $significant_digits - 3)) . 'G';
case 13: return number_format($number / 1000000000000, max(0, $significant_digits - 1)) . 'T';
case 14: return number_format($number / 1000000000000, max(0, $significant_digits - 2)) . 'T';
case 15: return number_format($number / 1000000000000, max(0, $significant_digits - 3)) . 'T';
default: return floor($number / 1000000000000) . 'T';
}
}
/**
* Convert a server-side path to a URL.
*

View file

@ -71,7 +71,7 @@
if (token) {
return $(this).each(function() {
if ($(this).data("csrf-token-checked") === "Y") return;
if (!isSameOrigin(location.href, $(this).attr("action"))) {
if ($(this).attr("action") && !isSameOrigin(location.href, $(this).attr("action"))) {
return $(this).data("csrf-token-checked", "Y");
}
$("<input />").attr({ type: "hidden", name: "_rx_csrf_token", value: token }).appendTo($(this));
@ -92,6 +92,7 @@
window.XE = {
loaded_popup_menus : [],
addedDocument : [],
cookie : window.Cookies,
URI : window.URI,
URITemplate : window.URITemplate,
SecondLevelDomains : window.SecondLevelDomains,
@ -224,6 +225,7 @@
window.XE.baseurl = window.XE.baseurl.hostname() + window.XE.baseurl.directory();
}
try {
var target_url = window.XE.URI(url).normalizePort().normalizeHostname().normalizePathname();
if (target_url.is("urn")) {
return false;
@ -232,9 +234,12 @@
target_url = target_url.absoluteTo(window.request_uri);
}
target_url = target_url.hostname() + target_url.directory();
return target_url.indexOf(window.XE.baseurl) === 0;
}
catch(err) {
return false;
}
}
};
})(jQuery);
@ -280,6 +285,10 @@ jQuery(function($) {
if (!rel.match(/\bnoopener\b/)) {
$this.attr('rel', $.trim(rel + ' noopener'));
}
var isChrome = navigator.userAgent.match(/Chrome\/([0-9]+)/);
if (isChrome && parseInt(isChrome[1], 10) >= 72) {
return;
}
event.preventDefault();
blankshield.open(href);
}
@ -621,22 +630,21 @@ function setFixedPopupSize() {
offset = $pc.css({overflow:'scroll'}).offset();
w = $pc.width(10).height(10000).get(0).scrollWidth + offset.left*2;
h = $pc.height(10).width(10000).get(0).scrollHeight + offset.top*2;
if(w < 800) w = 800 + offset.left*2;
// Window 의 너비나 높이는 스크린의 너비나 높이보다 클 수 없다. 스크린의 너비나 높이와 내용의 너비나 높이를 비교해서 최소값을 이용한다.
w = Math.min(w, window.screen.availWidth);
h = $pc.width(w - offset.left*2).height(10).get(0).scrollHeight + offset.top*2;
dw = $win.width();
dh = $win.height();
// Window 의 너비나 높이는 스크린의 너비나 높이보다 클 수 없다. 스크린의 너비나 높이와 내용의 너비나 높이를 비교해서 최소값을 이용한다.
w = Math.min(w, window.screen.availWidth);
h = Math.min(h, window.screen.availHeight - 100);
window.resizeBy(w - dw, h - dh);
$pc.width(w - offset.left*2).css({overflow:'',height:''});
if(h === window.screen.availHeight - 100) {
$pc.width(w - offset.left*2-scbw).css({overflow:'',height:''});
}
$pc.width('100%').css({overflow:'',height:'','box-sizing':'border-box'});
}
/**
@ -674,9 +682,7 @@ function doChangeLangType(obj) {
location.href = location.href.setQuery('l', '');
}
function setLangType(lang_type) {
var expire = new Date();
expire.setTime(expire.getTime()+ (7000 * 24 * 3600000));
setCookie('lang_type', lang_type, expire, '/');
XE.cookie.set("lang_type", lang_type, { path: "/", expires: 3650 });
}
/* 미리보기 */
@ -1052,18 +1058,16 @@ function getOuterHTML(obj) {
return jQuery(obj).html().trim();
}
function setCookie(name, value, expire, path) {
var s_cookie = name + "=" + escape(value) +
((!expire) ? "" : ("; expires=" + expire.toGMTString())) +
"; path=" + ((!path) ? "/" : path) +
((cookies_ssl) ? ";secure" : "");
document.cookie = s_cookie;
function setCookie(name, value, expires, path) {
XE.cookie.set(name, value, {
expires: expires ? expires : 0,
path: path ? path : "/",
secure: cookies_ssl ? true : false
});
}
function getCookie(name) {
var match = document.cookie.match(new RegExp(name+'=(.*?)(?:;|$)'));
if(match) return unescape(match[1]);
return XE.cookie.get(name);
}
function is_def(v) {

View file

@ -0,0 +1,165 @@
/*!
* JavaScript Cookie v2.2.0
* https://github.com/js-cookie/js-cookie
*
* Copyright 2006, 2015 Klaus Hartl & Fagner Brack
* Released under the MIT license
*/
;(function (factory) {
var registeredInModuleLoader = false;
if (typeof define === 'function' && define.amd) {
define(factory);
registeredInModuleLoader = true;
}
if (typeof exports === 'object') {
module.exports = factory();
registeredInModuleLoader = true;
}
if (!registeredInModuleLoader) {
var OldCookies = window.Cookies;
var api = window.Cookies = factory();
api.noConflict = function () {
window.Cookies = OldCookies;
return api;
};
}
}(function () {
function extend () {
var i = 0;
var result = {};
for (; i < arguments.length; i++) {
var attributes = arguments[ i ];
for (var key in attributes) {
result[key] = attributes[key];
}
}
return result;
}
function init (converter) {
function api (key, value, attributes) {
var result;
if (typeof document === 'undefined') {
return;
}
// Write
if (arguments.length > 1) {
attributes = extend({
path: '/'
}, api.defaults, attributes);
if (typeof attributes.expires === 'number') {
var expires = new Date();
expires.setMilliseconds(expires.getMilliseconds() + attributes.expires * 864e+5);
attributes.expires = expires;
}
// We're using "expires" because "max-age" is not supported by IE
attributes.expires = attributes.expires ? attributes.expires.toUTCString() : '';
try {
result = JSON.stringify(value);
if (/^[\{\[]/.test(result)) {
value = result;
}
} catch (e) {}
if (!converter.write) {
value = encodeURIComponent(String(value))
.replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent);
} else {
value = converter.write(value, key);
}
key = encodeURIComponent(String(key));
key = key.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent);
key = key.replace(/[\(\)]/g, escape);
var stringifiedAttributes = '';
for (var attributeName in attributes) {
if (!attributes[attributeName]) {
continue;
}
stringifiedAttributes += '; ' + attributeName;
if (attributes[attributeName] === true) {
continue;
}
stringifiedAttributes += '=' + attributes[attributeName];
}
return (document.cookie = key + '=' + value + stringifiedAttributes);
}
// Read
if (!key) {
result = {};
}
// To prevent the for loop in the first place assign an empty array
// in case there are no cookies at all. Also prevents odd result when
// calling "get()"
var cookies = document.cookie ? document.cookie.split('; ') : [];
var rdecode = /(%[0-9A-Z]{2})+/g;
var i = 0;
for (; i < cookies.length; i++) {
var parts = cookies[i].split('=');
var cookie = parts.slice(1).join('=');
if (!this.json && cookie.charAt(0) === '"') {
cookie = cookie.slice(1, -1);
}
try {
var name = parts[0].replace(rdecode, decodeURIComponent);
cookie = converter.read ?
converter.read(cookie, name) : converter(cookie, name) ||
cookie.replace(rdecode, decodeURIComponent);
if (this.json) {
try {
cookie = JSON.parse(cookie);
} catch (e) {}
}
if (key === name) {
result = cookie;
break;
}
if (!key) {
result[name] = cookie;
}
} catch (e) {}
}
return result;
}
api.set = api;
api.get = function (key) {
return api.call(api, key);
};
api.getJSON = function () {
return api.apply({
json: true
}, [].slice.call(arguments));
};
api.defaults = {};
api.remove = function (key, attributes) {
api(key, '', extend(attributes, {
expires: -1
}));
};
api.withConverter = init;
return api;
}
return init(function () {});
}));

View file

@ -0,0 +1 @@
!function(e){var n=!1;if("function"==typeof define&&define.amd&&(define(e),n=!0),"object"==typeof exports&&(module.exports=e(),n=!0),!n){var o=window.Cookies,t=window.Cookies=e();t.noConflict=function(){return window.Cookies=o,t}}}(function(){function e(){for(var e=0,n={};e<arguments.length;e++){var o=arguments[e];for(var t in o)n[t]=o[t]}return n}function n(o){function t(n,r,i){var c;if("undefined"!=typeof document){if(arguments.length>1){if("number"==typeof(i=e({path:"/"},t.defaults,i)).expires){var a=new Date;a.setMilliseconds(a.getMilliseconds()+864e5*i.expires),i.expires=a}i.expires=i.expires?i.expires.toUTCString():"";try{/^[\{\[]/.test(c=JSON.stringify(r))&&(r=c)}catch(e){}r=o.write?o.write(r,n):encodeURIComponent(String(r)).replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g,decodeURIComponent),n=(n=(n=encodeURIComponent(String(n))).replace(/%(23|24|26|2B|5E|60|7C)/g,decodeURIComponent)).replace(/[\(\)]/g,escape);var s="";for(var f in i)i[f]&&(s+="; "+f,!0!==i[f]&&(s+="="+i[f]));return document.cookie=n+"="+r+s}n||(c={});for(var p=document.cookie?document.cookie.split("; "):[],d=/(%[0-9A-Z]{2})+/g,u=0;u<p.length;u++){var l=p[u].split("="),C=l.slice(1).join("=");this.json||'"'!==C.charAt(0)||(C=C.slice(1,-1));try{var g=l[0].replace(d,decodeURIComponent);if(C=o.read?o.read(C,g):o(C,g)||C.replace(d,decodeURIComponent),this.json)try{C=JSON.parse(C)}catch(e){}if(n===g){c=C;break}n||(c[g]=C)}catch(e){}}return c}}return t.set=t,t.get=function(e){return t.call(t,e)},t.getJSON=function(){return t.apply({json:!0},[].slice.call(arguments))},t.defaults={},t.remove=function(n,o){t(n,"",e(o,{expires:-1}))},t.withConverter=n,t}return n(function(){})});

View file

@ -0,0 +1 @@
{"version":3,"sources":["js.cookie.js"],"names":["factory","registeredInModuleLoader","define","amd","exports","module","OldCookies","window","Cookies","api","noConflict","extend","i","result","arguments","length","attributes","key","init","converter","value","document","path","defaults","expires","Date","setMilliseconds","getMilliseconds","toUTCString","test","JSON","stringify","e","write","encodeURIComponent","String","replace","decodeURIComponent","escape","stringifiedAttributes","attributeName","cookie","cookies","split","rdecode","parts","slice","join","this","json","charAt","name","read","parse","set","get","call","getJSON","apply","remove","withConverter"],"mappings":"CAOE,SAAUA,GACX,IAAIC,GAA2B,EAS/B,GARsB,mBAAXC,QAAyBA,OAAOC,MAC1CD,OAAOF,GACPC,GAA2B,GAEL,iBAAZG,UACVC,OAAOD,QAAUJ,IACjBC,GAA2B,IAEvBA,EAA0B,CAC9B,IAAIK,EAAaC,OAAOC,QACpBC,EAAMF,OAAOC,QAAUR,IAC3BS,EAAIC,WAAa,WAEhB,OADAH,OAAOC,QAAUF,EACVG,IAfT,CAkBC,WACD,SAASE,IAGR,IAFA,IAAIC,EAAI,EACJC,KACGD,EAAIE,UAAUC,OAAQH,IAAK,CACjC,IAAII,EAAaF,UAAWF,GAC5B,IAAK,IAAIK,KAAOD,EACfH,EAAOI,GAAOD,EAAWC,GAG3B,OAAOJ,EAGR,SAASK,EAAMC,GACd,SAASV,EAAKQ,EAAKG,EAAOJ,GACzB,IAAIH,EACJ,GAAwB,oBAAbQ,SAAX,CAMA,GAAIP,UAAUC,OAAS,EAAG,CAKzB,GAAkC,iBAJlCC,EAAaL,GACZW,KAAM,KACJb,EAAIc,SAAUP,IAEKQ,QAAsB,CAC3C,IAAIA,EAAU,IAAIC,KAClBD,EAAQE,gBAAgBF,EAAQG,kBAAyC,MAArBX,EAAWQ,SAC/DR,EAAWQ,QAAUA,EAItBR,EAAWQ,QAAUR,EAAWQ,QAAUR,EAAWQ,QAAQI,cAAgB,GAE7E,IAEK,UAAUC,KADdhB,EAASiB,KAAKC,UAAUX,MAEvBA,EAAQP,GAER,MAAOmB,IAMRZ,EAJID,EAAUc,MAINd,EAAUc,MAAMb,EAAOH,GAHvBiB,mBAAmBC,OAAOf,IAChCgB,QAAQ,4DAA6DC,oBAOxEpB,GADAA,GADAA,EAAMiB,mBAAmBC,OAAOlB,KACtBmB,QAAQ,2BAA4BC,qBACpCD,QAAQ,UAAWE,QAE7B,IAAIC,EAAwB,GAE5B,IAAK,IAAIC,KAAiBxB,EACpBA,EAAWwB,KAGhBD,GAAyB,KAAOC,GACE,IAA9BxB,EAAWwB,KAGfD,GAAyB,IAAMvB,EAAWwB,KAE3C,OAAQnB,SAASoB,OAASxB,EAAM,IAAMG,EAAQmB,EAK1CtB,IACJJ,MAUD,IAJA,IAAI6B,EAAUrB,SAASoB,OAASpB,SAASoB,OAAOE,MAAM,SAClDC,EAAU,mBACVhC,EAAI,EAEDA,EAAI8B,EAAQ3B,OAAQH,IAAK,CAC/B,IAAIiC,EAAQH,EAAQ9B,GAAG+B,MAAM,KACzBF,EAASI,EAAMC,MAAM,GAAGC,KAAK,KAE5BC,KAAKC,MAA6B,MAArBR,EAAOS,OAAO,KAC/BT,EAASA,EAAOK,MAAM,GAAI,IAG3B,IACC,IAAIK,EAAON,EAAM,GAAGT,QAAQQ,EAASP,oBAKrC,GAJAI,EAAStB,EAAUiC,KAClBjC,EAAUiC,KAAKX,EAAQU,GAAQhC,EAAUsB,EAAQU,IACjDV,EAAOL,QAAQQ,EAASP,oBAErBW,KAAKC,KACR,IACCR,EAASX,KAAKuB,MAAMZ,GACnB,MAAOT,IAGV,GAAIf,IAAQkC,EAAM,CACjBtC,EAAS4B,EACT,MAGIxB,IACJJ,EAAOsC,GAAQV,GAEf,MAAOT,KAGV,OAAOnB,GAsBR,OAnBAJ,EAAI6C,IAAM7C,EACVA,EAAI8C,IAAM,SAAUtC,GACnB,OAAOR,EAAI+C,KAAK/C,EAAKQ,IAEtBR,EAAIgD,QAAU,WACb,OAAOhD,EAAIiD,OACVT,MAAM,MACDH,MAAMU,KAAK1C,aAElBL,EAAIc,YAEJd,EAAIkD,OAAS,SAAU1C,EAAKD,GAC3BP,EAAIQ,EAAK,GAAIN,EAAOK,GACnBQ,SAAU,MAIZf,EAAImD,cAAgB1C,EAEbT,EAGR,OAAOS,EAAK"}

View file

@ -0,0 +1 @@
js.cookie.min.js

View file

@ -0,0 +1,21 @@
MIT License
Copyright © 2010 Sebastian Tschan, https://blueimp.net
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -1,20 +1,20 @@
@charset "UTF-8";
/*
* jQuery File Upload Plugin NoScript CSS 1.2.0
* jQuery File Upload Plugin NoScript CSS
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT
* https://opensource.org/licenses/MIT
*/
.fileinput-button input {
position: static;
opacity: 1;
filter: none;
font-size: inherit;
font-size: inherit !important;
direction: inherit;
}
.fileinput-button span {

View file

@ -1,13 +1,13 @@
@charset "UTF-8";
/*
* jQuery File Upload UI Plugin NoScript CSS 8.8.5
* jQuery File Upload UI Plugin NoScript CSS
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2012, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT
* https://opensource.org/licenses/MIT
*/
.fileinput-button i,

View file

@ -1,13 +1,13 @@
@charset "UTF-8";
/*
* jQuery File Upload UI Plugin CSS 9.0.0
* jQuery File Upload UI Plugin CSS
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2010, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT
* https://opensource.org/licenses/MIT
*/
.fileupload-buttonbar .btn,

View file

@ -1,18 +1,19 @@
@charset "UTF-8";
/*
* jQuery File Upload Plugin CSS 1.3.0
* jQuery File Upload Plugin CSS
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT
* https://opensource.org/licenses/MIT
*/
.fileinput-button {
position: relative;
overflow: hidden;
display: inline-block;
}
.fileinput-button input {
position: absolute;
@ -21,7 +22,7 @@
margin: 0;
opacity: 0;
-ms-filter: 'alpha(opacity=0)';
font-size: 200px;
font-size: 200px !important;
direction: ltr;
cursor: pointer;
}

View file

@ -1,18 +1,18 @@
/*
* jQuery File Upload Plugin Angular JS Example 1.2.1
* jQuery File Upload Plugin Angular JS Example
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT
* https://opensource.org/licenses/MIT
*/
/* jshint nomen:false */
/* global window, angular */
(function () {
;(function () {
'use strict';
var isOnGitHub = window.location.hostname === 'blueimp.github.io',

View file

@ -1,17 +1,17 @@
/*
* jQuery postMessage Transport Plugin 1.1.2
* jQuery postMessage Transport Plugin
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2011, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT
* https://opensource.org/licenses/MIT
*/
/* global define, require, window, document */
(function (factory) {
;(function (factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
@ -64,6 +64,12 @@
loc = $('<a>').prop('href', options.postMessage)[0],
target = loc.protocol + '//' + loc.host,
xhrUpload = options.xhr().upload;
// IE always includes the port for the host property of a link
// element, but not in the location.host or origin property for the
// default http port 80 and https port 443, so we strip it:
if (/^(http:\/\/.+:80)|(https:\/\/.+:443)$/.test(target)) {
target = target.replace(/:(80|443)$/, '');
}
return {
send: function (_, completeCallback) {
counter += 1;

View file

@ -1,12 +1,12 @@
/*
* jQuery XDomainRequest Transport Plugin 1.1.4
* jQuery XDomainRequest Transport Plugin
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2011, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT
* https://opensource.org/licenses/MIT
*
* Based on Julian Aubourg's ajaxHooks xdr.js:
* https://github.com/jaubourg/ajaxHooks/
@ -14,7 +14,7 @@
/* global define, require, window, XDomainRequest */
(function (factory) {
;(function (factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:

View file

@ -1,18 +1,18 @@
/*
* jQuery File Upload AngularJS Plugin 2.2.0
* jQuery File Upload AngularJS Plugin
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT
* https://opensource.org/licenses/MIT
*/
/* jshint nomen:false */
/* global define, angular */
/* global define, angular, require */
(function (factory) {
;(function (factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
@ -24,6 +24,16 @@
'./jquery.fileupload-video',
'./jquery.fileupload-validate'
], factory);
} else if (typeof exports === 'object') {
// Node/CommonJS:
factory(
require('jquery'),
require('angular'),
require('./jquery.fileupload-image'),
require('./jquery.fileupload-audio'),
require('./jquery.fileupload-video'),
require('./jquery.fileupload-validate')
);
} else {
factory();
}
@ -91,7 +101,7 @@
angular.forEach(data.files, function (file) {
filesCopy.push(file);
});
scope.$apply(function () {
scope.$parent.$applyAsync(function () {
addFileMethods(scope, data);
var method = scope.option('prependFiles') ?
'unshift' : 'push';
@ -100,7 +110,7 @@
data.process(function () {
return scope.process(data);
}).always(function () {
scope.$apply(function () {
scope.$parent.$applyAsync(function () {
addFileMethods(scope, data);
scope.replace(filesCopy, data.files);
});
@ -112,12 +122,6 @@
}
});
},
progress: function (e, data) {
if (e.isDefaultPrevented()) {
return false;
}
data.scope.$apply();
},
done: function (e, data) {
if (e.isDefaultPrevented()) {
return false;
@ -197,8 +201,8 @@
// The FileUploadController initializes the fileupload widget and
// provides scope methods to control the File Upload functionality:
.controller('FileUploadController', [
'$scope', '$element', '$attrs', '$window', 'fileUpload',
function ($scope, $element, $attrs, $window, fileUpload) {
'$scope', '$element', '$attrs', '$window', 'fileUpload','$q',
function ($scope, $element, $attrs, $window, fileUpload, $q) {
var uploadMethods = {
progress: function () {
return $element.fileupload('progress');
@ -260,19 +264,21 @@
$scope.applyOnQueue = function (method) {
var list = this.queue.slice(0),
i,
file;
file,
promises = [];
for (i = 0; i < list.length; i += 1) {
file = list[i];
if (file[method]) {
file[method]();
promises.push(file[method]());
}
}
return $q.all(promises);
};
$scope.submit = function () {
this.applyOnQueue('$submit');
return this.applyOnQueue('$submit');
};
$scope.cancel = function () {
this.applyOnQueue('$cancel');
return this.applyOnQueue('$cancel');
};
// Add upload methods to the scope:
angular.extend($scope, uploadMethods);
@ -320,9 +326,11 @@
'fileuploadprocessalways',
'fileuploadprocessstop'
].join(' '), function (e, data) {
$scope.$parent.$applyAsync(function () {
if ($scope.$emit(e.type, data).defaultPrevented) {
e.preventDefault();
}
});
}).on('remove', function () {
// Remove upload methods from the scope,
// when the widget is removed:

View file

@ -1,18 +1,18 @@
/*
* jQuery File Upload Audio Preview Plugin 1.0.4
* jQuery File Upload Audio Preview Plugin
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT
* https://opensource.org/licenses/MIT
*/
/* jshint nomen:false */
/* global define, require, window, document */
(function (factory) {
;(function (factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
@ -25,7 +25,8 @@
// Node/CommonJS:
factory(
require('jquery'),
require('load-image')
require('blueimp-load-image/js/load-image'),
require('./jquery.fileupload-process')
);
} else {
// Browser globals:

View file

@ -1,18 +1,18 @@
/*
* jQuery File Upload Image Preview & Resize Plugin 1.7.3
* jQuery File Upload Image Preview & Resize Plugin
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT
* https://opensource.org/licenses/MIT
*/
/* jshint nomen:false */
/* global define, require, window, Blob */
(function (factory) {
;(function (factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
@ -20,8 +20,8 @@
'jquery',
'load-image',
'load-image-meta',
'load-image-scale',
'load-image-exif',
'load-image-ios',
'canvas-to-blob',
'./jquery.fileupload-process'
], factory);
@ -29,7 +29,12 @@
// Node/CommonJS:
factory(
require('jquery'),
require('load-image')
require('blueimp-load-image/js/load-image'),
require('blueimp-load-image/js/load-image-meta'),
require('blueimp-load-image/js/load-image-scale'),
require('blueimp-load-image/js/load-image-exif'),
require('blueimp-canvas-to-blob'),
require('./jquery.fileupload-process')
);
} else {
// Browser globals:

View file

@ -1,25 +1,31 @@
/*
* jQuery File Upload jQuery UI Plugin 8.7.2
* jQuery File Upload jQuery UI Plugin
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT
* https://opensource.org/licenses/MIT
*/
/* jshint nomen:false */
/* global define, require, window */
(function (factory) {
;(function (factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
define(['jquery', './jquery.fileupload-ui'], factory);
define([
'jquery',
'./jquery.fileupload-ui'
], factory);
} else if (typeof exports === 'object') {
// Node/CommonJS:
factory(require('jquery'));
factory(
require('jquery'),
require('./jquery.fileupload-ui')
);
} else {
// Browser globals:
factory(window.jQuery);

View file

@ -1,18 +1,18 @@
/*
* jQuery File Upload Processing Plugin 1.3.1
* jQuery File Upload Processing Plugin
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2012, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT
* https://opensource.org/licenses/MIT
*/
/* jshint nomen:false */
/* global define, require, window */
(function (factory) {
;(function (factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
@ -22,7 +22,10 @@
], factory);
} else if (typeof exports === 'object') {
// Node/CommonJS:
factory(require('jquery'));
factory(
require('jquery'),
require('./jquery.fileupload')
);
} else {
// Browser globals:
factory(
@ -84,7 +87,7 @@
settings
);
};
chain = chain.pipe(func, settings.always && func);
chain = chain.then(func, settings.always && func);
});
chain
.done(function () {
@ -151,7 +154,7 @@
};
opts.index = index;
that._processing += 1;
that._processingQueue = that._processingQueue.pipe(func, func)
that._processingQueue = that._processingQueue.then(func, func)
.always(function () {
that._processing -= 1;
if (that._processing === 0) {

View file

@ -1,24 +1,24 @@
/*
* jQuery File Upload User Interface Plugin 9.6.1
* jQuery File Upload User Interface Plugin
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2010, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT
* https://opensource.org/licenses/MIT
*/
/* jshint nomen:false */
/* global define, require, window */
(function (factory) {
;(function (factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
define([
'jquery',
'tmpl',
'blueimp-tmpl',
'./jquery.fileupload-image',
'./jquery.fileupload-audio',
'./jquery.fileupload-video',
@ -28,7 +28,11 @@
// Node/CommonJS:
factory(
require('jquery'),
require('tmpl')
require('blueimp-tmpl'),
require('./jquery.fileupload-image'),
require('./jquery.fileupload-audio'),
require('./jquery.fileupload-video'),
require('./jquery.fileupload-validate')
);
} else {
// Browser globals:

View file

@ -1,17 +1,17 @@
/*
* jQuery File Upload Validation Plugin 1.1.3
* jQuery File Upload Validation Plugin
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT
* https://opensource.org/licenses/MIT
*/
/* global define, require, window */
(function (factory) {
;(function (factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
@ -21,7 +21,10 @@
], factory);
} else if (typeof exports === 'object') {
// Node/CommonJS:
factory(require('jquery'));
factory(
require('jquery'),
require('./jquery.fileupload-process')
);
} else {
// Browser globals:
factory(

View file

@ -1,18 +1,18 @@
/*
* jQuery File Upload Video Preview Plugin 1.0.4
* jQuery File Upload Video Preview Plugin
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT
* https://opensource.org/licenses/MIT
*/
/* jshint nomen:false */
/* global define, require, window, document */
(function (factory) {
;(function (factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
@ -25,7 +25,8 @@
// Node/CommonJS:
factory(
require('jquery'),
require('load-image')
require('blueimp-load-image/js/load-image'),
require('./jquery.fileupload-process')
);
} else {
// Browser globals:

View file

@ -1,24 +1,24 @@
/*
* jQuery File Upload Plugin 5.42.3
* jQuery File Upload Plugin
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2010, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT
* https://opensource.org/licenses/MIT
*/
/* jshint nomen:false */
/* global define, require, window, document, location, Blob, FormData */
(function (factory) {
;(function (factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
define([
'jquery',
'jquery.ui.widget'
'jquery-ui/ui/widget'
], factory);
} else if (typeof exports === 'object') {
// Node/CommonJS:
@ -43,7 +43,7 @@
'|(Kindle/(1\\.0|2\\.[05]|3\\.0))'
).test(window.navigator.userAgent) ||
// Feature detection for all other devices:
$('<input type="file">').prop('disabled'));
$('<input type="file"/>').prop('disabled'));
// The FileReader API is not actually used, but works as feature detection,
// as some Safari versions (5?) support XHR file uploads via the FormData API,
@ -453,7 +453,7 @@
}
if (!multipart || options.blob || !this._isInstanceOf('File', file)) {
options.headers['Content-Disposition'] = 'attachment; filename="' +
encodeURI(file.name) + '"';
encodeURI(file.uploadName || file.name) + '"';
}
if (!multipart) {
options.contentType = file.type || 'application/octet-stream';
@ -489,7 +489,11 @@
});
}
if (options.blob) {
formData.append(paramName, options.blob, file.name);
formData.append(
paramName,
options.blob,
file.uploadName || file.name
);
} else {
$.each(options.files, function (index, file) {
// This check allows the tests to run with
@ -652,7 +656,7 @@
data.process = function (resolveFunc, rejectFunc) {
if (resolveFunc || rejectFunc) {
data._processQueue = this._processQueue =
(this._processQueue || getPromise([this])).pipe(
(this._processQueue || getPromise([this])).then(
function () {
if (data.errorThrown) {
return $.Deferred()
@ -660,7 +664,7 @@
}
return getPromise(arguments);
}
).pipe(resolveFunc, rejectFunc);
).then(resolveFunc, rejectFunc);
}
return this._processQueue || getPromise([this]);
};
@ -730,7 +734,7 @@
promise = dfd.promise(),
jqXHR,
upload;
if (!(this._isXHRUpload(options) && slice && (ub || mcs < fs)) ||
if (!(this._isXHRUpload(options) && slice && (ub || ($.type(mcs) === 'function' ? mcs(options) : mcs) < fs)) ||
options.data) {
return false;
}
@ -753,7 +757,7 @@
o.blob = slice.call(
file,
ub,
ub + mcs,
ub + ($.type(mcs) === 'function' ? mcs(o) : mcs),
file.type
);
// Store the current chunk size, as the blob itself
@ -945,9 +949,9 @@
if (this.options.limitConcurrentUploads > 1) {
slot = $.Deferred();
this._slots.push(slot);
pipe = slot.pipe(send);
pipe = slot.then(send);
} else {
this._sequence = this._sequence.pipe(send, send);
this._sequence = this._sequence.then(send, send);
pipe = this._sequence;
}
// Return the piped Promise object, enhanced with an abort method,
@ -1046,13 +1050,19 @@
_replaceFileInput: function (data) {
var input = data.fileInput,
inputClone = input.clone(true);
inputClone = input.clone(true),
restoreFocus = input.is(document.activeElement);
// Add a reference for the new cloned file input to the data argument:
data.fileInputClone = inputClone;
$('<form></form>').append(inputClone)[0].reset();
// Detaching allows to insert the fileInput on another form
// without loosing the file input value:
input.after(inputClone).detach();
// If the fileInput had focus before it was detached,
// restore focus to the inputClone.
if (restoreFocus) {
inputClone.focus();
}
// Avoid memory leaks with the detached file input:
$.cleanData(input.unbind('remove'));
// Replace the original file input element in the fileInput
@ -1074,6 +1084,8 @@
_handleFileTreeEntry: function (entry, path) {
var that = this,
dfd = $.Deferred(),
entries = [],
dirReader,
errorHandler = function (e) {
if (e && !e.entry) {
e.entry = entry;
@ -1101,8 +1113,7 @@
readEntries();
}
}, errorHandler);
},
dirReader, entries = [];
};
path = path || '';
if (entry.isFile) {
if (entry._file) {
@ -1119,7 +1130,7 @@
dirReader = entry.createReader();
readEntries();
} else {
// Return an empy list for file system items
// Return an empty list for file system items
// other than files or directories:
dfd.resolve([]);
}
@ -1133,7 +1144,7 @@
$.map(entries, function (entry) {
return that._handleFileTreeEntry(entry, path);
})
).pipe(function () {
).then(function () {
return Array.prototype.concat.apply(
[],
arguments
@ -1168,16 +1179,9 @@
_getSingleFileInputFiles: function (fileInput) {
fileInput = $(fileInput);
var entries = fileInput.prop('webkitEntries') ||
fileInput.prop('entries'),
files,
value;
if (entries && entries.length) {
return this._handleFileTreeEntries(entries);
}
files = $.makeArray(fileInput.prop('files'));
var files = $.makeArray(fileInput.prop('files'));
if (!files.length) {
value = fileInput.prop('value');
var value = fileInput.prop('value');
if (!value) {
return $.Deferred().resolve([]).promise();
}
@ -1202,10 +1206,10 @@
return $.when.apply(
$,
$.map(fileInput, this._getSingleFileInputFiles)
).pipe(function () {
).then(function (files) {
return Array.prototype.concat.apply(
[],
arguments
files
);
});
},
@ -1217,7 +1221,7 @@
form: $(e.target.form)
};
this._getFileInputFiles(data.fileInput).always(function (files) {
data.files = files;
data.files = $.makeArray(files);
if (that.options.replaceFileInput) {
that._replaceFileInput(data);
}
@ -1305,6 +1309,10 @@
this._off(this.options.fileInput, 'change');
},
_destroy: function () {
this._destroyEventHandlers();
},
_setOption: function (key, value) {
var reinit = $.inArray(key, this._specialOptions) !== -1;
if (reinit) {

View file

@ -1,17 +1,17 @@
/*
* jQuery Iframe Transport Plugin 1.8.3
* jQuery Iframe Transport Plugin
* https://github.com/blueimp/jQuery-File-Upload
*
* Copyright 2011, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT
* https://opensource.org/licenses/MIT
*/
/* global define, require, window, document */
/* global define, require, window, document, JSON */
(function (factory) {
;(function (factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
@ -27,7 +27,14 @@
'use strict';
// Helper variable to create unique names for the transport iframes:
var counter = 0;
var counter = 0,
jsonAPI = $,
jsonParse = 'parseJSON';
if ('JSON' in window && 'parse' in JSON) {
jsonAPI = JSON;
jsonParse = 'parse';
}
// The iframe transport accepts four additional options:
// options.fileInput: a jQuery collection of file input fields
@ -197,7 +204,7 @@
return iframe && $(iframe[0].body).text();
},
'iframe json': function (iframe) {
return iframe && $.parseJSON($(iframe[0].body).text());
return iframe && jsonAPI[jsonParse]($(iframe[0].body).text());
},
'iframe html': function (iframe) {
return iframe && $(iframe[0].body).html();

View file

@ -52,6 +52,7 @@
var self = this;
var $container = containerEl;
var data = $container.data();
var lastUploadTime = 0;
$.extend(data, {
files: {},
@ -93,15 +94,16 @@
},
submit: function(e, item) {
item.formData = defaultFormData;
item.formData.nonce = "T" + new Date().getTime() + "." + Math.random();
chunkStatus = true;
},
chunksend: function(e, res) {
lastUploadTime = Date.now();
if (!chunkStatus) {
return false;
}
},
chunkdone: function(e, res) {
lastUploadTime = Date.now();
if (res.result) {
if (res.result.error != 0) {
if (res.result.message) {
@ -117,16 +119,22 @@
}
},
chunkfail: function(e, res) {
lastUploadTime = Date.now();
if (chunkStatus) {
alert(window.xe.msg_file_upload_error + " (Type 3)" + "<br>\n" + res.errorThrown + "<br>\n" + res.textStatus);
return chunkStatus = false;
}
},
done: function(e, res) {
lastUploadTime = Date.now();
data.settings.progressbarGraph.width('100%');
data.settings.progressPercent.text('100%');
data.settings.progressbar.delay(1000).slideUp();
data.settings.progressStatus.delay(1000).slideUp();
setTimeout(function() {
if (lastUploadTime < Date.now() - 800) {
data.settings.progressbar.slideUp();
data.settings.progressStatus.slideUp();
}
}, 1000);
var result = res.response().result;
var temp_code = '';
if (!result) {
@ -159,22 +167,30 @@
}
},
fail: function(e, res) {
data.settings.progressbar.delay(1000).slideUp();
data.settings.progressStatus.delay(1000).slideUp();
lastUploadTime = Date.now();
setTimeout(function() {
if (lastUploadTime < Date.now() - 800) {
data.settings.progressbar.slideUp();
data.settings.progressStatus.slideUp();
}
}, 1000);
if (chunkStatus) {
alert(window.xe.msg_file_upload_error + " (Type 7)" + "<br>\n" + res.errorThrown + "<br>\n" + res.textStatus);
return false;
}
},
stop: function() {
lastUploadTime = Date.now();
self.loadFilelist($container);
},
start: function() {
lastUploadTime = Date.now();
data.settings.progressbarGraph.width(0);
data.settings.progressStatus.show();
data.settings.progressbar.show();
},
progressall: function (e, res) {
lastUploadTime = Date.now();
var progress = Math.round(res.loaded / res.total * 999) / 10;
data.settings.progressbarGraph.width(progress+'%');
data.settings.progressPercent.text(progress+'%');
@ -203,6 +219,7 @@
// 본문 삽입
data.settings.actSelectedInsertContent.on('click', function() {
self.insertToContent($container);
data.settings.fileList.finderSelect('unHighlightAll');
});
// 파일 삭제

View file

@ -1,38 +1,48 @@
/*! jQuery UI - v1.11.1+CommonJS - 2014-09-17
/*! jQuery UI - v1.12.1+CommonJS - 2018-02-10
* http://jqueryui.com
* Includes: widget.js
* Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */
* Copyright jQuery Foundation and other contributors; Licensed MIT */
(function( factory ) {
if ( typeof define === "function" && define.amd ) {
// AMD. Register as an anonymous module.
define([ "jquery" ], factory );
} else if ( typeof exports === "object" ) {
// Node/CommonJS:
factory(require("jquery"));
// Node/CommonJS
factory( require( "jquery" ) );
} else {
// Browser globals
factory( jQuery );
}
}(function( $ ) {
$.ui = $.ui || {};
var version = $.ui.version = "1.12.1";
/*!
* jQuery UI Widget 1.11.1
* jQuery UI Widget 1.12.1
* http://jqueryui.com
*
* Copyright 2014 jQuery Foundation and other contributors
* Copyright jQuery Foundation and other contributors
* Released under the MIT license.
* http://jquery.org/license
*
* http://api.jqueryui.com/jQuery.widget/
*/
//>>label: Widget
//>>group: Core
//>>description: Provides a factory for creating stateful widgets with a common API.
//>>docs: http://api.jqueryui.com/jQuery.widget/
//>>demos: http://jqueryui.com/widget/
var widget_uuid = 0,
widget_slice = Array.prototype.slice;
var widgetUuid = 0;
var widgetSlice = Array.prototype.slice;
$.cleanData = ( function( orig ) {
return function( elems ) {
@ -46,7 +56,7 @@ $.cleanData = (function( orig ) {
$( elem ).triggerHandler( "remove" );
}
// http://bugs.jquery.com/ticket/8235
// Http://bugs.jquery.com/ticket/8235
} catch ( e ) {}
}
orig( elems );
@ -54,21 +64,26 @@ $.cleanData = (function( orig ) {
} )( $.cleanData );
$.widget = function( name, base, prototype ) {
var fullName, existingConstructor, constructor, basePrototype,
// proxiedPrototype allows the provided prototype to remain unmodified
// so that it can be used as a mixin for multiple widgets (#8876)
proxiedPrototype = {},
namespace = name.split( "." )[ 0 ];
var existingConstructor, constructor, basePrototype;
// ProxiedPrototype allows the provided prototype to remain unmodified
// so that it can be used as a mixin for multiple widgets (#8876)
var proxiedPrototype = {};
var namespace = name.split( "." )[ 0 ];
name = name.split( "." )[ 1 ];
fullName = namespace + "-" + name;
var fullName = namespace + "-" + name;
if ( !prototype ) {
prototype = base;
base = $.Widget;
}
// create selector for plugin
if ( $.isArray( prototype ) ) {
prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
}
// Create selector for plugin
$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
return !!$.data( elem, fullName );
};
@ -76,30 +91,35 @@ $.widget = function( name, base, prototype ) {
$[ namespace ] = $[ namespace ] || {};
existingConstructor = $[ namespace ][ name ];
constructor = $[ namespace ][ name ] = function( options, element ) {
// allow instantiation without "new" keyword
// Allow instantiation without "new" keyword
if ( !this._createWidget ) {
return new constructor( options, element );
}
// allow instantiation without initializing for simple inheritance
// Allow instantiation without initializing for simple inheritance
// must use "new" keyword (the code above always passes args)
if ( arguments.length ) {
this._createWidget( options, element );
}
};
// extend with the existing constructor to carry over any static properties
// Extend with the existing constructor to carry over any static properties
$.extend( constructor, existingConstructor, {
version: prototype.version,
// copy the object used to create the prototype in case we need to
// Copy the object used to create the prototype in case we need to
// redefine the widget later
_proto: $.extend( {}, prototype ),
// track widgets that inherit from this widget in case this widget is
// Track widgets that inherit from this widget in case this widget is
// redefined after a widget inherits from it
_childConstructors: []
} );
basePrototype = new base();
// we need to make the options hash a property directly on the new instance
// We need to make the options hash a property directly on the new instance
// otherwise we'll modify the options hash on the prototype that we're
// inheriting from
basePrototype.options = $.widget.extend( {}, basePrototype.options );
@ -109,16 +129,18 @@ $.widget = function( name, base, prototype ) {
return;
}
proxiedPrototype[ prop ] = ( function() {
var _super = function() {
function _super() {
return base.prototype[ prop ].apply( this, arguments );
},
_superApply = function( args ) {
}
function _superApply( args ) {
return base.prototype[ prop ].apply( this, args );
};
}
return function() {
var __super = this._super,
__superApply = this._superApply,
returnValue;
var __super = this._super;
var __superApply = this._superApply;
var returnValue;
this._super = _super;
this._superApply = _superApply;
@ -133,6 +155,7 @@ $.widget = function( name, base, prototype ) {
} )();
} );
constructor.prototype = $.widget.extend( basePrototype, {
// TODO: remove support for widgetEventPrefix
// always use the name + a colon as the prefix, e.g., draggable:start
// don't prefix for widgets that aren't DOM-based
@ -152,11 +175,13 @@ $.widget = function( name, base, prototype ) {
$.each( existingConstructor._childConstructors, function( i, child ) {
var childPrototype = child.prototype;
// redefine the child widget using the same prototype that was
// Redefine the child widget using the same prototype that was
// originally used, but inherit from the new version of the base
$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor,
child._proto );
} );
// remove the list of existing child constructors from the old constructor
// Remove the list of existing child constructors from the old constructor
// so the old child constructors can be garbage collected
delete existingConstructor._childConstructors;
} else {
@ -169,21 +194,25 @@ $.widget = function( name, base, prototype ) {
};
$.widget.extend = function( target ) {
var input = widget_slice.call( arguments, 1 ),
inputIndex = 0,
inputLength = input.length,
key,
value;
var input = widgetSlice.call( arguments, 1 );
var inputIndex = 0;
var inputLength = input.length;
var key;
var value;
for ( ; inputIndex < inputLength; inputIndex++ ) {
for ( key in input[ inputIndex ] ) {
value = input[ inputIndex ][ key ];
if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
// Clone objects
if ( $.isPlainObject( value ) ) {
target[ key ] = $.isPlainObject( target[ key ] ) ?
$.widget.extend( {}, target[ key ], value ) :
// Don't extend strings, arrays, etc. with objects
$.widget.extend( {}, value );
// Copy everything else by reference
} else {
target[ key ] = value;
@ -197,31 +226,39 @@ $.widget.extend = function( target ) {
$.widget.bridge = function( name, object ) {
var fullName = object.prototype.widgetFullName || name;
$.fn[ name ] = function( options ) {
var isMethodCall = typeof options === "string",
args = widget_slice.call( arguments, 1 ),
returnValue = this;
// allow multiple hashes to be passed on init
options = !isMethodCall && args.length ?
$.widget.extend.apply( null, [ options ].concat(args) ) :
options;
var isMethodCall = typeof options === "string";
var args = widgetSlice.call( arguments, 1 );
var returnValue = this;
if ( isMethodCall ) {
// If this is an empty collection, we need to have the instance method
// return undefined instead of the jQuery instance
if ( !this.length && options === "instance" ) {
returnValue = undefined;
} else {
this.each( function() {
var methodValue,
instance = $.data( this, fullName );
var methodValue;
var instance = $.data( this, fullName );
if ( options === "instance" ) {
returnValue = instance;
return false;
}
if ( !instance ) {
return $.error( "cannot call methods on " + name + " prior to initialization; " +
return $.error( "cannot call methods on " + name +
" prior to initialization; " +
"attempted to call method '" + options + "'" );
}
if ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === "_" ) {
return $.error( "no such method '" + options + "' for " + name + " widget instance" );
return $.error( "no such method '" + options + "' for " + name +
" widget instance" );
}
methodValue = instance[ options ].apply( instance, args );
if ( methodValue !== instance && methodValue !== undefined ) {
returnValue = methodValue && methodValue.jquery ?
returnValue.pushStack( methodValue.get() ) :
@ -229,7 +266,14 @@ $.widget.bridge = function( name, object ) {
return false;
}
} );
}
} else {
// Allow multiple hashes to be passed on init
if ( args.length ) {
options = $.widget.extend.apply( null, [ options ].concat( args ) );
}
this.each( function() {
var instance = $.data( this, fullName );
if ( instance ) {
@ -254,25 +298,25 @@ $.Widget.prototype = {
widgetName: "widget",
widgetEventPrefix: "",
defaultElement: "<div>",
options: {
classes: {},
disabled: false,
// callbacks
// Callbacks
create: null
},
_createWidget: function( options, element ) {
element = $( element || this.defaultElement || this )[ 0 ];
this.element = $( element );
this.uuid = widget_uuid++;
this.uuid = widgetUuid++;
this.eventNamespace = "." + this.widgetName + this.uuid;
this.options = $.widget.extend( {},
this.options,
this._getCreateOptions(),
options );
this.bindings = $();
this.hoverable = $();
this.focusable = $();
this.classesElementLookup = {};
if ( element !== this ) {
$.data( element, this.widgetFullName, this );
@ -284,44 +328,61 @@ $.Widget.prototype = {
}
} );
this.document = $( element.style ?
// element within the document
// Element within the document
element.ownerDocument :
// element is window or document
// Element is window or document
element.document || element );
this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
}
this.options = $.widget.extend( {},
this.options,
this._getCreateOptions(),
options );
this._create();
if ( this.options.disabled ) {
this._setOptionDisabled( this.options.disabled );
}
this._trigger( "create", null, this._getCreateEventData() );
this._init();
},
_getCreateOptions: $.noop,
_getCreateOptions: function() {
return {};
},
_getCreateEventData: $.noop,
_create: $.noop,
_init: $.noop,
destroy: function() {
var that = this;
this._destroy();
// we can probably remove the unbind calls in 2.0
$.each( this.classesElementLookup, function( key, value ) {
that._removeClass( value, key );
} );
// We can probably remove the unbind calls in 2.0
// all event bindings should go through this._on()
this.element
.unbind( this.eventNamespace )
.removeData( this.widgetFullName )
// support: jquery <1.6.3
// http://bugs.jquery.com/ticket/9413
.removeData( $.camelCase( this.widgetFullName ) );
.off( this.eventNamespace )
.removeData( this.widgetFullName );
this.widget()
.unbind( this.eventNamespace )
.removeAttr( "aria-disabled" )
.removeClass(
this.widgetFullName + "-disabled " +
"ui-state-disabled" );
.off( this.eventNamespace )
.removeAttr( "aria-disabled" );
// clean up events and states
this.bindings.unbind( this.eventNamespace );
this.hoverable.removeClass( "ui-state-hover" );
this.focusable.removeClass( "ui-state-focus" );
// Clean up events and states
this.bindings.off( this.eventNamespace );
},
_destroy: $.noop,
widget: function() {
@ -329,18 +390,20 @@ $.Widget.prototype = {
},
option: function( key, value ) {
var options = key,
parts,
curOption,
i;
var options = key;
var parts;
var curOption;
var i;
if ( arguments.length === 0 ) {
// don't return a reference to the internal hash
// Don't return a reference to the internal hash
return $.widget.extend( {}, this.options );
}
if ( typeof key === "string" ) {
// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
// Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
options = {};
parts = key.split( "." );
key = parts.shift();
@ -367,6 +430,7 @@ $.Widget.prototype = {
return this;
},
_setOptions: function( options ) {
var key;
@ -376,42 +440,152 @@ $.Widget.prototype = {
return this;
},
_setOption: function( key, value ) {
if ( key === "classes" ) {
this._setOptionClasses( value );
}
this.options[ key ] = value;
if ( key === "disabled" ) {
this.widget()
.toggleClass( this.widgetFullName + "-disabled", !!value );
// If the widget is becoming disabled, then nothing is interactive
if ( value ) {
this.hoverable.removeClass( "ui-state-hover" );
this.focusable.removeClass( "ui-state-focus" );
}
this._setOptionDisabled( value );
}
return this;
},
_setOptionClasses: function( value ) {
var classKey, elements, currentElements;
for ( classKey in value ) {
currentElements = this.classesElementLookup[ classKey ];
if ( value[ classKey ] === this.options.classes[ classKey ] ||
!currentElements ||
!currentElements.length ) {
continue;
}
// We are doing this to create a new jQuery object because the _removeClass() call
// on the next line is going to destroy the reference to the current elements being
// tracked. We need to save a copy of this collection so that we can add the new classes
// below.
elements = $( currentElements.get() );
this._removeClass( currentElements, classKey );
// We don't use _addClass() here, because that uses this.options.classes
// for generating the string of classes. We want to use the value passed in from
// _setOption(), this is the new value of the classes option which was passed to
// _setOption(). We pass this value directly to _classes().
elements.addClass( this._classes( {
element: elements,
keys: classKey,
classes: value,
add: true
} ) );
}
},
_setOptionDisabled: function( value ) {
this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
// If the widget is becoming disabled, then nothing is interactive
if ( value ) {
this._removeClass( this.hoverable, null, "ui-state-hover" );
this._removeClass( this.focusable, null, "ui-state-focus" );
}
},
enable: function() {
return this._setOptions( { disabled: false } );
},
disable: function() {
return this._setOptions( { disabled: true } );
},
_on: function( suppressDisabledCheck, element, handlers ) {
var delegateElement,
instance = this;
_classes: function( options ) {
var full = [];
var that = this;
// no suppressDisabledCheck flag, shuffle arguments
options = $.extend( {
element: this.element,
classes: this.options.classes || {}
}, options );
function processClassString( classes, checkOption ) {
var current, i;
for ( i = 0; i < classes.length; i++ ) {
current = that.classesElementLookup[ classes[ i ] ] || $();
if ( options.add ) {
current = $( $.unique( current.get().concat( options.element.get() ) ) );
} else {
current = $( current.not( options.element ).get() );
}
that.classesElementLookup[ classes[ i ] ] = current;
full.push( classes[ i ] );
if ( checkOption && options.classes[ classes[ i ] ] ) {
full.push( options.classes[ classes[ i ] ] );
}
}
}
this._on( options.element, {
"remove": "_untrackClassesElement"
} );
if ( options.keys ) {
processClassString( options.keys.match( /\S+/g ) || [], true );
}
if ( options.extra ) {
processClassString( options.extra.match( /\S+/g ) || [] );
}
return full.join( " " );
},
_untrackClassesElement: function( event ) {
var that = this;
$.each( that.classesElementLookup, function( key, value ) {
if ( $.inArray( event.target, value ) !== -1 ) {
that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
}
} );
},
_removeClass: function( element, keys, extra ) {
return this._toggleClass( element, keys, extra, false );
},
_addClass: function( element, keys, extra ) {
return this._toggleClass( element, keys, extra, true );
},
_toggleClass: function( element, keys, extra, add ) {
add = ( typeof add === "boolean" ) ? add : extra;
var shift = ( typeof element === "string" || element === null ),
options = {
extra: shift ? keys : extra,
keys: shift ? element : keys,
element: shift ? this.element : element,
add: add
};
options.element.toggleClass( this._classes( options ), add );
return this;
},
_on: function( suppressDisabledCheck, element, handlers ) {
var delegateElement;
var instance = this;
// No suppressDisabledCheck flag, shuffle arguments
if ( typeof suppressDisabledCheck !== "boolean" ) {
handlers = element;
element = suppressDisabledCheck;
suppressDisabledCheck = false;
}
// no element argument, shuffle and use this.element
// No element argument, shuffle and use this.element
if ( !handlers ) {
handlers = element;
element = this.element;
@ -423,7 +597,8 @@ $.Widget.prototype = {
$.each( handlers, function( event, handler ) {
function handlerProxy() {
// allow widgets to customize the disabled handling
// Allow widgets to customize the disabled handling
// - disabled as an array instead of boolean
// - disabled class as method for disabling individual parts
if ( !suppressDisabledCheck &&
@ -435,26 +610,33 @@ $.Widget.prototype = {
.apply( instance, arguments );
}
// copy the guid so direct unbinding works
// Copy the guid so direct unbinding works
if ( typeof handler !== "string" ) {
handlerProxy.guid = handler.guid =
handler.guid || handlerProxy.guid || $.guid++;
}
var match = event.match( /^([\w:-]*)\s*(.*)$/ ),
eventName = match[1] + instance.eventNamespace,
selector = match[2];
var match = event.match( /^([\w:-]*)\s*(.*)$/ );
var eventName = match[ 1 ] + instance.eventNamespace;
var selector = match[ 2 ];
if ( selector ) {
delegateElement.delegate( selector, eventName, handlerProxy );
delegateElement.on( eventName, selector, handlerProxy );
} else {
element.bind( eventName, handlerProxy );
element.on( eventName, handlerProxy );
}
} );
},
_off: function( element, eventName ) {
eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
element.unbind( eventName ).undelegate( eventName );
eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
this.eventNamespace;
element.off( eventName ).off( eventName );
// Clear the stack to avoid memory leaks (#10056)
this.bindings = $( this.bindings.not( element ).get() );
this.focusable = $( this.focusable.not( element ).get() );
this.hoverable = $( this.hoverable.not( element ).get() );
},
_delay: function( handler, delay ) {
@ -470,10 +652,10 @@ $.Widget.prototype = {
this.hoverable = this.hoverable.add( element );
this._on( element, {
mouseenter: function( event ) {
$( event.currentTarget ).addClass( "ui-state-hover" );
this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
},
mouseleave: function( event ) {
$( event.currentTarget ).removeClass( "ui-state-hover" );
this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
}
} );
},
@ -482,28 +664,29 @@ $.Widget.prototype = {
this.focusable = this.focusable.add( element );
this._on( element, {
focusin: function( event ) {
$( event.currentTarget ).addClass( "ui-state-focus" );
this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
},
focusout: function( event ) {
$( event.currentTarget ).removeClass( "ui-state-focus" );
this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
}
} );
},
_trigger: function( type, event, data ) {
var prop, orig,
callback = this.options[ type ];
var prop, orig;
var callback = this.options[ type ];
data = data || {};
event = $.Event( event );
event.type = ( type === this.widgetEventPrefix ?
type :
this.widgetEventPrefix + type ).toLowerCase();
// the original event may come from any element
// The original event may come from any element
// so we need to reset the target on the new event
event.target = this.element[ 0 ];
// copy original event properties over to the new event
// Copy original event properties over to the new event
orig = event.originalEvent;
if ( orig ) {
for ( prop in orig ) {
@ -525,21 +708,26 @@ $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
if ( typeof options === "string" ) {
options = { effect: options };
}
var hasOptions,
effectName = !options ?
var hasOptions;
var effectName = !options ?
method :
options === true || typeof options === "number" ?
defaultEffect :
options.effect || defaultEffect;
options = options || {};
if ( typeof options === "number" ) {
options = { duration: options };
}
hasOptions = !$.isEmptyObject( options );
options.complete = callback;
if ( options.delay ) {
element.delay( options.delay );
}
if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
element[ method ]( options );
} else if ( effectName !== method && element[ effectName ] ) {
@ -560,4 +748,5 @@ var widget = $.widget;
}));

View file

@ -231,6 +231,8 @@ $lang->msg_input_password = 'Please type the password.';
$lang->msg_invalid_document = 'Invalid Article Number';
$lang->msg_invalid_request = 'Invalid Request';
$lang->msg_invalid_password = 'The password you entered is incorrect.';
$lang->msg_security_violation = 'Security Violation';
$lang->msg_feature_disabled = 'This feature is disabled.';
$lang->msg_error_occured = 'An error has occured.';
$lang->msg_not_founded = 'Cannot find the target.';
$lang->msg_no_result = 'No results found.';
@ -244,6 +246,7 @@ $lang->msg_empty_search_keyword = 'Cannot find the Keyword.';
$lang->msg_empty_content = 'The content is empty.';
$lang->msg_server_error = 'Server Error';
$lang->msg_server_error_see_log = 'Your server is configured to hide error messages. Please see your server\'s error log for details.';
$lang->msg_crypto_not_available = 'OpenSSL extension is not installed.';
$lang->comment_to_be_approved = 'Your comment must be approved by admin before being published.';
$lang->success_registed = 'Registered successfully.';
$lang->success_declared = 'Reported successfully.';
@ -266,7 +269,9 @@ $lang->fail_to_update = 'Fail to update.';
$lang->fail_to_delete = 'Failed to delete.';
$lang->fail_to_move = 'Failed to move.';
$lang->failed_voted = 'No permission to upvote.';
$lang->failed_voted_canceled = 'You cannot cancel an upvote that you did\'t make.';
$lang->failed_blamed = 'No permission to downvote.';
$lang->failed_blamed_canceled = 'You cannot cancel a downvote that you did\'t make.';
$lang->failed_declared = 'No permission to Report.';
$lang->fail_to_delete_have_children = 'Cannot delete the article with comments.';
$lang->confirm_submit = 'Are you sure you want to submit?';

View file

@ -231,6 +231,8 @@ $lang->msg_input_password = '비밀번호를 입력하세요.';
$lang->msg_invalid_document = '잘못된 문서번호입니다.';
$lang->msg_invalid_request = '잘못된 요청입니다.';
$lang->msg_invalid_password = '비밀번호가 올바르지 않습니다.';
$lang->msg_security_violation = '보안정책상 허용되지 않습니다.';
$lang->msg_feature_disabled = '사용할 수 없는 기능입니다.';
$lang->msg_error_occured = '오류가 발생했습니다.';
$lang->msg_not_founded = '대상을 찾을 수 없습니다.';
$lang->msg_no_result = '검색 결과가 없습니다.';
@ -244,6 +246,7 @@ $lang->msg_empty_search_keyword = '검색어가 없습니다.';
$lang->msg_empty_content = '내용이 없습니다.';
$lang->msg_server_error = '서버 오류';
$lang->msg_server_error_see_log = '오류 메시지를 표시하지 않도록 설정되어 있습니다. 서버의 에러 로그에서 자세한 내용을 확인해 주십시오.';
$lang->msg_crypto_not_available = 'openssl 확장모듈이 설치되어 있지 않습니다.';
$lang->comment_to_be_approved = '관리자의 확인이 필요한 댓글입니다.';
$lang->success_registed = '등록했습니다.';
$lang->success_declared = '신고했습니다.';
@ -266,7 +269,9 @@ $lang->fail_to_update = '수정하지 못했습니다.';
$lang->fail_to_delete = '삭제 실패했습니다.';
$lang->fail_to_move = '이동 실패했습니다.';
$lang->failed_voted = '추천할 수 없습니다.';
$lang->failed_voted_canceled = '추천한 적이 없으므로 취소할 수 없습니다.';
$lang->failed_blamed = '비추천할 수 없습니다.';
$lang->failed_blamed_canceled = '비추천한 적이 없으므로 취소할 수 없습니다.';
$lang->failed_declared = '신고할 수 없습니다.';
$lang->fail_to_delete_have_children = '댓글이 있어서 삭제할 수 없습니다.';
$lang->confirm_submit = '등록하시겠습니까?';

View file

@ -868,7 +868,7 @@ function removeSrcHack($match)
* @param string $file Taget file path
* @return bool
*/
function checkUploadedFile($file)
function checkUploadedFile($file, $filename = null)
{
return true;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Some files were not shown because too many files have changed in this diff Show more