-
Notifications
You must be signed in to change notification settings - Fork 1.9k
feat: add Boot class #8604
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
feat: add Boot class #8604
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
1671882
refactor: extract Boot class
kenjis 5338b3d
refactor: move code to Boot class
kenjis 529eb95
refactor: use Boot class in Test/bootstrap.php
kenjis 5691689
refactor: fix method name
kenjis c5191a0
refactor: remove rtrim()
kenjis 41db766
docs: update comments
kenjis 7b81bb0
docs: add user guide
kenjis c335731
docs: add @codeCoverageIgnore
kenjis 4a430ea
docs: remove space
kenjis 4cd1a70
docs: remove @used-by
kenjis a95c6f1
refactor: extract boot() method
kenjis 1022a33
refactor: improve readability
kenjis 61bf440
refactor: remove unneeded unset()
kenjis dc9caae
refactor: move checkMissingExtensions() up
kenjis a5ee340
refactor: early return
kenjis 44583a4
fix: change HTTP status code from 200 to 503
kenjis 842fd6e
feat: "system/bootstrap.php" shows upgrade error message
kenjis File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,237 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/** | ||
* This file is part of CodeIgniter 4 framework. | ||
* | ||
* (c) CodeIgniter Foundation <admin@codeigniter.com> | ||
* | ||
* For the full copyright and license information, please view | ||
* the LICENSE file that was distributed with this source code. | ||
*/ | ||
|
||
namespace CodeIgniter; | ||
|
||
use CodeIgniter\Config\DotEnv; | ||
use Config\Autoload; | ||
use Config\Modules; | ||
use Config\Paths; | ||
use Config\Services; | ||
|
||
/** | ||
* Bootstrap for the application | ||
* | ||
* @codeCoverageIgnore | ||
*/ | ||
class Boot | ||
{ | ||
/** | ||
* Used by `public/index.php` | ||
* | ||
* Context | ||
* web: Invoked by HTTP request | ||
* php-cli: Invoked by CLI via `php public/index.php` | ||
*/ | ||
public static function bootWeb(Paths $paths): void | ||
{ | ||
static::boot($paths); | ||
} | ||
|
||
/** | ||
* Used by `spark` | ||
*/ | ||
public static function bootSpark(Paths $paths): void | ||
MGatner marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
static::boot($paths); | ||
} | ||
|
||
protected static function boot(Paths $paths): void | ||
{ | ||
static::definePathConstants($paths); | ||
if (! defined('APP_NAMESPACE')) { | ||
static::loadConstants(); | ||
} | ||
static::checkMissingExtensions(); | ||
|
||
static::loadDotEnv($paths); | ||
static::defineEnvironment(); | ||
static::loadEnvironmentBootstrap($paths); | ||
|
||
static::loadCommonFunctions(); | ||
static::loadAutoloader(); | ||
static::setExceptionHandler(); | ||
static::initializeKint(); | ||
} | ||
|
||
/** | ||
* Used by `system/Test/bootstrap.php` | ||
*/ | ||
public static function bootTest(Paths $paths): void | ||
{ | ||
static::loadConstants(); | ||
static::checkMissingExtensions(); | ||
|
||
static::loadDotEnv($paths); | ||
static::loadEnvironmentBootstrap($paths, false); | ||
|
||
static::loadCommonFunctions(); | ||
static::loadAutoloader(); | ||
static::setExceptionHandler(); | ||
static::initializeKint(); | ||
} | ||
|
||
/** | ||
* Load environment settings from .env files into $_SERVER and $_ENV | ||
*/ | ||
protected static function loadDotEnv(Paths $paths): void | ||
{ | ||
require_once $paths->systemDirectory . '/Config/DotEnv.php'; | ||
(new DotEnv($paths->appDirectory . '/../'))->load(); | ||
} | ||
|
||
protected static function defineEnvironment(): void | ||
{ | ||
if (! defined('ENVIRONMENT')) { | ||
// @phpstan-ignore-next-line | ||
$env = $_ENV['CI_ENVIRONMENT'] ?? $_SERVER['CI_ENVIRONMENT'] | ||
?? getenv('CI_ENVIRONMENT') | ||
?: 'production'; | ||
|
||
define('ENVIRONMENT', $env); | ||
} | ||
} | ||
|
||
protected static function loadEnvironmentBootstrap(Paths $paths, bool $exit = true): void | ||
{ | ||
if (is_file($paths->appDirectory . '/Config/Boot/' . ENVIRONMENT . '.php')) { | ||
require_once $paths->appDirectory . '/Config/Boot/' . ENVIRONMENT . '.php'; | ||
|
||
return; | ||
} | ||
|
||
if ($exit) { | ||
header('HTTP/1.1 503 Service Unavailable.', true, 503); | ||
echo 'The application environment is not set correctly.'; | ||
|
||
exit(EXIT_ERROR); | ||
} | ||
} | ||
|
||
/** | ||
* The path constants provide convenient access to the folders throughout | ||
* the application. We have to set them up here, so they are available in | ||
* the config files that are loaded. | ||
*/ | ||
protected static function definePathConstants(Paths $paths): void | ||
{ | ||
// The path to the application directory. | ||
if (! defined('APPPATH')) { | ||
define('APPPATH', realpath(rtrim($paths->appDirectory, '\\/ ')) . DIRECTORY_SEPARATOR); | ||
} | ||
|
||
// The path to the project root directory. Just above APPPATH. | ||
if (! defined('ROOTPATH')) { | ||
define('ROOTPATH', realpath(APPPATH . '../') . DIRECTORY_SEPARATOR); | ||
} | ||
|
||
// The path to the system directory. | ||
if (! defined('SYSTEMPATH')) { | ||
define('SYSTEMPATH', realpath(rtrim($paths->systemDirectory, '\\/ ')) . DIRECTORY_SEPARATOR); | ||
} | ||
|
||
// The path to the writable directory. | ||
if (! defined('WRITEPATH')) { | ||
define('WRITEPATH', realpath(rtrim($paths->writableDirectory, '\\/ ')) . DIRECTORY_SEPARATOR); | ||
} | ||
|
||
// The path to the tests directory | ||
if (! defined('TESTPATH')) { | ||
define('TESTPATH', realpath(rtrim($paths->testsDirectory, '\\/ ')) . DIRECTORY_SEPARATOR); | ||
} | ||
} | ||
|
||
protected static function loadConstants(): void | ||
{ | ||
require_once APPPATH . 'Config/Constants.php'; | ||
} | ||
|
||
protected static function loadCommonFunctions(): void | ||
{ | ||
// Require app/Common.php file if exists. | ||
if (is_file(APPPATH . 'Common.php')) { | ||
require_once APPPATH . 'Common.php'; | ||
} | ||
|
||
// Require system/Common.php | ||
require_once SYSTEMPATH . 'Common.php'; | ||
} | ||
|
||
/** | ||
* The autoloader allows all the pieces to work together in the framework. | ||
* We have to load it here, though, so that the config files can use the | ||
* path constants. | ||
*/ | ||
protected static function loadAutoloader(): void | ||
{ | ||
if (! class_exists(Autoload::class, false)) { | ||
require_once SYSTEMPATH . 'Config/AutoloadConfig.php'; | ||
require_once APPPATH . 'Config/Autoload.php'; | ||
require_once SYSTEMPATH . 'Modules/Modules.php'; | ||
require_once APPPATH . 'Config/Modules.php'; | ||
} | ||
|
||
require_once SYSTEMPATH . 'Autoloader/Autoloader.php'; | ||
require_once SYSTEMPATH . 'Config/BaseService.php'; | ||
require_once SYSTEMPATH . 'Config/Services.php'; | ||
require_once APPPATH . 'Config/Services.php'; | ||
|
||
// Initialize and register the loader with the SPL autoloader stack. | ||
Services::autoloader()->initialize(new Autoload(), new Modules())->register(); | ||
Services::autoloader()->loadHelpers(); | ||
} | ||
|
||
protected static function setExceptionHandler(): void | ||
{ | ||
Services::exceptions()->initialize(); | ||
} | ||
|
||
protected static function checkMissingExtensions(): void | ||
{ | ||
if (is_file(COMPOSER_PATH)) { | ||
return; | ||
} | ||
|
||
// Run this check for manual installations | ||
$missingExtensions = []; | ||
|
||
foreach ([ | ||
'intl', | ||
'json', | ||
'mbstring', | ||
] as $extension) { | ||
if (! extension_loaded($extension)) { | ||
$missingExtensions[] = $extension; | ||
} | ||
} | ||
|
||
if ($missingExtensions === []) { | ||
return; | ||
} | ||
|
||
$message = sprintf( | ||
'The framework needs the following extension(s) installed and loaded: %s.', | ||
implode(', ', $missingExtensions) | ||
); | ||
|
||
header('HTTP/1.1 503 Service Unavailable.', true, 503); | ||
echo $message; | ||
|
||
exit(EXIT_ERROR); | ||
} | ||
|
||
protected static function initializeKint(): void | ||
{ | ||
Services::autoloader()->initializeKint(CI_DEBUG); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I always find it difficult to intercept the boot process. I don't want to overcomplicated this, but would it make sense to have an extension of this in
App\
to allow devs to modify the boot process? This class could have necessary methods asfinal
. Alternatively there could be another file like app/Config/Boot/Default.php that is always loaded alongside the environment-specific version.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you want to modify the boot process, extend the
Boot
class, and run your Boot inindex.php
.