Merge branch 'develop' into pr/member-phone-number
|
|
@ -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]
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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('&' => '&'));
|
||||
}
|
||||
}
|
||||
}
|
||||
$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};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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}))";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -18,4 +18,7 @@ return array(
|
|||
'session_shield' => true,
|
||||
'smartphone' => true,
|
||||
'zipperupper' => true,
|
||||
'elkha_www' => true,
|
||||
'autowww' => true,
|
||||
'fix_domain' => true,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
20
common/framework/drivers/cache/apc.php
vendored
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
18
common/framework/exceptions/featuredisabled.php
Normal 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);
|
||||
}
|
||||
}
|
||||
18
common/framework/exceptions/invalidrequest.php
Normal 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);
|
||||
}
|
||||
}
|
||||
18
common/framework/exceptions/mustlogin.php
Normal 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);
|
||||
}
|
||||
}
|
||||
18
common/framework/exceptions/notpermitted.php
Normal 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);
|
||||
}
|
||||
}
|
||||
18
common/framework/exceptions/securityviolation.php
Normal 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);
|
||||
}
|
||||
}
|
||||
18
common/framework/exceptions/targetnotfound.php
Normal 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);
|
||||
}
|
||||
}
|
||||
197
common/framework/filters/filecontentfilter.php
Normal 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ class Mail
|
|||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->message = \Swift_Message::newInstance();
|
||||
$this->message = new \Swift_Message;
|
||||
$this->driver = self::getDefaultDriver();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
165
common/js/plugins/cookie/js.cookie.js
Normal 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 () {});
|
||||
}));
|
||||
1
common/js/plugins/cookie/js.cookie.min.js
vendored
Normal 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(){})});
|
||||
1
common/js/plugins/cookie/js.cookie.min.js.map
Normal 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"}
|
||||
1
common/js/plugins/cookie/plugin.load
Normal file
|
|
@ -0,0 +1 @@
|
|||
js.cookie.min.js
|
||||
21
common/js/plugins/jquery.fileupload/LICENSE.txt
Executable 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.
|
||||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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');
|
||||
});
|
||||
|
||||
// 파일 삭제
|
||||
|
|
|
|||
|
|
@ -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;
|
|||
|
||||
|
||||
|
||||
|
||||
}));
|
||||
|
|
|
|||
|
|
@ -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?';
|
||||
|
|
|
|||
|
|
@ -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 = '등록하시겠습니까?';
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 7.8 KiB |
|
Before Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 3 KiB |
|
Before Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 6 KiB |
|
Before Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 9.3 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 25 KiB |