Sistema de eventos de XOOPS
2.5.x: Precargas 4.0.x: PSR-14
Descripción general
Sección titulada «Descripción general»El sistema de eventos de XOOPS permite un acoplamiento débil entre módulos a través de un patrón observador. Los componentes pueden emitir eventos que otras partes del sistema pueden escuchar y responder.
Tipos de eventos
Sección titulada «Tipos de eventos»Eventos principales
Sección titulada «Eventos principales»| Evento | Punto de disparo |
|---|---|
core.header.start | Antes del procesamiento del encabezado |
core.header.end | Después del procesamiento del encabezado |
core.footer.start | Antes de renderizar el pie de página |
core.footer.end | Después de renderizar el pie de página |
core.exception | Cuando ocurre una excepción |
Eventos del ciclo de vida del módulo
Sección titulada «Eventos del ciclo de vida del módulo»| Evento | Punto de disparo |
|---|---|
module.install | Después de instalar el módulo |
module.update | Después de actualizar el módulo |
module.uninstall | Antes de eliminar el módulo |
module.activate | Cuando el módulo se activa |
module.deactivate | Cuando el módulo se desactiva |
Eventos de usuario
Sección titulada «Eventos de usuario»| Evento | Punto de disparo |
|---|---|
user.login | Después de iniciar sesión exitosamente |
user.logout | Después de cerrar sesión |
user.register | Después del registro |
user.delete | Antes de eliminar el usuario |
Sistema de precargas (heredado)
Sección titulada «Sistema de precargas (heredado)»Creación de una precarga
Sección titulada «Creación de una precarga»<?phpnamespace XoopsModules\MyModule;
use Xmf\Module\Helper\AbstractHelper;
final class Preload extends AbstractHelper{ public function eventCoreHeaderStart(array $args): void { // Se ejecuta en cada página antes del encabezado }
public function eventCoreFooterStart(array $args): void { // Se ejecuta antes de que se renderice el pie de página }
public function eventUserLogin(array $args): void { $userId = $args['userid']; // Manejar evento de inicio de sesión }
public function eventCoreException(array $args): void { $exception = $args['exception']; // Registrar o manejar excepción }}Nomenclatura del método de evento
Sección titulada «Nomenclatura del método de evento»event{Category}{Action}
Ejemplos:- eventCoreHeaderStart- eventUserLogin- eventModuleNewsArticleCreateDespachador de eventos PSR-14 (XOOPS 4.0)
Sección titulada «Despachador de eventos PSR-14 (XOOPS 4.0)»Clase de evento
Sección titulada «Clase de evento»<?php
declare(strict_types=1);
namespace XoopsModules\MyModule\Event;
final class ArticleCreatedEvent{ public function __construct( public readonly int $articleId, public readonly int $authorId, public readonly string $title, public readonly \DateTimeImmutable $createdAt ) {}}Despachando eventos
Sección titulada «Despachando eventos»use Psr\EventDispatcher\EventDispatcherInterface;
final class ArticleService{ public function __construct( private readonly ArticleRepository $repository, private readonly EventDispatcherInterface $dispatcher ) {}
public function create(CreateArticleDTO $dto): Article { $article = Article::create($dto); $this->repository->save($article);
// Despachar evento $this->dispatcher->dispatch(new ArticleCreatedEvent( articleId: $article->getId(), authorId: $article->getAuthorId(), title: $article->getTitle(), createdAt: new \DateTimeImmutable() ));
return $article; }}Escuchador de eventos
Sección titulada «Escuchador de eventos»<?php
declare(strict_types=1);
namespace XoopsModules\MyModule\Listener;
use XoopsModules\MyModule\Event\ArticleCreatedEvent;
final class SendNotificationOnArticleCreated{ public function __construct( private readonly NotificationService $notifications ) {}
public function __invoke(ArticleCreatedEvent $event): void { $this->notifications->notifySubscribers( 'new_article', [ 'article_id' => $event->articleId, 'title' => $event->title, ] ); }}Registrar escuchadores
Sección titulada «Registrar escuchadores»return [ ArticleCreatedEvent::class => [ SendNotificationOnArticleCreated::class, UpdateSearchIndex::class, ClearArticleCache::class, ],
ArticleUpdatedEvent::class => [ UpdateSearchIndex::class, ClearArticleCache::class, ],
ArticleDeletedEvent::class => [ RemoveFromSearchIndex::class, ClearArticleCache::class, ],];Eventos detenibles
Sección titulada «Eventos detenibles»use Psr\EventDispatcher\StoppableEventInterface;
final class ArticlePublishingEvent implements StoppableEventInterface{ private bool $propagationStopped = false; private ?string $rejectionReason = null;
public function __construct( public readonly Article $article ) {}
public function isPropagationStopped(): bool { return $this->propagationStopped; }
public function reject(string $reason): void { $this->propagationStopped = true; $this->rejectionReason = $reason; }
public function getRejectionReason(): ?string { return $this->rejectionReason; }}
// El escuchador puede detener la propagaciónfinal class ContentModerationListener{ public function __invoke(ArticlePublishingEvent $event): void { if ($this->containsProhibitedContent($event->article)) { $event->reject('El contenido viola las directrices de la comunidad'); } }}Mejores prácticas
Sección titulada «Mejores prácticas»- Eventos inmutables - Los eventos deben ser de solo lectura
- Eventos específicos - Crear eventos específicos, no genéricos
- Asincrón cuando sea posible - Usar colas para operaciones lentas
- Sin efectos secundarios en el envío - El envío debe ser rápido
- Documentar eventos - Listar eventos disponibles para usuarios del módulo
Documentación relacionada
Sección titulada «Documentación relacionada»- Desarrollo de módulos - Desarrollo de módulos
- Guía del sistema de eventos - Guía PSR-14
- Ganchos-Eventos - Ganchos heredados
- Eventos-y-Ganchos - Ejemplos de eventos