Przejdź do głównej zawartości

System zdarzeń XOOPS

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

System zdarzeń XOOPS umożliwia luźne powiązanie między modułami poprzez wzorzec observer. Komponenty mogą emitować zdarzenia, które inne części systemu mogą słuchać i na nie reagować.

ZdarzeniePunkt wyzwolenia
core.header.startPrzed przetwarzaniem nagłówka
core.header.endPo przetwarzaniu nagłówka
core.footer.startPrzed renderowaniem stopki
core.footer.endPo renderowaniu stopki
core.exceptionGdy pojawi się wyjątek
ZdarzeniePunkt wyzwolenia
module.installPo instalacji modułu
module.updatePo aktualizacji modułu
module.uninstallPrzed usunięciem modułu
module.activateGdy moduł jest aktywowany
module.deactivateGdy moduł jest dezaktywowany
ZdarzeniePunkt wyzwolenia
user.loginPo pomyślnym zalogowaniu
user.logoutPo wylogowaniu
user.registerPo rejestracji
user.deletePrzed usunięciem użytkownika
class/Preload.php
<?php
namespace XoopsModules\MyModule;
use Xmf\Module\Helper\AbstractHelper;
final class Preload extends AbstractHelper
{
public function eventCoreHeaderStart(array $args): void
{
// Wykonaj na każdej stronie przed nagłówkiem
}
public function eventCoreFooterStart(array $args): void
{
// Wykonaj przed renderowaniem stopki
}
public function eventUserLogin(array $args): void
{
$userId = $args['userid'];
// Obsługuj zdarzenie logowania
}
public function eventCoreException(array $args): void
{
$exception = $args['exception'];
// Zaloguj lub obsługuj wyjątek
}
}
event{Kategoria}{Akcja}
Przykłady:
- 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);
// Dyspozycja zdarzenia
$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;
}
}
// Nasłuchiwacz może zatrzymać propagację
final class ContentModerationListener
{
public function __invoke(ArticlePublishingEvent $event): void
{
if ($this->containsProhibitedContent($event->article)) {
$event->reject('Content violates community guidelines');
}
}
}
  1. Zdarzenia niezmienne - Zdarzenia powinny być tylko do odczytu
  2. Zdarzenia specyficzne - Twórz zdarzenia specyficzne, nie generyczne
  3. Asynchronizacja gdy to możliwe - Użyj kolejek dla wolnych operacji
  4. Brak efektów ubocznych w dyspozycji - Dyspozycja powinna być szybka
  5. Dokumentuj zdarzenia - Wypisz dostępne zdarzenia dla użytkowników modułu