-
-
Notifications
You must be signed in to change notification settings - Fork 366
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1700 from brefphp/more-hooks
Rework the low-level hook system used by framework integrations
- Loading branch information
Showing
9 changed files
with
239 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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 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 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 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 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,59 @@ | ||
<?php declare(strict_types=1); | ||
|
||
namespace Bref\Listener; | ||
|
||
use Bref\Context\Context; | ||
// @phpcs:disable | ||
use Bref\Event\Handler; | ||
use Psr\Http\Server\RequestHandlerInterface; | ||
|
||
/** | ||
* Listen to Bref internal events. | ||
* | ||
* Warning: Bref events are low-level extension points to be used by framework | ||
* integrations. For user code, it is not recommended to use them. Use your | ||
* framework's extension points instead. | ||
* | ||
* @internal This API is experimental and may change at any time. | ||
*/ | ||
abstract class BrefEventSubscriber | ||
{ | ||
/** | ||
* Register a hook to be executed before the runtime starts. | ||
*/ | ||
public function beforeStartup(): void | ||
{ | ||
} | ||
|
||
/** | ||
* Register a hook to be executed after the runtime has started. | ||
*/ | ||
public function afterStartup(): void | ||
{ | ||
} | ||
|
||
/** | ||
* Register a hook to be executed before any Lambda invocation. | ||
*/ | ||
public function beforeInvoke( | ||
callable | Handler | RequestHandlerInterface $handler, | ||
mixed $event, | ||
Context $context, | ||
): void { | ||
} | ||
|
||
/** | ||
* Register a hook to be executed after any Lambda invocation. | ||
* | ||
* In case of an error, the `$error` parameter will be set and | ||
* `$result` will be `null`. | ||
*/ | ||
public function afterInvoke( | ||
callable | Handler | RequestHandlerInterface $handler, | ||
mixed $event, | ||
Context $context, | ||
mixed $result, | ||
\Throwable | null $error = null, | ||
): void { | ||
} | ||
} |
This file contains 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,86 @@ | ||
<?php declare(strict_types=1); | ||
|
||
namespace Bref\Listener; | ||
|
||
use Bref\Context\Context; | ||
// @phpcs:disable | ||
use Bref\Event\Handler; | ||
use Psr\Http\Server\RequestHandlerInterface; | ||
|
||
/** | ||
* @internal This API is experimental and may change at any time. | ||
*/ | ||
final class EventDispatcher extends BrefEventSubscriber | ||
{ | ||
/** | ||
* @param BrefEventSubscriber[] $subscribers | ||
*/ | ||
public function __construct( | ||
private array $subscribers = [], | ||
) { | ||
} | ||
|
||
/** | ||
* Register an event subscriber class. | ||
*/ | ||
public function subscribe(BrefEventSubscriber $subscriber): void | ||
{ | ||
$this->subscribers[] = $subscriber; | ||
} | ||
|
||
/** | ||
* Trigger the `beforeStartup` event. | ||
* | ||
* @internal This method is called by Bref and should not be called by user code. | ||
*/ | ||
public function beforeStartup(): void | ||
{ | ||
foreach ($this->subscribers as $listener) { | ||
$listener->beforeStartup(); | ||
} | ||
} | ||
|
||
/** | ||
* Trigger the `afterStartup` event. | ||
* | ||
* @internal This method is called by Bref and should not be called by user code. | ||
*/ | ||
public function afterStartup(): void | ||
{ | ||
foreach ($this->subscribers as $listener) { | ||
$listener->afterStartup(); | ||
} | ||
} | ||
|
||
/** | ||
* Trigger the `beforeInvoke` event. | ||
* | ||
* @internal This method is called by Bref and should not be called by user code. | ||
*/ | ||
public function beforeInvoke( | ||
callable | Handler | RequestHandlerInterface $handler, | ||
mixed $event, | ||
Context $context, | ||
): void { | ||
foreach ($this->subscribers as $listener) { | ||
$listener->beforeInvoke($handler, $event, $context); | ||
} | ||
} | ||
|
||
/** | ||
* Trigger the `afterInvoke` event. | ||
* | ||
* @internal This method is called by Bref and should not be called by user code. | ||
*/ | ||
public function afterInvoke( | ||
callable | Handler | RequestHandlerInterface $handler, | ||
mixed $event, | ||
Context $context, | ||
mixed $result, | ||
\Throwable | null $error = null, | ||
): void { | ||
foreach ($this->subscribers as $listener) { | ||
$listener->afterInvoke($handler, $event, $context, $result, $error); | ||
} | ||
} | ||
} |
This file contains 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 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,31 @@ | ||
<?php declare(strict_types=1); | ||
|
||
namespace Bref\Test\Listener; | ||
|
||
use Bref\Context\Context; | ||
use Bref\Listener\EventDispatcher; | ||
use PHPUnit\Framework\TestCase; | ||
use stdClass; | ||
|
||
class EventDispatcherTest extends TestCase | ||
{ | ||
public function test subscribe(): void | ||
{ | ||
$eventDispatcher = new EventDispatcher; | ||
$subscriber = new FakeSubscriber; | ||
$eventDispatcher->subscribe($subscriber); | ||
|
||
$eventDispatcher->beforeStartup(); | ||
$this->assertTrue($subscriber->invokedBeforeStartup); | ||
|
||
$handler = fn () => null; | ||
$event = new stdClass; | ||
$context = Context::fake(); | ||
$eventDispatcher->beforeInvoke($handler, $event, $context); | ||
$this->assertEquals([$handler, $event, $context], $subscriber->invokedBeforeInvoke); | ||
|
||
$result = new stdClass; | ||
$eventDispatcher->afterInvoke($handler, $event, $context, $result); | ||
$this->assertEquals([$handler, $event, $context, $result, null], $subscriber->invokedAfterInvoke); | ||
} | ||
} |
This file contains 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,33 @@ | ||
<?php declare(strict_types=1); | ||
|
||
namespace Bref\Test\Listener; | ||
|
||
use Bref\Listener\BrefEventSubscriber; | ||
|
||
class FakeSubscriber extends BrefEventSubscriber | ||
{ | ||
public bool $invokedBeforeStartup = false; | ||
public mixed $invokedBeforeInvoke = null; | ||
public mixed $invokedAfterInvoke = null; | ||
|
||
public function beforeStartup(): void | ||
{ | ||
$this->invokedBeforeStartup = true; | ||
} | ||
|
||
/** | ||
* @param mixed ...$params | ||
*/ | ||
public function beforeInvoke(...$params): void | ||
{ | ||
$this->invokedBeforeInvoke = $params; | ||
} | ||
|
||
/** | ||
* @param mixed ...$params | ||
*/ | ||
public function afterInvoke(...$params): void | ||
{ | ||
$this->invokedAfterInvoke = $params; | ||
} | ||
} |