/**
* User-set variables (Context::get, Context::set)
*
* 사용자가 설정한 변수들 (Context::get, Context::set을 통해 설정)
*
* 이 변수는 사용자가 설정한 변수들을 저장하는데 사용됩니다. 이러한 변수들은 Context::set과 Context::get 메소드를
* 통해 설정되고 가져올 수 있습니다.
*
* @var object|null
*/
private static $_user_vars = NULL;
/**
* Singleton instance
* 싱글톤 인스턴스
*
* 이 변수는 클래스의 단일 인스턴스를 저장합니다. 싱글톤 패턴은 클래스가 오직 하나의 인스턴스만을 가지도록 보장하며
* 전역적으로 접근 가능한 점을 제공합니다.
*
* @var self
*/
private static $_instance;
/**
* Initialization, it sets DB information, request arguments and so on.
* 초기화에서는 DB 정보, 요청 인수 등을 설정합니다.
*
* @return void
*/
public static function init()
{
// Prevent calling init() twice.
if(self::$_init_called)
{
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();
if (in_array(self::$_instance->request_method, array('GET', 'POST', 'JSON')))
{
$method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
$request = Rhymix\Framework\Router::parseURL($method, RX_REQUEST_URL, Rhymix\Framework\Router::getRewriteLevel());
self::$_current_request = $request;
self::setRequestArguments($request->args);
}
else
{
self::$_current_request = new Rhymix\Framework\Request;
self::setRequestArguments();
}
self::setUploadInfo();
// If Rhymix is installed, get virtual site information.
if(self::isInstalled())
{
if (PHP_SAPI === 'cli')
{
self::set('_default_url', $default_url = config('url.default'));
if (!defined('RX_BASEURL'))
{
define('RX_BASEURL', parse_url($default_url, PHP_URL_PATH));
}
}
$site_module_info = ModuleModel::getDefaultMid() ?: new stdClass;
$site_timezone = (isset($site_module_info->settings->timezone) && $site_module_info->settings->timezone !== 'default') ? $site_module_info->settings->timezone : null;
self::set('site_module_info', $site_module_info);
self::set('_default_timezone', $site_timezone);
self::set('_default_url', self::$_instance->db_info->default_url = self::getDefaultUrl($site_module_info, RX_SSL));
self::set('_http_port', self::$_instance->db_info->http_port = $site_module_info->http_port ?: null);
self::set('_https_port', self::$_instance->db_info->https_port = $site_module_info->https_port ?: null);
self::set('_use_ssl', self::$_instance->db_info->use_ssl = ($site_module_info->security === 'none' ? 'none' : 'always'));
}
else
{
$site_module_info = new stdClass;
$site_module_info->domain = $_SERVER['HTTP_HOST'];
$site_module_info->security = RX_SSL ? 'always' : 'none';
$site_module_info->settings = new stdClass;
$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)
{
$ssl_url = self::getDefaultUrl($site_module_info, true) . RX_REQUEST_URL;
self::setCacheControl(0);
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)
{
$set_lang_cookie = true;
}
}
elseif(isset($_COOKIE['lang_type']) && $_COOKIE['lang_type'])
{
$lang_type = $_COOKIE['lang_type'];
}
elseif(config('locale.auto_select_lang') && count($enabled_langs) > 1 && isset($_SERVER['HTTP_ACCEPT_LANGUAGE']))
{
$ua_locale = Rhymix\Framework\UA::getLocale();
if (substr($ua_locale, 0, 2) !== 'zh')
{
$ua_locale = substr($ua_locale, 0, 2);
}
if (isset($enabled_langs[$ua_locale]))
{
$lang_type = $ua_locale;
$set_lang_cookie = true;
}
}
$lang_type = preg_replace('/[^a-zA-Z0-9_-]/', '', $lang_type ?? '');
if ($set_lang_cookie)
{
Rhymix\Framework\Cookie::set('lang_type', $lang_type, ['expires' => 365, 'path' => \RX_BASEURL]);
}
if(!$lang_type || !isset($enabled_langs[$lang_type]))
{
if(isset($site_module_info->settings->language) && $site_module_info->settings->language !== 'default')
{
$lang_type = self::$_instance->db_info->lang_type = $site_module_info->settings->language;
}
else
{
$lang_type = self::$_instance->db_info->lang_type = config('locale.default_lang');
}
}
if(!$lang_type || !isset($enabled_langs[$lang_type]))
{
$lang_type = self::$_instance->db_info->lang_type = 'ko';
}
$lang = Rhymix\Framework\Lang::getInstance($lang_type);
$lang->loadDirectory(RX_BASEDIR . 'common/lang', 'common');
$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::$_user_vars;
$GLOBALS['_time_zone'] = config('locale.default_timezone');
$GLOBALS['lang'] = &$lang;
// set session handler
if(self::isInstalled() && config('session.use_db'))
{
$oSessionModel = SessionModel::getInstance();
$oSessionController = SessionController::getInstance();
ini_set('session.serialize_handler', 'php');
session_set_save_handler(
array($oSessionController, 'open'), array($oSessionController, 'close'), array($oSessionModel, 'read'), array($oSessionController, 'write'), array($oSessionController, 'destroy'), array($oSessionController, 'gc')
);
}
// start session
if (\PHP_SAPI !== 'cli')
{
if (self::$_current_request->getRouteOption('enable_session'))
{
session_cache_limiter('');
Rhymix\Framework\Session::checkSSO($site_module_info);
Rhymix\Framework\Session::start(false);
}
if (self::$_current_request->getRouteOption('cache_control'))
{
if (!session_cache_limiter())
{
self::setCacheControl(0);
}
}
}
// start output buffer
if (\PHP_SAPI !== 'cli')
{
ob_start();
}
// set authentication information in Context and session
if (self::isInstalled())
{
if (Rhymix\Framework\Session::getMemberSrl())
{
MemberController::getInstance()->setSessionInfo();
}
else
{
self::set('is_logged', false);
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::$_current_request->args)
{
if ($query_string = http_build_query(self::$_current_request->args))
{
$current_url .= '?' . $query_string;
}
}
if (strpos($current_url, 'xn--') !== false)
{
$current_url = Rhymix\Framework\URL::decodeIdna($current_url);
}
if (strpos($request_uri, 'xn--') !== false)
{
$request_uri = Rhymix\Framework\URL::decodeIdna($request_uri);
}
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'))
{
self::enforceSiteLock();
}
}
/**
* Obtain a singleton instance of Context.
* Context의 싱글톤 인스턴스를 얻습니다.
*
* @return object Instance
*/
public static function getInstance()
{
if(self::$_instance === null)
{
// Create a singleton instance and initialize static properties.
// 싱글톤 인스턴스를 생성하고 정적 속성을 초기화합니다.
self::$_instance = new Context();
self::$_oFrontEndFileHandler = self::$_instance->oFrontEndFileHandler = new FrontEndFileHandler();
self::$_user_vars = self::$_user_vars ?: new stdClass;
}
return self::$_instance;
}
/**
* Return key's value
* 키의 값을 반환
*
* 이 메소드는 변수의 키를 통해 그 값을 가져오는 정적 메소드입니다.
* 먼저 키가 비어 있는지 확인하고, 비어 있으면 에러를 발생시킵니다.
* 그 다음 사용자가 설정한 변수들 중에서 키를 확인하고, 찾으면 그 값을 반환합니다.
* 사용자 변수에 없으면 인스턴스 변수에서 확인합니다.
* 두 곳 모두에 키가 없으면 null을 반환합니다.
*
* @param string $key 가져올 변수의 키.
* @return mixed 찾은 경우 변수의 값, 그렇지 않으면 null.
*/
public static function get($key)
{
// 제공된 키가 비어 있는지 확인합니다. 비어 있다면 사용자 경고를 발생시키고 반환합니다.
if(empty($key))
{
trigger_error('Called Context::get() with an empty key', \E_USER_WARNING);
return;
}
// 키가 사용자 설정 변수에 존재하는지 확인하고, 찾으면 그 값을 반환합니다.
if(isset(self::$_user_vars->{$key}))
{
return self::$_user_vars->{$key};
}
// 사용자 설정 변수에 없으면 인스턴스 변수에서 키가 존재하는지 확인합니다.
elseif(isset(self::$_instance->{$key}))
{
return self::$_instance->{$key};
}
// 두 곳 모두에 키가 없으면 null을 반환합니다.
else
{
return null;
}
}
/**
* Set a context value with a key
*
* @param string $key Key
* @param mixed $val Value
* @param mixed $replace_request_arg
* @return void
*/
public static function set($key, $val, $replace_request_arg = false)
{
if(empty($key))
{
trigger_error('Called Context::set() with an empty key', \E_USER_WARNING);
return;
}
self::$_user_vars->{$key} = $val;
if($replace_request_arg || isset(self::$_current_request->args[$key]))
{
if($val === NULL || $val === '')
{
unset(self::$_current_request->args[$key]);
}
else
{
self::$_current_request->args[$key] = $val;
}
}
}