Tpl: Add stuff to handle static files
* Move example application in example sub-directory * Widely use App::get() instead of Config::get()
This commit is contained in:
parent
f2edf4910a
commit
4f47dc056d
1148 changed files with 319 additions and 2959 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -3,6 +3,7 @@
|
||||||
.*.swp
|
.*.swp
|
||||||
# Exclude composer installed libs
|
# Exclude composer installed libs
|
||||||
/vendor
|
/vendor
|
||||||
|
/composer.lock
|
||||||
# Common UNIX user home directory files
|
# Common UNIX user home directory files
|
||||||
/.bash*
|
/.bash*
|
||||||
/.vim*
|
/.vim*
|
||||||
|
|
|
@ -26,7 +26,8 @@
|
||||||
"sentry/sdk": "^3.3",
|
"sentry/sdk": "^3.3",
|
||||||
"ext-pdo": "^7.3",
|
"ext-pdo": "^7.3",
|
||||||
"ext-json": "^7.3",
|
"ext-json": "^7.3",
|
||||||
"ext-yaml": "^2.0"
|
"ext-yaml": "^2.0",
|
||||||
|
"league/mime-type-detection": "^1.11"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpstan/phpstan": "^1.9"
|
"phpstan/phpstan": "^1.9"
|
||||||
|
|
2866
composer.lock
generated
2866
composer.lock
generated
File diff suppressed because it is too large
Load diff
0
data/.gitignore → example/data/.gitignore
vendored
0
data/.gitignore → example/data/.gitignore
vendored
|
@ -1,7 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use EesyPHP\App;
|
use EesyPHP\App;
|
||||||
use EesyPHP\Config;
|
|
||||||
use EesyPHP\I18n;
|
use EesyPHP\I18n;
|
||||||
use EesyPHP\SentrySpan;
|
use EesyPHP\SentrySpan;
|
||||||
|
|
||||||
|
@ -25,7 +24,7 @@ $root_dir_path = realpath(dirname($script).'/../');
|
||||||
set_include_path($root_dir_path.'/includes' . PATH_SEPARATOR . get_include_path());
|
set_include_path($root_dir_path.'/includes' . PATH_SEPARATOR . get_include_path());
|
||||||
|
|
||||||
// Load composer autoload.php
|
// Load composer autoload.php
|
||||||
require("$root_dir_path/vendor/autoload.php");
|
require("$root_dir_path/../vendor/autoload.php");
|
||||||
|
|
||||||
// Initialize EesyPHP application
|
// Initialize EesyPHP application
|
||||||
App::init(
|
App::init(
|
||||||
|
@ -34,6 +33,11 @@ App::init(
|
||||||
'overwrite_config_files' => array(
|
'overwrite_config_files' => array(
|
||||||
"$root_dir_path/includes/config.local.yml",
|
"$root_dir_path/includes/config.local.yml",
|
||||||
),
|
),
|
||||||
|
'templates' => array(
|
||||||
|
'static_directories' => array(
|
||||||
|
"$root_dir_path/static"
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
$root_dir_path
|
$root_dir_path
|
||||||
);
|
);
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use EesyPHP\Config;
|
use EesyPHP\App;
|
||||||
use EesyPHP\Db;
|
use EesyPHP\Db;
|
||||||
use EesyPHP\Hook;
|
use EesyPHP\Hook;
|
||||||
use EesyPHP\Log;
|
use EesyPHP\Log;
|
||||||
|
@ -8,12 +8,12 @@ use EesyPHP\Log;
|
||||||
use Unidecode\Unidecode;
|
use Unidecode\Unidecode;
|
||||||
|
|
||||||
$db = new Db(
|
$db = new Db(
|
||||||
Config::get('db.dsn', null, 'string'),
|
App::get('db.dsn', null, 'string'),
|
||||||
Config::get('db.user', null, 'string'),
|
App::get('db.user', null, 'string'),
|
||||||
Config::get('db.password', null, 'string'),
|
App::get('db.password', null, 'string'),
|
||||||
Config::get('db.options', array(), 'array'),
|
App::get('db.options', array(), 'array'),
|
||||||
Config::get('db.date_format', null, 'string'),
|
App::get('db.date_format', null, 'string'),
|
||||||
Config::get('db.datetime_format', null, 'string'),
|
App::get('db.datetime_format', null, 'string'),
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -154,7 +154,7 @@ function search_items($params) {
|
||||||
global $db;
|
global $db;
|
||||||
|
|
||||||
// Detect PgSQL backend
|
// Detect PgSQL backend
|
||||||
$is_pgsql = (strpos(Config::get('db.dsn', '', 'string'), "pgsql:") === 0);
|
$is_pgsql = (strpos(App::get('db.dsn', '', 'string'), "pgsql:") === 0);
|
||||||
|
|
||||||
$where = array();
|
$where = array();
|
||||||
if (isset($params['status']) && $params['status'] && $params['status'] != 'all')
|
if (isset($params['status']) && $params['status'] && $params['status'] != 'all')
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
use EesyPHP\Config;
|
use EesyPHP\App;
|
||||||
use EesyPHP\Date;
|
use EesyPHP\Date;
|
||||||
use EesyPHP\Hook;
|
use EesyPHP\Hook;
|
||||||
use EesyPHP\Log;
|
use EesyPHP\Log;
|
||||||
|
@ -23,13 +23,13 @@ Tpl :: enable_security_mode(
|
||||||
);
|
);
|
||||||
|
|
||||||
// Defined some global template variables
|
// Defined some global template variables
|
||||||
Tpl :: assign('public_root_url', Config::get('public_root_url', '/', 'string'));
|
Tpl :: assign('public_root_url', App::get('public_root_url', '/', 'string'));
|
||||||
Tpl :: assign('main_pagetitle', Config::get('main_pagetitle', null, 'string'));
|
Tpl :: assign('main_pagetitle', App::get('main_pagetitle', null, 'string'));
|
||||||
Tpl :: assign('session_key', $_SESSION['session_key']);
|
Tpl :: assign('session_key', $_SESSION['session_key']);
|
||||||
|
|
||||||
// Handle CSS & JS files included
|
// Handle CSS & JS files included
|
||||||
Tpl :: add_css_file(Config::get('included_css_files', array(), 'array'));
|
Tpl :: add_css_file(App::get('included_css_files', array(), 'array'));
|
||||||
Tpl :: add_js_file(Config::get('included_js_files', array(), 'array'));
|
Tpl :: add_js_file(App::get('included_js_files', array(), 'array'));
|
||||||
|
|
||||||
function define_common_template_variables($event) {
|
function define_common_template_variables($event) {
|
||||||
global $status_list, $admin;
|
global $status_list, $admin;
|
||||||
|
@ -41,7 +41,7 @@ function define_common_template_variables($event) {
|
||||||
Tpl :: assign('admin', isset($admin) && $admin);
|
Tpl :: assign('admin', isset($admin) && $admin);
|
||||||
Tpl :: assign(
|
Tpl :: assign(
|
||||||
'webstats_js_code',
|
'webstats_js_code',
|
||||||
Config::get('webstats_js_code', null, 'string'));
|
App::get('webstats_js_code', null, 'string'));
|
||||||
}
|
}
|
||||||
Hook :: register('before_displaying_template', 'define_common_template_variables');
|
Hook :: register('before_displaying_template', 'define_common_template_variables');
|
||||||
|
|
|
@ -102,11 +102,11 @@ function handle_search($request) {
|
||||||
Tpl :: assign('nbs_by_page', $nbs_by_page);
|
Tpl :: assign('nbs_by_page', $nbs_by_page);
|
||||||
Tpl :: assign('status_list', $status_list);
|
Tpl :: assign('status_list', $status_list);
|
||||||
|
|
||||||
Tpl :: add_js_file(array(
|
Tpl :: add_js_file(
|
||||||
'lib/bootstrap4dialog/dist/js/bootstrap4dialog.min.js',
|
'lib/bootstrap4dialog/dist/js/bootstrap4dialog.min.js',
|
||||||
'js/myconfirm.js',
|
'js/myconfirm.js',
|
||||||
'js/search.js'
|
'js/search.js'
|
||||||
));
|
);
|
||||||
|
|
||||||
Tpl :: display("search.tpl", _("Search"));
|
Tpl :: display("search.tpl", _("Search"));
|
||||||
}
|
}
|
||||||
|
@ -124,10 +124,10 @@ function handle_show($request) {
|
||||||
Tpl :: assign('item', $item);
|
Tpl :: assign('item', $item);
|
||||||
|
|
||||||
// Dialog
|
// Dialog
|
||||||
Tpl :: add_js_file(array(
|
Tpl :: add_js_file(
|
||||||
'lib/bootstrap4dialog/dist/js/bootstrap4dialog.min.js',
|
'lib/bootstrap4dialog/dist/js/bootstrap4dialog.min.js',
|
||||||
'js/myconfirm.js',
|
'js/myconfirm.js',
|
||||||
));
|
);
|
||||||
|
|
||||||
Tpl :: display(
|
Tpl :: display(
|
||||||
"show.tpl", _("Element %s"),
|
"show.tpl", _("Element %s"),
|
|
@ -1,30 +1,29 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="fr">
|
<html lang="fr">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8"/>
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
|
||||||
<meta name="description" content="">
|
<meta name="description" content=""/>
|
||||||
<meta name="author" content="">
|
<meta name="author" content=""/>
|
||||||
|
|
||||||
<base href="{$public_root_url}/"/>
|
<base href="{$public_root_url}/"/>
|
||||||
{block name="head"}{/block}
|
{block name="head"}{/block}
|
||||||
|
|
||||||
<link rel="icon" href="images/favicon.png">
|
<link rel="icon" href="{static_url path="images/favicon.png"}"/>
|
||||||
|
|
||||||
<title>{$main_pagetitle}{if $pagetitle} - {$pagetitle}{/if}</title>
|
<title>{$main_pagetitle}{if $pagetitle} - {$pagetitle}{/if}</title>
|
||||||
|
|
||||||
<!-- Bootstrap -->
|
<!-- Bootstrap -->
|
||||||
<link href="lib/bootstrap4/css/bootstrap.min.css" rel="stylesheet">
|
<link href="{static_url path="lib/bootstrap4/css/bootstrap.min.css"}" rel="stylesheet"/>
|
||||||
|
|
||||||
<!-- Font Awesome -->
|
<!-- Font Awesome -->
|
||||||
<link href="lib/Fork-Awesome-1.1.7/css/fork-awesome.min.css" rel="stylesheet">
|
<link href="{static_url path="lib/Fork-Awesome-1.1.7/css/fork-awesome.min.css"}" rel="stylesheet"/>
|
||||||
|
|
||||||
<link href="css/style.css" rel="stylesheet">
|
<link href="{static_url path="css/style.css"}" rel="stylesheet"/>
|
||||||
{foreach $css as $file}
|
{foreach $css as $path}
|
||||||
<link href="{$file}" rel="stylesheet">
|
<link href="{$path|escape:"quotes"}" rel="stylesheet"/>
|
||||||
{/foreach}
|
{/foreach}
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
@ -34,7 +33,7 @@
|
||||||
{block name="navbar"}
|
{block name="navbar"}
|
||||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||||
<a class="navbar-brand" href="">
|
<a class="navbar-brand" href="">
|
||||||
<img id="logo" src="images/logo.png" alt="Logo" title="Logo"/>
|
<img id="logo" src="{static_url path="images/logo.png"}" alt="Logo" title="Logo"/>
|
||||||
</a>
|
</a>
|
||||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
<span class="navbar-toggler-icon"></span>
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
@ -89,12 +88,12 @@
|
||||||
|
|
||||||
|
|
||||||
<!-- Jquery & Bootstrap -->
|
<!-- Jquery & Bootstrap -->
|
||||||
<script src="lib/jquery-3.4.1.min.js"></script>
|
<script src="{static_url path="lib/jquery-3.4.1.min.js"}"></script>
|
||||||
<script src="lib/bootstrap4/js/bootstrap.bundle.min.js"></script>
|
<script src="{static_url path="lib/bootstrap4/js/bootstrap.bundle.min.js"}"></script>
|
||||||
|
|
||||||
<!-- Other libs & JavaScript scripts -->
|
<!-- Other libs & JavaScript scripts -->
|
||||||
{foreach $js as $file}
|
{foreach $js as $path}
|
||||||
<script language="javascript" src="{$file}"></script>
|
<script language="javascript" src="{$path|escape:"quotes"}"></script>
|
||||||
{/foreach}
|
{/foreach}
|
||||||
|
|
||||||
{if $webstats_js_code}{$webstats_js_code}{/if}
|
{if $webstats_js_code}{$webstats_js_code}{/if}
|
11
phpstan.neon
11
phpstan.neon
|
@ -2,11 +2,12 @@ parameters:
|
||||||
level: 5
|
level: 5
|
||||||
paths:
|
paths:
|
||||||
- src
|
- src
|
||||||
- includes
|
- example
|
||||||
- public_html
|
|
||||||
- bin/eesyphp
|
|
||||||
excludePaths:
|
excludePaths:
|
||||||
- includes/config.local.php
|
- example/includes/config.local.php
|
||||||
|
- example/data/tmp/templates_c
|
||||||
|
universalObjectCratesClasses:
|
||||||
|
- EesyPHP\UrlRequest
|
||||||
ignoreErrors:
|
ignoreErrors:
|
||||||
-
|
-
|
||||||
message: "#Instantiated class Mail_mime not found\\.#"
|
message: "#Instantiated class Mail_mime not found\\.#"
|
||||||
|
@ -23,5 +24,5 @@ parameters:
|
||||||
-
|
-
|
||||||
message: "#Variable \\$status_list might not be defined\\.#"
|
message: "#Variable \\$status_list might not be defined\\.#"
|
||||||
paths:
|
paths:
|
||||||
- includes/cli.php
|
- example/includes/cli.php
|
||||||
|
|
||||||
|
|
30
src/App.php
30
src/App.php
|
@ -40,35 +40,43 @@ class App {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load overwrite configuration file
|
// Load overwrite configuration file
|
||||||
foreach (self :: get_option('overwrite_config_files', array(), 'array') as $file) {
|
foreach (self :: get('overwrite_config_files', array(), 'array') as $file) {
|
||||||
$file = Config::replace_variables($file);
|
$file = Config::replace_variables($file);
|
||||||
if (is_file($file)) Config::load($file, true);
|
if (is_file($file)) Config::load($file, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self :: get_option('sentry.enabled', true, 'bool'))
|
if (self :: get('sentry.enabled', true, 'bool'))
|
||||||
SentryIntegration :: init();
|
SentryIntegration :: init();
|
||||||
$sentry_transaction = new SentryTransaction();
|
$sentry_transaction = new SentryTransaction();
|
||||||
$sentry_span = new SentrySpan('app.init', 'Application initialization');
|
$sentry_span = new SentrySpan('app.init', 'Application initialization');
|
||||||
|
|
||||||
// Define upload_tmp_dir
|
// Define upload_tmp_dir
|
||||||
if (is_string(Config::get('upload_tmp_directory')))
|
if (is_string(self::get('upload_tmp_directory')))
|
||||||
ini_set('upload_tmp_dir', Config::get('upload_tmp_directory'));
|
ini_set('upload_tmp_dir', self::get('upload_tmp_directory'));
|
||||||
|
|
||||||
if (self :: get_option('log.enabled', true, 'bool'))
|
if (self :: get('log.enabled', true, 'bool'))
|
||||||
Log::init();
|
Log::init();
|
||||||
if (self :: get_option('session.enabled', true, 'bool'))
|
if (self :: get('session.enabled', true, 'bool'))
|
||||||
Session::init();
|
Session::init();
|
||||||
if (self :: get_option('template.enabled', true, 'bool'))
|
if (self :: get('template.enabled', true, 'bool'))
|
||||||
Tpl :: init();
|
Tpl :: init();
|
||||||
if (self :: get_option('url.enabled', true, 'bool'))
|
if (self :: get('url.enabled', true, 'bool'))
|
||||||
Url::init();
|
Url::init();
|
||||||
if (self :: get_option('mail.enabled', true, 'bool'))
|
if (self :: get('mail.enabled', true, 'bool'))
|
||||||
Email :: init();
|
Email :: init();
|
||||||
if (self :: get_option('i18n.enabled', true, 'bool'))
|
if (self :: get('i18n.enabled', true, 'bool'))
|
||||||
I18n::init();
|
I18n::init();
|
||||||
$sentry_span->finish();
|
$sentry_span->finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the application is initialized
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function initialized() {
|
||||||
|
return !is_null(self :: $root_directory_path);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a specific option value
|
* Get a specific option value
|
||||||
*
|
*
|
||||||
|
@ -82,7 +90,7 @@ class App {
|
||||||
* is a string, split the value by comma (optional, default: true)
|
* is a string, split the value by comma (optional, default: true)
|
||||||
* @return mixed The configuration variable value
|
* @return mixed The configuration variable value
|
||||||
**/
|
**/
|
||||||
public static function get_option($key, $default=null, $cast=null, $split=true) {
|
public static function get($key, $default=null, $cast=null, $split=true) {
|
||||||
return Config::get(
|
return Config::get(
|
||||||
$key,
|
$key,
|
||||||
Config::loaded()?Config::get($key, $default, $cast, $split):$default,
|
Config::loaded()?Config::get($key, $default, $cast, $split):$default,
|
||||||
|
|
|
@ -68,31 +68,31 @@ class Email {
|
||||||
public static function init($sender=null, $send_method=null, $send_params=null, $catch_all=null,
|
public static function init($sender=null, $send_method=null, $send_params=null, $catch_all=null,
|
||||||
$headers=null, $php_mail_path=null, $php_mail_mime_path=null) {
|
$headers=null, $php_mail_path=null, $php_mail_mime_path=null) {
|
||||||
if (is_null($sender))
|
if (is_null($sender))
|
||||||
$sender = Config::get('email.sender', null, 'string');
|
$sender = App::get('email.sender', null, 'string');
|
||||||
if ($sender) self :: $sender = $sender;
|
if ($sender) self :: $sender = $sender;
|
||||||
|
|
||||||
if (is_null($send_method))
|
if (is_null($send_method))
|
||||||
$send_method = Config::get('email.send_method', null, 'string');
|
$send_method = App::get('email.send_method', null, 'string');
|
||||||
if ($send_method) self :: $send_method = $send_method;
|
if ($send_method) self :: $send_method = $send_method;
|
||||||
|
|
||||||
if (is_null($send_params))
|
if (is_null($send_params))
|
||||||
$send_params = Config::get('email.send_params', null, 'array');
|
$send_params = App::get('email.send_params', null, 'array');
|
||||||
if ($send_params) self :: $send_params = $send_params;
|
if ($send_params) self :: $send_params = $send_params;
|
||||||
|
|
||||||
if (is_null($catch_all))
|
if (is_null($catch_all))
|
||||||
$catch_all = Config::get('email.catch_all');
|
$catch_all = App::get('email.catch_all');
|
||||||
if ($catch_all) self :: $catch_all = $catch_all;
|
if ($catch_all) self :: $catch_all = $catch_all;
|
||||||
|
|
||||||
if (is_null($headers))
|
if (is_null($headers))
|
||||||
$headers = Config::get('email.headers', null, 'array');
|
$headers = App::get('email.headers', null, 'array');
|
||||||
if ($headers) self :: $headers = $headers;
|
if ($headers) self :: $headers = $headers;
|
||||||
|
|
||||||
if (is_null($php_mail_path))
|
if (is_null($php_mail_path))
|
||||||
$php_mail_path = Config::get('email.php_mail_path', null, 'string');
|
$php_mail_path = App::get('email.php_mail_path', null, 'string');
|
||||||
if ($php_mail_path) self :: $php_mail_path = $php_mail_path;
|
if ($php_mail_path) self :: $php_mail_path = $php_mail_path;
|
||||||
|
|
||||||
if (is_null($php_mail_mime_path))
|
if (is_null($php_mail_mime_path))
|
||||||
$php_mail_mime_path = Config::get('email.php_mail_mime_path', null, 'string');
|
$php_mail_mime_path = App::get('email.php_mail_mime_path', null, 'string');
|
||||||
if ($php_mail_mime_path) self :: $php_mail_mime_path = $php_mail_mime_path;
|
if ($php_mail_mime_path) self :: $php_mail_mime_path = $php_mail_mime_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
15
src/I18n.php
15
src/I18n.php
|
@ -36,13 +36,13 @@ class I18n {
|
||||||
*/
|
*/
|
||||||
public static function init($root_path=null, $default_locale=null) {
|
public static function init($root_path=null, $default_locale=null) {
|
||||||
if (is_null($root_path))
|
if (is_null($root_path))
|
||||||
self :: $root_path = Config::get(
|
self :: $root_path = App::get(
|
||||||
'i18n.root_directory', '${root_directory_path}/locales', 'string');
|
'i18n.root_directory', '${root_directory_path}/locales', 'string');
|
||||||
if (!is_null($root_path))
|
if (!is_null($root_path))
|
||||||
self :: $root_path = $root_path;
|
self :: $root_path = $root_path;
|
||||||
|
|
||||||
if (is_null($default_locale))
|
if (is_null($default_locale))
|
||||||
self :: $default_locale = Config::get('i18n.default_locale', null, 'string');
|
self :: $default_locale = App::get('i18n.default_locale', null, 'string');
|
||||||
if (!is_null($default_locale))
|
if (!is_null($default_locale))
|
||||||
self :: $default_locale = $default_locale;
|
self :: $default_locale = $default_locale;
|
||||||
|
|
||||||
|
@ -68,7 +68,10 @@ class I18n {
|
||||||
else {
|
else {
|
||||||
$lang = Locale::lookup(
|
$lang = Locale::lookup(
|
||||||
self :: get_available_langs(),
|
self :: get_available_langs(),
|
||||||
Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE']),
|
Locale::acceptFromHttp(
|
||||||
|
isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])?
|
||||||
|
$_SERVER['HTTP_ACCEPT_LANGUAGE']:null
|
||||||
|
),
|
||||||
true,
|
true,
|
||||||
Locale::getPrimaryLanguage(self :: $default_locale)
|
Locale::getPrimaryLanguage(self :: $default_locale)
|
||||||
);
|
);
|
||||||
|
@ -111,13 +114,13 @@ class I18n {
|
||||||
Log :: trace("Test: "._('Hello world !'));
|
Log :: trace("Test: "._('Hello world !'));
|
||||||
|
|
||||||
// JS translation file
|
// JS translation file
|
||||||
$js_translation_file = "translations/$lang.js";
|
|
||||||
if (
|
if (
|
||||||
php_sapi_name() != "cli"
|
php_sapi_name() != "cli"
|
||||||
&& is_file(App :: root_directory_path()."/public_html/$js_translation_file")
|
|
||||||
&& Tpl :: initialized()
|
&& Tpl :: initialized()
|
||||||
) {
|
) {
|
||||||
Tpl :: add_js_file(array("lib/babel.js", "js/translation.js", $js_translation_file));
|
Tpl :: register_static_directory(self :: $root_path, null, 'locales/');
|
||||||
|
Tpl :: add_js_file("lib/babel.js", "js/translation.js");
|
||||||
|
Tpl :: add_js_file("locales/", "$lang.js");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (php_sapi_name() == 'cli') {
|
if (php_sapi_name() == 'cli') {
|
||||||
|
|
10
src/Log.php
10
src/Log.php
|
@ -72,19 +72,19 @@ class Log {
|
||||||
if ($filepath)
|
if ($filepath)
|
||||||
self :: $filepath = $filepath;
|
self :: $filepath = $filepath;
|
||||||
elseif (php_sapi_name() == 'cli')
|
elseif (php_sapi_name() == 'cli')
|
||||||
self :: $filepath = Config::get(
|
self :: $filepath = App::get(
|
||||||
'log.cli_logfile_path', Config::get('log.cli_file_path'));
|
'log.cli_logfile_path', App::get('log.cli_file_path'));
|
||||||
else
|
else
|
||||||
self :: $filepath = Config::get('log.file_path');
|
self :: $filepath = App::get('log.file_path');
|
||||||
|
|
||||||
// Set log level
|
// Set log level
|
||||||
self :: set_level($level?$level:Config::get('log.level'));
|
self :: set_level($level?$level:App::get('log.level'));
|
||||||
|
|
||||||
// Log PHP errors
|
// Log PHP errors
|
||||||
if (!is_null($php_errors_levels)) {
|
if (!is_null($php_errors_levels)) {
|
||||||
self :: $php_errors_levels = $php_errors_levels;
|
self :: $php_errors_levels = $php_errors_levels;
|
||||||
}
|
}
|
||||||
elseif ($levels = Config::get('log.php_errors_levels', array(), 'array')) {
|
elseif ($levels = App::get('log.php_errors_levels', array(), 'array')) {
|
||||||
$code = 'self :: $php_errors_levels = ';
|
$code = 'self :: $php_errors_levels = ';
|
||||||
while($level = array_shift($levels)) {
|
while($level = array_shift($levels)) {
|
||||||
if (!is_string($level)) continue;
|
if (!is_string($level)) continue;
|
||||||
|
|
|
@ -38,11 +38,11 @@ class SentryIntegration {
|
||||||
public static function init($dsn=null, $traces_sample_rate=null,
|
public static function init($dsn=null, $traces_sample_rate=null,
|
||||||
$php_error_types=null) {
|
$php_error_types=null) {
|
||||||
\Sentry\init([
|
\Sentry\init([
|
||||||
'dsn' => $dsn?$dsn:Config::get('sentry.dsn'),
|
'dsn' => $dsn?$dsn:App::get('sentry.dsn'),
|
||||||
'traces_sample_rate' => (
|
'traces_sample_rate' => (
|
||||||
$traces_sample_rate?
|
$traces_sample_rate?
|
||||||
$traces_sample_rate:
|
$traces_sample_rate:
|
||||||
Config::get('sentry.traces_sample_rate', 0.2, 'float')
|
App::get('sentry.traces_sample_rate', 0.2, 'float')
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ class SentryIntegration {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!is_array($php_error_types))
|
if (!is_array($php_error_types))
|
||||||
$php_error_types = Config::get(
|
$php_error_types = App::get(
|
||||||
'sentry.php_error_types', self :: $php_error_types, 'array'
|
'sentry.php_error_types', self :: $php_error_types, 'array'
|
||||||
);
|
);
|
||||||
self :: $php_error_types = array();
|
self :: $php_error_types = array();
|
||||||
|
|
|
@ -27,7 +27,7 @@ class Session {
|
||||||
|
|
||||||
// Define session max duration
|
// Define session max duration
|
||||||
if (is_null($max_duration))
|
if (is_null($max_duration))
|
||||||
$max_duration = Config::get('session.max_duration', null, 'int');
|
$max_duration = App::get('session.max_duration', null, 'int');
|
||||||
if (is_int($max_duration))
|
if (is_int($max_duration))
|
||||||
self :: $max_duration = $max_duration;
|
self :: $max_duration = $max_duration;
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ class Session {
|
||||||
|
|
||||||
// Handle session timeout
|
// Handle session timeout
|
||||||
if (is_null($timeout))
|
if (is_null($timeout))
|
||||||
$timeout = Config::get('session.timeout', null, 'int');
|
$timeout = App::get('session.timeout', null, 'int');
|
||||||
if (is_int($timeout) && $timeout) {
|
if (is_int($timeout) && $timeout) {
|
||||||
if (!isset($_SESSION['session_last_access'])) {
|
if (!isset($_SESSION['session_last_access'])) {
|
||||||
Log :: debug('Set initial session last access');
|
Log :: debug('Set initial session last access');
|
||||||
|
|
203
src/Tpl.php
203
src/Tpl.php
|
@ -5,6 +5,7 @@ namespace EesyPHP;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Smarty;
|
use Smarty;
|
||||||
use Smarty_Security;
|
use Smarty_Security;
|
||||||
|
use League\MimeTypeDetection\ExtensionMimeTypeDetector;
|
||||||
|
|
||||||
class Tpl {
|
class Tpl {
|
||||||
|
|
||||||
|
@ -38,6 +39,12 @@ class Tpl {
|
||||||
*/
|
*/
|
||||||
public static bool $_debug_ajax;
|
public static bool $_debug_ajax;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Static directories
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private static array $static_directories = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CSS files to load in next displayed page
|
* CSS files to load in next displayed page
|
||||||
* @var array<string>
|
* @var array<string>
|
||||||
|
@ -50,6 +57,18 @@ class Tpl {
|
||||||
*/
|
*/
|
||||||
private static array $js_files = array();
|
private static array $js_files = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MIME type detector object
|
||||||
|
* @var null|string
|
||||||
|
*/
|
||||||
|
private static $static_root_url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MIME type detector object
|
||||||
|
* @var ExtensionMimeTypeDetector|null
|
||||||
|
*/
|
||||||
|
private static $mime_type_detector = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialization
|
* Initialization
|
||||||
* @param string $templates_dir Smarty templates directory path
|
* @param string $templates_dir Smarty templates directory path
|
||||||
|
@ -59,14 +78,18 @@ class Tpl {
|
||||||
* @param bool $debug_ajax Enable/disable AJAX returned data debugging in logs
|
* @param bool $debug_ajax Enable/disable AJAX returned data debugging in logs
|
||||||
* (optional, default: from template.debug_ajax or debug_ajax config keys if set,
|
* (optional, default: from template.debug_ajax or debug_ajax config keys if set,
|
||||||
* false otherwise)
|
* false otherwise)
|
||||||
|
* @param bool $static_root_url Configure custom root URL path for static files
|
||||||
|
* (optional, default: from template.static_root_url config key if set,
|
||||||
|
* '/static' otherwise. Set to False to disable)
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public static function init($templates_dir=null, $templates_c_dir=null, $debug_ajax=null) {
|
public static function init($templates_dir=null, $templates_c_dir=null, $debug_ajax=null,
|
||||||
|
$static_root_url=null) {
|
||||||
// Check templates/templates_c directories
|
// Check templates/templates_c directories
|
||||||
if (is_null($templates_dir))
|
if (is_null($templates_dir))
|
||||||
$templates_dir = Config::get('template.directory', null, 'string');
|
$templates_dir = App::get('template.directory', null, 'string');
|
||||||
if (is_null($templates_c_dir))
|
if (is_null($templates_c_dir))
|
||||||
$templates_c_dir = Config::get('template.cache_directory', null, 'string');
|
$templates_c_dir = App::get('template.cache_directory', null, 'string');
|
||||||
if (!$templates_dir || !is_dir($templates_dir)) {
|
if (!$templates_dir || !is_dir($templates_dir)) {
|
||||||
Log :: fatal(
|
Log :: fatal(
|
||||||
"Template directory not found (%s)",
|
"Template directory not found (%s)",
|
||||||
|
@ -83,9 +106,25 @@ class Tpl {
|
||||||
self :: $smarty->setTemplateDir($templates_dir);
|
self :: $smarty->setTemplateDir($templates_dir);
|
||||||
self :: $smarty->setCompileDir($templates_c_dir);
|
self :: $smarty->setCompileDir($templates_c_dir);
|
||||||
if (is_null($debug_ajax))
|
if (is_null($debug_ajax))
|
||||||
$debug_ajax = Config::get('template.debug_ajax', Config::get('debug_ajax'));
|
$debug_ajax = App::get('template.debug_ajax', App::get('debug_ajax'));
|
||||||
self :: $_debug_ajax = boolval($debug_ajax);
|
self :: $_debug_ajax = boolval($debug_ajax);
|
||||||
Log :: register_fatal_error_handler(array('\\EesyPHP\\Tpl', 'fatal_error'));
|
Log :: register_fatal_error_handler(array('\\EesyPHP\\Tpl', 'fatal_error'));
|
||||||
|
|
||||||
|
if (is_null($static_root_url))
|
||||||
|
$static_root_url = App::get('template.static_root_url', 'static/', 'string');
|
||||||
|
if ($static_root_url) {
|
||||||
|
if (substr($static_root_url, 0, 1) == '/')
|
||||||
|
$static_root_url = substr($static_root_url, 1);
|
||||||
|
if (substr($static_root_url, -1) != '/')
|
||||||
|
$static_root_url = "$static_root_url/";
|
||||||
|
self :: $static_root_url = $static_root_url;
|
||||||
|
$default_static_directory = realpath(__DIR__."/../static");
|
||||||
|
self :: register_static_directory($default_static_directory, 100);
|
||||||
|
self :: register_function('static_url', array('EesyPHP\\Tpl', 'smarty_static_url'));
|
||||||
|
|
||||||
|
foreach(App :: get('templates.static_directories', array(), 'array') as $path)
|
||||||
|
self :: register_static_directory($path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -175,30 +214,50 @@ class Tpl {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register CSS file(s) to load on next displayed page
|
* Register CSS file(s) to load on next displayed page
|
||||||
* @param array<string|array<string>> $args CSS files to load
|
* @param string|array<string> $args CSS files to load
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public static function add_css_file(...$args) {
|
public static function add_css_file(...$args) {
|
||||||
|
// Check if the first argument is a custom static root URL
|
||||||
|
$root_url = self :: $static_root_url;
|
||||||
|
if (
|
||||||
|
$args && is_string($args[0]) && array_key_exists(
|
||||||
|
self :: clean_static_root_url($args[0]),
|
||||||
|
self :: $static_directories
|
||||||
|
)
|
||||||
|
)
|
||||||
|
$root_url = self :: clean_static_root_url(array_shift($args));
|
||||||
foreach ($args as $files) {
|
foreach ($args as $files) {
|
||||||
if (!is_array($files)) $files = array($files);
|
if (!is_array($files)) $files = array($files);
|
||||||
foreach ($files as $file) {
|
foreach ($files as $file) {
|
||||||
if (!in_array($file, self :: $css_files))
|
$path = $root_url.$file;
|
||||||
self :: $css_files[] = $file;
|
if (!in_array($path, self :: $css_files))
|
||||||
|
self :: $css_files[] = $path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register JS file(s) to load on next displayed page
|
* Register JS file(s) to load on next displayed page
|
||||||
* @param array<string|array<string>> $args JS files to load
|
* @param string|array<string> $args JS files to load
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public static function add_js_file(...$args) {
|
public static function add_js_file(...$args) {
|
||||||
|
// Check if the first argument is a custom static root URL
|
||||||
|
$root_url = self :: $static_root_url;
|
||||||
|
if (
|
||||||
|
$args && is_string($args[0]) && array_key_exists(
|
||||||
|
self :: clean_static_root_url($args[0]),
|
||||||
|
self :: $static_directories
|
||||||
|
)
|
||||||
|
)
|
||||||
|
$root_url = self :: clean_static_root_url(array_shift($args));
|
||||||
foreach ($args as $files) {
|
foreach ($args as $files) {
|
||||||
if (!is_array($files)) $files = array($files);
|
if (!is_array($files)) $files = array($files);
|
||||||
foreach ($files as $file) {
|
foreach ($files as $file) {
|
||||||
if (!in_array($file, self :: $js_files))
|
$path = $root_url.$file;
|
||||||
self :: $js_files[] = $file;
|
if (!in_array($path, self :: $js_files))
|
||||||
|
self :: $js_files[] = $path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -360,4 +419,128 @@ class Tpl {
|
||||||
public static function templates_directory() {
|
public static function templates_directory() {
|
||||||
return isset(self :: $templates_directory)?self :: $templates_directory:null;
|
return isset(self :: $templates_directory)?self :: $templates_directory:null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clean static root URL helper
|
||||||
|
* @param string $value
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function clean_static_root_url($value) {
|
||||||
|
if (substr($value, 0, 1) == '/')
|
||||||
|
$value = substr($value, 1);
|
||||||
|
if (substr($value, -1) != '/')
|
||||||
|
$value = "$value/";
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a static directory
|
||||||
|
* @param string $path The static directory path
|
||||||
|
* @param int|null $priority The priority of this static directory
|
||||||
|
* (optional, default: prior than all other registered directories)
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function register_static_directory($path, $priority=null, $root_url=null) {
|
||||||
|
if (is_null($root_url)) {
|
||||||
|
if (!self :: $static_root_url)
|
||||||
|
Log :: fatal(
|
||||||
|
'register_static_directory(%s): no root URL provided and no default value configured',
|
||||||
|
$path);
|
||||||
|
$root_url = self :: $static_root_url;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!array_key_exists($root_url, self :: $static_directories)) {
|
||||||
|
self :: $static_directories[$root_url] = array();
|
||||||
|
if (is_null($priority)) $priority = 100;
|
||||||
|
$pattern = "#^(?P<root_url>$root_url)(?P<path>.*)#";
|
||||||
|
Log :: trace(
|
||||||
|
'Register static file URL handler for root URL "%s" with pattern "%s" and directory '.
|
||||||
|
'"%s" (priority: %d)', $root_url, $pattern, $path, $priority);
|
||||||
|
Url :: add_url_handler(
|
||||||
|
$pattern,
|
||||||
|
array('EesyPHP\\Tpl', 'handle_static_file'),
|
||||||
|
false, // authenticated
|
||||||
|
false, // override
|
||||||
|
false, // API mode
|
||||||
|
array('GET') // methods
|
||||||
|
);
|
||||||
|
if (is_null(self :: $mime_type_detector))
|
||||||
|
self :: $mime_type_detector = new ExtensionMimeTypeDetector();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (is_null($priority)) {
|
||||||
|
$priority = max(self :: $static_directories[$root_url]);
|
||||||
|
$priority++;
|
||||||
|
}
|
||||||
|
Log :: trace(
|
||||||
|
'Register additionnal static directory "%s" for root URL "%s" (priority: %d)',
|
||||||
|
$path, $root_url, $priority);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (substr($path, -1) == PATH_SEPARATOR)
|
||||||
|
$path = substr($path, 0, -1);
|
||||||
|
self :: $static_directories[$root_url][$path] = $priority;
|
||||||
|
arsort(self :: $static_directories[$root_url]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve static path against registered static directories
|
||||||
|
* @param string $path
|
||||||
|
* @return string|false
|
||||||
|
*/
|
||||||
|
public static function resolve_static_path($root_url, $path) {
|
||||||
|
if (!array_key_exists($root_url, self :: $static_directories)) {
|
||||||
|
Log::error(
|
||||||
|
'No static directory registered for root URL "%s". Can no resolve static file "%s" path.',
|
||||||
|
$root_url, $path);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
foreach(array_keys(self :: $static_directories[$root_url]) as $dir) {
|
||||||
|
$fullpath = "$dir/$path";
|
||||||
|
if (file_exists($fullpath))
|
||||||
|
return $fullpath;
|
||||||
|
}
|
||||||
|
Log::trace('Static file "%s%s" not found', $root_url, $path);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle URL request for static file
|
||||||
|
* Note: this URL handler is registered in EesyPHP\Url by self::init().
|
||||||
|
* @see self::init()
|
||||||
|
* @param UrlRequest $request
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function handle_static_file($request) {
|
||||||
|
$path = self :: resolve_static_path($request->root_url, $request->path);
|
||||||
|
Log::trace('Resolved static file path for "%s": "%s"', $request->path, $path);
|
||||||
|
if (!$path)
|
||||||
|
Url :: trigger_error_404($request);
|
||||||
|
$mime_type = self :: $mime_type_detector->detectMimeTypeFromFile($path);
|
||||||
|
Log::trace('MIME type detected for "%s" is "%s"', $path, $mime_type);
|
||||||
|
dump_file($path, $mime_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to retrieve static file URL
|
||||||
|
* @param string $path The file path
|
||||||
|
* @return string|false
|
||||||
|
*/
|
||||||
|
public static function static_url($path) {
|
||||||
|
if (self :: $static_root_url)
|
||||||
|
return self :: $static_root_url.$path;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smarty function to print static file URL
|
||||||
|
* @param array<string,mixed> $params Parameters from template file
|
||||||
|
* @param Smarty $smarty The smarty object
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function smarty_static_url($params, $smarty) {
|
||||||
|
if (!isset($params['path'])) return;
|
||||||
|
$url = self :: static_url($params['path']);
|
||||||
|
if ($url) echo $url;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
11
src/Url.php
11
src/Url.php
|
@ -57,7 +57,7 @@ class Url {
|
||||||
*/
|
*/
|
||||||
public static function init($public_root_url=null, $api_mode=false) {
|
public static function init($public_root_url=null, $api_mode=false) {
|
||||||
if (is_null($public_root_url))
|
if (is_null($public_root_url))
|
||||||
$public_root_url = Config::get('public_root_url', null, 'string');
|
$public_root_url = App::get('public_root_url', null, 'string');
|
||||||
if (is_string($public_root_url) && $public_root_url) {
|
if (is_string($public_root_url) && $public_root_url) {
|
||||||
// Check URL end
|
// Check URL end
|
||||||
if (substr(self :: $public_root_url, -1) == '/')
|
if (substr(self :: $public_root_url, -1) == '/')
|
||||||
|
@ -201,6 +201,15 @@ class Url {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trigger a 404 HTTP error
|
||||||
|
* @param UrlRequest|null $request Current UrlRequest object (optional, default: null)
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function trigger_error_404($request=null) {
|
||||||
|
call_user_func_array(self :: $error_404_handler, array($request));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interprets the requested URL and return the corresponding UrlRequest object
|
* Interprets the requested URL and return the corresponding UrlRequest object
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
namespace EesyPHP;
|
namespace EesyPHP;
|
||||||
|
|
||||||
|
use League\MimeTypeDetection\ExtensionMimeTypeDetector;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parser/formater values helpers
|
* Parser/formater values helpers
|
||||||
*/
|
*/
|
||||||
|
@ -120,12 +122,28 @@ function cast($value, $type, $split=false) {
|
||||||
/*
|
/*
|
||||||
* Generic file/directory helpers
|
* Generic file/directory helpers
|
||||||
*/
|
*/
|
||||||
function dump_file($file_path, $max_age=3600) {
|
|
||||||
|
/**
|
||||||
|
* Dump file content to propose its download
|
||||||
|
* @param string $file_path The file path
|
||||||
|
* @param string|null $mime_type The file MIME type (optional, default: auto-detected)
|
||||||
|
* @param int|null $max_age Max age in second of this file in browser cache (optional,
|
||||||
|
* default: null=1h, set to False to disable Cache-Control header)
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function dump_file($file_path, $mime_type=null, $max_age=null) {
|
||||||
if (is_file($file_path)) {
|
if (is_file($file_path)) {
|
||||||
header('Content-Type: '.mime_content_type($file_path));
|
if (is_null($mime_type)) {
|
||||||
|
$detector = new ExtensionMimeTypeDetector();
|
||||||
|
$mime_type = $detector->detectMimeTypeFromFile($file_path);
|
||||||
|
Log::trace('MIME type detected for "%s" is "%s"', $file_path, $mime_type);
|
||||||
|
}
|
||||||
|
header("Content-Type: $mime_type");
|
||||||
$last_modified_time = filemtime($file_path);
|
$last_modified_time = filemtime($file_path);
|
||||||
$etag = md5_file($file_path);
|
$etag = md5_file($file_path);
|
||||||
header("Cache-Control: max-age=$max_age, must-revalidate");
|
$max_age = is_null($max_age)?3600:$max_age;
|
||||||
|
if ($max_age)
|
||||||
|
header("Cache-Control: max-age=$max_age, must-revalidate");
|
||||||
header("Last-Modified: ".gmdate("D, d M Y H:i:s", $last_modified_time)." GMT");
|
header("Last-Modified: ".gmdate("D, d M Y H:i:s", $last_modified_time)." GMT");
|
||||||
header("Etag: $etag");
|
header("Etag: $etag");
|
||||||
|
|
||||||
|
@ -147,8 +165,7 @@ function dump_file($file_path, $max_age=3600) {
|
||||||
readfile($file_path);
|
readfile($file_path);
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
header("HTTP/1.1 404 Not found");
|
Url :: trigger_error_404();
|
||||||
exit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function delete_directory($dir, $recursive=true) {
|
function delete_directory($dir, $recursive=true) {
|
||||||
|
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 470 KiB After Width: | Height: | Size: 470 KiB |
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue