diff --git a/src/App.php b/src/App.php index c46cceb..7a89a6c 100644 --- a/src/App.php +++ b/src/App.php @@ -39,13 +39,30 @@ class App { exit(1); } + // Set config default values + App :: set_defaults( + array( + 'overwrite_config_files' => array(), + 'upload_tmp_directory' => null, + 'upload_max_filesize' => null, + 'sentry.enabled' => true, + 'log.enabled' => true, + 'session.enabled' => true, + 'templates.enabled' => true, + 'url.enabled' => true, + 'mail.enabled' => true, + 'i18n.enabled' => true, + 'cli.enabled' => true, + ) + ); + // Load overwrite configuration file - foreach (self :: get('overwrite_config_files', array(), 'array') as $file) { + foreach (self :: get('overwrite_config_files', null, 'array') as $file) { $file = Config::replace_variables($file); if (is_file($file)) Config::load($file, true); } - if (self :: get('sentry.enabled', true, 'bool')) + if (self :: get('sentry.enabled', null, 'bool')) SentryIntegration :: init(); $sentry_transaction = new SentryTransaction(); $sentry_span = new SentrySpan('app.init', 'Application initialization'); @@ -60,13 +77,13 @@ class App { Config :: ini_set('post_max_size', strval(self::get('upload_max_filesize', null, 'int') * 1.1)); } - if (self :: get('log.enabled', true, 'bool')) + if (self :: get('log.enabled', null, 'bool')) Log::init(); - if (self :: get('session.enabled', true, 'bool')) + if (self :: get('session.enabled', null, 'bool')) Session::init(); - if (self :: get('templates.enabled', true, 'bool')) + if (self :: get('templates.enabled', null, 'bool')) Tpl :: init(); - if (self :: get('url.enabled', true, 'bool')) { + if (self :: get('url.enabled', null, 'bool')) { Url::init(); Url :: add_url_handler(null, array('EesyPHP\\App', 'handle_homepage')); } @@ -74,11 +91,11 @@ class App { Auth :: init(); Url :: add_url_handler('#^logout$#', array('EesyPHP\\App', 'handle_logout'), null, false); } - if (self :: get('mail.enabled', true, 'bool')) + if (self :: get('mail.enabled', null, 'bool')) Email :: init(); - if (self :: get('i18n.enabled', true, 'bool')) + if (self :: get('i18n.enabled', null, 'bool')) I18n::init(); - if (self :: get('cli.enabled', true, 'bool')) + if (self :: get('cli.enabled', null, 'bool')) Cli::init(); $sentry_span->finish(); } @@ -175,6 +192,32 @@ class App { return Config::set($key, $value); } + /** + * Set a specific option default value + * + * @param string $key The configuration variable key + * @param mixed $value The configuration variable default value + * @return boolean + **/ + public static function set_default($key, $value) { + return Config::set("default.$key", $value, self :: $options); + } + + /** + * Set a specific options default value + * + * @param array $values Associative array of configuration variables name and + * default values + * @return boolean + **/ + public static function set_defaults($values) { + $error = false; + foreach($values as $key => $value) + if (!self :: set_default($key, $value)) + $error = true; + return !$error; + } + /** * Retreive application root directory path * @return string|null diff --git a/src/Auth.php b/src/Auth.php index 96553e8..7d18384 100644 --- a/src/Auth.php +++ b/src/Auth.php @@ -36,7 +36,17 @@ class Auth { * @return void */ public static function init() { - if (!self :: enabled()) return; + // Set config default values + App :: set_default( + 'auth', + array( + 'methods' => array(), + 'backends' => array(), + 'enabled' => self :: enabled(), + 'allow_multiple_match' => null, + 'allow_multiple_match_with_valid_password' => null, + ) + ); self :: $methods = array(); foreach(App::get('auth.methods', array(), 'array') as $method) { if (!$method || !is_string($method)) { diff --git a/src/Auth/Cas.php b/src/Auth/Cas.php index cc52c8c..5594b76 100644 --- a/src/Auth/Cas.php +++ b/src/Auth/Cas.php @@ -25,6 +25,20 @@ class Cas extends Method { // In phpstan context, do not initialize if (defined('__PHPSTAN_RUNNING__') && constant('__PHPSTAN_RUNNING__')) return true; + // Set config default values + App :: set_default( + 'auth.cas', + array( + 'host' => null, + 'port' => 443, + 'context' => '/idp/cas', + 'version' => '2.0', + 'logout' => true, + 'fake_authenticated_user' => null, + 'debug_log_file' => null, + 'ca_cert_certificate_path' => null, + ) + ); self :: $fake_authenticated_user = App :: get( 'auth.cas.fake_authenticated_user', null, 'string'); if (self :: $fake_authenticated_user) return true; @@ -37,7 +51,7 @@ class Cas extends Method { return false; } - $cas_version = App :: get('auth.cas.version', '2.0', 'string'); + $cas_version = App :: get('auth.cas.version', null, 'string'); $supported_cas_versions = phpCAS::getSupportedProtocols(); if (!array_key_exists($cas_version, $supported_cas_versions)) { Log :: error( @@ -51,8 +65,8 @@ class Cas extends Method { phpCAS::client( $cas_version, App :: get('auth.cas.host'), - App :: get('auth.cas.port', 443, 'int'), - App :: get('auth.cas.context', '/idp/cas', 'string'), + App :: get('auth.cas.port', null, 'int'), + App :: get('auth.cas.context', null, 'string'), Url :: get_absolute_url("/") ); if (App :: get('auth.cas.ca_cert_certificate_path')) @@ -109,7 +123,7 @@ class Cas extends Method { * @return void */ public static function logout() { - if (App :: get('auth.cas.logout', true, 'bool') && !self :: $fake_authenticated_user) { + if (App :: get('auth.cas.logout', null, 'bool') && !self :: $fake_authenticated_user) { if (App :: get('auth.cas.logout_url')) { Url :: redirect(App :: get('auth.cas.logout_url')); exit(); diff --git a/src/Auth/Db.php b/src/Auth/Db.php index 149fd68..101413b 100644 --- a/src/Auth/Db.php +++ b/src/Auth/Db.php @@ -69,14 +69,28 @@ class Db extends Backend { * @return boolean */ public static function init() { + // Set config default values + App :: set_default( + 'auth.db', + array( + 'dsn' => null, + 'user' => null, + 'password' => null, + 'options' => array(), + 'users_table' => 'users', + 'username_field' => 'username', + 'password_field' => 'password', + 'exposed_fields' => array('name', 'mail'), + ) + ); self :: $dsn = App::get('auth.db.dsn', null, 'string'); self :: $user = App::get('auth.db.user', null, 'string'); self :: $password = App::get('auth.db.password', null, 'string'); - self :: $options = App::get('auth.db.options', array(), 'array'); - self :: $users_table = App::get('auth.db.users_table', 'users', 'string'); - self :: $username_field = App::get('auth.db.username_field', 'username', 'string'); - self :: $password_field = App::get('auth.db.password_field', 'password', 'string'); - self :: $exposed_fields = App::get('auth.db.exposed_fields', array('name', 'mail'), 'array'); + self :: $options = App::get('auth.db.options', null, 'array'); + self :: $users_table = App::get('auth.db.users_table', null, 'string'); + self :: $username_field = App::get('auth.db.username_field', null, 'string'); + self :: $password_field = App::get('auth.db.password_field', null, 'string'); + self :: $exposed_fields = App::get('auth.db.exposed_fields', null, 'array'); return boolval(self :: $dsn); } diff --git a/src/Auth/Form.php b/src/Auth/Form.php index 97742a7..fb9b09d 100644 --- a/src/Auth/Form.php +++ b/src/Auth/Form.php @@ -16,6 +16,13 @@ class Form extends Method { * @return boolean */ public static function init() { + // Set config default values + App :: set_default( + 'auth.login_form', + array( + 'display_other_methods' => array(), + ) + ); Url :: add_url_handler('#^login$#', array('EesyPHP\\Auth\\Form', 'handle_login'), null, false); Hook :: register('logged_in', array('\\EesyPHP\\Auth\\Form', 'logged_in_hook')); return true; diff --git a/src/Auth/Http.php b/src/Auth/Http.php index b0d3808..425a8eb 100644 --- a/src/Auth/Http.php +++ b/src/Auth/Http.php @@ -29,9 +29,18 @@ class Http extends Method { * @return boolean */ public static function init() { - self :: $method = App::get('auth.http.method', 'PHP_AUTH', 'string'); + // Set default config values + App :: set_default( + 'auth.http', + array( + 'method' => 'PHP_AUTH', + 'realm' => _('Authentication required'), + 'trust_without_password_challenge' => false, + ) + ); + self :: $method = App::get('auth.http.method', null, 'string'); self :: $realm = App::get( - 'auth.http.realm', _('Authentication required'), 'string'); + 'auth.http.realm', null, 'string'); return true; } @@ -91,7 +100,7 @@ class Http extends Method { return null; } - if (App :: get('auth.http.trust_without_password_challenge', false, 'bool')) + if (App :: get('auth.http.trust_without_password_challenge', null, 'bool')) $user = Auth :: get_user($auth_data['username']); else $user = Auth :: authenticate($auth_data['username'], $auth_data['password']); diff --git a/src/Auth/Ldap.php b/src/Auth/Ldap.php index 562ae5a..bb9d1fe 100644 --- a/src/Auth/Ldap.php +++ b/src/Auth/Ldap.php @@ -28,38 +28,49 @@ class Ldap extends Backend { */ private static $connection = null; - /** - * Default LDAP user attributes configuration - * @var array - */ - private static $default_user_attributes = array( - 'login' => array( - 'ldap_name' => 'uid', - 'type' => 'string', - 'multivalued' => false, - 'default' => null, - ), - 'mail' => array( - 'type' => 'string', - 'multivalued' => false, - 'default' => null, - ), - 'name' => array( - 'ldap_name' => 'displayName', - 'alt_ldap_name' => 'cn', - 'type' => 'string', - 'multivalued' => false, - 'default' => null, - ), - ); - /** * Initialize * @return bool */ public static function init() { + // Set default config values + App :: set_default( + 'auth.ldap', + array( + 'host' => array(), + 'port' => null, + 'basedn' => null, + 'binddn' => null, + 'bindpw' => null, + 'starttls' => false, + 'user_filter_by_uid' => 'uid=[username]', + 'user_basedn' => null, + 'bind_with_username' => false, + 'user_attributes' => array( + 'login' => array( + 'ldap_name' => 'uid', + 'type' => 'string', + 'multivalued' => false, + 'default' => null, + ), + 'mail' => array( + 'type' => 'string', + 'multivalued' => false, + 'default' => null, + ), + 'name' => array( + 'ldap_name' => 'displayName', + 'alt_ldap_name' => 'cn', + 'type' => 'string', + 'multivalued' => false, + 'default' => null, + ), + ), + 'netldap2_path' => 'Net/LDAP2.php', + ) + ); if (!class_exists('Net_LDAP2')) { - $path = App::get('auth.ldap.netldap2_path', 'Net/LDAP2.php', 'string'); + $path = App::get('auth.ldap.netldap2_path', null, 'string'); if (!@include($path)) { Log::error('Fail to load Net_LDAP2 (%s)', $path); return false; @@ -73,11 +84,11 @@ class Ldap extends Backend { } self :: $ldap_config = array ( - 'host' => implode(' ', App :: get('auth.ldap.host', array(), 'array')), + 'host' => implode(' ', App :: get('auth.ldap.host', null, 'array')), 'basedn' => App :: get('auth.ldap.basedn', null, 'string'), 'binddn' => App :: get('auth.ldap.bind_dn', null, 'string'), 'bindpw' => App :: get('auth.ldap.bind_password', null, 'string'), - 'starttls' => App :: get('starttls', false, 'bool'), + 'starttls' => App :: get('starttls', null, 'bool'), ); if ($port = App :: get('auth.ldap.port', null, 'int')) self :: $ldap_config['port'] = $port; @@ -202,7 +213,7 @@ class Ldap extends Backend { * @return \EesyPHP\Auth\User|null|false The user object if found, null it not, false in case of error */ public static function get_user($username) { - $attrs = App::get('auth.ldap.user_attributes', self :: $default_user_attributes, 'array'); + $attrs = App::get('auth.ldap.user_attributes', null, 'array'); $attrs_names = array(); foreach($attrs as $attr => $attr_config) { $name = Config::get("ldap_name", $attr, 'string', false, $attr_config); @@ -215,7 +226,7 @@ class Ldap extends Backend { $users = self :: search( str_replace( '[username]', Net_LDAP2_Filter::escape($username), - App::get('auth.ldap.user_filter_by_uid', 'uid=[username]', 'string') + App::get('auth.ldap.user_filter_by_uid', null, 'string') ), $attrs_names, App::get('auth.ldap.user_basedn', null, 'string') @@ -261,7 +272,7 @@ class Ldap extends Backend { public static function check_password($user, $password) { $config = self :: $ldap_config; $config['binddn'] = ( - App::get('auth.ldap.bind_with_username', false, 'bool')? + App::get('auth.ldap.bind_with_username', null, 'bool')? $user->username: $user->dn ); diff --git a/src/Email.php b/src/Email.php index 3082b93..dd47bb9 100644 --- a/src/Email.php +++ b/src/Email.php @@ -10,90 +10,45 @@ use finfo; class Email { - /** - * Default sender - * @var string|null; - */ - protected static $sender = null; - - /** - * Sending method : - * - mail : use PHP mail function - * - sendmail : use sendmail system command - * - smtp : use an SMTP server (PHP PEAR Net_SMTP required) - * @var string - */ - protected static $send_method = 'mail'; - - /** - * Sending parameters - * @see http://pear.php.net/manual/en/package.mail.mail.factory.php - * @var array|null - */ - protected static $send_params = null; - - /** - * Catch all sent email recipient - * @var string|array|null - */ - protected static $catch_all = null; - - /** - * Default headers to add on all sent emails - * @var array - */ - protected static $headers = array(); - - /** - * PHP PEAR Mail lib path - * @var string - */ - protected static $php_mail_path = 'Mail.php'; - - /** - * PHP PEAR Mail lib path - * @var string - */ - protected static $php_mail_mime_path = 'Mail/mime.php'; - - /** * Initialization - * @param string|null $php_mail_path PHP PEAR Mail lib path (optional, default: from - * email.php_mail_path config key if set, 'Mail.php' otherwise) - * @param string|null $php_mail_mime_path PHP PEAR Mail lib path (optional, default: from - * email.php_mail_mime_path config key if set, 'Mail/mime.php' otherwise) * @return void */ - 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) { - if (is_null($sender)) - $sender = App::get('email.sender', null, 'string'); - if ($sender) self :: $sender = $sender; + public static function init() { + // Set config default values + App :: set_default( + 'email', + array( + // Default sender + 'sender' => null, - if (is_null($send_method)) - $send_method = App::get('email.send_method', null, 'string'); - if ($send_method) self :: $send_method = $send_method; + /** + * Sending method : + * - mail : use PHP mail function + * - sendmail : use sendmail system command + * - smtp : use an SMTP server (PHP PEAR Net_SMTP required) + */ + 'send_method' => null, - if (is_null($send_params)) - $send_params = App::get('email.send_params', null, 'array'); - if ($send_params) self :: $send_params = $send_params; + /** + * Sending parameters + * @see http://pear.php.net/manual/en/package.mail.mail.factory.php + */ + 'send_params' => array(), - if (is_null($catch_all)) - $catch_all = App::get('email.catch_all'); - if ($catch_all) self :: $catch_all = $catch_all; + // Catch all sent email recipient + 'catch_all' => null, - if (is_null($headers)) - $headers = App::get('email.headers', null, 'array'); - if ($headers) self :: $headers = $headers; + // Default headers to add on all sent emails + 'headers' => array(), - if (is_null($php_mail_path)) - $php_mail_path = App::get('email.php_mail_path', null, 'string'); - if ($php_mail_path) self :: $php_mail_path = $php_mail_path; + // PHP PEAR Mail lib path + 'php_mail_path' => 'Mail.php', - if (is_null($php_mail_mime_path)) - $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; + // PHP PEAR Mail_mime lib path + 'php_mail_mime_path' => 'Mail/mime.php', + ) + ); } @@ -116,24 +71,29 @@ class Email { public static function send($from, $to, $subject, $msg, $html=false, $attachments=null, $headers=null, $encoding=null, $eol=null) { if (!class_exists('Mail')) - require_once(self :: $php_mail_path); + require_once(App :: get('php_mail_path', null, 'string')); if (!class_exists('Mail_mime')) - require_once(self :: $php_mail_mime_path); + require_once(App :: get('php_mail_mime_path', null, 'string')); - $mail_obj = Mail::factory(self :: $send_method, self :: $send_params); + $mail_obj = Mail::factory( + App :: get('email.send_method', null, 'string'), + App :: get('email.send_params', null, 'array') + ); if (!$headers) $headers = array(); - $headers = array_merge($headers, self :: $headers); + $headers = array_merge($headers, App :: get('email.headers', null, 'array')); Log :: trace( 'Mail catch all: %s', - self :: $catch_all? - vardump(self :: $catch_all):'not set' + App :: get('email.catch_all')? + vardump(App :: get('email.catch_all')):'not set' ); - if (self :: $catch_all) { + if (App :: get('email.catch_all')) { Log :: debug( 'Mail catch to %s', - is_array(self :: $catch_all)?implode(',', self :: $catch_all):self :: $catch_all + is_array(App :: get('email.catch_all'))? + implode(',', App :: get('email.catch_all')): + App :: get('email.catch_all') ); $msg .= sprintf( ( @@ -144,8 +104,9 @@ class Email { (is_array($to)?implode(',', $to):$to)); $headers["X-Orig-To"] = $to; $to = ( - is_array(self :: $catch_all)? - implode(',', self :: $catch_all):self :: $catch_all + is_array(App :: get('email.catch_all'))? + implode(',', App :: get('email.catch_all')): + App :: get('email.catch_all') ); } @@ -159,7 +120,7 @@ class Email { unset($headers['From']); } elseif (!$from) { - $from = self :: $sender; + $from = App::get('email.sender'); } $headers["To"] = $to; @@ -170,7 +131,7 @@ class Email { foreach(array_keys($headers) as $header) { if(in_array(strtoupper($header), array('BCC', 'CC'))) { - if (self :: $catch_all) { + if (App :: get('email.catch_all')) { Log :: debug("Mail catched: remove $header header"); $msg .= sprintf( ( diff --git a/src/I18n.php b/src/I18n.php index bb6dd30..1d6e547 100644 --- a/src/I18n.php +++ b/src/I18n.php @@ -35,25 +35,21 @@ class I18n { * Detect best translation language and configure the translation * system. * - * @param string|null $root_path The root directory path of translation files - * (optional, default: from i18n.root_directory config key if set, - * '${root_directory_path}/locales' otherwise) - * @param string|null $default_locale The default locale - * (optional, default: from i18n.default_locale config key if set, - * 'en_US.UTF8' otherwise) * @return void */ - public static function init($root_path=null, $default_locale=null) { - if (is_null($root_path)) - self :: $root_path = App::get( - 'i18n.root_directory', '${root_directory_path}/locales', 'string'); - if (!is_null($root_path)) - self :: $root_path = $root_path; + public static function init() { + // Set config default values + App :: set_default( + 'i18n', + array( + 'root_directory' => '${root_directory_path}/locales', + 'default_locale' => null, + ) + ); - if (is_null($default_locale)) - $default_locale = App::get('i18n.default_locale', null, 'string'); - if (!is_null($default_locale)) - self :: $default_locale = $default_locale; + self :: $root_path = App::get( + 'i18n.root_directory', null, 'string'); + $default_locale = App::get('i18n.default_locale', null, 'string'); if (!class_exists('Locale')) { Log :: error('Locale PHP class does not exist. May be php-intl is not installed?'); diff --git a/src/Log.php b/src/Log.php index a877459..804ae8d 100644 --- a/src/Log.php +++ b/src/Log.php @@ -38,12 +38,6 @@ class Log { 'FATAL' => 5, ); - /* - * Default log level - * @var string - */ - protected static $default_level = 'WARNING'; - /* * Current log level * @var string|null @@ -63,42 +57,46 @@ class Log { /** * Initialization - * @param string $filepath The log file path - * (optional, default: from log.file_path or log.cli_file_path is set) - * @param string|null $level The log level - * (optional, default: from log.level config key if set, otherwise, - * see self :: $default_level) - * @param int|null $php_errors_levels PHP errors level as expected by set_error_handler() - * (optional, default: from log.php_errors_levels if set, E_ALL & ~E_STRICT - * if level is TRACE or DEBUG, and E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED - * otherwise) * @return void */ - public static function init($filepath=null, $level=null, $php_errors_levels=null) { - if ($filepath) - self :: $filepath = $filepath; - elseif (php_sapi_name() == 'cli') - self :: $filepath = App::get( - 'log.cli_logfile_path', App::get('log.cli_file_path')); - else - self :: $filepath = App::get('log.file_path'); + public static function init() { + // Set config default values + App :: set_default( + 'log', + array( + 'level' => 'WARNING', + 'file_path' => null, + 'cli_file_path' => '${log.file_path}', + 'default_locale' => null, + 'error_log_fallback' => true, + 'php_errors_levels' => array(), // Depend of effective log level, see below + ) + ); + self :: $filepath = App::get( + php_sapi_name() == 'cli'?'log.cli_logfile_path':'log.file_path' + ); // PHP error_log() fallback - self :: $error_log_fallback = App::get('log.error_log_fallback', true, 'bool'); + self :: $error_log_fallback = App::get('log.error_log_fallback', null, 'bool'); // Set log level: // Note: in Phpstan context, force FATAL level if (defined('__PHPSTAN_RUNNING__') && constant('__PHPSTAN_RUNNING__')) self :: set_level('FATAL'); else - self :: set_level($level?$level:App::get('log.level')); + self :: set_level(App::get('log.level', null, 'string')); + App :: set_default( + 'log.php_errors_levels', + in_array(self :: $level, array('DEBUG', 'TRACE'))? + array('E_ALL', '~E_STRICT'): + array('E_ALL', '~E_STRICT', '~E_NOTICE', '~E_DEPRECATED') + ); // Log PHP errors - if (!is_null($php_errors_levels)) { - self :: $php_errors_levels = $php_errors_levels; - } - elseif ($levels = App::get('log.php_errors_levels', array(), 'array')) { + $levels = App::get('log.php_errors_levels', array(), 'array'); + if ($levels) { + self :: $php_errors_levels = E_ALL; $code = 'self :: $php_errors_levels = '; while($level = array_shift($levels)) { if (!is_string($level)) continue; @@ -125,14 +123,8 @@ class Log { } $code .= ";"; eval($code); + set_error_handler(array('EesyPHP\\Log', 'on_php_error'), self :: $php_errors_levels); } - elseif (in_array(self :: $level, array('DEBUG', 'TRACE'))) { - self :: $php_errors_levels = E_ALL & ~E_STRICT; - } - else { - self :: $php_errors_levels = E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED; - } - set_error_handler(array('EesyPHP\\Log', 'on_php_error'), self :: $php_errors_levels); // Log uncatched exceptions set_exception_handler(array('EesyPHP\\Log', 'exception')); @@ -162,7 +154,13 @@ class Log { public static function log($level, $message, ...$extra_args) { global $argv; - if (!array_key_exists($level, self :: $levels)) $level = self :: $default_level; + if (!array_key_exists($level, self :: $levels)) { + self :: warning( + "Invalid log level specified logging the message %s, use 'WARNING':\n%s", + $message, self :: get_debug_backtrace_context() + ); + $level = 'WARNING'; + } if (self :: $levels[$level] < self :: $levels[self :: $level]) return true; if(self :: $filepath && is_null(self :: $file_fd)) { self :: $file_fd = fopen(self :: $filepath, 'a'); @@ -337,13 +335,13 @@ class Log { public static function set_level($level=null) { // Set default log level (if not defined or invalid) if (is_null($level)) { - self :: $level = self :: $default_level; + self :: $level = App::get_default('log.level', null, 'string'); } elseif (!array_key_exists($level, self :: $levels)) { - self :: $level = self :: $default_level; + self :: $level = App::get_default('log.level', null, 'string'); self :: warning( "Invalid log level value found in configuration (%s). ". - "Set as default (%s).", vardump($level), self :: $default_level); + "Set as default (%s).", vardump($level), self :: $level); } else { self :: $level = $level; diff --git a/src/SentryIntegration.php b/src/SentryIntegration.php index 4afde2a..bf9024a 100644 --- a/src/SentryIntegration.php +++ b/src/SentryIntegration.php @@ -18,35 +18,31 @@ class SentryIntegration { * @see https://www.php.net/manual/fr/errorfunc.constants.php * @var array */ - protected static $php_error_types = array( - E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR, - E_RECOVERABLE_ERROR,E_DEPRECATED, - ); + protected static $php_error_types; /** * Initialization - * @param string|null $dsn Sentry DSN - * (optional, default: from sentry.dsn config key if set, null otherwise) - * @param float|null $traces_sample_rate Sentry traces sample rate - * (optional, default: from sentry.traces_sample_rate config key if set, - * 0.2 otherwise) - * @param array|null $php_error_types Types of PHP error to log in Sentry - * (optional, default: from sentry.php_error_types config key if set, - * otherwise, see self::$php_error_types) * @return void */ - public static function init($dsn=null, $traces_sample_rate=null, - $php_error_types=null) { + public static function init() { // In phpstan context, do not initialize if (defined('__PHPSTAN_RUNNING__') && constant('__PHPSTAN_RUNNING__')) return; - \Sentry\init([ - 'dsn' => $dsn?$dsn:App::get('sentry.dsn'), - 'traces_sample_rate' => ( - $traces_sample_rate? - $traces_sample_rate: - App::get('sentry.traces_sample_rate', 0.2, 'float') + // Set config default values + App :: set_default( + 'sentry', + array( + 'dsn' => null, + 'traces_sample_rate' => 0.2, + 'php_error_types' => array( + 'E_ERROR', 'E_PARSE', 'E_CORE_ERROR', 'E_COMPILE_ERROR', 'E_USER_ERROR', + 'E_RECOVERABLE_ERROR', 'E_DEPRECATED', ), + ) + ); + \Sentry\init([ + 'dsn' => App::get('sentry.dsn'), + 'traces_sample_rate' => App::get('sentry.traces_sample_rate', null, 'float'), ]); \Sentry\configureScope(function (\Sentry\State\Scope $scope): void { @@ -56,12 +52,8 @@ class SentryIntegration { ]); }); - if (!is_array($php_error_types)) - $php_error_types = App::get( - 'sentry.php_error_types', self :: $php_error_types, 'array' - ); self :: $php_error_types = array(); - foreach($php_error_types as $php_error_type) { + foreach(App::get('sentry.php_error_types', null, 'array') as $php_error_type) { if (is_string($php_error_type) && defined($php_error_type)) $php_error_type = constant($php_error_type); if (!is_int($php_error_type)) continue; diff --git a/src/Session.php b/src/Session.php index 22c0df7..fed7fcb 100644 --- a/src/Session.php +++ b/src/Session.php @@ -11,30 +11,30 @@ class Session { * Session max duration (in seconds, default: 12h) * @var int */ - protected static $max_duration = 12 * 60 * 60; + protected static $max_duration; /** * Initialization - * @param int|null $max_duration Session max duration in second - * (optional, default: from session.max_duration config key if set, 12h otherwise) - * @param int|null $timeout Session inactivity timeout in second - * (optional, default: from session.timeout config key if set, no timeout otherwise) * @return void */ - public static function init($max_duration=null, $timeout=null) { + public static function init() { // In CLI or Phpstan context, do not initialize if ( php_sapi_name() == "cli" || (defined('__PHPSTAN_RUNNING__') && constant('__PHPSTAN_RUNNING__')) ) return; + // Set config default values + App :: set_default( + 'session', + array( + 'max_duration' => 43200, // 12h + 'timeout' => null, + ) + ); // Define session max duration - if (is_null($max_duration)) - $max_duration = App::get('session.max_duration', null, 'int'); - if (is_int($max_duration)) - self :: $max_duration = $max_duration; - + self :: $max_duration = App::get('session.max_duration', null, 'int'); Config :: ini_set('session.gc_maxlifetime', strval(self :: $max_duration)); Config :: ini_set('session.cookie_lifetime', strval(self :: $max_duration)); @@ -47,9 +47,8 @@ class Session { } // Handle session timeout - if (is_null($timeout)) - $timeout = App::get('session.timeout', null, 'int'); - if (is_int($timeout) && $timeout) { + $timeout = App::get('session.timeout', null, 'int'); + if ($timeout) { if (!isset($_SESSION['session_last_access'])) { Log :: debug('Set initial session last access'); $_SESSION['session_last_access'] = time(); diff --git a/src/Tpl.php b/src/Tpl.php index 8acb4be..2dd817f 100644 --- a/src/Tpl.php +++ b/src/Tpl.php @@ -33,12 +33,6 @@ class Tpl { */ public static $templates_directories = array(); - /** - * Smarty cache templates directory path - * @var string - */ - public static $templates_c_dir; - /** * Enable/disable AJAX returned data debugging in logs * @var bool @@ -83,28 +77,38 @@ class Tpl { /** * Initialization - * @param string $templates_dir Smarty templates directory path - * (optional, default: from templates.directory config key) - * @param string $templates_c_dir Smarty cache templates directory path - * (optional, default: from templates.cache_directory config key) - * @param bool $debug_ajax Enable/disable AJAX returned data debugging in logs - * (optional, default: from templates.debug_ajax or debug_ajax config keys if set, - * false otherwise) - * @param bool $static_root_url Configure custom root URL path for static files - * (optional, default: from templates.static_root_url config key if set, - * '/static' otherwise. Set to False to disable) * @return void */ - public static function init($templates_dir=null, $templates_c_dir=null, $debug_ajax=null, - $static_root_url=null) { + public static function init() { // In phpstan context, do not initialize if (defined('__PHPSTAN_RUNNING__') && constant('__PHPSTAN_RUNNING__')) return; + + // Set config default values + App :: set_default( + 'templates', + array( + // Main Smarty templates directory path + 'directory' => null, + // Smarty cache templates directory path + // Default: see below, compute only if not set + 'cache_directory' => null, + 'main_pagetitle' => null, + 'static_root_url' => 'static/', + 'static_directories' => array(), + 'included_css_files' => array(), + 'included_js_files' => array(), + 'webstats_js_code' => null, + 'upload_max_filesize' => null, + 'debug_ajax' => App::get('debug_ajax', false, 'bool'), + ) + ); + // Handle templates directories self :: $core_templates_directory = realpath(__DIR__."/../templates"); self :: register_templates_directory(self :: $core_templates_directory); - if (is_null($templates_dir)) - $templates_dir = App::get('templates.directory', null, 'string'); + + $templates_dir = App::get('templates.directory', null, 'string'); if ($templates_dir) { if (!is_dir($templates_dir)) Log :: fatal("Template directory not found (%s)", $templates_dir); @@ -112,8 +116,7 @@ class Tpl { } // Handle and check templates_c directories - if (is_null($templates_c_dir)) - $templates_c_dir = App::get('templates.cache_directory', null, 'string'); + $templates_c_dir = App::get('templates.cache_directory', null, 'string'); if ($templates_c_dir) { if (!is_dir($templates_c_dir) || !is_writable($templates_c_dir)) { Log :: fatal( @@ -151,18 +154,17 @@ class Tpl { $templates_c_dir); return; } + App :: set_default('templates.cache_directory', $templates_c_dir); } self :: $smarty = new Smarty(); self :: $smarty->setTemplateDir(self :: $core_templates_directory); self :: $smarty->setCompileDir($templates_c_dir); self :: $smarty->registerResource('Tpl', new TplSmartyResource()); - if (is_null($debug_ajax)) - $debug_ajax = App::get('templates.debug_ajax', App::get('debug_ajax')); + $debug_ajax = App::get('templates.debug_ajax', null, 'bool'); self :: $_debug_ajax = boolval($debug_ajax); Log :: register_fatal_error_handler(array('\\EesyPHP\\Tpl', 'fatal_error')); - if (is_null($static_root_url)) - $static_root_url = App::get('templates.static_root_url', 'static/', 'string'); + $static_root_url = App::get('templates.static_root_url', null, 'string'); if ($static_root_url) { if (substr($static_root_url, 0, 1) == '/') $static_root_url = substr($static_root_url, 1); @@ -173,7 +175,7 @@ class Tpl { self :: register_static_directory(self :: $core_static_directory, 100); self :: register_function('static_url', array('EesyPHP\\Tpl', 'smarty_static_url')); - foreach(App :: get('templates.static_directories', array(), 'array') as $path) + foreach(App :: get('templates.static_directories', null, 'array') as $path) self :: register_static_directory($path); self :: register_function('var_dump', array('EesyPHP\\Tpl', 'smarty_var_dump')); @@ -365,8 +367,8 @@ class Tpl { self :: assign('session_key', isset($_SESSION['session_key'])?$_SESSION['session_key']:null); // Handle CSS & JS files included - self :: add_css_file(App::get('templates.included_css_files', array(), 'array')); - self :: add_js_file(App::get('templates.included_js_files', array(), 'array')); + self :: add_css_file(App::get('templates.included_css_files', null, 'array')); + self :: add_js_file(App::get('templates.included_js_files', null, 'array')); // Messages self :: assign('errors', self :: get_errors()); diff --git a/src/Url.php b/src/Url.php index 1e3e89f..8e5f993 100644 --- a/src/Url.php +++ b/src/Url.php @@ -58,22 +58,23 @@ class Url { /** * Initialization - * @param string|null $public_root_url The application public root URL - * (optional, default: from public_root_url config key) - * @param bool $api_mode Enable/disable API mode * @return void */ - public static function init($public_root_url=null, $api_mode=false) { + public static function init() { + // Set default config values + App :: set_default('public_root_url', null); + App :: set_default('api_mode', false); + if (php_sapi_name() == 'cli-server' && getenv('EESYPHP_SERVE_URL')) $public_root_url = getenv('EESYPHP_SERVE_URL'); - else if (is_null($public_root_url)) + else $public_root_url = App::get('public_root_url', null, 'string'); if (is_string($public_root_url) && $public_root_url) { // Remove trailing slash $public_root_url = rtrim($public_root_url, '/'); self :: $public_root_url = $public_root_url?$public_root_url:null; } - self :: $_api_mode = boolval($api_mode); + self :: $_api_mode = boolval(App::get('api_mode', null, 'bool')); } /**