General cleanup of ModuleHandler init()

This commit is contained in:
Kijin Sung 2020-06-18 21:04:44 +09:00
parent e17ddbbdb1
commit 41e02eb89a
3 changed files with 204 additions and 239 deletions

View file

@ -13,15 +13,16 @@
class ModuleHandler extends Handler
{
var $method = 'GET';
var $module = NULL; ///< Module
var $act = NULL; ///< action
var $mid = NULL; ///< Module ID
var $document_srl = NULL; ///< Document Number
var $module_srl = NULL; ///< Module Number
var $module_info = NULL; ///< Module Info
var $route = NULL; ///< Router result
var $error = NULL; ///< an error code.
var $httpStatusCode = NULL; ///< http status code.
var $module_info = null;
var $module_srl = null;
var $module = null;
var $act = null;
var $mid = null;
var $document_srl = null;
var $route = null;
var $error = null;
var $is_mobile = false;
var $httpStatusCode = 200;
/**
* Valid types and kinds of module instances.
@ -87,6 +88,7 @@ class ModuleHandler extends Handler
$this->document_srl = $document_srl ? (int) $document_srl : (int) Context::get('document_srl');
$this->module_srl = $module_srl ? (int) $module_srl : (int) Context::get('module_srl');
$this->route = Context::getRouteInfo() ?: new stdClass;
$this->is_mobile = Mobile::isFromMobilePhone();
if($entry = Context::get('entry'))
{
$this->entry = Context::convertEncodingStr($entry);
@ -103,7 +105,7 @@ class ModuleHandler extends Handler
// execute addon (before module initialization)
$called_position = 'before_module_init';
$oAddonController = AddonController::getInstance();
$addon_file = $oAddonController->getCacheFilePath(Mobile::isFromMobilePhone() ? 'mobile' : 'pc');
$addon_file = $oAddonController->getCacheFilePath($this->is_mobile ? 'mobile' : 'pc');
if(file_exists($addon_file)) include($addon_file);
}
@ -143,42 +145,25 @@ class ModuleHandler extends Handler
}
}
// Check success_return_url and error_return_url to prevent dangerous redirects.
$urls = array('success_return_url', 'error_return_url');
foreach($urls as $key)
{
$url = Context::get($key);
if ($url && !Rhymix\Framework\URL::isInternalURL($url))
{
Context::set($key, null);
}
}
// If the Router returned an error earlier, show an error here.
if($this->route && $this->route->status > 200)
{
$this->error = 'msg_module_is_not_exists';
$this->httpStatusCode = '404';
$this->httpStatusCode = 404;
return true;
}
// if success_return_url and error_return_url is incorrect
$urls = array(Context::get('success_return_url'), Context::get('error_return_url'));
foreach($urls as $url)
{
if(empty($url))
{
continue;
}
if($host = parse_url($url, PHP_URL_HOST))
{
$defaultHost = parse_url(Context::getDefaultUrl(), PHP_URL_HOST);
if($host !== $defaultHost)
{
$siteModuleHost = $site_module_info->domain;
if(strpos($siteModuleHost, '/') !== false)
{
$siteModuleHost = parse_url($siteModuleHost, PHP_URL_HOST);
}
if($host !== $siteModuleHost)
{
Context::set('success_return_url', null);
Context::set('error_return_url', null);
}
}
}
}
// Convert document alias (entry) to document_srl
if(!$this->document_srl && $this->mid && $this->entry)
{
@ -189,65 +174,35 @@ class ModuleHandler extends Handler
}
}
// Get module's information based on document_srl, if it's specified
// Get module info from document_srl.
if($this->document_srl)
{
$module_info = ModuleModel::getModuleInfoByDocumentSrl($this->document_srl);
if($module_info)
$module_info = $this->_checkDocumentSrl();
if ($module_info === false)
{
// If it exists, compare mid based on the module information
// if mids are not matching, set it as the document's mid
if(!$this->mid || ($this->mid != $module_info->mid))
{
if(Context::getRequestMethod() == 'GET')
{
Context::setCacheControl(0);
header('location: ' . getNotEncodedSiteUrl($site_module_info->domain, 'mid', $module_info->mid, 'document_srl', $this->document_srl), true, 301);
return false;
}
else
{
$this->mid = $module_info->mid;
Context::set('mid', $this->mid);
}
}
// if requested module is different from one of the document, remove the module information retrieved based on the document number
if($this->module && $module_info->module != $this->module)
{
unset($module_info);
}
}
// Block access to secret or temporary documents.
if(Context::getRequestMethod() == 'GET')
{
$oDocument = DocumentModel::getDocument($this->document_srl);
if($oDocument->isExists() && !$oDocument->isAccessible())
{
$this->httpStatusCode = '403';
}
return false;
}
}
// If module_info is not set yet, and there exists mid information, get module information based on the mid
// Get module info from mid.
if(!$module_info && $this->mid)
{
$module_info = ModuleModel::getModuleInfoByMid($this->mid, $site_module_info->site_srl);
$module_info = ModuleModel::getModuleInfoByMid($this->mid);
}
// If module_info is not set still, and $module does not exist, find the default module
// Set module info as the default module for the domain.
if(!$module_info && !$this->module && !$this->mid)
{
$module_info = $site_module_info;
}
// Set index document
// Set the index document.
if($site_module_info->index_document_srl && !$this->module && !$this->mid && !$this->document_srl && $this->method === 'GET' && !$this->route->args)
{
Context::set('document_srl', $this->document_srl = $site_module_info->index_document_srl, true);
}
// redirect, if site start module
// Redirect if the index module was requested.
if(!$site_module_info->index_document_srl && $this->method === 'GET' && isset($this->route->args['mid']) && $this->route->args['mid'] === $site_module_info->mid && count($this->route->args) === 1)
{
Context::setCacheControl(0);
@ -258,57 +213,18 @@ class ModuleHandler extends Handler
// If module info was set, retrieve variables from the module information
if($module_info)
{
// Set instance variables and SEO info.
$this->module = $module_info->module;
$this->mid = $module_info->mid;
$this->module_info = $module_info;
if ($module_info->mid == $site_module_info->mid)
{
$seo_title = config('seo.main_title') ?: '$SITE_TITLE - $SITE_SUBTITLE';
}
else
{
$seo_title = config('seo.subpage_title') ?: '$SITE_TITLE - $SUBPAGE_TITLE';
}
$this->_setModuleSEOInfo($module_info, $site_module_info);
ModuleController::getInstance()->replaceDefinedLangCode($seo_title);
Context::setBrowserTitle($seo_title, array(
'site_title' => Context::getSiteTitle(),
'site_subtitle' => Context::getSiteSubtitle(),
'subpage_title' => $module_info->browser_title,
'page' => Context::get('page') ?: 1,
));
$module_config = ModuleModel::getModuleConfig('module');
if ($module_info->meta_keywords)
{
Context::addMetaTag('keywords', $module_info->meta_keywords);
}
elseif ($site_module_info->settings->meta_keywords)
{
Context::addMetaTag('keywords', $site_module_info->settings->meta_keywords);
}
elseif ($module_config->meta_keywords)
{
Context::addMetaTag('keywords', $module_config->meta_keywords);
}
if ($module_info->meta_description)
{
Context::addMetaTag('description', $module_info->meta_description);
}
elseif ($site_module_info->settings->meta_description)
{
Context::addMetaTag('description', $site_module_info->settings->meta_description);
}
elseif($module_config->meta_description)
{
Context::addMetaTag('description', $module_config->meta_description);
}
$viewType = (Mobile::isFromMobilePhone()) ? 'M' : 'P';
// Check if the current request is from a mobile device.
$this->is_mobile = Mobile::isFromMobilePhone();
$viewType = $this->is_mobile ? 'M' : 'P';
$targetSrl = $viewType === 'M' ? 'mlayout_srl' : 'layout_srl';
// use the site default layout.
// Apply default layouts.
if($module_info->{$targetSrl} == -1)
{
$oLayoutAdminModel = getAdminModel('layout');
@ -329,29 +245,28 @@ class ModuleHandler extends Handler
$layoutSrl = $module_info->{$targetSrl};
}
// reset a layout_srl in module_info.
// 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);
}
// Set module and mid into module_info
if(!isset($this->module_info))
else
{
$this->module_info = new stdClass();
$this->module_info = new stdClass;
$this->module_info->module = $this->module;
$this->module_info->mid = $this->mid;
}
$this->module_info->module = $this->module;
$this->module_info->mid = $this->mid;
// Set site_srl add 2011 08 09
// Always overwrite site_srl (deprecated)
$this->module_info->site_srl = $site_module_info->site_srl;
// Still no module? it's an error
if(!$this->module)
{
$this->error = 'msg_module_is_not_exists';
$this->httpStatusCode = '404';
$this->httpStatusCode = 404;
return true;
}
@ -381,21 +296,13 @@ class ModuleHandler extends Handler
* */
public function procModule()
{
$display_mode = Mobile::isFromMobilePhone() ? 'mobile' : 'view';
// Set the display mode for the current device type.
$this->is_mobile = Mobile::isFromMobilePhone();
// If error occurred while preparation, return a message instance
if($this->error)
{
self::_setInputErrorToContext();
$oMessageObject = self::getModuleInstance('message', $display_mode);
$oMessageObject->setError(-1);
$oMessageObject->setMessage($this->error);
$oMessageObject->dispMessage();
if($this->httpStatusCode)
{
$oMessageObject->setHttpStatusCode($this->httpStatusCode);
}
return $oMessageObject;
return self::_createErrorMessage(-1, $this->error, $this->httpStatusCode);
}
// Get action information with conf/module.xml
@ -419,19 +326,7 @@ class ModuleHandler extends Handler
// still no act means error
if(!$this->act)
{
$this->error = 'msg_module_is_not_exists';
$this->httpStatusCode = '404';
self::_setInputErrorToContext();
$oMessageObject = self::getModuleInstance('message', $display_mode);
$oMessageObject->setError(-1);
$oMessageObject->setMessage($this->error);
$oMessageObject->dispMessage();
if($this->httpStatusCode)
{
$oMessageObject->setHttpStatusCode($this->httpStatusCode);
}
return $oMessageObject;
return self::_createErrorMessage(-1, 'msg_module_is_not_exists', 404);
}
// get type, kind
@ -465,12 +360,7 @@ class ModuleHandler extends Handler
if(!in_array(strtoupper($_SERVER['REQUEST_METHOD']), $allowedMethodList))
{
$this->error = 'msg_invalid_request';
$oMessageObject = self::getModuleInstance('message', $display_mode);
$oMessageObject->setError(-1);
$oMessageObject->setMessage($this->error);
$oMessageObject->dispMessage();
return $oMessageObject;
return self::_createErrorMessage(-1, 'msg_method_not_allowed', 405);
}
}
@ -479,13 +369,7 @@ class ModuleHandler extends Handler
{
if($xml_info->action->{$this->act} && $xml_info->action->{$this->act}->check_csrf !== 'false' && !checkCSRF())
{
$this->_setInputErrorToContext();
$this->error = 'msg_invalid_request';
$oMessageObject = ModuleHandler::getModuleInstance('message', $display_mode);
$oMessageObject->setError(-1);
$oMessageObject->setMessage($this->error);
$oMessageObject->dispMessage();
return $oMessageObject;
return self::_createErrorMessage(-1, 'msg_security_violation');
}
}
@ -497,7 +381,7 @@ class ModuleHandler extends Handler
$logged_info = Context::get('logged_info');
// if(type == view, and case for using mobilephone)
if($type == "view" && Mobile::isFromMobilePhone() && Context::isInstalled())
if($type == "view" && $this->is_mobile && Context::isInstalled())
{
$orig_type = "view";
$type = "mobile";
@ -518,16 +402,7 @@ class ModuleHandler extends Handler
if(!is_object($oModule))
{
self::_setInputErrorToContext();
$oMessageObject = self::getModuleInstance('message', $display_mode);
$oMessageObject->setError(-1);
$oMessageObject->setMessage($this->error);
$oMessageObject->dispMessage();
if($this->httpStatusCode)
{
$oMessageObject->setHttpStatusCode($this->httpStatusCode);
}
return $oMessageObject;
return self::_createErrorMessage(-1, $this->error, $this->httpStatusCode);
}
// If there is no such action in the module object
@ -535,17 +410,7 @@ class ModuleHandler extends Handler
{
if(!Context::isInstalled())
{
self::_setInputErrorToContext();
$this->error = 'msg_invalid_request';
$oMessageObject = self::getModuleInstance('message', $display_mode);
$oMessageObject->setError(-1);
$oMessageObject->setMessage($this->error);
$oMessageObject->dispMessage();
if($this->httpStatusCode)
{
$oMessageObject->setHttpStatusCode($this->httpStatusCode);
}
return $oMessageObject;
return self::_createErrorMessage(-1, 'msg_invalid_request');
}
// 1. Look for the module with action name
@ -565,13 +430,7 @@ class ModuleHandler extends Handler
}
else
{
$this->error = 'msg_invalid_request';
$oMessageObject = self::getModuleInstance('message', $display_mode);
$oMessageObject->setError(-1);
$oMessageObject->setMessage($this->error);
$oMessageObject->dispMessage();
return $oMessageObject;
return self::_createErrorMessage(-1, 'msg_invalid_request');
}
}
@ -599,13 +458,7 @@ class ModuleHandler extends Handler
{
if($this->module == 'admin' || empty($xml_info->action->{$this->act}->permission->target))
{
self::_setInputErrorToContext();
$this->error = 'admin.msg_is_not_administrator';
$oMessageObject = self::getModuleInstance('message', $display_mode);
$oMessageObject->setError(-1);
$oMessageObject->setMessage($this->error);
$oMessageObject->dispMessage();
return $oMessageObject;
return self::_createErrorMessage(-1, 'admin.msg_is_not_administrator');
}
}
@ -626,12 +479,7 @@ class ModuleHandler extends Handler
if(!in_array(strtoupper($_SERVER['REQUEST_METHOD']), $allowedMethodList))
{
$this->error = 'msg_security_violation';
$oMessageObject = self::getModuleInstance('message', $display_mode);
$oMessageObject->setError(-1);
$oMessageObject->setMessage($this->error);
$oMessageObject->dispMessage();
return $oMessageObject;
return self::_createErrorMessage(-1, 'msg_method_not_allowed', 405);
}
}
@ -640,17 +488,11 @@ class ModuleHandler extends Handler
{
if($xml_info->action->{$this->act} && $xml_info->action->{$this->act}->check_csrf !== 'false' && !checkCSRF())
{
$this->_setInputErrorToContext();
$this->error = 'msg_security_violation';
$oMessageObject = ModuleHandler::getModuleInstance('message', $display_mode);
$oMessageObject->setError(-1);
$oMessageObject->setMessage($this->error);
$oMessageObject->dispMessage();
return $oMessageObject;
return self::_createErrorMessage(-1, 'msg_security_violation');
}
}
if($type == "view" && Mobile::isFromMobilePhone())
if($type == "view" && $this->is_mobile)
{
$orig_type = "view";
$type = "mobile";
@ -670,16 +512,7 @@ class ModuleHandler extends Handler
if(!is_object($oModule))
{
self::_setInputErrorToContext();
$oMessageObject = self::getModuleInstance('message', $display_mode);
$oMessageObject->setError(-1);
$oMessageObject->setMessage('msg_module_is_not_exists');
$oMessageObject->dispMessage();
if($this->httpStatusCode)
{
$oMessageObject->setHttpStatusCode($this->httpStatusCode);
}
return $oMessageObject;
return self::_createErrorMessage(-1, 'msg_module_is_not_exists', 404);
}
// Admin page layout
@ -841,6 +674,115 @@ class ModuleHandler extends Handler
return $oModule;
}
/**
* Check the value of $document_srl. This method is called during init().
*
* @return object|false
*/
protected function _checkDocumentSrl()
{
// Get the module that the document belongs to.
$module_info = ModuleModel::getModuleInfoByDocumentSrl($this->document_srl);
if($module_info)
{
// Compare the current mid to the module that the document belongs to.
if(!$this->mid || ($this->mid !== $module_info->mid))
{
// If this is a GET request, redirect to the correct mid.
if(Context::getRequestMethod() === 'GET')
{
Context::setCacheControl(0);
header('Location: ' . getNotEncodedUrl('', 'mid', $module_info->mid, 'document_srl', $this->document_srl), true, 301);
return false;
}
// If this is NOT a GET request, don't redirect. Just overwrite the mid for the current request.
else
{
$this->mid = $module_info->mid;
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')
{
$oDocument = DocumentModel::getDocument($this->document_srl);
if($oDocument->isExists())
{
$this->httpStatusCode = 404;
}
elseif(!$oDocument->isAccessible())
{
$this->httpStatusCode = 403;
}
}
// Return the module info for further processing.
return $module_info;
}
/**
* Set SEO information to Context.
*
* @param object $module_info
* @param object $site_module_info
*/
protected function _setModuleSEOInfo($module_info, $site_module_info)
{
// Set the browser title.
if ($module_info->mid == $site_module_info->mid)
{
$seo_title = config('seo.main_title') ?: '$SITE_TITLE - $SITE_SUBTITLE';
}
else
{
$seo_title = config('seo.subpage_title') ?: '$SITE_TITLE - $SUBPAGE_TITLE';
}
ModuleController::getInstance()->replaceDefinedLangCode($seo_title);
Context::setBrowserTitle($seo_title, array(
'site_title' => Context::getSiteTitle(),
'site_subtitle' => Context::getSiteSubtitle(),
'subpage_title' => $module_info->browser_title,
'page' => Context::get('page') ?: 1,
));
// Set meta keywords.
$module_config = ModuleModel::getModuleConfig('module');
if ($module_info->meta_keywords)
{
Context::addMetaTag('keywords', $module_info->meta_keywords);
}
elseif ($site_module_info->settings->meta_keywords)
{
Context::addMetaTag('keywords', $site_module_info->settings->meta_keywords);
}
elseif ($module_config->meta_keywords)
{
Context::addMetaTag('keywords', $module_config->meta_keywords);
}
// Set meta description.
if ($module_info->meta_description)
{
Context::addMetaTag('description', $module_info->meta_description);
}
elseif ($site_module_info->settings->meta_description)
{
Context::addMetaTag('description', $site_module_info->settings->meta_description);
}
elseif($module_config->meta_description)
{
Context::addMetaTag('description', $module_config->meta_description);
}
}
/**
* set error message to Session.
* @return void
@ -903,6 +845,28 @@ class ModuleHandler extends Handler
}
}
/**
* Create a message module instance with an error message.
*/
protected static function _createErrorMessage($error, $message, $status_code = 403, $location = null)
{
$display_mode = Mobile::isFromMobilePhone() ? 'mobile' : 'view';
if (!$location)
{
$backtrace = debug_backtrace(false);
$caller = array_shift($backtrace);
$location = $caller['file'] . ':' . $caller['line'];
}
self::_setInputErrorToContext();
$oMessageObject = self::getModuleInstance('message', $display_mode);
$oMessageObject->setError($error);
$oMessageObject->setMessage($message);
$oMessageObject->setHttpStatusCode($status_code ?: 403);
$oMessageObject->dispMessage('', $location);
return $oMessageObject;
}
/**
* display contents from executed module
* @param ModuleObject $oModule module instance
@ -910,11 +874,14 @@ class ModuleHandler extends Handler
* */
public function displayContent($oModule = NULL)
{
// 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))
{
$this->error = 'msg_module_is_not_exists';
$this->httpStatusCode = '404';
$this->httpStatusCode = 404;
}
// If connection to DB has a problem even though it's not install module, set error
@ -979,11 +946,7 @@ class ModuleHandler extends Handler
if($this->error)
{
// display content with message module instance
$type = Mobile::isFromMobilePhone() ? 'mobile' : 'view';
$oMessageObject = self::getModuleInstance('message', $type);
$oMessageObject->setError(-1);
$oMessageObject->setMessage($this->error);
$oMessageObject->dispMessage(null, $oModule->get('rx_error_location'));
$oMessageObject = self::_createErrorMessage(-1, $this->error, $this->httpStatusCode, $oModule->get('rx_error_location'));
// display Error Page
if(!in_array($oMessageObject->getHttpStatusCode(), array(200, 403)))
@ -997,8 +960,8 @@ class ModuleHandler extends Handler
$oModule->setTemplatePath($oMessageObject->getTemplatePath());
$oModule->setTemplateFile($oMessageObject->getTemplateFile());
$oModule->setHttpStatusCode($oMessageObject->getHttpStatusCode());
// Otherwise, set message instance as the target module
}
// Otherwise, set message instance as the target module
else
{
$oModule = $oMessageObject;
@ -1008,7 +971,7 @@ class ModuleHandler extends Handler
}
// Check if layout_srl exists for the module
$viewType = (Mobile::isFromMobilePhone()) ? 'M' : 'P';
$viewType = $this->is_mobile ? 'M' : 'P';
if($viewType === 'M')
{
$layout_srl = $oModule->module_info->mlayout_srl;

View file

@ -234,6 +234,7 @@ $lang->msg_invalid_document = 'Invalid Article Number';
$lang->msg_invalid_request = 'Invalid Request';
$lang->msg_invalid_password = 'The password you entered is incorrect.';
$lang->msg_security_violation = 'Security Violation';
$lang->msg_method_not_allowed = 'This HTTP method is not allowed for this action.';
$lang->msg_feature_disabled = 'This feature is disabled.';
$lang->msg_error_occured = 'An error has occured.';
$lang->msg_not_founded = 'Cannot find the target.';

View file

@ -236,6 +236,7 @@ $lang->msg_invalid_document = '잘못된 문서번호입니다.';
$lang->msg_invalid_request = '잘못된 요청입니다.';
$lang->msg_invalid_password = '비밀번호가 올바르지 않습니다.';
$lang->msg_security_violation = '보안정책상 허용되지 않습니다.';
$lang->msg_method_not_allowed = '이 요청에 사용할 수 없는 HTTP 메소드입니다.';
$lang->msg_feature_disabled = '사용할 수 없는 기능입니다.';
$lang->msg_error_occured = '오류가 발생했습니다.';
$lang->msg_not_founded = '대상을 찾을 수 없습니다.';