Laravel Stateflow Demo
January 14, 2026 · View on GitHub
This demo application showcases Laravel Stateflow — a powerful state machine package for Laravel. It demonstrates two different approaches to configuring state workflows using real-world examples.
Overview
| Model | Approach | Description |
|---|---|---|
| Order | Traditional | State transitions defined explicitly using allowTransition() calls |
| Booking | Hybrid Enum | Transition topology defined in an enum, behavior in state classes |
1. Orders — Traditional Approach
The Order model demonstrates the traditional approach where state classes and transitions are configured explicitly in the model's registerStates() method.
State Topology
┌─────────┐ ┌────────────┐ ┌─────────┐ ┌───────────┐
│ Pending │────▶│ Processing │────▶│ Shipped │────▶│ Delivered │
└─────────┘ └────────────┘ └─────────┘ └───────────┘
│ │
│ │
▼ ▼
┌───────────┐ ┌───────────┐
│ Cancelled │◀──│ │
└───────────┘ └───────────┘
Allowed Transitions
| From | To |
|---|---|
| Pending | Processing |
| Pending | Cancelled |
| Processing | Shipped |
| Processing | Cancelled |
| Shipped | Delivered |
Configuration
// app/Models/Order.php
public static function registerStates(): void
{
static::addState('state', StateConfig::make(OrderState::class)
->default(Pending::class)
->registerStates([
Pending::class,
Processing::class,
Shipped::class,
Delivered::class,
Cancelled::class,
])
->allowTransition(Pending::class, Processing::class)
->allowTransition(Pending::class, Cancelled::class)
->allowTransition(Processing::class, Shipped::class)
->allowTransition(Processing::class, Cancelled::class)
->allowTransition(Shipped::class, Delivered::class)
);
}
Key Files
- Model: app/Models/Order.php
- Base State: app/States/Order/OrderState.php
- States: app/States/Order/
2. Bookings — Hybrid Enum Approach
The Booking model demonstrates the hybrid approach where the transition topology is defined in an enum (BookingWorkflow), while behavior and metadata remain in state classes.
State Topology
┌───────┐ ┌───────────┐ ┌──────┐ ┌───────────┐
│ Draft │────▶│ Confirmed │────▶│ Paid │────▶│ Fulfilled │
└───────┘ └───────────┘ └──────┘ └───────────┘
│ │ │
│ │ │
▼ ▼ ▼
┌─────────┐ ┌───────────┐ ┌───────────┐
│ Expired │ │ Cancelled │◀──│ │
└─────────┘ │ Expired │ └───────────┘
└───────────┘
Allowed Transitions
| From | To |
|---|---|
| Draft | Confirmed |
| Draft | Expired |
| Confirmed | Paid |
| Confirmed | Cancelled |
| Confirmed | Expired |
| Paid | Fulfilled |
| Paid | Cancelled (refund) |
Configuration
The enum defines the transition topology:
// app/Enums/BookingStateStatus.php
enum BookingWorkflow: string
{
case Draft = 'draft';
case Confirmed = 'confirmed';
case Paid = 'paid';
case Fulfilled = 'fulfilled';
case Cancelled = 'cancelled';
case Expired = 'expired';
public function canTransitionTo(): array
{
return match ($this) {
self::Draft => [Confirmed::class, Expired::class],
self::Confirmed => [Paid::class, Cancelled::class, Expired::class],
self::Paid => [Fulfilled::class, Cancelled::class],
// Final states
self::Fulfilled, self::Cancelled, self::Expired => [],
};
}
public static function transitions(): array
{
// Generates array for allowTransitionsFromArray()
}
}
The model uses the enum for configuration:
// app/Models/Booking.php
public static function registerStates(): void
{
static::addState('state', StateConfig::make(BookingState::class)
->default(Draft::class)
->registerStates(BookingWorkflow::stateClasses())
->allowTransitionsFromArray(BookingWorkflow::transitions())
);
}
Key Files
- Model: app/Models/Booking.php
- Enum: app/Enums/BookingWorkflow.php
- Base State: app/States/Booking/BookingState.php
- States: app/States/Booking/
Approach Comparison
| Aspect | Traditional (Order) | Hybrid Enum (Booking) |
|---|---|---|
| Topology Definition | In model's registerStates() | In dedicated enum |
| State Classes | Required for behavior | Required for behavior |
| Transitions | allowTransition() calls | allowTransitionsFromArray() |
| Reusability | Tied to model | Enum can be shared/documented |
| Testability | Test via model | Can unit test enum independently |
| Visualization | Read from model | Enum is self-documenting |
When to Use Each Approach
Traditional Approach
- Simple workflows with few states
- Transitions tightly coupled to model logic
- Quick prototyping
Hybrid Enum Approach
- Complex workflows with many states
- Need clear separation of topology and behavior
- Want self-documenting transition rules
- Team prefers enum-based architecture
Learn More
- 📚 Enum Documentation: See the Enum Usage Guide for detailed patterns
- 📦 Package Repository: hpwebdeveloper/laravel-stateflow
Running the Demo
# Install dependencies
composer install
npm install
# Run migrations
php artisan migrate
# Seed sample data
php artisan db:seed
# Start the development server
composer run dev