winzou/state-machine
Lightweight PHP state machine library. Define graphs with states, transitions, and guard/before/after callbacks, then apply and validate transitions on your domain objects. Supports multiple graphs per object and configurable state property paths.
object->setCancelled()), enabling event-driven side effects without polluting business logic.Order with payment_status and shipping_status graphs), though coordination between graphs requires explicit handling (e.g., atomic transactions).StateMachineBundle. Avoids reinventing state management for common use cases.StateMachineBundle provides Symfony-style service integration (e.g., dependency injection, event dispatchers).stateA) with no ORM coupling. Supports soft deletes or state history via callbacks.Event facade for cross-cutting concerns (e.g., broadcast notifications on state changes).EventDispatcher is a drop-in replacement.~0.4 releases suggest API instability, though MIT license and active maintenance reduce risk. Pin to ^0.4.6 for stability.after callbacks to log transitions).state_history JSON column).Order::ship() called twice) via database transactions or optimistic locking.pending → shipped → cancelled)?StateMachineFactory to the container for dependency injection:
$this->app->singleton(StateMachineFactory::class, fn() => new StateMachineFactory());
status) and hydrate the state machine in the model’s constructor:
class Order extends Model {
protected $stateMachine;
public function __construct(array $attributes = []) {
parent::__construct($attributes);
$this->stateMachine = StateMachineFactory::get($this, 'orderWorkflow');
}
}
OrderShipped) in after callbacks:
'after' => [
'on-ship' => [
'on' => 'ship',
'do' => fn(Order $order) => event(new OrderShipped($order)),
],
]
StateMachineBundle for event dispatchers, validation, and Symfony forms integration.winzou_state_machine:
graphs:
order_workflow:
class: App\Entity\Order
property_path: status
states: [pending, shipped, cancelled]
transitions: { /* ... */ }
status column (e.g., VARCHAR) and hydrate in boot():
protected static function boot() {
parent::boot();
static::created(fn($order) => $order->initializeStateMachine());
}
Cache::remember()).config/state_machines/order.php).feature() helper to toggle state machine usage alongside old logic.#[StateMachine(
states: ['pending', 'shipped'],
transitions: ['ship' => ['from' => 'pending', 'to' => 'shipped']]
)]
class Order {}
ENUM or VARCHAR for state columns.pending → shipped → cancelled) with Laravel’s actingAs() and assertDatabaseHas().order, user, support_ticket).boot() methods.How can I help you explore Laravel packages today?