Skip to content

Commit 9bd17d9

Browse files
authored
Merge pull request #632 from flightphp/event-handler
Added an event system
2 parents fe3e78a + 046a034 commit 9bd17d9

4 files changed

Lines changed: 320 additions & 3 deletions

File tree

flight/Engine.php

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use ErrorException;
99
use Exception;
1010
use flight\core\Dispatcher;
11+
use flight\core\EventDispatcher;
1112
use flight\core\Loader;
1213
use flight\net\Request;
1314
use flight\net\Response;
@@ -51,6 +52,10 @@
5152
* @method void render(string $file, ?array<string,mixed> $data = null, ?string $key = null) Renders template
5253
* @method View view() Gets current view
5354
*
55+
* # Events
56+
* @method void onEvent(string $event, callable $callback) Registers a callback for an event.
57+
* @method void triggerEvent(string $event, ...$args) Triggers an event.
58+
*
5459
* # Request-Response
5560
* @method Request request() Gets current request
5661
* @method Response response() Gets current response
@@ -79,7 +84,8 @@ class Engine
7984
private const MAPPABLE_METHODS = [
8085
'start', 'stop', 'route', 'halt', 'error', 'notFound',
8186
'render', 'redirect', 'etag', 'lastModified', 'json', 'jsonHalt', 'jsonp',
82-
'post', 'put', 'patch', 'delete', 'group', 'getUrl', 'download', 'resource'
87+
'post', 'put', 'patch', 'delete', 'group', 'getUrl', 'download', 'resource',
88+
'onEvent', 'triggerEvent'
8389
];
8490

8591
/** @var array<string, mixed> Stored variables. */
@@ -88,9 +94,12 @@ class Engine
8894
/** Class loader. */
8995
protected Loader $loader;
9096

91-
/** Event dispatcher. */
97+
/** Method and class dispatcher. */
9298
protected Dispatcher $dispatcher;
9399

100+
/** Event dispatcher. */
101+
protected EventDispatcher $eventDispatcher;
102+
94103
/** If the framework has been initialized or not. */
95104
protected bool $initialized = false;
96105

@@ -101,6 +110,7 @@ public function __construct()
101110
{
102111
$this->loader = new Loader();
103112
$this->dispatcher = new Dispatcher();
113+
$this->eventDispatcher = new EventDispatcher();
104114
$this->init();
105115
}
106116

@@ -493,6 +503,8 @@ public function _start(): void
493503
$this->router()->reset();
494504
}
495505
$request = $this->request();
506+
$this->triggerEvent('flight.request.received', $request);
507+
496508
$response = $this->response();
497509
$router = $this->router();
498510

@@ -515,6 +527,7 @@ public function _start(): void
515527
// Route the request
516528
$failedMiddlewareCheck = false;
517529
while ($route = $router->route($request)) {
530+
$this->triggerEvent('flight.route.matched', $route);
518531
$params = array_values($route->params);
519532

520533
// Add route info to the parameter list
@@ -548,6 +561,7 @@ public function _start(): void
548561
$failedMiddlewareCheck = true;
549562
break;
550563
}
564+
$this->triggerEvent('flight.route.middleware.before', $route);
551565
}
552566

553567
$useV3OutputBuffering =
@@ -563,6 +577,7 @@ public function _start(): void
563577
$route->callback,
564578
$params
565579
);
580+
$this->triggerEvent('flight.route.executed', $route);
566581

567582
if ($useV3OutputBuffering === true) {
568583
$response->write(ob_get_clean());
@@ -577,6 +592,7 @@ public function _start(): void
577592
$failedMiddlewareCheck = true;
578593
break;
579594
}
595+
$this->triggerEvent('flight.route.middleware.after', $route);
580596
}
581597

582598
$dispatched = true;
@@ -662,6 +678,8 @@ public function _stop(?int $code = null): void
662678
}
663679

664680
$response->send();
681+
682+
$this->triggerEvent('flight.response.sent', $response);
665683
}
666684
}
667685

@@ -992,4 +1010,26 @@ public function _getUrl(string $alias, array $params = []): string
9921010
{
9931011
return $this->router()->getUrlByAlias($alias, $params);
9941012
}
1013+
1014+
/**
1015+
* Adds an event listener.
1016+
*
1017+
* @param string $eventName The name of the event to listen to
1018+
* @param callable $callback The callback to execute when the event is triggered
1019+
*/
1020+
public function _onEvent(string $eventName, callable $callback): void
1021+
{
1022+
$this->eventDispatcher->on($eventName, $callback);
1023+
}
1024+
1025+
/**
1026+
* Triggers an event.
1027+
*
1028+
* @param string $eventName The name of the event to trigger
1029+
* @param mixed ...$args The arguments to pass to the event listeners
1030+
*/
1031+
public function _triggerEvent(string $eventName, ...$args): void
1032+
{
1033+
$this->eventDispatcher->trigger($eventName, ...$args);
1034+
}
9951035
}

flight/Flight.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,15 @@
4646
* Adds standardized RESTful routes for a controller.
4747
* @method static Router router() Returns Router instance.
4848
* @method static string getUrl(string $alias, array<string, mixed> $params = []) Gets a url from an alias
49-
*
5049
* @method static void map(string $name, callable $callback) Creates a custom framework method.
5150
*
51+
* # Filters
5252
* @method static void before(string $name, Closure(array<int, mixed> &$params, string &$output): (void|false) $callback)
5353
* Adds a filter before a framework method.
5454
* @method static void after(string $name, Closure(array<int, mixed> &$params, string &$output): (void|false) $callback)
5555
* Adds a filter after a framework method.
5656
*
57+
* # Variables
5758
* @method static void set(string|iterable<string, mixed> $key, mixed $value) Sets a variable.
5859
* @method static mixed get(?string $key) Gets a variable.
5960
* @method static bool has(string $key) Checks if a variable is set.
@@ -64,6 +65,10 @@
6465
* Renders a template file.
6566
* @method static View view() Returns View instance.
6667
*
68+
* # Events
69+
* @method void onEvent(string $event, callable $callback) Registers a callback for an event.
70+
* @method void triggerEvent(string $event, ...$args) Triggers an event.
71+
*
6772
* # Request-Response
6873
* @method static Request request() Returns Request instance.
6974
* @method static Response response() Returns Response instance.

flight/core/EventDispatcher.php

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace flight\core;
6+
7+
class EventDispatcher
8+
{
9+
/** @var array<string, array<int, callable>> */
10+
protected array $listeners = [];
11+
12+
/**
13+
* Register a callback for an event.
14+
*
15+
* @param string $event Event name
16+
* @param callable $callback Callback function
17+
*/
18+
public function on(string $event, callable $callback): void
19+
{
20+
if (isset($this->listeners[$event]) === false) {
21+
$this->listeners[$event] = [];
22+
}
23+
$this->listeners[$event][] = $callback;
24+
}
25+
26+
/**
27+
* Trigger an event with optional arguments.
28+
*
29+
* @param string $event Event name
30+
* @param mixed ...$args Arguments to pass to the callbacks
31+
*/
32+
public function trigger(string $event, ...$args): void
33+
{
34+
if (isset($this->listeners[$event]) === true) {
35+
foreach ($this->listeners[$event] as $callback) {
36+
$result = call_user_func_array($callback, $args);
37+
38+
// If you return false, it will break the loop and stop the other event listeners.
39+
if ($result === false) {
40+
break; // Stop executing further listeners
41+
}
42+
}
43+
}
44+
}
45+
}

0 commit comments

Comments
 (0)