Pular para o conteúdo

Sistema de Eventos XOOPS

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

O sistema de eventos XOOPS permite o acoplamento fraco entre módulos através de um padrão observer. Componentes podem emitir eventos que outras partes do sistema podem ouvir e responder.

EventoPonto de Disparo
core.header.startAntes do processamento do cabeçalho
core.header.endDepois do processamento do cabeçalho
core.footer.startAntes da renderização do rodapé
core.footer.endDepois da renderização do rodapé
core.exceptionQuando exceção ocorre
EventoPonto de Disparo
module.installDepois da instalação do módulo
module.updateDepois da atualização do módulo
module.uninstallAntes da remoção do módulo
module.activateQuando o módulo é ativado
module.deactivateQuando o módulo é desativado
EventoPonto de Disparo
user.loginDepois do login bem-sucedido
user.logoutDepois do logout
user.registerDepois do registro
user.deleteAntes da exclusão do usuário
class/Preload.php
<?php
namespace XoopsModules\MyModule;
use Xmf\Module\Helper\AbstractHelper;
final class Preload extends AbstractHelper
{
public function eventCoreHeaderStart(array $args): void
{
// Executa em cada página antes do cabeçalho
}
public function eventCoreFooterStart(array $args): void
{
// Executa antes do rodapé renderizar
}
public function eventUserLogin(array $args): void
{
$userId = $args['userid'];
// Lidar com evento de login
}
public function eventCoreException(array $args): void
{
$exception = $args['exception'];
// Log ou lidar com exceção
}
}
event{Categoria}{Ação}
Exemplos:
- 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);
// Disparar 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;
}
}
// Ouvinte pode parar propagação
final class ContentModerationListener
{
public function __invoke(ArticlePublishingEvent $event): void
{
if ($this->containsProhibitedContent($event->article)) {
$event->reject('Conteúdo viola diretrizes da comunidade');
}
}
}
  1. Eventos Imutáveis - Eventos devem ser somente leitura
  2. Eventos Específicos - Criar eventos específicos, não genéricos
  3. Assíncrono Quando Possível - Usar filas para operações lentas
  4. Nenhum Efeito Colateral no Despacho - Despacho deve ser rápido
  5. Documente Eventos - Listar eventos disponíveis para usuários do módulo