jf / event
Sistema de eventos PSR-14
2.0.1
2023-07-29 15:50 UTC
Requires
- psr/event-dispatcher: ^1.0
This package is auto-updated.
Last update: 2024-04-29 17:27:53 UTC
README
Sistema de eventos PSR-14.
Instalación
Composer
Este proyecto usa como gestor de dependencias Composer el cual puede ser instalado siguiendo las instrucciones especificadas en la documentación oficial del proyecto.
Para instalar el paquete jf/event
usando este manejador de paquetes se debe ejecutar:
composer require jf/event
Dependencias
Cuando el proyecto es instalado, adicionalmente se instalan las siguientes dependencias:
Paquete | Versión |
---|---|
psr/event-dispatcher | ^1.0 |
Control de versiones
Este proyecto puede ser instalado usando git
. Primero se debe clonar el proyecto y luego instalar las dependencias:
git clone git@gitlab.com:joaquinfq/jfEvent.git
cd jfEvent
composer install
Archivos disponibles
Clases
Nombre | Descripción |
---|---|
jf\event\Event | Clase simple para eventos genéricos. |
jf\event\Manager | Manejador simple de eventos. |
jf\event\Proxy | Evento genérico usado como proxy al objeto almacenado en subject en aquellos caso en los que se quiera pasar al update de los observadores el evento directamente. |
Interfaces
Nombre | Descripción |
---|---|
jf\event\IEvent | Interfaz para los eventos que se emiten. |
jf\event\IObserver | Interfaz para los observadores de los eventos. |
jf\event\ISubject | Interfaz para los emisores de eventos. |
Traits
Nombre | Descripción |
---|---|
jf\event\TDispatcher | Trait que facilita la implementación de las interfaces SplSubject , Psr\EventDispatcher\EventDispatcherInterface y Psr\EventDispatcher\ListenerProviderInterface . |
jf\event\TEvent | Trait para implementar la interfaz IEvent . |
jf\event\TEventDispatcher | Trait que implementa las interfaces Psr\EventDispatcher\EventDispatcherInterface y Psr\EventDispatcher\ListenerProviderInterface . |
jf\event\TObservers | Gestiona la lista de observadores de los eventos. |
jf\event\TSplSubject | Trait que implementa la interfaz SplSubject . |
jf\event\TStoppable | Trait que implementa la interfaz Psr\EventDispatcher\StoppableEventInterface . |
Demos
demos/events.php
Demostración complera del uso de eventos y observadores tanto SPL como jf/event
.
<?php
use jf\event\Event;
use jf\event\IObserver;
use jf\event\Manager;
use jf\event\TSplSubject;
require_once __DIR__. '/../vendor/autoload.php';
/**
* Trait para simplificar la creación de los observadores.
*/
trait TLogObserver
{
/**
* @inheritdoc
*/
public function update(SplSubject $subject) : void
{
global $counter;
if ($subject instanceof LogEvent || $subject instanceof LogEventSplSubject)
{
printf("%d %s(%s -- %s)\n", $counter++, static::class, $subject::class, $subject->message);
}
else if ($subject instanceof Manager)
{
// Se entra aquí si se usa `$manager->notify()`.
printf("%d %s(%s)\n", $counter++, static::class, $subject::class);
}
}
}
/**
* Evento para registar una traza.
*/
trait TLogEvent
{
/**
* Constructor de la clase.
*
* @param string $message Mensaje de la traza.
*/
public function __construct(public readonly string $message)
{
}
}
/**
* Evento para registar una traza.
*/
class LogEvent extends Event
{
use TLogEvent;
}
/**
* Evento para registar una traza.
*/
class LogEventSplSubject implements SplSubject
{
use TLogEvent;
use TSplSubject;
}
/**
* Observador para detectar la solicitud de registro de traza y mostrarla por pantalla
* pero podría almacenarse en disco, base de datos, etc., usando otros observadores.
*
* Usando IObserver
*/
readonly class LogObserver implements IObserver
{
use TLogObserver;
/**
* @inheritdoc
*/
public function observedEvents() : array
{
return [ LogEvent::class, LogEventSplSubject::class ];
}
}
/**
* Observador para detectar la solicitud de registro de traza y mostrarla por pantalla
* pero podría almacenarse en disco, base de datos, etc., usando otros observadores.
*
* Usando SplObserver
*/
readonly class LogSplObserver implements SplObserver
{
use TLogObserver;
}
//----------------------------------------------------------------------------------------------------------------------
// Inicio del script
//----------------------------------------------------------------------------------------------------------------------
// Opción 1: Usando el manager y cpm la configuración de eventos y observadores.
//----------------------------------------------------------------------------------------------------------------------
$counter = 1;
$manager = new Manager(
[
LogEvent::class => [ LogObserver::class, LogSplObserver::class ],
LogEventSplSubject::class => [ LogObserver::class, LogSplObserver::class ]
]
);
$manager->dispatch(new LogEvent('Opción 1'));
$manager->dispatch(new LogEventSplSubject('Opción 1'));
$manager->notify(); // No se ha usado `attach` así que no ejecuta ningún observador SPL
//----------------------------------------------------------------------------------------------------------------------
// Resultado por pantalla:
//----------------------------------------------------------------------------------------------------------------------
// 1 LogObserver(LogEvent -- Opción 1)
// 2 LogSplObserver(LogEvent -- Opción 1)
// 3 LogObserver(LogEventSplSubject -- Opción 1)
// 4 LogObserver(LogEventSplSubject -- Opción 1)
// 5 LogSplObserver(LogEventSplSubject -- Opción 1)
// 6 LogObserver(jf\event\Manager) <-- notify()
// 7 LogSplObserver(jf\event\Manager) <-- notify()
// 8 LogObserver(jf\event\Manager) <-- notify()
// 9 LogSplObserver(jf\event\Manager) <-- notify()
//----------------------------------------------------------------------------------------------------------------------
// Las lineas 3 y 4 se repiten por pasar el nombre de una clase IEvent y llamarse a observedEvents().
// Al llamar a `notify()` se llamarán a tantos observadores como nombres de clases de observadores se pasaron, en este
// caso 2 para LogEvent y 2 para LogEventSplSubject.
// Si en vez de pasar nombres de clases sino instancias se eliminan algunas de esas duplicidades.
//----------------------------------------------------------------------------------------------------------------------
// Opción 2: Agregando manualmente los eventos y sus observadores.
// Usando `attach` el manager trabaja solamente con IObserver para poder obtener los nombres de los eventos a escuchar.
// El resto debe llamarse con `nofity()`.
//----------------------------------------------------------------------------------------------------------------------
$manager = new Manager();
$manager->attach(new LogObserver());
$manager->attach(new LogSplObserver()); // No observará eventos al no ser IEvent, se usa con `notify()`
$manager->dispatch(new LogEvent('Opción 2'));
$manager->dispatch(new LogEventSplSubject('Opción 2'));
$manager->notify(); // Ejecuta los observadores SPL agregados con attach.
//----------------------------------------------------------------------------------------------------------------------
// Resultado por pantalla:
//----------------------------------------------------------------------------------------------------------------------
// 10 LogObserver(LogEvent -- Opción 2)
// 11 LogObserver(LogEventSplSubject -- Opción 2)
// 12 LogObserver(jf\event\Manager) <-- notify()
// 13 LogSplObserver(jf\event\Manager) <-- notify()
//----------------------------------------------------------------------------------------------------------------------
// Opción 3: Usando SPL
//----------------------------------------------------------------------------------------------------------------------
$subject = new LogEventSplSubject('Opción 3');
$subject->attach(new LogSplObserver());
$subject->attach(new LogObserver());
$subject->notify();
//----------------------------------------------------------------------------------------------------------------------
// Resultado por pantalla:
//----------------------------------------------------------------------------------------------------------------------
// 14 LogSplObserver(LogEventSplSubject -- Opción 3)
// 15 LogObserver(LogEventSplSubject -- Opción 3)