Aller au contenu

Système d'événements XOOPS

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

Le système d’événements XOOPS permet un couplage faible entre les modules via un modèle d’observateur. Les composants peuvent émettre des événements que d’autres parties du système peuvent écouter et auxquels elles peuvent répondre.

ÉvénementPoint de déclenchement
core.header.startAvant le traitement du header
core.header.endAprès le traitement du header
core.footer.startAvant le rendu du footer
core.footer.endAprès le rendu du footer
core.exceptionQuand une exception se produit
ÉvénementPoint de déclenchement
module.installAprès l’installation du module
module.updateAprès la mise à jour du module
module.uninstallAvant la suppression du module
module.activateQuand le module est activé
module.deactivateQuand le module est désactivé
ÉvénementPoint de déclenchement
user.loginAprès la connexion réussie
user.logoutAprès la déconnexion
user.registerAprès l’enregistrement
user.deleteAvant la suppression de l’utilisateur
class/Preload.php
<?php
namespace XoopsModules\MyModule;
use Xmf\Module\Helper\AbstractHelper;
final class Preload extends AbstractHelper
{
public function eventCoreHeaderStart(array $args): void
{
// Runs on every page before header
}
public function eventCoreFooterStart(array $args): void
{
// Runs before footer renders
}
public function eventUserLogin(array $args): void
{
$userId = $args['userid'];
// Handle login event
}
public function eventCoreException(array $args): void
{
$exception = $args['exception'];
// Log or handle exception
}
}
event{Category}{Action}
Exemples:
- 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);
// Dispatch event
$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;
}
}
// Listener can stop propagation
final class ContentModerationListener
{
public function __invoke(ArticlePublishingEvent $event): void
{
if ($this->containsProhibitedContent($event->article)) {
$event->reject('Content violates community guidelines');
}
}
}
  1. Événements immuables - Les événements doivent être en lecture seule
  2. Événements spécifiques - Créez des événements spécifiques, pas des événements génériques
  3. Async si possible - Utilisez des files d’attente pour les opérations lentes
  4. Pas d’effets secondaires dans la distribution - La distribution doit être rapide
  5. Documentez les événements - Listez les événements disponibles pour les utilisateurs du module