Skip to main content

Events

Laravel Event System provides a comprehensive event system that fires domain events for all CRUD operations on event-listener bindings. These events allow you to hook into the event system lifecycle and perform additional actions when bindings are created or deleted.

Overview​

The event system in Laravel Event System:

  • Fires automatically during CRUD operations
  • Provides model instances in event payloads
  • Uses DomainEvent interface for consistency
  • Supports event listeners for custom logic
  • Enables event-driven architecture for event binding management

Event Structure​

All events in Laravel Event System:

  • Implement JobMetric\EventSystem\Contracts\DomainEvent
  • Are readonly classes for immutability
  • Contain the affected Event model instance
  • Provide a stable key() method
  • Include metadata via definition() method

Base Event Structure​

readonly class EventSystemStoredEvent implements DomainEvent
{
public function __construct(
public Event $event,
public array $data
) {}

public static function key(): string
{
return 'event_system.stored';
}

public static function definition(): DomainEventDefinition
{
return new DomainEventDefinition(
self::key(),
'event-system::base.events.event_system_stored.group',
'event-system::base.events.event_system_stored.title',
'event-system::base.events.event_system_stored.description',
'fas fa-save',
['event system', 'storage', 'management']
);
}
}

Available Events​

Event System Events​

Events fired for Event System CRUD operations.

Event ClassEvent KeyDescriptionPayloadTriggered When
EventSystemStoredEventevent_system.storedFired when a new event-listener binding is createdEvent $event, array $dataEventSystem::store()
EventSystemDeletingEventevent_system.deletingFired before an event-listener binding is deletedEvent $eventBefore EventSystem::delete()
EventSystemDeletedEventevent_system.deletedFired after an event-listener binding is deletedEvent $eventAfter EventSystem::delete()

Namespace: JobMetric\EventSystem\Events\*

Listening to Events​

Method 1: Event Listeners in Service Provider​

Register event listeners in a service provider:

namespace App\Providers;

use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use JobMetric\EventSystem\Events\EventSystemStoredEvent;
use JobMetric\EventSystem\Events\EventSystemDeletedEvent;

class EventServiceProvider extends ServiceProvider
{
protected $listen = [
EventSystemStoredEvent::class => [
\App\Listeners\EventSystem\LogEventSystemStored::class,
\App\Listeners\EventSystem\InvalidateEventSystemCache::class,
\App\Listeners\EventSystem\NotifyEventSystemStored::class,
],
EventSystemDeletedEvent::class => [
\App\Listeners\EventSystem\LogEventSystemDeleted::class,
\App\Listeners\EventSystem\InvalidateEventSystemCache::class,
],
];

public function boot(): void
{
parent::boot();
}
}

Method 2: Using Event Facade​

Listen to events using the Event facade:

use Illuminate\Support\Facades\Event;
use JobMetric\EventSystem\Events\EventSystemStoredEvent;

Event::listen(EventSystemStoredEvent::class, function (EventSystemStoredEvent $event) {
$eventModel = $event->event;
$data = $event->data;

// Perform actions
Log::info('Event system entry created', [
'name' => $eventModel->name,
'event' => $eventModel->event,
'listener' => $eventModel->listener,
'priority' => $eventModel->priority,
]);

Cache::forget('events');
});

Method 3: Using Event Subscribers​

Create event subscribers for multiple events:

namespace App\Listeners;

use Illuminate\Events\Dispatcher;
use JobMetric\EventSystem\Events\EventSystemStoredEvent;
use JobMetric\EventSystem\Events\EventSystemDeletedEvent;

class EventSystemEventSubscriber
{
public function handleEventSystemStored(EventSystemStoredEvent $event): void
{
$eventModel = $event->event;

Log::info('Event system entry created', [
'name' => $eventModel->name,
'event' => $eventModel->event,
'listener' => $eventModel->listener,
]);
}

public function handleEventSystemDeleted(EventSystemDeletedEvent $event): void
{
$eventModel = $event->event;

Log::warning('Event system entry deleted', [
'name' => $eventModel->name,
'id' => $eventModel->id,
]);
}

public function subscribe(Dispatcher $events): void
{
$events->listen(
EventSystemStoredEvent::class,
[EventSystemEventSubscriber::class, 'handleEventSystemStored']
);

$events->listen(
EventSystemDeletedEvent::class,
[EventSystemEventSubscriber::class, 'handleEventSystemDeleted']
);
}
}

Register the subscriber:

namespace App\Providers;

use App\Listeners\EventSystemEventSubscriber;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;

class EventServiceProvider extends ServiceProvider
{
protected $subscribe = [
EventSystemEventSubscriber::class,
];
}

Complete Examples​

Example 1: Cache Invalidation on Event System Changes​

Invalidate cache when event bindings are modified:

namespace App\Listeners\EventSystem;

use Illuminate\Support\Facades\Cache;
use JobMetric\EventSystem\Events\EventSystemStoredEvent;
use JobMetric\EventSystem\Events\EventSystemDeletedEvent;

class InvalidateEventSystemCache
{
public function handle(EventSystemStoredEvent|EventSystemDeletedEvent $event): void
{
$eventModel = $event->event;

// Invalidate specific event cache
Cache::forget("event_system_{$eventModel->id}");
Cache::forget("event_system_name_{$eventModel->name}");

// Invalidate all events cache
Cache::forget('events');
Cache::forget('event_system_all');

// Clear tagged cache
Cache::tags(['event_system'])->flush();
}
}

Example 2: Audit Logging​

Log all event system operations for audit trail:

namespace App\Listeners\EventSystem;

use App\Models\AuditLog;
use Illuminate\Support\Facades\Auth;
use JobMetric\EventSystem\Events\EventSystemStoredEvent;
use JobMetric\EventSystem\Events\EventSystemDeletedEvent;

class AuditEventSystemOperations
{
public function handleEventSystemStored(EventSystemStoredEvent $event): void
{
$this->logAudit('stored', $event->event, $event->data);
}

public function handleEventSystemDeleted(EventSystemDeletedEvent $event): void
{
$this->logAudit('deleted', $event->event);
}

protected function logAudit(string $action, $eventModel, ?array $data = null): void
{
AuditLog::create([
'user_id' => Auth::id(),
'action' => "event_system.{$action}",
'model_type' => get_class($eventModel),
'model_id' => $eventModel->id,
'data' => [
'name' => $eventModel->name,
'event' => $eventModel->event,
'listener' => $eventModel->listener,
'priority' => $eventModel->priority,
'status' => $eventModel->status,
'input_data' => $data,
],
'ip_address' => request()->ip(),
]);
}
}

Example 3: Notification System​

Send notifications when critical event bindings are registered:

namespace App\Listeners\EventSystem;

use App\Notifications\CriticalEventBindingRegistered;
use Illuminate\Support\Facades\Notification;
use JobMetric\EventSystem\Events\EventSystemStoredEvent;

class NotifyEventSystemChanges
{
protected array $criticalEvents = ['user.created', 'order.completed', 'payment.processed'];

public function handle(EventSystemStoredEvent $event): void
{
$eventModel = $event->event;

// Notify for critical events
if (in_array($eventModel->name, $this->criticalEvents)) {
$admins = User::whereHas('roles', function ($query) {
$query->where('name', 'admin');
})->get();

Notification::send($admins, new CriticalEventBindingRegistered($eventModel));
}

// Notify via Slack
if (config('services.slack.webhook')) {
Notification::route('slack', config('services.slack.webhook'))
->notify(new CriticalEventBindingRegistered($eventModel));
}
}
}

Example 4: Analytics Tracking​

Track event system changes for analytics:

namespace App\Listeners\EventSystem;

use App\Services\AnalyticsService;
use JobMetric\EventSystem\Events\EventSystemStoredEvent;
use JobMetric\EventSystem\Events\EventSystemDeletedEvent;

class TrackEventSystemAnalytics
{
public function __construct(
protected AnalyticsService $analytics
) {}

public function handleEventSystemStored(EventSystemStoredEvent $event): void
{
$eventModel = $event->event;

$this->analytics->track('event_system.stored', [
'event_id' => $eventModel->id,
'name' => $eventModel->name,
'event_class' => $eventModel->event,
'listener_class' => $eventModel->listener,
'priority' => $eventModel->priority,
'status' => $eventModel->status,
]);
}

public function handleEventSystemDeleted(EventSystemDeletedEvent $event): void
{
$eventModel = $event->event;

$this->analytics->track('event_system.deleted', [
'event_id' => $eventModel->id,
'name' => $eventModel->name,
'deleted_at' => now(),
]);
}
}

Example 5: Validation and Business Rules​

Validate event bindings before deletion:

namespace App\Listeners\EventSystem;

use Illuminate\Validation\ValidationException;
use JobMetric\EventSystem\Events\EventSystemDeletingEvent;

class ValidateEventSystemDeletion
{
protected array $protectedEvents = ['critical.event.1', 'critical.event.2', 'system.event'];

public function handle(EventSystemDeletingEvent $event): void
{
$eventModel = $event->event;

// Prevent deletion of protected events
if (in_array($eventModel->name, $this->protectedEvents)) {
throw ValidationException::withMessages([
'event' => 'Cannot delete protected event bindings.',
]);
}

// Check if event is in use
if ($this->isEventInUse($eventModel)) {
throw ValidationException::withMessages([
'event' => 'Cannot delete event binding that is currently in use.',
]);
}
}

protected function isEventInUse($eventModel): bool
{
// Check if event is being used in active workflows
// Implement your business logic here
return false;
}
}

Example 6: Synchronization with External Systems​

Synchronize event bindings with external systems:

namespace App\Listeners\EventSystem;

use App\Services\ExternalApiService;
use JobMetric\EventSystem\Events\EventSystemStoredEvent;
use JobMetric\EventSystem\Events\EventSystemDeletedEvent;

class SynchronizeEventSystem
{
public function __construct(
protected ExternalApiService $externalApi
) {}

public function handleEventSystemStored(EventSystemStoredEvent $event): void
{
$eventModel = $event->event;

$this->externalApi->syncEventBinding([
'name' => $eventModel->name,
'event' => $eventModel->event,
'listener' => $eventModel->listener,
'priority' => $eventModel->priority,
'status' => $eventModel->status,
]);
}

public function handleEventSystemDeleted(EventSystemDeletedEvent $event): void
{
$eventModel = $event->event;

$this->externalApi->deleteEventBinding($eventModel->name);
}
}

Example 7: Real-time Updates​

Send real-time updates via WebSockets or broadcasting:

namespace App\Listeners\EventSystem;

use Illuminate\Support\Facades\Broadcast;
use JobMetric\EventSystem\Events\EventSystemStoredEvent;
use JobMetric\EventSystem\Events\EventSystemDeletedEvent;

class BroadcastEventSystemChanges
{
public function handleEventSystemStored(EventSystemStoredEvent $event): void
{
$eventModel = $event->event;

Broadcast::channel('event-system', function () {
return true;
})->toOthers();

event(new EventSystemChanged([
'type' => 'stored',
'event' => $eventModel,
]));
}

public function handleEventSystemDeleted(EventSystemDeletedEvent $event): void
{
$eventModel = $event->event;

event(new EventSystemChanged([
'type' => 'deleted',
'event' => $eventModel,
]));
}
}

Example 8: Complete Event Listener Setup​

Complete setup for all event system events:

namespace App\Providers;

use App\Listeners\EventSystem\AuditEventSystemOperations;
use App\Listeners\EventSystem\BroadcastEventSystemChanges;
use App\Listeners\EventSystem\InvalidateEventSystemCache;
use App\Listeners\EventSystem\NotifyEventSystemChanges;
use App\Listeners\EventSystem\TrackEventSystemAnalytics;
use App\Listeners\EventSystem\ValidateEventSystemDeletion;
use App\Listeners\EventSystem\SynchronizeEventSystem;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use JobMetric\EventSystem\Events\EventSystemStoredEvent;
use JobMetric\EventSystem\Events\EventSystemDeletingEvent;
use JobMetric\EventSystem\Events\EventSystemDeletedEvent;

class EventServiceProvider extends ServiceProvider
{
protected $listen = [
// After storing
EventSystemStoredEvent::class => [
AuditEventSystemOperations::class,
InvalidateEventSystemCache::class,
NotifyEventSystemChanges::class,
TrackEventSystemAnalytics::class,
BroadcastEventSystemChanges::class,
SynchronizeEventSystem::class,
],

// Before deleting
EventSystemDeletingEvent::class => [
ValidateEventSystemDeletion::class,
],

// After deleting
EventSystemDeletedEvent::class => [
AuditEventSystemOperations::class,
InvalidateEventSystemCache::class,
TrackEventSystemAnalytics::class,
BroadcastEventSystemChanges::class,
SynchronizeEventSystem::class,
],
];

public function boot(): void
{
parent::boot();
}
}

Event Timing​

EventSystemStoredEvent​

Fired after the event binding is saved to database:

// Execution order:
// 1. Validate input data
// 2. Create event binding record
// 3. Save to database
// 4. Clear cache
// 5. Fire EventSystemStoredEvent ← Event fired here
// 6. Return response

EventSystemDeletingEvent / EventSystemDeletedEvent​

  • EventSystemDeletingEvent: Fired before the deletion operation
  • EventSystemDeletedEvent: Fired after the deletion operation completes
// Execution order:
// 1. Find event binding by name
// 2. Fire EventSystemDeletingEvent ← Before deletion
// 3. Delete event binding record
// 4. Fire EventSystemDeletedEvent ← After deletion
// 5. Clear cache
// 6. Return response

Important Notes:

  • The event binding is saved to database before EventSystemStoredEvent fires
  • You can access fresh model data in listeners
  • Database transaction is committed before events fire
  • Events are synchronous by default (can be queued)
  • EventSystemDeletingEvent allows you to prevent deletion if needed
  • Cache is cleared before events fire

Queued Events​

You can queue events for asynchronous processing:

namespace App\Listeners\EventSystem;

use Illuminate\Contracts\Queue\ShouldQueue;
use JobMetric\EventSystem\Events\EventSystemStoredEvent;

class ProcessEventSystemAsync implements ShouldQueue
{
public function handle(EventSystemStoredEvent $event): void
{
$eventModel = $event->event;

// Heavy processing that doesn't block the request
$this->syncWithExternalService($eventModel);
$this->generateAnalyticsReport($eventModel);
$this->sendWelcomeNotifications($eventModel);
}

protected function syncWithExternalService($eventModel): void
{
// Sync with external API
}

protected function generateAnalyticsReport($eventModel): void
{
// Generate analytics
}

protected function sendWelcomeNotifications($eventModel): void
{
// Send notifications
}
}

Event Payload Details​

EventSystemStoredEvent​

readonly class EventSystemStoredEvent implements DomainEvent
{
public function __construct(
public Event $event, // Event model instance (saved to database)
public array $data // Validated input data
) {}
}

Available Properties on $event:

  • id: Event binding ID
  • name: Unique name identifier
  • description: Optional description
  • event: Fully qualified event class name
  • listener: Fully qualified listener class name
  • priority: Execution priority
  • status: Active status (boolean)
  • created_at: Creation timestamp
  • updated_at: Update timestamp

Available Properties on $data:

  • All validated input fields from StoreEventSystemRequest
  • Normalized values (priority defaults, etc.)

EventSystemDeletingEvent / EventSystemDeletedEvent​

readonly class EventSystemDeletedEvent implements DomainEvent
{
public function __construct(
public Event $event // Event model instance (deleted)
) {}
}

Available Properties:

  • $event: Event model instance with all properties (still accessible after deletion)
  • All properties from EventSystemStoredEvent are available
  • Model is deleted but instance remains accessible

When to Use Events​

Use events when you need to:

  • Cache Management: Invalidate or update cached event bindings
  • Notifications: Send notifications when event bindings change
  • Analytics: Track event system operations for analytics
  • Audit Logging: Log event binding changes for compliance
  • Validation: Validate event bindings before deletion
  • Synchronization: Sync event bindings with external systems
  • Real-time Updates: Broadcast event binding changes to clients
  • Business Rules: Enforce business rules on event operations
  • Integration: Integrate with external services
  • Side Effects: Perform side effects without coupling