Event Driven Core for laravel applications
pektiyaz/laravel-event-engine is a Laravel package for event driven core for laravel applications.
It currently has 0 GitHub stars and 135 downloads on Packagist (latest version v1.0.0).
Install it with composer require pektiyaz/laravel-event-engine.
Discover more Laravel packages by pektiyaz
or browse all Laravel packages to compare alternatives.
Last updated
EventEngine is a powerful and declarative extension for Laravel’s event system, providing a clear can → do → after pattern for modular business logic.
composer require pektiyaz/laravel-event-engine
Must return:
return new EventCanValue(true)
// OR
return new EventCanValue(true, $data)
// OR
return new EventCanValue(false, "Reason..")
Must return:
return new EventDoValue(true)
// OR
return new EventDoValue(true, $data)
// OR
return new EventDoValue(false, "Reason...")
Must return:
//Listener in module Account
return new EventAskValue(true, ["name" => "John"])
//Listener in module Finance
return new EventAskValue(true, ["balance" => 500])
//Result
[
"name" => "John",
"balance" => 500
]
Should not return anything. These may implement ShouldQueue.
Create an event and a listener for can(), do(), or after() patterns.
Register the listener in Laravel (EventServiceProvider).
Example: CanClientPay
namespace App\Events;
class CanClientPay
{
public function __construct(
public int $clientId,
public float $amount
) {}
}
Listener that handles this event and returns a EventCanValue response.
namespace App\Listeners;
use App\Events\CanClientPay;use Pektiyaz\LaravelEventEngine\CanValues\EventCanValue;
class CheckClientBalanceListener
{
public function handle(CanClientPay $event): EventCanValue
{
// Example logic: client can pay if they have more than $event->amount
$balance = 500; // You’d normally fetch this from DB
if ($balance >= $event->amount) {
return new EventCanValue(true);
}
return new EventCanValue(false, 'Insufficient balance');
}
}
Note: Always return an array from the listener (for can() and do() usage).
Open app/Providers/EventServiceProvider.php and add your event + listener:
protected $listen = [
\App\Events\CanClientPay::class => [
\App\Listeners\CheckClientBalanceListener::class,
],
];
Then run:
php artisan event:clear
php artisan event:cache
use App\Support\EventEngine;
use App\Events\CanClientPay;
$result = EventEngine::can(new CanClientPay($clientId, $amount));
if (!$result->can) {
// Listing all answers
foreach ($result->answers as $answer) {
//$answer->can
//$answer->data
//$answer->toArray()
Log::debug('Event Answer', $answer->toArray());
}
//$result->toArray()
return response()->json(['error' => 'Payment denied', 'details' => $result->data]);
}
use App\Events\ClientProcessPay;
$process = EventEngine::do(new ClientProcessPay($clientId, $amount));
if (!$process->success) {
// Listing all answers
foreach ($result->answers as $answer) {
//$answer->success
//$answer->data
//$answer->toArray()
Log::debug('Event Answer', $answer->toArray());
}
//$result->toArray()
return response()->json(['error' => 'Payment failed', 'details' => $process->data]);
}
return response()->json(['message' => 'Payment success', 'data' => $process->data]);
$response = EventEngine::doAtomic(new ClientPaid($clientId, $amount));
if (!$response->success) {
return response()->json([
'error' => 'Transaction rolled back',
'details' => $response->data,
]);
}
use App\Events\ClientPaid;
EventEngine::after(new ClientPaid($clientId, $amount));
use App\Events\GetUserInfo;
$process = EventEngine::ask(new GetUserInfo($clientId));
if($process->success){
return response()->json([
'user' => $response->data,
]);
}
namespace App\Listeners;
use App\Events\CanClientPay;use Pektiyaz\LaravelEventEngine\CanValues\EventCanValue;
class CanClientPayListener
{
public function handle(CanClientPay $event): EventCanValue
{
// Example logic: client can pay if they have more than $event->amount
$balance = 500; // You’d normally fetch this from DB
if ($balance >= $event->amount) {
return new EventCanValue(true);
}
return new EventCanValue(false, 'Insufficient balance', "CanClientPayListener");
}
}
$result = EventEngine::can(new CanClientPay($clientId, $amount));
foreach($result->answers as $answer){
$answer->listener // CanClientPayListener
}
Clear separation of responsibilities (can, do, after)
Easy to test and maintain
Decouples business logic from the framework
Centralized event orchestration
Scales well with modular systems
Configurable behavior via config file
failFast and collectAllErrors options
Automatic event registration
Publishable Laravel package with service provider