From 71549442574d1948632b0a11b9c0878ba197db5b Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Sat, 13 Jul 2024 19:00:03 +0200 Subject: [PATCH 01/10] Add booting/booted callbacks to the base HydeExtension class --- .../src/Foundation/Concerns/HydeExtension.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/packages/framework/src/Foundation/Concerns/HydeExtension.php b/packages/framework/src/Foundation/Concerns/HydeExtension.php index 0eb9f6ccf0c..08f30b7e040 100644 --- a/packages/framework/src/Foundation/Concerns/HydeExtension.php +++ b/packages/framework/src/Foundation/Concerns/HydeExtension.php @@ -77,4 +77,22 @@ public function discoverRoutes(RouteCollection $collection): void { // } + + /** + * Register a callback to be run before the kernel is booted. + * Override this method to define your booting logic. + */ + public function booting(): void + { + // + } + + /** + * Register a callback to be run after the kernel is booted. + * Override this method to define your booted logic. + */ + public function booted(): void + { + // + } } From 9b4b19fd6c6c9e65aa5c3e059e7b28d1ce80d3bd Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Sat, 13 Jul 2024 19:00:54 +0200 Subject: [PATCH 02/10] Introduce local variable so we can use the instance --- .../framework/src/Foundation/Concerns/ManagesExtensions.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/framework/src/Foundation/Concerns/ManagesExtensions.php b/packages/framework/src/Foundation/Concerns/ManagesExtensions.php index 080c74e5344..ec63d54074f 100644 --- a/packages/framework/src/Foundation/Concerns/ManagesExtensions.php +++ b/packages/framework/src/Foundation/Concerns/ManagesExtensions.php @@ -54,7 +54,8 @@ public function registerExtension(string $extension): void throw new InvalidArgumentException("Extension [$extension] is already registered."); } - $this->extensions[$extension] = new $extension(); + $instance = new $extension(); + $this->extensions[$extension] = $instance; } /** From c1bf78fecb050bfbdfa1f022ccbd332a8672599a Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Sat, 13 Jul 2024 19:01:34 +0200 Subject: [PATCH 03/10] Register the boot callbacks with the extension Much more elegant idea by Claude, compared to what I was thinking (looping extensions before/after boot) --- .../framework/src/Foundation/Concerns/ManagesExtensions.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/framework/src/Foundation/Concerns/ManagesExtensions.php b/packages/framework/src/Foundation/Concerns/ManagesExtensions.php index ec63d54074f..52de766e3cf 100644 --- a/packages/framework/src/Foundation/Concerns/ManagesExtensions.php +++ b/packages/framework/src/Foundation/Concerns/ManagesExtensions.php @@ -56,6 +56,9 @@ public function registerExtension(string $extension): void $instance = new $extension(); $this->extensions[$extension] = $instance; + + $this->booting([$instance, 'booting']); + $this->booted([$instance, 'booted']); } /** From 838dc6e4d0885624c59f4ac7ab89ca5e910be20e Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Sat, 13 Jul 2024 19:09:09 +0200 Subject: [PATCH 04/10] Update test to cover new callback methods --- .../Feature/HydeExtensionFeatureTest.php | 40 ++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/packages/framework/tests/Feature/HydeExtensionFeatureTest.php b/packages/framework/tests/Feature/HydeExtensionFeatureTest.php index 6ed83dd5793..a773e97f4f4 100644 --- a/packages/framework/tests/Feature/HydeExtensionFeatureTest.php +++ b/packages/framework/tests/Feature/HydeExtensionFeatureTest.php @@ -51,7 +51,7 @@ public function testHandlerMethodsAreCalledByDiscovery() $this->kernel->boot(); - $this->assertSame(['files', 'pages', 'routes'], HydeTestExtension::$callCache); + $this->assertSame(['booting', 'files', 'pages', 'routes', 'booted'], HydeTestExtension::$callCache); HydeTestExtension::$callCache = []; } @@ -133,6 +133,19 @@ public function testCustomRegisteredPagesAreDiscoveredByTheRouteCollectionClass( $this->assertEquals(new Route(new TestPageClass('bar')), Routes::get('foo/bar')); } + public function testBootingAndBootedMethodsAreCalled() + { + $this->kernel->registerExtension(BootableTestExtension::class); + + $this->assertSame([], BootableTestExtension::$callCache); + + $this->kernel->boot(); + + $this->assertSame(['booting', 'booted'], BootableTestExtension::$callCache); + + BootableTestExtension::$callCache = []; + } + protected function markTestSuccessful(): void { $this->assertTrue(true); @@ -165,6 +178,16 @@ public function discoverRoutes(RouteCollection $collection): void { static::$callCache[] = 'routes'; } + + public function booting(): void + { + static::$callCache[] = 'booting'; + } + + public function booted(): void + { + static::$callCache[] = 'booted'; + } } class HydeExtensionTestPage extends HydePage @@ -225,3 +248,18 @@ public static function getCalled(string $method): array return self::$callCache[$method]; } } + +class BootableTestExtension extends HydeExtension +{ + public static array $callCache = []; + + public function booting(): void + { + static::$callCache[] = 'booting'; + } + + public function booted(): void + { + static::$callCache[] = 'booted'; + } +} From 2f44b8501b7118bd69c85b3c9668eadef6204da3 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Sat, 13 Jul 2024 19:18:33 +0200 Subject: [PATCH 05/10] Document extension booting and booted callbacks --- docs/architecture-concepts/extensions-api.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/docs/architecture-concepts/extensions-api.md b/docs/architecture-concepts/extensions-api.md index d71e6a258b5..5213e0f139d 100644 --- a/docs/architecture-concepts/extensions-api.md +++ b/docs/architecture-concepts/extensions-api.md @@ -92,6 +92,24 @@ public function discoverRoutes(RouteCollection $collection): void; Any of these can be implemented in your extension class, and they will be called during the discovery. As you can see, the instance of the discovery collection is injected into the method for you to interact with. +### Booting and Booted Callbacks + +In addition to the discovery handlers, you can also define `booting` and `booted` callbacks in your extension class. These methods allow you to run custom logic before and after the kernel boots, respectively. + +```php +class JsonPageExtension extends HydeExtension { + public function booting(): void { + // This runs before the kernel boots, meaning pages have not been discovered yet + } + + public function booted(): void { + // This runs after the kernel has booted, meaning pages have been discovered + } +} +``` + +These methods are particularly useful for setting up your extension's environment or performing post-boot operations. + #### Discovery handler example Let's go crazy and implement a discovery handler to collect `JsonPage` files from an external API! We will do this From 798a948939358b09a23c928a8ebbae792e4e7543 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Sat, 13 Jul 2024 19:26:38 +0200 Subject: [PATCH 06/10] Update extension boot callbacks to inject the kernel --- docs/architecture-concepts/extensions-api.md | 12 +++++++---- .../src/Foundation/Concerns/HydeExtension.php | 5 +++-- .../Feature/HydeExtensionFeatureTest.php | 21 ++++++++++++------- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/docs/architecture-concepts/extensions-api.md b/docs/architecture-concepts/extensions-api.md index 5213e0f139d..2a5588927ae 100644 --- a/docs/architecture-concepts/extensions-api.md +++ b/docs/architecture-concepts/extensions-api.md @@ -94,21 +94,25 @@ the instance of the discovery collection is injected into the method for you to ### Booting and Booted Callbacks -In addition to the discovery handlers, you can also define `booting` and `booted` callbacks in your extension class. These methods allow you to run custom logic before and after the kernel boots, respectively. +In addition to the discovery handlers, you can also define `booting` and `booted` callbacks in your extension class. These methods allow you to run custom logic before and after the kernel boots, respectively. Both methods receive the `HydeKernel` instance as a parameter, allowing you to interact with the kernel directly. ```php +use Hyde\Foundation\HydeKernel; + class JsonPageExtension extends HydeExtension { - public function booting(): void { + public function booting(HydeKernel $kernel): void { // This runs before the kernel boots, meaning pages have not been discovered yet + // You can use $kernel to interact with the HydeKernel instance } - public function booted(): void { + public function booted(HydeKernel $kernel): void { // This runs after the kernel has booted, meaning pages have been discovered + // You can use $kernel to interact with the HydeKernel instance } } ``` -These methods are particularly useful for setting up your extension's environment or performing post-boot operations. +These callbacks provide powerful hooks into the Hyde system, allowing your extensions to integrate deeply and modify Hyde's behavior as needed. The `booting` callback can be used to set up the system with information needed to discover pages, while the `booted` callback can can be used to perform operations requiring knowledge of discovered data, even modifying them if needed. #### Discovery handler example diff --git a/packages/framework/src/Foundation/Concerns/HydeExtension.php b/packages/framework/src/Foundation/Concerns/HydeExtension.php index 08f30b7e040..d274ddbd663 100644 --- a/packages/framework/src/Foundation/Concerns/HydeExtension.php +++ b/packages/framework/src/Foundation/Concerns/HydeExtension.php @@ -4,6 +4,7 @@ namespace Hyde\Foundation\Concerns; +use Hyde\Foundation\HydeKernel; use Hyde\Foundation\Kernel\FileCollection; use Hyde\Foundation\Kernel\PageCollection; use Hyde\Foundation\Kernel\RouteCollection; @@ -82,7 +83,7 @@ public function discoverRoutes(RouteCollection $collection): void * Register a callback to be run before the kernel is booted. * Override this method to define your booting logic. */ - public function booting(): void + public function booting(HydeKernel $kernel): void { // } @@ -91,7 +92,7 @@ public function booting(): void * Register a callback to be run after the kernel is booted. * Override this method to define your booted logic. */ - public function booted(): void + public function booted(HydeKernel $kernel): void { // } diff --git a/packages/framework/tests/Feature/HydeExtensionFeatureTest.php b/packages/framework/tests/Feature/HydeExtensionFeatureTest.php index a773e97f4f4..dc46d02c503 100644 --- a/packages/framework/tests/Feature/HydeExtensionFeatureTest.php +++ b/packages/framework/tests/Feature/HydeExtensionFeatureTest.php @@ -133,7 +133,7 @@ public function testCustomRegisteredPagesAreDiscoveredByTheRouteCollectionClass( $this->assertEquals(new Route(new TestPageClass('bar')), Routes::get('foo/bar')); } - public function testBootingAndBootedMethodsAreCalled() + public function testBootingAndBootedMethodsAreCalledWithKernel() { $this->kernel->registerExtension(BootableTestExtension::class); @@ -141,7 +141,12 @@ public function testBootingAndBootedMethodsAreCalled() $this->kernel->boot(); - $this->assertSame(['booting', 'booted'], BootableTestExtension::$callCache); + $this->assertCount(2, BootableTestExtension::$callCache); + + $this->assertInstanceOf(HydeKernel::class, BootableTestExtension::$callCache['booting']); + $this->assertInstanceOf(HydeKernel::class, BootableTestExtension::$callCache['booted']); + $this->assertSame($this->kernel, BootableTestExtension::$callCache['booting']); + $this->assertSame($this->kernel, BootableTestExtension::$callCache['booted']); BootableTestExtension::$callCache = []; } @@ -179,12 +184,12 @@ public function discoverRoutes(RouteCollection $collection): void static::$callCache[] = 'routes'; } - public function booting(): void + public function booting(HydeKernel $kernel): void { static::$callCache[] = 'booting'; } - public function booted(): void + public function booted(HydeKernel $kernel): void { static::$callCache[] = 'booted'; } @@ -253,13 +258,13 @@ class BootableTestExtension extends HydeExtension { public static array $callCache = []; - public function booting(): void + public function booting(HydeKernel $kernel): void { - static::$callCache[] = 'booting'; + static::$callCache['booting'] = $kernel; } - public function booted(): void + public function booted(HydeKernel $kernel): void { - static::$callCache[] = 'booted'; + static::$callCache['booted'] = $kernel; } } From 9db32e71ca0d2c9e60c09ca1c2b35a30a4e63deb Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Sat, 13 Jul 2024 19:32:10 +0200 Subject: [PATCH 07/10] Remove parts of documentation that should be obvious --- docs/architecture-concepts/extensions-api.md | 2 -- packages/framework/src/Foundation/Concerns/HydeExtension.php | 2 -- 2 files changed, 4 deletions(-) diff --git a/docs/architecture-concepts/extensions-api.md b/docs/architecture-concepts/extensions-api.md index 2a5588927ae..e894444b6c0 100644 --- a/docs/architecture-concepts/extensions-api.md +++ b/docs/architecture-concepts/extensions-api.md @@ -102,12 +102,10 @@ use Hyde\Foundation\HydeKernel; class JsonPageExtension extends HydeExtension { public function booting(HydeKernel $kernel): void { // This runs before the kernel boots, meaning pages have not been discovered yet - // You can use $kernel to interact with the HydeKernel instance } public function booted(HydeKernel $kernel): void { // This runs after the kernel has booted, meaning pages have been discovered - // You can use $kernel to interact with the HydeKernel instance } } ``` diff --git a/packages/framework/src/Foundation/Concerns/HydeExtension.php b/packages/framework/src/Foundation/Concerns/HydeExtension.php index d274ddbd663..1435eb8e929 100644 --- a/packages/framework/src/Foundation/Concerns/HydeExtension.php +++ b/packages/framework/src/Foundation/Concerns/HydeExtension.php @@ -81,7 +81,6 @@ public function discoverRoutes(RouteCollection $collection): void /** * Register a callback to be run before the kernel is booted. - * Override this method to define your booting logic. */ public function booting(HydeKernel $kernel): void { @@ -90,7 +89,6 @@ public function booting(HydeKernel $kernel): void /** * Register a callback to be run after the kernel is booted. - * Override this method to define your booted logic. */ public function booted(HydeKernel $kernel): void { From 4f339b6acf516feb45f7c7939b1088f93f502bcf Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Sat, 13 Jul 2024 19:32:30 +0200 Subject: [PATCH 08/10] Update code documentation --- .../framework/src/Foundation/Concerns/HydeExtension.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/framework/src/Foundation/Concerns/HydeExtension.php b/packages/framework/src/Foundation/Concerns/HydeExtension.php index 1435eb8e929..54f99977325 100644 --- a/packages/framework/src/Foundation/Concerns/HydeExtension.php +++ b/packages/framework/src/Foundation/Concerns/HydeExtension.php @@ -80,7 +80,8 @@ public function discoverRoutes(RouteCollection $collection): void } /** - * Register a callback to be run before the kernel is booted. + * Register a callback to be run before the kernel is booted, + * and before file/page/route discovery has begun. */ public function booting(HydeKernel $kernel): void { @@ -88,7 +89,8 @@ public function booting(HydeKernel $kernel): void } /** - * Register a callback to be run after the kernel is booted. + * Register a callback to be run after the kernel is booted, + * and after file/page/route discovery has completed. */ public function booted(HydeKernel $kernel): void { From b8547688682bccac90d3701469b649cc8cb343f7 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Sat, 13 Jul 2024 19:33:53 +0200 Subject: [PATCH 09/10] Restructure documentation --- docs/architecture-concepts/extensions-api.md | 8 +++++--- .../framework/src/Foundation/Concerns/HydeExtension.php | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/architecture-concepts/extensions-api.md b/docs/architecture-concepts/extensions-api.md index e894444b6c0..7c6f4c7928e 100644 --- a/docs/architecture-concepts/extensions-api.md +++ b/docs/architecture-concepts/extensions-api.md @@ -101,16 +101,18 @@ use Hyde\Foundation\HydeKernel; class JsonPageExtension extends HydeExtension { public function booting(HydeKernel $kernel): void { - // This runs before the kernel boots, meaning pages have not been discovered yet + // This runs before the kernel boots and before running auto-discovery } public function booted(HydeKernel $kernel): void { - // This runs after the kernel has booted, meaning pages have been discovered + // This runs after the kernel boots and after running auto-discovery } } ``` -These callbacks provide powerful hooks into the Hyde system, allowing your extensions to integrate deeply and modify Hyde's behavior as needed. The `booting` callback can be used to set up the system with information needed to discover pages, while the `booted` callback can can be used to perform operations requiring knowledge of discovered data, even modifying them if needed. +The `booting` callback can be used to set up the system with information needed to discover pages, while the `booted` callback can can be used to perform operations requiring knowledge of discovered data, even modifying them if needed. + +These callbacks provide powerful hooks into the Hyde system, allowing your extensions to integrate deeply and modify Hyde's behavior as needed. #### Discovery handler example diff --git a/packages/framework/src/Foundation/Concerns/HydeExtension.php b/packages/framework/src/Foundation/Concerns/HydeExtension.php index 54f99977325..b83a83780bc 100644 --- a/packages/framework/src/Foundation/Concerns/HydeExtension.php +++ b/packages/framework/src/Foundation/Concerns/HydeExtension.php @@ -81,7 +81,7 @@ public function discoverRoutes(RouteCollection $collection): void /** * Register a callback to be run before the kernel is booted, - * and before file/page/route discovery has begun. + * which is before any file/page/route discovery has begun. */ public function booting(HydeKernel $kernel): void { @@ -90,7 +90,7 @@ public function booting(HydeKernel $kernel): void /** * Register a callback to be run after the kernel is booted, - * and after file/page/route discovery has completed. + * which is after file/page/route discovery has completed. */ public function booted(HydeKernel $kernel): void { From af8714f88508626247d154c70d11d66412945d0a Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Sat, 13 Jul 2024 19:35:24 +0200 Subject: [PATCH 10/10] Update RELEASE_NOTES.md --- RELEASE_NOTES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 1bd2a7a4fcd..443c767eab7 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -15,6 +15,7 @@ This serves two purposes: - Added a new `\Hyde\Framework\Exceptions\ParseException` exception class to handle parsing exceptions in data collection files in https://github.com/hydephp/develop/pull/1732 - Added a new `\Hyde\Framework\Exceptions\InvalidConfigurationException` exception class to handle invalid configuration exceptions in https://github.com/hydephp/develop/pull/1799 - The `\Hyde\Facades\Features` class is no longer marked as internal, and is now thus part of the public API. +- Added support for setting `booting()` and `booted()` callbacks in `HydeExtension` classes, allowing extension developers to hook into the kernel boot process more easily in https://github.com/hydephp/develop/pull/1847 - Added support for setting custom navigation items in the YAML configuration in https://github.com/hydephp/develop/pull/1818 - Added support for setting extra attributes for navigation items in https://github.com/hydephp/develop/pull/1824 - Introduced a new navigation config builder class to simplify navigation configuration in https://github.com/hydephp/develop/pull/1827