diff --git a/src/System/Integrate/Application.php b/src/System/Integrate/Application.php index e6f40fe1..f9b4d4f8 100644 --- a/src/System/Integrate/Application.php +++ b/src/System/Integrate/Application.php @@ -182,6 +182,20 @@ final class Application extends Container */ private $terminateCallback = []; + /** + * Registered booting callback. + * + * @var callable[] + */ + protected array $booting_callbacks = []; + + /** + * Registered booted callback. + * + * @var callable[] + */ + protected array $booted_callbacks = []; + /** * Contructor. * @@ -873,6 +887,8 @@ public function bootProvider() return; } + $this->callBootCallbacks($this->booting_callbacks); + foreach ($this->providers as $provider) { if (in_array($provider, $this->booted_providers)) { continue; @@ -882,6 +898,8 @@ public function bootProvider() $this->booted_providers[] = $provider; } + $this->callBootCallbacks($this->booted_callbacks); + $this->isBooted = true; } @@ -903,6 +921,46 @@ public function registerProvider() } } + /** + * Call the registered booting callbacks. + * + * @param callable[] $bootCallBacks + */ + public function callBootCallbacks($bootCallBacks): void + { + $index = 0; + + while ($index < count($bootCallBacks)) { + $this->call($bootCallBacks[$index]); + + $index++; + } + } + + /** + * Add booting call back, call before boot is calling. + * + * @param callable[] $callback + */ + public function bootingCallback($callback): void + { + $this->booting_callbacks[] = $callback; + } + + /** + * Add booted call back, call after boot is called. + * + * @param callable[] $callback + */ + public function bootedCallback($callback): void + { + $this->booted_callbacks[] = $callback; + + if ($this->isBooted()) { + $this->call($callback); + } + } + /** * Flush or reset application (static). */ @@ -914,6 +972,8 @@ public function flush(): void $this->looded_providers = []; $this->booted_providers = []; $this->terminateCallback = []; + $this->booting_callbacks = []; + $this->booted_callbacks = []; parent::flush(); } diff --git a/tests/Integrate/ApplicationTest.php b/tests/Integrate/ApplicationTest.php index f012fd26..4e68739e 100644 --- a/tests/Integrate/ApplicationTest.php +++ b/tests/Integrate/ApplicationTest.php @@ -168,6 +168,48 @@ public function itCanBootstrapWith() $this->assertTrue($app->isBootstrapped()); } + /** @test */ + public function itCanAddCallBacksBeforeAndAfterBoot() + { + $app = new Application(__DIR__); + + $app->bootedCallback(static function () { + echo 'booted01'; + }); + $app->bootedCallback(static function () { + echo 'booted02'; + }); + $app->bootingCallback(static function () { + echo 'booting01'; + }); + $app->bootingCallback(static function () { + echo 'booting02'; + }); + + ob_start(); + $app->bootProvider(); + $out = ob_get_clean(); + + $this->assertEquals($out, 'booting01booting02booted01booted02'); + $this->assertTrue($app->isBooted()); + } + + public function itCanAddCallImediatllyIfApplicationAlredyBooted() + { + $app = new Application(__DIR__); + + $app->bootProvider(); + + ob_start(); + $app->bootedCallback(static function () { + echo 'imediatly call'; + }); + $out = ob_get_clean(); + + $this->assertTrue($app->isBooted()); + $this->assertEquals($out, 'imediatly call'); + } + /** @test */ public function itCanCallDeprecatedMethod() {