Initialize Nest events library.
This commit is contained in:
commit
fcb3e114a7
6 changed files with 216 additions and 0 deletions
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
# IDEA
|
||||||
|
.idea/
|
||||||
|
*.iml
|
||||||
|
|
||||||
|
# Composer
|
||||||
|
vendor/
|
27
composer.json
Normal file
27
composer.json
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"version": "1.0",
|
||||||
|
"name": "nest/events",
|
||||||
|
"description": "Nest events implementation.",
|
||||||
|
"type": "library",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Madeorsk",
|
||||||
|
"email": "madeorsk@protonmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Nest\\Events\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"repositories": [
|
||||||
|
{
|
||||||
|
"type": "vcs",
|
||||||
|
"url": "https://code.zeptotech.net/Nest/Core"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"require": {
|
||||||
|
"php": "^8.3",
|
||||||
|
"nest/core": "dev-main"
|
||||||
|
}
|
||||||
|
}
|
56
composer.lock
generated
Normal file
56
composer.lock
generated
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
{
|
||||||
|
"_readme": [
|
||||||
|
"This file locks the dependencies of your project to a known state",
|
||||||
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
|
"This file is @generated automatically"
|
||||||
|
],
|
||||||
|
"content-hash": "4185bcac56ba1943814494a50cebd442",
|
||||||
|
"packages": [
|
||||||
|
{
|
||||||
|
"name": "nest/core",
|
||||||
|
"version": "dev-main",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://code.zeptotech.net/Nest/Core",
|
||||||
|
"reference": "22296b8d7c8b528089189a8d9500395424cb6468"
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": "^8.3"
|
||||||
|
},
|
||||||
|
"default-branch": true,
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Nest\\": "src/"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"src/Utils/Array.php",
|
||||||
|
"src/Utils/Paths.php",
|
||||||
|
"src/Utils/Reflection.php",
|
||||||
|
"src/Utils/String.php"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Madeorsk",
|
||||||
|
"email": "madeorsk@protonmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Nest framework core.",
|
||||||
|
"time": "2024-11-08T11:12:38+00:00"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"packages-dev": [],
|
||||||
|
"aliases": [],
|
||||||
|
"minimum-stability": "stable",
|
||||||
|
"stability-flags": {
|
||||||
|
"nest/core": 20
|
||||||
|
},
|
||||||
|
"prefer-stable": false,
|
||||||
|
"prefer-lowest": false,
|
||||||
|
"platform": {
|
||||||
|
"php": "^8.3"
|
||||||
|
},
|
||||||
|
"platform-dev": {},
|
||||||
|
"plugin-api-version": "2.6.0"
|
||||||
|
}
|
7
src/Event.php
Normal file
7
src/Event.php
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Nest\Events;
|
||||||
|
|
||||||
|
abstract class Event
|
||||||
|
{
|
||||||
|
}
|
81
src/EventsManager.php
Normal file
81
src/EventsManager.php
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Nest\Events;
|
||||||
|
|
||||||
|
use Nest\Exceptions\InvalidTypeException;
|
||||||
|
use function Nest\Utils\expect_type;
|
||||||
|
use function Nest\Utils\get_all_classes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Events manager class.
|
||||||
|
*/
|
||||||
|
class EventsManager
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Events listeners.
|
||||||
|
* If false is returned, stop event propagation.
|
||||||
|
* @var array<class-string, (callable(Event $event): (void|bool))[]>
|
||||||
|
*/
|
||||||
|
protected array $listeners = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an event listener to the listeners list.
|
||||||
|
* @template T of Event
|
||||||
|
* @param class-string<T> $eventType The event type class to listen for.
|
||||||
|
* @param callable(T $event): (void|bool) $listener The event listener to add. If false is returned, stop event propagation.
|
||||||
|
* @return void
|
||||||
|
* @throws InvalidTypeException
|
||||||
|
*/
|
||||||
|
public function addListener(string $eventType, callable $listener): void
|
||||||
|
{
|
||||||
|
expect_type($eventType, Event::class);
|
||||||
|
|
||||||
|
// Initialize the listeners list if it's empty.
|
||||||
|
if (empty($this->listeners[$eventType])) $this->listeners[$eventType] = [];
|
||||||
|
// Add the listener.
|
||||||
|
$this->listeners[$eventType][] = $listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the given listener from the listeners list.
|
||||||
|
* @template T of Event
|
||||||
|
* @param class-string<T> $eventType The event type class.
|
||||||
|
* @param callable(T $event): (void|bool) $listener The listener to remove.
|
||||||
|
* @return void
|
||||||
|
* @throws InvalidTypeException
|
||||||
|
*/
|
||||||
|
public function removeListener(string $eventType, callable $listener): void
|
||||||
|
{
|
||||||
|
expect_type($eventType, Event::class);
|
||||||
|
|
||||||
|
if (!empty($this->listeners[$eventType]))
|
||||||
|
{
|
||||||
|
foreach ($this->listeners[$eventType] as $key => $currentListener)
|
||||||
|
{ // For each listeners, if it's matching the given one, remove it.
|
||||||
|
if ($currentListener == $listener) unset($this->listeners[$eventType][$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fire an event.
|
||||||
|
* @param Event $event The event to fire.
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function fire(Event $event): void
|
||||||
|
{
|
||||||
|
foreach (get_all_classes($event) as $className)
|
||||||
|
{ // For each class, from the most specific to the least specific.
|
||||||
|
if (!empty($this->listeners[$className]))
|
||||||
|
{ // If there are listeners for the current class.
|
||||||
|
foreach ($this->listeners[$className] as $listener)
|
||||||
|
{ // Call each listener.
|
||||||
|
$result = $listener($event);
|
||||||
|
if ($result === false)
|
||||||
|
// If the result is false, stop firing.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
39
src/HasEvents.php
Normal file
39
src/HasEvents.php
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Nest\Events;
|
||||||
|
|
||||||
|
use Nest\Exceptions\InvalidTypeException;
|
||||||
|
|
||||||
|
trait HasEvents
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Events manager instance.
|
||||||
|
* @var EventsManager
|
||||||
|
*/
|
||||||
|
private EventsManager $eventsManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current instance of the events manager.
|
||||||
|
* @return EventsManager - The events manager.
|
||||||
|
*/
|
||||||
|
protected function getEventsManager(): EventsManager
|
||||||
|
{
|
||||||
|
// If there is no instance, initializing one.
|
||||||
|
if (empty($this->eventsManager)) $this->eventsManager = new EventsManager();
|
||||||
|
|
||||||
|
return $this->eventsManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a listener for the given event type.
|
||||||
|
* @template T of Event
|
||||||
|
* @param class-string<T> $eventType The event type class to listen for.
|
||||||
|
* @param callable(T $event): (void|bool) $eventListener The event listener. If false is returned, stop event propagation.
|
||||||
|
* @return void
|
||||||
|
* @throws InvalidTypeException
|
||||||
|
*/
|
||||||
|
public function listen(string $eventType, callable $eventListener): void
|
||||||
|
{
|
||||||
|
$this->getEventsManager()->addListener($eventType, $eventListener);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue