Ir al contenido

Sistema de eventos de XOOPS

2.5.x: Precargas 4.0.x: PSR-14

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.

EventoPunto de disparo
core.header.startAntes del procesamiento del encabezado
core.header.endDespués del procesamiento del encabezado
core.footer.startAntes de renderizar el pie de página
core.footer.endDespués de renderizar el pie de página
core.exceptionCuando ocurre una excepción
EventoPunto de disparo
module.installDespués de instalar el módulo
module.updateDespués de actualizar el módulo
module.uninstallAntes de eliminar el módulo
module.activateCuando el módulo se activa
module.deactivateCuando el módulo se desactiva
EventoPunto de disparo
user.loginDespués de iniciar sesión exitosamente
user.logoutDespués de cerrar sesión
user.registerDespués del registro
user.deleteAntes de eliminar el usuario
class/Preload.php
<?php
namespace 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
}
}
event{Category}{Action}
Ejemplos:
- eventCoreHeaderStart
- eventUserLogin
- eventModuleNewsArticleCreate
<?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
) {}
}
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;
}
}
<?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,
]
);
}
}
config/events.php
return [
ArticleCreatedEvent::class => [
SendNotificationOnArticleCreated::class,
UpdateSearchIndex::class,
ClearArticleCache::class,
],
ArticleUpdatedEvent::class => [
UpdateSearchIndex::class,
ClearArticleCache::class,
],
ArticleDeletedEvent::class => [
RemoveFromSearchIndex::class,
ClearArticleCache::class,
],
];
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ón
final class ContentModerationListener
{
public function __invoke(ArticlePublishingEvent $event): void
{
if ($this->containsProhibitedContent($event->article)) {
$event->reject('El contenido viola las directrices de la comunidad');
}
}
}
  1. Eventos inmutables - Los eventos deben ser de solo lectura
  2. Eventos específicos - Crear eventos específicos, no genéricos
  3. Asincrón cuando sea posible - Usar colas para operaciones lentas
  4. Sin efectos secundarios en el envío - El envío debe ser rápido
  5. Documentar eventos - Listar eventos disponibles para usuarios del módulo