PHP code example of monkeyscloud / monkeyslegion-events

1. Go to this page and download the library: Download monkeyscloud/monkeyslegion-events library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

monkeyscloud / monkeyslegion-events example snippets


use MonkeysLegion\Events\Event;
use MonkeysLegion\Events\EventDispatcher;
use MonkeysLegion\Events\ListenerProvider;

// Define an event
final class UserCreated extends Event
{
    public function __construct(
        public readonly string $email,
    ) {
        parent::__construct();
    }
}

// Register listeners
$provider = new ListenerProvider();
$provider->add(UserCreated::class, function (UserCreated $event) {
    echo "Welcome, {$event->email}!";
});

// Dispatch
$dispatcher = new EventDispatcher($provider);
$dispatcher->dispatch(new UserCreated('[email protected]'));

use MonkeysLegion\Events\Attribute\Listener;

#[Listener(event: UserCreated::class, priority: 10)]
final class SendWelcomeEmail
{
    public function __invoke(UserCreated $event): void
    {
        // Send email to $event->email
    }
}

// Register via attribute scanning
$provider->addFromAttributes(new SendWelcomeEmail());

use MonkeysLegion\Events\Attribute\Listener;
use MonkeysLegion\Events\Attribute\ListenWhen;

#[Listener(event: OrderPlaced::class)]
#[ListenWhen(method: 'isHighValue')]
final class OnHighValueOrder
{
    public function isHighValue(OrderPlaced $event): bool
    {
        return $event->amount > 1000;
    }

    public function __invoke(OrderPlaced $event): void
    {
        // Only called when amount > 1000
    }
}

use MonkeysLegion\Events\Attribute\BeforeEvent;
use MonkeysLegion\Events\Attribute\AfterEvent;

final class OrderInterceptor
{
    #[BeforeEvent(event: OrderPlaced::class)]
    public function validate(OrderPlaced $event): void
    {
        // Runs BEFORE regular listeners
    }

    #[AfterEvent(event: OrderPlaced::class)]
    public function audit(OrderPlaced $event): void
    {
        // Runs AFTER all regular listeners
    }
}

$provider->addFromAttributes(new OrderInterceptor());

use MonkeysLegion\Events\Interceptor\TimingInterceptor;
use MonkeysLegion\Events\Interceptor\LoggingInterceptor;
use MonkeysLegion\Events\EventMetrics;

$metrics = new EventMetrics();
$dispatcher->addInterceptor(new TimingInterceptor($metrics));
$dispatcher->addInterceptor(new LoggingInterceptor($psrLogger));

$dispatcher->dispatch(new OrderPlaced(42, 99.99));

echo $metrics->countFor(OrderPlaced::class);   // 1
echo $metrics->averageFor(OrderPlaced::class);  // 0.123 ms

use MonkeysLegion\Events\EventSubscriberInterface;

final class UserEventSubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [
            UserCreated::class => 'onUserCreated',
            UserDeleted::class => ['onUserDeleted', 10], // with priority
            OrderPlaced::class => [
                ['onOrderLog', 10],
                ['onOrderNotify', 5],
            ],
        ];
    }

    public function onUserCreated(UserCreated $event): void { /* ... */ }
    public function onUserDeleted(UserDeleted $event): void { /* ... */ }
    public function onOrderLog(OrderPlaced $event): void { /* ... */ }
    public function onOrderNotify(OrderPlaced $event): void { /* ... */ }
}

$provider->addSubscriber(new UserEventSubscriber());

// Matches UserCreated, UserDeleted, UserUpdated, etc.
$provider->addWildcard('*UserCreated', function (object $event) {
    // Handle any event matching the pattern
});

$provider->add(GenericEvent::class, function (Event $event) {
    $event->stopPropagation(); // Subsequent listeners won't run
}, priority: 10);

$provider->add(GenericEvent::class, function () {
    // This will NOT be called
}, priority: 0);

use MonkeysLegion\Events\Store\EventStore;

$store = new EventStore();
$dispatcher = new EventDispatcher($provider, store: $store);

$dispatcher->dispatch(new UserCreated('[email protected]'));
$dispatcher->dispatch(new OrderPlaced(1, 50.0));

// Query recorded events
$users = $store->ofType(UserCreated::class); // [UserCreated]
echo $store->size; // 2

// Replay all events through another dispatcher
$store->replay($anotherDispatcher);

$result = $dispatcher->dispatchWithResult(new UserCreated('[email protected]'));

echo $result->listenersInvoked; // 3
echo $result->durationMs;       // 0.456
echo $result->stopped;           // false
echo $result->isClean();         // true (no errors)

// Batch dispatch
$results = $dispatcher->dispatchBatch([
    new UserCreated('[email protected]'),
    new OrderPlaced(1, 50.0),
]);

$descriptor = new ListenerDescriptor(
    listener:         fn() => throw new \RuntimeException('fail'),
    eventClass:       OrderPlaced::class,
    circuitThreshold: 3,    // Trip after 3 failures
    circuitResetTime: 60,   // Try again after 60 seconds
);

// Catch listener exceptions instead of crashing
$dispatcher = new EventDispatcher($provider, safeMode: true);

$result = $dispatcher->dispatchWithResult(new OrderPlaced(1, 50.0));
// Errors captured in $result->errors instead of throwing

use MonkeysLegion\Events\Contract\ShouldQueue;

#[Listener(event: OrderPlaced::class)]
final class ProcessPayment implements ShouldQueue
{
    public function __invoke(OrderPlaced $event): void
    {
        // Will be dispatched to queue by integration layer
    }
}

$event = new UserCreated('[email protected]');
echo $event->correlationId;  // "a1b2c3d4..." (auto-generated 32-char hex correlation ID)
echo $event->name;            // "UserCreated" (auto-derived)
echo $event->timestamp;       // DateTimeImmutable