Handle static files access via LSurl routes

This commit is contained in:
Benjamin Renard 2020-05-05 12:48:52 +02:00
parent 4c344aa570
commit 2a39fb7661
15 changed files with 215 additions and 98 deletions

View file

@ -1,7 +1,9 @@
RewriteEngine On
# Always rewrite tmp file access
# Always rewrite tmp, css & libs file access
RewriteRule ^(tmp/.*)$ index.php?REQUESTED_URL=$1 [L,QSA]
RewriteRule ^(css/.*)$ index.php?REQUESTED_URL=$1 [L,QSA]
RewriteRule ^(libs/.*)$ index.php?REQUESTED_URL=$1 [L,QSA]
# If the request is not for a valid file
RewriteCond %{REQUEST_FILENAME} !-f

View file

@ -166,11 +166,11 @@ class LSformElement_date extends LSformElement {
$codeLang = str_replace('_','-',preg_replace('/\..*$/','',LSsession :: getLang()));
LSsession :: addJSscript('Picker.js',LS_LIB_DIR.'arian-mootools-datepicker/');
LSsession :: addJSscript('Picker.Attach.js',LS_LIB_DIR.'arian-mootools-datepicker/');
LSsession :: addJSscript('Picker.Date.js',LS_LIB_DIR.'arian-mootools-datepicker/');
LSsession :: addJSscript('Locale.'.$codeLang.'.DatePicker.js',LS_LIB_DIR.'arian-mootools-datepicker/');
LSsession :: addCssFile('datepicker_'.$params['style'].'.css',LS_LIB_DIR.'arian-mootools-datepicker/datepicker_'.$params['style'].'/');
LSsession :: addLibJSscript('arian-mootools-datepicker/Picker.js');
LSsession :: addLibJSscript('arian-mootools-datepicker/Picker.Attach.js');
LSsession :: addLibJSscript('arian-mootools-datepicker/Picker.Date.js');
LSsession :: addLibJSscript('arian-mootools-datepicker/Locale.'.$codeLang.'.DatePicker.js');
LSsession :: addLibCssFile('arian-mootools-datepicker/datepicker_'.$params['style'].'/datepicker_'.$params['style'].'.css');
LSsession :: addJSscript('LSformElement_date_field.js');
LSsession :: addJSscript('LSformElement_date.js');

View file

@ -76,12 +76,18 @@ class LSsession {
// Les fichiers JS à charger dans la page
private static $JSscripts = array();
// Libs JS files to load on page
private static $LibsJSscripts = array();
// Les paramètres JS à communiquer dans la page
private static $_JSconfigParams = array();
// Les fichiers CSS à charger dans la page
private static $CssFiles = array();
// Libs CSS files to load on page
private static $LibsCssFiles = array();
// L'objet de l'utilisateur connecté
private static $LSuserObject = NULL;
@ -192,6 +198,8 @@ class LSsession {
'template_dir' => LS_ROOT_DIR . '/'. LS_TEMPLATES_DIR,
'image_dir' => LS_IMAGES_DIR,
'css_dir' => LS_CSS_DIR,
'js_dir' => LS_JS_DIR,
'libs_dir' => LS_LIB_DIR,
'compile_dir' => LS_TMP_DIR_PATH,
'debug' => LSdebug,
'debug_smarty' => (isset($_REQUEST) && isset($_REQUEST['LStemplate_debug'])),
@ -1401,20 +1409,32 @@ class LSsession {
}
/**
* Ajoute un script JS au chargement de la page
* Add a JS script to load on page
*
* Remarque : les scripts doivents être dans le dossier LS_JS_DIR.
*
* @param[in] $script Le nom du fichier de script à charger.
* @param[in] $file string The JS filename
* @param[in] $path string|null The sub-directory path that contain this file.
* Keep for retro-compatibility : you could just
* prefix the file name.
*
* @retval void
*/
public static function addJSscript($file, $path=NULL) {
$script=array(
'file' => $file,
'path' => $path
);
self :: $JSscripts[$path.$file]=$script;
if ($path)
$file = $path.$file;
if (!in_array($file, self :: $JSscripts))
self :: $JSscripts[] = $file;
}
/**
* Add a library JS file to load on page
*
* @param[in] $file string The JS filename
*
* @retval void
*/
public static function addLibJSscript($file) {
if (!in_array($file, self :: $LibsJSscripts))
self :: $LibsJSscripts[] = $file;
}
/**
@ -1430,20 +1450,32 @@ class LSsession {
}
/**
* Ajoute une feuille de style au chargement de la page
* Add a CSS file to load on page
*
* @param[in] $script Le nom du fichier css à charger.
* @param[in] $file string The CSS filename
* @param[in] $path string|null The sub-directory path that contain this file.
* Keep for retro-compatibility : you could just
* prefix the file name.
*
* @retval void
*/
public static function addCssFile($file, $path=NULL) {
if ($path) {
if ($path)
$file = $path.$file;
if (!in_array($file, self :: $CssFiles))
self :: $CssFiles[] = $file;
}
else {
$file = LStemplate :: getCSSPath($file);
}
self :: $CssFiles[$file]=$file;
/**
* Add a library CSS file to load on page
*
* @param[in] $file string The CSS filename
*
* @retval void
*/
public static function addLibCssFile($file) {
if (!in_array($file, self :: $LibsCssFiles))
self :: $LibsCssFiles[] = $file;
}
/**
@ -1454,24 +1486,6 @@ class LSsession {
* @retval void
*/
public static function displayTemplate() {
// JS
$JSscript_txt='';
foreach ($GLOBALS['defaultJSscipts'] as $script) {
$nocache = LStemplate :: getNoCacheFileValue(LS_JS_DIR.$script);
$JSscript_txt.="<script src='".LS_JS_DIR.$script."?nocache=$nocache' type='text/javascript'></script>\n";
}
foreach (self :: $JSscripts as $script) {
if (!$script['path']) {
$script['path']=LS_JS_DIR;
}
else {
$script['path'].='/';
}
$nocache = LStemplate :: getNoCacheFileValue($script['path'].$script['file']);
$JSscript_txt.="<script src='".$script['path'].$script['file']."?nocache=$nocache' type='text/javascript'></script>\n";
}
$KAconf = LSconfig :: get('keepLSsessionActive');
if (
(
@ -1487,28 +1501,28 @@ class LSsession {
LStemplate :: assign('LSjsConfig',base64_encode(json_encode(self :: $_JSconfigParams)));
if (LSdebug) {
$JSscript_txt.="<script type='text/javascript'>LSdebug_active = 1;</script>\n";
}
else {
$JSscript_txt.="<script type='text/javascript'>LSdebug_active = 0;</script>\n";
}
// JS files
$JSscripts = array();
if (isset($GLOBALS['defaultJSscipts']) && is_array($GLOBALS['defaultJSscipts']))
foreach ($GLOBALS['defaultJSscipts'] as $script)
if (!in_array($script, $JSscripts))
$JSscripts[] = $script;
LStemplate :: assign('LSsession_js',$JSscript_txt);
foreach (self :: $JSscripts as $script)
if (!in_array($script, $JSscripts))
$JSscripts[] = $script;
LStemplate :: assign('JSscripts', $JSscripts);
LStemplate :: assign('LibsJSscripts', self :: $LibsJSscripts);
LStemplate :: assign('LSdebug', boolval(LSdebug));
// Css
// CSS files
self :: addCssFile("LSdefault.css");
if (isset($GLOBALS['defaultCSSfiles']) && is_array($GLOBALS['defaultCSSfiles'])) {
foreach ($GLOBALS['defaultCSSfiles'] as $file) {
if (isset($GLOBALS['defaultCSSfiles']) && is_array($GLOBALS['defaultCSSfiles']))
foreach ($GLOBALS['defaultCSSfiles'] as $file)
if (!in_array($script, self :: $CssFiles))
self :: addCssFile($file);
}
}
$Css_txt='';
foreach (self :: $CssFiles as $file) {
$nocache = LStemplate :: getNoCacheFileValue($file);
$Css_txt.="<link rel='stylesheet' type='text/css' href='".$file."?nocache=$nocache' />\n";
}
LStemplate :: assign('LSsession_css',$Css_txt);
LStemplate :: assign('CssFiles', self :: $CssFiles);
LStemplate :: assign('LibsCssFiles', self :: $LibsCssFiles);
// Access
LStemplate :: assign('LSaccess', self :: getLSaccess());

View file

@ -48,6 +48,8 @@ class LStemplate {
'template_dir' => 'templates',
'image_dir' => 'images',
'css_dir' => 'css',
'js_dir' => 'includes/js',
'libs_dir' => 'includes/libs',
'compile_dir' => 'tmp',
'debug' => False,
'debug_smarty' => False
@ -60,10 +62,7 @@ class LStemplate {
private static $_smarty_version = NULL;
// Array of directories
private static $directories = array(
'local',
LS_THEME
);
private static $directories = array('local', LS_THEME, './');
// Registered events
private static $_events = array();
@ -177,11 +176,23 @@ class LStemplate {
$default_dir = self :: getDefaultDir();
$path = false;
foreach(self :: $directories as $dir) {
$path = $root_dir.'/'.$dir.'/'.$file;
if (file_exists($path)) {
$dir_path = realpath($root_dir.'/'.$dir);
if ($dir_path === false)
// Directory not found or not accessible
continue;
$file_path = realpath($dir_path.'/'.$file);
if ($file_path === false)
// File not found or not accessible
continue;
// Checks that the file is in the actual folder location
$pos = strpos($file_path, $dir_path);
if (!is_int($pos) || $pos != 0) {
LSlog :: error("LStemplate :: getFilePath($file, $root_dir, $default_dir, $with_nocache) : File '$file_path' is not in root directory '$dir_path' (".varDump($pos).").");
}
elseif (file_exists($file_path)) {
$path = $file_path;
break;
}
$path = false;
}
if (!$path) {
if (!$default_dir)
@ -222,6 +233,30 @@ class LStemplate {
return self :: getFilePath($css, self :: $config['css_dir'], Null, $with_nocache);
}
/**
* Return the path of the JS file to use
*
* @param[in] string $js The JS name (eg: LSdefaults.js)
* @param[in] bool $with_nocache If true, include nocache URL param (default: false)
*
* @retval string The path of the CSS file
**/
public static function getJSPath($js, $with_nocache=false) {
return self :: getFilePath($js, self :: $config['js_dir'], Null, $with_nocache);
}
/**
* Return the path of the libary file to use
*
* @param[in] string $file_path The lib file path (eg: arian-mootools-datepicker/Picker.js)
* @param[in] bool $with_nocache If true, include nocache URL param (default: false)
*
* @retval string The path of the Lib file
**/
public static function getLibFilePath($file_path, $with_nocache=false) {
return self :: getFilePath($file_path, self :: $config['libs_dir'], Null, $with_nocache);
}
/**
* Return the path of the Smarty template file to use
*
@ -429,8 +464,7 @@ function LStemplate_smarty_img($params) {
}
function LStemplate_smarty_css($params) {
extract($params);
echo LStemplate :: getCSSPath($name, true);
echo "css/".$params['name'];
}
function LStemplate_smarty_uniqid($params, &$smarty) {

View file

@ -665,14 +665,15 @@ function LSdebugDefined() {
* Dump file content
*
* @param[in] $file_path string The file path to dump
* @param[in] $mime_type string|null The MIME type return as Content-type (optional, default: auto-detected)
* @param[in] $max_age integer The cache max_age value, as return in Cache-Control HTTP header
* (optional, default: 3600)
*
* @retval void
**/
function dumpFile($file_path, $max_age=3600) {
function dumpFile($file_path, $mime_type=null, $max_age=3600) {
if (is_file($file_path)) {
header('Content-Type: '.mime_content_type($file_path));
header('Content-Type: '.(is_null($mime_type)?mime_content_type($file_path):$mime_type));
$last_modified_time = filemtime($file_path);
$etag = md5_file($file_path);
header("Cache-Control: max-age=$max_age, must-revalidate");

View file

@ -234,20 +234,59 @@ function handle_old_global_search_php($request) {
LSurl :: add_handler('#^global_search\.php#', 'handle_old_global_search_php');
/*
* Handle image request
* Handle static file request
*
* @param[in] $request LSurlRequest The request
*
* @retval void
**/
function handle_image($request) {
$img_path = LStemplate :: getImagePath($request -> image);
if (is_file($img_path)) {
dumpFile($img_path);
function handle_static_file($request) {
switch ($request -> type) {
case 'image':
$path = LStemplate :: getImagePath($request -> file);
$mime_type = null;
break;
case 'css':
$path = LStemplate :: getCSSPath($request -> file);
$mime_type = 'text/css';
break;
case 'js':
$path = LStemplate :: getJSPath($request -> file);
$mime_type = 'text/javascript';
break;
}
if ($path && is_file($path)) {
dumpFile($path, $mime_type);
}
LSurl :: error_404($request);
}
LSurl :: add_handler('#^image/(?P<image>[^/]+)$#', 'handle_image', false);
LSurl :: add_handler('#^(?P<type>image|css|js)/(?P<file>[^/]+)$#', 'handle_static_file', false);
/*
* Handle libs file request
*
* @param[in] $request LSurlRequest The request
*
* @retval void
**/
function handle_libs_file($request) {
$path = LStemplate :: getLibFilePath($request -> file);
if ($path && is_file($path)) {
switch (strtolower(substr($path, -4))) {
case '.css':
$mime_type = 'text/css';
break;
case '.js':
$mime_type = 'text/javascript';
break;
default:
$mime_type = null;
}
dumpFile($path, $mime_type);
}
LSurl :: error_404($request);
}
LSurl :: add_handler('#^libs/(?P<file>.+)$#', 'handle_libs_file', false);
/*
* Handle tmp file request

View file

@ -0,0 +1,13 @@
{if isset($CssFiles) && is_array($CssFiles)}
<!-- Additional CSS files -->
{foreach $CssFiles as $file}
<link rel="stylesheet" type="text/css" href="{css name=$file}" title="Normal" />
{/foreach}
{/if}
{if isset($LibsCssFiles) && is_array($LibsCssFiles)}
<!-- Additional libraries CSS files -->
{foreach $LibsCssFiles as $file}
<link rel="stylesheet" type="text/css" href="libs/{$file}" title="Normal" />
{/foreach}
{/if}

View file

@ -0,0 +1,16 @@
{if isset($JSscripts) && is_array($JSscripts)}
<!-- JS files -->
{foreach $JSscripts as $file}
<script src="js/{$file}" type="text/javascript"></script>
{/foreach}
{/if}
<!-- Set LSdebug status -->
<script type='text/javascript'>LSdebug_active = {if $LSdebug}1{else}0{/if};</script>
{if isset($LibsJSscripts) && is_array($LibsJSscripts)}
<!-- Additional libraries JS files -->
{foreach $LibsJSscripts as $file}
<script src="libs/{$file}" type="text/javascript"></script>
{/foreach}
{/if}

View file

@ -8,13 +8,13 @@
<link rel="icon" type="image/png" href="images/default/favicon.png" />
<link rel="stylesheet" type="text/css" href="{css name='base.css'}" title="Normal" />
<link rel="stylesheet" type="text/css" href="{css name='base_print.css'}" media='print' title="Normal" />
{$LSsession_css}
{include file='ls:LSsession_css.tpl'}
</head>
<body>
{include file='ls:LSdefault.tpl'}
{$LSsession_js}
{include file='ls:LSsession_js.tpl'}
</body>
</html>

View file

@ -1,6 +1,6 @@
</td>
</tr>
</table>
{$LSsession_js}
{include file='ls:LSsession_js.tpl'}
</body>
</html>

View file

@ -8,17 +8,16 @@
<link rel="icon" type="image/png" href="images/default/favicon.png" />
<link rel="stylesheet" type="text/css" href="{css name='base.css'}" title="Normal" />
<link rel="stylesheet" type="text/css" href="{css name='base_print.css'}" media='print' title="Normal" />
{$LSsession_css}
{include file='ls:LSsession_css.tpl'}
</head>
<body>
{include file='ls:LSdefault.tpl'}
{$LSsession_js}
<div id="fatal_error">
<h1>{tr msg="The requested page was not found."}</h1>
</div>
{include file='ls:LSsession_js.tpl'}
</body>
</html>

View file

@ -8,14 +8,12 @@
<link rel="icon" type="image/png" href="images/default/favicon.png" />
<link rel="stylesheet" type="text/css" href="{css name='base.css'}" title="Normal" />
<link rel="stylesheet" type="text/css" href="{css name='base_print.css'}" media='print' title="Normal" />
{$LSsession_css}
{include file='ls:LSsession_css.tpl'}
</head>
<body>
{include file='ls:LSdefault.tpl'}
{$LSsession_js}
<div id="fatal_error">
<h1>{tr msg="A fatal error occured. If problem persist, please contact support."}</h1>
@ -26,5 +24,6 @@
{/if}
</div>
{include file='ls:LSsession_js.tpl'}
</body>
</html>

View file

@ -7,8 +7,7 @@
<base href="{$public_root_url}/"/>
<link rel="icon" type="image/png" href="images/default/favicon.png" />
<link rel="stylesheet" type="text/css" href="{css name='login.css'}" media="screen" title="Normal" />
{$LSsession_css}
{$LSsession_js}
{include file='ls:LSsession_css.tpl'}
</head>
<body>
@ -43,5 +42,6 @@
<span>{$lang_label} : <img id='LSlang' src='{img name=$LSlang}' alt='{$LSlang|escape:"htmlall"}' title='{$LSlang|escape:"htmlall"}'/></span>
<a href='index.php?LSsession_recoverPassword' class='LSsession_recoverPassword LSsession_recoverPassword_hidden'>{$loginform_label_recoverPassword|escape:"htmlall"}</a>
</div>
{include file='ls:LSsession_js.tpl'}
</body>
</html>

View file

@ -6,8 +6,7 @@
<title>LdapSaisie{if $pagetitle != ''} - {$pagetitle|escape:"htmlall"}{/if}</title>
<base href="{$public_root_url}/"/>
<link rel="stylesheet" type="text/css" href="{css name='recoverpassword.css'}" media="screen" title="Normal" />
{$LSsession_css}
{$LSsession_js}
{include file='ls:LSsession_css.tpl'}
</head>
<body>
@ -34,5 +33,6 @@
<span>{$lang_label|escape:"htmlall"} : <img id='LSlang' src='{img name=$LSlang}' alt='{$LSlang|escape:"htmlall"}' title='{$LSlang|escape:"htmlall"}'/></span>
<a href='index.php' id='recoverpassword_back'>{$recoverpasswordform_label_back|escape:"htmlall"}</a>
</div>
{include file='ls:LSsession_js.tpl'}
</body>
</html>

View file

@ -8,7 +8,7 @@
<link rel="icon" type="image/png" href="images/default/favicon.png" />
<link rel="stylesheet" type="text/css" href="{css name='base.css'}" title="Normal" />
<link rel="stylesheet" type="text/css" href="{css name='base_print.css'}" media='print' title="Normal" />
{$LSsession_css}
{include file='ls:LSsession_css.tpl'}
</head>
<body>