Merge pull request #2069 from kijin/pr/whitespace

.editorconfig에서 trim_trailing_whitespace = true로 변경
This commit is contained in:
Kijin Sung 2023-02-05 20:38:49 +09:00 committed by GitHub
commit 9aec92fbfd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
292 changed files with 6253 additions and 6379 deletions

View file

@ -1,12 +1,15 @@
root = true
[*]
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = false
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true
indent_style = tab
[*.md]
trim_trailing_whitespace = false
[*.py]
indent_style = space
indent_size = 4
@ -14,3 +17,7 @@ indent_size = 4
[*.{json,yml,md}]
indent_style = space
indent_size = 2
[*.{jsx,tsx,svelte,vue}]
indent_style = space
indent_size = 2

View file

@ -1,5 +1,4 @@
<?php
/* Copyright (C) NAVER <http://www.navercorp.com> */
/**
* CacheHandler
@ -12,7 +11,7 @@ class CacheHandler extends Handler
* Force file cache.
*/
protected $_always_use_file = false;
/**
* Get a instance of CacheHandler(for singleton)
*
@ -158,6 +157,3 @@ class CacheHandler extends Handler
return Rhymix\Framework\Cache::clearGroup($keyGroupName);
}
}
/* End of file CacheHandler.class.php */
/* Location: ./classes/cache/CacheHandler.class.php */

View file

@ -1,5 +1,4 @@
<?php
/* Copyright (C) NAVER <http://www.navercorp.com> */
/**
* Manages Context such as request arguments/environment variables
@ -81,7 +80,7 @@ class Context
* @var array
*/
public $opengraph_metadata = array();
/**
* Canonical URL
* @var string
@ -124,7 +123,7 @@ class Context
* @var object
*/
private static $_instance = null;
/**
* Flag to prevent calling init() twice
*/
@ -208,7 +207,7 @@ class Context
*/
private function __construct()
{
}
/**
@ -224,16 +223,16 @@ class Context
return;
}
self::$_init_called = true;
// Obtain a singleton instance if not already given.
if(self::$_instance === null)
{
self::$_instance = self::getInstance();
}
// Load system configuration.
self::loadDBInfo();
// Set information about the current request.
self::_checkGlobalVars();
self::setRequestMethod();
@ -249,7 +248,7 @@ class Context
self::setRequestArguments();
}
self::setUploadInfo();
// If Rhymix is installed, get virtual site information.
if(self::isInstalled())
{
@ -279,7 +278,7 @@ class Context
$site_module_info->is_default_replaced = true;
self::set('site_module_info', $site_module_info);
}
// Redirect to SSL if the current domain requires SSL.
if (!RX_SSL && PHP_SAPI !== 'cli' && $site_module_info->security !== 'none' && !$site_module_info->is_default_replaced)
{
@ -288,12 +287,12 @@ class Context
header('Location: ' . $ssl_url, true, 301);
exit;
}
// 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)
@ -318,13 +317,13 @@ class Context
$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, \RX_BASEURL, null, !!config('session.use_ssl_cookies'));
}
if(!$lang_type || !isset($enabled_langs[$lang_type]))
{
if(isset($site_module_info->settings->language) && $site_module_info->settings->language !== 'default')
@ -346,13 +345,13 @@ class Context
$lang->loadDirectory(RX_BASEDIR . 'modules/module/lang', 'module');
self::setLangType(self::$_instance->lang_type = $lang_type);
self::set('lang', self::$_instance->lang = $lang);
// Set global variables for backward compatibility.
$GLOBALS['oContext'] = self::$_instance;
$GLOBALS['__Context__'] = &self::$_tpl_vars;
$GLOBALS['_time_zone'] = config('locale.default_timezone');
$GLOBALS['lang'] = &$lang;
// set session handler
if(self::isInstalled() && config('session.use_db'))
{
@ -363,14 +362,14 @@ class Context
array($oSessionController, 'open'), array($oSessionController, 'close'), array($oSessionModel, 'read'), array($oSessionController, 'write'), array($oSessionController, 'destroy'), array($oSessionController, 'gc')
);
}
// start session
if (\PHP_SAPI !== 'cli')
{
Rhymix\Framework\Session::checkSSO($site_module_info);
Rhymix\Framework\Session::start(false);
}
// start output buffer
if (\PHP_SAPI !== 'cli')
{
@ -390,10 +389,10 @@ class Context
self::set('logged_info', false);
}
}
// start debugging
Rhymix\Framework\Debug::isEnabledForCurrentUser();
// set locations for javascript use
$current_url = $request_uri = self::getRequestUri();
if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'GET' && self::$_get_vars)
@ -413,10 +412,10 @@ class Context
}
self::set('current_url', $current_url);
self::set('request_uri', $request_uri);
// set mobile status
self::set('m', Mobile::isFromMobilePhone() ? 1 : 0);
// If the site is locked, display the locked page.
if(config('lock.locked'))
{
@ -426,7 +425,7 @@ class Context
/**
* Get the session status
*
*
* @return bool
*/
public static function getSessionStatus()
@ -436,7 +435,7 @@ class Context
/**
* Start the session if $_SESSION was touched
*
*
* @return void
*/
public static function checkSessionStatus($force = false)
@ -456,7 +455,7 @@ class Context
{
DisplayHandler::getDebugInfo();
}
// Check session status and close it if open.
if (Rhymix\Framework\Session::checkStart())
{
@ -500,7 +499,7 @@ class Context
{
$config = Rhymix\Framework\Config::getAll();
}
// Copy to old format for backward compatibility.
self::$_instance->db_info = new stdClass;
if (is_array($config) && count($config))
@ -582,12 +581,12 @@ class Context
{
return $default_url;
}
if ($site_module_info === null)
{
$site_module_info = self::get('site_module_info');
}
$prefix = ($site_module_info->security !== 'none' || $use_ssl) ? 'https://' : 'http://';
$hostname = $site_module_info->domain;
$port = ($prefix === 'https://') ? $site_module_info->https_port : $site_module_info->http_port;
@ -751,7 +750,7 @@ class Context
/**
* Return site title
*
*
* @return string
*/
public static function getSiteTitle()
@ -766,10 +765,10 @@ class Context
return '';
}
}
/**
* Return site subtitle
*
*
* @return string
*/
public static function getSiteSubtitle()
@ -808,13 +807,13 @@ class Context
$path = \RX_BASEDIR . $matches[1] . '/' . $matches[2] . '/lang';
$plugin_name = $matches[2];
}
if (!(($GLOBALS['lang'] ?? null) instanceof Rhymix\Framework\Lang))
{
$GLOBALS['lang'] = Rhymix\Framework\Lang::getInstance(self::$_instance->lang_type ?: config('locale.default_lang') ?: 'ko');
$GLOBALS['lang']->loadDirectory(RX_BASEDIR . 'common/lang', 'common');
}
return $GLOBALS['lang']->loadDirectory($path, $plugin_name);
}
@ -830,7 +829,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);
@ -864,7 +863,7 @@ class Context
$GLOBALS['lang'] = Rhymix\Framework\Lang::getInstance(self::$_instance->lang_type ?: config('locale.default_lang') ?: 'ko');
$GLOBALS['lang']->loadDirectory(RX_BASEDIR . 'common/lang', 'common');
}
return $GLOBALS['lang']->get($code);
}
@ -882,7 +881,7 @@ class Context
$GLOBALS['lang'] = Rhymix\Framework\Lang::getInstance(self::$_instance->lang_type ?: config('locale.default_lang') ?: 'ko');
$GLOBALS['lang']->loadDirectory(RX_BASEDIR . 'common/lang', 'common');
}
$GLOBALS['lang']->set($code, $val);
}
@ -900,7 +899,7 @@ class Context
$lang = ModuleAdminController::getInstance()->makeCacheDefinedLangCode(0);
}
}
return preg_replace_callback('/\$user_lang->([a-zA-Z0-9\_]+)/', function($matches) use($lang) {
if(isset($lang[$matches[1]]) && !self::get($matches[1]))
{
@ -912,7 +911,7 @@ class Context
}
}, $output);
}
/**
* Convert strings of variables in $source_object into UTF-8
*
@ -1017,7 +1016,7 @@ class Context
/**
* Encode UTF-8 domain into IDNA (punycode)
*
*
* @param string $domain Domain to convert
* @return string Converted string
*/
@ -1028,7 +1027,7 @@ class Context
/**
* Convert IDNA (punycode) domain into UTF-8
*
*
* @param string $domain Domain to convert
* @return string Converted string
*/
@ -1116,7 +1115,7 @@ class Context
{
self::$_instance->request_method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
}
if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'POST')
{
// Set variables for XE compatibility.
@ -1132,7 +1131,7 @@ class Context
{
$GLOBALS['HTTP_RAW_POST_DATA'] = file_get_contents('php://input');
}
// Check the Content-Type header for a hint of JSON.
foreach (array('HTTP_ACCEPT', 'HTTP_CONTENT_TYPE', 'CONTENT_TYPE') as $header)
{
@ -1142,7 +1141,7 @@ class Context
return;
}
}
// Decide whether it's JSON or XMLRPC by looking at the first character of the POST data.
if (!$_POST && !empty($GLOBALS['HTTP_RAW_POST_DATA']))
{
@ -1170,7 +1169,7 @@ class Context
$request_args[$key] = $val;
}
}
// Set JSON and XMLRPC arguments.
if(isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'POST' && !$_POST && !empty($GLOBALS['HTTP_RAW_POST_DATA']))
{
@ -1199,7 +1198,7 @@ class Context
parse_str($GLOBALS['HTTP_RAW_POST_DATA'], $params);
}
}
foreach($params as $key => $val)
{
if ($val !== '' && $val !== null && !isset($request_args[$key]))
@ -1207,13 +1206,13 @@ class Context
$request_args[$key] = $val;
}
}
if (!empty($params['_rx_csrf_token']) && !isset($_REQUEST['_rx_csrf_token']))
{
$_REQUEST['_rx_csrf_token'] = $params['_rx_csrf_token'];
}
}
// Filter all arguments and set them to Context.
foreach($request_args as $key => $val)
{
@ -1225,10 +1224,10 @@ class Context
}
}
}
/**
* Handle uploaded file info.
*
*
* @return void
*/
private static function setUploadInfo()
@ -1302,7 +1301,7 @@ class Context
/**
* Check if a value (or array of values) matches a pattern defined in this class.
*
*
* @param mixed $val Values to check
* @return bool
*/
@ -1334,7 +1333,7 @@ class Context
}
}
}
return true;
}
@ -1355,7 +1354,7 @@ class Context
foreach($val as $_key => $_val)
{
unset($_val->node_name, $_val->attrs);
$args = new stdClass;
foreach((array)$_val as $name => $node)
{
@ -1363,7 +1362,7 @@ class Context
{
$node = array($node);
}
if($name == 'body' && count((array)$_val) === 1)
{
$_val = self::_filterRequestVar($key, $node);
@ -1381,7 +1380,7 @@ class Context
}
$result[escape($_key)] = !empty((array)$args) ? $args : $_val;
}
return $is_array ? $result : $result[0];
}
@ -1399,7 +1398,7 @@ class Context
{
return;
}
$result = array();
if(!$is_array = is_array($val))
{
@ -1438,7 +1437,7 @@ class Context
$result[escape($_key)] = $_val;
self::_recursiveCheckVar($_val);
}
return $is_array ? $result : $result[0];
}
@ -1477,7 +1476,7 @@ class Context
{
return;
}
// Allow if the current user is in the list of allowed IPs.
if (PHP_SAPI === 'cli')
{
@ -1487,7 +1486,7 @@ class Context
{
return;
}
// Set headers and constants for backward compatibility.
header('HTTP/1.1 503 Service Unavailable');
define('_XE_SITELOCK_', TRUE);
@ -1495,7 +1494,7 @@ class Context
define('_XE_SITELOCK_MESSAGE_', config('lock.message'));
unset($_SESSION['XE_VALIDATOR_RETURN_URL']);
self::$_instance->is_site_locked = true;
// Load the sitelock template.
if(FileHandler::exists(RX_BASEDIR . 'common/tpl/sitelock.user.html'))
{
@ -1507,10 +1506,10 @@ class Context
}
exit;
}
/**
* Display a generic error page and exit.
*
*
* @param string $title
* @param string $message
* @return void
@ -1519,11 +1518,11 @@ class Context
{
// Change current directory to the Rhymix installation path.
chdir(\RX_BASEDIR);
// Set the title.
self::setBrowserTitle(self::getSiteTitle());
self::addBrowserTitle($title);
// Set the message.
$oMessageObject = getView('message');
$oMessageObject->setError(-1);
@ -1531,7 +1530,7 @@ class Context
{
$oMessageObject->setHttpStatusCode($status);
}
// Find out the caller's location.
if (!$location)
{
@ -1543,7 +1542,7 @@ class Context
$location = substr($location, strlen(\RX_BASEDIR));
}
}
if (in_array(self::getRequestMethod(), array('XMLRPC', 'JSON', 'JS_CALLBACK')))
{
$oMessageObject->setMessage(trim($title . "\n\n" . $message));
@ -1553,7 +1552,7 @@ class Context
$oMessageObject->setMessage($title);
$oMessageObject->dispMessage($message, $location);
}
// Display the message.
$oModuleHandler = new ModuleHandler;
$oModuleHandler->displayContent($oMessageObject);
@ -1610,7 +1609,7 @@ class Context
{
$rewrite_level = Rhymix\Framework\Router::getRewriteLevel();
}
if ($site_module_info === null)
{
$site_module_info = self::get('site_module_info');
@ -1697,12 +1696,12 @@ class Context
}
}
}
// remove vid, rnd, error_return_url
unset($get_vars['error_return_url']);
unset($get_vars['rnd']);
unset($get_vars['vid']);
// for compatibility to lower versions
$act = $get_vars['act'] ?? null;
$act_alias = array(
@ -1715,7 +1714,7 @@ class Context
{
$get_vars['act'] = $act_alias[$act];
}
// Don't use full short URL for admin pages #1643
if (isset($get_vars['module']) && $get_vars['module'] === 'admin' && $rewrite_level > 1)
{
@ -1725,14 +1724,14 @@ class Context
{
$force_rewrite_level = 0;
}
// organize URL
$query = '';
if(count($get_vars) > 0)
{
$query = Rhymix\Framework\Router::getURL($get_vars, $force_rewrite_level ?: $rewrite_level);
}
// If using SSL always
if($site_module_info->security !== 'none')
{
@ -1833,7 +1832,7 @@ class Context
}
$site_module_info = $domain_infos[$domain] ?: $site_module_info;
}
$prefix = ($use_ssl || $site_module_info->security !== 'none') ? 'https://' : 'http://';
$hostname = $site_module_info->domain;
$port = ($use_ssl || $site_module_info->security !== 'none') ? $site_module_info->https_port : $site_module_info->http_port;
@ -1856,7 +1855,7 @@ class Context
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}))
@ -1885,7 +1884,7 @@ class Context
trigger_error('Called Context::get() with an empty key', \E_USER_WARNING);
return;
}
if(isset(self::$_tpl_vars->{$key}))
{
return self::$_tpl_vars->{$key};
@ -1949,7 +1948,7 @@ class Context
/**
* Clear all values from GET/POST/XMLRPC
*
*
* @return void
*/
public static function clearRequestVars()
@ -1959,7 +1958,7 @@ class Context
/**
* Clear all user-set values
*
*
* @return void
*/
public static function clearUserVars()
@ -1976,7 +1975,7 @@ class Context
*/
public static function addSSLAction($action)
{
}
/**
@ -1988,7 +1987,7 @@ class Context
*/
public static function addSSLActions($action_array)
{
}
/**
@ -2000,7 +1999,7 @@ class Context
*/
public static function subtractSSLAction($action)
{
}
/**
@ -2092,7 +2091,7 @@ class Context
{
$args = func_get_args();
}
self::$_oFrontEndFileHandler->loadFile($args);
}
@ -2419,7 +2418,7 @@ class Context
/**
* Remove all content added by addHtmlHeader()
*
*
* @return void
*/
public static function clearHtmlHeader()
@ -2544,7 +2543,7 @@ class Context
/**
* Set a validator message
*
*
* @param string $id
* @param string $message
* @param string $type (optional)
@ -2601,7 +2600,7 @@ class Context
/**
* Check whether an addon, layout, module, or widget is distributed with Rhymix core.
*
*
* @param string $plugin_name
* @param string $type
* @return bool
@ -2616,13 +2615,13 @@ class Context
self::$_default_plugins = array();
}
}
return isset(self::$_default_plugins[$type][$plugin_name]);
}
/**
* Check whether an addon, module, or widget is blacklisted
*
*
* @param string $plugin_name
* @param string $type
* @return bool
@ -2637,7 +2636,7 @@ class Context
self::$_blacklist = array();
}
}
if ($type)
{
return isset(self::$_blacklist[$type][$plugin_name]);
@ -2657,7 +2656,7 @@ class Context
/**
* Check whether a word is reserved in Rhymix
*
*
* @param string $word
* @return bool
*/
@ -2671,7 +2670,7 @@ class Context
self::$_reserved_words = array();
}
}
return isset(self::$_reserved_words[$word]);
}
@ -2734,7 +2733,7 @@ class Context
/**
* Get meta tag
*
*
* @param string $name (optional)
* @return array The list of meta tags
*/
@ -2744,7 +2743,7 @@ class Context
{
return isset(self::$_instance->meta_tags[$name]) ? self::$_instance->meta_tags[$name]['content'] : null;
}
$ret = array();
foreach(self::$_instance->meta_tags as $name => $content)
{
@ -2769,17 +2768,17 @@ class Context
'content' => self::replaceUserLang($content),
);
}
/**
* Get meta images
*
*
* @return array
*/
public static function getMetaImages()
{
return self::$_instance->meta_images;
}
/**
* Add meta image
*
@ -2805,10 +2804,10 @@ class Context
'height' => $height,
);
}
/**
* Get OpenGraph metadata
*
*
* @return array
*/
public static function getOpenGraphData()
@ -2824,10 +2823,10 @@ class Context
}
return $ret;
}
/**
* Add OpenGraph metadata
*
*
* @param string $name
* @param mixed $content
* @return void
@ -2846,10 +2845,10 @@ class Context
self::$_instance->opengraph_metadata[] = array($name, $content);
}
}
/**
* Set canonical URL
*
*
* @param string $url
* @return void
*/
@ -2858,10 +2857,10 @@ class Context
self::$_instance->canonical_url = escape($url, false);
self::addOpenGraphData('og:url', self::$_instance->canonical_url);
}
/**
* Get canonical URL
*
*
* @return string
*/
public static function getCanonicalURL()
@ -2869,5 +2868,3 @@ class Context
return self::$_instance->canonical_url;
}
}
/* End of file Context.class.php */
/* Location: ./classes/context/Context.class.php */

View file

@ -1,13 +1,9 @@
<?php
/* Copyright (C) NAVER <http://www.navercorp.com> */
/**
* @class DisplayHandler
* DisplayHandler
*
* @author NAVER (developers@xpressengine.com)
* DisplayHandler is responsible for displaying the execution result. \n
* Depending on the request type, it can display either HTML or XML content.\n
* Xml content is simple xml presentation of variables in oModule while html content
* is the combination of the variables of oModue and template files/.
*/
class DisplayHandler extends Handler
{
@ -57,7 +53,7 @@ class DisplayHandler extends Handler
{
$handler = new HTMLDisplayHandler();
}
// Handle error location info
if ($location = $oModule->get('rx_error_location'))
{
@ -151,16 +147,16 @@ class DisplayHandler extends Handler
print $output;
print $debug;
}
/**
* Get debug information.
*
*
* @return string
*/
public static function getDebugInfo(&$output = null)
{
// Check if debugging information has already been printed.
if (self::$debug_printed)
{
return;
@ -169,13 +165,13 @@ class DisplayHandler extends Handler
{
self::$debug_printed = 1;
}
// Check if debugging is enabled for this request.
if (!Rhymix\Framework\Debug::isEnabledForCurrentUser())
{
return;
}
// Do not display debugging information if there is no output.
$display_types = config('debug.display_type') ?: [];
if ($display_types && !is_array($display_types))
@ -186,7 +182,7 @@ class DisplayHandler extends Handler
{
return;
}
// Print debug information.
$debug_output = '';
$response_type = Context::getResponseMethod();
@ -234,7 +230,7 @@ class DisplayHandler extends Handler
}
}
}
switch ($response_type)
{
case 'HTML':
@ -293,7 +289,7 @@ class DisplayHandler extends Handler
}
}
}
return $debug_output;
}
@ -323,10 +319,10 @@ class DisplayHandler extends Handler
{
header("Content-Type: application/json; charset=UTF-8");
}
/**
* print a custom Content-Type header.
*
*
* @param string $content_type
* @return void
*/
@ -347,5 +343,3 @@ class DisplayHandler extends Handler
}
}
/* End of file DisplayHandler.class.php */
/* Location: ./classes/display/DisplayHandler.class.php */

View file

@ -1,5 +1,4 @@
<?php
/* Copyright (C) NAVER <http://www.navercorp.com> */
class HTMLDisplayHandler
{
@ -10,12 +9,12 @@ class HTMLDisplayHandler
public const JQUERY_V2_MIGRATE = '1.4.1';
public const JQUERY_V3 = '3.6.3';
public const JQUERY_V3_MIGRATE = '3.4.0';
/**
* Default viewport setting
*/
public const DEFAULT_VIEWPORT = 'width=device-width, initial-scale=1.0, user-scalable=yes';
/**
* Reserved scripts
*/
@ -37,12 +36,12 @@ class HTMLDisplayHandler
'@\beditor/skins/xpresseditor/js/xe_textarea\.(?:min\.)?js@' => 'editor/skins/ckeditor/js/xe_textarea.js',
'@/lang$@' => '/lang/lang.xml',
);
/**
* Image type information for SEO
*/
protected $_image_type = 'none';
/**
* Produce HTML compliant content given a module object.\n
* @param ModuleObject $oModule the module object
@ -171,7 +170,7 @@ class HTMLDisplayHandler
$GLOBALS['__layout_compile_elapsed__'] = microtime(true) - $start;
}
}
// Add OpenGraph and Twitter metadata
if (config('seo.og_enabled') && Context::get('module') !== 'admin')
{
@ -189,7 +188,7 @@ class HTMLDisplayHandler
$mobicon_url = $oAdminModel->getMobileIconUrl($site_module_info->domain_srl);
Context::set('favicon_url', $favicon_url);
Context::set('mobicon_url', $mobicon_url);
return $output;
}
@ -234,10 +233,10 @@ class HTMLDisplayHandler
$pattern = '/href=(["\'])(\?[^"\']+)/s';
$output = preg_replace($pattern, 'href=$1' . \RX_BASEURL . '$2', $output);
}
// prevent the 2nd request due to url(none) of the background-image
$output = preg_replace('/url\((["\']?)none(["\']?)\)/is', 'none', $output);
$INPUT_ERROR = Context::get('INPUT_ERROR');
if(is_array($INPUT_ERROR) && count($INPUT_ERROR))
{
@ -266,10 +265,10 @@ class HTMLDisplayHandler
$this->_loadDesktopJSCSS();
}
$output = $oTemplate->compile('./common/tpl', 'common_layout');
// replace the user-defined-language
$output = Context::replaceUserLang($output);
// remove template path comment tag
/*
if(!Rhymix\Framework\Debug::isEnabledForCurrentUser())
@ -420,7 +419,7 @@ class HTMLDisplayHandler
/**
* Add OpenGraph metadata tags.
*
*
* @return void
*/
function _addOpenGraphMetadata()
@ -455,14 +454,14 @@ class HTMLDisplayHandler
}
}
}
// Get existing metadata.
$og_data = array();
foreach (Context::getOpenGraphData() as $val)
{
$og_data[$val['property']] = $val['content'];
}
// Add basic metadata.
Context::addOpenGraphData('og:title', $permitted ? Context::getBrowserTitle() : lang('msg_not_permitted'));
Context::addOpenGraphData('og:site_name', Context::getSiteTitle());
@ -479,7 +478,7 @@ class HTMLDisplayHandler
Context::addOpenGraphData('og:description', $description);
Context::addMetaTag('description', $description);
}
// Add metadata about this page.
if (!isset($og_data['og:type']))
{
@ -506,7 +505,7 @@ class HTMLDisplayHandler
Context::addOpenGraphData('og:url', $canonical_url);
Context::setCanonicalURL($canonical_url);
}
// Add metadata about the locale.
$lang_type = Context::getLangType();
$locales = (include \RX_BASEDIR . 'common/defaults/locales.php');
@ -518,7 +517,7 @@ class HTMLDisplayHandler
{
Context::addOpenGraphData('og:locale:alternate', $locales[$oDocument->getLangCode()]);
}
// Add image.
if ($document_images = Context::getMetaImages())
{
@ -535,20 +534,20 @@ class HTMLDisplayHandler
usort($document_files, function($a, $b) {
return ord($b->cover_image) - ord($a->cover_image);
});
foreach ($document_files as $file)
{
if ($file->isvalid !== 'Y' || !preg_match('/\.(?:bmp|gif|jpe?g|png)$/i', $file->uploaded_filename))
{
continue;
}
list($width, $height) = @getimagesize($file->uploaded_filename);
if ($width < 100 && $height < 100)
{
continue;
}
$document_images[] = array('filepath' => $file->uploaded_filename, 'width' => $width, 'height' => $height);
break;
}
@ -560,7 +559,7 @@ class HTMLDisplayHandler
{
$document_images = null;
}
if ($document_images)
{
$first_image = array_first($document_images);
@ -584,7 +583,7 @@ class HTMLDisplayHandler
{
$this->_image_type = 'none';
}
// Add tags and hashtags for articles.
if ($page_type === 'article' && $permitted)
{
@ -596,7 +595,7 @@ class HTMLDisplayHandler
Context::addOpenGraphData('og:article:tag', $tag, false);
}
}
if (config('seo.og_extract_hashtags'))
{
$hashtags = $oDocument->getHashtags();
@ -608,17 +607,17 @@ class HTMLDisplayHandler
}
}
}
Context::addOpenGraphData('og:article:section', Context::replaceUserLang($current_module_info->browser_title));
}
// Add author name for articles.
if ($page_type === 'article' && $permitted && config('seo.og_use_nick_name'))
{
Context::addMetaTag('author', $oDocument->getNickName());
Context::addOpenGraphData('og:article:author', $oDocument->getNickName());
}
// Add datetime for articles.
if ($page_type === 'article' && $permitted && config('seo.og_use_timestamps'))
{
@ -626,17 +625,17 @@ class HTMLDisplayHandler
Context::addOpenGraphData('og:article:modified_time', $oDocument->getUpdate('c'));
}
}
/**
* Add Twitter metadata tags.
*
*
* @return void
*/
function _addTwitterMetadata()
{
$card_type = $this->_image_type === 'document' ? 'summary_large_image' : 'summary';
Context::addMetaTag('twitter:card', $card_type);
foreach(Context::getOpenGraphData() as $val)
{
if ($val['property'] === 'og:title')
@ -686,9 +685,9 @@ class HTMLDisplayHandler
$jquery_version = self::JQUERY_V2;
$jquery_migrate_version = self::JQUERY_V2_MIGRATE;
}
Context::loadFile(array('./common/css/rhymix.scss', '', '', -1600000000), true);
$original_file_list = array(
'plugins/jquery.migrate/jquery-migrate-' . $jquery_migrate_version . '.min.js',
'plugins/cookie/js.cookie.min.js',
@ -700,7 +699,7 @@ class HTMLDisplayHandler
'xml_handler.js',
'xml_js_filter.js',
);
if(config('view.minify_scripts') === 'none')
{
Context::loadFile(array('./common/js/jquery-' . $jquery_version . '.js', 'head', '', -1800000000), true);
@ -734,5 +733,3 @@ class HTMLDisplayHandler
}
}
}
/* End of file HTMLDisplayHandler.class.php */
/* Location: ./classes/display/HTMLDisplayHandler.class.php */

View file

@ -1,5 +1,4 @@
<?php
/* Copyright (C) NAVER <http://www.navercorp.com> */
class JSCallbackDisplayHandler
{
@ -21,5 +20,3 @@ class JSCallbackDisplayHandler
</script>', Context::getJSCallbackFunc(), json_encode($variables));
}
}
/* End of file JSCallback.class.php */
/* Location: ./classes/display/JSCallback.class.php */

View file

@ -1,5 +1,4 @@
<?php
/* Copyright (C) NAVER <http://www.navercorp.com> */
class JSONDisplayHandler
{
@ -14,14 +13,14 @@ class JSONDisplayHandler
$variables = $oModule->getVariables();
$variables['error'] = $oModule->getError();
$variables['message'] = $oModule->getMessage();
self::_convertCompat($variables, Context::getRequestMethod());
return json_encode($variables);
}
/**
* Convert arrays in a format that is compatible with XE.
*
*
* @param array $array
* @param string $compat_type
* @return array
@ -51,10 +50,10 @@ class JSONDisplayHandler
}
}
}
/**
* Check if an array only has numeric keys.
*
*
* @param array $array
* @return bool
*/
@ -74,5 +73,3 @@ class JSONDisplayHandler
return true;
}
}
/* End of file JSONDisplayHandler.class.php */
/* Location: ./classes/display/JSONDisplayHandler.class.php */

View file

@ -1,5 +1,4 @@
<?php
/* Copyright (C) NAVER <http://www.navercorp.com> */
class VirtualXMLDisplayHandler
{
@ -57,13 +56,11 @@ class VirtualXMLDisplayHandler
$html[] = ' parent.location.href = ' . json_encode($output->url) . ';';
$html[] = '}';
}
$html[] = '</script>';
$html[] = '</head><body></body></html>';
return join("\n", $html);
}
}
/* End of file VirtualXMLDisplayHandler.class.php */
/* Location: ./classes/display/VirtualXMLDisplayHandler.class.php */

View file

@ -1,5 +1,4 @@
<?php
/* Copyright (C) NAVER <http://www.navercorp.com> */
class XMLDisplayHandler
{
@ -26,7 +25,7 @@ class XMLDisplayHandler
/**
* produce XML code given variable object\n
* @param object $obj
* @param object $obj
* @return string
*/
function _makeXmlDoc($obj)
@ -63,5 +62,3 @@ class XMLDisplayHandler
}
}
/* End of file XMLDisplayHandler.class.php */
/* Location: ./classes/display/XMLDisplayHandler.class.php */

View file

@ -1,9 +1,7 @@
<?php
/* Copyright (C) NAVER <http://www.navercorp.com> */
/**
* Superclass of the edit component.
* Set up the component variables
* Superclass of the editor component.
*
* @class EditorHandler
* @author NAVER (developers@xpressengine.com)
@ -32,5 +30,3 @@ class EditorHandler extends BaseObject
}
}
/* End of file EditorHandler.class.php */
/* Location: ./classes/editor/EditorHandler.class.php */

View file

@ -1,5 +1,4 @@
<?php
/* Copyright (C) NAVER <http://www.navercorp.com> */
/**
* A class to handle extra variables used in posts, member and others
@ -45,7 +44,7 @@ class ExtraVar
/**
* Register a key of extra variable
*
*
* @param object[] $extra_keys Array of extra variable. A value of array is object that contains module_srl, idx, name, default, desc, is_required, search, value, eid.
* @return void
*/
@ -359,13 +358,13 @@ class ExtraItem
return $country_name;
case 'textarea' :
return nl2br($value);
case 'date' :
return $value ? sprintf('%s-%s-%s', substr($value, 0, 4), substr($value, 4, 2), substr($value, 6, 2)) : '';
case 'language':
return Rhymix\Framework\Lang::getSupportedList()[$value]['name'];
case 'timezone':
return Rhymix\Framework\DateTime::getTimezoneList()[$value];
case 'checkbox' :
@ -480,7 +479,7 @@ class ExtraItem
{
$selected = ' selected="selected"';
}
$buff[] = ' <option value="' . $lang_type . '" ' . $selected . '>' . $supported_lang[$lang_type]['name'] . '</option>';
}
$buff[] = '</select>';
@ -560,7 +559,7 @@ class ExtraItem
Context::loadJavascriptPlugin('ui.datepicker');
$formattedValue = $value ? sprintf('%s-%s-%s', substr($value, 0, 4), substr($value, 4, 2), substr($value, 6, 2)) : '';
$buff[] = '<input type="hidden" class="rx_ev_date" name="' . $column_name . '" value="' . $value . '" />';
$buff[] = '<input type="hidden" class="rx_ev_date" name="' . $column_name . '" value="' . $value . '" />';
$buff[] = '<input type="text" id="date_' . $column_name . '" value="' . $formattedValue . '" class="date" autocomplete="off" />';
$buff[] = '<input type="button" value="' . lang('cmd_delete') . '" class="btn" id="dateRemover_' . $column_name . '" />';
$buff[] = '<script type="text/javascript">';
@ -600,10 +599,8 @@ class ExtraItem
{
$buff[] = '<p>' . escape(Context::replaceUserLang($this->desc), false) . '</p>';
}
return join("\n", $buff);
}
}
/* End of file ExtraVar.class.php */
/* Location: ./classes/extravar/ExtraVar.class.php */

View file

@ -1,5 +1,4 @@
<?php
/* Copyright (C) NAVER <http://www.navercorp.com> */
/**
* Contains methods for accessing file system
@ -152,7 +151,7 @@ class FileHandler
{
return array();
}
$output = array();
foreach ($list as $filename)
{
@ -290,12 +289,12 @@ class FileHandler
'verify' => \RX_BASEDIR . 'common/vendor/composer/ca-bundle/res/cacert.pem',
'timeout' => $timeout,
);
foreach($headers as $key => $val)
{
$request_headers[$key] = $val;
}
if(isset($cookies[$host]) && is_array($cookies[$host]))
{
foreach($cookies[$host] as $key => $val)
@ -307,17 +306,17 @@ class FileHandler
{
$request_headers['Cookie'] = implode('; ', $request_cookies);
}
foreach($request_config as $key => $val)
{
$request_options[$key] = $val;
}
if($content_type)
{
$request_headers['Content-Type'] = $content_type;
}
if(defined('__PROXY_SERVER__'))
{
$proxy = parse_url(__PROXY_SERVER__);
@ -331,7 +330,7 @@ class FileHandler
}
}
}
$url = str_replace('&amp;', '&', $url);
$start_time = microtime(true);
$response = Requests::request($url, $request_headers, $body ?: $post_data, $method, $request_options);
@ -341,12 +340,12 @@ class FileHandler
$GLOBALS['__remote_request_elapsed__'] = 0;
}
$GLOBALS['__remote_request_elapsed__'] += $elapsed_time;
$log = array();
$log['url'] = $url;
$log['status'] = $response ? $response->status_code : 0;
$log['elapsed_time'] = $elapsed_time;
if (Rhymix\Framework\Debug::isEnabledForCurrentUser())
{
if (in_array('slow_remote_requests', config('debug.display_content')))
@ -373,12 +372,12 @@ class FileHandler
}
Rhymix\Framework\Debug::addRemoteRequest($log);
}
foreach($response->cookies as $cookie)
{
$cookies[$host][$cookie->name] = $cookie->value;
}
if($response->success)
{
if (isset($request_config['filename']))
@ -420,7 +419,7 @@ class FileHandler
{
return false;
}
$request_config['filename'] = $target_filename;
$success = self::getRemoteResource($url, $body, $timeout, $method, $content_type, $headers, $cookies, $post_data, $request_config);
return $success ? true : false;
@ -487,7 +486,7 @@ class FileHandler
/**
* Check if image needs rotation
*
*
* @param string $filename
* @return int|bool 0, 90, 180, 360, or false
*/
@ -571,7 +570,7 @@ class FileHandler
6 => 'bmp',
18 => 'webp',
);
$type = isset($typemap[$type]) ? $typemap[$type] : null;
if (!$type)
{
@ -583,13 +582,13 @@ class FileHandler
{
$target_type = 'jpg';
}
// Automatically set resize_height if it is 'auto'
if ($resize_height === 'auto')
{
$resize_height = round($resize_width / ($width / $height));
}
// create temporary image having original type
if ($type === 'gif' && function_exists('imagecreatefromgif'))
{
@ -654,7 +653,7 @@ class FileHandler
imagefilledrectangle($thumb, 0, 0, $resize_width - 1, $resize_height - 1, imagecolorallocate($thumb, 255, 255, 255));
}
}
// Resize the original image and copy it to a temporary image
if ($resize_needed)
{
@ -663,7 +662,7 @@ class FileHandler
$ratio_y = ($resize_height > 0 && $height > 0) ? $resize_height / $height : 1;
$ratio_max = max($ratio_x, $ratio_y);
$ratio_min = min($ratio_x, $ratio_y);
// Determine the X-Y coordinates to copy
if ($thumbnail_type === 'stretch')
{
@ -690,16 +689,16 @@ class FileHandler
$dst_width = round($width * min(1, $ratio_max));
$dst_height = round($height * min(1, $ratio_max));
}
// Adjust for small margins of error
if (abs($resize_width - $dst_width) < ($resize_width * 0.02)) $dst_width = $resize_width;
if (abs($resize_height - $dst_height) < ($resize_height * 0.02)) $dst_height = $resize_height;
$dst_x = round(($resize_width - $dst_width) / 2);
$dst_y = round(($resize_height - $dst_height) / 2);
imagecopyresampled($thumb, $source, $dst_x, $dst_y, 0, 0, $dst_width, $dst_height, $width, $height);
}
// create directory
self::makeDir(dirname($target_file));
@ -728,7 +727,7 @@ class FileHandler
{
return false;
}
imagedestroy($thumb);
imagedestroy($source);
@chmod($target_file, 0666 & ~Rhymix\Framework\Storage::getUmask());
@ -748,7 +747,7 @@ class FileHandler
{
return false;
}
$arr = parse_ini_file($filename, true);
return is_array($arr) ? $arr : array();
}
@ -876,7 +875,7 @@ class FileHandler
/**
* @deprecated
*
*
* Clears file status cache
*
* @param string|array $target filename or directory
@ -897,10 +896,10 @@ class FileHandler
}
}
}
/**
* @deprecated
*
*
* Invalidates a cached script of OPcache
*
* @param string|array $target filename or directory
@ -909,7 +908,7 @@ class FileHandler
public static function invalidateOpcache($target, $force = true)
{
static $opcache = null;
if($opcache === null)
{
$opcache = function_exists('opcache_invalidate');
@ -918,7 +917,7 @@ class FileHandler
{
return;
}
foreach(is_array($target) ? $target : array($target) as $target_item)
{
if(substr($target_item, -4) === '.php')
@ -932,6 +931,3 @@ class FileHandler
}
}
}
/* End of file FileHandler.class.php */
/* Location: ./classes/file/FileHandler.class.php */

View file

@ -1,8 +1,7 @@
<?php
/* Copyright (C) NAVER <http://www.navercorp.com> */
/**
* File abstraction class
* File abstraction class
*
* @author NAVER (developers@xpressengine.com)
*/
@ -28,10 +27,10 @@ class FileObject extends BaseObject
var $mode = "r";
/**
* Constructor
* Constructor
*
* @param string $path Path of target file
* @param string $mode File open mode
* @param string $mode File open mode
* @return void
*/
function __construct($path, $mode)
@ -43,10 +42,10 @@ class FileObject extends BaseObject
}
/**
* Append target file's content to current file
* Append target file's content to current file
*
* @param string $file_name Path of target file
* @return void
* @return void
*/
function append($file_name)
{
@ -62,7 +61,7 @@ class FileObject extends BaseObject
/**
* Check current file meets eof
*
* @return bool true: if eof. false: otherwise
* @return bool true: if eof. false: otherwise
*/
function feof()
{
@ -70,7 +69,7 @@ class FileObject extends BaseObject
}
/**
* Read from current file
* Read from current file
*
* @param int $size Size to read
* @return string Returns the read string or false on failure.
@ -81,7 +80,7 @@ class FileObject extends BaseObject
}
/**
* Write string to current file
* Write string to current file
*
* @param string $str String to write
* @return int Returns the number of bytes written, or false on error.
@ -144,7 +143,7 @@ class FileObject extends BaseObject
}
/**
* Close file
* Close file
*
* @return void
*/
@ -158,5 +157,3 @@ class FileObject extends BaseObject
}
}
/* End of file FileObject.class.php */
/* Location: ./classes/file/FileObject.class.php */

View file

@ -1,5 +1,4 @@
<?php
/* Copyright (C) NAVER <http://www.navercorp.com> */
/**
* Handle front end files
@ -12,7 +11,7 @@ class FrontEndFileHandler extends Handler
*/
public static $minify = null;
public static $concat = null;
/**
* Directory for minified, compiled, and concatenated CSS/JS assets.
*/
@ -93,11 +92,11 @@ class FrontEndFileHandler extends Handler
{
$args = array($args);
}
// Replace obsolete paths with current paths.
$args[0] = preg_replace(array_keys(HTMLDisplayHandler::$replacements), array_values(HTMLDisplayHandler::$replacements), $args[0]);
$isCommon = preg_match(HTMLDisplayHandler::$reservedCSS, $args[0]) || preg_match(HTMLDisplayHandler::$reservedJS, $args[0]);
// Prevent overwriting common scripts.
if(!isset($args[3]) || intval($args[3]) > -1500000000)
{
@ -113,7 +112,7 @@ class FrontEndFileHandler extends Handler
}
}
}
if (isset($args[2]) && preg_match('/IE/i', $args[2]))
{
$source_hint = '';
@ -127,7 +126,7 @@ class FrontEndFileHandler extends Handler
{
$source_hint = '';
}
$file = $this->getFileInfo($args[0], $args[2] ?? '', $args[1] ?? 'all', $args[4] ?? [], $isCommon);
$file->index = (int)($args[3] ?? 0);
@ -179,7 +178,7 @@ class FrontEndFileHandler extends Handler
protected function getFileInfo($fileName, $targetIe = '', $media = 'all', $vars = array(), $isCommon = false)
{
$pathInfo = pathinfo($fileName);
$file = new stdClass();
$file->fileName = $pathInfo['basename'];
$file->filePath = $this->_getAbsFileUrl($pathInfo['dirname'] ?? '');
@ -221,16 +220,16 @@ class FrontEndFileHandler extends Handler
$file->fileFullPath = $file->fileRealPath . '/' . $file->fileNameNoExt . '.' . $file->fileExtension;
}
}
// Do not minify common JS plugins
if (strpos($file->filePath, 'common/js/plugins') !== false)
{
$file->isMinified = true;
}
// Since Rhymix 2.1, targetIe is always empty
$file->targetIe = '';
// Process media attributes and generate the key
if($file->fileExtension == 'css' || $file->fileExtension == 'less' || $file->fileExtension == 'scss')
{
@ -244,10 +243,10 @@ class FrontEndFileHandler extends Handler
return $file;
}
/**
* Process CSS and JS file
*
*
* @param object $file
* @param bool $minify
* @return void
@ -258,11 +257,11 @@ class FrontEndFileHandler extends Handler
{
return;
}
$minifiedFileName = $file->fileNameNoExt . '.min.' . $file->fileExtension;
$minifiedFileHash = ltrim(str_replace(array('/', '\\'), '.', substr($file->fileRealPath, strlen(\RX_BASEDIR))), '.');
$minifiedFilePath = \RX_BASEDIR . self::$assetdir . '/minified/' . $minifiedFileHash . '.' . $minifiedFileName;
if (!file_exists($minifiedFilePath) || filemtime($minifiedFilePath) < filemtime($file->fileFullPath))
{
$method_name = 'minify' . $file->fileExtension;
@ -272,7 +271,7 @@ class FrontEndFileHandler extends Handler
return;
}
}
$file->fileName = $minifiedFileHash . '.' . $minifiedFileName;
$file->filePath = \RX_BASEURL . self::$assetdir . '/minified';
$file->fileRealPath = \RX_BASEDIR . self::$assetdir . '/minified';
@ -281,10 +280,10 @@ class FrontEndFileHandler extends Handler
$file->cdnPath = './' . self::$assetdir . '/minified';
$file->isMinified = true;
}
/**
* Process LESS and SCSS file
*
*
* @param object $file
* @param bool $minify
* @return void
@ -295,7 +294,7 @@ class FrontEndFileHandler extends Handler
{
return;
}
$default_font_config = Context::get('default_font_config') ?: EditorModel::$default_font_config;
$file->vars['enable_xe_btn_styles'] = (defined('DISABLE_XE_BTN_STYLES') && DISABLE_XE_BTN_STYLES) ? 'false' : 'true';
$file->vars['enable_xe_msg_styles'] = (defined('DISABLE_XE_MSG_STYLES') && DISABLE_XE_MSG_STYLES) ? 'false' : 'true';
@ -306,14 +305,14 @@ class FrontEndFileHandler extends Handler
return preg_match('/^[0-9a-zA-Z\.%_-]+$/', $str) ? $str : ('~"' . str_replace('"', '\\"', $str) . '"');
}, $file->vars);
}
$compiledFileName = $file->fileName . ($minify ? '.min' : '') . '.css';
$compiledFileHash = sha1($file->fileRealPath . ':' . serialize($file->vars));
$compiledFilePath = \RX_BASEDIR . self::$assetdir . '/compiled/' . $compiledFileHash . '.' . $compiledFileName;
$importedFileName = $file->fileName . ($minify ? '.min' : '') . '.imports.php';
$importedFilePath = \RX_BASEDIR . self::$assetdir . '/compiled/' . $compiledFileHash . '.' . $importedFileName;
if (!file_exists($compiledFilePath))
{
$recompile = 1;
@ -346,13 +345,13 @@ class FrontEndFileHandler extends Handler
}
}
}
if ($recompile)
{
$method_name = 'compile' . $file->fileExtension;
Rhymix\Framework\Formatter::$method_name($file->fileFullPath, $compiledFilePath, $file->vars, $minify);
}
$file->fileName = $compiledFileHash . '.' . $compiledFileName;
$file->filePath = \RX_BASEURL . self::$assetdir . '/compiled';
$file->fileRealPath = \RX_BASEDIR . self::$assetdir . '/compiled';
@ -434,7 +433,7 @@ class FrontEndFileHandler extends Handler
$minify = self::$minify !== null ? self::$minify : (config('view.minify_scripts') ?: 'common');
$concat = strpos(self::$concat !== null ? self::$concat : config('view.concat_scripts'), 'css') !== false;
$this->_sortMap($map, $mapIndex);
// Minify all scripts, and compile LESS/SCSS into CSS.
if ($finalize)
{
@ -454,7 +453,7 @@ class FrontEndFileHandler extends Handler
}
}
}
// Add all files to the final result.
$result = array();
if ($concat && $finalize && count($concat_list = $this->_concatMap($map)))
@ -507,7 +506,7 @@ class FrontEndFileHandler extends Handler
}
}
}
// Enable HTTP/2 server push for CSS resources.
if ($finalize && $this->_isServerPushEnabled())
{
@ -541,11 +540,11 @@ class FrontEndFileHandler extends Handler
$map = &$this->jsBodyMap;
$mapIndex = &$this->jsBodyMapIndex;
}
$minify = self::$minify !== null ? self::$minify : (config('view.minify_scripts') ?: 'common');
$concat = strpos(self::$concat !== null ? self::$concat : config('view.concat_scripts'), 'js') !== false;
$this->_sortMap($map, $mapIndex);
// Minify all scripts.
if ($finalize)
{
@ -560,7 +559,7 @@ class FrontEndFileHandler extends Handler
}
}
}
// Add all files to the final result.
$result = array();
if ($concat && $finalize && $type === 'head' && count($concat_list = $this->_concatMap($map)))
@ -611,7 +610,7 @@ class FrontEndFileHandler extends Handler
}
}
}
// Enable HTTP/2 server push for JS resources.
if ($type === 'head' && $finalize && $this->_isServerPushEnabled())
{
@ -625,10 +624,10 @@ class FrontEndFileHandler extends Handler
}
return $result;
}
/**
* Create a concatenation map, skipping external URLs and unreadable scripts.
*
*
* @param array $map
* @return array
*/
@ -654,7 +653,7 @@ class FrontEndFileHandler extends Handler
}
return $concat_list;
}
/**
* Sort a map
*
@ -724,7 +723,7 @@ class FrontEndFileHandler extends Handler
{
return;
}
if ($hint)
{
$tmp = $hint;
@ -744,10 +743,10 @@ class FrontEndFileHandler extends Handler
$file->index += isset($cssSortList[$tmp]) ? $cssSortList[$tmp] : 0;
}
}
/**
* Check if server push is enabled.
*
*
* @return bool
*/
protected function _isServerPushEnabled()
@ -770,5 +769,3 @@ class FrontEndFileHandler extends Handler
}
}
}
/* End of file FrontEndFileHandler.class.php */
/* Location: ./classes/frontendfile/FrontEndFileHandler.class.php */

View file

@ -1,8 +1,7 @@
<?php
/* Copyright (C) NAVER <http://www.navercorp.com> */
/**
* An abstract class of (*)Handler
* An abstract class of (*)Handler
*
* @author NAVER (developers@xpressengine.com)
*/
@ -10,5 +9,3 @@ class Handler
{
}
/* End of file Handler.class.php */
/* Location: ./classes/handler/Handler.class.php */

View file

@ -1,5 +1,4 @@
<?php
/* Copyright (C) NAVER <http://www.navercorp.com> */
/**
* - HttpRequest class
@ -26,7 +25,7 @@ class XEHttpRequest
var $m_port;
/**
* target scheme
* target scheme
* @var string
*/
var $m_scheme;
@ -255,5 +254,3 @@ class XEHttpRequest
}
}
/* End of file XEHttpRequest.class.php */
/* Location: ./classes/httprequest/XEHttpRequest.class.php */

View file

@ -2,8 +2,6 @@
/**
* Mail class for XE Compatibility
*
* @author Kijin Sung <kijin@kijinsung.com>
*/
class Mail extends Rhymix\Framework\Mail
{
@ -18,7 +16,7 @@ class Mail extends Rhymix\Framework\Mail
{
self::useSMTP(null, 'smtp.gmail.com', $account_name, $account_passwd, 'ssl', 465);
}
/**
* Set parameters for using SMTP protocol
*
@ -41,7 +39,7 @@ class Mail extends Rhymix\Framework\Mail
'smtp_pass' => $pass,
)));
}
/**
* Set additional parameters
*/
@ -49,7 +47,7 @@ class Mail extends Rhymix\Framework\Mail
{
// no-op
}
/**
* Set the sender (From:).
*
@ -61,7 +59,7 @@ class Mail extends Rhymix\Framework\Mail
{
$this->setFrom($email, $name ?: null);
}
/**
* Get the sender.
*
@ -71,7 +69,7 @@ class Mail extends Rhymix\Framework\Mail
{
return $this->getFrom() ?: false;
}
/**
* Set Recipient (To:)
*
@ -84,7 +82,7 @@ class Mail extends Rhymix\Framework\Mail
$this->message->setTo(array());
return $this->addTo($email, $name ?: null);
}
/**
* Get Recipient (To:)
*
@ -95,7 +93,7 @@ class Mail extends Rhymix\Framework\Mail
$list = $this->getRecipients();
return $list ? array_first($list) : false;
}
/**
* Set BCC
*
@ -107,7 +105,7 @@ class Mail extends Rhymix\Framework\Mail
$this->message->setBcc(array());
return $this->addBcc($bcc);
}
/**
* Get the Plain content of body message
*
@ -117,17 +115,17 @@ class Mail extends Rhymix\Framework\Mail
{
return chunk_split(base64_encode(htmlspecialchars($this->message->getBody())));
}
/**
* Get the HTML content of body message
*
*
* @return string
*/
public function getHTMLContent()
{
return chunk_split(base64_encode($this->content_type != 'text/html' ? nl2br($this->message->getBody()) : $this->message->getBody()));
}
/**
* Add file attachment
*
@ -139,7 +137,7 @@ class Mail extends Rhymix\Framework\Mail
{
return $this->attach($original_filename, $filename);
}
/**
* Add content attachment
*
@ -151,7 +149,7 @@ class Mail extends Rhymix\Framework\Mail
{
return $this->embed($original_filename, $cid);
}
/**
* Process the images from attachments
*
@ -161,20 +159,20 @@ class Mail extends Rhymix\Framework\Mail
{
// no-op
}
/**
* Process the images from body content. This functions is used if Mailer is set as mail not as SMTP
*
*
* @return void
*/
public function procCidAttachments()
{
// no-op
}
/**
* Check if DNS of param is real or fake
*
*
* @param string $email_address Email address to check
* @return bool
*/
@ -198,20 +196,20 @@ class Mail extends Rhymix\Framework\Mail
}
return TRUE;
}
/**
* Check if this class supports Advanced Mailer features.
*
*
* @return bool
*/
public static function isAdvancedMailer()
{
return true;
}
/**
* Check if param is a valid email or not
*
*
* @param string $email_address Email address to check
* @return string
*/
@ -241,5 +239,3 @@ class Mail extends Rhymix\Framework\Mail
}
}
/* End of file Mail.class.php */
/* Location: ./classes/mail/Mail.class.php */

View file

@ -1,5 +1,4 @@
<?php
/* Copyright (C) NAVER <http://www.navercorp.com> */
/**
* Mobile class
@ -13,20 +12,20 @@ class Mobile
* @var bool
*/
protected static $_ismobile = null;
/**
* Get instance of Mobile class
*
*
* @return Mobile
*/
public function getInstance()
{
return new self();
}
/**
* Get current mobile mode
*
*
* @return bool
*/
public static function isFromMobilePhone()
@ -36,13 +35,13 @@ class Mobile
{
return self::$_ismobile;
}
// Not mobile if disabled explicitly.
if (!self::isMobileEnabled() || Context::get('full_browse') || ($_COOKIE['FullBrowse'] ?? 0))
{
return self::$_ismobile = false;
}
// Try to detect from URL arguments and cookies, and finally fall back to user-agent detection.
$m = Context::get('m');
$cookie = isset($_COOKIE['rx_uatype']) ? $_COOKIE['rx_uatype'] : null;
@ -55,7 +54,7 @@ class Mobile
{
$m = substr($cookie, -1);
}
if ($m === '1')
{
self::$_ismobile = TRUE;
@ -68,7 +67,7 @@ class Mobile
{
self::$_ismobile = Rhymix\Framework\UA::isMobile() && (config('mobile.tablets') || !Rhymix\Framework\UA::isTablet());
}
// Set cookie to prevent recalculation.
$uatype = $uahash . ':' . (self::$_ismobile ? '1' : '0');
if ($cookie !== $uatype)
@ -76,10 +75,10 @@ class Mobile
setcookie('rx_uatype', $uatype, 0, \RX_BASEURL, null, !!config('session.use_ssl_cookies'));
$_COOKIE['rx_uatype'] = $uatype;
}
return self::$_ismobile;
}
/**
* Get current mobile mode
*
@ -89,7 +88,7 @@ class Mobile
{
return self::isFromMobilePhone();
}
/**
* Detect mobile device by user agent
*
@ -109,7 +108,7 @@ class Mobile
{
return Rhymix\Framework\UA::isTablet();
}
/**
* Set mobile mode
*
@ -123,7 +122,7 @@ class Mobile
/**
* Check if mobile view is enabled
*
*
* @raturn bool
*/
public static function isMobileEnabled()

View file

@ -1,15 +1,10 @@
<?php
/* Copyright (C) NAVER <http://www.navercorp.com> */
/**
* @class ModuleHandler
* @author NAVER (developers@xpressengine.com)
* Handling modules
* ModuleHandler
*
* @remarks This class is to excute actions of modules.
* Constructing an instance without any parameterconstructor, it finds the target module based on Context.
* If there is no act on the found module, excute an action referencing action_forward.
* */
* @author NAVER (developers@xpressengine.com)
*/
class ModuleHandler extends Handler
{
var $method = 'GET';
@ -120,7 +115,7 @@ class ModuleHandler extends Handler
public function init()
{
$site_module_info = Context::get('site_module_info');
// Check unregistered domain action.
if (!$site_module_info || !isset($site_module_info->domain_srl) || ($site_module_info->is_default_replaced ?? false))
{
@ -133,17 +128,17 @@ class ModuleHandler extends Handler
case 'redirect_301':
header('Location: ' . Context::getDefaultUrl($site_module_info) . RX_REQUEST_URL, true, 301);
return false;
case 'redirect_302':
header('Location: ' . Context::getDefaultUrl($site_module_info) . RX_REQUEST_URL, true, 302);
return false;
case 'block':
$this->error = 'The site does not exist';
$this->error_detail = 'ERR_DOMAIN_NOT_FOUND';
$this->httpStatusCode = 404;
return true;
case 'display':
// pass
}
@ -160,7 +155,7 @@ class ModuleHandler extends Handler
Context::set($key, null);
}
}
// If the Router returned an error earlier, show an error here.
if($this->route && $this->route->status > 200)
{
@ -169,7 +164,7 @@ class ModuleHandler extends Handler
$this->httpStatusCode = 404;
return true;
}
// Convert document alias (entry) to document_srl
if(!$this->document_srl && $this->mid && $this->entry)
{
@ -193,7 +188,7 @@ class ModuleHandler extends Handler
{
$module_info = null;
}
// Get module info from mid.
if(!$module_info && $this->mid)
{
@ -219,7 +214,7 @@ class ModuleHandler extends Handler
header('location: ' . getNotEncodedSiteUrl($site_module_info->domain), true, 301);
return false;
}
// If module info was set, retrieve variables from the module information
if($module_info)
{
@ -228,7 +223,7 @@ class ModuleHandler extends Handler
$this->mid = $module_info->mid;
$this->module_info = $module_info;
$this->_setModuleSEOInfo($module_info, $site_module_info);
// Check if the current request is from a mobile device.
$this->is_mobile = Mobile::isFromMobilePhone();
$viewType = $this->is_mobile ? 'M' : 'P';
@ -257,7 +252,7 @@ class ModuleHandler extends Handler
// Reset layout_srl in module_info.
$module_info->{$targetSrl} = $layoutSrl;
// Add layout header script.
$part_config = ModuleModel::getModulePartConfig('layout', $layoutSrl);
Context::addHtmlHeader($part_config->header_script);
@ -270,7 +265,7 @@ class ModuleHandler extends Handler
}
$this->_setModuleColorScheme($site_module_info);
// Always overwrite site_srl (deprecated)
$this->module_info->site_srl = $site_module_info->site_srl;
@ -288,7 +283,7 @@ class ModuleHandler extends Handler
{
Context::set('mid', $this->mid, TRUE);
}
// Call a trigger after moduleHandler init
$output = self::triggerCall('moduleHandler.init', 'after', $this->module_info);
if(!$output->toBool())
@ -376,7 +371,7 @@ class ModuleHandler extends Handler
return self::_createErrorMessage(-1, 'msg_security_violation', 403, 'ERR_CSRF_CHECK_FAILED');
}
}
// check if the current action allows standalone access (without mid)
if(isset($xml_info->action->{$this->act}))
{
@ -467,7 +462,7 @@ class ModuleHandler extends Handler
{
return self::_createErrorMessage(-1, 'msg_invalid_request', 403, 'ERR_NOT_FORWARDABLE');
}
// 1. Look for the module with action name
if(preg_match('/^[a-z]+([A-Z][a-z0-9\_]+).*$/', $this->act, $matches))
{
@ -497,12 +492,12 @@ class ModuleHandler extends Handler
$forward->act = $this->act;
}
}
if(empty($forward->module))
{
$forward = ModuleModel::getActionForward($this->act);
}
if(!empty($forward->module))
{
$kind = (stripos($forward->act, 'admin') !== false || stripos($forward->class_name, 'admin') !== false) ? 'admin' : '';
@ -514,9 +509,9 @@ class ModuleHandler extends Handler
{
Context::addMetaTag('robots', 'noindex');
}
$xml_info = ModuleModel::getModuleActionXml($forward->module);
// Protect admin action
if(($this->module == 'admin' || $kind == 'admin') && !ModuleModel::getGrant($forward, $logged_info)->root)
{
@ -525,7 +520,7 @@ class ModuleHandler extends Handler
return self::_createErrorMessage(-1, 'admin.msg_is_not_administrator');
}
}
// SECISSUE also check REQUEST_METHOD for forwarded actions
$allowedMethodList = explode('|', $xml_info->action->{$this->act}->method);
if(!in_array($_SERVER['REQUEST_METHOD'], $allowedMethodList))
@ -541,7 +536,7 @@ class ModuleHandler extends Handler
return self::_createErrorMessage(-1, 'msg_security_violation', 403, 'ERR_CSRF_CHECK_FAILED');
}
}
if($forward->class_name)
{
$class_fullname = sprintf('Rhymix\\Modules\\%s\\%s', $forward->module, $forward->class_name);
@ -572,12 +567,12 @@ class ModuleHandler extends Handler
{
$oModule = self::getModuleInstance($forward->module, $type, $kind);
}
if(!is_object($oModule))
{
return self::_createErrorMessage(-1, 'msg_module_class_not_found', 404);
}
// Admin page layout
if($this->module == 'admin' && $type == 'view' && $this->act != 'dispLayoutAdminLayoutModify')
{
@ -598,7 +593,7 @@ class ModuleHandler extends Handler
return $oModule;
}
}
// ruleset check...
if(!empty($ruleset))
{
@ -668,11 +663,11 @@ class ModuleHandler extends Handler
$domain_info = Context::get('site_module_info');
if ($domain_info && $domain_info->settings && $domain_info->settings->html_header)
{
Context::addHtmlHeader($domain_info->settings->html_header);
Context::addHtmlHeader($domain_info->settings->html_header);
}
if ($domain_info && $domain_info->settings && $domain_info->settings->html_footer)
{
Context::addHtmlFooter($domain_info->settings->html_footer);
Context::addHtmlFooter($domain_info->settings->html_footer);
}
if ($domain_info && $domain_info->settings && $domain_info->settings->title)
{
@ -737,7 +732,7 @@ class ModuleHandler extends Handler
/**
* Check the value of $document_srl. This method is called during init().
*
*
* @return object|false
*/
protected function _checkDocumentSrl()
@ -773,14 +768,14 @@ class ModuleHandler extends Handler
Context::set('mid', $this->mid);
}
}
// Remove module info if a different module has already been selected for the current request.
if($this->module && $module_info->module !== $this->module)
{
$module_info = null;
}
}
// Block access to secret or temporary documents.
if(Context::getRequestMethod() === 'GET')
{
@ -794,14 +789,14 @@ class ModuleHandler extends Handler
$this->httpStatusCode = 403;
}
}
// Return the module info for further processing.
return $module_info;
}
/**
* Set color scheme.
*
*
* @param object $site_module_info
*/
protected function _setModuleColorScheme($site_module_info)
@ -820,10 +815,10 @@ class ModuleHandler extends Handler
Context::addBodyClass('color_scheme_' . $color_scheme);
}
}
/**
* Set SEO information to Context.
*
*
* @param object $module_info
* @param object $site_module_info
*/
@ -845,7 +840,7 @@ class ModuleHandler extends Handler
'subpage_title' => $module_info->browser_title,
'page' => Context::get('page') ?: 1,
));
// Set meta keywords.
$module_config = ModuleModel::getModuleConfig('module');
if (!empty($module_info->meta_keywords))
@ -860,7 +855,7 @@ class ModuleHandler extends Handler
{
Context::addMetaTag('keywords', $module_config->meta_keywords);
}
// Set meta description.
if (!empty($module_info->meta_description))
{
@ -875,10 +870,10 @@ class ModuleHandler extends Handler
Context::addMetaTag('description', $module_config->meta_description);
}
}
/**
* Save input values to session so that they can be recovered after returning to the previous form.
*
*
* @return void
*/
protected static function _setInputValueToSession()
@ -893,7 +888,7 @@ class ModuleHandler extends Handler
/**
* Get previous error information and restore it to Context so that it is available to templates.
*
*
* @return void
*/
protected static function _setInputErrorToContext()
@ -905,7 +900,7 @@ class ModuleHandler extends Handler
'XE_VALIDATOR_ERROR',
'XE_VALIDATOR_RETURN_URL',
];
foreach ($keys as $key)
{
if (!Context::get($key))
@ -913,7 +908,7 @@ class ModuleHandler extends Handler
Context::set($key, empty($_SESSION[$key]) ? null : $_SESSION[$key]);
}
}
if (!empty($_SESSION['INPUT_ERROR']))
{
Context::set('INPUT_ERROR', $_SESSION['INPUT_ERROR']);
@ -947,7 +942,7 @@ class ModuleHandler extends Handler
$caller = array_shift($backtrace);
$location = $caller['file'] . ':' . $caller['line'];
}
self::_setInputErrorToContext();
$oMessageObject = MessageView::getInstance();
$oMessageObject->setError($error);
@ -966,7 +961,7 @@ class ModuleHandler extends Handler
{
// Set the display mode for the current device type.
$this->is_mobile = Mobile::isFromMobilePhone();
// If the module is not set or not an object, set error
if(!$oModule || !is_object($oModule))
{
@ -1006,12 +1001,12 @@ class ModuleHandler extends Handler
$data['message'] = lang($oModule->message);
}
$data = array_merge($data, $oModule->getVariables());
ob_end_clean();
echo sprintf('<html><head></head><body><script>parent.XE.handleIframeResponse(%s, %s);</script></body></html>', json_encode(strval($_POST['_rx_ajax_form'])), json_encode($data));
return;
}
// Handle redirects.
if($oModule->getRedirectUrl())
{
@ -1038,7 +1033,7 @@ class ModuleHandler extends Handler
return;
}
}
// If error occurred, handle it
if($this->error)
{
@ -1050,7 +1045,7 @@ class ModuleHandler extends Handler
{
$oMessageObject->setTemplateFile('http_status_code');
}
// If module was called normally, change the templates of the module into ones of the message view module
if($oModule)
{
@ -1063,7 +1058,7 @@ class ModuleHandler extends Handler
{
$oModule = $oMessageObject;
}
self::_clearErrorSession();
}
@ -1118,7 +1113,7 @@ class ModuleHandler extends Handler
{
$oMenuAdminController = getAdminController('menu');
$homeMenuCacheFile = null;
foreach($layout_info->menu as $menu_id => $menu)
{ // No menu selected
if($menu->menu_srl == 0)
@ -1139,12 +1134,12 @@ class ModuleHandler extends Handler
{
include($homeMenuCacheFile);
}
$menu->xml_file = './files/cache/menu/' . $homeMenuSrl . '.xml.php';
$menu->php_file = './files/cache/menu/' . $homeMenuSrl . '.php';
$menu->menu_srl = $homeMenuSrl;
}
$php_file = FileHandler::exists($menu->php_file);
if(!$php_file)
{
@ -1156,7 +1151,7 @@ class ModuleHandler extends Handler
include($php_file);
}
}
Context::set($menu_id, $menu);
}
}
@ -1190,16 +1185,16 @@ class ModuleHandler extends Handler
}
}
}
// Set http status code
if($this->httpStatusCode && $oModule->getHttpStatusCode() === 200)
{
$oModule->setHttpStatusCode($this->httpStatusCode);
}
// Set http status message
self::_setHttpStatusMessage($oModule->getHttpStatusCode());
// Display contents
$oDisplayHandler = new DisplayHandler();
$oDisplayHandler->printContent($oModule);
@ -1264,7 +1259,7 @@ class ModuleHandler extends Handler
{
$triggers = array();
}
foreach($triggers as $item)
{
$module = $item->module;
@ -1289,13 +1284,13 @@ class ModuleHandler extends Handler
{
continue;
}
// do not call if module is blacklisted
if (Context::isBlacklistedPlugin($oModule->module))
{
continue;
}
try
{
$before_each_trigger_time = microtime(true);
@ -1310,7 +1305,7 @@ class ModuleHandler extends Handler
if ($trigger_name !== 'common.flushDebugInfo')
{
$trigger_target = $module . ($type === 'class' ? '' : $type) . '.' . $called_method;
if (Rhymix\Framework\Debug::isEnabledForCurrentUser())
{
Rhymix\Framework\Debug::addTrigger(array(
@ -1364,7 +1359,7 @@ class ModuleHandler extends Handler
{
$trigger_target = 'closure';
}
if (Rhymix\Framework\Debug::isEnabledForCurrentUser())
{
Rhymix\Framework\Debug::addTrigger(array(
@ -1472,5 +1467,3 @@ class ModuleHandler extends Handler
}
}
/* End of file ModuleHandler.class.php */
/* Location: ./classes/module/ModuleHandler.class.php */

View file

@ -1,10 +1,9 @@
<?php
/* Copyright (C) NAVER <http://www.navercorp.com> */
/**
* @class ModuleObject
* ModuleObject
*
* @author NAVER (developers@xpressengine.com)
* base class of ModuleHandler
*/
class ModuleObject extends BaseObject
{
@ -52,7 +51,7 @@ class ModuleObject extends BaseObject
/**
* Singleton
*
*
* @param string $module_hint (optional)
* @return static
*/
@ -97,7 +96,7 @@ class ModuleObject extends BaseObject
/**
* setter to set the name of module
*
*
* @param string $module name of module
* @return $this
*/
@ -109,7 +108,7 @@ class ModuleObject extends BaseObject
/**
* setter to set the name of module path
*
*
* @param string $path the directory path to a module directory
* @return $this
*/
@ -125,7 +124,7 @@ class ModuleObject extends BaseObject
/**
* setter to set an url for redirection
*
*
* @param string $url url for redirection
* @return $this
*/
@ -145,7 +144,7 @@ class ModuleObject extends BaseObject
/**
* get url for redirection
*
*
* @return string
*/
public function getRedirectUrl()
@ -157,7 +156,7 @@ class ModuleObject extends BaseObject
* Set the template path for refresh.html
* refresh.html is executed as a result of method execution
* Tpl as the common run of the refresh.html ..
*
*
* @deprecated
* @return $this
*/
@ -170,7 +169,7 @@ class ModuleObject extends BaseObject
/**
* Set the action name
*
*
* @param string $act
* @return $this
*/
@ -179,10 +178,10 @@ class ModuleObject extends BaseObject
$this->act = $act;
return $this;
}
/**
* Set module information
*
*
* @param object $module_info object containing module information
* @param object $xml_info object containing module description
* @return $this
@ -197,14 +196,14 @@ class ModuleObject extends BaseObject
$this->xml_info = $xml_info;
$this->skin_vars = $module_info->skin_vars ?? null;
$this->module_config = ModuleModel::getInstance()->getModuleConfig($this->module, $module_info->site_srl);
// Set privileges(granted) information
if($this->setPrivileges() !== true)
{
$this->stop('msg_not_permitted');
return;
}
// Set admin layout
if(preg_match('/^disp[A-Z][a-z0-9\_]+Admin/', $this->act))
{
@ -219,7 +218,7 @@ class ModuleObject extends BaseObject
$oTemplate->compile('modules/admin/tpl', '_admin_common.html');
}
}
// Execute init
if(method_exists($this, 'init'))
{
@ -235,10 +234,10 @@ class ModuleObject extends BaseObject
return $this;
}
/**
* Set privileges(granted) information of current user and check permission of current module
*
*
* @return bool
*/
public function setPrivileges()
@ -253,7 +252,7 @@ class ModuleObject extends BaseObject
{
return false;
}
// If value is not array
if(!is_array($check_module_srl))
{
@ -267,7 +266,7 @@ class ModuleObject extends BaseObject
$check_module_srl = array($check_module_srl);
}
}
// Check permission by privileges(granted) information for target module
foreach($check_module_srl as $target_srl)
{
@ -276,7 +275,7 @@ class ModuleObject extends BaseObject
{
return false;
}
// Check permission
if(!$this->checkPermission($grant, $this->user))
{
@ -286,13 +285,13 @@ class ModuleObject extends BaseObject
}
}
}
// If no privileges(granted) information, check permission by privileges(granted) information for current module
if(!isset($grant))
{
// Get privileges(granted) information of current user for current module
$grant = ModuleModel::getInstance()->getGrant($this->module_info, $this->user, $this->xml_info);
// Check permission
if(!$this->checkPermission($grant, $this->user))
{
@ -300,23 +299,23 @@ class ModuleObject extends BaseObject
return false;
}
}
// If member action, grant access for log-in, sign-up, member pages
if(preg_match('/^(disp|proc)(Member|Communication)[A-Z][a-zA-Z]+$/', $this->act))
{
$grant->access = true;
}
// Set privileges(granted) variables
$this->grant = $grant;
Context::set('grant', $grant);
return true;
}
/**
* Check permission
*
*
* @param object $grant privileges(granted) information of user
* @param object $member_info member information
* @return bool
@ -328,28 +327,28 @@ class ModuleObject extends BaseObject
{
$member_info = $this->user;
}
// Get privileges(granted) information of the member for current module
if(!$grant)
{
$grant = ModuleModel::getGrant($this->module_info, $member_info, $this->xml_info);
}
// If an administrator, Pass
if($grant->root)
{
return true;
}
// Get permission types(guest, member, manager, root) of the currently requested action
$permission = $this->xml_info->action->{$this->act}->permission->target ?: ($this->xml_info->permission->{$this->act} ?? null);
// If admin action, set default permission
if(empty($permission) && stripos($this->act, 'admin') !== false)
{
$permission = 'root';
}
// If permission is not or 'guest', Pass
if(empty($permission) || $permission == 'guest')
{
@ -370,7 +369,7 @@ class ModuleObject extends BaseObject
{
return true;
}
// If permission is '*-managers', search modules to find manager privilege of the member
if(Context::get('is_logged') && isset($type[2]))
{
@ -401,7 +400,7 @@ class ModuleObject extends BaseObject
else if($grant_names = explode(',', $permission))
{
$privilege_list = array_keys((array) $this->xml_info->grant);
foreach($grant_names as $name)
{
if(!in_array($name, $privilege_list) || !$grant->$name)
@ -409,16 +408,16 @@ class ModuleObject extends BaseObject
return false;
}
}
return true;
}
return false;
}
/**
* Stop processing this module instance.
*
*
* @param string $msg_code an error code
* @return ModuleObject $this
*/
@ -428,33 +427,33 @@ class ModuleObject extends BaseObject
{
// flag setting to stop the proc processing
$this->stop_proc = true;
// Error handling
$this->setError(-1);
$this->setMessage($msg_code);
// Get backtrace
$backtrace = debug_backtrace(false);
$caller = array_shift($backtrace);
$location = $caller['file'] . ':' . $caller['line'];
// Error message display by message module
$oMessageObject = MessageView::getInstance();
$oMessageObject->setError(-1);
$oMessageObject->setMessage($msg_code);
$oMessageObject->dispMessage('', $location);
$this->setTemplatePath($oMessageObject->getTemplatePath());
$this->setTemplateFile($oMessageObject->getTemplateFile());
$this->setHttpStatusCode($oMessageObject->getHttpStatusCode());
}
return $this;
}
/**
* set the file name of the template file
*
*
* @param string name of file
* @return $this
*/
@ -470,7 +469,7 @@ class ModuleObject extends BaseObject
/**
* retrieve the directory path of the template directory
*
*
* @return string
*/
public function getTemplateFile()
@ -480,7 +479,7 @@ class ModuleObject extends BaseObject
/**
* set the directory path of the template directory
*
*
* @param string path of template directory.
* @return $this
*/
@ -501,7 +500,7 @@ class ModuleObject extends BaseObject
/**
* retrieve the directory path of the template directory
*
*
* @return string
*/
public function getTemplatePath()
@ -511,7 +510,7 @@ class ModuleObject extends BaseObject
/**
* set the file name of the temporarily modified by admin
*
*
* @param string name of file
* @return $this
*/
@ -529,7 +528,7 @@ class ModuleObject extends BaseObject
/**
* retreived the file name of edited_layout_file
*
*
* @return string
*/
public function getEditedLayoutFile()
@ -539,7 +538,7 @@ class ModuleObject extends BaseObject
/**
* set the file name of the layout file
*
*
* @param string name of file
* @return $this
*/
@ -555,7 +554,7 @@ class ModuleObject extends BaseObject
/**
* get the file name of the layout file
*
*
* @return string
*/
public function getLayoutFile()
@ -565,7 +564,7 @@ class ModuleObject extends BaseObject
/**
* set the directory path of the layout directory
*
*
* @param string path of layout directory.
* @return $this
*/
@ -586,7 +585,7 @@ class ModuleObject extends BaseObject
/**
* set the directory path of the layout directory
*
*
* @return string
*/
public function getLayoutPath($layout_name = "", $layout_type = "P")
@ -605,7 +604,7 @@ class ModuleObject extends BaseObject
{
return FALSE;
}
// Check mobile status
$is_mobile = Mobile::isFromMobilePhone();
@ -623,7 +622,7 @@ class ModuleObject extends BaseObject
$oAddonController = AddonController::getInstance();
$addon_file = $oAddonController->getCacheFilePath($is_mobile ? "mobile" : "pc");
if(FileHandler::exists($addon_file)) include($addon_file);
// Check mobile status again, in case a trigger changed it
$is_mobile = Mobile::isFromMobilePhone();
@ -636,7 +635,7 @@ class ModuleObject extends BaseObject
$this->stop("msg_not_permitted_act");
return FALSE;
}
// Set module skin
if(isset($this->module_info->skin) && $this->module_info->module === $this->module && strpos($this->act, 'Admin') === false)
{
@ -645,7 +644,7 @@ class ModuleObject extends BaseObject
$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)
{
@ -669,12 +668,12 @@ class ModuleObject extends BaseObject
}
$this->setTemplatePath(sprintf('%s%s/%s', $this->module_path, $skin_dir, $module_skin));
}
// Set skin variable
ModuleModel::syncSkinInfoToModuleInfo($this->module_info);
Context::set('module_info', $this->module_info);
}
// Run
try
{
@ -756,10 +755,10 @@ class ModuleObject extends BaseObject
}
return TRUE;
}
/**
* Copy the response of another ModuleObject into this instance.
*
*
* @param self $instance
* @return void
*/
@ -769,14 +768,14 @@ class ModuleObject extends BaseObject
$this->error = $instance->getError();
$this->message = $instance->getMessage();
$this->httpStatusCode = $instance->getHttpStatusCode();
// Copy template settings.
$this->setTemplatePath($instance->getTemplatePath());
$this->setTemplateFile($instance->getTemplateFile());
$this->setLayoutPath($instance->getLayoutPath());
$this->setLayoutFile($instance->getLayoutFile());
$this->setEditedLayoutFile($instance->getEditedLayoutFile());
// Copy all other variables: redirect URL, message type, etc.
foreach ($instance->getVariables() as $key => $val)
{
@ -784,5 +783,3 @@ class ModuleObject extends BaseObject
}
}
}
/* End of file ModuleObject.class.php */
/* Location: ./classes/module/ModuleObject.class.php */

View file

@ -1,5 +1,4 @@
<?php
/* Copyright (C) NAVER <http://www.navercorp.com> */
/**
* Every module inherits from BaseObject class.
@ -44,7 +43,7 @@ class BaseObject
{
$this->setError($error);
$this->setMessage($message);
if ($error)
{
$backtrace = debug_backtrace(false);
@ -58,10 +57,10 @@ class BaseObject
$this->add('rx_error_location', $location);
}
}
/**
* Set state for var_export()
*
*
* @param array $vars
* @return object
*/
@ -94,7 +93,7 @@ class BaseObject
{
$this->error = -1;
}
// Convert the error message into the correct language and interpolate any other variables into it.
if(count($args))
{
@ -104,7 +103,7 @@ class BaseObject
$this->message = vsprintf($this->message, $args);
}
}
return $this;
}
@ -323,6 +322,3 @@ class BaseObject
return $this->toBool();
}
}
/* End of file Object.class.php */
/* Location: ./classes/object/Object.class.php */

View file

@ -1,41 +1,36 @@
<?php
/* Copyright (C) NAVER <http://www.navercorp.com> */
/**
* @class PageHandler
* @author NAVER (developers@xpressengine.com)
* handles page navigation
* @version 0.1
* PageHandler
*
* @remarks Getting total counts, number of pages, current page number, number of items per page,
* this class implements methods and contains variables for page navigation
* @author NAVER (developers@xpressengine.com)
*/
class PageHandler extends Handler implements Iterator
{
// Number of total items
public $total_count = 0;
// Number of total pages
public $total_page = 0;
// Current page number
public $cur_page = 0;
// Number of page links displayed at one time.
public $page_count = 10;
// First page number
public $first_page = 1;
// Last page number
public $last_page = 1;
// Stepper
public $point = 0;
/**
* Constructor
*
*
* @param int $total_count number of total items
* @param int $total_page number of total pages
* @param int $cur_page current page number
@ -71,7 +66,7 @@ class PageHandler extends Handler implements Iterator
/**
* Request next page
*
*
* @return int
*/
public function getNextPage(): int
@ -86,7 +81,7 @@ class PageHandler extends Handler implements Iterator
/**
* Return number of page that added offset.
*
*
* @param int $offset
* @return int
*/
@ -97,7 +92,7 @@ class PageHandler extends Handler implements Iterator
/**
* Rewind iterator stepper.
*
*
* @return void
*/
public function rewind(): void
@ -107,7 +102,7 @@ class PageHandler extends Handler implements Iterator
/**
* Determine if a current iterated item is valid.
*
*
* @return bool
*/
public function valid(): bool
@ -118,7 +113,7 @@ class PageHandler extends Handler implements Iterator
/**
* Get a current iterated page number.
*
*
* @return int
*/
public function current(): int
@ -128,7 +123,7 @@ class PageHandler extends Handler implements Iterator
/**
* Get a current iterator stepper.
*
*
* @return int
*/
public function key(): int
@ -138,7 +133,7 @@ class PageHandler extends Handler implements Iterator
/**
* Step up the iterator.
*
*
* @return void
*/
public function next(): void
@ -146,5 +141,3 @@ class PageHandler extends Handler implements Iterator
$this->point++;
}
}
/* End of file PageHandler.class.php */
/* Location: ./classes/page/PageHandler.class.php */

View file

@ -1,5 +1,4 @@
<?php
/* Copyright (C) NAVER <http://www.navercorp.com> */
class EmbedFilter
{
@ -14,68 +13,66 @@ class EmbedFilter
/**
* Return EmbedFilter object
*
*
* @return EmbedFilter
*/
function getInstance()
{
return new self();
}
public function getWhiteUrlList()
{
return Rhymix\Framework\Filters\MediaFilter::getObjectWhitelist();
}
public function getWhiteIframeUrlList()
{
return Rhymix\Framework\Filters\MediaFilter::getIframeWhitelist();
}
function isWhiteDomain($urlAttribute)
{
return Rhymix\Framework\Filters\MediaFilter::matchObjectWhitelist($urlAttribute);
}
function isWhiteIframeDomain($urlAttribute)
{
return Rhymix\Framework\Filters\MediaFilter::matchIframeWhitelist($urlAttribute);
}
function isWhiteMimetype($mimeType)
{
return true;
}
function isWhiteExt($ext)
{
return true;
}
function check(&$content)
{
// This functionality has been moved to the HTMLFilter class.
}
function checkIframeTag(&$content)
{
// This functionality has been moved to the HTMLFilter class.
}
function checkObjectTag(&$content)
{
// This functionality has been moved to the HTMLFilter class.
}
function checkEmbedTag(&$content)
{
// This functionality has been moved to the HTMLFilter class.
}
function checkParamTag(&$content)
{
// This functionality has been moved to the HTMLFilter class.
}
}
/* End of file : EmbedFilter.class.php */
/* Location: ./classes/security/EmbedFilter.class.php */

View file

@ -1,5 +1,4 @@
<?php
/* Copyright (C) NAVER <http://www.navercorp.com> */
class IpFilter
{
@ -8,13 +7,10 @@ class IpFilter
if(!$ip) $ip = \RX_CLIENT_IP;
return Rhymix\Framework\Filters\IpFilter::inRanges($ip, $ip_list);
}
public static function validate($ip_list = array())
{
return Rhymix\Framework\Filters\IpFilter::validateRanges($ip_list);
}
}
/* End of file : IpFilter.class.php */
/* Location: ./classes/security/IpFilter.class.php */
}

View file

@ -1,5 +1,4 @@
<?php
/* Copyright (C) NAVER <http://www.navercorp.com> */
class Password
{
@ -58,22 +57,22 @@ class Password
{
return Rhymix\Framework\Password::getRandomPassword($length);
}
public static function createSignature($string)
{
return Rhymix\Framework\Security::createSignature($string);
}
public static function checkSignature($string, $signature)
{
return Rhymix\Framework\Security::verifySignature($string, $signature);
}
public static function getSecretKey()
{
return config('crypto.authentication_key');
}
public static function pbkdf2($password, $salt, $algorithm = 'sha256', $iterations = 8192, $length = 24)
{
$hash = Rhymix\Framework\Security::pbkdf2($password, $salt, $algorithm, $iterations, $length);
@ -91,5 +90,3 @@ class Password
return Rhymix\Framework\Security::compareStrings($a, $b);
}
}
/* End of file : Password.class.php */
/* Location: ./classes/security/Password.class.php */

View file

@ -1,5 +1,4 @@
<?php
/* Copyright (C) NAVER <http://www.navercorp.com> */
class Purifier
{
@ -7,12 +6,10 @@ class Purifier
{
return new self();
}
public function purify(&$content)
{
$content = Rhymix\Framework\Filters\HTMLFilter::clean($content);
}
}
/* End of file : Purifier.class.php */
/* Location: ./classes/security/Purifier.class.php */

View file

@ -1,12 +1,9 @@
<?php
/* Copyright (C) NAVER <http://www.navercorp.com> */
/**
* - Security class
* - This class helps to solve security problems.
* Security class
*
* @author NAVER (developers@xpressengine.com)
* @package /classes/security
* @version 0.1
*/
class Security
{
@ -188,5 +185,3 @@ class Security
return !Rhymix\Framework\Security::checkXXE($xml);
}
}
/* End of file : Security.class.php */
/* Location: ./classes/security/Security.class.php */

View file

@ -4,7 +4,7 @@ class UploadFileFilter
{
/**
* Generic checker
*
*
* @param string $file
* @param string $filename
* @return bool
@ -16,7 +16,7 @@ class UploadFileFilter
{
return false;
}
// Don't check partial uploads (chunks).
if (Context::get('act') === 'procFileUpload' && preg_match('!^bytes (\d+)-(\d+)/(\d+)$!', $_SERVER['HTTP_CONTENT_RANGE']))
{
@ -27,6 +27,3 @@ class UploadFileFilter
return Rhymix\Framework\Filters\FileContentFilter::check($file, $filename);
}
}
/* End of file : UploadFileFilter.class.php */
/* Location: ./classes/security/UploadFileFilter.class.php */

View file

@ -1,13 +1,9 @@
<?php
/* Copyright (C) NAVER <http://www.navercorp.com> */
/**
* @class TemplateHandler
* Template compiler
*
* @author NAVER (developers@xpressengine.com)
* template compiler
* @version 0.1
* @remarks It compiles template file by using regular expression into php
* code, and XE caches compiled code for further uses
*/
class TemplateHandler
{
@ -21,7 +17,7 @@ class TemplateHandler
private $skipTags = NULL;
private $handler_mtime = 0;
private static $rootTpl = NULL;
/**
* Context variables accessible as $this in template files
*/
@ -66,7 +62,7 @@ class TemplateHandler
/**
* Reset all instance properties to the default state.
*
*
* @return void
*/
protected function resetState()
@ -166,7 +162,7 @@ class TemplateHandler
}
$latest_mtime = max(filemtime($this->file), $this->handler_mtime);
// make compiled file
if(!file_exists($this->compiled_file) || filemtime($this->compiled_file) < $latest_mtime)
{
@ -180,14 +176,14 @@ class TemplateHandler
trigger_error($error_message, \E_USER_WARNING);
return escape($error_message);
}
$this->compiled_file = $tmpfilename;
}
}
Rhymix\Framework\Debug::addFilenameAlias($this->file, $this->compiled_file);
$output = $this->_fetch($this->compiled_file);
// delete tmpfile
if(isset($tmpfilename))
{
@ -326,7 +322,7 @@ class TemplateHandler
{
$autoform = true;
}
// form ruleset attribute move to hidden tag
if ($autoform && $matches[1])
{
@ -399,7 +395,7 @@ class TemplateHandler
$matches[1] = preg_replace('/no-(?:error-)?return-url="true"/i', '', $matches[1]);
}
}
array_shift($matches);
return implode('', $matches);
}
@ -415,28 +411,28 @@ class TemplateHandler
$__Context = Context::getAll();
$__Context->tpl_path = $this->path;
global $lang;
// Start the output buffer.
$__ob_level_before_fetch = ob_get_level();
ob_start();
// Include the compiled template.
include $filename;
// Fetch contents of the output buffer until the buffer level is the same as before.
$contents = '';
while (ob_get_level() > $__ob_level_before_fetch)
{
$contents .= ob_get_clean();
}
// Insert template path comment tag.
if(Rhymix\Framework\Debug::isEnabledForCurrentUser() && Context::getResponseMethod() === 'HTML' && !starts_with('<!DOCTYPE', $contents) && !starts_with('<?xml', $contents))
{
$sign = "\n" . '<!-- Template %s : ' . $this->web_path . $this->filename . ' -->' . "\n";
$contents = sprintf($sign, 'start') . $contents . sprintf($sign, 'end');
}
return $contents;
}
@ -525,11 +521,11 @@ class TemplateHandler
{
// list of self closing tags
$self_closing = array('area' => 1, 'base' => 1, 'basefont' => 1, 'br' => 1, 'hr' => 1, 'input' => 1, 'img' => 1, 'link' => 1, 'meta' => 1, 'param' => 1, 'frame' => 1, 'col' => 1);
$skip = $this->skipTags ? sprintf('(?!%s)', implode('|', $this->skipTags)) : '';
$split_regex = "@(</?{$skip}[a-zA-Z](?>[^<>{}\"]+|<!--.*?-->.*?<!--.*?end-->|{[^}]*}|\"(?>'.*?'|.)*?\"|.)*?>)@s";
$nodes = preg_split($split_regex, $buff, -1, PREG_SPLIT_DELIM_CAPTURE);
for($idx = 1, $node_len = count($nodes); $idx < $node_len; $idx+=2)
{
if(!($node = $nodes[$idx]))
@ -652,7 +648,7 @@ class TemplateHandler
{
return $m[0];
}
if($m[1][0] == '@')
{
$m[1] = self::_replaceVar(substr($m[1], 1));
@ -677,7 +673,7 @@ class TemplateHandler
{
$escape_option = $this->config->autoescape !== null ? 'auto' : 'noescape';
}
// Separate filters from variable.
if (preg_match('@^(.+?)(?<![|\s])((?:\|[a-z]{2}[a-z0-9_]+(?::.+)?)+)$@', $m[1], $mm))
{
@ -688,10 +684,10 @@ class TemplateHandler
{
$filters = array();
}
// Process the variable.
$var = self::_replaceVar($m[1]);
// Apply filters.
foreach ($filters as $filter)
{
@ -713,7 +709,7 @@ class TemplateHandler
{
$filter_option = null;
}
// Apply each filter.
switch ($filter)
{
@ -724,60 +720,60 @@ class TemplateHandler
case 'noescape':
$escape_option = $filter;
break;
case 'escapejs':
$var = "escape_js({$var})";
break;
case 'json':
$var = "json_encode({$var})";
break;
case 'strip':
case 'strip_tags':
$var = $filter_option ? "strip_tags({$var}, {$filter_option})" : "strip_tags({$var})";
break;
case 'trim':
$var = "trim({$var})";
break;
case 'urlencode':
$var = "rawurlencode({$var})";
break;
case 'lower':
$var = "strtolower({$var})";
break;
case 'upper':
$var = "strtoupper({$var})";
break;
case 'nl2br':
$var = $this->_applyEscapeOption($var, $escape_option);
$var = "nl2br({$var})";
$escape_option = 'noescape';
break;
case 'join':
$var = $filter_option ? "implode({$filter_option}, {$var})" : "implode(', ', {$var})";
break;
case 'date':
$var = $filter_option ? "getDisplayDateTime(ztime({$var}), {$filter_option})" : "getDisplayDateTime(ztime({$var}), 'Y-m-d H:i:s')";
break;
case 'format':
case 'number_format':
$var = $filter_option ? "number_format({$var}, {$filter_option})" : "number_format({$var})";
break;
case 'shorten':
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)
@ -791,13 +787,13 @@ class TemplateHandler
}
$escape_option = 'noescape';
break;
default:
$filter = escape_sqstr($filter);
$var = "'INVALID FILTER ({$filter})'";
}
}
// Apply the escape option and return.
return '<?php echo ' . $this->_applyEscapeOption($var, $escape_option) . ' ?>';
}
@ -1035,7 +1031,7 @@ class TemplateHandler
{
$str = "$str ?? ''";
}
switch($escape_option)
{
case 'escape':
@ -1089,10 +1085,10 @@ class TemplateHandler
return $path;
}
/**
* Check if a string seems to contain a variable.
*
*
* @param string $str
* @return bool
*/
@ -1103,7 +1099,7 @@ class TemplateHandler
/**
* Replace PHP variables of $ character
*
*
* @param string $php
* @return string
*/
@ -1113,12 +1109,12 @@ class TemplateHandler
{
return '';
}
// Replace variables that need to be enclosed in curly braces, using temporary entities to prevent double-replacement.
$php = preg_replace_callback('@(?<!\$__Context)->\$([a-z_][a-z0-9_]*)@i', function($matches) {
return '->' . self::_getTempEntityForChar('{') . '$__Context->' . $matches[1] . self::_getTempEntityForChar('}');
}, $php);
// Replace all other variables with Context attributes.
$php = preg_replace_callback('@(?<!::|\\\\|\$__Context->|(?<!eval\()\')\$([a-z_][a-z0-9_]*)@i', function($matches) {
if (preg_match('/^(?:GLOBALS|_SERVER|_COOKIE|_GET|_POST|_REQUEST|_SESSION|__Context|this|lang)$/', $matches[1]))
@ -1130,13 +1126,13 @@ class TemplateHandler
return '$__Context->' . $matches[1];
}
}, $php);
return $php;
}
/**
* Replace temporary entities to curly braces.
*
*
* @param string $str
* @return string
*/
@ -1147,10 +1143,10 @@ class TemplateHandler
'&#x1B;&#x7D;' => '}',
]);
}
/**
* Get the temporary entity for a character.
*
*
* @param string $char
* @return string
*/
@ -1159,5 +1155,3 @@ class TemplateHandler
return '&#x1B;&#x' . strtoupper(bin2hex($char)) . ';';
}
}
/* End of File: TemplateHandler.class.php */
/* Location: ./classes/template/TemplateHandler.class.php */

View file

@ -1,11 +1,9 @@
<?php
/* Copyright (C) NAVER <http://www.navercorp.com> */
/**
* Validator class
*
* @author NAVER (developers@xpressengine.com)
* @package /classes/validator
* @version 0.1
*/
class Validator
{
@ -133,7 +131,7 @@ class Validator
$rules = array();
$messages = array();
// custom rules
if(isset($xml->ruleset->customrules) && isset($xml->ruleset->customrules->rule))
{
@ -196,7 +194,7 @@ class Validator
{
$fieldsNames[$name] = $title;
}
unset($filter['name']);
// conditional statement
@ -832,10 +830,10 @@ class Validator
return "(function($,v){\nv=xe.getApp('validator')[0];if(!v)return;\n{$addrules}\nv.cast('ADD_FILTER',['{$ruleset}', {{$content}}]);\n{$messages}\n})(jQuery);";
}
/**
* Polyfill for create_function()
*
*
* @param mixed $value
* @param string $expression
* @return mixed
@ -853,5 +851,3 @@ class Validator
}
}
/* End of file Validator.class.php */
/* Location: ./classes/validator/Validator.class.php */

View file

@ -1,17 +1,11 @@
<?php
/* Copyright (C) NAVER <http://www.navercorp.com> */
/**
* @class WidgetHandler
* WidgetHandler
*
* @author NAVER (developers@xpressengine.com)
* @brief Handler class for widget execution
* @remark it is empty for now, it would be removed in the future
*/
class WidgetHandler
{
var $widget_path = '';
}
/* End of file WidgetHandler.class.php */
/* Location: ./classes/widget/WidgetHandler.class.php */

View file

@ -1,5 +1,4 @@
<?php
/* Copyright (C) NAVER <http://www.navercorp.com> */
/**
* GeneralXmlParser class
@ -102,5 +101,3 @@ class GeneralXmlParser
}
}
/* End of file GeneralXmlParser.class.php */
/* Location: ./classes/xml/GeneralXmlParser.class.php */

View file

@ -1,5 +1,4 @@
<?php
/* Copyright (C) NAVER <http://www.navercorp.com> */
/**
* XmlGenerator class
@ -72,5 +71,3 @@ class XmlGenerator
}
}
/* End of file XmlGenerator.class.php */
/* Location: ./classes/xml/XmlGenerator.class.php */

View file

@ -1,5 +1,4 @@
<?php
/* Copyright (C) NAVER <http://www.navercorp.com> */
/**
* filter class traslate xml content into javascript code
@ -70,7 +69,7 @@ class XmlJsFilter extends XeXmlParser
* Compiled js file
* @var string
*/
var $js_file = NULL; // /
var $js_file = NULL; // /
/**
* constructor
@ -424,5 +423,3 @@ class XmlJsFilter extends XeXmlParser
}
}
/* End of file XmlJsFilter.class.php */
/* Location: ./classes/xml/XmlJsFilter.class.php */

View file

@ -1,5 +1,4 @@
<?php
/* Copyright (C) NAVER <http://www.navercorp.com> */
/**
* XmlLangParser class
@ -275,5 +274,3 @@ class XmlLangParser extends XeXmlParser
}
}
/* End of file XmlLangParser.class.php */
/* Location: ./classes/xml/XmlLangParser.class.php */

View file

@ -1,5 +1,4 @@
<?php
/* Copyright (C) NAVER <http://www.navercorp.com> */
/**
* Xml_Node_ class
@ -26,7 +25,7 @@ class Xml_Node_
/**
* XmlParser class
* Class parsing a given xmlrpc request and creating a data object
* @remarks <pre>{
* @remarks <pre>{
* This class may drops unsupported xml lanuage attributes when multiple language attributes are given.
* For example, if 'xml:lang='ko, en, ch, jp..' is given in a xml file, only ko will be left ignoring all other language
* attributes when kor is only supported language. It seems to work fine now but we did not scrutinze any potential side effects,
@ -221,8 +220,8 @@ class XeXmlParser
}
/**
* Method to transfer values in an array to a data object
* @param array $arr data array
* Method to transfer values in an array to a data object
* @param array $arr data array
* @return Xml_Node_ object
*/
function _arrToAttrsObj($arr)
@ -245,6 +244,3 @@ if (!class_exists('XmlParser', false))
{
class_alias('XeXmlParser', 'XmlParser');
}
/* End of file XmlParser.class.php */
/* Location: ./classes/xml/XmlParser.class.php */

View file

@ -107,7 +107,7 @@ spl_autoload_register(function($class_name)
$filename2 = null;
$lang_plugin = null;
$lang_path = null;
// Try namespaced classes, legacy classes, and module classes.
if (preg_match('!^Rhymix/(Framework|Addons|Modules|Plugins|Themes|Widgets)/((\w+)/(?:\w+/)*)?(\w+)$!', $class_name, $matches))
{
@ -136,7 +136,7 @@ spl_autoload_register(function($class_name)
$lang_path = RX_BASEDIR . 'modules/' . $module . '/lang';
}
}
// Load the PHP file.
if ($filename1 && file_exists($filename1))
{
@ -146,7 +146,7 @@ spl_autoload_register(function($class_name)
{
include $filename2;
}
// Load the lang file for the plugin.
if ($lang_plugin)
{

View file

@ -12,25 +12,25 @@ class Cache
*/
protected static $_driver = null;
protected static $_driver_name = null;
/**
* The cache prefix.
*/
protected static $_prefix = null;
/**
* The default TTL.
*/
protected static $_ttl = 86400;
/**
* Cache group versions.
*/
protected static $_group_versions = array();
/**
* Initialize the cache system.
*
*
* @param array $config
* @return void
*/
@ -40,7 +40,7 @@ class Cache
{
$config = array($config);
}
if (isset($config['type']))
{
$driver_name = $config['type'];
@ -61,7 +61,7 @@ class Cache
$driver_name = null;
$class_name = null;
}
if ($class_name !== null && $driver_name !== 'file' && class_exists($class_name) && $class_name::isSupported())
{
self::$_driver = $class_name::getInstance($config);
@ -72,7 +72,7 @@ class Cache
self::$_driver = Drivers\Cache\Dummy::getInstance(array());
self::$_driver_name = 'dummy';
}
if (self::$_driver->prefix)
{
self::$_prefix = substr(sha1(\RX_BASEDIR), 0, 10) . ':' . \RX_VERSION . ':';
@ -81,13 +81,13 @@ class Cache
{
self::$_prefix = \RX_VERSION . ':';
}
return self::$_driver;
}
/**
* Get the list of supported cache drivers.
*
*
* @return array
*/
public static function getSupportedDrivers()
@ -104,20 +104,20 @@ class Cache
}
return $result;
}
/**
* Get the name of the currently enabled cache driver.
*
*
* @return string|null
*/
public static function getDriverName()
{
return self::$_driver_name;
}
/**
* Get the currently enabled cache driver, or a named driver with the given settings.
*
*
* @param string $name (optional)
* @param array $config (optional)
* @return object|null
@ -141,30 +141,30 @@ class Cache
}
}
}
/**
* Get the automatically generated cache prefix for this installation of Rhymix.
*
*
* @return object|null
*/
public static function getPrefix()
{
return self::$_prefix;
}
/**
* Get the default TTL.
*
*
* @return int
*/
public static function getDefaultTTL()
{
return self::$_ttl;
}
/**
* Set the default TTL.
*
*
* @param int $ttl
* @return void
*/
@ -172,12 +172,12 @@ class Cache
{
self::$_ttl = $ttl;
}
/**
* Get the value of a key.
*
*
* This method returns null if the key was not found.
*
*
* @param string $key
* @return mixed
*/
@ -192,14 +192,14 @@ class Cache
return null;
}
}
/**
* Set the value to a key.
*
*
* This method returns true on success and false on failure.
* $ttl is measured in seconds. If it is not given, the default TTL is used.
* $force is used to cache essential data when using the default driver.
*
*
* @param string $key
* @param mixed $value
* @param int $ttl (optional)
@ -226,13 +226,13 @@ class Cache
return false;
}
}
/**
* Delete a key.
*
*
* This method returns true on success and false on failure.
* If the key does not exist, it should return false.
*
*
* @param string $key
* @return bool
*/
@ -247,12 +247,12 @@ class Cache
return false;
}
}
/**
* Check if a key exists.
*
*
* This method returns true on success and false on failure.
*
*
* @param string $key
* @return bool
*/
@ -267,13 +267,13 @@ class Cache
return false;
}
}
/**
* Increase the value of a key by $amount.
*
*
* If the key does not exist, this method assumes that the current value is zero.
* This method returns the new value, or -1 on failure.
*
*
* @param string $key
* @param int $amount (optional)
* @return int
@ -289,13 +289,13 @@ class Cache
return -1;
}
}
/**
* Decrease the value of a key by $amount.
*
*
* If the key does not exist, this method assumes that the current value is zero.
* This method returns the new value, or -1 on failure.
*
*
* @param string $key
* @param int $amount (optional)
* @return int
@ -311,12 +311,12 @@ class Cache
return -1;
}
}
/**
* Clear a group of keys from the cache.
*
*
* This method returns true on success and false on failure.
*
*
* @param string $group_name
* @return bool
*/
@ -333,12 +333,12 @@ class Cache
return false;
}
}
/**
* Clear all keys from the cache.
*
*
* This method returns true on success and false on failure.
*
*
* @return bool
*/
public static function clearAll(): bool
@ -352,10 +352,10 @@ class Cache
return false;
}
}
/**
* Get the group version.
*
*
* @param string $group_name
* @return int
*/
@ -377,10 +377,10 @@ class Cache
}
}
}
/**
* Get the actual key used by Rhymix.
*
*
* @param string $key
* @return string
*/
@ -390,7 +390,7 @@ class Cache
{
$key = $matches[1] . '#' . self::getGroupVersion($matches[1]) . ':' . $matches[2];
}
return self::$_prefix . $key;
}
}

View file

@ -9,7 +9,7 @@ class Calendar
{
/**
* This method returns the English name of a month, e.g. 9 = 'September'.
*
*
* @param int $month_number
* @param bool $long_format (optional, default is true)
* @return string
@ -21,16 +21,16 @@ class Calendar
{
return false;
}
return date($long_format ? 'F' : 'M', mktime(0, 0, 0, $month_number, 1));
}
/**
* This method returns the day on which a month begins.
*
*
* 0 = Sunday, 1 = Monday, 2 = Tuesday, 3 = Wednesday, 4 = Thursday, 5 = Friday, 6 = Saturday.
* If you do not specify a year, the current year is assumed.
*
*
* @param int $month_number
* @param int $year (optional)
* @return int
@ -42,16 +42,16 @@ class Calendar
{
return false;
}
return (int)date('w', mktime(0, 0, 0, $month_number, 1, $year ?: date('Y')));
}
/**
* This method returns the number of days in a month, e.g. February 2016 has 29 days.
*
*
* If you do not specify a year, the current year is assumed.
* You must specify a year to get the number of days in February.
*
*
* @param int $month_number
* @param int $year (optional)
* @return int
@ -63,19 +63,19 @@ class Calendar
{
return false;
}
return (int)date('t', mktime(0, 0, 0, $month_number, 1, $year ?: date('Y')));
}
/**
* This method returns a complete calendar for a month.
*
*
* The return value is an array with six members, each representing a week.
* Each week is an array with seven members, each representing a day.
* 6 weeks are returned. Empty cells are represented by nulls.
*
*
* If you do not specify a year, the current year is assumed.
*
*
* @param int $month_number
* @param int $year (optional)
* @param int $start_dow (optional)
@ -96,13 +96,13 @@ class Calendar
{
$year = date('Y');
}
$start = self::getMonthStartDayOfWeek($month_number, $year);
$count = self::getMonthDays($month_number, $year);
$initial_blank_cells = (7 + $start - $start_dow) % 7;
$final_blank_cells = 42 - $count - $initial_blank_cells;
$temp = array();
for ($i = 0; $i < $initial_blank_cells; $i++)
{
$temp[] = null;
@ -115,7 +115,7 @@ class Calendar
{
$temp[] = null;
}
$return = array();
for ($i = 0; $i < 6; $i++)
{
@ -126,7 +126,7 @@ class Calendar
}
$return[] = $week;
}
return $return;
}
}

View file

@ -11,7 +11,7 @@ class Config
* System configuration is stored here.
*/
protected static $_config = array();
/**
* Location of configuration files.
*/
@ -20,10 +20,10 @@ class Config
public static $old_ftp_config_filename = 'files/config/ftp.config.php';
public static $old_lang_config_filename = 'files/config/lang_selected.info';
public static $default_config_filename = 'common/defaults/config.php';
/**
* Load system configuration.
*
*
* @return void
*/
public static function init()
@ -43,30 +43,30 @@ class Config
}
return self::$_config;
}
/**
* Get all system configuration.
*
*
* @return array
*/
public static function getAll()
{
return self::$_config;
}
/**
* Get default system configuration.
*
*
* @return array
*/
public static function getDefaults()
{
return (include \RX_BASEDIR . self::$default_config_filename);
}
/**
* Get a system configuration value.
*
*
* @param string $key
* @return mixed
*/
@ -88,10 +88,10 @@ class Config
}
return $data;
}
/**
* Set a system configuration value.
*
*
* @param string $key
* @param mixed $value
* @return void
@ -110,10 +110,10 @@ class Config
}
$data = $value;
}
/**
* Set all system configuration.
*
*
* @param array $config
* @return void
*/
@ -121,10 +121,10 @@ class Config
{
self::$_config = $config;
}
/**
* Save the current system configuration.
*
*
* @param array $config (optional)
* @return bool
*/
@ -134,7 +134,7 @@ class Config
{
self::setAll($config);
}
// Backup the main config file.
$config_filename = \RX_BASEDIR . self::$config_filename;
if (Storage::exists($config_filename))
@ -147,7 +147,7 @@ class Config
return false;
}
}
// Save the main config file.
$buff = '<?php' . "\n" . '// Rhymix System Configuration' . "\n" . 'return ' . self::serialize(self::$_config) . ';' . "\n";
$result = Storage::write($config_filename, $buff) ? true : false;
@ -156,10 +156,10 @@ class Config
{
return false;
}
// Remove the backup file.
Storage::delete($backup_filename);
// Save XE-compatible config files.
$warning = '// THIS FILE IS NOT USED IN RHYMIX.' . "\n" . '// TO MODIFY SYSTEM CONFIGURATION, EDIT config.php INSTEAD.';
$buff = '<?php' . "\n" . $warning . "\n";
@ -167,10 +167,10 @@ class Config
Storage::write(\RX_BASEDIR . self::$old_ftp_config_filename, $buff);
return true;
}
/**
* Serialize a value for insertion into a PHP-based configuration file.
*
*
* @param mixed $value
* @return string
*/

File diff suppressed because it is too large Load diff

View file

@ -11,10 +11,10 @@ class DateTime
* Time zone objects and settings are cached here.
*/
protected static $_timezones = array();
/**
* Format a Unix timestamp using the internal timezone.
*
*
* @param string $format Format used in PHP date() function
* @param int $timestamp Unix timestamp (optional, default is now)
* @return string
@ -25,14 +25,14 @@ class DateTime
{
return self::getRelativeTimestamp($timestamp ?: time());
}
$offset = Config::get('locale.internal_timezone') ?: date('Z', $timestamp);
return gmdate($format, ($timestamp ?: time()) + $offset);
}
/**
* Format a Unix timestamp for the current user's timezone.
*
*
* @param string $format Format used in PHP date() function
* @param int $timestamp Unix timestamp (optional, default is now)
* @return string
@ -43,7 +43,7 @@ class DateTime
{
return self::getRelativeTimestamp($timestamp ?: time());
}
$timezone = self::getTimezoneForCurrentUser();
if (!isset(self::$_timezones[$timezone]))
{
@ -54,10 +54,10 @@ class DateTime
$datetime->setTimezone(self::$_timezones[$timezone]);
return $datetime->format($format);
}
/**
* Get the current user's timezone.
*
*
* @return string
*/
public static function getTimezoneForCurrentUser()
@ -79,10 +79,10 @@ class DateTime
return @date_default_timezone_get();
}
}
/**
* Get the list of time zones supported on this server.
*
*
* @return array
*/
public static function getTimezoneList()
@ -103,10 +103,10 @@ class DateTime
$result['Etc/UTC'] = 'GMT/UTC (+00:00)';
return $result;
}
/**
* Get the absolute (UTC) offset of a timezone.
*
*
* @param string $timezone Timezone identifier, e.g. Asia/Seoul
* @param int $timestamp Unix timestamp (optional, default is now)
* @return int
@ -122,10 +122,10 @@ class DateTime
$datetime->setTimezone(self::$_timezones[$timezone]);
return $datetime->getOffset();
}
/**
* Get the relative offset between a timezone and Rhymix's internal timezone.
*
*
* @param string $timezone Timezone identifier, e.g. Asia/Seoul
* @param int $timestamp Unix timestamp (optional, default is now)
* @return int
@ -134,10 +134,10 @@ class DateTime
{
return self::getTimezoneOffset($timezone, $timestamp) - Config::get('locale.internal_timezone');
}
/**
* Get the absolute (UTC) offset of a timezone written in XE legacy format ('+0900').
*
*
* @param string $timezone
* @return int
*/
@ -148,16 +148,16 @@ class DateTime
list($hours, $minutes) = str_split($timezone, 2);
return (((int)$hours * 60) + (int)$minutes) * $multiplier;
}
/**
* Get a PHP time zone by UTC offset.
*
*
* Time zones with both (a) fractional offsets and (b) daylight saving time
* (such as Iran's +03:30/+04:30) cannot be converted in this way.
* However, if Rhymix is installed for the first time in such a time zone,
* the internal time zone will be automatically set to UTC,
* so this should never be a problem in practice.
*
*
* @param int $offset
* @return bool
*/
@ -178,10 +178,10 @@ class DateTime
default: return 'Etc/GMT' . ($offset > 0 ? '-' : '+') . intval(abs($offset / 3600));
}
}
/**
* Get a relative timestamp (3 hours ago, etc.)
*
*
* @param int $timestamp
* @return string
*/
@ -189,7 +189,7 @@ class DateTime
{
$diff = \RX_TIME - $timestamp;
$langs = lang('common.time_gap');
if ($diff < 3)
{
return $langs['now'];

View file

@ -25,90 +25,90 @@ class Debug
protected static $_slow_remote_requests = array();
protected static $_session_time = 0;
protected static $_query_time = 0;
/**
* Enable log collection.
*
*
* @return void
*/
public static function enable()
{
self::$_enabled = true;
}
/**
* Disable log collection.
*
*
* @return void
*/
public static function disable()
{
self::$_enabled = false;
}
/**
* Get all entries.
*
*
* @return array
*/
public static function getEntries()
{
return self::$_entries;
}
/**
* Clear all entries.
*
*
* @return void
*/
public static function clearEntries()
{
self::$_entries = array();
}
/**
* Get all errors.
*
*
* @return array
*/
public static function getErrors()
{
return self::$_errors;
}
/**
* Clear all errors.
*
*
* @return void
*/
public static function clearErrors()
{
self::$_errors = array();
}
/**
* Get all queries.
*
*
* @return array
*/
public static function getQueries()
{
return self::$_queries;
}
/**
* Get all slow queries.
*
*
* @return array
*/
public static function getSlowQueries()
{
return self::$_slow_queries;
}
/**
* Clear all queries.
*
*
* @return void
*/
public static function clearQueries()
@ -116,30 +116,30 @@ class Debug
self::$_queries = array();
self::$_slow_queries = array();
}
/**
* Get all triggers.
*
*
* @return array
*/
public static function getTriggers()
{
return self::$_triggers;
}
/**
* Get all slow triggers.
*
*
* @return array
*/
public static function getSlowTriggers()
{
return self::$_slow_triggers;
}
/**
* Clear all triggers.
*
*
* @return void
*/
public static function clearTriggers()
@ -147,30 +147,30 @@ class Debug
self::$_triggers = array();
self::$_slow_triggers = array();
}
/**
* Get all widgets.
*
*
* @return array
*/
public static function getWidgets()
{
return self::$_widgets;
}
/**
* Get all slow widgets.
*
*
* @return array
*/
public static function getSlowWidgets()
{
return self::$_slow_widgets;
}
/**
* Clear all widgets.
*
*
* @return void
*/
public static function clearWidgets()
@ -178,30 +178,30 @@ class Debug
self::$_widgets = array();
self::$_slow_widgets = array();
}
/**
* Get all remote requests.
*
*
* @return array
*/
public static function getRemoteRequests()
{
return self::$_remote_requests;
}
/**
* Get all slow remote requests.
*
*
* @return array
*/
public static function getSlowRemoteRequests()
{
return self::$_slow_remote_requests;
}
/**
* Clear all remote requests.
*
*
* @return void
*/
public static function clearRemoteRequests()
@ -209,10 +209,10 @@ class Debug
self::$_remote_requests = array();
self::$_slow_remote_requests = array();
}
/**
* Clear all records.
*
*
* @return void
*/
public static function clearAll()
@ -230,10 +230,10 @@ class Debug
self::$_session_time = 0;
self::$_query_time = 0;
}
/**
* Add a filename alias.
*
*
* @param string $display_filename
* @param string $real_filename
* @return void
@ -242,10 +242,10 @@ class Debug
{
self::$_aliases[$real_filename] = $display_filename;
}
/**
* Add session start time.
*
*
* @param float $session_start_time
* @return void
*/
@ -253,10 +253,10 @@ class Debug
{
self::$_session_time += $session_start_time;
}
/**
* Add an arbitrary entry to the log.
*
*
* @param string $message
* @return void
*/
@ -267,14 +267,14 @@ class Debug
{
return;
}
// Get the backtrace.
$backtrace = debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS);
if (count($backtrace) > 1 && $backtrace[1]['function'] === 'debugPrint' && empty($backtrace[1]['class']))
{
array_shift($backtrace);
}
// Create a log entry.
$entry = (object)array(
'message' => unserialize(serialize($message)),
@ -285,7 +285,7 @@ class Debug
'type' => 'Debug',
);
self::$_entries[] = $entry;
// Add the entry to the error log.
if (isset(self::$_config['write_error_log']) && self::$_config['write_error_log'] === 'all')
{
@ -294,10 +294,10 @@ class Debug
error_log($log_entry);
}
}
/**
* Add a PHP error to the log.
*
*
* @param int $errno
* @param string $errstr
* @param string $errfile
@ -312,13 +312,13 @@ class Debug
{
return;
}
// Do not handle error types that we were told to ignore.
if (!($errno & error_reporting()))
{
return;
}
// Rewrite the error message with relative paths.
$message = str_replace(array(
' called in ' . \RX_BASEDIR,
@ -327,10 +327,10 @@ class Debug
' called in ',
' defined in ',
), $errstr);
// Get the backtrace.
$backtrace = debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS);
// Prepare the error entry.
self::$_errors[] = $errinfo = (object)array(
'message' => $message,
@ -340,7 +340,7 @@ class Debug
'time' => microtime(true),
'type' => self::getErrorType($errno),
);
// Add the entry to the error log.
if (isset(self::$_config['write_error_log']) && self::$_config['write_error_log'] === 'all')
{
@ -348,10 +348,10 @@ class Debug
error_log($log_entry . \PHP_EOL . self::formatBacktrace($backtrace));
}
}
/**
* Add a query to the log.
*
*
* @return void
*/
public static function addQuery($query)
@ -361,7 +361,7 @@ class Debug
{
return;
}
// Prepare the log entry.
$query_object = (object)array(
'query_id' => $query['query_id'],
@ -377,10 +377,10 @@ class Debug
'time' => microtime(true),
'type' => 'Query',
);
self::$_queries[] = $query_object;
self::$_query_time += $query_object->query_time;
// Add the entry to the error log if the result wasn't successful.
if ($query['result'] === 'error')
{
@ -392,26 +392,26 @@ class Debug
'time' => $query_object->time,
'type' => 'Query Error',
);
self::$_errors[] = $error_object;
if (self::$_config['write_error_log'] === 'all')
{
$log_entry = strtr(sprintf('Query Error: %s in %s on line %d', $error_object->message, $error_object->file, intval($error_object->line)), "\0\r\n\t\v\e\f", ' ');
error_log($log_entry . \PHP_EOL . self::formatBacktrace($error_object->backtrace));
}
}
// Add the entry to the slow query log.
if ($query_object->query_time && $query_object->query_time >= (self::$_config['log_slow_queries'] ?? 1))
{
self::$_slow_queries[] = $query_object;
}
}
/**
* Add a trigger to the log.
*
*
* @return bool
*/
public static function addTrigger($trigger)
@ -421,7 +421,7 @@ class Debug
{
return;
}
// Prepare the log entry.
$trigger_object = (object)array(
'trigger_name' => $trigger['name'],
@ -435,17 +435,17 @@ class Debug
'time' => microtime(true),
'type' => 'Trigger',
);
self::$_triggers[] = $trigger_object;
if ($trigger_object->trigger_time && $trigger_object->trigger_time >= (self::$_config['log_slow_triggers'] ?? 1))
{
self::$_slow_triggers[] = $trigger_object;
}
}
/**
* Add a widget to the log.
*
*
* @return bool
*/
public static function addWidget($widget)
@ -455,7 +455,7 @@ class Debug
{
return;
}
// Prepare the log entry.
$widget_object = (object)array(
'widget_name' => $widget['name'],
@ -467,17 +467,17 @@ class Debug
'time' => microtime(true),
'type' => 'Widget',
);
self::$_widgets[] = $widget_object;
if ($widget_object->widget_time && $widget_object->widget_time >= (self::$_config['log_slow_widgets'] ?? 1))
{
self::$_slow_widgets[] = $widget_object;
}
}
/**
* Add a remote request to the log.
*
*
* @return bool
*/
public static function addRemoteRequest($request)
@ -487,7 +487,7 @@ class Debug
{
return;
}
// Prepare the log entry.
$request_object = (object)array(
'url' => $request['url'],
@ -501,17 +501,17 @@ class Debug
'time' => microtime(true),
'type' => 'Remote Request',
);
self::$_remote_requests[] = $request_object;
if ($request_object->elapsed_time && $request_object->elapsed_time >= (self::$_config['log_slow_remote_requests'] ?? 1))
{
self::$_slow_remote_requests[] = $request_object;
}
}
/**
* The default handler for catching exceptions.
*
*
* @param Exception $e
* @return void
*/
@ -519,7 +519,7 @@ class Debug
{
// Find out the file where the error really occurred.
$errfile = self::translateFilename($e->getFile());
// If the exception was thrown in a Rhymix Framework class, find out where that class was called.
$backtrace = $e->getTrace();
$caller_errfile = $errfile;
@ -537,9 +537,9 @@ class Debug
$caller_errline = $trace['line'];
}
}
// Add the exception to the error log.
if ($caller_errfile && $caller_errfile !== $errfile)
{
$log_entry = str_replace("\0", '', sprintf('%s #%d "%s" in %s on line %d (via %s on line %d)',
@ -554,15 +554,15 @@ class Debug
{
error_log('PHP Exception: ' . $log_entry . \PHP_EOL . self::formatBacktrace($e->getTrace()));
}
// Display the error screen.
self::displayErrorScreen($log_entry);
exit;
}
/**
* The default handler for catching fatal errors.
*
*
* @return void
*/
public static function shutdownHandler()
@ -573,10 +573,10 @@ class Debug
{
return;
}
// Find out the file where the error really occurred.
$errinfo['file'] = self::translateFilename($errinfo['file']);
// Add the entry to the error log.
$message = sprintf('%s in %s on line %d', $errinfo['message'], $errinfo['file'], intval($errinfo['line']));
$log_entry = str_replace("\0", '', 'PHP ' . self::getErrorType($errinfo['type']) . ': ' . $message);
@ -584,11 +584,11 @@ class Debug
{
error_log($log_entry);
}
// Display the error screen.
self::displayErrorScreen($log_entry);
}
/**
* Format a backtrace for error logging.
*/
@ -607,10 +607,10 @@ class Debug
}
return implode(\PHP_EOL, $result);
}
/**
* Translate filenames.
*
*
* @param string $filename
* @return string
*/
@ -626,10 +626,10 @@ class Debug
}
return $filename;
}
/**
* Register all error handlers.
*
*
* @return void
*/
public static function registerErrorHandlers($error_types)
@ -639,10 +639,10 @@ class Debug
set_exception_handler('\\Rhymix\\Framework\\Debug::exceptionHandler');
register_shutdown_function('\\Rhymix\\Framework\\Debug::shutdownHandler');
}
/**
* Display a fatal error screen.
*
*
* @param string $message
* @return void
*/
@ -653,20 +653,20 @@ class Debug
{
return;
}
// Disable output buffering.
while (ob_get_level())
{
ob_end_clean();
}
// Localize the error title.
$title = lang('msg_server_error');
if ($title === 'msg_server_error')
{
$message = 'Server Error';
}
// Localize the error message.
$display_error_message = ini_get('display_errors') || !\Context::isInstalled() || Session::isAdmin() || self::isEnabledForCurrentUser();
$message = $display_error_message ? $message : lang('msg_server_error_see_log');
@ -674,7 +674,7 @@ class Debug
{
$message = 'Your server is configured to hide error messages. Please see your server\'s error log for details.';
}
// Display a generic error page.
try
{
@ -685,10 +685,10 @@ class Debug
self::displayError($message);
}
}
/**
* Display a default error.
*
*
* @param string $message
* @return void
*/
@ -706,10 +706,10 @@ class Debug
echo json_encode(array('error' => -1, 'message' => escape($message, false)), \JSON_UNESCAPED_UNICODE);
}
}
/**
* Check if debugging is enabled for the current user.
*
*
* @return bool
*/
public static function isEnabledForCurrentUser()
@ -722,12 +722,12 @@ class Debug
{
return self::$_enabled = false;
}
switch (self::$_config['display_to'])
{
case 'everyone':
return self::$_enabled = true;
case 'ip':
if (Filters\IpFilter::inRanges(\RX_CLIENT_IP, self::$_config['allow']))
{
@ -742,7 +742,7 @@ class Debug
return self::$_enabled = true;
}
return self::$_enabled = false;
case 'admin':
default:
$logged_info = \Context::get('logged_info');
@ -760,10 +760,10 @@ class Debug
}
}
}
/**
* Get all debug information as an object.
*
*
* @return object
*/
public static function getDebugData()
@ -802,7 +802,7 @@ class Debug
'slow_widgets' => self::$_slow_widgets,
'slow_remote_requests' => self::$_slow_remote_requests,
);
// Clean up the querystring.
if (isset($data->queries))
{
@ -811,7 +811,7 @@ class Debug
$query->query_string = trim(utf8_normalize_spaces($query->query_string, true));
}
}
// Clean up the backtrace.
foreach (array('entries', 'errors', 'queries', 'slow_queries', 'remote_requests', 'slow_remote_requests') as $key)
{
@ -838,13 +838,13 @@ class Debug
}
}
}
return $data;
}
/**
* Convert a PHP error number to the corresponding error name.
*
*
* @param int $errno
* @return string
*/

View file

@ -7,5 +7,5 @@ namespace Rhymix\Framework;
*/
class Exception extends \Exception
{
}

View file

@ -12,16 +12,16 @@ class Formatter
*/
const TEXT_NEWLINE_AS_P = 1;
const TEXT_DOUBLE_NEWLINE_AS_P = 2;
/**
* Options for Markdown to HTML conversion.
*/
const MD_NEWLINE_AS_BR = 16;
const MD_ENABLE_EXTRA = 128;
/**
* Convert plain text to HTML.
*
*
* @param string $text
* @param int $options (optional)
* @return string
@ -39,7 +39,7 @@ class Formatter
}
return $result;
}
// This option uses <br> to separate lines and <p> to separate paragraphs.
if ($options & self::TEXT_DOUBLE_NEWLINE_AS_P)
{
@ -52,14 +52,14 @@ class Formatter
}
return $result;
}
// The default is to use <br> always.
return nl2br(escape(trim($text))) . "<br />\n";
}
/**
* Convert HTML to plain text.
*
*
* @param string $html
* @return string
*/
@ -69,7 +69,7 @@ class Formatter
$html = preg_replace('!<br[^>]*>\s*!i', "\n", $html);
$html = preg_replace('!<p\b[^>]*>\s*!i', '', $html);
$html = preg_replace('!</p[^>]*>\s*!i', "\n\n", $html);
// Encode links and images to preserve essential information.
$html = preg_replace_callback('!<a\b[^>]*href="([^>"]+)"[^>]*>([^<]*)</a>!i', function($matches) {
return trim($matches[2] . ' &lt;' . $matches[1] . '&gt;');
@ -79,20 +79,20 @@ class Formatter
$title = $title ?: (preg_match('!alt="([^>"]+)"!i', $matches[0], $m) ? $m[1] : 'IMAGE');
return trim('[' . $title . '] &lt;' . $matches[1] . '&gt;');
}, $html);
// Strip all other HTML.
$text = html_entity_decode(strip_tags($html));
unset($html);
// Normalize whitespace and return.
$text = str_replace("\r\n", "\n", $text);
$text = preg_replace('/\n(?:\s*\n)+/', "\n\n", $text);
return trim($text) . "\n";
}
/**
* Convert Markdown to HTML.
*
*
* @param string $markdown
* @param int $options (optional)
* @return string
@ -110,19 +110,19 @@ class Formatter
$classes = false;
$parser = new \Michelf\Markdown;
}
if ($options & self::MD_NEWLINE_AS_BR)
{
$parser->hard_wrap = true;
}
$html = $parser->transform($markdown);
return Filters\HTMLFilter::clean($html, $classes);
}
/**
* Convert HTML to Markdown.
*
*
* @param string $html
* @return string
*/
@ -133,10 +133,10 @@ class Formatter
$converter->getConfig()->setOption('strip_tags', true);
return trim($converter->convert($html)) . "\n";
}
/**
* Convert BBCode to HTML.
*
*
* @param string $bbcode
* @return string
*/
@ -144,21 +144,21 @@ class Formatter
{
$parser = new \JBBCode\Parser;
$parser->addCodeDefinitionSet(new \JBBCode\DefaultCodeDefinitionSet());
$builder = new \JBBCode\CodeDefinitionBuilder('quote', '<blockquote>{param}</blockquote>');
$parser->addCodeDefinition($builder->build());
$builder = new \JBBCode\CodeDefinitionBuilder('code', '<pre><code>{param}</code></pre>');
$builder->setParseContent(false);
$parser->addCodeDefinition($builder->build());
$parser->parse($bbcode);
$html = $parser->getAsHtml();
return Filters\HTMLFilter::clean($html);
}
/**
* Apply smart quotes and other stylistic enhancements to HTML.
*
*
* @param string $html
* @return string
*/
@ -166,10 +166,10 @@ class Formatter
{
return \Michelf\SmartyPants::defaultTransform($html, 'qbBdDiew');
}
/**
* Compile LESS into CSS.
*
*
* @param string|array $source_filename
* @param string $target_filename
* @param array $variables (optional)
@ -181,7 +181,7 @@ class Formatter
// Get the cleaned and concatenated content.
$imported_list = [];
$content = self::concatCSS($source_filename, $target_filename, true, $imported_list);
// Compile!
try
{
@ -192,7 +192,7 @@ class Formatter
{
$less_compiler->setVariables($variables);
}
$content = $less_compiler->compile($content) . "\n";
$content = strpos($content, '@charset') === false ? ('@charset "UTF-8";' . "\n" . $content) : $content;
$result = true;
@ -204,20 +204,20 @@ class Formatter
$content = sprintf("/*\n Error while compiling %s\n\n %s\n*/\n", $filename, $message);
$result = false;
}
// Save the result to the target file.
Storage::write($target_filename, $content);
// Save the list of imported files.
Storage::writePHPData(preg_replace('/\.css$/', '.imports.php', $target_filename), $imported_list, null, false);
// Also return the compiled CSS content.
return $result;
}
/**
* Compile SCSS into CSS.
*
*
* @param string|array $source_filename
* @param string $target_filename
* @param array $variables (optional)
@ -229,7 +229,7 @@ class Formatter
// Get the cleaned and concatenated content.
$imported_list = [];
$content = self::concatCSS($source_filename, $target_filename, true, $imported_list);
// Compile!
try
{
@ -240,7 +240,7 @@ class Formatter
{
$scss_compiler->addVariables(array_map('\ScssPhp\ScssPhp\ValueConverter::parseValue', $variables));
}
$content = $scss_compiler->compileString($content)->getCss() . "\n";
$content = strpos($content, '@charset') === false ? ('@charset "UTF-8";' . "\n" . $content) : $content;
$result = true;
@ -252,20 +252,20 @@ class Formatter
$content = sprintf("/*\n Error while compiling %s\n\n %s\n*/\n", $filename, $message);
$result = false;
}
// Save the result to the target file.
Storage::write($target_filename, $content);
// Save the list of imported files.
Storage::writePHPData(preg_replace('/\.css$/', '.imports.php', $target_filename), $imported_list, null, false);
// Also return the compiled CSS content.
return $result;
}
/**
* Minify CSS.
*
*
* @param string|array $source_filename
* @param string $target_filename
* @return bool
@ -290,10 +290,10 @@ class Formatter
Storage::write($target_filename, $content);
return strlen($content) ? true : false;
}
/**
* Minify JS.
*
*
* @param string|array $source_filename
* @param string $target_filename
* @return bool
@ -316,10 +316,10 @@ class Formatter
Storage::write($target_filename, $content);
return strlen($content) ? true : false;
}
/**
* CSS concatenation subroutine for compileLESS() and compileSCSS().
*
*
* @param string|array $source_filename
* @param string $target_filename
* @param bool $add_comment
@ -331,12 +331,12 @@ class Formatter
$charsets = [];
$imported_urls = [];
$result = '';
if (!is_array($source_filename))
{
$source_filename = array($source_filename);
}
foreach ($source_filename as $filename)
{
// Get the media query.
@ -348,10 +348,10 @@ class Formatter
{
$media = null;
}
// Clean the content.
$content = utf8_clean(file_get_contents($filename));
// Convert all paths in LESS and SCSS imports, too.
$dirname = dirname($filename);
$import_type = ends_with('.scss', $filename) ? 'scss' : 'normal';
@ -421,7 +421,7 @@ class Formatter
}
return trim($import_content);
}, $content);
// Convert all paths to be relative to the new filename.
$path_converter = new \MatthiasMullie\PathConverter\Converter($filename, $target_filename);
$content = preg_replace_callback('/\burl\\(([^)]+)\\)/iU', function($matches) use ($path_converter) {
@ -436,19 +436,19 @@ class Formatter
}
}, $content);
unset($path_converter);
// Extract all @charset declarations.
$content = preg_replace_callback('/@charset\s+(["\'a-z0-9_-]+);[\r\n]*/i', function($matches) use (&$charsets) {
$charsets[] = trim($matches[1], '"\'');
return '';
}, $content);
// Wrap the content in a media query if there is one.
if ($media !== null)
{
$content = "@media $media {\n\n" . trim($content) . "\n\n}";
}
// Append to the result string.
$original_filename = starts_with(\RX_BASEDIR, $filename) ? substr($filename, strlen(\RX_BASEDIR)) : $filename;
if ($add_comment)
@ -460,7 +460,7 @@ class Formatter
$result .= trim($content) . "\n\n";
}
}
// Place all @charset and @import statements at the beginning.
if (count($imported_urls))
{
@ -474,13 +474,13 @@ class Formatter
$charset = '@charset "' . escape_dqstr(array_first($charsets)) . '";';
$result = $charset . "\n" . $result;
}
return $result;
}
/**
* JS concatenation subroutine.
*
*
* @param string|array $source_filename
* @param string $target_filename
* @return string
@ -488,12 +488,12 @@ class Formatter
public static function concatJS($source_filename, $target_filename)
{
$result = '';
if (!is_array($source_filename))
{
$source_filename = array($source_filename);
}
foreach ($source_filename as $filename)
{
// Handle the array format, previously used for the targetIE attribute.
@ -501,21 +501,21 @@ class Formatter
{
$filename = reset($filename);
}
// Clean the content.
$content = utf8_clean(file_get_contents($filename));
// Append to the result string.
$original_filename = starts_with(\RX_BASEDIR, $filename) ? substr($filename, strlen(\RX_BASEDIR)) : $filename;
$result .= '/* Original file: ' . $original_filename . ' */' . "\n\n" . trim($content) . ";\n\n";
}
return $result;
}
/**
* Convert IE conditional comments to JS conditions.
*
*
* @deprecated
* @param string $condition
* @return string

View file

@ -9,7 +9,7 @@ class Image
{
/**
* Check if a file is an image
*
*
* @param string $filename
* @return bool
*/
@ -17,10 +17,10 @@ class Image
{
return array_shift(explode('/', MIME::getContentType($filename))) === 'image';
}
/**
* Check if a file is an animated GIF.
*
*
* @param string $filename
* @return bool
*/
@ -46,10 +46,10 @@ class Image
fclose($fp);
return $frames > 1;
}
/**
* Get image information
*
*
* @param string $filename
* @return array|false
*/

View file

@ -9,7 +9,7 @@ class Korea
{
/**
* Format a phone number.
*
*
* @param string $num
* @return string
*/
@ -17,7 +17,7 @@ class Korea
{
// Remove all non-numbers.
$num = preg_replace('/[^0-9]/', '', $num);
// Remove the country code.
if (strncmp($num, '82', 2) === 0)
{
@ -27,7 +27,7 @@ class Korea
$num = '0' . $num;
}
}
// Apply different format based on the number of digits.
switch (strlen($num))
{
@ -62,10 +62,10 @@ class Korea
}
}
}
/**
* Check if a Korean phone number contains a valid area code and the correct number of digits.
*
*
* @param string $num
* @return bool
*/
@ -90,10 +90,10 @@ class Korea
}
return false;
}
/**
* Check if a Korean phone number is a mobile phone number.
*
*
* @param string $num
* @return bool
*/
@ -103,14 +103,14 @@ class Korea
$len = strlen($num);
return preg_match('/^01[016789][2-9][0-9]{6,7}$/', $num) ? true : false;
}
/**
* Check if the given string is a valid resident registration number (주민등록번호)
* or foreigner registration number (외국인등록번호).
*
*
* This method only checks the format.
* It does not check that the number is actually in use.
*
*
* @param string $code
* @return bool
*/
@ -121,16 +121,16 @@ class Korea
{
return false;
}
// Remove hyphen.
$code = str_replace('-', '', $code);
// Return false if the date of birth is in the future.
if (in_array((int)($code[6]), array(3, 4, 7, 8)) && intval(substr($code, 0, 6), 10) > date('ymd'))
{
return false;
}
// Calculate the checksum.
$sum = 0;
for ($i = 0; $i < 12; $i++)
@ -154,13 +154,13 @@ class Korea
}
}
}
/**
* Check if the given string is a valid corporation registration number (법인등록번호).
*
*
* This method only checks the format.
* It does not check that the number is actually in use.
*
*
* @param string $code
* @return bool
*/
@ -171,10 +171,10 @@ class Korea
{
return false;
}
// Remove hyphen.
$code = str_replace('-', '', $code);
// Calculate the checksum.
$sum = 0;
for ($i = 0; $i < 12; $i++)
@ -182,7 +182,7 @@ class Korea
$sum += $code[$i] * (($i % 2) + 1);
}
$checksum = (10 - ($sum % 10)) % 10;
// Check the 7th and 13th digits.
if ($code[6] !== '0')
{
@ -190,13 +190,13 @@ class Korea
}
return $checksum === (int)($code[12]);
}
/**
* Check if the given string is a valid business registration number (사업자등록번호).
*
*
* This method only checks the format.
* It does not check that the number is actually in use.
*
*
* @param string $code
* @return bool
*/
@ -207,10 +207,10 @@ class Korea
{
return false;
}
// Remove hyphen.
$code = str_replace('-', '', $code);
// Calculate the checksum.
$sum = 0;
$sum += $code[0] + ($code[1] * 3) + ($code[2] * 7);
@ -218,17 +218,17 @@ class Korea
$sum += $code[6] + ($code[7] * 3) + ($code[8] * 5);
$sum += floor(($code[8] * 5) / 10);
$checksum = (10 - ($sum % 10)) % 10;
// Check the last digit.
return $checksum === (int)($code[9]);
}
/**
* Check if the given IP address is Korean.
*
* This method may return incorrect results if the IP allocation databases
* (korea.ipv4.php, korea.ipv6.php) are out of date.
*
*
* @param string $ip
* @return bool
*/
@ -236,22 +236,22 @@ class Korea
{
// Extract the IPv4 address from an "IPv4-mapped IPv6" address.
if (preg_match('/::ffff:(?:0+:)?([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)$/', $ip, $matches)) $ip = $matches[1];
// Return false if the IP address is not in the right format.
if (!filter_var($ip, \FILTER_VALIDATE_IP)) return false;
// Check IPv4.
if (filter_var($ip, \FILTER_VALIDATE_IP, array('flags' => \FILTER_FLAG_IPV4)))
{
// Convert to integer.
$ipnum = sprintf('%u', ip2long($ip));
// Treat local addresses as Korean.
if ($ipnum >= 167772160 && $ipnum <= 184549375) return true; // 10.0.0.0/8
if ($ipnum >= 2130706432 && $ipnum <= 2147483647) return true; // 127.0.0.0/8
if ($ipnum >= 3232235520 && $ipnum <= 3232301055) return true; // 192.168.0.0/16
if ($ipnum >= 2886729728 && $ipnum <= 2887778303) return true; // 172.16.0.0/20
// Check the IPv4 allocation database.
$ranges = (include \RX_BASEDIR . 'common/defaults/korea.ipv4.php');
foreach ($ranges as $range)
@ -260,17 +260,17 @@ class Korea
}
return false;
}
// Check IPv6.
elseif (function_exists('inet_pton'))
{
// Convert to hexadecimal format.
$ipbin = strtolower(bin2hex(inet_pton($ip)));
// Treat local addresses as Korean.
if ($ipbin == '00000000000000000000000000000001') return true; // ::1
if (preg_match('/^f(?:[cd]|e80{13})/', $ipbin)) return true; // fc00::/8, fd00::/8, fe80::/64
// Check the IPv6 allocation database.
$ranges = (include \RX_BASEDIR . 'common/defaults/korea.ipv6.php');
foreach ($ranges as $range)
@ -279,16 +279,16 @@ class Korea
}
return false;
}
return false;
}
/**
* Check if the given email address is hosted by a Korean portal site.
*
*
* This can be used to tell which recipients may subscribe to the KISA RBL (kisarbl.or.kr).
* If the domain is not found, this method returns false.
*
*
* @param string $domain
* @param bool $clear_cache (optional)
* @return bool
@ -300,7 +300,7 @@ class Korea
{
self::$_domain_cache = array();
}
// Get the domain from the email address.
if ($pos = strpos($email_address, '@'))
{
@ -311,13 +311,13 @@ class Korea
$domain = $email_address;
}
$domain = rtrim(strtolower($domain), '.');
// Return cached result if available.
if (array_key_exists($domain, self::$_domain_cache))
{
return self::$_domain_cache[$domain];
}
// Shortcut for known domains.
if (in_array($domain, self::$known_korean))
{
@ -327,10 +327,10 @@ class Korea
{
return self::$_domain_cache[$domain] = false;
}
// For unknown domains, check the MX record.
$mx = self::_getDNSRecords($domain, \DNS_MX);
$i = 0;
foreach ($mx as $mx)
{
@ -358,13 +358,13 @@ class Korea
break;
}
}
return self::$_domain_cache[$domain] = false;
}
/**
* Get the DNS records of a domain.
*
*
* @param string $domain
* @param int $type
* @return array
@ -376,7 +376,7 @@ class Korea
{
return array();
}
$result = array();
foreach ($records as $record)
{
@ -397,16 +397,16 @@ class Korea
$result[] = $record['txt'];
}
}
ksort($result);
return $result;
}
/**
* Prevent multiple lookups for the same domain.
*/
protected static $_domain_cache = array();
/**
* Domains known to be Korean and subscribed to the KISA RBL.
*/
@ -432,7 +432,7 @@ class Korea
'empal.com',
'hanafos.com',
);
/**
* Domains known to be foreign.
*/

View file

@ -11,7 +11,7 @@ class Lang
* Instances are stored here.
*/
protected static $_instances = array();
/**
* Configuration.
*/
@ -19,10 +19,10 @@ class Lang
protected $_loaded_directories = array();
protected $_loaded_plugins = array();
protected $_search_priority = array();
/**
* This method returns the cached instance of a language.
*
*
* @param string $language
* @return object
*/
@ -38,10 +38,10 @@ class Lang
}
return self::$_instances[$language];
}
/**
* The constructor should not be called from outside.
*
*
* @param string $language
*/
protected function __construct($language)
@ -49,20 +49,20 @@ class Lang
$this->_language = preg_replace('/[^a-z0-9_-]/i', '', $language);
$this->_loaded_plugins['_custom_'] = new \stdClass();
}
/**
* Return language type.
*
*
* @return string
*/
public function langType()
{
return $this->_language;
}
/**
* Load translations from a plugin (module, addon).
*
*
* @param string $name
* @return bool
*/
@ -72,7 +72,7 @@ class Lang
{
return true;
}
if ($name === 'common')
{
$this->loadDirectory(\RX_BASEDIR . 'common/lang', 'common');
@ -90,10 +90,10 @@ class Lang
$this->loadDirectory(\RX_BASEDIR . "addons/$name/lang", $name);
}
}
/**
* Load translations from a directory.
*
*
* @param string $dir
* @param string $plugin_name
* @return bool
@ -107,12 +107,12 @@ class Lang
{
return true;
}
// Initialize variables.
$filename = null;
$lang = new \stdClass;
$result = true;
// Find a suitable language file in the given directory.
if (file_exists($dir . '/' . $this->_language . '.php'))
{
@ -130,7 +130,7 @@ class Lang
{
$filename = $dir . '/' . ($this->_language === 'ja' ? 'jp' : $this->_language) . '.lang.php';
}
// Load the language file.
if ($filename)
{
@ -142,23 +142,23 @@ class Lang
{
$result = false;
}
// Mark this directory and plugin as loaded.
$this->_loaded_directories[$dir] = true;
$this->_loaded_plugins[$plugin_name] = $lang;
// Load the same directory in the default language, too.
if ($this->_language !== 'en')
{
self::getInstance('en')->loadDirectory($dir, $plugin_name);
}
return $result;
}
/**
* Get the list of supported languages.
*
*
* @return array
*/
public static function getSupportedList()
@ -170,10 +170,10 @@ class Lang
}
return $list;
}
/**
* Generic getter.
*
*
* @param string $key
* @return string
*/
@ -185,20 +185,20 @@ class Lang
{
$args = $args[0];
}
// Get the translation.
$translation = $this->__get($key);
// If there are no arguments, return the translation.
if (!count($args)) return $translation;
// If there are arguments, interpolate them into the translation and return the result.
return vsprintf($translation, $args);
}
/**
* Generic setter.
*
*
* @param string $key
* @param string $value
* @return void
@ -207,10 +207,10 @@ class Lang
{
$this->__set($key, $value);
}
/**
* Fallback method for getting the default translation.
*
*
* @param string $key
* @return string
*/
@ -225,10 +225,10 @@ class Lang
return self::getInstance('en')->__get($key);
}
}
/**
* Magic method for translations without arguments.
*
*
* @param string $key
* @return string
*/
@ -247,7 +247,7 @@ class Lang
{
return $this->getFromDefaultLang($key);
}
// Find the given key.
$lang = $this->_loaded_plugins[$plugin_name];
foreach ($keys as $subkey)
@ -267,14 +267,14 @@ class Lang
}
return is_array($lang) ? new \ArrayObject($lang, 3) : $lang;
}
// Search custom translations first.
if (isset($this->_loaded_plugins['_custom_']->{$key}))
{
$lang = $this->_loaded_plugins['_custom_']->{$key};
return is_array($lang) ? new \ArrayObject($lang, 3) : $lang;
}
// Search other plugins.
foreach ($this->_search_priority as $plugin_name)
{
@ -284,14 +284,14 @@ class Lang
return is_array($lang) ? new \ArrayObject($lang, 3) : $lang;
}
}
// If no translation is found, return the default language.
return $this->getFromDefaultLang($key);
}
/**
* Magic method for setting a new custom translation.
*
*
* @param string $key
* @param string $value
* @return void
@ -311,7 +311,7 @@ class Lang
{
return false;
}
// Set the given key.
$count = count($keys);
$lang = $this->_loaded_plugins[$plugin_name];
@ -363,14 +363,14 @@ class Lang
}
}
}
// Set a regular key.
$this->_loaded_plugins['_custom_']->{$key} = $value;
}
/**
* Magic method for checking whether a translation exists.
*
*
* @param string $key
* @return bool
*/
@ -385,10 +385,10 @@ class Lang
}
return false;
}
/**
* Magic method for unsetting a translation.
*
*
* @param string $key
* @return void
*/
@ -396,10 +396,10 @@ class Lang
{
$this->set($key, null);
}
/**
* Magic method for translations with arguments.
*
*
* @param string $key
* @param mixed $args
* @return string|null

View file

@ -9,9 +9,9 @@ class MIME
{
/**
* Get the MIME type of a file, detected by its content.
*
*
* This method returns the MIME type of a file, or false on error.
*
*
* @param string $filename
* @return array|false
*/
@ -38,10 +38,10 @@ class MIME
return false;
}
}
/**
* Get the MIME type for the given extension.
*
*
* @param string $extension
* @return string
*/
@ -50,10 +50,10 @@ class MIME
$extension = strtolower($extension);
return array_key_exists($extension, self::$_types) ? self::$_types[$extension][0] : self::$_default;
}
/**
* Get the MIME type for the given filename.
*
*
* @param string $filename
* @return string
*/
@ -64,10 +64,10 @@ class MIME
$extension = strtolower(substr($extension, 1));
return array_key_exists($extension, self::$_types) ? self::$_types[$extension][0] : self::$_default;
}
/**
* Get the most common extension for the given MIME type.
*
*
* @param string $type
* @return string|false
*/
@ -82,17 +82,17 @@ class MIME
}
return false;
}
/**
* The default MIME type for unknown extensions.
*/
protected static $_default = 'application/octet-stream';
/**
* The list of known MIME types.
*/
protected static $_types = array(
// Text-based document formats.
'html' => ['text/html'],
'htm' => ['text/html'],
@ -107,7 +107,7 @@ class MIME
'xsl' => ['text/xml'],
'css' => ['text/css'],
'csv' => ['text/csv'],
// Binary document formats.
'doc' => ['application/msword'],
'dot' => ['application/msword'],
@ -124,7 +124,7 @@ class MIME
'odb' => ['application/vnd.oasis.opendocument.database'],
'pdf' => ['application/pdf'],
'dvi' => ['application/x-dvi'],
// Images.
'bmp' => ['image/bmp'],
'gif' => ['image/gif'],
@ -138,7 +138,7 @@ class MIME
'tiff' => ['image/tiff'],
'tif' => ['image/tiff'],
'ico' => ['image/x-icon'],
// Audio.
'mid' => ['audio/midi'],
'midi' => ['audio/midi'],
@ -153,7 +153,7 @@ class MIME
'aiff' => ['audio/x-aiff'],
'ra' => ['audio/x-realaudio'],
'm4a' => ['audio/x-m4a'],
// Video.
'avi' => ['video/x-msvideo'],
'flv' => ['video/x-flv'],
@ -173,7 +173,7 @@ class MIME
'wma' => ['video/x-ms-asf'],
'asf' => ['video/x-ms-asf'],
'm4v' => ['video/x-m4v'],
// Other multimedia file formats.
'psd' => ['application/x-photoshop'],
'swf' => ['application/x-shockwave-flash'],
@ -182,11 +182,11 @@ class MIME
'ps' => ['application/postscript'],
'mif' => ['application/vnd.mif'],
'xul' => ['application/vnd.mozilla.xul+xml'],
// Source code formats.
'phps' => ['application/x-httpd-php-source'],
'js' => ['application/x-javascript'],
// Archives.
'bz2' => ['application/x-bzip'],
'gz' => ['application/x-gzip'],
@ -195,13 +195,13 @@ class MIME
'gtar' => ['application/x-gtar'],
'rar' => ['application/x-rar-compressed'],
'zip' => ['application/x-zip'],
// Executables and packages.
'apk' => ['application/vnd.android.package-archive'],
'pkg' => ['application/x-newton-compatible-pkg'],
'exe' => ['application/vnd.microsoft.portable-executable'],
'msi' => ['application/x-msdownload'],
// RFC822 email message.
'eml' => ['message/rfc822'],
);

View file

@ -17,16 +17,16 @@ class Mail
protected $attachments = array();
public $errors = array();
protected $sent = false;
/**
* Static properties.
*/
public static $default_driver = null;
public static $custom_drivers = array();
/**
* Set the default driver.
*
*
* @param object $driver
* @return void
*/
@ -34,10 +34,10 @@ class Mail
{
self::$default_driver = $driver;
}
/**
* Get the default driver.
*
*
* @return object
*/
public static function getDefaultDriver()
@ -58,7 +58,7 @@ class Mail
}
return self::$default_driver;
}
/**
* Add a custom mail driver.
*/
@ -66,10 +66,10 @@ class Mail
{
self::$custom_drivers[] = $driver;
}
/**
* Get the list of supported mail drivers.
*
*
* @return array
*/
public static function getSupportedDrivers()
@ -106,7 +106,7 @@ class Mail
ksort($result);
return $result;
}
/**
* The constructor.
*/
@ -115,7 +115,7 @@ class Mail
$this->message = new \Swift_Message;
$this->driver = self::getDefaultDriver();
}
/**
* Set the sender (From:).
*
@ -136,7 +136,7 @@ class Mail
return false;
}
}
/**
* Get the sender (From:).
*
@ -147,7 +147,7 @@ class Mail
$list = $this->message->getFrom();
return $list ? array_first($this->formatAddresses($list)) : null;
}
/**
* Add a recipient (To:).
*
@ -168,7 +168,7 @@ class Mail
return false;
}
}
/**
* Add a recipient (CC:).
*
@ -189,7 +189,7 @@ class Mail
return false;
}
}
/**
* Add a recipient (BCC:).
*
@ -210,7 +210,7 @@ class Mail
return false;
}
}
/**
* Get the list of recipients.
*
@ -219,7 +219,7 @@ class Mail
public function getRecipients()
{
$result = array();
foreach ($this->formatAddresses($this->message->getTo()) as $address)
{
$result[] = $address;
@ -232,10 +232,10 @@ class Mail
{
$result[] = $address;
}
return array_unique($result);
}
/**
* Set the Reply-To: address.
*
@ -255,7 +255,7 @@ class Mail
return false;
}
}
/**
* Set the Return-Path: address.
*
@ -275,7 +275,7 @@ class Mail
return false;
}
}
/**
* Set the Message ID.
*
@ -296,7 +296,7 @@ class Mail
return false;
}
}
/**
* Set the In-Reply-To: header.
*
@ -317,7 +317,7 @@ class Mail
return false;
}
}
/**
* Set the References: header.
*
@ -338,7 +338,7 @@ class Mail
return false;
}
}
/**
* Set the subject.
*
@ -358,7 +358,7 @@ class Mail
return false;
}
}
/**
* Get the subject.
*
@ -368,7 +368,7 @@ class Mail
{
return $this->message->getSubject();
}
/**
* Set the subject (alias to setSubject).
*
@ -379,7 +379,7 @@ class Mail
{
return $this->setSubject($subject);
}
/**
* Get the subject (alias to getSubject).
*
@ -389,7 +389,7 @@ class Mail
{
return $this->getSubject();
}
/**
* Set the body content.
*
@ -403,25 +403,25 @@ class Mail
{
$this->setContentType($content_type);
}
if (strpos($this->content_type, 'html') !== false)
{
$content = Filters\HTMLFilter::fixRelativeUrls($content);
}
$this->message->setBody($content, $this->content_type);
}
/**
* Get the body content.
*
*
* @return string
*/
public function getBody()
{
return $this->message->getBody();
}
/**
* Set the body content (alias to setBody).
*
@ -433,20 +433,20 @@ class Mail
{
return $this->setBody($content, $content_type);
}
/**
* Get the body content (alias to getBody).
*
*
* @return string
*/
public function getContent()
{
return $this->getBody();
}
/**
* Set the content type.
*
*
* @param string $mode The type
* @return void
*/
@ -454,17 +454,17 @@ class Mail
{
$this->content_type = (strpos($type, 'html') !== false) ? 'text/html' : ((strpos($type, '/') !== false) ? $type : 'text/plain');
}
/**
* Get the content type.
*
*
* @return string
*/
public function getContentType()
{
return $this->content_type;
}
/**
* Attach a file.
*
@ -482,11 +482,11 @@ class Mail
{
return false;
}
$attachment = \Swift_Attachment::fromPath($local_filename);
$attachment->setFilename($display_filename);
$result = $this->message->attach($attachment);
if ($result)
{
$this->attachments[] = (object)array(
@ -502,7 +502,7 @@ class Mail
return false;
}
}
/**
* Embed a file.
*
@ -516,14 +516,14 @@ class Mail
{
return false;
}
$embedded = \Swift_EmbeddedFile::fromPath($local_filename);
if ($cid !== null)
{
$embedded->setId(preg_replace('/^cid:/i', '', $cid));
}
$result = $this->message->embed($embedded);
if ($result)
{
$this->attachments[] = (object)array(
@ -539,20 +539,20 @@ class Mail
return false;
}
}
/**
* Get the list of attachments to this message.
*
*
* @return array
*/
public function getAttachments()
{
return $this->attachments;
}
/**
* Send the email.
*
*
* @return bool
*/
public function send()
@ -563,20 +563,20 @@ class Mail
{
$this->caller = $backtrace[0]['file'] . ($backtrace[0]['line'] ? (' line ' . $backtrace[0]['line']) : '');
}
// Reset Message-ID in case send() is called multiple times.
$random = substr(hash('sha256', mt_rand() . microtime() . getmypid()), 0, 32);
$sender = $this->message->getFrom(); reset($sender);
$id = $random . '@' . (preg_match('/^(.+)@([^@]+)$/', key($sender), $matches) ? $matches[2] : 'swift.generated');
$this->message->getHeaders()->get('Message-ID')->setId($id);
$output = \ModuleHandler::triggerCall('mail.send', 'before', $this);
if(!$output->toBool())
{
$this->errors[] = $output->getMessage();
return false;
}
try
{
$this->sent = $this->driver->send($this) ? true : false;
@ -586,46 +586,46 @@ class Mail
$this->errors[] = $e->getMessage();
$this->sent = false;
}
$output = \ModuleHandler::triggerCall('mail.send', 'after', $this);
if(!$output->toBool())
{
$this->errors[] = $output->getMessage();
}
return $this->sent;
}
/**
* Check if the message was sent.
*
*
* @return bool
*/
public function isSent()
{
return $this->sent;
}
/**
* Get caller information.
*
*
* @return string
*/
public function getCaller()
{
return $this->caller;
}
/**
* Get errors.
*
*
* @return array
*/
public function getErrors()
{
return $this->errors;
}
/**
* Convert image paths to absolute URLs.
*
@ -637,22 +637,22 @@ class Mail
{
return Filters\HTMLFilter::fixRelativeUrls($matches[0]);
}
/**
* Format an array of addresses for display.
*
*
* @param array $addresses
* @return array
*/
protected function formatAddresses($addresses)
{
$result = array();
if (!$addresses)
{
return array();
}
foreach($addresses as $email => $name)
{
if(strval($name) === '')
@ -664,7 +664,7 @@ class Mail
$result[] = $name . ' <' . $email . '>';
}
}
return $result;
}
}

View file

@ -12,10 +12,10 @@ class Pagination
*/
const COUNT_STYLE_NORMAL = 1;
const COUNT_STYLE_CONTINUOUS = 2;
/**
* Calculate the number of pages.
*
*
* @param int $total_items
* @param int $items_per_page
* @param int $minimum (optional)
@ -32,10 +32,10 @@ class Pagination
return (int)max($minimum, ceil($total_items / $items_per_page));
}
}
/**
* Create HTML for pagination.
*
*
* @param string $base_url ($PAGE will be replaced with the page number)
* @param int $current_page
* @param int $total_pages
@ -47,7 +47,7 @@ class Pagination
$current_page = (int)$current_page;
$total_pages = (int)$total_pages;
$count = (int)$count;
// Determine the range of pages to show.
if ($count_style === self::COUNT_STYLE_NORMAL)
{
@ -72,10 +72,10 @@ class Pagination
$first_shown = max(1, $last_shown - $count + 1);
}
}
// Open the <div> tag.
$return = array('<div class="pagination">');
// Compose the link to the first page.
if ($first_shown > 1)
{
@ -87,11 +87,11 @@ class Pagination
{
$target_url = $base_url . 1;
}
$return[] = self::_composeLink($target_url, '<span class="arrow">&laquo;</span> <span class="page_number first_page">1</span>');
$return[] = '<span class="ellipsis">...</span>';
}
// Compose links for each page.
for ($page = $first_shown; $page <= $last_shown; $page++)
{
@ -103,7 +103,7 @@ class Pagination
{
$opening_span = '<span class="page_number">';
}
if (strpos($base_url, '$PAGE') !== false)
{
$target_url = str_replace('$PAGE', $page, $base_url);
@ -112,10 +112,10 @@ class Pagination
{
$target_url = $base_url . $page;
}
$return[] = self::_composeLink($target_url, $opening_span . $page . '</span>');
}
// Compose the link to the last page.
if ($last_shown < $total_pages)
{
@ -127,21 +127,21 @@ class Pagination
{
$target_url = $base_url . $total_pages;
}
$return[] = '<span class="ellipsis">...</span>';
$return[] = self::_composeLink($target_url, '<span class="page_number last_page">' . $total_pages . '</span> <span class="arrow">&raquo;</span>');
}
// Close the <div> tag.
$return[] = '</div>';
// Return the completed HTML.
return implode(' ', $return);
}
/**
* Link creation subroutine.
*
*
* @param string $target_url
* @param string $content
* @return string

View file

@ -31,10 +31,10 @@ class Password
'kimsqrb' => '/\$[1-4]\$[0-9]{14}$/',
'crypt' => '/^([0-9a-zA-Z\.\/]{13}$|_[0-9a-zA-Z\.\/]{19}$|\$[156]\$)/',
);
/**
* Add a custom algorithm.
*
*
* @param string $name
* @param string $signature
* @param callable $callback
@ -45,10 +45,10 @@ class Password
self::$_algorithm_signatures[$name] = $signature;
self::$_algorithm_callbacks[$name] = $callback;
}
/**
* Check if the given sequence of algorithms is valid.
*
*
* @param array|string $algos
* @return bool
*/
@ -70,10 +70,10 @@ class Password
}
return true;
}
/**
* Get the list of hashing algorithms supported by this server.
*
*
* @return array
*/
public static function getSupportedAlgorithms()
@ -96,7 +96,7 @@ class Password
/**
* Get the best hashing algorithm supported by this server.
*
*
* @return string
*/
public static function getBestSupportedAlgorithm()
@ -107,7 +107,7 @@ class Password
/**
* Get the current default hashing algorithm.
*
*
* @return string
*/
public static function getDefaultAlgorithm()
@ -130,7 +130,7 @@ class Password
/**
* Get the currently configured work factor for bcrypt and other adjustable algorithms.
*
*
* @return int
*/
public static function getWorkFactor()
@ -148,13 +148,13 @@ class Password
{
$work_factor = 10;
}
return $work_factor;
}
/**
* Generate a reasonably strong random password.
*
*
* @param int $length
* @return string
*/
@ -176,14 +176,14 @@ class Password
}
}
}
/**
* Hash a password.
*
*
* To use multiple algorithms in series, provide them as an array.
* Salted algorithms such as bcrypt, pbkdf2, or portable must be used last.
* On error, false will be returned.
*
*
* @param string $password
* @param string|array $algos (optional)
* @param string $salt (optional)
@ -196,11 +196,11 @@ class Password
{
$algos = self::getDefaultAlgorithm();
}
// Initialize the chain of hashes.
$algos = array_map('strtolower', array_map('trim', is_array($algos) ? $algos : explode(',', $algos)));
$hashchain = preg_replace('/\\s+/', ' ', trim($password));
// Apply the given algorithms one by one.
foreach ($algos as $algo)
{
@ -211,7 +211,7 @@ class Password
$hashchain = self::bcrypt($hashchain, $salt, self::getWorkFactor());
if ($hashchain[0] === '*') return false;
return $hashchain;
// PBKDF2 (must be used last)
case 'pbkdf2':
if ($salt === null)
@ -231,7 +231,7 @@ class Password
}
$iterations_padding = ($salt === null || !isset($parts[1])) ? 7 : strlen($parts[1]);
return self::pbkdf2($hashchain, $salt, $hash_algorithm, $iterations, $key_length, $iterations_padding);
// phpass portable algorithm (must be used last)
case 'portable':
$phpass = new \Hautelook\Phpass\PasswordHash(self::getWorkFactor(), true);
@ -245,47 +245,47 @@ class Password
$match = $phpass->CheckPassword($hashchain, $salt);
return $match ? $salt : false;
}
// Drupal's SHA-512 based algorithm (must be used last)
case 'drupal':
$hashchain = \VendorPass::drupal($password, $salt);
return $hashchain;
// Joomla's MD5 based algorithm (must be used last)
case 'joomla':
$hashchain = \VendorPass::joomla($password, $salt);
return $hashchain;
// KimsQ Rb algorithms (must be used last)
case 'kimsqrb':
$hashchain = \VendorPass::kimsqrb($password, $salt);
return $hashchain;
// crypt() function (must be used last)
case 'crypt':
if ($salt === null) $salt = Security::getRandom(2, 'alnum');
$hashchain = crypt($hashchain, $salt);
return $hashchain;
// MS SQL's PWDENCRYPT() function (must be used last)
case 'mssql_pwdencrypt':
$hashchain = \VendorPass::mssql_pwdencrypt($hashchain, $salt);
return $hashchain;
// MySQL's old PASSWORD() function.
case 'mysql_old_password':
$hashchain = \VendorPass::mysql_old_password($hashchain);
break;
// MySQL's new PASSWORD() function.
case 'mysql_new_password':
$hashchain = \VendorPass::mysql_new_password($hashchain);
break;
// A dummy algorithm that does nothing.
case 'null':
break;
// All other algorithms will be passed to hash() or treated as a function name.
default:
if (isset(self::$_algorithm_callbacks[$algo]))
@ -307,16 +307,16 @@ class Password
}
}
}
return $hashchain;
}
/**
* Check a password against a hash.
*
*
* This method returns true if the password is correct, and false otherwise.
* If the algorithm is not specified, it will be guessed from the format of the hash.
*
*
* @param string $password
* @param string $hash
* @param array|string $algos
@ -341,12 +341,12 @@ class Password
return Security::compareStrings($hash, self::hashPassword($password, $algos, $hash));
}
}
/**
* Guess which algorithm(s) were used to generate the given hash.
*
*
* If there are multiple possibilities, all of them will be returned in an array.
*
*
* @param string $hash
* @return array
*/
@ -359,10 +359,10 @@ class Password
}
return $candidates;
}
/**
* Check the work factor of a hash.
*
*
* @param string $hash
* @return int
*/
@ -381,10 +381,10 @@ class Password
return 0;
}
}
/**
* Generate the bcrypt hash of a string.
*
*
* @param string $password
* @param string $salt (optional)
* @param int $work_factor (optional)
@ -396,13 +396,13 @@ class Password
{
$salt = '$2y$' . sprintf('%02d', $work_factor) . '$' . Security::getRandom(22, 'alnum');
}
return crypt($password, $salt);
}
/**
* Generate the PBKDF2 hash of a string.
*
*
* @param string $password
* @param string $salt (optional)
* @param string $algorithm (optional)
@ -417,7 +417,7 @@ class Password
{
$salt = Security::getRandom(12, 'alnum');
}
if (function_exists('hash_pbkdf2'))
{
$hash = hash_pbkdf2($algorithm, $password, $salt, $iterations, $length, true);
@ -438,24 +438,24 @@ class Password
}
$hash = substr($output, 0, $length);
}
return $algorithm . ':' . str_pad($iterations, $iterations_padding, '0', STR_PAD_LEFT) . ':' . $salt . ':' . base64_encode($hash);
}
/**
* Count the amount of entropy that a password contains.
*
*
* @param string $password
* @return int
*/
public static function countEntropyBits($password)
{
// An empty string has no entropy.
if ($password === '') return 0;
// Common character sets and the number of possible mutations.
static $entropy_per_char = array(
'/^[0-9]+$/' => 10,
'/^[a-z]+$/' => 26,
@ -468,7 +468,7 @@ class Password
'/^[\\x20-\\x7e]+$/' => 95,
'/^[\\x00-\\x7f]+$/' => 128,
);
foreach ($entropy_per_char as $regex => $entropy)
{
if (preg_match($regex, $password))
@ -476,7 +476,7 @@ class Password
return log(pow($entropy, strlen($password)), 2);
}
}
return strlen($password) * 8;
}
}

View file

@ -26,10 +26,10 @@ class Push
* Static properties.
*/
protected static $_drivers = array();
/**
* Add a custom Push driver.
*
*
* @param string $name
* @param object $driver
* @return void
@ -38,10 +38,10 @@ class Push
{
self::$_drivers[$name] = $driver;
}
/**
* Get the default driver.
*
*
* @param string $name
* @return object|null
*/
@ -51,7 +51,7 @@ class Push
{
return self::$_drivers[$name];
}
$driver_class = '\Rhymix\Framework\Drivers\Push\\' . $name;
if (class_exists($driver_class))
{
@ -63,10 +63,10 @@ class Push
return null;
}
}
/**
* Get the list of supported Push drivers.
*
*
* @return array
*/
public static function getSupportedDrivers(): array
@ -99,15 +99,15 @@ class Push
ksort($result);
return $result;
}
/**
* The constructor.
*/
public function __construct()
{
}
/**
* Set the sender's member_srl.
*
@ -119,7 +119,7 @@ class Push
$this->from = $member_srl;
return true;
}
/**
* Get the sender's phone number.
*
@ -129,7 +129,7 @@ class Push
{
return intval($this->from);
}
/**
* Add a recipient.
*
@ -141,7 +141,7 @@ class Push
$this->to[] = $member_srl;
return true;
}
/**
* Get the list of recipients without country codes.
*
@ -151,7 +151,7 @@ class Push
{
return $this->to;
}
/**
* Set the subject.
*
@ -163,7 +163,7 @@ class Push
$this->subject = utf8_trim(utf8_clean($subject));
return true;
}
/**
* Get the subject.
*
@ -173,7 +173,7 @@ class Push
{
return $this->subject;
}
/**
* Set the content.
*
@ -186,17 +186,17 @@ class Push
$this->content = strtr($this->content, array("\r\n" => "\n"));
return true;
}
/**
* Get the content.
*
*
* @return string
*/
public function getContent(): string
{
return $this->content;
}
/**
* Set an click-action to associate with this push notification.
*
@ -211,14 +211,14 @@ class Push
/**
* Get the click-action associated with this push notification.
*
*
* @return string
*/
public function getClickAction(): string
{
return $this->metadata['click_action'];
}
/**
* Set a sound to associate with this push notification.
*
@ -230,7 +230,7 @@ class Push
$this->metadata['sound'] = utf8_trim(utf8_clean($sound));
return true;
}
/**
* Set a badge to associate with this push notification.
*
@ -266,7 +266,7 @@ class Push
$this->metadata['tag'] = utf8_trim(utf8_clean($tag));
return true;
}
/**
* Set a color to associate with this push notification.
*
@ -278,7 +278,7 @@ class Push
$this->metadata['color'] = utf8_trim(utf8_clean($color));
return true;
}
/**
* Set an android-channel-id to associate with this push notification.
*
@ -290,10 +290,10 @@ class Push
$this->metadata['android_channel_id'] = utf8_trim(utf8_clean($android_channel_id));
return true;
}
/**
* Get notification array
*
*
* @return array
*/
public function getMetadata(): array
@ -314,17 +314,17 @@ class Push
$this->data = $data;
return true;
}
/**
* Get the data associated with this push notification.
*
*
* @return array
*/
public function getData(): array
{
return $this->data;
}
/**
* Set a URL to associate with this push notification.
*
@ -336,20 +336,20 @@ class Push
$this->data['url'] = $url;
return true;
}
/**
* Get the URL associated with this push notification.
*
*
* @return string
*/
public function getURL(): string
{
return $this->data['url'];
}
/**
* Send the message.
*
*
* @return bool
*/
public function send(): bool
@ -360,19 +360,19 @@ class Push
{
$this->caller = $backtrace[0]['file'] . ($backtrace[0]['line'] ? (' line ' . $backtrace[0]['line']) : '');
}
$output = \ModuleHandler::triggerCall('push.send', 'before', $this);
if(!$output->toBool())
{
$this->errors[] = $output->getMessage();
return false;
}
try
{
$tokens = $this->_getDeviceTokens();
$output = null;
// Android FCM
if(count($tokens->fcm))
{
@ -398,28 +398,28 @@ class Push
$this->_deleteInvalidTokens($output->invalid);
$this->_updateDeviceTokens($output->needUpdate);
}
}
catch(\Exception $e)
{
$this->errors[] = class_basename($e) . ': ' . $e->getMessage();
$this->sent = false;
}
$output = \ModuleHandler::triggerCall('push.send', 'after', $this);
if(!$output->toBool())
{
$this->errors[] = $output->getMessage();
}
return $this->sent > 0 ? true : false;
}
/**
* Get the device token
*
*
* @return \stdClass
*
*
*/
protected function _getDeviceTokens(): \stdClass
{
@ -461,7 +461,7 @@ class Push
/**
* Delete the device toekn
*
*
* @param array
* @return void
*/
@ -478,7 +478,7 @@ class Push
/**
* Update the device toekn
*
*
* @param array
* @return void
*/
@ -492,70 +492,70 @@ class Push
executeQueryArray('member.updateMemberDevice', $args);
}
}
/**
* Check if the message was sent.
*
*
* @return bool
*/
public function isSent(): bool
{
return $this->sent > 0 ? true : false;
}
/**
* Get caller information.
*
*
* @return string
*/
public function getCaller(): string
{
return $this->caller;
}
/**
* Get errors.
*
*
* @return array
*/
public function getErrors(): array
{
return $this->errors;
}
/**
* Get success tokens.
*
*
* @return array
*/
public function getSuccessTokens(): array
{
return $this->success_tokens;
}
/**
* Get deleted tokens.
*
*
* @return array
*/
public function getDeletedTokens(): array
{
return $this->deleted_tokens;
}
/**
* Get updated tokens.
*
*
* @return array
*/
public function getUpdatedTokens(): array
{
return $this->updated_tokens;
}
/**
* Add an error message.
*
*
* @param string $message
* @return void
*/

View file

@ -65,7 +65,7 @@ class Router
'priority' => 0,
),
);
/**
* List of legacy URLs that should not be treated as prefixes.
*/
@ -73,14 +73,14 @@ class Router
'rss' => true,
'atom' => true,
);
/**
* List of legacy modules whose URLs should not be shortened.
*/
protected static $_except_modules = array(
'socialxe' => true,
);
/**
* Internal cache for module and route information.
*/
@ -89,14 +89,14 @@ class Router
protected static $_global_forwarded_cache = array();
protected static $_internal_forwarded_cache = array();
protected static $_route_cache = array();
/**
* Return the currently configured rewrite level.
*
*
* 0 = None
* 1 = XE-compatible rewrite rules only
* 2 = Full rewrite support
*
*
* @return int
*/
public static function getRewriteLevel(): int
@ -108,10 +108,10 @@ class Router
}
return intval($level);
}
/**
* Extract request arguments from the current URL.
*
*
* @param string $method
* @param string $url
* @param int $rewrite_level
@ -128,7 +128,7 @@ class Router
$result->act = '';
$result->forwarded = false;
$result->args = array();
// Separate additional arguments from the URL.
$args = array();
$argstart = strpos($url, '?');
@ -138,7 +138,7 @@ class Router
$url = substr($url, 0, $argstart);
$result->args = $args;
}
// Decode the URL into plain UTF-8.
$url = $result->url = urldecode($url);
if ($url === '')
@ -150,7 +150,7 @@ class Router
$result->status = 404;
return $result;
}
// Try to detect the prefix. This might be $mid.
if ($rewrite_level >= 2 && preg_match('#^([a-zA-Z0-9_-]+)(?:/(.*))?$#s', $url, $matches) && !isset(self::$_except_prefixes[$matches[1]]))
{
@ -158,7 +158,7 @@ class Router
$prefix = $matches[1];
$internal_url = $matches[2] ?? '';
$prefix_type = 'mid';
// Find the module associated with this prefix.
$module_name = '';
$action_info = self::_getActionInfoByPrefix($prefix, $module_name);
@ -171,7 +171,7 @@ class Router
$prefix_type = 'module';
}
}
// If a module is found, try its routes.
if ($action_info)
{
@ -184,7 +184,7 @@ class Router
$result->args = $allargs;
return $result;
}
// Try the list of routes defined by the module.
foreach ($action_info->route->{$method} as $regexp => $action)
{
@ -199,7 +199,7 @@ class Router
return $result;
}
}
// Check other modules.
if ($prefix_type === 'mid')
{
@ -219,7 +219,7 @@ class Router
}
}
}
// Try the generic mid/act pattern.
if (preg_match('#^[a-zA-Z0-9_]+$#', $internal_url))
{
@ -231,7 +231,7 @@ class Router
$result->args = $allargs;
return $result;
}
// If the module defines a 404 error handler, call it.
if ($internal_url && isset($action_info->error_handlers[404]))
{
@ -245,7 +245,7 @@ class Router
}
}
}
// Try registered global routes.
if ($rewrite_level >= 2)
{
@ -264,7 +264,7 @@ class Router
}
}
}
// Try XE-compatible global routes.
foreach (self::$_global_routes as $route_info)
{
@ -280,7 +280,7 @@ class Router
return $result;
}
}
// If no pattern matches, return either an empty route or a 404 error.
$result->module = isset($args['module']) ? $args['module'] : '';
$result->mid = isset($args['mid']) ? $args['mid'] : '';
@ -297,10 +297,10 @@ class Router
return $result;
}
}
/**
* Create a URL for the given set of arguments.
*
*
* @param array $args
* @param int $rewrite_level
* @return string
@ -312,23 +312,23 @@ class Router
{
return 'index.php?' . http_build_query($args);
}
// Cache the number of arguments and their keys.
$count = count($args);
$keys = array_keys($args);
// If there are no arguments, return the URL of the main page.
if ($count == 0)
{
return '';
}
// If there is only one argument, try either $mid or $document_srl.
if ($rewrite_level >= 1 && $count == 1 && ($keys[0] === 'mid' || $keys[0] === 'document_srl'))
{
return urlencode($args[$keys[0]]);
}
// If the list of keys is already cached, return the corresponding route.
$keys_sorted = $keys; sort($keys_sorted);
$keys_string = implode('.', $keys_sorted) . ':' . ($args['mid'] ?? '') . ':' . ($args['act'] ?? '');
@ -336,10 +336,10 @@ class Router
{
return self::_insertRouteVars(self::$_route_cache[$rewrite_level][$keys_string], $args);
}
// Remove $mid and $act from arguments and work with the remainder.
$args2 = $args; unset($args2['module'], $args2['mid'], $args2['act']);
// If $mid exists, try routes defined in the module.
if ($rewrite_level >= 2 && (isset($args['mid']) || isset($args['module'])))
{
@ -354,10 +354,10 @@ class Router
$action_info = self::_getActionInfoByModule($args['module']);
$prefix_type = 'module';
}
// If there is no $act, use the default action.
$act = isset($args['act']) ? $args['act'] : $action_info->default_index_act;
// Check if $act has any routes defined.
$action = $action_info->action->{$act} ?? null;
if ($action && $action->route)
@ -375,7 +375,7 @@ class Router
return $args[$prefix_type];
}
}
// Check other modules for $act.
if ($prefix_type === 'mid')
{
@ -391,7 +391,7 @@ class Router
}
}
}
// Try the generic mid/act pattern.
if (($prefix_type !== 'module' || !isset(self::$_except_modules[$args[$prefix_type]])) && isset($args['act']))
{
@ -400,7 +400,7 @@ class Router
return $args[$prefix_type] . ($internal_url ? ('/' . $internal_url) : '');
}
}
// Try registered global routes.
if ($rewrite_level >= 2 && isset($args['act']))
{
@ -415,7 +415,7 @@ class Router
}
}
}
// Try XE-compatible global routes.
if ($rewrite_level >= 1)
{
@ -429,15 +429,15 @@ class Router
}
}
}
// If no route matches, just create a query string.
self::$_route_cache[$rewrite_level][$keys_string] = 'index.php';
return 'index.php?' . http_build_query($args);
}
/**
* Load and cache module action info.
*
*
* @param string $prefix
* @return object
*/
@ -448,7 +448,7 @@ class Router
$module_name = self::$_action_cache_prefix[$prefix];
return self::_getActionInfoByModule(self::$_action_cache_prefix[$prefix]) ?: false;
}
$module_info = \ModuleModel::getModuleInfoByMid($prefix);
if ($module_info && $module_info->module)
{
@ -460,10 +460,10 @@ class Router
return self::$_action_cache_prefix[$prefix] = false;
}
}
/**
* Load and cache module action info.
*
*
* @param string $prefix
* @return object
*/
@ -473,14 +473,14 @@ class Router
{
return self::$_action_cache_module[$module];
}
$action_info = \ModuleModel::getModuleActionXml($module);
return self::$_action_cache_module[$module] = $action_info ?: false;
}
/**
* Get the list of routes that are registered for action-forward.
*
*
* @param string $type
* @return array
*/
@ -494,14 +494,14 @@ class Router
{
return self::$_global_forwarded_cache;
}
self::$_global_forwarded_cache['GET'] = array();
self::$_global_forwarded_cache['POST'] = array();
self::$_global_forwarded_cache['reverse'] = array();
self::$_internal_forwarded_cache['GET'] = array();
self::$_internal_forwarded_cache['POST'] = array();
self::$_internal_forwarded_cache['reverse'] = array();
$action_forward = \ModuleModel::getActionForward();
foreach ($action_forward as $action_name => $action_info)
{
@ -530,10 +530,10 @@ class Router
}
return $type === 'internal' ? self::$_internal_forwarded_cache : self::$_global_forwarded_cache;
}
/**
* Find the best matching route for an array of variables.
*
*
* @param array $routes
* @param array $vars
* @return string|false
@ -551,7 +551,7 @@ class Router
}
return $only_route;
}
// If the action has multiple routes, select the one that matches the most arguments.
else
{
@ -574,10 +574,10 @@ class Router
return $best_route;
}
}
/**
* Insert variables into a route.
*
*
* @param string $route
* @param array $vars
* @return string
@ -597,7 +597,7 @@ class Router
return '';
}
}, $route);
// Add a query string for the remaining arguments.
return $route . (count($vars) ? ('?' . http_build_query($vars)) : '');
}

View file

@ -24,16 +24,16 @@ class SMS
protected $allow_split_lms = true;
protected $errors = array();
protected $sent = false;
/**
* Static properties.
*/
public static $default_driver = null;
public static $custom_drivers = array();
/**
* Set the default driver.
*
*
* @param object $driver
* @return void
*/
@ -41,10 +41,10 @@ class SMS
{
self::$default_driver = $driver;
}
/**
* Get the default driver.
*
*
* @return object
*/
public static function getDefaultDriver()
@ -65,7 +65,7 @@ class SMS
}
return self::$default_driver;
}
/**
* Add a custom mail driver.
*/
@ -73,10 +73,10 @@ class SMS
{
self::$custom_drivers[] = $driver;
}
/**
* Get the list of supported mail drivers.
*
*
* @return array
*/
public static function getSupportedDrivers()
@ -114,7 +114,7 @@ class SMS
ksort($result);
return $result;
}
/**
* The constructor.
*/
@ -125,7 +125,7 @@ class SMS
$this->allow_split_sms = (config('sms.allow_split.sms') !== false);
$this->allow_split_lms = (config('sms.allow_split.lms') !== false);
}
/**
* Set the sender's phone number.
*
@ -137,7 +137,7 @@ class SMS
$this->from = preg_replace('/[^0-9]/', '', $number);
return true;
}
/**
* Get the sender's phone number.
*
@ -147,7 +147,7 @@ class SMS
{
return $this->from;
}
/**
* Add a recipient.
*
@ -163,7 +163,7 @@ class SMS
);
return true;
}
/**
* Get the list of recipients without country codes.
*
@ -175,7 +175,7 @@ class SMS
return $recipient->number;
}, $this->to);
}
/**
* Get the list of recipients with country codes.
*
@ -185,7 +185,7 @@ class SMS
{
return $this->to;
}
/**
* Get the list of recipients grouped by country code.
*
@ -200,7 +200,7 @@ class SMS
}
return $result;
}
/**
* Set the subject.
*
@ -212,7 +212,7 @@ class SMS
$this->subject = utf8_trim(utf8_clean($subject));
return true;
}
/**
* Get the subject.
*
@ -222,7 +222,7 @@ class SMS
{
return $this->subject;
}
/**
* Set the subject (alias to setSubject).
*
@ -233,7 +233,7 @@ class SMS
{
return $this->setSubject($subject);
}
/**
* Get the subject (alias to getSubject).
*
@ -243,7 +243,7 @@ class SMS
{
return $this->getSubject();
}
/**
* Set the content.
*
@ -256,17 +256,17 @@ class SMS
$this->content = strtr($this->content, array("\r\n" => "\n"));
return true;
}
/**
* Get the content.
*
*
* @return string
*/
public function getBody()
{
return $this->content;
}
/**
* Set the content (alias to setBody).
*
@ -277,17 +277,17 @@ class SMS
{
return $this->setBody($content);
}
/**
* Get the content (alias to getBody).
*
*
* @return string
*/
public function getContent()
{
return $this->getBody();
}
/**
* Attach a file.
*
@ -305,7 +305,7 @@ class SMS
{
return false;
}
$this->attachments[] = (object)array(
'type' => 'mms',
'local_filename' => $local_filename,
@ -314,20 +314,20 @@ class SMS
);
return true;
}
/**
* Get the list of attachments to this message.
*
*
* @return array
*/
public function getAttachments()
{
return $this->attachments;
}
/**
* Set an extra variable.
*
*
* @param string $key
* @param mixed $value
* @return void
@ -336,10 +336,10 @@ class SMS
{
$this->extra_vars[$key] = $value;
}
/**
* Get an extra variable.
*
*
* @param string $key
* @return mixed
*/
@ -347,10 +347,10 @@ class SMS
{
return isset($this->extra_vars[$key]) ? $this->extra_vars[$key] : null;
}
/**
* Get all extra variables.
*
*
* @param string $key
* @return mixed
*/
@ -358,10 +358,10 @@ class SMS
{
return $this->extra_vars;
}
/**
* Set all extra variables.
*
*
* @param array $vars
* @return void
*/
@ -369,15 +369,15 @@ class SMS
{
$this->extra_vars = $vars;
}
/**
* Delay sending the message.
*
*
* Delays (in seconds) less than 1 year will be treated as relative to the
* current time. Greater values will be interpreted as a Unix timestamp.
*
*
* This feature may not be implemented by all drivers.
*
*
* @param int $when Unix timestamp
* @return bool
*/
@ -391,119 +391,119 @@ class SMS
{
$when = 0;
}
$this->delay_timestamp = intval($when);
return true;
}
/**
* Get the Unix timestamp of when to send the message.
*
*
* This method always returns a Unix timestamp, even if the original value
* was given as a relative delay.
*
*
* This feature may not be implemented by all drivers.
*
*
* @return int
*/
public function getDelay()
{
return $this->delay_timestamp;
}
/**
* Force this message to use SMS (not LMS or MMS).
*
*
* @return void
*/
public function forceSMS()
{
$this->force_sms = true;
}
/**
* Unforce this message to use SMS (not LMS or MMS).
*
*
* @return void
*/
public function unforceSMS()
{
$this->force_sms = false;
}
/**
* Check if this message is forced to use SMS.
*
*
* @return bool
*/
public function isForceSMS()
{
return $this->force_sms;
}
/**
* Allow this message to be split into multiple SMS.
*
*
* @return void
*/
public function allowSplitSMS()
{
$this->allow_split_sms = true;
}
/**
* Allow this message to be split into multiple LMS.
*
*
* @return void
*/
public function allowSplitLMS()
{
$this->allow_split_lms = true;
}
/**
* Disallow this message to be split into multiple SMS.
*
*
* @return void
*/
public function disallowSplitSMS()
{
$this->allow_split_sms = false;
}
/**
* Disallow this message to be split into multiple LMS.
*
*
* @return void
*/
public function disallowSplitLMS()
{
$this->allow_split_lms = false;
}
/**
* Check if splitting this message into multiple SMS is allowed.
*
*
* @return bool
*/
public function isSplitSMSAllowed()
{
return $this->allow_split_sms;
}
/**
* Check if splitting this message into multiple LMS is allowed.
*
*
* @return bool
*/
public function isSplitLMSAllowed()
{
return $this->allow_split_lms;
}
/**
* Send the message.
*
*
* @return bool
*/
public function send()
@ -514,19 +514,19 @@ class SMS
{
$this->caller = $backtrace[0]['file'] . ($backtrace[0]['line'] ? (' line ' . $backtrace[0]['line']) : '');
}
$output = \ModuleHandler::triggerCall('sms.send', 'before', $this);
if(!$output->toBool())
{
$this->errors[] = $output->getMessage();
return false;
}
if (config('sms.default_force') && config('sms.default_from'))
{
$this->setFrom(config('sms.default_from'));
}
try
{
if ($this->driver)
@ -553,49 +553,49 @@ class SMS
$this->errors[] = class_basename($e) . ': ' . $e->getMessage();
$this->sent = false;
}
$output = \ModuleHandler::triggerCall('sms.send', 'after', $this);
if(!$output->toBool())
{
$this->errors[] = $output->getMessage();
}
return $this->sent;
}
/**
* Check if the message was sent.
*
*
* @return bool
*/
public function isSent()
{
return $this->sent;
}
/**
* Get caller information.
*
*
* @return string
*/
public function getCaller()
{
return $this->caller;
}
/**
* Get errors.
*
*
* @return array
*/
public function getErrors()
{
return $this->errors;
}
/**
* Add an error message.
*
*
* @param string $message
* @return void
*/
@ -603,10 +603,10 @@ class SMS
{
$this->errors[] = $message;
}
/**
* Format the current message according to an API spec.
*
*
* @param array $spec API specifications
* @return array
*/
@ -614,10 +614,10 @@ class SMS
{
// Initialize the return array.
$result = array();
// Get the list of recipients.
$recipients = $this->getRecipientsGroupedByCountry();
// Group the recipients by country code.
foreach ($recipients as $country_code => $country_recipients)
{
@ -626,7 +626,7 @@ class SMS
{
$country_recipients = array_chunk($country_recipients, $spec['max_recipients']);
}
// Send to each set of merged recipients.
foreach ($country_recipients as $recipient_numbers)
{
@ -640,12 +640,12 @@ class SMS
{
$item->delay = $this->getDelay() ?: 0;
}
// Get message content.
$subject = $this->getSubject();
$content = $this->getContent();
$attachments = $attachments = $this->getAttachments();
// Determine the message type.
if (!$this->isForceSMS() && ($spec['lms_supported'] || $spec['mms_supported']))
{
@ -667,7 +667,7 @@ class SMS
{
$item->type = 'SMS';
}
// Check the country code.
if ($item->type === 'MMS' && $country_code && is_array($spec['mms_supported_country_codes']) && !in_array($country_code, $spec['mms_supported_country_codes']))
{
@ -678,7 +678,7 @@ class SMS
$item->type = 'SMS';
}
}
// Remove subject and attachments if the message type is SMS.
if ($item->type === 'SMS')
{
@ -689,7 +689,7 @@ class SMS
}
$attachments = array();
}
// If message subject is not supported, prepend it to the content instead.
if (isset($item->subject) && $item->subject && !$spec[strtolower($item->type) . '_subject_supported'])
{
@ -704,7 +704,7 @@ class SMS
$item->subject = $subject_short;
$content = $subject_remainder . "\n" . $content;
}
// Split the content if necessary.
if (($item->type === 'SMS' && $this->allow_split_sms) || ($item->type !== 'SMS' && $this->allow_split_lms))
{
@ -721,7 +721,7 @@ class SMS
{
$content_parts = array($content);
}
// Generate a message for each part of the content and attachments.
$message_count = max(count($content_parts), count($attachments));
$last_content = $item->type;
@ -736,7 +736,7 @@ class SMS
{
$item->content = $last_content ?: $item->type;
}
// Get the attachment.
if ($attachment = array_shift($attachments))
{
@ -746,42 +746,42 @@ class SMS
{
unset($item->image);
}
// Clone the item to make a part.
$cloneitem = clone $item;
// Determine the best message type for this part.
if ($cloneitem->type !== 'SMS' && (!isset($cloneitem->subject) || !$cloneitem->subject))
{
$cloneitem->type = $attachment ? 'MMS' : ($this->_getLengthInCharset($content_part, $spec['sms_max_length_in_charset']) > $spec['sms_max_length'] ? 'LMS' : 'SMS');
}
// Add the cloned part to the result array.
$result[] = $cloneitem;
}
}
}
// Return the message parts.
return $result;
}
/**
* Get the length of a string in another character set.
*
*
* @param string $str String to measure
* @param string $charset Character set to measure length
* @return
* @return
*/
protected function _getLengthInCharset($str, $charset)
{
$str = @iconv('UTF-8', $charset . '//IGNORE', $str);
return strlen($str);
}
/**
* Split a string into several short chunks.
*
*
* @param string $str String to split
* @param int $max_length Maximum length of a chunk
* @param string $charset Character set to measure length
@ -794,7 +794,7 @@ class SMS
$result = array();
$current_entry = '';
$current_length = 0;
foreach ($chars as $char)
{
$char_length = strlen(@iconv('UTF-8', $charset . '//IGNORE', $char));
@ -810,12 +810,12 @@ class SMS
$current_length += $char_length;
}
}
if ($current_entry !== '')
{
$result[] = trim($current_entry);
}
return $result;
}
}

View file

@ -9,7 +9,7 @@ class Security
{
/**
* Sanitize a variable.
*
*
* @param string $input
* @param string $type
* @return string|false
@ -22,30 +22,30 @@ class Security
case 'escape':
if (!utf8_check($input)) return false;
return escape($input);
// Strip all HTML tags.
case 'strip':
if (!utf8_check($input)) return false;
return escape(strip_tags($input));
// Clean up HTML content to prevent XSS attacks.
case 'html':
if (!utf8_check($input)) return false;
return Filters\HTMLFilter::clean($input);
// Clean up the input to be used as a safe filename.
case 'filename':
if (!utf8_check($input)) return false;
return Filters\FilenameFilter::clean($input);
// Unknown filters return false.
default: return false;
}
}
/**
* Encrypt a string using AES.
*
*
* @param string $plaintext
* @param string $key (optional)
* @return string|false
@ -55,14 +55,14 @@ class Security
// Get the encryption key.
$key = $key ?: config('crypto.encryption_key');
$key = substr(hash('sha256', $key, true), 0, 16);
// Encrypt in a format that is compatible with defuse/php-encryption 1.2.x.
return base64_encode(\CryptoCompat::encrypt($plaintext, $key));
}
/**
* Decrypt a string using AES.
*
*
* @param string $plaintext
* @param string $key (optional)
* @return string|false
@ -72,21 +72,21 @@ class Security
// Get the encryption key.
$key = $key ?: config('crypto.encryption_key');
$key = substr(hash('sha256', $key, true), 0, 16);
// Check whether the ciphertext is valid.
$ciphertext = @base64_decode($ciphertext);
if (strlen($ciphertext) < 48)
{
return false;
}
// Decrypt in a format that is compatible with defuse/php-encryption 1.2.x.
return \CryptoCompat::decrypt($ciphertext, $key);
}
/**
* Create a digital signature to verify the authenticity of a string.
*
*
* @param string $string
* @return string
*/
@ -97,10 +97,10 @@ class Security
$hash = substr(base64_encode(hash_hmac('sha256', hash_hmac('sha256', $string, $salt), $key, true)), 0, 32);
return $salt . strtr($hash, '+/', '-_');
}
/**
* Check whether a signature is valid.
*
*
* @param string $string
* @param string $signature
* @return bool
@ -111,16 +111,16 @@ class Security
{
return false;
}
$key = config('crypto.authentication_key');
$salt = substr($signature, 0, 8);
$hash = substr(base64_encode(hash_hmac('sha256', hash_hmac('sha256', $string, $salt), $key, true)), 0, 32);
return self::compareStrings(substr($signature, 8), strtr($hash, '+/', '-_'));
}
/**
* Generate a cryptographically secure random string.
*
*
* @param int $length
* @param string $format
* @return string
@ -142,11 +142,11 @@ class Security
$entropy_required_bytes = ceil($length * 3 / 4);
break;
}
// Cap entropy to 256 bits from any one source, because anything more is meaningless.
$entropy_capped_bytes = min(32, $entropy_required_bytes);
$entropy = false;
// Find and use the most secure way to generate a random string.
if(function_exists('random_bytes'))
{
@ -159,7 +159,7 @@ class Security
$entropy = false;
}
}
// Use other good sources of entropy if random_bytes() is not available.
if ($entropy === false)
{
@ -186,7 +186,7 @@ class Security
fclose($fp);
}
}
// Use built-in source of entropy if an error occurs while using other functions.
if($entropy === false || strlen($entropy) < $entropy_capped_bytes)
{
@ -196,14 +196,14 @@ class Security
$entropy .= pack('S', rand(0, 65536) ^ mt_rand(0, 65535));
}
}
// Mixing (see RFC 4086 section 5)
$output = '';
for($i = 0; $i < $entropy_required_bytes; $i += 32)
{
$output .= hash('sha256', $entropy . $i . rand(), true);
}
// Encode and return the random string.
switch($format)
{
@ -225,10 +225,10 @@ class Security
return strtr($salt, '+/=', $replacements);
}
}
/**
* Generate a cryptographically secure random number between $min and $max.
*
*
* @param int $min
* @param int $max
* @return int
@ -247,10 +247,10 @@ class Security
return intval($min + $offset);
}
}
/**
* Generate a random UUID.
*
*
* @return string
*/
public static function getRandomUUID()
@ -260,10 +260,10 @@ class Security
$randpool[8] = chr(ord($randpool[8]) & 0x3f | 0x80);
return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($randpool), 4));
}
/**
* Compare two strings in constant time.
*
*
* @param string $a
* @param string $b
* @return bool
@ -274,7 +274,7 @@ class Security
{
return hash_equals($a, $b);
}
$diff = strlen($a) ^ strlen($b);
$maxlen = min(strlen($a), strlen($b));
for($i = 0; $i < $maxlen; $i++)
@ -283,13 +283,13 @@ class Security
}
return $diff === 0;
}
/**
* Check if the current request seems to be a CSRF attack.
*
*
* This method returns true if the request seems to be innocent,
* and false if it seems to be a CSRF attack.
*
*
* @param string $referer (optional)
* @return bool
*/
@ -315,7 +315,7 @@ class Security
{
trigger_error('CSRF token missing in POST request: ' . (\Context::get('act') ?: '(no act)'), \E_USER_WARNING);
}
if (!$referer)
{
$referer = strval(($_SERVER['HTTP_ORIGIN'] ?? '') ?: ($_SERVER['HTTP_REFERER'] ?? ''));
@ -330,15 +330,15 @@ class Security
}
}
}
/**
* 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 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
*/
@ -349,33 +349,33 @@ class Security
{
return true;
}
// Reject entity tags.
if (strpos($xml, '<!ENTITY') !== false)
{
return false;
}
// Check if there is no content after the xml tag.
$header = preg_replace('/<\?xml.*?\?'.'>/s', '', substr($xml, 0, 100), 1);
if (($xml = trim(substr_replace($xml, $header, 0, 100))) === '')
{
return false;
}
// Check if there is no content after the DTD.
$header = preg_replace('/^<!DOCTYPE[^>]*+>/i', '', substr($xml, 0, 200), 1);
if (($xml = trim(substr_replace($xml, $header, 0, 200))) === '')
{
return false;
}
// Check that the root tag is valid.
if (!preg_match('/^<(methodCall|methodResponse|fault)/', $xml))
{
return false;
}
return true;
}
}

File diff suppressed because it is too large Load diff

View file

@ -11,25 +11,25 @@ class Storage
* Use atomic rename to overwrite files.
*/
public static $safe_overwrite = true;
/**
* Cache the umask here.
*/
protected static $_umask;
/**
* Cache the opcache status here.
*/
protected static $_opcache;
/**
* Cache locks here.
*/
protected static $_locks = array();
/**
* Check if a path really exists.
*
*
* @param string $path
* @return bool
*/
@ -39,10 +39,10 @@ class Storage
clearstatcache(true, $path);
return @file_exists($path);
}
/**
* Check if the given path is a file.
*
*
* @param string $path
* @return bool
*/
@ -51,10 +51,10 @@ class Storage
$path = rtrim($path, '/\\');
return @self::exists($path) && @is_file($path);
}
/**
* Check if the given path is an empty file.
*
*
* @param string $path
* @return bool
*/
@ -63,11 +63,11 @@ class Storage
$path = rtrim($path, '/\\');
return @self::exists($path) && @is_file($path) && (@filesize($path) == 0);
}
/**
* Check if the given path is a directory.
*
*
* @param string $path
* @return bool
*/
@ -76,10 +76,10 @@ class Storage
$path = rtrim($path, '/\\');
return @self::exists($path) && @is_dir($path);
}
/**
* Check if the given path is an empty directory.
*
*
* @param string $path
* @return bool
*/
@ -90,14 +90,14 @@ class Storage
{
return false;
}
$iterator = new \FilesystemIterator($path, \FilesystemIterator::SKIP_DOTS);
return (iterator_count($iterator)) === 0 ? true : false;
}
/**
* Check if the given path is a symbolic link.
*
*
* @param string $path
* @return bool
*/
@ -106,10 +106,10 @@ class Storage
$path = rtrim($path, '/\\');
return @is_link($path);
}
/**
* Check if the given path is a valid symbolic link.
*
*
* @param string $path
* @return bool
*/
@ -118,10 +118,10 @@ class Storage
$path = rtrim($path, '/\\');
return @is_link($path) && ($target = @readlink($path)) !== false && self::exists($target);
}
/**
* Check if the given path is readable.
*
*
* @param string $path
* @return bool
*/
@ -130,10 +130,10 @@ class Storage
$path = rtrim($path, '/\\');
return @self::exists($path) && @is_readable($path);
}
/**
* Check if the given path is writable.
*
*
* @param string $path
* @return bool
*/
@ -142,10 +142,10 @@ class Storage
$path = rtrim($path, '/\\');
return @self::exists($path) && @is_writable($path);
}
/**
* Check if the given path is executable.
*
*
* @param string $path
* @return bool
*/
@ -169,12 +169,12 @@ class Storage
return @self::exists($path) && @is_executable($path);
}
}
/**
* Get the size of a file.
*
*
* This method returns the size of a file, or false on error.
*
*
* @param string $filename
* @return int|false
*/
@ -190,15 +190,15 @@ class Storage
return false;
}
}
/**
* Get the content of a file.
*
*
* This method returns the content if it exists and is readable.
* If $stream is true, it will return the content as a stream instead of
* loading the entire content in memory. This may be useful for large files.
* If the file cannot be opened, this method returns false.
*
*
* @param string $filename
* @param bool $stream (optional)
* @return string|resource|false
@ -216,7 +216,7 @@ class Storage
{
$result = @file_get_contents($filename);
}
if ($result === false)
{
trigger_error('Cannot read file: ' . $filename, \E_USER_WARNING);
@ -228,12 +228,12 @@ class Storage
return false;
}
}
/**
* Read PHP data from a file, formatted for easy retrieval.
*
* This method returns the data on success and false on failure.
*
*
* @param string $filename
* @return mixed
*/
@ -249,14 +249,14 @@ class Storage
return false;
}
}
/**
* Write $content to a file.
*
* If $content is a stream, this method will copy it to the target file
* without loading the entire content in memory. This may be useful for large files.
* This method returns true on success and false on failure.
*
*
* @param string $filename
* @param string|resource $content
* @param string $mode (optional)
@ -276,7 +276,7 @@ class Storage
return false;
}
}
if (self::$safe_overwrite && strncasecmp($mode, 'a', 1) && @is_writable($destination_dir))
{
$use_atomic_rename = true;
@ -287,7 +287,7 @@ class Storage
{
$use_atomic_rename = false;
}
if ($fp = @fopen($filename, $mode))
{
flock($fp, \LOCK_EX);
@ -302,7 +302,7 @@ class Storage
fflush($fp);
flock($fp, \LOCK_UN);
fclose($fp);
if ($result === false || (is_string($content) && strlen($content) !== $result))
{
trigger_error('Cannot write file: ' . (isset($original_filename) ? $original_filename : $filename), \E_USER_WARNING);
@ -314,9 +314,9 @@ class Storage
trigger_error('Cannot write file: ' . (isset($original_filename) ? $original_filename : $filename), \E_USER_WARNING);
return false;
}
@chmod($filename, ($perms === null ? (0666 & ~self::getUmask()) : $perms));
if ($use_atomic_rename)
{
$rename_success = @rename($filename, $original_filename);
@ -333,7 +333,7 @@ class Storage
}
$filename = $original_filename;
}
if (self::$_opcache === null)
{
self::$_opcache = function_exists('opcache_invalidate');
@ -342,17 +342,17 @@ class Storage
{
@opcache_invalidate($filename, true);
}
clearstatcache(true, $filename);
return true;
}
/**
* Write PHP data to a file, formatted for easy retrieval.
*
* This method returns true on success and false on failure.
* Resources and anonymous functions cannot be saved.
*
*
* @param string $filename
* @param mixed $data
* @param string $comment (optional)
@ -375,13 +375,13 @@ class Storage
}
return self::write($filename, $content);
}
/**
* Copy $source to $destination.
*
*
* This method returns true on success and false on failure.
* If the destination permissions are not given, they will be copied from the source.
*
*
* @param string $source
* @param string $destination
* @param int $destination_perms
@ -396,7 +396,7 @@ class Storage
trigger_error('Cannot copy because the source does not exist: ' . $source, \E_USER_WARNING);
return false;
}
$destination_dir = dirname($destination);
if (!self::exists($destination_dir) && !self::createDirectory($destination_dir))
{
@ -408,7 +408,7 @@ class Storage
$destination_dir = $destination;
$destination = $destination . '/' . basename($source);
}
if (self::$safe_overwrite && @is_writable($destination_dir))
{
$use_atomic_rename = true;
@ -419,14 +419,14 @@ class Storage
{
$use_atomic_rename = false;
}
$copy_success = @copy($source, $destination);
if (!$copy_success)
{
trigger_error('Cannot copy ' . $source . ' to ' . (isset($original_destination) ? $original_destination : $destination), \E_USER_WARNING);
return false;
}
if ($destination_perms === null)
{
if (is_uploaded_file($source))
@ -442,7 +442,7 @@ class Storage
{
@chmod($destination, $destination_perms);
}
if ($use_atomic_rename)
{
$rename_success = @rename($destination, $original_destination);
@ -459,7 +459,7 @@ class Storage
}
$destination = $original_destination;
}
if (self::$_opcache === null)
{
self::$_opcache = function_exists('opcache_invalidate');
@ -468,16 +468,16 @@ class Storage
{
@opcache_invalidate($destination, true);
}
clearstatcache(true, $destination);
return true;
}
/**
* Move $source to $destination.
*
*
* This method returns true on success and false on failure.
*
*
* @param string $source
* @param string $destination
* @return bool
@ -491,7 +491,7 @@ class Storage
trigger_error('Cannot move because the source does not exist: ' . $source, \E_USER_WARNING);
return false;
}
$destination_dir = dirname($destination);
if (!self::exists($destination_dir) && !self::createDirectory($destination_dir))
{
@ -502,19 +502,19 @@ class Storage
{
$destination = $destination . '/' . basename($source);
}
$result = @rename($source, $destination);
if (!$result)
{
trigger_error('Cannot move ' . $source . ' to ' . $destination, \E_USER_WARNING);
return false;
}
if (is_uploaded_file($source))
{
@chmod($destination, 0666 & ~self::getUmask());
}
if (self::$_opcache === null)
{
self::$_opcache = function_exists('opcache_invalidate');
@ -530,16 +530,16 @@ class Storage
@opcache_invalidate($destination, true);
}
}
clearstatcache(true, $destination);
return true;
}
/**
* Move uploaded $source to $destination.
*
*
* This method returns true on success and false on failure.
*
*
* @param string $source
* @param string $destination
* @param string $type
@ -579,13 +579,13 @@ class Storage
}
return true;
}
/**
* Delete a file.
*
*
* This method returns true if the file exists and has been successfully
* deleted, and false on any kind of failure.
*
*
* @param string $filename
* @return bool
*/
@ -596,13 +596,13 @@ class Storage
{
return false;
}
$result = @is_file($filename) && @unlink($filename);
if (!$result)
{
trigger_error('Cannot delete file: ' . $filename, \E_USER_WARNING);
}
if (self::$_opcache === null)
{
self::$_opcache = function_exists('opcache_invalidate');
@ -613,10 +613,10 @@ class Storage
}
return $result;
}
/**
* Create a directory.
*
*
* @param string $dirname
* @return bool
*/
@ -627,7 +627,7 @@ class Storage
{
$mode = 0777 & ~self::getUmask();
}
$result = @mkdir($dirname, $mode, true);
if (!$result)
{
@ -646,10 +646,10 @@ class Storage
return true;
}
}
/**
* Read the list of files in a directory.
*
*
* @param string $dirname
* @param bool $full_path (optional)
* @param bool $skip_dotfiles (optional)
@ -663,7 +663,7 @@ class Storage
{
return false;
}
try
{
$iterator = new \FilesystemIterator($dirname, \FilesystemIterator::CURRENT_AS_PATHNAME | \FilesystemIterator::SKIP_DOTS);
@ -673,7 +673,7 @@ class Storage
trigger_error('Cannot read directory: ' . $dirname, \E_USER_WARNING);
return false;
}
$result = array();
foreach ($iterator as $fileinfo)
{
@ -689,7 +689,7 @@ class Storage
sort($result);
return $result;
}
/**
* Copy a directory recursively.
*
@ -712,11 +712,11 @@ class Storage
trigger_error('Cannot create directory to copy into: ' . $destination, \E_USER_WARNING);
return false;
}
$rdi_options = \FilesystemIterator::KEY_AS_PATHNAME | \FilesystemIterator::CURRENT_AS_FILEINFO | \FilesystemIterator::SKIP_DOTS;
$rii_options = \RecursiveIteratorIterator::CHILD_FIRST;
$iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($source, $rdi_options), $rii_options);
foreach ($iterator as $path)
{
$path_source = $path->getPathname();
@ -728,7 +728,7 @@ class Storage
{
continue;
}
$path_destination = $destination . substr($path_source, strlen($source));
if ($path->isDir())
{
@ -747,13 +747,13 @@ class Storage
}
}
}
return true;
}
/**
* Move a directory.
*
*
* @param string $source
* @param string $destination
* @return bool
@ -762,10 +762,10 @@ class Storage
{
return self::move($source, $destination);
}
/**
* Delete a directory recursively.
*
*
* @param string $dirname
* @param bool $delete_self (optional)
* @return bool
@ -782,11 +782,11 @@ class Storage
trigger_error('Delete target is not a directory: ' . $dirname, \E_USER_WARNING);
return false;
}
$rdi_options = \FilesystemIterator::KEY_AS_PATHNAME | \FilesystemIterator::CURRENT_AS_FILEINFO | \FilesystemIterator::SKIP_DOTS;
$rii_options = \RecursiveIteratorIterator::CHILD_FIRST;
$iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dirname, $rdi_options), $rii_options);
foreach ($iterator as $path)
{
if ($path->isDir())
@ -806,7 +806,7 @@ class Storage
}
}
}
if ($delete_self)
{
$result = @rmdir($dirname);
@ -825,10 +825,10 @@ class Storage
return true;
}
}
/**
* Delete a directory only if it is empty.
*
*
* @param string $dirname
* @param bool $delete_empty_parents (optional)
* @return bool
@ -840,7 +840,7 @@ class Storage
{
return false;
}
$result = @rmdir($dirname);
if (!$result)
{
@ -855,10 +855,10 @@ class Storage
return true;
}
}
/**
* Get the current umask.
*
*
* @return int
*/
public static function getUmask()
@ -869,10 +869,10 @@ class Storage
}
return self::$_umask;
}
/**
* Set the current umask.
*
*
* @param int $umask
* @return void
*/
@ -880,10 +880,10 @@ class Storage
{
self::$_umask = intval($umask);
}
/**
* Determine the best umask for this installation of Rhymix.
*
*
* @return string
*/
public static function recommendUmask()
@ -893,29 +893,29 @@ class Storage
{
return '0000';
}
// Get the UID of the owner of the current file.
$file_uid = fileowner(__FILE__);
// Get the UID of the current PHP process.
$php_uid = self::getServerUID();
// If both UIDs are the same, set the umask to 0022.
if ($file_uid == $php_uid)
{
return '0022';
}
// Otherwise, set the umask to 0000.
else
{
return '0000';
}
}
/**
* Get the UID of the server process.
*
*
* @return int|false
*/
public static function getServerUID()
@ -931,7 +931,7 @@ class Storage
{
self::delete($testfile);
}
if (self::write($testfile, 'TEST'))
{
$uid = fileowner($testfile);
@ -944,10 +944,10 @@ class Storage
}
}
}
/**
* Obtain an exclusive lock.
*
*
* @return bool
*/
public static function getLock($name)
@ -957,20 +957,20 @@ class Storage
{
return false;
}
$lockdir = \RX_BASEDIR . 'files/locks';
if (!self::isDirectory($lockdir) && !self::createDirectory($lockdir))
{
return false;
}
self::$_locks[$name] = @fopen($lockdir . '/' . $name . '.lock', 'w');
if (!self::$_locks[$name])
{
unset(self::$_locks[$name]);
return false;
}
$result = @flock(self::$_locks[$name], \LOCK_EX | \LOCK_NB);
if (!$result)
{
@ -978,14 +978,14 @@ class Storage
unset(self::$_locks[$name]);
return false;
}
register_shutdown_function('\\Rhymix\\Framework\\Storage::clearLocks');
return true;
}
/**
* Clear all locks.
*
*
* @return void
*/
public static function clearLocks()

View file

@ -11,34 +11,34 @@ class Timer
* Timestamps are stored here.
*/
protected static $_timestamps = array();
/**
* Start a timer.
*
*
* This method returns the current microtime.
*
*
* @param string $name (optional)
* @return float
*/
public static function start($name = null)
{
$timestamp = microtime(true);
if ($name === null)
{
$name = 'anon-timer-' . $timestamp;
}
self::$_timestamps[$name] = $timestamp;
return $timestamp;
}
/**
* Stop a timer and return the elapsed time.
*
*
* If the name is not given, the most recently started timer will be stopped.
* If no timer has been started, this method returns false.
*
*
* @param string $name (optional)
* @return float|false
*/
@ -46,7 +46,7 @@ class Timer
{
$timestamp = microtime(true);
$started_timestamp = 0;
if ($name === null)
{
if (count(self::$_timestamps))
@ -67,16 +67,16 @@ class Timer
{
return false;
}
return $timestamp - $started_timestamp;
}
/**
* Stop a timer and return the elapsed time in a human-readable format.
*
*
* If the name is not given, the most recently started timer will be stopped.
* If no timer has been started, this method returns false.
*
*
* @param string $name (optional)
* @return string|false
*/
@ -86,17 +86,17 @@ class Timer
if ($result === false) return $result;
return number_format($result * 1000, 1, '.', ',') . 'ms';
}
/**
* This method returns how much time has elapsed since Rhymix startup.
*
*
* @return float
*/
public static function sinceStartup()
{
return microtime(true) - \RX_MICROTIME;
}
/**
* This method returns how much time has elapsed since startup in a human-readable format.
*

View file

@ -13,7 +13,7 @@ class UA
protected static $_mobile_cache = array();
protected static $_tablet_cache = array();
protected static $_robot_cache = array();
/**
* Windows version lookup table.
*/
@ -25,10 +25,10 @@ class UA
'6.2' => '8',
'6.3' => '8.1',
);
/**
* Check whether the current visitor is using a mobile device.
*
*
* @param string $ua (optional)
* @return bool
*/
@ -44,37 +44,37 @@ class UA
{
$using_header = false;
}
// If the User-Agent header is missing, it's probably not a mobile browser.
if (is_null($ua))
{
return false;
}
// Look for headers that are only used in mobile browsers.
if ($using_header && (isset($_SERVER['HTTP_X_WAP_PROFILE']) || isset($_SERVER['HTTP_X_OPERAMINI_PHONE_UA'])))
{
return true;
}
// Look up the cache.
if (isset(self::$_mobile_cache[$ua]))
{
return self::$_mobile_cache[$ua];
}
// Look for the 'mobile' keyword and common mobile platform names.
if (preg_match('/android|ip(hone|ad|od)|blackberry|nokia|palm|mobile/i', $ua))
{
return self::$_mobile_cache[$ua] = true;
}
// Look for common non-mobile OS names.
if (preg_match('/windows|linux|os [x9]|bsd/i', $ua))
{
return self::$_mobile_cache[$ua] = false;
}
// Look for other platform, manufacturer, and device names that are known to be mobile.
if (preg_match('/kindle|opera (mini|mobi)|polaris|netfront|fennec|motorola|symbianos|webos/i', $ua))
{
@ -84,14 +84,14 @@ class UA
{
return self::$_mobile_cache[$ua] = true;
}
// If we're here, it's probably not a mobile device.
return self::$_mobile_cache[$ua] = false;
}
/**
* Check whether the current visitor is using a tablet.
*
*
* @param string $ua (optional)
* @return bool
*/
@ -99,44 +99,44 @@ class UA
{
// Get the User-Agent header if the caller did not specify $ua.
$ua = $ua ?: (isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : null);
// If the User-Agent header is missing, it's probably not a tablet.
if (is_null($ua))
{
return false;
}
// Look up the cache.
if (isset(self::$_tablet_cache[$ua]))
{
return self::$_tablet_cache[$ua];
}
// Check if the user-agent is mobile.
if (!self::isMobile($ua))
{
return self::$_tablet_cache[$ua] = false;
}
// Check for Android tablets without the 'mobile' keyword.
if (stripos($ua, 'android') !== false && stripos($ua, 'mobile') === false)
{
return self::$_tablet_cache[$ua] = true;
}
// Check for common tablet identifiers.
if (preg_match('/tablet|pad\b|tab\b|\bgt-\d+|kindle|nook|playbook|webos|xoom/i', $ua))
{
return self::$_tablet_cache[$ua] = true;
}
// If we're here, it's probably not a tablet.
return self::$_tablet_cache[$ua] = false;
}
/**
* Check whether the current visitor is a robot.
*
*
* @param string $ua (optional)
* @return bool
*/
@ -144,25 +144,25 @@ class UA
{
// Get the User-Agent header if the caller did not specify $ua.
$ua = $ua ?: (isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : null);
// If the User-Agent header is missing, it's probably not a robot.
if (is_null($ua))
{
return false;
}
// Look up the cache.
if (isset(self::$_robot_cache[$ua]))
{
return self::$_robot_cache[$ua];
}
// Look for common search engine names and the 'bot' keyword.
if (preg_match('/bot|spider|crawler|archiver|wget|curl|php|slurp|wordpress|facebook|teoma|yeti|daum|apachebench|mediapartners-google|[(<+]https?:|@/i', $ua))
{
return self::$_robot_cache[$ua] = true;
}
// Use the custom user-agent list.
$customlist = Config::get('security.robot_user_agents') ?: array();
foreach ($customlist as $item)
@ -172,14 +172,14 @@ class UA
return self::$_robot_cache[$ua] = true;
}
}
// If we're here, it's probably not a robot.
return self::$_robot_cache[$ua] = false;
}
/**
* This method parses the Accept-Language header to guess the browser's default locale.
*
*
* @param string $header (optional)
* @return string
*/
@ -187,14 +187,14 @@ class UA
{
// Get the Accept-Language header if the caller did not specify $header.
$header = $header ?: (isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? $_SERVER['HTTP_ACCEPT_LANGUAGE'] : 'en-US');
// Return the first locale name found.
return preg_match('/^([a-z0-9_-]+)/i', $header, $matches) ? $matches[1] : 'en-US';
}
/**
* This method parses the User-Agent string to guess what kind of browser it is.
*
*
* @param string $ua (optional)
* @return object
*/
@ -202,7 +202,7 @@ class UA
{
// Get the User-Agent header if the caller did not specify $ua.
$ua = $ua ?: (isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : null);
// Initialize the result.
$result = (object)array(
'browser' => null,
@ -219,7 +219,7 @@ class UA
{
return $result;
}
// Try to guess the OS.
if (preg_match('#(Windows|Android|Linux|i(?:Phone|P[ao]d)|OS X|Macintosh)#i', $ua, $matches))
{
@ -258,13 +258,13 @@ class UA
}
}
}
// Fill in miscellaneous fields.
$result->is_mobile = self::isMobile($ua);
$result->is_tablet = self::isTablet($ua);
$result->is_webview = strpos($ua, '; wv)') !== false;
$result->is_robot = self::isRobot($ua);
// Try to match some of the most common browsers.
if ($result->os === 'Android' && preg_match('#Android ([0-9]+\\.[0-9]+)#', $ua, $matches))
{
@ -361,15 +361,15 @@ class UA
$result->version = isset($matches[2]) ? ($matches[2] ?: null) : null;
return $result;
}
return $result;
}
/**
* This method encodes a UTF-8 filename for downloading in the current visitor's browser.
*
* See: https://blog.bloodcat.com/302
*
*
* @param string $filename
* @param string $ua (optional)
* @return string
@ -378,10 +378,10 @@ class UA
{
// Get the User-Agent header if the caller did not specify $ua.
$ua = $ua ?: (isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : null);
// Get the browser name and version.
$browser = self::getBrowserInfo($ua);
// Find the best format that this browser supports.
if ($browser->browser === 'Chrome' && $browser->version >= 11 & !$browser->is_webview)
{
@ -419,30 +419,30 @@ class UA
{
$output_format = 'old_ie';
}
// Clean the filename.
$filename = Filters\FilenameFilter::clean($filename);
// Apply the format and return.
switch ($output_format)
{
case 'raw':
return 'filename="' . $filename . '"';
case 'rfc5987':
$filename = rawurlencode($filename);
return "filename*=UTF-8''" . $filename;
case 'old_ie':
default:
$filename = rawurlencode($filename);
return 'filename="' . preg_replace('/\./', '%2e', $filename, substr_count($filename, '.') - 1) . '"';
}
}
/**
* Get the current color scheme (auto, light, dark)
*
*
* @return string
*/
public static function getColorScheme(): string
@ -456,10 +456,10 @@ class UA
return 'auto';
}
}
/**
* Set the color scheme (auto, light, dark)
*
*
* @param string $color_scheme
* @return void
*/

View file

@ -9,10 +9,10 @@ class URL
{
/**
* Get the current URL.
*
*
* If $changes are given, they will be appended to the current URL as a query string.
* To delete an existing query string, set its value to null.
*
*
* @param array $changes
* @return string
*/
@ -29,10 +29,10 @@ class URL
return self::getCanonicalURL($url);
}
}
/**
* Get the current domain.
*
*
* @param string $path
* @return string
*/
@ -42,10 +42,10 @@ class URL
$host = isset($_SERVER['HTTP_HOST']) ? self::decodeIdna($_SERVER['HTTP_HOST']) : 'localhost';
return $proto . $host . '/' . ltrim($path, '/');
}
/**
* Convert a URL to its canonical format.
*
*
* @param string $url
* @return string
*/
@ -60,10 +60,10 @@ class URL
return $matches[1] . '//' . self::decodeIdna($matches[2]);
}, $url);
}
/**
* Get the domain from a URL.
*
*
* @param string $url
* @return string|false
*/
@ -79,10 +79,10 @@ class URL
return self::decodeIdna($domain);
}
}
/**
* Check if a URL is internal to this site.
*
*
* @param string $url
* @return bool
*/
@ -93,26 +93,26 @@ class URL
{
return true;
}
if ($domain === self::getDomainFromURL('http://' . $_SERVER['HTTP_HOST']))
{
return true;
}
if (\ModuleModel::getInstance()->getSiteInfoByDomain($domain))
{
return true;
}
return false;
}
/**
* Modify a URL.
*
*
* If $changes are given, they will be appended to the current URL as a query string.
* To delete an existing query string, set its value to null.
*
*
* @param string $url
* @param array $changes
* @return string
@ -133,13 +133,13 @@ class URL
return $prefix;
}
}
/**
* Convert a server-side path to a URL.
*
*
* This method returns false if the path cannot be converted to a URL,
* e.g. if the path is outside of the document root.
*
*
* @param string $path
* @return string|false
*/
@ -161,13 +161,13 @@ class URL
}
return false;
}
/**
* Convert a URL to a server-side path.
*
*
* This method returns false if the URL cannot be converted to a server-side path,
* e.g. if the URL belongs to an external domain.
*
*
* @param string $url
* @return string
*/
@ -180,10 +180,10 @@ class URL
}
return Filters\FilenameFilter::cleanPath($_SERVER['DOCUMENT_ROOT'] . parse_url($url, \PHP_URL_PATH));
}
/**
* Encode UTF-8 domain into IDNA (punycode)
*
*
* @param string $url
* @return string
*/
@ -203,7 +203,7 @@ class URL
$domain = $url;
$position = 0;
}
if (function_exists('idn_to_ascii'))
{
$new_domain = idn_to_ascii($domain);
@ -213,13 +213,13 @@ class URL
$encoder = new \TrueBV\Punycode();
$new_domain = $encoder->encode($domain);
}
return substr_replace($url, $new_domain, $position, strlen($domain));
}
/**
* Convert IDNA (punycode) domain into UTF-8
*
*
* @param string $url
* @return string
*/
@ -239,7 +239,7 @@ class URL
$domain = $url;
$position = 0;
}
if (function_exists('idn_to_utf8'))
{
$new_domain = idn_to_utf8($domain);
@ -249,7 +249,7 @@ class URL
$decoder = new \TrueBV\Punycode();
$new_domain = $decoder->decode($domain);
}
return substr_replace($url, $new_domain, $position, strlen($domain));
}
}

View file

@ -9,47 +9,47 @@ interface CacheInterface
{
/**
* Create a new instance of the current cache driver, using the given settings.
*
*
* @param array $config
* @return void
*/
public static function getInstance(array $config);
/**
* Check if the current cache driver is supported on this server.
*
*
* This method returns true on success and false on failure.
*
*
* @return bool
*/
public static function isSupported();
/**
* Validate cache settings.
*
*
* This method returns true on success and false on failure.
*
*
* @param mixed $config
* @return bool
*/
public static function validateSettings($config);
/**
* Get the value of a key.
*
*
* This method returns null if the key was not found.
*
*
* @param string $key
* @return mixed
*/
public function get($key);
/**
* Set the value to a key.
*
*
* This method returns true on success and false on failure.
* $ttl is measured in seconds. If it is zero, the key should not expire.
*
*
* @param string $key
* @param mixed $value
* @param int $ttl
@ -57,57 +57,57 @@ interface CacheInterface
* @return bool
*/
public function set($key, $value, $ttl = 0, $force = false);
/**
* Delete a key.
*
*
* This method returns true on success and false on failure.
* If the key does not exist, it should return false.
*
*
* @param string $key
* @return bool
*/
public function delete($key);
/**
* Check if a key exists.
*
*
* This method returns true on success and false on failure.
*
*
* @param string $key
* @return bool
*/
public function exists($key);
/**
* Increase the value of a key by $amount.
*
*
* If the key does not exist, this method assumes that the current value is zero.
* This method returns the new value.
*
*
* @param string $key
* @param int $amount
* @return int
*/
public function incr($key, $amount);
/**
* Decrease the value of a key by $amount.
*
*
* If the key does not exist, this method assumes that the current value is zero.
* This method returns the new value.
*
*
* @param string $key
* @param int $amount
* @return int
*/
public function decr($key, $amount);
/**
* Clear all keys from the cache.
*
*
* This method returns true on success and false on failure.
*
*
* @return bool
*/
public function clear();

View file

@ -9,61 +9,61 @@ interface MailInterface
{
/**
* Create a new instance of the current mail driver, using the given settings.
*
*
* @param array $config
* @return void
*/
public static function getInstance(array $config);
/**
* Get the human-readable name of this mail driver.
*
*
* @return string
*/
public static function getName();
/**
* Get the list of configuration fields required by this mail driver.
*
*
* @return array
*/
public static function getRequiredConfig();
/**
* Get the list of API types supported by this mail driver.
*
*
* @return array
*/
public static function getAPITypes();
/**
* Get the SPF hint.
*
*
* @return string
*/
public static function getSPFHint();
/**
* Get the DKIM hint.
*
*
* @return string
*/
public static function getDKIMHint();
/**
* Check if the current mail driver is supported on this server.
*
*
* This method returns true on success and false on failure.
*
*
* @return bool
*/
public static function isSupported();
/**
* Send a message.
*
*
* This method returns true on success and false on failure.
*
*
* @param object $message
* @return bool
*/

View file

@ -9,47 +9,47 @@ interface PushInterface
{
/**
* Create a new instance of the current Push driver, using the given settings.
*
*
* @param array $config
* @return void
*/
public static function getInstance(array $config): PushInterface;
/**
* Get the human-readable name of this Push driver.
*
*
* @return string
*/
public static function getName(): string;
/**
* Get the list of configuration fields required by this Push driver.
*
*
* @return array
*/
public static function getRequiredConfig(): array;
/**
* Get the list of configuration fields optionally used by this Push driver.
*
*
* @return array
*/
public static function getOptionalConfig(): array;
/**
* Check if the current SMS driver is supported on this server.
*
*
* This method returns true on success and false on failure.
*
*
* @return bool
*/
public static function isSupported(): bool;
/**
* Send a message.
*
*
* This method returns true on success and false on failure.
*
*
* @param object $message
* @param array $tokens
* @return \stdClass

View file

@ -9,61 +9,61 @@ interface SMSInterface
{
/**
* Create a new instance of the current SMS driver, using the given settings.
*
*
* @param array $config
* @return void
*/
public static function getInstance(array $config);
/**
* Get the human-readable name of this SMS driver.
*
*
* @return string
*/
public static function getName();
/**
* Get the list of configuration fields required by this SMS driver.
*
*
* @return array
*/
public static function getRequiredConfig();
/**
* Get the list of configuration fields optionally used by this SMS driver.
*
*
* @return array
*/
public static function getOptionalConfig();
/**
* Get the list of API types supported by this SMS driver.
*
*
* @return array
*/
public static function getAPITypes();
/**
* Get the spec for this SMS driver.
*
*
* @return array
*/
public static function getAPISpec();
/**
* Check if the current SMS driver is supported on this server.
*
*
* This method returns true on success and false on failure.
*
*
* @return bool
*/
public static function isSupported();
/**
* Send a message.
*
*
* This method returns true on success and false on failure.
*
*
* @param array $messages
* @param object $original
* @return bool

View file

@ -11,23 +11,23 @@ class APC implements \Rhymix\Framework\Drivers\CacheInterface
* Set this flag to false to disable cache prefixes.
*/
public $prefix = true;
/**
* The singleton instance is stored here.
*/
protected static $_instance = null;
/**
* Direct invocation of the constructor is not permitted.
*/
protected function __construct()
{
}
/**
* Create a new instance of the current cache driver, using the given settings.
*
*
* @param array $config
* @return void
*/
@ -39,24 +39,24 @@ class APC implements \Rhymix\Framework\Drivers\CacheInterface
}
return self::$_instance;
}
/**
* Check if the current cache driver is supported on this server.
*
*
* This method returns true on success and false on failure.
*
*
* @return bool
*/
public static function isSupported()
{
return function_exists('apcu_exists');
}
/**
* Validate cache settings.
*
*
* This method returns true on success and false on failure.
*
*
* @param mixed $config
* @return bool
*/
@ -64,12 +64,12 @@ class APC implements \Rhymix\Framework\Drivers\CacheInterface
{
return true;
}
/**
* Get the value of a key.
*
*
* This method returns null if the key was not found.
*
*
* @param string $key
* @return mixed
*/
@ -78,13 +78,13 @@ class APC implements \Rhymix\Framework\Drivers\CacheInterface
$value = apcu_fetch($key);
return $value === false ? null : $value;
}
/**
* Set the value to a key.
*
*
* This method returns true on success and false on failure.
* $ttl is measured in seconds. If it is zero, the key should not expire.
*
*
* @param string $key
* @param mixed $value
* @param int $ttl
@ -95,13 +95,13 @@ class APC implements \Rhymix\Framework\Drivers\CacheInterface
{
return apcu_store($key, $value, $ttl);
}
/**
* Delete a key.
*
*
* This method returns true on success and false on failure.
* If the key does not exist, it should return false.
*
*
* @param string $key
* @return bool
*/
@ -109,12 +109,12 @@ class APC implements \Rhymix\Framework\Drivers\CacheInterface
{
return apcu_delete($key);
}
/**
* Check if a key exists.
*
*
* This method returns true on success and false on failure.
*
*
* @param string $key
* @return bool
*/
@ -122,13 +122,13 @@ class APC implements \Rhymix\Framework\Drivers\CacheInterface
{
return apcu_exists($key);
}
/**
* Increase the value of a key by $amount.
*
*
* If the key does not exist, this method assumes that the current value is zero.
* This method returns the new value.
*
*
* @param string $key
* @param int $amount
* @return int
@ -143,13 +143,13 @@ class APC implements \Rhymix\Framework\Drivers\CacheInterface
}
return $result;
}
/**
* Decrease the value of a key by $amount.
*
*
* If the key does not exist, this method assumes that the current value is zero.
* This method returns the new value.
*
*
* @param string $key
* @param int $amount
* @return int
@ -164,12 +164,12 @@ class APC implements \Rhymix\Framework\Drivers\CacheInterface
}
return $result;
}
/**
* Clear all keys from the cache.
*
*
* This method returns true on success and false on failure.
*
*
* @return bool
*/
public function clear()

View file

@ -11,32 +11,32 @@ class Dummy extends File implements \Rhymix\Framework\Drivers\CacheInterface
* Set this flag to false to disable cache prefixes.
*/
public $prefix = false;
/**
* The singleton instance is stored here.
*/
protected static $_instance = null;
/**
* Dummy data is stored here.
*/
public $data = array();
/**
* Override the isSupported() method of the file driver.
*
*
* @return bool
*/
public static function isSupported()
{
return true;
}
/**
* Get the value of a key.
*
*
* This method returns null if the key was not found.
*
*
* @param string $key
* @return mixed
*/
@ -61,13 +61,13 @@ class Dummy extends File implements \Rhymix\Framework\Drivers\CacheInterface
return null;
}
}
/**
* Set the value to a key.
*
*
* This method returns true on success and false on failure.
* $ttl is measured in seconds. If it is zero, the key should not expire.
*
*
* @param string $key
* @param mixed $value
* @param int $ttl
@ -86,13 +86,13 @@ class Dummy extends File implements \Rhymix\Framework\Drivers\CacheInterface
return true;
}
}
/**
* Delete a key.
*
*
* This method returns true on success and false on failure.
* If the key does not exist, it should return false.
*
*
* @param string $key
* @return bool
*/
@ -112,12 +112,12 @@ class Dummy extends File implements \Rhymix\Framework\Drivers\CacheInterface
return false;
}
}
/**
* Check if a key exists.
*
*
* This method returns true on success and false on failure.
*
*
* @param string $key
* @return bool
*/
@ -125,12 +125,12 @@ class Dummy extends File implements \Rhymix\Framework\Drivers\CacheInterface
{
return parent::exists($key) || isset($this->data[$key]);
}
/**
* Clear all keys from the cache.
*
*
* This method returns true on success and false on failure.
*
*
* @return bool
*/
public function clear()

View file

@ -13,17 +13,17 @@ class File implements \Rhymix\Framework\Drivers\CacheInterface
* Set this flag to false to disable cache prefixes.
*/
public $prefix = false;
/**
* The singleton instance is stored here.
*/
protected static $_instance = null;
/**
* The cache directory.
*/
protected $_dir;
/**
* Direct invocation of the constructor is not permitted.
*/
@ -35,10 +35,10 @@ class File implements \Rhymix\Framework\Drivers\CacheInterface
Storage::createDirectory($this->_dir);
}
}
/**
* Create a new instance of the current cache driver, using the given settings.
*
*
* @param array $config
* @return void
*/
@ -50,23 +50,23 @@ class File implements \Rhymix\Framework\Drivers\CacheInterface
}
return static::$_instance;
}
/**
* Since Rhymix 2.1, This method always returns false.
* The file cache driver can only be used through the dummy driver.
*
*
* @return bool
*/
public static function isSupported()
{
return false;
}
/**
* Validate cache settings.
*
*
* This method returns true on success and false on failure.
*
*
* @param mixed $config
* @return bool
*/
@ -74,12 +74,12 @@ class File implements \Rhymix\Framework\Drivers\CacheInterface
{
return true;
}
/**
* Get the value of a key.
*
*
* This method returns null if the key was not found.
*
*
* @param string $key
* @return mixed
*/
@ -87,7 +87,7 @@ class File implements \Rhymix\Framework\Drivers\CacheInterface
{
$filename = $this->_getFilename($key);
$data = Storage::readPHPData($filename);
if ($data === false)
{
return null;
@ -102,13 +102,13 @@ class File implements \Rhymix\Framework\Drivers\CacheInterface
return $data[1];
}
}
/**
* Set the value to a key.
*
*
* This method returns true on success and false on failure.
* $ttl is measured in seconds. If it is zero, the key should not expire.
*
*
* @param string $key
* @param mixed $value
* @param int $ttl
@ -119,13 +119,13 @@ class File implements \Rhymix\Framework\Drivers\CacheInterface
{
return Storage::writePHPData($this->_getFilename($key), array($ttl ? (time() + $ttl) : 0, $value), $key);
}
/**
* Delete a key.
*
*
* This method returns true on success and false on failure.
* If the key does not exist, it should return false.
*
*
* @param string $key
* @return bool
*/
@ -133,12 +133,12 @@ class File implements \Rhymix\Framework\Drivers\CacheInterface
{
return Storage::delete($this->_getFilename($key));
}
/**
* Check if a key exists.
*
*
* This method returns true on success and false on failure.
*
*
* @param string $key
* @return bool
*/
@ -146,13 +146,13 @@ class File implements \Rhymix\Framework\Drivers\CacheInterface
{
return $this->get($key) !== null;
}
/**
* Increase the value of a key by $amount.
*
*
* If the key does not exist, this method assumes that the current value is zero.
* This method returns the new value.
*
*
* @param string $key
* @param int $amount
* @return int
@ -163,13 +163,13 @@ class File implements \Rhymix\Framework\Drivers\CacheInterface
$success = $this->set($key, $value + $amount, 0, true);
return $success ? ($value + $amount) : false;
}
/**
* Decrease the value of a key by $amount.
*
*
* If the key does not exist, this method assumes that the current value is zero.
* This method returns the new value.
*
*
* @param string $key
* @param int $amount
* @return int
@ -178,22 +178,22 @@ class File implements \Rhymix\Framework\Drivers\CacheInterface
{
return $this->incr($key, 0 - $amount);
}
/**
* Clear all keys from the cache.
*
*
* This method returns true on success and false on failure.
*
*
* @return bool
*/
public function clear()
{
return Storage::deleteDirectory($this->_dir) ? true : false;
}
/**
* Get the filename to store a key.
*
*
* @param string $key
* @return string
*/

View file

@ -11,18 +11,18 @@ class Memcached implements \Rhymix\Framework\Drivers\CacheInterface
* Set this flag to false to disable cache prefixes.
*/
public $prefix = true;
/**
* The singleton instance is stored here.
*/
protected static $_instance = null;
/**
* The Memcached connection is stored here.
*/
protected $_conn = null;
protected $_ext = null;
/**
* Direct invocation of the constructor is not permitted.
*/
@ -42,7 +42,7 @@ class Memcached implements \Rhymix\Framework\Drivers\CacheInterface
{
return;
}
foreach ($config as $url)
{
if (starts_with('/', $url))
@ -59,10 +59,10 @@ class Memcached implements \Rhymix\Framework\Drivers\CacheInterface
}
}
}
/**
* Create a new instance of the current cache driver, using the given settings.
*
*
* @param array $config
* @return void
*/
@ -74,24 +74,24 @@ class Memcached implements \Rhymix\Framework\Drivers\CacheInterface
}
return self::$_instance;
}
/**
* Check if the current cache driver is supported on this server.
*
*
* This method returns true on success and false on failure.
*
*
* @return bool
*/
public static function isSupported()
{
return class_exists('\\Memcached', false) || class_exists('\\Memcache', false);
}
/**
* Validate cache settings.
*
*
* This method returns true on success and false on failure.
*
*
* @param mixed $config
* @return bool
*/
@ -111,7 +111,7 @@ class Memcached implements \Rhymix\Framework\Drivers\CacheInterface
{
return false;
}
foreach ($config as $url)
{
if (starts_with('/', $url))
@ -127,7 +127,7 @@ class Memcached implements \Rhymix\Framework\Drivers\CacheInterface
}
}
}
for ($i = 0; $i < 5; $i++)
{
$key = 'rhymix:test:' . md5($i);
@ -136,12 +136,12 @@ class Memcached implements \Rhymix\Framework\Drivers\CacheInterface
}
return true;
}
/**
* Get the value of a key.
*
*
* This method returns null if the key was not found.
*
*
* @param string $key
* @return mixed
*/
@ -157,13 +157,13 @@ class Memcached implements \Rhymix\Framework\Drivers\CacheInterface
return $value;
}
}
/**
* Set the value to a key.
*
*
* This method returns true on success and false on failure.
* $ttl is measured in seconds. If it is zero, the key should not expire.
*
*
* @param string $key
* @param mixed $value
* @param int $ttl
@ -181,13 +181,13 @@ class Memcached implements \Rhymix\Framework\Drivers\CacheInterface
return $this->_conn->set($key, $value, MEMCACHE_COMPRESSED, $ttl);
}
}
/**
* Delete a key.
*
*
* This method returns true on success and false on failure.
* If the key does not exist, it should return false.
*
*
* @param string $key
* @return bool
*/
@ -195,12 +195,12 @@ class Memcached implements \Rhymix\Framework\Drivers\CacheInterface
{
return $this->_conn->delete($key);
}
/**
* Check if a key exists.
*
*
* This method returns true on success and false on failure.
*
*
* @param string $key
* @return bool
*/
@ -208,13 +208,13 @@ class Memcached implements \Rhymix\Framework\Drivers\CacheInterface
{
return $this->_conn->get($key) !== false;
}
/**
* Increase the value of a key by $amount.
*
*
* If the key does not exist, this method assumes that the current value is zero.
* This method returns the new value.
*
*
* @param string $key
* @param int $amount
* @return int
@ -229,13 +229,13 @@ class Memcached implements \Rhymix\Framework\Drivers\CacheInterface
}
return $result;
}
/**
* Decrease the value of a key by $amount.
*
*
* If the key does not exist, this method assumes that the current value is zero.
* This method returns the new value.
*
*
* @param string $key
* @param int $amount
* @return int
@ -250,12 +250,12 @@ class Memcached implements \Rhymix\Framework\Drivers\CacheInterface
}
return $result;
}
/**
* Clear all keys from the cache.
*
*
* This method returns true on success and false on failure.
*
*
* @return bool
*/
public function clear()

View file

@ -11,17 +11,17 @@ class Redis implements \Rhymix\Framework\Drivers\CacheInterface
* Set this flag to false to disable cache prefixes.
*/
public $prefix = true;
/**
* The singleton instance is stored here.
*/
protected static $_instance = null;
/**
* The Redis connection is stored here.
*/
protected $_conn = null;
/**
* Direct invocation of the constructor is not permitted.
*/
@ -71,10 +71,10 @@ class Redis implements \Rhymix\Framework\Drivers\CacheInterface
$this->_conn = null;
}
}
/**
* Create a new instance of the current cache driver, using the given settings.
*
*
* @param array $config
* @return void
*/
@ -86,24 +86,24 @@ class Redis implements \Rhymix\Framework\Drivers\CacheInterface
}
return self::$_instance;
}
/**
* Check if the current cache driver is supported on this server.
*
*
* This method returns true on success and false on failure.
*
*
* @return bool
*/
public static function isSupported()
{
return class_exists('\\Redis', false);
}
/**
* Validate cache settings.
*
*
* This method returns true on success and false on failure.
*
*
* @param mixed $config
* @return bool
*/
@ -150,12 +150,12 @@ class Redis implements \Rhymix\Framework\Drivers\CacheInterface
return false;
}
}
/**
* Get the value of a key.
*
*
* This method returns null if the key was not found.
*
*
* @param string $key
* @return mixed
*/
@ -169,7 +169,7 @@ class Redis implements \Rhymix\Framework\Drivers\CacheInterface
{
return null;
}
if ($value === false)
{
return null;
@ -178,7 +178,7 @@ class Redis implements \Rhymix\Framework\Drivers\CacheInterface
{
return $value;
}
$value = unserialize($value);
if ($value === false)
{
@ -186,13 +186,13 @@ class Redis implements \Rhymix\Framework\Drivers\CacheInterface
}
return $value;
}
/**
* Set the value to a key.
*
*
* This method returns true on success and false on failure.
* $ttl is measured in seconds. If it is zero, the key should not expire.
*
*
* @param string $key
* @param mixed $value
* @param int $ttl
@ -211,13 +211,13 @@ class Redis implements \Rhymix\Framework\Drivers\CacheInterface
return false;
}
}
/**
* Delete a key.
*
*
* This method returns true on success and false on failure.
* If the key does not exist, it should return false.
*
*
* @param string $key
* @return bool
*/
@ -232,12 +232,12 @@ class Redis implements \Rhymix\Framework\Drivers\CacheInterface
return false;
}
}
/**
* Check if a key exists.
*
*
* This method returns true on success and false on failure.
*
*
* @param string $key
* @return bool
*/
@ -252,13 +252,13 @@ class Redis implements \Rhymix\Framework\Drivers\CacheInterface
return false;
}
}
/**
* Increase the value of a key by $amount.
*
*
* If the key does not exist, this method assumes that the current value is zero.
* This method returns the new value.
*
*
* @param string $key
* @param int $amount
* @return int
@ -274,13 +274,13 @@ class Redis implements \Rhymix\Framework\Drivers\CacheInterface
return false;
}
}
/**
* Decrease the value of a key by $amount.
*
*
* If the key does not exist, this method assumes that the current value is zero.
* This method returns the new value.
*
*
* @param string $key
* @param int $amount
* @return int
@ -296,12 +296,12 @@ class Redis implements \Rhymix\Framework\Drivers\CacheInterface
return false;
}
}
/**
* Clear all keys from the cache.
*
*
* This method returns true on success and false on failure.
*
*
* @return bool
*/
public function clear()

View file

@ -13,18 +13,18 @@ class SQLite implements \Rhymix\Framework\Drivers\CacheInterface
* Set this flag to false to disable cache prefixes.
*/
public $prefix = false;
/**
* The singleton instance is stored here.
*/
protected static $_instance = null;
/**
* The database handle and prepared statements are stored here.
*/
protected $_dbh = null;
protected $_ps = array();
/**
* Direct invocation of the constructor is not permitted.
*/
@ -35,7 +35,7 @@ class SQLite implements \Rhymix\Framework\Drivers\CacheInterface
{
Storage::createDirectory($dir);
}
$key = substr(hash_hmac('sha256', $dir, config('crypto.authentication_key')), 0, 32);
$filename = "$dir/$key.db";
if (Storage::exists($filename))
@ -51,10 +51,10 @@ class SQLite implements \Rhymix\Framework\Drivers\CacheInterface
}
}
}
/**
* Connect to an SQLite3 database.
*
*
* @param string $filename
* @return void
*/
@ -65,10 +65,10 @@ class SQLite implements \Rhymix\Framework\Drivers\CacheInterface
$this->_dbh->exec('PRAGMA journal_mode = MEMORY');
$this->_dbh->exec('PRAGMA synchronous = OFF');
}
/**
* Create a new instance of the current cache driver, using the given settings.
*
*
* @param array $config
* @return void
*/
@ -80,24 +80,24 @@ class SQLite implements \Rhymix\Framework\Drivers\CacheInterface
}
return self::$_instance;
}
/**
* Check if the current cache driver is supported on this server.
*
*
* This method returns true on success and false on failure.
*
*
* @return bool
*/
public static function isSupported()
{
return class_exists('\\SQLite3', false) && config('crypto.authentication_key') !== null && stripos(\PHP_SAPI, 'win') === false;
}
/**
* Validate cache settings.
*
*
* This method returns true on success and false on failure.
*
*
* @param mixed $config
* @return bool
*/
@ -105,12 +105,12 @@ class SQLite implements \Rhymix\Framework\Drivers\CacheInterface
{
return true;
}
/**
* Get the value of a key.
*
*
* This method returns null if the key was not found.
*
*
* @param string $key
* @return mixed
*/
@ -122,14 +122,14 @@ class SQLite implements \Rhymix\Framework\Drivers\CacheInterface
{
return null;
}
$stmt->bindValue(':key', $key, \SQLITE3_TEXT);
$result = $stmt->execute();
if (!$result)
{
return null;
}
$row = $result->fetchArray(\SQLITE3_NUM);
if ($row)
{
@ -148,13 +148,13 @@ class SQLite implements \Rhymix\Framework\Drivers\CacheInterface
return null;
}
}
/**
* Set the value to a key.
*
*
* This method returns true on success and false on failure.
* $ttl is measured in seconds. If it is zero, the key should not expire.
*
*
* @param string $key
* @param mixed $value
* @param int $ttl
@ -169,19 +169,19 @@ class SQLite implements \Rhymix\Framework\Drivers\CacheInterface
{
return false;
}
$stmt->bindValue(':key', $key, \SQLITE3_TEXT);
$stmt->bindValue(':val', serialize($value), \SQLITE3_TEXT);
$stmt->bindValue(':exp', $ttl ? (time() + $ttl) : 0, \SQLITE3_INTEGER);
return $stmt->execute() ? true : false;
}
/**
* Delete a key.
*
*
* This method returns true on success and false on failure.
* If the key does not exist, it should return false.
*
*
* @param string $key
* @return bool
*/
@ -193,16 +193,16 @@ class SQLite implements \Rhymix\Framework\Drivers\CacheInterface
{
return false;
}
$stmt->bindValue(':key', $key, \SQLITE3_TEXT);
return $stmt->execute() ? true : false;
}
/**
* Check if a key exists.
*
*
* This method returns true on success and false on failure.
*
*
* @param string $key
* @return bool
*/
@ -214,7 +214,7 @@ class SQLite implements \Rhymix\Framework\Drivers\CacheInterface
{
return false;
}
$stmt->bindValue(':key', $key, \SQLITE3_TEXT);
$stmt->bindValue(':exp', time(), \SQLITE3_INTEGER);
$result = $stmt->execute();
@ -222,7 +222,7 @@ class SQLite implements \Rhymix\Framework\Drivers\CacheInterface
{
return false;
}
$row = $result->fetchArray(\SQLITE3_NUM);
if ($row)
{
@ -233,13 +233,13 @@ class SQLite implements \Rhymix\Framework\Drivers\CacheInterface
return false;
}
}
/**
* Increase the value of a key by $amount.
*
*
* If the key does not exist, this method assumes that the current value is zero.
* This method returns the new value.
*
*
* @param string $key
* @param int $amount
* @return int
@ -260,13 +260,13 @@ class SQLite implements \Rhymix\Framework\Drivers\CacheInterface
return false;
}
}
/**
* Decrease the value of a key by $amount.
*
*
* If the key does not exist, this method assumes that the current value is zero.
* This method returns the new value.
*
*
* @param string $key
* @param int $amount
* @return int
@ -275,12 +275,12 @@ class SQLite implements \Rhymix\Framework\Drivers\CacheInterface
{
return $this->incr($key, 0 - $amount);
}
/**
* Clear all keys from the cache.
*
*
* This method returns true on success and false on failure.
*
*
* @return bool
*/
public function clear()
@ -289,12 +289,12 @@ class SQLite implements \Rhymix\Framework\Drivers\CacheInterface
{
$this->_dbh->exec('DROP TABLE cache_' . $i);
}
for ($i = 0; $i < 32; $i++)
{
$this->_dbh->exec('CREATE TABLE cache_' . $i . ' (k TEXT PRIMARY KEY, v TEXT, exp INT)');
}
return true;
}
}

View file

@ -11,12 +11,12 @@ abstract class Base implements \Rhymix\Framework\Drivers\MailInterface
* The configuration is stored here.
*/
protected $_config = null;
/**
* The mailer instance is stored here.
*/
protected $_mailer = null;
/**
* Direct invocation of the constructor is not permitted.
*/
@ -24,10 +24,10 @@ abstract class Base implements \Rhymix\Framework\Drivers\MailInterface
{
$this->_config = $config;
}
/**
* Create a new instance of the current mail driver, using the given settings.
*
*
* @param array $config
* @return object
*/
@ -35,74 +35,74 @@ abstract class Base implements \Rhymix\Framework\Drivers\MailInterface
{
return new static($config);
}
/**
* Get the human-readable name of this mail driver.
*
*
* @return string
*/
public static function getName()
{
return class_basename(get_called_class());
}
/**
* Get the list of configuration fields required by this mail driver.
*
*
* @return array
*/
public static function getRequiredConfig()
{
return array();
}
/**
* Get the list of API types supported by this mail driver.
*
*
* @return array
*/
public static function getAPITypes()
{
return array();
}
/**
* Get the SPF hint.
*
*
* @return string
*/
public static function getSPFHint()
{
return '';
}
/**
* Get the DKIM hint.
*
*
* @return string
*/
public static function getDKIMHint()
{
return '';
}
/**
* Check if the current mail driver is supported on this server.
*
*
* This method returns true on success and false on failure.
*
*
* @return bool
*/
public static function isSupported()
{
return false;
}
/**
* Send a message.
*
*
* This method returns true on success and false on failure.
*
*
* @param object $message
* @return bool
*/

View file

@ -9,21 +9,21 @@ class Dummy extends Base implements \Rhymix\Framework\Drivers\MailInterface
{
/**
* Check if the current mail driver is supported on this server.
*
*
* This method returns true on success and false on failure.
*
*
* @return bool
*/
public static function isSupported()
{
return true;
}
/**
* Send a message.
*
*
* This method returns true on success and false on failure.
*
*
* @param object $message
* @return bool
*/

View file

@ -15,44 +15,44 @@ class MailFunction extends Base implements \Rhymix\Framework\Drivers\MailInterfa
include_once \RX_BASEDIR . 'common/libraries/swift_mail.php';
$this->mailer = new \Swift_Mailer(new \Swift_MailTransport);
}
/**
* Get the human-readable name of this mail driver.
*
*
* @return string
*/
public static function getName()
{
return 'mail() Function';
}
/**
* Get the SPF hint.
*
*
* @return string
*/
public static function getSPFHint()
{
return 'ip4:$SERVER_ADDR';
}
/**
* Check if the current mail driver is supported on this server.
*
*
* This method returns true on success and false on failure.
*
*
* @return bool
*/
public static function isSupported()
{
return true;
}
/**
* Send a message.
*
*
* This method returns true on success and false on failure.
*
*
* @param object $message
* @return bool
*/
@ -67,7 +67,7 @@ class MailFunction extends Base implements \Rhymix\Framework\Drivers\MailInterfa
$message->errors[] = $e->getMessage();
return false;
}
foreach ($errors as $error)
{
$message->errors[] = $error;

View file

@ -11,54 +11,54 @@ class Mailgun extends Base implements \Rhymix\Framework\Drivers\MailInterface
* The API URL.
*/
protected static $_url = 'https://api.mailgun.net/v3';
/**
* Get the list of configuration fields required by this mail driver.
*
*
* @return array
*/
public static function getRequiredConfig()
{
return array('api_domain', 'api_token');
}
/**
* Get the SPF hint.
*
*
* @return string
*/
public static function getSPFHint()
{
return 'include:mailgun.org';
}
/**
* Get the DKIM hint.
*
*
* @return string
*/
public static function getDKIMHint()
{
return 'mailo._domainkey';
}
/**
* Check if the current mail driver is supported on this server.
*
*
* This method returns true on success and false on failure.
*
*
* @return bool
*/
public static function isSupported()
{
return true;
}
/**
* Send a message.
*
*
* This method returns true on success and false on failure.
*
*
* @param object $message
* @return bool
*/
@ -87,7 +87,7 @@ class Mailgun extends Base implements \Rhymix\Framework\Drivers\MailInterface
$recipients[] = $address;
}
}
// Prepare data and options for Requests.
$boundary = str_repeat('-', 24) . substr(md5(mt_rand()), 0, 16);
$headers = array(
@ -112,12 +112,12 @@ class Mailgun extends Base implements \Rhymix\Framework\Drivers\MailInterface
'timeout' => 5,
'useragent' => 'PHP',
);
// Send the API request.
$url = self::$_url . '/' . $this->_config['api_domain'] . '/messages.mime';
$request = \Requests::post($url, $headers, $data, $options);
$result = @json_decode($request->body);
// Parse the result.
if (!$result)
{

View file

@ -19,30 +19,30 @@ class Mandrill extends SMTP implements \Rhymix\Framework\Drivers\MailInterface
$config['smtp_pass'] = $config['api_token'];
parent::__construct($config);
}
/**
* Get the list of configuration fields required by this mail driver.
*
*
* @return array
*/
public static function getRequiredConfig()
{
return array('api_user', 'api_token');
}
/**
* Get the SPF hint.
*
*
* @return string
*/
public static function getSPFHint()
{
return 'include:spf.mandrillapp.com';
}
/**
* Get the DKIM hint.
*
*
* @return string
*/
public static function getDKIMHint()

View file

@ -19,30 +19,30 @@ class Postmark extends SMTP implements \Rhymix\Framework\Drivers\MailInterface
$config['smtp_pass'] = $config['api_token'];
parent::__construct($config);
}
/**
* Get the list of configuration fields required by this mail driver.
*
*
* @return array
*/
public static function getRequiredConfig()
{
return array('api_token');
}
/**
* Get the SPF hint.
*
*
* @return string
*/
public static function getSPFHint()
{
return 'include:spf.mtasv.net';
}
/**
* Get the DKIM hint.
*
*
* @return string
*/
public static function getDKIMHint()

View file

@ -11,54 +11,54 @@ class SendGrid extends Base implements \Rhymix\Framework\Drivers\MailInterface
* The API URL.
*/
protected static $_url = 'https://api.sendgrid.com/v3/mail/send';
/**
* Get the list of configuration fields required by this mail driver.
*
*
* @return array
*/
public static function getRequiredConfig()
{
return array('api_token');
}
/**
* Get the SPF hint.
*
*
* @return string
*/
public static function getSPFHint()
{
return 'include:sendgrid.net';
}
/**
* Get the DKIM hint.
*
*
* @return string
*/
public static function getDKIMHint()
{
return 'smtpapi._domainkey';
}
/**
* Check if the current mail driver is supported on this server.
*
*
* This method returns true on success and false on failure.
*
*
* @return bool
*/
public static function isSupported()
{
return true;
}
/**
* Send a message.
*
*
* This method returns true on success and false on failure.
*
*
* @param object $message
* @return bool
*/
@ -70,11 +70,11 @@ class SendGrid extends Base implements \Rhymix\Framework\Drivers\MailInterface
$message->errors[] = 'SendGrid: Please use API key (token) instead of username and password.';
return;
}
// Initialize the request data.
$data = [];
$data['personalizations'] = [];
// Assemble the list of recipients.
$to_list = [];
if ($to = $message->message->getTo())
@ -103,7 +103,7 @@ class SendGrid extends Base implements \Rhymix\Framework\Drivers\MailInterface
}
$data['personalizations'][] = ['bcc' => $bcc_list];
}
// Set the sender information.
$from = $message->message->getFrom();
if ($from)
@ -114,21 +114,21 @@ class SendGrid extends Base implements \Rhymix\Framework\Drivers\MailInterface
$data['from']['name'] = array_first($from);
}
}
// Set the Reply-To address.
$replyTo = $message->message->getReplyTo();
if ($replyTo)
{
$data['reply_to']['email'] = array_first_key($from);
}
// Set the subject.
$data['subject'] = strval($message->getSubject()) ?: 'Title';
// Set the body.
$data['content'][0]['type'] = $message->getContentType();
$data['content'][0]['value'] = $message->getBody();
// Add attachments.
foreach ($message->getAttachments() as $attachment)
{
@ -142,7 +142,7 @@ class SendGrid extends Base implements \Rhymix\Framework\Drivers\MailInterface
}
$data['attachments'][] = $file_info;
}
// Prepare data and options for Requests.
$headers = array(
'Authorization' => 'Bearer ' . $this->_config['api_token'],
@ -152,11 +152,11 @@ class SendGrid extends Base implements \Rhymix\Framework\Drivers\MailInterface
'timeout' => 8,
'useragent' => 'PHP',
);
// Send the API request.
$request = \Requests::post(self::$_url, $headers, json_encode($data), $options);
$response_code = intval($request->status_code);;
// Parse the result.
if (!$response_code)
{
@ -168,7 +168,7 @@ class SendGrid extends Base implements \Rhymix\Framework\Drivers\MailInterface
$message->errors[] = 'SendGrid: Response code ' . $response_code . ': ' . $request->body;
return false;
}
return true;
}
}

View file

@ -11,7 +11,7 @@ class SES extends SMTP implements \Rhymix\Framework\Drivers\MailInterface
* Cache the message here for debug access.
*/
protected $_message;
/**
* Direct invocation of the constructor is not permitted.
*/
@ -22,30 +22,30 @@ class SES extends SMTP implements \Rhymix\Framework\Drivers\MailInterface
$config['smtp_security'] = 'tls';
parent::__construct($config);
}
/**
* Get the human-readable name of this mail driver.
*
*
* @return string
*/
public static function getName()
{
return 'Amazon SES (SMTP)';
}
/**
* Get the list of configuration fields required by this mail driver.
*
*
* @return array
*/
public static function getRequiredConfig()
{
return array('smtp_user', 'smtp_pass', 'api_type');
}
/**
* Get the list of API types supported by this mail driver.
*
*
* @return array
*/
public static function getAPITypes()
@ -57,20 +57,20 @@ class SES extends SMTP implements \Rhymix\Framework\Drivers\MailInterface
'ap-southeast-1', 'ap-southeast-2', 'ap-south-1',
);
}
/**
* Get the SPF hint.
*
*
* @return string
*/
public static function getSPFHint()
{
return 'include:amazonses.com';
}
/**
* Get the DKIM hint.
*
*
* @return string
*/
public static function getDKIMHint()

View file

@ -23,34 +23,34 @@ class SMTP extends Base implements \Rhymix\Framework\Drivers\MailInterface
}
$this->mailer = new \Swift_Mailer($transport);
}
/**
* Get the list of configuration fields required by this mail driver.
*
*
* @return array
*/
public static function getRequiredConfig()
{
return array('smtp_host', 'smtp_port', 'smtp_security', 'smtp_user', 'smtp_pass');
}
/**
* Check if the current mail driver is supported on this server.
*
*
* This method returns true on success and false on failure.
*
*
* @return bool
*/
public static function isSupported()
{
return function_exists('proc_open');
}
/**
* Send a message.
*
*
* This method returns true on success and false on failure.
*
*
* @param object $message
* @return bool
*/
@ -65,7 +65,7 @@ class SMTP extends Base implements \Rhymix\Framework\Drivers\MailInterface
$message->errors[] = $e->getMessage();
return false;
}
foreach ($errors as $error)
{
$message->errors[] = 'Failed to send to ' . $error;

View file

@ -11,54 +11,54 @@ class SparkPost extends Base implements \Rhymix\Framework\Drivers\MailInterface
* The API URL.
*/
protected static $_url = 'https://api.sparkpost.com/api/v1/transmissions';
/**
* Get the list of configuration fields required by this mail driver.
*
*
* @return array
*/
public static function getRequiredConfig()
{
return array('api_token');
}
/**
* Get the SPF hint.
*
*
* @return string
*/
public static function getSPFHint()
{
return 'include:sparkpostmail.com';
}
/**
* Get the DKIM hint.
*
*
* @return string
*/
public static function getDKIMHint()
{
return '********._domainkey';
}
/**
* Check if the current mail driver is supported on this server.
*
*
* This method returns true on success and false on failure.
*
*
* @return bool
*/
public static function isSupported()
{
return true;
}
/**
* Send a message.
*
*
* This method returns true on success and false on failure.
*
*
* @param object $message
* @return bool
*/
@ -87,7 +87,7 @@ class SparkPost extends Base implements \Rhymix\Framework\Drivers\MailInterface
$recipients[] = array('address' => array('name' => $name, 'email' => $address));
}
}
// Prepare data and options for Requests.
$headers = array(
'Authorization' => $this->_config['api_token'],
@ -106,11 +106,11 @@ class SparkPost extends Base implements \Rhymix\Framework\Drivers\MailInterface
'timeout' => 5,
'useragent' => 'PHP',
);
// Send the API request.
$request = \Requests::post(self::$_url, $headers, $data, $options);
$result = @json_decode($request->body);
// Parse the result.
if (!$result)
{
@ -124,7 +124,7 @@ class SparkPost extends Base implements \Rhymix\Framework\Drivers\MailInterface
$message->errors[] = 'SparkPost: ' . $error->message . ': ' . $error->description . ' (code ' . $error->code . ')';
}
}
if ($result->results)
{
return $result->results->total_accepted_recipients > 0 ? true : false;

View file

@ -11,7 +11,7 @@ class Woorimail extends Base implements \Rhymix\Framework\Drivers\MailInterface
* The API URL.
*/
protected static $_url = 'https://woorimail.com/index.php';
/**
* Error codes and messages.
*/
@ -25,69 +25,69 @@ class Woorimail extends Base implements \Rhymix\Framework\Drivers\MailInterface
'me_007' => '이메일과 등록일 갯수가 다릅니다.',
'me_008' => '이메일 갯수가 2,000개가 넘습니다.',
'me_009' => 'type이 api가 아닙니다.',
'me_010' => '인증키가 없습니다.',
'me_010' => '인증키가 없습니다.',
'me_011' => '인증키가 부정확합니다.',
'me_012' => '포인트가 부족합니다.',
'me_013' => '전용채널에 도메인이 등록되어 있지 않습니다.',
);
/**
* Get the list of configuration fields required by this mail driver.
*
*
* @return array
*/
public static function getRequiredConfig()
{
return array('api_domain', 'api_token', 'api_type');
}
/**
* Get the list of API types supported by this mail driver.
*
*
* @return array
*/
public static function getAPITypes()
{
return array('free', 'paid');
}
/**
* Get the SPF hint.
*
*
* @return string
*/
public static function getSPFHint()
{
return 'include:woorimail.com';
}
/**
* Get the DKIM hint.
*
*
* @return string
*/
public static function getDKIMHint()
{
return '';
}
/**
* Check if the current mail driver is supported on this server.
*
*
* This method returns true on success and false on failure.
*
*
* @return bool
*/
public static function isSupported()
{
return true;
}
/**
* Send a message.
*
*
* This method returns true on success and false on failure.
*
*
* @param object $message
* @return bool
*/
@ -112,7 +112,7 @@ class Woorimail extends Base implements \Rhymix\Framework\Drivers\MailInterface
'callback' => '',
'is_sendok' => 'W',
);
// Fill the sender info.
$from = $message->message->getFrom();
foreach($from as $email => $name)
@ -137,7 +137,7 @@ class Woorimail extends Base implements \Rhymix\Framework\Drivers\MailInterface
$data['sender_email'] = $replyTo;
}
}
// Fill the recipient info.
if ($to = $message->message->getTo())
{
@ -166,7 +166,7 @@ class Woorimail extends Base implements \Rhymix\Framework\Drivers\MailInterface
$data['member_regdate'] = implode(',', array_fill(0, count($data['receiver_email']), date('YmdHis')));
$data['receiver_email'] = implode(',', $data['receiver_email']);
$data['receiver_nickname'] = implode(',', $data['receiver_nickname']);
// Define connection options.
$headers = array(
'Accept' => 'application/json, text/javascript, */*; q=0.1',
@ -175,7 +175,7 @@ class Woorimail extends Base implements \Rhymix\Framework\Drivers\MailInterface
'timeout' => 5,
'useragent' => 'PHP',
);
// Send the API request.
try
{
@ -187,7 +187,7 @@ class Woorimail extends Base implements \Rhymix\Framework\Drivers\MailInterface
$message->errors[] = 'Woorimail: ' . $e->getMessage();
return false;
}
// Parse the result.
if (!$result)
{

View file

@ -12,34 +12,34 @@ class APNs extends Base implements \Rhymix\Framework\Drivers\PushInterface
*/
protected static $_required_config = array('certificate', 'passphrase');
protected static $_optional_config = array();
/**
* Get the human-readable name of this Push driver.
*
*
* @return string
*/
public static function getName(): string
{
return 'APNs';
}
/**
* Check if the current Push driver is supported on this server.
*
*
* This method returns true on success and false on failure.
*
*
* @return bool
*/
public static function isSupported(): bool
{
return true;
}
/**
* Send a message.
*
*
* This method returns true on success and false on failure.
*
*
* @param object $message
* @param array $tokens
* @return \stdClass
@ -86,7 +86,7 @@ class APNs extends Base implements \Rhymix\Framework\Drivers\PushInterface
$output->success[] = $token;
fclose($fp);
}
return $output;
}
}

View file

@ -13,13 +13,13 @@ abstract class Base implements PushInterface
* The configuration is stored here.
*/
protected $_config = null;
/**
* Config keys used by this driver are stored here.
*/
protected static $_required_config = array();
protected static $_optional_config = array();
/**
* Direct invocation of the constructor is not permitted.
*/
@ -27,10 +27,10 @@ abstract class Base implements PushInterface
{
$this->_config = $config;
}
/**
* Create a new instance of the current Push driver, using the given settings.
*
*
* @param array $config
* @return PushInterface
*/
@ -38,54 +38,54 @@ abstract class Base implements PushInterface
{
return new static($config);
}
/**
* Get the human-readable name of this Push driver.
*
*
* @return string
*/
public static function getName(): string
{
return class_basename(get_called_class());
}
/**
* Get the list of configuration fields required by this Push driver.
*
*
* @return array
*/
public static function getRequiredConfig(): array
{
return static::$_required_config;
}
/**
* Get the list of configuration fields optionally used by this Push driver.
*
*
* @return array
*/
public static function getOptionalConfig(): array
{
return static::$_optional_config;
}
/**
* Check if the current Push driver is supported on this server.
*
*
* This method returns true on success and false on failure.
*
*
* @return bool
*/
public static function isSupported(): bool
{
return false;
}
/**
* Send a message.
*
*
* This method returns true on success and false on failure.
*
*
* @param object $message
* @param array $tokens
* @return \stdClass

View file

@ -12,34 +12,34 @@ class FCM extends Base implements \Rhymix\Framework\Drivers\PushInterface
*/
protected static $_required_config = array('api_key');
protected static $_optional_config = array();
/**
* Get the human-readable name of this Push driver.
*
*
* @return string
*/
public static function getName(): string
{
return 'Google FCM';
}
/**
* Check if the current Push driver is supported on this server.
*
*
* This method returns true on success and false on failure.
*
*
* @return bool
*/
public static function isSupported(): bool
{
return true;
}
/**
* Send a message.
*
*
* This method returns true on success and false on failure.
*
*
* @param object $message
* @param array $tokens
* @return \stdClass

View file

@ -23,34 +23,34 @@ class ApiStore extends Base implements \Rhymix\Framework\Drivers\SMSInterface
'mms_supported' => false,
'delay_supported' => true,
);
/**
* Config keys used by this driver are stored here.
*/
protected static $_required_config = array('api_user', 'api_key');
/**
* Check if the current SMS driver is supported on this server.
*
*
* This method returns true on success and false on failure.
*
*
* @return bool
*/
public static function isSupported()
{
return true;
}
/**
* Store the last response.
*/
protected $_last_response = '';
/**
* Send a message.
*
*
* This method returns true on success and false on failure.
*
*
* @param array $messages
* @param object $original
* @return bool
@ -58,7 +58,7 @@ class ApiStore extends Base implements \Rhymix\Framework\Drivers\SMSInterface
public function send(array $messages, \Rhymix\Framework\SMS $original)
{
$status = true;
foreach ($messages as $i => $message)
{
$data = array();
@ -69,7 +69,7 @@ class ApiStore extends Base implements \Rhymix\Framework\Drivers\SMSInterface
{
$data['subject'] = $message->subject;
}
$result = $this->_apiCall(sprintf('message/%s', strtolower($message->type)), $data);
if (!$result)
{
@ -81,13 +81,13 @@ class ApiStore extends Base implements \Rhymix\Framework\Drivers\SMSInterface
$message->errors[] = 'ApiStore API error: ' . $result->result_code . ' ' . $result->result_message;
}
}
return $status;
}
/**
* API call.
*
*
* @param string $url
* @param array $data
* @param string $method (optional)
@ -106,12 +106,12 @@ class ApiStore extends Base implements \Rhymix\Framework\Drivers\SMSInterface
$version = 1;
}
$url = sprintf('http://api.apistore.co.kr/ppurio/%d/%s/%s', $version, trim($url, '/'), $this->_config['api_user']);
// Set the API key in the header.
$headers = array(
'x-waple-authorization' => $this->_config['api_key'],
);
// Send the API reqeust.
if ($method === 'GET')
{
@ -128,10 +128,10 @@ class ApiStore extends Base implements \Rhymix\Framework\Drivers\SMSInterface
$result = @json_decode($this->_last_response);
return $result ?: false;
}
/**
* Fetch the last API response.
*
*
* @return string
*/
protected function _getLastResponse()

View file

@ -11,18 +11,18 @@ abstract class Base implements \Rhymix\Framework\Drivers\SMSInterface
* The configuration is stored here.
*/
protected $_config = null;
/**
* The driver specification is stored here.
*/
protected static $_spec = array();
/**
* Config keys used by this driver are stored here.
*/
protected static $_required_config = array();
protected static $_optional_config = array();
/**
* Direct invocation of the constructor is not permitted.
*/
@ -30,10 +30,10 @@ abstract class Base implements \Rhymix\Framework\Drivers\SMSInterface
{
$this->_config = $config;
}
/**
* Create a new instance of the current SMS driver, using the given settings.
*
*
* @param array $config
* @return object
*/
@ -41,74 +41,74 @@ abstract class Base implements \Rhymix\Framework\Drivers\SMSInterface
{
return new static($config);
}
/**
* Get the human-readable name of this SMS driver.
*
*
* @return string
*/
public static function getName()
{
return class_basename(get_called_class());
}
/**
* Get the list of configuration fields required by this SMS driver.
*
*
* @return array
*/
public static function getRequiredConfig()
{
return static::$_required_config;
}
/**
* Get the list of configuration fields optionally used by this SMS driver.
*
*
* @return array
*/
public static function getOptionalConfig()
{
return static::$_optional_config;
}
/**
* Get the list of API types supported by this SMS driver.
*
*
* @return array
*/
public static function getAPITypes()
{
return array();
}
/**
* Get the spec for this SMS driver.
*
*
* @return array
*/
public static function getAPISpec()
{
return static::$_spec;
}
/**
* Check if the current SMS driver is supported on this server.
*
*
* This method returns true on success and false on failure.
*
*
* @return bool
*/
public static function isSupported()
{
return false;
}
/**
* Send a message.
*
*
* This method returns true on success and false on failure.
*
*
* @param array $messages
* @param object $original
* @return bool

View file

@ -31,30 +31,30 @@ class CoolSMS extends Base implements \Rhymix\Framework\Drivers\SMSInterface
'image_max_filesize' => 300000,
'delay_supported' => true,
);
/**
* Config keys used by this driver are stored here.
*/
protected static $_required_config = array('api_key', 'api_secret');
protected static $_optional_config = array('sender_key');
/**
* Check if the current SMS driver is supported on this server.
*
*
* This method returns true on success and false on failure.
*
*
* @return bool
*/
public static function isSupported()
{
return true;
}
/**
* Send a message.
*
*
* This method returns true on success and false on failure.
*
*
* @param array $messages
* @param object $original
* @return bool
@ -111,7 +111,7 @@ class CoolSMS extends Base implements \Rhymix\Framework\Drivers\SMSInterface
$status = false;
}
}
return $status;
}
catch (\Nurigo\Exceptions\CoolsmsException $e)

View file

@ -31,29 +31,29 @@ class Dummy extends Base implements \Rhymix\Framework\Drivers\SMSInterface
'image_max_filesize' => 300000,
'delay_supported' => true,
);
/**
* Sent messages are stored here for debugging and testing.
*/
protected $_sent_messages = array();
/**
* Check if the current SMS driver is supported on this server.
*
*
* This method returns true on success and false on failure.
*
*
* @return bool
*/
public static function isSupported()
{
return true;
}
/**
* Send a message.
*
*
* This method returns true on success and false on failure.
*
*
* @param array $messages
* @param object $original
* @return bool
@ -66,20 +66,20 @@ class Dummy extends Base implements \Rhymix\Framework\Drivers\SMSInterface
}
return true;
}
/**
* Get sent messages.
*
*
* @return array
*/
public function getSentMessages()
{
return $this->_sent_messages;
}
/**
* Reset sent messages.
*
*
* @return void
*/
public function resetSentMessages()

View file

@ -11,7 +11,7 @@ class iwinv extends Base implements \Rhymix\Framework\Drivers\SMSInterface
* API endpoint URL (fallback if URL is not explicitly configured)
*/
const LEGACY_API_URL = 'https://sms.service.iwinv.kr/send/';
/**
* API specifications.
*/
@ -54,10 +54,10 @@ class iwinv extends Base implements \Rhymix\Framework\Drivers\SMSInterface
{
return true;
}
/**
* Get the list of API URLs supported by this driver.
*
*
* @return array
*/
public static function getApiUrls()
@ -81,7 +81,7 @@ class iwinv extends Base implements \Rhymix\Framework\Drivers\SMSInterface
{
$status = true;
$curl = null;
foreach ($messages as $i => $message)
{
// Authentication
@ -89,7 +89,7 @@ class iwinv extends Base implements \Rhymix\Framework\Drivers\SMSInterface
'Content-Type: multipart/form-data',
'secret: ' . base64_encode($this->_config['api_key'] . '&' . $this->_config['api_secret']),
);
// Sender and recipient
$data = array();
$data['from'] = str_replace('-', '', \Rhymix\Framework\Korea::formatPhoneNumber($message->from));
@ -100,26 +100,26 @@ class iwinv extends Base implements \Rhymix\Framework\Drivers\SMSInterface
{
$data['to'] = array_first($data['to']);
}
// Subject and content
if ($message->type === 'LMS' && $message->subject)
{
$data['title'] = $message->subject;
}
$data['text'] = $message->content;
// Image attachment
if ($message->image)
{
$data['image'] = curl_file_create(realpath($message->image));
}
// Set delay
if ($message->delay && $message->delay > time() + 900)
{
$data['date'] = gmdate('Y-m-d H:i:s', $message->delay + (3600 * 9));
}
// Set API URL
if (!empty($this->_config['api_url']))
{
@ -129,7 +129,7 @@ class iwinv extends Base implements \Rhymix\Framework\Drivers\SMSInterface
{
$api_url = self::LEGACY_API_URL;
}
// We need to use curl because Filehandler::getRemoteResource() doesn't work with this API for some reason.
if (!$curl)
{
@ -143,7 +143,7 @@ class iwinv extends Base implements \Rhymix\Framework\Drivers\SMSInterface
curl_setopt($curl, \CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($curl);
$err = curl_error($curl);
// Check the result.
if ($err)
{
@ -161,12 +161,12 @@ class iwinv extends Base implements \Rhymix\Framework\Drivers\SMSInterface
$status = false;
}
}
if ($curl)
{
@curl_close($curl);
}
return $status;
}
}

View file

@ -23,29 +23,29 @@ class Ppurio extends Base implements \Rhymix\Framework\Drivers\SMSInterface
'mms_supported' => false,
'delay_supported' => true,
);
/**
* Config keys used by this driver are stored here.
*/
protected static $_required_config = array('api_user');
/**
* Check if the current SMS driver is supported on this server.
*
*
* This method returns true on success and false on failure.
*
*
* @return bool
*/
public static function isSupported()
{
return true;
}
/**
* Send a message.
*
*
* This method returns true on success and false on failure.
*
*
* @param array $messages
* @param object $original
* @return bool
@ -59,26 +59,26 @@ class Ppurio extends Base implements \Rhymix\Framework\Drivers\SMSInterface
// Authentication and basic information
$data = array();
$data['userid'] = $this->_config['api_user'];
// Sender and recipient
$data['callback'] = preg_replace('/[^0-9]/', '', $message->from);
$data['phone'] = implode('|', array_map(function($num) {
return preg_replace('/[^0-9]/', '', $num);
}, $message->to));
// Subject and content
if ($message->type === 'LMS' && $message->subject)
{
$data['subject'] = $message->subject;
}
$data['msg'] = $message->content;
// Set delay
if ($message->delay && $message->delay > time() + 600)
{
$data['appdate'] = gmdate('YmdHis', $message->delay + (3600 * 9));
}
// Send!
$url = 'https://www.ppurio.com/api/send_utf8_json.php';
$result = \FileHandler::getRemoteResource($url, $data, 5, 'POST');
@ -97,7 +97,7 @@ class Ppurio extends Base implements \Rhymix\Framework\Drivers\SMSInterface
}
}
}
return $status;
}
}

View file

@ -8,7 +8,7 @@ namespace Rhymix\Framework\Drivers\SMS;
class SolAPI extends Base implements \Rhymix\Framework\Drivers\SMSInterface
{
const appId = 'PAOe9c8ftH8R';
/**
* API specifications.
*/
@ -115,7 +115,7 @@ class SolAPI extends Base implements \Rhymix\Framework\Drivers\SMSInterface
}
$groupArray[] = $options;
}
if($groupMessage)
{
$jsonObject = new \stdClass();
@ -156,7 +156,7 @@ class SolAPI extends Base implements \Rhymix\Framework\Drivers\SMSInterface
return true;
}
/**
* Create header string for http protocol
* @param $config
@ -212,7 +212,7 @@ class SolAPI extends Base implements \Rhymix\Framework\Drivers\SMSInterface
private function request($method, $url, $data = false)
{
$url = 'https://api.solapi.com/' . $url;
if(!$data)
{
$data = null;
@ -222,7 +222,7 @@ class SolAPI extends Base implements \Rhymix\Framework\Drivers\SMSInterface
$data = json_encode($data);
}
$result = \FileHandler::getRemoteResource($url, $data, 3, $method, 'application/json', array('Authorization' => $this->getHeader()));
return $result;
}
}

View file

@ -11,10 +11,10 @@ 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
@ -26,62 +26,62 @@ class FileContentFilter
{
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)
*
@ -100,10 +100,10 @@ class FileContentFilter
{
return false;
}
return true;
}
/**
* Check XML file for external entity inclusion.
*
@ -118,10 +118,10 @@ class FileContentFilter
{
return false;
}
return true;
}
/**
* Check HTML file for PHP code, server-side includes, and other nastiness.
*
@ -136,18 +136,18 @@ class FileContentFilter
{
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
@ -169,10 +169,10 @@ class FileContentFilter
}
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

View file

@ -9,7 +9,7 @@ class FilenameFilter
{
/**
* Remove illegal and dangerous characters from a filename.
*
*
* @param string $filename
* @return string
*/
@ -19,27 +19,27 @@ class FilenameFilter
$illegal = array('\\', '/', '<', '>', '{', '}', ':', ';', '|', '"', '~', '`', '$', '%', '^', '*', '?');
$replace = array('', '', '(', ')', '(', ')', '_', ',', '_', '', '_', '\'', '_', '_', '_', '', '');
$filename = str_replace($illegal, $replace, $filename);
// Remove control characters.
$filename = preg_replace('/([\\x00-\\x1f\\x7f\\xff]+)/u', '', $filename);
// Standardize whitespace characters.
$filename = trim(preg_replace('/[\\pZ\\pC]+/u', ' ', $filename));
// Remove excess spaces and replacement characters.
$filename = trim($filename, ' .-_');
$filename = preg_replace('/__+/', '_', $filename);
$filename = preg_replace('/\.\.+/', '.', $filename);
// Clean up unnecessary encodings.
$filename = strtr($filename, array('&amp;' => '&'));
// Change .php files to .phps to make them non-executable.
if (strtolower(substr($filename, strlen($filename) - 4)) === '.php')
{
$filename = substr($filename, 0, strlen($filename) - 4) . '.phps';
}
// Truncate filenames over 127 chars long, or extensions over 16 chars long.
if (mb_strlen($filename, 'UTF-8') > 127)
{
@ -47,13 +47,13 @@ class FilenameFilter
if (mb_strlen($extension, 'UTF-8') > 16) $extension = mb_substr($extension, 0, 16);
$filename = mb_substr($filename, 0, 127 - mb_strlen($extension)) . $extension;
}
return $filename;
}
/**
* Clean a path to remove ./, ../, trailing slashes, etc.
*
*
* @param string $path
* @return string
*/
@ -64,35 +64,35 @@ class FilenameFilter
{
$path = \RX_BASEDIR . $path;
}
// Convert backslashes to forward slashes.
$path = str_replace('\\', '/', $path);
// Remove querystrings and URL fragments.
if (($querystring = strpbrk($path, '?#')) !== false)
{
$path = substr($path, 0, -1 * strlen($querystring));
}
// Remove single dots, three or more dots, and duplicate slashes.
$path = preg_replace(array(
'@(?<!^|^http:|^https:)/{2,}@',
'@/(?:(?:\.|\.{3,})/)+@',
), '/', $path);
// Remove double dots and the preceding directory.
while (preg_match('@/(?!\.\.)[^/]+/\.\.(?:/|$)@', $path, $matches))
{
$path = str_replace($matches[0], '/', $path);
}
// Trim trailing slashes.
return rtrim($path, '/');
}
/**
* Check if a file has an extension that would allow direct download.
*
*
* @param string $filename
* @param bool $include_multimedia (optional)
* @return bool
@ -103,7 +103,7 @@ class FilenameFilter
$audios = 'mp3|wav|ogg|flac|aac';
$videos = 'mp4|webm|ogv';
$legacy = 'avi|as[fx]|flv|m4[av]|midi?|mkv|moo?v|mpe?g|qt|r[am]m?|wm[av]';
if ($include_multimedia)
{
$pattern = sprintf('/\.(?:%s|%s|%s|%s)$/i', $images, $audios, $videos, $legacy);
@ -112,7 +112,7 @@ class FilenameFilter
{
$pattern = sprintf('/\.(?:%s)$/i', $images);
}
return preg_match($pattern, $filename) ? true : false;
}
}

View file

@ -16,16 +16,16 @@ class HTMLFilter
* HTMLPurifier instances are cached here.
*/
protected static $_instances = array();
/**
* Pre-processing and post-processing filters are stored here.
*/
protected static $_preproc = array();
protected static $_postproc = array();
/**
* Prepend a pre-processing filter.
*
*
* @param callable $callback
* @return void
*/
@ -33,10 +33,10 @@ class HTMLFilter
{
array_unshift(self::$_preproc, $callback);
}
/**
* Append a pre-processing filter.
*
*
* @param callable $callback
* @return void
*/
@ -44,10 +44,10 @@ class HTMLFilter
{
self::$_preproc[] = $callback;
}
/**
* Prepend a post-processing filter.
*
*
* @param callable $callback
* @return void
*/
@ -55,10 +55,10 @@ class HTMLFilter
{
array_unshift(self::$_postproc, $callback);
}
/**
* Append a post-processing filter.
*
*
* @param callable $callback
* @return void
*/
@ -66,10 +66,10 @@ class HTMLFilter
{
self::$_postproc[] = $callback;
}
/**
* Filter HTML content to block XSS attacks.
*
*
* @param string $input
* @param array|bool $allow_classes (optional)
* @param bool $allow_editor_components (optional)
@ -82,7 +82,7 @@ class HTMLFilter
{
$input = $callback($input);
}
if ($allow_classes === true)
{
$allowed_classes = null;
@ -97,36 +97,36 @@ class HTMLFilter
{
$allowed_classes = Config::get('mediafilter.classes') ?: array();
}
if ($allow_widgets)
{
$allowed_classes[] = 'zbxe_widget_output';
}
}
$input = self::_preprocess($input, $allow_editor_components, $allow_widgets);
$output = self::getHTMLPurifier($allowed_classes)->purify($input);
$output = self::_postprocess($output, $allow_editor_components, $allow_widgets);
foreach (self::$_postproc as $callback)
{
$output = $callback($output);
}
return $output;
}
/**
* Convert relative URLs to absolute URLs in HTML content.
*
*
* This is useful when sending content outside of the website,
* such as e-mail and RSS, where relative URLs might not mean the same.
*
*
* This method also removes attributes that don't mean anything
* when sent outside of the website, such as editor component names.
*
*
* This method DOES NOT check HTML content for XSS or other attacks.
*
*
* @param string $content
* @return string
*/
@ -146,10 +146,10 @@ class HTMLFilter
return preg_replace($patterns, $replacements, $match[0]);
}, $content);
}
/**
* Get an instance of HTMLPurifier.
*
*
* @param array|null $allowed_classes (optional)
* @return object
*/
@ -162,13 +162,13 @@ class HTMLFilter
sort($allowed_classes);
}
$key = sha1(serialize($allowed_classes));
// Create an instance with reasonable defaults.
if (!isset(self::$_instances[$key]))
{
// Get the default configuration.
$config = \HTMLPurifier_Config::createDefault();
// Customize the default configuration.
$config->set('Attr.AllowedClasses', $allowed_classes);
$config->set('Attr.AllowedFrameTargets', array('_blank', '_self'));
@ -188,42 +188,42 @@ class HTMLFilter
$config->set('Output.FlashCompat', true);
$config->set('Output.Newline', "\n");
$config->set('URI.MakeAbsolute', false);
// Allow embedding of external multimedia content.
$config->set('HTML.SafeEmbed', true);
$config->set('HTML.SafeIframe', true);
$config->set('HTML.SafeObject', true);
$config->set('URI.SafeIframeRegexp', MediaFilter::getWhitelistRegex());
// Set the serializer path.
$config->set('Cache.SerializerPath', \RX_BASEDIR . 'files/cache/htmlpurifier');
Storage::createDirectory(\RX_BASEDIR . 'files/cache/htmlpurifier');
// Modify the HTML definition to support editor components and widgets.
// Modify the HTML definition to support editor components and widgets.
$def = $config->getHTMLDefinition(true);
$def->addAttribute('img', 'editor_component', 'Text');
$def->addAttribute('div', 'editor_component', 'Text');
$def->addAttribute('img', 'rx_encoded_properties', 'Text');
$def->addAttribute('div', 'rx_encoded_properties', 'Text');
// Support HTML5 and CSS3.
self::_supportHTML5($config);
self::_supportCSS3($config);
// Cache our instance of HTMLPurifier.
self::$_instances[$key] = new \HTMLPurifier($config);
}
// Return the cached instance.
return self::$_instances[$key];
}
/**
* Patch HTMLPurifier to support some HTML5 tags and attributes.
*
*
* These changes are based on https://github.com/xemlock/htmlpurifier-html5
* but modified to support even more tags and attributes.
*
*
* @param object $config
* @return void
*/
@ -231,7 +231,7 @@ class HTMLFilter
{
// Get the HTML definition.
$def = $config->getHTMLDefinition(true);
// Add various block-level tags.
$def->addElement('header', 'Block', 'Flow', 'Common');
$def->addElement('footer', 'Block', 'Flow', 'Common');
@ -240,26 +240,26 @@ class HTMLFilter
$def->addElement('section', 'Block', 'Flow', 'Common');
$def->addElement('article', 'Block', 'Flow', 'Common');
$def->addElement('aside', 'Block', 'Flow', 'Common');
// Add various inline tags.
$def->addElement('s', 'Inline', 'Inline', 'Common');
$def->addElement('sub', 'Inline', 'Inline', 'Common');
$def->addElement('sup', 'Inline', 'Inline', 'Common');
$def->addElement('mark', 'Inline', 'Inline', 'Common');
$def->addElement('wbr', 'Inline', 'Empty', 'Core');
// Support figures.
$def->addElement('figure', 'Block', 'Optional: (figcaption, Flow) | (Flow, figcaption) | Flow', 'Common');
$def->addElement('figcaption', 'Inline', 'Flow', 'Common');
// Support insertions and deletions.
$def->addElement('ins', 'Block', 'Flow', 'Common', array('cite' => 'URI', 'datetime' => 'Text'));
$def->addElement('del', 'Block', 'Flow', 'Common', array('cite' => 'URI', 'datetime' => 'Text'));
// Support the <time> tag.
$time = $def->addElement('time', 'Inline', 'Inline', 'Common', array('datetime' => 'Text', 'pubdate' => 'Bool'));
$time->excludes = array('time' => true);
// Suppport <audio> and <video> tags.
$def->addElement('audio', 'Block', 'Optional: (source, Flow) | (Flow, source) | Flow', 'Common', array(
'src' => 'URI',
@ -296,23 +296,23 @@ class HTMLFilter
'kind' => 'Enum#captions,chapters,descriptions,metadata,subtitles',
'default' => 'Bool',
));
// Support additional properties.
$def->addAttribute('i', 'aria-hidden', 'Text');
$def->addAttribute('img', 'srcset', 'Text');
$def->addAttribute('img', 'data-file-srl', 'Number');
$def->addAttribute('iframe', 'allowfullscreen', 'Bool');
// Support contenteditable="false" (#1710)
$def->addAttribute('div', 'contenteditable', 'Enum#false');
}
/**
* Patch HTMLPurifier to support more CSS2 and some CSS3 properties.
*
*
* These changes are based on:
* - https://github.com/mattiaswelander/htmlpurifier
*
*
* @param object $config
* @return void
*/
@ -320,14 +320,14 @@ class HTMLFilter
{
// Initialize $info.
$info = array();
// min-width, max-width, etc.
$info['min-width'] = $info['max-width'] = $info['min-height'] =
$info['max-height'] = new \HTMLPurifier_AttrDef_CSS_Composite(array(
new \HTMLPurifier_AttrDef_CSS_Length(0),
new \HTMLPurifier_AttrDef_Enum(array('none', 'initial', 'inherit')),
));
// border-radius, etc.
$border_radius = $info['border-top-left-radius'] =
$info['border-top-right-radius'] = $info['border-bottom-left-radius'] =
@ -337,7 +337,7 @@ class HTMLFilter
new \HTMLPurifier_AttrDef_Enum(array('initial', 'inherit')),
));
$info['border-radius'] = new \HTMLPurifier_AttrDef_CSS_Multiple($border_radius);
// word-break word-wrap, etc.
$info['word-break'] = new \HTMLPurifier_AttrDef_Enum(array(
'normal', 'break-all', 'keep-all', 'initial', 'inherit',
@ -348,7 +348,7 @@ class HTMLFilter
$info['text-overflow'] = new \HTMLPurifier_AttrDef_CSS_Composite(array(
new \HTMLPurifier_AttrDef_Enum(array('clip', 'ellipsis', 'initial', 'inherit')),
));
// text-shadow
$info['text-shadow'] = new \HTMLPurifier_AttrDef_CSS_Composite(array(
new \HTMLPurifier_AttrDef_CSS_Multiple(new \HTMLPurifier_AttrDef_CSS_Composite(array(
@ -357,7 +357,7 @@ class HTMLFilter
))),
new \HTMLPurifier_AttrDef_Enum(array('none', 'initial', 'inherit')),
));
// box-shadow and box-sizing
$info['box-shadow'] = new \HTMLPurifier_AttrDef_CSS_Multiple(new \HTMLPurifier_AttrDef_CSS_Composite(array(
new \HTMLPurifier_AttrDef_CSS_Length(),
@ -368,7 +368,7 @@ class HTMLFilter
$info['box-sizing'] = new \HTMLPurifier_AttrDef_Enum(array(
'content-box', 'border-box', 'initial', 'inherit',
));
// outline
$info['outline-color'] = new \HTMLPurifier_AttrDef_CSS_Composite(array(
new \HTMLPurifier_AttrDef_CSS_Color(),
@ -389,7 +389,7 @@ class HTMLFilter
$info['outline-color'], $info['outline-style'], $info['outline-width'],
new \HTMLPurifier_AttrDef_Enum(array('initial', 'inherit')),
)));
// flexbox
$info['display'] = new \HTMLPurifier_AttrDef_Enum(array(
'block', 'flex', '-webkit-flex', 'inline', 'inline-block', 'inline-flex', '-webkit-inline-flex', 'inline-table',
@ -424,7 +424,7 @@ class HTMLFilter
$info['flex-grow'], $info['flex-shrink'], $info['flex-basis'],
new \HTMLPurifier_AttrDef_Enum(array('auto', 'none', 'initial', 'inherit')),
)));
// misc
$info['caption-side'] = new \HTMLPurifier_AttrDef_Enum(array(
'top', 'bottom', 'initial', 'inherit',
@ -449,7 +449,7 @@ class HTMLFilter
$info['object-fit'] = new \HTMLPurifier_AttrDef_Enum(array(
'contain', 'cover', 'fill', 'none', 'scale-down', 'initial', 'inherit',
));
// Wrap all new properties with a decorator that handles !important.
$allow_important = $config->get('CSS.AllowImportant');
$css_definition = $config->getCSSDefinition();
@ -458,10 +458,10 @@ class HTMLFilter
$css_definition->info[$key] = new \HTMLPurifier_AttrDef_CSS_ImportantDecorator($val, $allow_important);
}
}
/**
* Rhymix-specific preprocessing method.
*
*
* @param string $content
* @param bool $allow_editor_components (optional)
* @param bool $allow_widgets (optional)
@ -476,10 +476,10 @@ class HTMLFilter
}
return $content;
}
/**
* Rhymix-specific postprocessing method.
*
*
* @param string $content
* @param bool $allow_editor_components (optional)
* @param bool $allow_widgets (optional)
@ -490,12 +490,12 @@ class HTMLFilter
// Define acts to allow and deny.
$allow_acts = array('procFileDownload');
$deny_acts = array('dispMemberLogout', 'dispLayoutPreview');
// Remove tags not supported in Rhymix. Some of these may also have been removed by HTMLPurifier.
$content = preg_replace_callback('!</?(?:html|body|head|title|meta|base|link|script|style|applet)\b[^>]*>!i', function($matches) {
return htmlspecialchars($matches[0], ENT_QUOTES, 'UTF-8');
}, $content);
// Remove object and embed URLs that are not allowed.
$whitelist = MediaFilter::getWhitelistRegex();
$content = preg_replace_callback('!<(object|embed|param|audio|video|source|track)([^>]+)>!i', function($matches) use($whitelist) {
@ -511,7 +511,7 @@ class HTMLFilter
return $attr[0];
}, $matches[0]);
}, $content);
// Remove link URLs that may be CSRF attempts.
$content = preg_replace_callback('!\b(src|href|data|value)="([^"]+)"!i', function($matches) use($allow_acts, $deny_acts) {
$url = preg_replace('!\s+!', '', htmlspecialchars_decode(rawurldecode($matches[2])));
@ -525,15 +525,15 @@ class HTMLFilter
}
return $matches[0];
}, $content);
// Restore widget and editor component properties.
$content = self::_decodeWidgetsAndEditorComponents($content, $allow_editor_components, $allow_widgets);
return $content;
}
/**
* Encode widgets and editor components before processing.
*
*
* @param string $content
* @param bool $allow_editor_components (optional)
* @param bool $allow_widgets (optional)
@ -554,7 +554,7 @@ class HTMLFilter
{
return $content;
}
return preg_replace_callback('!<(div|img)([^>]*)(' . implode('|', $regexp) . ')([^>]*)>!i', function($match) {
$tag = strtolower($match[1]);
$attrs = array();
@ -585,10 +585,10 @@ class HTMLFilter
return substr($html, 0, 4) . ' rx_encoded_properties="' . $encoded_properties . '"' . substr($html, 4);
}, $content);
}
/**
* Decode widgets and editor components after processing.
*
*
* @param string $content
* @param bool $allow_editor_components (optional)
* @param bool $allow_widgets (optional)
@ -608,7 +608,7 @@ class HTMLFilter
{
return $content;
}
return preg_replace_callback('!<(div|img)([^>]*)(\srx_encoded_properties="([^"]+)")!i', function($match) {
$attrs = array();
list($encoded_properties, $signature) = explode(':', $match[4]);

View file

@ -9,7 +9,7 @@ class IpFilter
{
/**
* Check whether the given IP address belongs to a range.
*
*
* @param string $ip
* @param string $range
* @return bool
@ -27,7 +27,7 @@ class IpFilter
$ip = strtolower($ip);
$ip_type = 6;
}
// Determine the type of the range.
if ($ip_type === 6 && strpos($range, ':') !== false)
{
@ -49,7 +49,7 @@ class IpFilter
{
$range_type = 'unknown';
}
// Check!
switch ($range_type)
{
@ -65,10 +65,10 @@ class IpFilter
return false;
}
}
/**
* Check whether the given IP address belongs to a set of ranges.
*
*
* @param string $ip
* @param array $ranges
* @return bool
@ -84,10 +84,10 @@ class IpFilter
}
return false;
}
/**
* Check whether a range definition is valid.
*
*
* @param string $range
* @return bool
*/
@ -99,7 +99,7 @@ class IpFilter
'/^\d+\.\d+\.\d+\.\d+-\d+\.\d+\.\d+\.\d+$/',
'/^[0-9a-f:]+(\/\d+)?$/i',
);
foreach ($regexes as $regex)
{
if (preg_match($regex, $range))
@ -109,10 +109,10 @@ class IpFilter
}
return false;
}
/**
* Check whether a set of range definitions is valid.
*
*
* @param array $ranges
* @return bool
*/
@ -127,10 +127,10 @@ class IpFilter
}
return true;
}
/**
* Get real IP from CloudFlare headers.
*
*
* @return string|false
*/
public static function getCloudFlareRealIP()
@ -139,7 +139,7 @@ class IpFilter
{
return false;
}
$cloudflare_ranges = (include \RX_BASEDIR . 'common/defaults/cloudflare.php');
foreach ($cloudflare_ranges as $cloudflare_range)
{
@ -150,12 +150,12 @@ class IpFilter
}
return false;
}
/**
* Check whether the given IPv4 address belongs to a IPv4 CIDR range with mask.
*
*
* Example: 172.16.0.0/12
*
*
* @param string $ip
* @param string $range
* @return bool
@ -168,12 +168,12 @@ class IpFilter
$range = ip2long($range) & (0xffffffff << (32 - $mask));
return $ip === $range;
}
/**
* Check whether the given IPv4 address belongs to a IPv6 CIDR range with mask.
*
*
* Example: 2400:cb00::/32
*
*
* @param string $ip
* @param string $range
* @return bool
@ -193,12 +193,12 @@ class IpFilter
return false;
}
}
/**
* Check whether the given IPv4 address belongs to a IPv4 wildcard range.
*
*
* Example: 192.168.*.*
*
*
* @param string $ip
* @param string $range
* @return bool
@ -213,12 +213,12 @@ class IpFilter
$range = str_replace(array('.', '*'), array('\\.', '\\d+'), trim($range));
return preg_match("/^$range$/", $ip) ? true : false;
}
/**
* Check whether the given IPv4 address belongs to a IPv4 hyphen range.
*
*
* Example: 192.168.0.0-192.168.255.255
*
*
* @param string $ip
* @param string $range
* @return bool

View file

@ -13,10 +13,10 @@ class MediaFilter
* Whitelists are cached here.
*/
protected static $_whitelist = [];
/**
* Add a prefix to the iframe whitelist.
*
*
* @param string $prefix
* @parsm bool $permanently
* @return void
@ -27,13 +27,13 @@ class MediaFilter
{
self::_loadWhitelists();
}
$prefix = self::formatPrefix($prefix);
if (!in_array($prefix, self::$_whitelist))
{
self::$_whitelist[] = $prefix;
natcasesort(self::$_whitelist);
if ($permanently)
{
Config::set('mediafilter.whitelist', self::$_whitelist);
@ -43,30 +43,30 @@ class MediaFilter
}
}
}
/**
* Add a prefix to the object whitelist.
*
*
* @deprecated
*/
public static function addIframePrefix($prefix, $permanently = false)
{
self::addPrefix($prefix, $permanently);
}
/**
* Add a prefix to the object whitelist.
*
*
* @deprecated
*/
public static function addObjectPrefix()
{
}
/**
* Format a prefix for standardization.
*
*
* @param string $prefix
* @return string
*/
@ -79,10 +79,10 @@ class MediaFilter
}
return $prefix;
}
/**
* Get the iframe whitelist.
*
*
* @return array
*/
public static function getWhitelist()
@ -93,10 +93,10 @@ class MediaFilter
}
return self::$_whitelist;
}
/**
* Get the iframe whitelist as a regular expression.
*
*
* @return string
*/
public static function getWhitelistRegex()
@ -112,10 +112,10 @@ class MediaFilter
}
return '%^(?:https?:)?//(' . implode('|', $result) . ')%';
}
/**
* Check if a URL matches the iframe whitelist.
*
*
* @param string $url
* @return bool
*/
@ -123,10 +123,10 @@ class MediaFilter
{
return preg_match(self::getWhitelistRegex(), $url) ? true : false;
}
/**
* Remove embedded media from HTML content.
*
*
* @param string $input
* @param string $replacement
* @return string
@ -138,10 +138,10 @@ class MediaFilter
$input = preg_replace('!<img[^>]*editor_component="multimedia_link"[^>]*>(.*?</img>)?!is', $replacement, $input);
return $input;
}
/**
* Load whitelists.
*
*
* @param array $custom_whitelist
* @return void
*/
@ -149,7 +149,7 @@ class MediaFilter
{
$default_whitelist = (include \RX_BASEDIR . 'common/defaults/whitelist.php');
self::$_whitelist = [];
if($custom_whitelist)
{
if(!is_array($custom_whitelist) || !isset($custom_whitelist['iframe']) || !isset($custom_whitelist['object']))
@ -199,19 +199,19 @@ class MediaFilter
}
}
}
self::$_whitelist = array_unique(self::$_whitelist);
natcasesort(self::$_whitelist);
}
/**
* ========================== DEPRECATED METHODS ==========================
* ============== KEPT FOR COMPATIBILITY WITH OLDER VERSIONS ==============
*/
/**
* Get the iframe whitelist.
*
*
* @deprecated
* @return array
*/
@ -219,10 +219,10 @@ class MediaFilter
{
return self::getWhitelist();
}
/**
* Get the iframe whitelist as a regular expression.
*
*
* @deprecated
* @return string
*/
@ -230,10 +230,10 @@ class MediaFilter
{
return self::getWhitelistRegex();
}
/**
* Check if a URL matches the iframe whitelist.
*
*
* @deprecated
* @param string $url
* @return bool
@ -242,10 +242,10 @@ class MediaFilter
{
return self::matchWhitelist($url);
}
/**
* Get the object whitelist.
*
*
* @deprecated
* @return array
*/
@ -253,10 +253,10 @@ class MediaFilter
{
return self::getWhitelist();
}
/**
* Get the object whitelist as a regular expression.
*
*
* @deprecated
* @return string
*/
@ -264,10 +264,10 @@ class MediaFilter
{
return self::getWhitelistRegex();
}
/**
* Check if a URL matches the iframe whitelist.
*
*
* @deprecated
* @param string $url
* @return bool

View file

@ -14,10 +14,10 @@ class ConfigHelper
* Cache plugin configuration during consolidation.
*/
protected static $_config_cache = array();
/**
* Consolidate configuration from multiple sources.
*
*
* @param array $format
* @return array
*/
@ -25,19 +25,19 @@ class ConfigHelper
{
self::$_config_cache = array();
$result = array();
foreach ($format as $key => $value)
{
$result[$key] = self::_parseConfigValue((array)$value);
}
self::$_config_cache = array();
return $result;
}
/**
* Parse and get a configuration value.
*
*
* @param array $value
* @return mixed
*/
@ -45,7 +45,7 @@ class ConfigHelper
{
$filters = array();
$result = null;
foreach ($value as $option)
{
$option = array_map('trim', explode(':', $option, 2));
@ -90,12 +90,12 @@ class ConfigHelper
$result = $temp;
}
}
foreach ($filters as $filter)
{
$result = $filter($result);
}
return $result;
}
}

View file

@ -8,7 +8,7 @@ use Rhymix\Framework\Exceptions\DBError;
/**
* DB helper class.
*
*
* We use instances of this class instead of raw PDO in order to provide
* better logging and error handling while keeping backward compatibility.
*/
@ -18,7 +18,7 @@ class DBHelper extends \PDO
* Store the database type (e.g. master) here.
*/
protected $_type = 'master';
/**
* Set the database type.
*/
@ -26,10 +26,10 @@ class DBHelper extends \PDO
{
$this->_type = $type;
}
/**
* Create a prepared statement.
*
*
* @param string $statement
* @param array $options
* @return DBStmtHelper
@ -39,7 +39,7 @@ class DBHelper extends \PDO
{
$start_time = microtime(true);
$db_class = DB::getInstance($this->_type);
try
{
/**
@ -66,24 +66,24 @@ class DBHelper extends \PDO
{
Debug::addQuery($db_class->getQueryLog($statement, $elapsed_time));
}
/**
* This is a new feature in Rhymix 2.0 so we don't have to mess
* with status objects. We just throw an exception. Catch it!
*/
throw new DBError($e->getMessage(), 0, $e);
}
return $stmt;
}
/**
* Execute a query.
*
*
* This method accepts additional parameters, but they are not for creating
* prepared statements. They exist because PDO's own query() method accepts
* various kinds of additional parameters, and we don't want to touch them.
*
*
* @param string $statement
* @param int $fetch_mode
* @return DBStmtHelper|false
@ -95,7 +95,7 @@ class DBHelper extends \PDO
$db_class = DB::getInstance($this->_type);
$args = func_get_args();
array_shift($args);
try
{
/**
@ -122,13 +122,13 @@ class DBHelper extends \PDO
Debug::addQuery($db_class->getQueryLog($statement, $elapsed_time));
}
}
return $stmt;
}
/**
* Execute a query and return the number of affected rows.
*
*
* @param string $statement
* @return int|false
*/
@ -137,7 +137,7 @@ class DBHelper extends \PDO
{
$start_time = microtime(true);
$db_class = DB::getInstance($this->_type);
try
{
$result = parent::exec($statement);
@ -156,7 +156,7 @@ class DBHelper extends \PDO
Debug::addQuery($db_class->getQueryLog($statement, $elapsed_time));
}
}
return $result;
}
}

View file

@ -4,7 +4,7 @@ namespace Rhymix\Framework\Helpers;
/**
* DB result helper class.
*
*
* Instances of this class will be returned from DB queries.
*/
class DBResultHelper extends \BaseObject

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