Events Reference

Overview

The Neuron framework implements a comprehensive event system for decoupled communication between components. Events are dispatched when specific actions occur, and listeners can respond to these events.

This reference documents ALL events available across the entire Neuron framework, organized by component.

Event Architecture

The event system consists of:

Application Component Events

Application lifecycle and error handling events.

ApplicationCrashedEvent

Event Name: application.crashed Namespace: Neuron\Application\Events\ApplicationCrashedEvent

Fired when the application crashes due to a fatal error or uncaught exception.

Properties:

When Emitted: From error handlers (fatalHandler, globalExceptionHandler, or onCrash)

Use Cases:

Example Listener:

class AlertOnCrashListener implements IListener
{
    public function event( $event ): void
    {
        if( !$event instanceof ApplicationCrashedEvent )
{
            return;
        }

        // Send alert to Slack, PagerDuty, etc.
        $message = "Application crashed: {$event->error['message']}";
        // ... send alert
    }
}

ApplicationShuttingDownEvent

Event Name: application.shutting_down Namespace: Neuron\Application\Events\ApplicationShuttingDownEvent

Fired when the application is shutting down gracefully.

Properties: None

When Emitted: In onFinish() method before application terminates

Use Cases:


ErrorOccurredEvent

Event Name: application.error Namespace: Neuron\Application\Events\ErrorOccurredEvent

Fired when a PHP error occurs (non-fatal).

Properties:

When Emitted: From phpErrorHandler() for non-fatal errors

Use Cases:


FatalErrorEvent

Event Name: application.fatal_error Namespace: Neuron\Application\Events\FatalErrorEvent

Fired when a fatal PHP error occurs.

Properties:

When Emitted: From fatalHandler() when fatal error is detected

Use Cases:


Jobs Component Events

Job queue, worker, and scheduler events.

JobProcessedEvent

Event Name: job.processed Namespace: Neuron\Jobs\Events\JobProcessedEvent

Fired when a job completes successfully.

Properties:

When Emitted: After job's run() method completes without throwing an exception

Use Cases:


JobFailedEvent

Event Name: job.failed Namespace: Neuron\Jobs\Events\JobFailedEvent

Fired when a job fails with an exception.

Properties:

When Emitted: When job's run() method throws an exception

Use Cases:


JobMaxAttemptsReachedEvent

Event Name: job.max_attempts_reached Namespace: Neuron\Jobs\Events\JobMaxAttemptsReachedEvent

Fired when a job exhausts all retry attempts and fails permanently.

Properties:

When Emitted: When job fails and reaches maximum retry attempts

Use Cases:


WorkerStartedEvent

Event Name: worker.started Namespace: Neuron\Jobs\Events\WorkerStartedEvent

Fired when a queue worker starts processing jobs.

Properties:

When Emitted: When worker begins its run loop

Use Cases:


WorkerStoppedEvent

Event Name: worker.stopped Namespace: Neuron\Jobs\Events\WorkerStoppedEvent

Fired when a queue worker stops processing jobs.

Properties:

When Emitted: When worker gracefully shuts down or crashes

Use Cases:


SchedulerJobTriggeredEvent

Event Name: scheduler.job_triggered Namespace: Neuron\Jobs\Events\SchedulerJobTriggeredEvent

Fired when the scheduler determines a scheduled job is due to run.

Properties:

When Emitted: When scheduler's cron expression evaluates to true and job is triggered

Use Cases:


MVC Component Events

HTTP request, view caching, and rate limiting events.

RequestReceivedEvent

Event Name: request.received Namespace: Neuron\Mvc\Events\RequestReceivedEvent

Fired when the MVC application receives an HTTP request.

Properties:

When Emitted: At the beginning of the request lifecycle, before routing and controller execution

Use Cases:


ViewCacheHitEvent

Event Name: view.cache_hit Namespace: Neuron\Mvc\Events\ViewCacheHitEvent

Fired when a rendered view is served from cache.

Properties:

When Emitted: When view caching system finds a valid cached version

Use Cases:


ViewCacheMissEvent

Event Name: view.cache_miss Namespace: Neuron\Mvc\Events\ViewCacheMissEvent

Fired when a view must be rendered because no cache exists.

Properties:

When Emitted: When view caching system does not find a cached version

Use Cases:


RateLimitExceededEvent

Event Name: rate_limit.exceeded Namespace: Neuron\Mvc\Events\RateLimitExceededEvent

Fired when a request exceeds rate limit thresholds.

Properties:

When Emitted: By RateLimitFilter when client exceeds configured rate limit

Use Cases:


CMS Component Events

User authentication, content management, and system administration events.

User Authentication Events

UserLoginEvent

Event Name: user.login Namespace: Neuron\Cms\Events\UserLoginEvent

Fired when a user successfully logs in.

Properties:

When Emitted: After successful authentication in Authentication::login()

Use Cases:


UserLoginFailedEvent

Event Name: user.login_failed Namespace: Neuron\Cms\Events\UserLoginFailedEvent

Fired when a login attempt fails.

Properties:

When Emitted: When authentication fails in Authentication::attempt()

Use Cases:


UserLogoutEvent

Event Name: user.logout Namespace: Neuron\Cms\Events\UserLogoutEvent

Fired when a user logs out.

Properties:

When Emitted: When user explicitly logs out in Authentication::logout()

Use Cases:


Email Verification Events

EmailVerifiedEvent

Event Name: email.verified Namespace: Neuron\Cms\Events\EmailVerifiedEvent

Fired when a user successfully verifies their email address.

Properties:

When Emitted: After successful email verification in EmailVerifier::verifyEmail()

Use Cases:


Password Reset Events

PasswordResetRequestedEvent

Event Name: password.reset_requested Namespace: Neuron\Cms\Events\PasswordResetRequestedEvent

Fired when a user requests a password reset.

Properties:

When Emitted: After reset token is generated in PasswordResetter::requestReset()

Use Cases:


PasswordResetCompletedEvent

Event Name: password.reset_completed Namespace: Neuron\Cms\Events\PasswordResetCompletedEvent

Fired when a user successfully completes a password reset.

Properties:

When Emitted: After password is successfully changed in PasswordResetter::resetPassword()

Use Cases:


Maintenance Mode Events

MaintenanceModeEnabledEvent

Event Name: maintenance.enabled Namespace: Neuron\Cms\Events\MaintenanceModeEnabledEvent

Fired when maintenance mode is enabled.

Properties:

When Emitted: When MaintenanceManager::enable() succeeds

Use Cases:


MaintenanceModeDisabledEvent

Event Name: maintenance.disabled Namespace: Neuron\Cms\Events\MaintenanceModeDisabledEvent

Fired when maintenance mode is disabled.

Properties:

When Emitted: When MaintenanceManager::disable() succeeds

Use Cases:


Content Management Events (Existing)

The following events already exist for content management operations:

User Events

Post Events

Page Events

Category Events


Event Configuration

Events and their listeners are configured in resources/config/event-listeners.yaml:

events:
  user.login:
    class: 'Neuron\Cms\Events\UserLoginEvent'
    listeners:
      - 'App\Listeners\LogUserLoginListener'
      - 'App\Listeners\SendLoginNotificationListener'

  job.failed:
    class: 'Neuron\Jobs\Events\JobFailedEvent'
    listeners:
      - 'App\Listeners\AlertOnJobFailureListener'

  rate_limit.exceeded:
    class: 'Neuron\Mvc\Events\RateLimitExceededEvent'
    listeners:
      - 'App\Listeners\BlockAbusiveIpListener'

Creating Custom Listeners

Step 1: Create Listener Class

<?php
namespace App\Listeners;

use Neuron\Events\IListener;
use Neuron\Jobs\Events\JobFailedEvent;
use Neuron\Log\Log;

class AlertOnJobFailureListener implements IListener
{
    public function event( $event ): void
    {
        if( !$event instanceof JobFailedEvent )
{
            return;
        }

        // Send alert to Slack, email, etc.
        Log::error( "Job failed: {$event->jobClass} - {$event->exception->getMessage()}" );

        // ... send notification
    }
}

Step 2: Register in Configuration

Add your listener to resources/config/event-listeners.yaml:

events:
  job.failed:
    class: 'Neuron\Jobs\Events\JobFailedEvent'
    listeners:
      - 'App\Listeners\AlertOnJobFailureListener'

Emitting Custom Events

You can emit events from anywhere in your application:

use Neuron\Application\CrossCutting\Event;
use Neuron\Cms\Events\UserLoginEvent;

// Emit an event
Event::emit( new UserLoginEvent( $user, $ip, microtime( true ) ) );

Event Quick Reference

By Component

Component Events
Application ApplicationCrashedEvent, ApplicationShuttingDownEvent, ErrorOccurredEvent, FatalErrorEvent
Jobs JobProcessedEvent, JobFailedEvent, JobMaxAttemptsReachedEvent, WorkerStartedEvent, WorkerStoppedEvent, SchedulerJobTriggeredEvent
MVC RequestReceivedEvent, ViewCacheHitEvent, ViewCacheMissEvent, RateLimitExceededEvent
CMS UserLoginEvent, UserLoginFailedEvent, UserLogoutEvent, EmailVerifiedEvent, PasswordResetRequestedEvent, PasswordResetCompletedEvent, MaintenanceModeEnabledEvent, MaintenanceModeDisabledEvent, UserCreatedEvent, UserUpdatedEvent, UserDeletedEvent, PostCreatedEvent, PostPublishedEvent, PostDeletedEvent, PageCreatedEvent, PagePublishedEvent, PageUpdatedEvent, PageDeletedEvent, CategoryCreatedEvent, CategoryUpdatedEvent, CategoryDeletedEvent

By Use Case

Security Monitoring:

Error Tracking:

Performance Monitoring:

System Operations:

Performance Considerations

Best Practices

  1. Keep Listeners Focused: Each listener should have a single responsibility
  2. Handle Errors Gracefully: Listeners should catch their own exceptions to prevent cascading failures
  3. Use Queued Jobs for Slow Operations: Don't block the main process
  4. Log Listener Actions: Help with debugging and audit trails
  5. Document Custom Events: Maintain clear documentation for team-created events
  6. Test Listeners in Isolation: Unit test listeners independently
  7. Use Type Checking: Always verify event type in listeners
  8. Consider Event Versioning: Plan for event schema changes

Troubleshooting

Event Not Firing

  1. Check event is emitted in source code
  2. Verify \Neuron\Application\CrossCutting\Event::emit() is called
  3. Check event system is initialized
  4. Enable debug logging to see event flow

Listener Not Executing

  1. Verify listener is registered in event-listeners.yaml
  2. Check listener class exists and namespace is correct
  3. Ensure listener implements IListener interface
  4. Verify event() method has correct signature
  5. Check listener is type-checking for correct event class

Multiple Events Firing

  1. Check for duplicate listener registrations
  2. Verify event is not emitted multiple times in code path
  3. Review event inheritance and type checking in listeners