Add option to control partial page rendering (layout drop)

XE 시절부터 layout=none 또는 isLayoutDrop=1 파라미터로 레이아웃이 없는
부분적인 페이지 렌더링을 허용하는 기능이 있었습니다. 관리자 화면에서
팝업이나 iframe을 표시하는 용도로도 사용하고, AJAX로 페이지 일부 내용만
새로고침할 때 불필요한 데이터를 주고받지 않도록 하는 데도 유용합니다.

그러나 사이트에 따라서는 레이아웃을 적용하지 않을 경우 민감한 정보가
노출되는 등의 부작용이 발생할 수도 있으므로, 이 기능을 사용하지 않도록
선택하는 옵션을 제공합니다.
This commit is contained in:
Kijin Sung 2023-09-12 00:33:54 +09:00
parent e2753300ee
commit e60ffb4e8d
7 changed files with 70 additions and 4 deletions

View file

@ -47,7 +47,7 @@ class HTMLDisplayHandler
* @param ModuleObject $oModule the module object
* @return string compiled template string
*/
function toDoc(&$oModule)
public function toDoc(&$oModule)
{
$oTemplate = TemplateHandler::getInstance();
@ -112,7 +112,13 @@ class HTMLDisplayHandler
$output = '<div class="x">' . $output . '</div>';
}
if(Context::get('layout') != 'none')
// Wrap content in layout
$use_layout = Context::get('layout') !== 'none';
if (!$use_layout && isset($_REQUEST['layout']) && !self::isPartialPageRendering())
{
$use_layout = true;
}
if ($use_layout)
{
$start = microtime(true);
@ -192,12 +198,42 @@ class HTMLDisplayHandler
return $output;
}
/**
* Check if partial page rendering (dropping the layout) is enabled.
*
* @return bool
*/
public static function isPartialPageRendering()
{
$ppr = config('view.partial_page_rendering') ?? 'internal_only';
if ($ppr === 'disabled')
{
return false;
}
elseif ($ppr === 'ajax_only' && empty($_SERVER['HTTP_X_REQUESTED_WITH']))
{
return false;
}
elseif ($ppr === 'internal_only' && (!isset($_SERVER['HTTP_REFERER']) || !Rhymix\Framework\URL::isInternalURL($_SERVER['HTTP_REFERER'])))
{
return false;
}
elseif ($ppr === 'except_robots' && isCrawler())
{
return false;
}
else
{
return true;
}
}
/**
* when display mode is HTML, prepare code before print.
* @param string $output compiled template string
* @return void
*/
function prepareToPrint(&$output)
public function prepareToPrint(&$output)
{
if(Context::getResponseMethod() != 'HTML')
{

View file

@ -1205,7 +1205,7 @@ class ModuleHandler extends Handler
{
$oModule->setLayoutFile('popup_layout');
}
else
elseif (HTMLDisplayHandler::isPartialPageRendering())
{
$oModule->setLayoutPath('common/tpl');
$oModule->setLayoutFile('default_layout');

View file

@ -78,6 +78,7 @@ return array(
'type' => 'mailfunction',
),
'view' => array(
'partial_page_rendering' => 'internal_only',
'manager_layout' => 'module',
'minify_scripts' => 'common',
'concat_scripts' => 'none',

View file

@ -104,6 +104,7 @@ class Advanced extends Base
Context::set('delay_session', Config::get('session.delay'));
Context::set('delay_template_compile', Config::get('view.delay_compile'));
Context::set('use_db_session', Config::get('session.use_db'));
Context::set('partial_page_rendering', Config::get('view.partial_page_rendering') ?? 'internal_only');
Context::set('manager_layout', Config::get('view.manager_layout'));
Context::set('minify_scripts', Config::get('view.minify_scripts'));
Context::set('concat_scripts', Config::get('view.concat_scripts'));
@ -220,6 +221,7 @@ class Advanced extends Base
Config::set('use_rewrite', $vars->use_rewrite > 0);
Config::set('session.delay', $vars->delay_session === 'Y');
Config::set('session.use_db', $vars->use_db_session === 'Y');
Config::set('view.partial_page_rendering', $vars->partial_page_rendering);
Config::set('view.manager_layout', $vars->manager_layout ?: 'module');
Config::set('view.minify_scripts', $vars->minify_scripts ?: 'common');
Config::set('view.concat_scripts', $vars->concat_scripts ?: 'none');

View file

@ -133,6 +133,13 @@ $lang->msg_invalid_timezone = 'The selected time zone is not usable on this serv
$lang->use_db_session = 'Store Session in DB';
$lang->about_db_session = 'Store PHP sessions in the database. This setting must be turned on if you want to see current users or get detailed statistics.<br>Unnecessary use may decrease server performance.';
$lang->qmail_compatibility = 'Enable Qmail';
$lang->cmd_partial_page_rendering = 'Partial Page Rendering';
$lang->cmd_partial_page_rendering_all = 'Allow all';
$lang->cmd_partial_page_rendering_except_robots = 'Allow all, except robots';
$lang->cmd_partial_page_rendering_internal_only = 'Internal requests only';
$lang->cmd_partial_page_rendering_ajax_only = 'AJAX requests only';
$lang->cmd_partial_page_rendering_disabled = 'Disabled';
$lang->about_partial_page_rendering = 'Select whether partial page rendering is allowed. Don\'t change this unless necessary.';
$lang->manager_layout = 'Module Setting Screen';
$lang->cmd_manager_layout_module = 'Use module layout';
$lang->cmd_manager_layout_admin = 'Use admin layout';

View file

@ -134,6 +134,13 @@ $lang->msg_invalid_timezone = '사용할 수 없는 표준 시간대입니다.';
$lang->use_db_session = '인증 세션 DB 사용';
$lang->about_db_session = '세션을 DB에 저장합니다. 현재 접속자를 파악하려면 이 기능을 켜야 합니다.<br>불필요하게 사용하면 서버 성능에 악영향을 줄 수 있으니 주의하십시오.';
$lang->qmail_compatibility = '큐메일(Qmail) 사용';
$lang->cmd_partial_page_rendering = '부분 페이지 렌더링';
$lang->cmd_partial_page_rendering_all = '모두 허용';
$lang->cmd_partial_page_rendering_except_robots = '로봇 제외 모두 허용';
$lang->cmd_partial_page_rendering_internal_only = '내부 요청만 허용';
$lang->cmd_partial_page_rendering_ajax_only = 'AJAX 요청만 허용';
$lang->cmd_partial_page_rendering_disabled = '사용하지 않음';
$lang->about_partial_page_rendering = '부분 페이지 렌더링 사용 여부를 설정할 수 있습니다. 특별한 이유가 없다면 변경하지 마세요.';
$lang->manager_layout = '모듈 설정 화면';
$lang->cmd_manager_layout_module = '해당 모듈 레이아웃 사용';
$lang->cmd_manager_layout_admin = '관리자 레이아웃 사용';

View file

@ -201,6 +201,19 @@
<p class="x_help-block">{$lang->about_cache_control_header}</p>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label" for="partial_page_rendering">{$lang->cmd_partial_page_rendering}</label>
<div class="x_controls">
<select name="partial_page_rendering" id="partial_page_rendering">
<option value="all" selected="selected"|cond="$partial_page_rendering === 'all'">{$lang->cmd_partial_page_rendering_all}</option>
<option value="except_robots" selected="selected"|cond="$partial_page_rendering === 'except_robots'">{$lang->cmd_partial_page_rendering_except_robots}</option>
<option value="internal_only" selected="selected"|cond="$partial_page_rendering === 'internal_only'">{$lang->cmd_partial_page_rendering_internal_only}</option>
<option value="ajax_only" selected="selected"|cond="$partial_page_rendering === 'ajax_only'">{$lang->cmd_partial_page_rendering_ajax_only}</option>
<option value="disabled" selected="selected"|cond="$partial_page_rendering === 'disabled'">{$lang->cmd_partial_page_rendering_disabled}</option>
</select>
<p class="x_help-block">{$lang->about_partial_page_rendering}</p>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->manager_layout}</label>
<div class="x_controls">