null, ); /** * Root directory path * @var string|null */ protected static $root_directory_path = null; /** * Initialization * @param string|null $config_file Application configuration file path * @param array|null $options Application options (default: null) * @param string|null $root_directory_path Application root directory path (default: null) * @return void */ public static function init($config_file, $options=null, $root_directory_path=null) { Config::register_extra_variable('init_time', hrtime(true)); if (is_array($options)) self :: $options = $options; if (is_null($root_directory_path)) { $traces = debug_backtrace(); $root_directory_path = realpath(dirname($traces[0]['file']).'/../'); } self :: $root_directory_path = $root_directory_path; Config::register_extra_variable('root_directory_path', $root_directory_path); $config_file = Config::replace_variables($config_file); if ($config_file && !Config::load($config_file)) Log::fatal('Fail to load configuration file (%s)', $config_file); // 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, 'db.enabled' => false, ) ); // Load overwrite configuration 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', null, 'bool')) SentryIntegration :: init(); $sentry_transaction = new SentryTransaction(); $sentry_span = new SentrySpan('app.init', 'Application initialization'); if (self :: get('log.enabled', null, 'bool')) Log::init(); if (self :: get('session.enabled', null, 'bool')) Session::init(); if (self :: get('templates.enabled', null, 'bool')) Tpl :: init(); if (self :: get('url.enabled', null, 'bool')) { Url::init(); Url :: add_url_handler(null, array('EesyPHP\\App', 'handle_homepage')); } if (Auth :: enabled()) { Auth :: init(); Url :: add_url_handler('#^logout$#', array('EesyPHP\\App', 'handle_logout'), null, false); } if (self :: get('mail.enabled', null, 'bool')) Email :: init(); if (self :: get('i18n.enabled', null, 'bool')) I18n::init(); if (self :: get('cli.enabled', null, 'bool')) Cli::init(); if (self :: get('db.enabled', null, 'bool')) Db::init(); // Define common upload_tmp_dir & upload_max_filesize PHP ini if (self::isset('upload_tmp_directory')) Config :: ini_set('upload_tmp_dir', self::get('upload_tmp_directory', null, 'string')); if (self::isset('upload_max_filesize')) { Config :: ini_set('upload_max_filesize', self::get('upload_max_filesize', null, 'string')); // post_max_size must be larger than upload_max_filesize // See: https://www.php.net/manual/en/ini.core.php#ini.post-max-size Config :: ini_set('post_max_size', strval(self::get('upload_max_filesize', null, 'int') * 1.1)); } $sentry_span->finish(); } /** * Check if the application is initialized * @return bool */ public static function initialized() { return !is_null(self :: $root_directory_path); } /** * Check if a specific configuration variable is set * * @param string $key The configuration variable key * @return bool **/ public static function isset($key) { return Config::isset($key, self :: $options) || (Config::loaded() && Config::isset($key)); } /** * Get a specific option value * * @param string $key The configuration variable key * @param mixed $default The default value to return if configuration variable * is not set (Default : null) * @param string $cast The type of expected value. The configuration variable * value will be cast as this type. Could be : bool, int, * float or string. (Optional, default : raw value) * @param bool $split If true, $cast is 'array' and value retrieved from configuration * is a string, split the value by comma (optional, default: true) * @return mixed The configuration variable value **/ public static function get($key, $default=null, $cast=null, $split=true) { $default = self :: get_default($key, $default, $cast, $split); return Config::get( $key, Config::loaded()?Config::get($key, $default, $cast, $split):$default, $cast, $split, self :: $options, array(self :: class, 'get') ); } /** * Get a specific option default value * * @param string $key The configuration variable key * @param mixed $default Default value provided by context * (optional, priority if not nul, default : null) * @param string $cast The type of expected value. The configuration variable * default value will be cast as this type. Could be : bool, int, * float or string. (Optional, default : raw value) * @param bool $split If true, $cast is 'array' and value retrieved from configuration * is a string, split the value by comma (optional, default: true) * @return mixed The configuration variable default value **/ public static function get_default($key, $default=null, $cast=null, $split=true) { if (!is_null($default)) return $default; return Config::get( "default.$key", $default, $cast, $split, self :: $options ); } /** * Get list of keys of a specific option * * @param string $key The configuration variable key * * @return array An array of the keys of a specific option **/ public static function keys($key) { $value = self :: get($key); return (is_array($value)?array_keys($value):array()); } /** * Set a specific option value * * @param string $key The configuration variable key * @param mixed $value The configuration variable value * @return boolean **/ public static function set($key, $value) { if (Config::isset($key, self :: $options)) return Config::set($key, $value, self :: $options); 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; } /** * Retrieve application root directory path * @return string|null */ public static function root_directory_path() { return self :: $root_directory_path?self :: $root_directory_path:'.'; } /** * Default homepage handler * @param UrlRequest $request * @return void */ public static function handle_homepage($request) { if (Tpl::initialized()) Tpl :: display("homepage.tpl", I18n::_("Hello world !")); else echo "

".I18n::_("Hello world!")."

"; } /** * Default logout handler * @param UrlRequest $request * @return void */ public static function handle_logout($request) { Auth::logout(); if (Tpl::initialized()) Tpl :: display("logout.tpl", I18n::_("Disconnected")); else echo "

".I18n::_("You are now disconnected.")."

"; } /** * Helper method to resolve a given path if need and make it relative * to application root directory * @param string|null $path The path to handle (optional, default: current directory) * @return string|false The relative path if exist and in app directory, absolute path if not in * app directory or false if not exists. */ public static function relative_path($path=null) { if (is_null($path)) $path = getcwd(); $path = realpath($path); if (!$path) return false; if (strpos($path, self::root_directory_path()) !== 0) return $path; return substr($path, strlen(self::root_directory_path())+1); } }