Skip to content

Commit

Permalink
Merge pull request #1847 from hydephp/extension-class-booting-callbacks
Browse files Browse the repository at this point in the history
[2.x] Add booting and booted callbacks to the HydeExtension feature
  • Loading branch information
caendesilva authored Jul 13, 2024
2 parents 087f183 + af8714f commit 593293e
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 2 deletions.
1 change: 1 addition & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
22 changes: 22 additions & 0 deletions docs/architecture-concepts/extensions-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,28 @@ 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. 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(HydeKernel $kernel): void {
// This runs before the kernel boots and before running auto-discovery
}

public function booted(HydeKernel $kernel): void {
// This runs after the kernel boots and after running auto-discovery
}
}
```

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

Let's go crazy and implement a discovery handler to collect `JsonPage` files from an external API! We will do this
Expand Down
19 changes: 19 additions & 0 deletions packages/framework/src/Foundation/Concerns/HydeExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -77,4 +78,22 @@ public function discoverRoutes(RouteCollection $collection): void
{
//
}

/**
* Register a callback to be run before the kernel is booted,
* which is before any file/page/route discovery has begun.
*/
public function booting(HydeKernel $kernel): void
{
//
}

/**
* Register a callback to be run after the kernel is booted,
* which is after file/page/route discovery has completed.
*/
public function booted(HydeKernel $kernel): void
{
//
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,11 @@ 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;

$this->booting([$instance, 'booting']);
$this->booted([$instance, 'booted']);
}

/**
Expand Down
45 changes: 44 additions & 1 deletion packages/framework/tests/Feature/HydeExtensionFeatureTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [];
}
Expand Down Expand Up @@ -133,6 +133,24 @@ public function testCustomRegisteredPagesAreDiscoveredByTheRouteCollectionClass(
$this->assertEquals(new Route(new TestPageClass('bar')), Routes::get('foo/bar'));
}

public function testBootingAndBootedMethodsAreCalledWithKernel()
{
$this->kernel->registerExtension(BootableTestExtension::class);

$this->assertSame([], BootableTestExtension::$callCache);

$this->kernel->boot();

$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 = [];
}

protected function markTestSuccessful(): void
{
$this->assertTrue(true);
Expand Down Expand Up @@ -165,6 +183,16 @@ public function discoverRoutes(RouteCollection $collection): void
{
static::$callCache[] = 'routes';
}

public function booting(HydeKernel $kernel): void
{
static::$callCache[] = 'booting';
}

public function booted(HydeKernel $kernel): void
{
static::$callCache[] = 'booted';
}
}

class HydeExtensionTestPage extends HydePage
Expand Down Expand Up @@ -225,3 +253,18 @@ public static function getCalled(string $method): array
return self::$callCache[$method];
}
}

class BootableTestExtension extends HydeExtension
{
public static array $callCache = [];

public function booting(HydeKernel $kernel): void
{
static::$callCache['booting'] = $kernel;
}

public function booted(HydeKernel $kernel): void
{
static::$callCache['booted'] = $kernel;
}
}

0 comments on commit 593293e

Please sign in to comment.