Zum Inhalt springen

XOOPS Event System

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

Das XOOPS Event System ermöglicht lose Kopplung zwischen Modulen durch ein Observer Pattern. Komponenten können Events aussenden, auf die andere Teile des Systems hören und reagieren können.

EventTrigger Point
core.header.startVor Header-Verarbeitung
core.header.endNach Header-Verarbeitung
core.footer.startVor Footer-Rendering
core.footer.endNach Footer-Rendering
core.exceptionWenn Exception auftritt
EventTrigger Point
module.installNach Modul-Installation
module.updateNach Modul-Update
module.uninstallVor Modul-Entfernung
module.activateWenn Modul aktiviert wird
module.deactivateWenn Modul deaktiviert wird
EventTrigger Point
user.loginNach erfolgreichem Login
user.logoutNach Logout
user.registerNach Registrierung
user.deleteVor Benutzer-Löschung
class/Preload.php
<?php
namespace XoopsModules\MyModule;
use Xmf\Module\Helper\AbstractHelper;
final class Preload extends AbstractHelper
{
public function eventCoreHeaderStart(array $args): void
{
// Läuft auf jeder Seite vor Header
}
public function eventCoreFooterStart(array $args): void
{
// Läuft vor Footer-Rendering
}
public function eventUserLogin(array $args): void
{
$userId = $args['userid'];
// Handle Login Event
}
public function eventCoreException(array $args): void
{
$exception = $args['exception'];
// Log oder handle Exception
}
}
event{Category}{Action}
Beispiele:
- 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);
// Event dispatchen
$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 kann Propagation stoppen
final class ContentModerationListener
{
public function __invoke(ArticlePublishingEvent $event): void
{
if ($this->containsProhibitedContent($event->article)) {
$event->reject('Content violates community guidelines');
}
}
}
  1. Immutable Events - Events sollten read-only sein
  2. Specific Events - Erstellen Sie spezifische Events, nicht generische
  3. Async When Possible - Verwenden Sie Queues für langsame Operationen
  4. No Side Effects in Dispatch - Dispatch sollte schnell sein
  5. Document Events - Listen Sie verfügbare Events für Modul-Benutzer auf