Skip to content

Commit 9630a7a

Browse files
authored
Merge pull request #1144 from hydephp/make-the-extensions-api-use-non-static-methods
Refactor the Extensions API to use Kernel Singletons instead of static classes
2 parents bc35bb2 + 726a62d commit 9630a7a

File tree

8 files changed

+220
-66
lines changed

8 files changed

+220
-66
lines changed

packages/framework/src/Foundation/Concerns/HydeExtension.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public static function getPageClasses(): array
5050
* at the end of the file discovery process. The collection instance
5151
* will be injected, so that you can interact with it directly.
5252
*/
53-
public static function discoverFiles(FileCollection $collection): void
53+
public function discoverFiles(FileCollection $collection): void
5454
{
5555
//
5656
}
@@ -61,7 +61,7 @@ public static function discoverFiles(FileCollection $collection): void
6161
* at the end of the page discovery process. The collection instance
6262
* will be injected, so that you can interact with it directly.
6363
*/
64-
public static function discoverPages(PageCollection $collection): void
64+
public function discoverPages(PageCollection $collection): void
6565
{
6666
//
6767
}
@@ -72,7 +72,7 @@ public static function discoverPages(PageCollection $collection): void
7272
* at the end of the route discovery process. The collection instance
7373
* will be injected, so that you can interact with it directly.
7474
*/
75-
public static function discoverRoutes(RouteCollection $collection): void
75+
public function discoverRoutes(RouteCollection $collection): void
7676
{
7777
//
7878
}

packages/framework/src/Foundation/Concerns/ManagesExtensions.php

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use BadMethodCallException;
88
use InvalidArgumentException;
9+
use function array_keys;
910
use function array_map;
1011
use function array_merge;
1112
use function array_unique;
@@ -45,15 +46,50 @@ public function registerExtension(string $extension): void
4546
throw new InvalidArgumentException('The specified class must extend the HydeExtension class.');
4647
}
4748

48-
if (! in_array($extension, $this->extensions, true)) {
49-
$this->extensions[] = $extension;
49+
if (in_array($extension, $this->getRegisteredExtensions(), true)) {
50+
// While throwing an exception here is not required since we are using an associative array,
51+
// it may be helpful for the developer to know that their registration logic may be flawed.
52+
53+
throw new InvalidArgumentException("Extension [$extension] is already registered.");
54+
}
55+
56+
$this->extensions[$extension] = new $extension();
57+
}
58+
59+
/**
60+
* Get the singleton instance of the specified extension.
61+
*
62+
* @param class-string<\Hyde\Foundation\Concerns\HydeExtension> $extension
63+
*/
64+
public function getExtension(string $extension): HydeExtension
65+
{
66+
if (! isset($this->extensions[$extension])) {
67+
throw new InvalidArgumentException("Extension [$extension] is not registered.");
5068
}
69+
70+
return $this->extensions[$extension];
71+
}
72+
73+
/**
74+
* Determine if the specified extension is registered.
75+
*
76+
* @param class-string<\Hyde\Foundation\Concerns\HydeExtension> $extension
77+
*/
78+
public function hasExtension(string $extension): bool
79+
{
80+
return isset($this->extensions[$extension]);
81+
}
82+
83+
/** @return array<\Hyde\Foundation\Concerns\HydeExtension> */
84+
public function getExtensions(): array
85+
{
86+
return $this->extensions;
5187
}
5288

5389
/** @return array<class-string<\Hyde\Foundation\Concerns\HydeExtension>> */
5490
public function getRegisteredExtensions(): array
5591
{
56-
return $this->extensions;
92+
return array_keys($this->extensions);
5793
}
5894

5995
/** @return array<class-string<\Hyde\Pages\Concerns\HydePage>> */

packages/framework/src/Foundation/HydeKernel.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,16 +67,16 @@ class HydeKernel implements SerializableContract
6767

6868
protected bool $booted = false;
6969

70-
/** @var array<class-string<\Hyde\Foundation\Concerns\HydeExtension>> */
71-
protected array $extensions = [
72-
HydeCoreExtension::class,
73-
];
70+
/** @var array<class-string<\Hyde\Foundation\Concerns\HydeExtension>, \Hyde\Foundation\Concerns\HydeExtension> */
71+
protected array $extensions = [];
7472

7573
public function __construct(?string $basePath = null)
7674
{
7775
$this->setBasePath($basePath ?? getcwd());
7876
$this->filesystem = new Filesystem($this);
7977
$this->hyperlinks = new Hyperlinks($this);
78+
79+
$this->registerExtension(HydeCoreExtension::class);
8080
}
8181

8282
public static function version(): string
@@ -102,7 +102,7 @@ public function toArray(): array
102102
'sourceRoot' => $this->sourceRoot,
103103
'outputDirectory' => $this->outputDirectory,
104104
'mediaDirectory' => $this->mediaDirectory,
105-
'extensions' => $this->extensions,
105+
'extensions' => $this->getRegisteredExtensions(),
106106
'features' => $this->features(),
107107
'files' => $this->files(),
108108
'pages' => $this->pages(),

packages/framework/src/Foundation/Kernel/FileCollection.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ protected function runDiscovery(): self
7474
protected function runExtensionCallbacks(): self
7575
{
7676
/** @var class-string<\Hyde\Foundation\Concerns\HydeExtension> $extension */
77-
foreach ($this->kernel->getRegisteredExtensions() as $extension) {
78-
$extension::discoverFiles($this);
77+
foreach ($this->kernel->getExtensions() as $extension) {
78+
$extension->discoverFiles($this);
7979
}
8080

8181
return $this;

packages/framework/src/Foundation/Kernel/PageCollection.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ protected function runDiscovery(): self
7272
protected function runExtensionCallbacks(): self
7373
{
7474
/** @var class-string<\Hyde\Foundation\Concerns\HydeExtension> $extension */
75-
foreach ($this->kernel->getRegisteredExtensions() as $extension) {
76-
$extension::discoverPages($this);
75+
foreach ($this->kernel->getExtensions() as $extension) {
76+
$extension->discoverPages($this);
7777
}
7878

7979
return $this;

packages/framework/src/Foundation/Kernel/RouteCollection.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,8 @@ protected function runDiscovery(): self
9494
protected function runExtensionCallbacks(): self
9595
{
9696
/** @var class-string<\Hyde\Foundation\Concerns\HydeExtension> $extension */
97-
foreach ($this->kernel->getRegisteredExtensions() as $extension) {
98-
$extension::discoverRoutes($this);
97+
foreach ($this->kernel->getExtensions() as $extension) {
98+
$extension->discoverRoutes($this);
9999
}
100100

101101
return $this;

packages/framework/tests/Feature/HydeExtensionFeatureTest.php

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,30 @@ public function testHandlerMethodsAreCalledByDiscovery()
5757
HydeTestExtension::$callCache = [];
5858
}
5959

60+
public function testFileHandlerDependencyInjection()
61+
{
62+
$this->kernel->registerExtension(InspectableTestExtension::class);
63+
$this->kernel->boot();
64+
65+
$this->assertInstanceOf(FileCollection::class, ...InspectableTestExtension::getCalled('files'));
66+
}
67+
68+
public function testPageHandlerDependencyInjection()
69+
{
70+
$this->kernel->registerExtension(InspectableTestExtension::class);
71+
$this->kernel->boot();
72+
73+
$this->assertInstanceOf(PageCollection::class, ...InspectableTestExtension::getCalled('pages'));
74+
}
75+
76+
public function testRouteHandlerDependencyInjection()
77+
{
78+
$this->kernel->registerExtension(InspectableTestExtension::class);
79+
$this->kernel->boot();
80+
81+
$this->assertInstanceOf(RouteCollection::class, ...InspectableTestExtension::getCalled('routes'));
82+
}
83+
6084
public function test_register_extension_method_throws_exception_when_kernel_is_already_booted()
6185
{
6286
$this->expectException(BadMethodCallException::class);
@@ -128,17 +152,17 @@ public static function getPageClasses(): array
128152
];
129153
}
130154

131-
public static function discoverFiles(FileCollection $collection): void
155+
public function discoverFiles(FileCollection $collection): void
132156
{
133157
static::$callCache[] = 'files';
134158
}
135159

136-
public static function discoverPages(PageCollection $collection): void
160+
public function discoverPages(PageCollection $collection): void
137161
{
138162
static::$callCache[] = 'pages';
139163
}
140164

141-
public static function discoverRoutes(RouteCollection $collection): void
165+
public function discoverRoutes(RouteCollection $collection): void
142166
{
143167
static::$callCache[] = 'routes';
144168
}
@@ -177,3 +201,28 @@ public static function getPageClasses(): array
177201
];
178202
}
179203
}
204+
205+
class InspectableTestExtension extends HydeExtension
206+
{
207+
private static array $callCache = [];
208+
209+
public function discoverFiles(FileCollection $collection): void
210+
{
211+
self::$callCache['files'] = func_get_args();
212+
}
213+
214+
public function discoverPages(PageCollection $collection): void
215+
{
216+
self::$callCache['pages'] = func_get_args();
217+
}
218+
219+
public function discoverRoutes(RouteCollection $collection): void
220+
{
221+
self::$callCache['routes'] = func_get_args();
222+
}
223+
224+
public static function getCalled(string $method): array
225+
{
226+
return self::$callCache[$method];
227+
}
228+
}

0 commit comments

Comments
 (0)