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 | ก่อนการลบผู้ใช้ |
ระบบพรีโหลด (รุ่นเก่า)
หัวข้อที่มีชื่อว่า “ระบบพรีโหลด (รุ่นเก่า)”กำลังสร้างพรีโหลด
หัวข้อที่มีชื่อว่า “กำลังสร้างพรีโหลด”<?phpnamespace 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- eventModuleNewsArticleCreatePSR-14 ผู้จัดส่งกิจกรรม (XOOPS 4.0)
หัวข้อที่มีชื่อว่า “PSR-14 ผู้จัดส่งกิจกรรม (XOOPS 4.0)”คลาสอีเว้นท์
หัวข้อที่มีชื่อว่า “คลาสอีเว้นท์”<?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, ] ); }}ลงทะเบียนผู้ฟัง
หัวข้อที่มีชื่อว่า “ลงทะเบียนผู้ฟัง”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 propagationfinal class ContentModerationListener{ public function __invoke(ArticlePublishingEvent $event): void { if ($this->containsProhibitedContent($event->article)) { $event->reject('Content violates community guidelines'); } }}แนวทางปฏิบัติที่ดีที่สุด
หัวข้อที่มีชื่อว่า “แนวทางปฏิบัติที่ดีที่สุด”- เหตุการณ์ที่ไม่เปลี่ยนรูป - กิจกรรมควรเป็นแบบอ่านอย่างเดียว
- กิจกรรมเฉพาะ - สร้างกิจกรรมเฉพาะ ไม่ใช่กิจกรรมทั่วไป
- Async เมื่อเป็นไปได้ - ใช้คิวสำหรับการดำเนินการที่ช้า
- ไม่มีผลข้างเคียงในการจัดส่ง - การจัดส่งควรจะรวดเร็ว
- เหตุการณ์เอกสาร - แสดงรายการเหตุการณ์ที่มีอยู่สำหรับผู้ใช้โมดูล
เอกสารที่เกี่ยวข้อง
หัวข้อที่มีชื่อว่า “เอกสารที่เกี่ยวข้อง”- โมดูล-การพัฒนา - การพัฒนาโมดูล
- Event-System-Guide - PSR-14 คู่มือ
- ตะขอ-กิจกรรม - ตะขอแบบเดิม
- กิจกรรมและตะขอ - ตัวอย่างกิจกรรม