PHP code example of iotron / laravel-state-machine
1. Go to this page and download the library: Download iotron/laravel-state-machine 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/ */
iotron / laravel-state-machine example snippets
namespace App\StateMachines;
use App\Enums\OrderStatus;
use Iotron\StateMachine\StateMachines\StateMachine;
class OrderStatusStateMachine extends StateMachine
{
public function transitions(): array
{
return [
'pending' => ['confirmed', 'cancelled'],
'confirmed' => ['dispatched', 'cancelled'],
'dispatched' => ['delivered'],
];
}
public function defaultState(): ?string
{
return OrderStatus::PENDING->value;
}
}
use Iotron\StateMachine\Concerns\HasStateMachines;
class Order extends Model
{
use HasStateMachines;
public $stateMachines = [
'status' => OrderStatusStateMachine::class,
];
protected function casts(): array
{
return [
'status' => OrderStatus::class, // native enum cast works!
];
}
}
// config/state-machine.php
return [
'tables' => [
'transitions' => 'state_histories', // history table name
'pending_transitions' => 'pending_transitions',
],
'record_changed_attributes' => true, // capture dirty attributes on transition
'cancel_pending_on_transition' => true, // auto-cancel pending when transitioning
];
public function transitions(): array
{
return [
'draft' => ['pending', 'cancelled'],
'pending' => ['approved', 'rejected'],
'approved' => ['published'],
// Wildcard support
'*' => ['archived'], // any state can go to archived
];
}
public function defaultState(): ?string
{
return 'draft';
// or: return MyEnum::DRAFT->value;
}
public function recordHistory(): bool
{
return true;
}
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Support\Facades\Validator as ValidatorFacade;
public function validatorForTransition($from, $to, $model): ?Validator
{
if ($to === 'published') {
$validator = ValidatorFacade::make([], []);
if (! $model->title) {
$validator->after(fn ($v) => $v->errors()->add(
'title', 'A title is
public function beforeTransitionHooks(): array
{
return [
'published' => [ // keyed by the FROM state
function (string $from, string $to, Model $model) {
// Runs before leaving 'published'
},
],
];
}
public function afterTransitionHooks(): array
{
return [
'confirmed' => [ // keyed by the TO state
function (string $from, string $to, Model $model) {
$model->update(['confirmed_at' => now()]);
},
],
];
}
// 2 queries total: models + stateHistory
$orders = Order::with('stateHistory')->get();
// 0 additional queries for any number of models
foreach ($orders as $order) {
$order->status()->was(OrderStatus::PENDING);
$order->status()->timesWas(OrderStatus::CONFIRMED);
$order->status()->snapshotWhen(OrderStatus::DISPATCHED);
}
// In a listener or EventServiceProvider
use Iotron\StateMachine\Events\TransitionCompleted;
Event::listen(TransitionCompleted::class, function (TransitionCompleted $event) {
if ($event->field === 'status' && $event->to === 'published') {
// Send notification, dispatch job, etc.
}
});
// bootstrap/app.php or routes/console.php
use Iotron\StateMachine\Jobs\DispatchPendingTransitions;
Schedule::job(new DispatchPendingTransitions)->everyMinute();