From 7a8cf821fef725b3da0434927a22e39201217976 Mon Sep 17 00:00:00 2001 From: ozh Date: Wed, 13 Sep 2017 22:48:24 +0200 Subject: [PATCH] Attempt at making bootstrap more modular The idea is to try and make the unit test bootstrapping less stupid with less duplicated code. --- includes/YOURLS/Config/Config.php | 168 +++++++++++++++++++ includes/YOURLS/Config/Init.php | 175 ++++++++++++++++++++ includes/YOURLS/Config/InitDefaults.php | 119 +++++++++++++ includes/load-yourls.php | 211 ++---------------------- 4 files changed, 479 insertions(+), 194 deletions(-) create mode 100644 includes/YOURLS/Config/Config.php create mode 100644 includes/YOURLS/Config/Init.php create mode 100644 includes/YOURLS/Config/InitDefaults.php diff --git a/includes/YOURLS/Config/Config.php b/includes/YOURLS/Config/Config.php new file mode 100644 index 000000000..3638f8b0e --- /dev/null +++ b/includes/YOURLS/Config/Config.php @@ -0,0 +1,168 @@ +root = $this->fix_win32_path(realpath(__DIR__ . '../../../..')); + if (!defined('YOURLS_CONFIGFILE')) { + define('YOURLS_CONFIGFILE', $this->find_config($config)); + } + } + + /** + * Convert antislashes to slashes + * + * @since 1.7.3 + * @param string $path + * @return string path with \ converted to / + */ + public function fix_win32_path($path) { + return str_replace('\\', '/', $path); + } + + /** + * Find config.php, either user defined or from standard location + * + * @since 1.7.3 + * @param mixed $config path to user defined config file + * @return string path to found config file + */ + public function find_config($config) { + + $config = $this->fix_win32_path($config); + if (file_exists($config)) { + return $config; + } + + // config.php in /user/ + if (file_exists($this->root . '/user/config.php')) { + return $this->root . '/user/config.php'; + } + + // config.php in /includes/ + if (file_exists($this->root . '/includes/config.php')) { + return $this->root . '/includes/config.php'; + } + + // config.php not found :( + die( '

Cannot find config.php.

Please read the readme.html to learn how to install YOURLS

' ); + } + + /** + * Define core constants that have not been user defined in config.php + * + * @since 1.7.3 + * @return void + */ + public function define_core_constants() { + // Check if config.php was properly updated for 1.4 + if (!defined( 'YOURLS_DB_PREFIX' )) { + die( '

Your config.php does not contain all the required constant definitions.

Please check config-sample.php and update your config accordingly, there are new stuffs!

' ); + } + + /** + * The following has an awful CRAP index and it would be much shorter reduced to something like + * defining an array of ('YOURLS_SOMETHING' => 'default value') and then a simple loop over the + * array, checking if $current is defined as a constant and otherwise define said constant with + * its default value. I did not wrote it that way because that would make it difficult for code + * parsers to identify which constants are defined and where. So, here it is, that long list of + * if (!defined) define(). Ho and by the way, such beautiful comment, much right aligned, wow ! + */ + + // physical path of YOURLS root + if (!defined( 'YOURLS_ABSPATH' )) + define('YOURLS_ABSPATH', $this->root); + + // physical path of includes directory + if (!defined( 'YOURLS_INC' )) + define('YOURLS_INC', YOURLS_ABSPATH.'/includes'); + + // physical path of user directory + if (!defined( 'YOURLS_USERDIR' )) + define( 'YOURLS_USERDIR', YOURLS_ABSPATH.'/user' ); + + // URL of user directory + if (!defined( 'YOURLS_USERURL' )) + define( 'YOURLS_USERURL', YOURLS_SITE.'/user' ); + + // physical path of translations directory + if (!defined( 'YOURLS_LANG_DIR' )) + define( 'YOURLS_LANG_DIR', YOURLS_USERDIR.'/languages' ); + + // physical path of plugins directory + if (!defined( 'YOURLS_PLUGINDIR' )) + define( 'YOURLS_PLUGINDIR', YOURLS_USERDIR.'/plugins' ); + + // URL of plugins directory + if (!defined( 'YOURLS_PLUGINURL' )) + define( 'YOURLS_PLUGINURL', YOURLS_USERURL.'/plugins' ); + + // physical path of pages directory + if (!defined( 'YOURLS_PAGEDIR' )) + define('YOURLS_PAGEDIR', YOURLS_ABSPATH.'/pages' ); + + // table to store URLs + if (!defined( 'YOURLS_DB_TABLE_URL' )) + define( 'YOURLS_DB_TABLE_URL', YOURLS_DB_PREFIX.'url' ); + + // table to store options + if (!defined( 'YOURLS_DB_TABLE_OPTIONS' )) + define( 'YOURLS_DB_TABLE_OPTIONS', YOURLS_DB_PREFIX.'options' ); + + // table to store hits, for stats + if (!defined( 'YOURLS_DB_TABLE_LOG' )) + define( 'YOURLS_DB_TABLE_LOG', YOURLS_DB_PREFIX.'log' ); + + // minimum delay in sec before a same IP can add another URL. Note: logged in users are not throttled down. + if (!defined( 'YOURLS_FLOOD_DELAY_SECONDS' )) + define( 'YOURLS_FLOOD_DELAY_SECONDS', 15 ); + + // comma separated list of IPs that can bypass flood check. + if (!defined( 'YOURLS_FLOOD_IP_WHITELIST' )) + define( 'YOURLS_FLOOD_IP_WHITELIST', '' ); + + // life span of an auth cookie in seconds (60*60*24*7 = 7 days) + if (!defined( 'YOURLS_COOKIE_LIFE' )) + define( 'YOURLS_COOKIE_LIFE', 60*60*24*7 ); + + // life span of a nonce in seconds + if (!defined( 'YOURLS_NONCE_LIFE' )) + define( 'YOURLS_NONCE_LIFE', 43200 ); // 3600 * 12 + + // if set to true, disable stat logging (no use for it, too busy servers, ...) + if (!defined( 'YOURLS_NOSTATS' )) + define( 'YOURLS_NOSTATS', false ); + + // if set to true, force https:// in the admin area + if (!defined( 'YOURLS_ADMIN_SSL' )) + define( 'YOURLS_ADMIN_SSL', false ); + + // if set to true, verbose debug infos. Will break things. Don't enable. + if (!defined( 'YOURLS_DEBUG' )) + define( 'YOURLS_DEBUG', false ); + + // Error reporting + if (defined( 'YOURLS_DEBUG' ) && YOURLS_DEBUG == true ) { + error_reporting( -1 ); + } else { + error_reporting( E_ERROR | E_PARSE ); + } + } + +} diff --git a/includes/YOURLS/Config/Init.php b/includes/YOURLS/Config/Init.php new file mode 100644 index 000000000..52e89bc96 --- /dev/null +++ b/includes/YOURLS/Config/Init.php @@ -0,0 +1,175 @@ +include_core_funcs === true) { + $this->include_core_functions(); + } + + // Enforce UTC timezone to suppress PHP warnings -- correct date/time will be managed using the config time offset + if ($actions->default_timezone === true) { + date_default_timezone_set( 'UTC' ); + } + + // Load locale + if ($actions->load_default_textdomain === true) { + yourls_load_default_textdomain(); + } + + // Check if we are in maintenance mode - if yes, it will die here. + if ($actions->check_maintenance_mode === true) { + yourls_check_maintenance_mode(); + } + + // Fix REQUEST_URI for IIS + if ($actions->fix_request_uri === true) { + yourls_fix_request_uri(); + } + + // If request for an admin page is http:// and SSL is required, redirect + if ($actions->redirect_ssl === true) { + $this->redirect_ssl_if_needed(); + } + + // Create the YOURLS object $ydb that will contain everything we globally need + if ($actions->include_db === true) { + $this->include_db_files(); + } + + // Allow early inclusion of a cache layer + if ($actions->include_cache === true) { + $this->include_cache_files(); + } + + // Abort initialization here if fast init wanted (for tests/debug/do not use) + if ($actions->return_if_fast_init === true && defined('YOURLS_FAST_INIT') && YOURLS_FAST_INIT){ + return; + } + + // Read options right from start + if ($actions->get_all_options === true) { + yourls_get_all_options(); + } + + // Register shutdown function + if ($actions->register_shutdown === true) { + register_shutdown_function( 'yourls_shutdown' ); + } + + // Core now loaded + if ($actions->core_loaded === true) { + yourls_do_action( 'init' ); // plugins can't see this, not loaded yet + } + + // Check if need to redirect to install procedure + if ($actions->redirect_to_install === true) { + if (!yourls_is_installed() && !yourls_is_installing()) { + yourls_redirect( yourls_admin_url('install.php'), 302 ); + } + } + + // Check if upgrade is needed (bypassed if upgrading or installing) + if ($actions->check_if_upgrade_needed === true) { + if (!yourls_is_upgrading() && !yourls_is_installing() && yourls_upgrade_is_needed()) { + yourls_redirect( yourls_admin_url('upgrade.php'), 302 ); + } + } + + // Init all plugins + if ($actions->load_plugins === true) { + yourls_load_plugins(); + yourls_do_action( 'plugins_loaded' ); + } + + // Is there a new version of YOURLS ? + if ($actions->check_new_version === true) { + if (yourls_is_installed() && !yourls_is_upgrading()) { + yourls_tell_if_new_version(); + } + } + + if ($actions->init_admin === true) { + if (yourls_is_admin()) { + yourls_do_action( 'admin_init' ); + } + } + + } + + /** + * @since 1.7.3 + * @return void + */ + public function redirect_ssl_if_needed() { + if (yourls_is_admin() && yourls_needs_ssl() && !yourls_is_ssl()) { + if ( 0 === strpos( $_SERVER['REQUEST_URI'], 'http' ) ) { + yourls_redirect( preg_replace( '|^http://|', 'https://', $_SERVER['REQUEST_URI'] ) ); + } else { + yourls_redirect( 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ); + } + exit(); + } + } + + /** + * @since 1.7.3 + * @return void + */ + public function include_db_files() { + // Allow drop-in replacement for the DB engine + if (file_exists(YOURLS_USERDIR.'/db.php')) { + require_once YOURLS_USERDIR.'/db.php'; + } else { + require_once YOURLS_INC.'/class-mysql.php'; + yourls_db_connect(); + } + } + + /** + * @since 1.7.3 + * @return void + */ + public function include_cache_files() { + if (file_exists(YOURLS_USERDIR.'/cache.php')) { + require_once YOURLS_USERDIR.'/cache.php'; + } + } + + /** + * @since 1.7.3 + * @return void + */ + public function include_core_functions() { + require_once YOURLS_INC.'/version.php'; + require_once YOURLS_INC.'/functions.php'; + require_once YOURLS_INC.'/functions-plugins.php'; + require_once YOURLS_INC.'/functions-formatting.php'; + require_once YOURLS_INC.'/functions-api.php'; + require_once YOURLS_INC.'/functions-kses.php'; + require_once YOURLS_INC.'/functions-l10n.php'; + require_once YOURLS_INC.'/functions-compat.php'; + require_once YOURLS_INC.'/functions-html.php'; + require_once YOURLS_INC.'/functions-http.php'; + require_once YOURLS_INC.'/functions-infos.php'; + require_once YOURLS_INC.'/functions-deprecated.php'; + + // Load auth functions if needed + if (yourls_is_private()) { + require_once YOURLS_INC.'/functions-auth.php'; + } + } + +} diff --git a/includes/YOURLS/Config/InitDefaults.php b/includes/YOURLS/Config/InitDefaults.php new file mode 100644 index 000000000..819b3c4b7 --- /dev/null +++ b/includes/YOURLS/Config/InitDefaults.php @@ -0,0 +1,119 @@ +Cannot find config.php.

Please read the readme.html to learn how to install YOURLS

' ); -} -require_once( YOURLS_CONFIGFILE ); +require __DIR__ . '/vendor/autoload.php'; -// Check if config.php was properly updated for 1.4 -if( !defined( 'YOURLS_DB_PREFIX' ) ) - die( '

Your config.php does not contain all the required constant definitions.

Please check config-sample.php and update your config accordingly, there are new stuffs!

' ); +// Set up YOURLS config +$config = new \YOURLS\Config\Config; +/* The following require has to be at global level so the variables inside config.php, including user defined if any, + * are registered in the global scope. If this require is moved in \YOURLS\Config\Config, $yourls_user_passwords for + * instance isn't registered. + */ +require_once YOURLS_CONFIGFILE; +$config->define_core_constants(); -// Define core constants that have not been user defined in config.php - -// physical path of YOURLS root -if( !defined( 'YOURLS_ABSPATH' ) ) - define( 'YOURLS_ABSPATH', str_replace( '\\', '/', dirname( __DIR__ ) ) ); - -// physical path of includes directory -if( !defined( 'YOURLS_INC' ) ) - define( 'YOURLS_INC', YOURLS_ABSPATH.'/includes' ); - -// physical path of user directory -if( !defined( 'YOURLS_USERDIR' ) ) - define( 'YOURLS_USERDIR', YOURLS_ABSPATH.'/user' ); - -// URL of user directory -if( !defined( 'YOURLS_USERURL' ) ) - define( 'YOURLS_USERURL', YOURLS_SITE.'/user' ); - -// physical path of translations directory -if( !defined( 'YOURLS_LANG_DIR' ) ) - define( 'YOURLS_LANG_DIR', YOURLS_USERDIR.'/languages' ); - -// physical path of plugins directory -if( !defined( 'YOURLS_PLUGINDIR' ) ) - define( 'YOURLS_PLUGINDIR', YOURLS_USERDIR.'/plugins' ); - -// URL of plugins directory -if( !defined( 'YOURLS_PLUGINURL' ) ) - define( 'YOURLS_PLUGINURL', YOURLS_USERURL.'/plugins' ); - -// physical path of pages directory -if( !defined( 'YOURLS_PAGEDIR' ) ) - define('YOURLS_PAGEDIR', YOURLS_ABSPATH.'/pages' ); - -// table to store URLs -if( !defined( 'YOURLS_DB_TABLE_URL' ) ) - define( 'YOURLS_DB_TABLE_URL', YOURLS_DB_PREFIX.'url' ); - -// table to store options -if( !defined( 'YOURLS_DB_TABLE_OPTIONS' ) ) - define( 'YOURLS_DB_TABLE_OPTIONS', YOURLS_DB_PREFIX.'options' ); - -// table to store hits, for stats -if( !defined( 'YOURLS_DB_TABLE_LOG' ) ) - define( 'YOURLS_DB_TABLE_LOG', YOURLS_DB_PREFIX.'log' ); - -// minimum delay in sec before a same IP can add another URL. Note: logged in users are not throttled down. -if( !defined( 'YOURLS_FLOOD_DELAY_SECONDS' ) ) - define( 'YOURLS_FLOOD_DELAY_SECONDS', 15 ); - -// comma separated list of IPs that can bypass flood check. -if( !defined( 'YOURLS_FLOOD_IP_WHITELIST' ) ) - define( 'YOURLS_FLOOD_IP_WHITELIST', '' ); - -// life span of an auth cookie in seconds (60*60*24*7 = 7 days) -if( !defined( 'YOURLS_COOKIE_LIFE' ) ) - define( 'YOURLS_COOKIE_LIFE', 60*60*24*7 ); - -// life span of a nonce in seconds -if( !defined( 'YOURLS_NONCE_LIFE' ) ) - define( 'YOURLS_NONCE_LIFE', 43200 ); // 3600 * 12 - -// if set to true, disable stat logging (no use for it, too busy servers, ...) -if( !defined( 'YOURLS_NOSTATS' ) ) - define( 'YOURLS_NOSTATS', false ); - -// if set to true, force https:// in the admin area -if( !defined( 'YOURLS_ADMIN_SSL' ) ) - define( 'YOURLS_ADMIN_SSL', false ); - -// if set to true, verbose debug infos. Will break things. Don't enable. -if( !defined( 'YOURLS_DEBUG' ) ) - define( 'YOURLS_DEBUG', false ); - -// Error reporting -if( defined( 'YOURLS_DEBUG' ) && YOURLS_DEBUG == true ) { - error_reporting( -1 ); -} else { - error_reporting( E_ERROR | E_PARSE ); -} - -// Load 3rd party and YOURLS libraries -require_once YOURLS_INC. '/vendor/autoload.php'; - -// Include all functions -require_once( YOURLS_INC.'/version.php' ); -require_once( YOURLS_INC.'/functions.php'); -require_once( YOURLS_INC.'/functions-plugins.php' ); -require_once( YOURLS_INC.'/functions-formatting.php' ); -require_once( YOURLS_INC.'/functions-api.php' ); -require_once( YOURLS_INC.'/functions-kses.php' ); -require_once( YOURLS_INC.'/functions-l10n.php' ); -require_once( YOURLS_INC.'/functions-compat.php' ); -require_once( YOURLS_INC.'/functions-html.php' ); -require_once( YOURLS_INC.'/functions-http.php' ); -require_once( YOURLS_INC.'/functions-infos.php' ); -require_once( YOURLS_INC.'/functions-deprecated.php' ); - -// Load auth functions if needed -if( yourls_is_private() ) { - require_once( YOURLS_INC.'/functions-auth.php' ); -} - -// Enforce UTC timezone to suppress PHP warnings -- correct date/time will be managed using the config time offset -date_default_timezone_set( 'UTC' ); - -// Load locale -yourls_load_default_textdomain(); - -// Check if we are in maintenance mode - if yes, it will die here. -yourls_check_maintenance_mode(); - -// Fix REQUEST_URI for IIS -yourls_fix_request_uri(); - -// If request for an admin page is http:// and SSL is required, redirect -if( yourls_is_admin() && yourls_needs_ssl() && !yourls_is_ssl() ) { - if ( 0 === strpos( $_SERVER['REQUEST_URI'], 'http' ) ) { - yourls_redirect( preg_replace( '|^http://|', 'https://', $_SERVER['REQUEST_URI'] ) ); - exit(); - } else { - yourls_redirect( 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ); - exit(); - } -} - -// Create the YOURLS object $ydb that will contain everything we globally need -global $ydb; - -// Allow drop-in replacement for the DB engine -if( file_exists( YOURLS_USERDIR.'/db.php' ) ) { - require_once( YOURLS_USERDIR.'/db.php' ); -} else { - require_once( YOURLS_INC.'/class-mysql.php' ); - yourls_db_connect(); -} - -// Allow early inclusion of a cache layer -if( file_exists( YOURLS_USERDIR.'/cache.php' ) ) - require_once( YOURLS_USERDIR.'/cache.php' ); - -// Abort initialization here if fast init wanted (for tests/debug/do not use) -if (defined('YOURLS_FAST_INIT') && YOURLS_FAST_INIT){ - return; -} - -// Read options right from start -yourls_get_all_options(); - -// Register shutdown function -register_shutdown_function( 'yourls_shutdown' ); - -// Core now loaded -yourls_do_action( 'init' ); // plugins can't see this, not loaded yet - -// Check if need to redirect to install procedure -if( !yourls_is_installed() && !yourls_is_installing() ) { - yourls_redirect( yourls_admin_url( 'install.php' ), 302 ); -} - -// Check if upgrade is needed (bypassed if upgrading or installing) -if ( !yourls_is_upgrading() && !yourls_is_installing() ) { - if ( yourls_upgrade_is_needed() ) { - yourls_redirect( YOURLS_SITE .'/admin/upgrade.php', 302 ); - } -} - -// Init all plugins -yourls_load_plugins(); -yourls_do_action( 'plugins_loaded' ); - -// Is there a new version of YOURLS ? -if( yourls_is_installed() && !yourls_is_upgrading() ) { - yourls_tell_if_new_version(); -} - -if( yourls_is_admin() ) - yourls_do_action( 'admin_init' ); +// Initialize YOURLS with default behaviors +$init_defaults = new \YOURLS\Config\InitDefaults; +new \YOURLS\Config\Init($init_defaults);