/** * 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; } } }