ข้ามไปยังเนื้อหา

XOOPS ระบบเหตุการณ์

2.5.x: โหลดล่วงหน้า 4.0.x: PSR-14

ระบบเหตุการณ์ XOOPS ช่วยให้การเชื่อมต่อแบบหลวมๆ ระหว่างโมดูลผ่านรูปแบบผู้สังเกตการณ์ ส่วนประกอบสามารถปล่อยเหตุการณ์ที่ส่วนอื่นๆ ของระบบสามารถรับฟังและตอบสนองได้

เหตุการณ์จุดกระตุ้น
core.header.startก่อนการประมวลผลส่วนหัว
core.header.endหลังจากการประมวลผลส่วนหัว
core.footer.startก่อนที่จะเรนเดอร์ส่วนท้าย
core.footer.endหลังจากการเรนเดอร์ส่วนท้าย
core.exceptionเมื่อเกิดข้อยกเว้น
เหตุการณ์จุดกระตุ้น
module.installหลังการติดตั้งโมดูล
module.updateหลังจากอัพเดตโมดูล
module.uninstallก่อนการลบโมดูล
module.activateเมื่อเปิดใช้งานโมดูล
module.deactivateเมื่อปิดการใช้งานโมดูล
เหตุการณ์จุดกระตุ้น
user.loginหลังจากเข้าสู่ระบบสำเร็จ
user.logoutหลังจากออกจากระบบ
user.registerหลังจากลงทะเบียน
user.deleteก่อนการลบผู้ใช้
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}
Examples:
- 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. เหตุการณ์ที่ไม่เปลี่ยนรูป - กิจกรรมควรเป็นแบบอ่านอย่างเดียว
  2. กิจกรรมเฉพาะ - สร้างกิจกรรมเฉพาะ ไม่ใช่กิจกรรมทั่วไป
  3. Async เมื่อเป็นไปได้ - ใช้คิวสำหรับการดำเนินการที่ช้า
  4. ไม่มีผลข้างเคียงในการจัดส่ง - การจัดส่งควรจะรวดเร็ว
  5. เหตุการณ์เอกสาร - แสดงรายการเหตุการณ์ที่มีอยู่สำหรับผู้ใช้โมดูล