Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Model States Laravel Package

spatie/laravel-model-states

Add robust state behavior to Laravel Eloquent models using the state pattern and state machines. Represent each state as a class, cast states transparently to/from the database, and define clear, safe transitions with configurable state logic.

View on GitHub
Deep Wiki
Context7

title: Configuring transitions weight: 1

Transitions can be used to transition the state of a model from one to another, in a structured and safe way.

You can specify which states are allowed to transition from one to another, and if you want to handle side effects or have more complex transitions, you can also provide custom transition classes.

Transitions are configured in the config method on your state classes.

abstract class PaymentState extends State
{
    // …

    public static function config(): StateConfig
    {
        return parent::config()
            ->allowTransition(Pending::class, Paid::class)
            ->allowTransition(Pending::class, Failed::class, PendingToFailed::class);
    }
}

In this example we're using both a simple transition, and a custom one. You can also allow all transitions for all registered states. Concrete states extending the abstract state class that are located in the same directory as the abstract state class will be automatically registered:

abstract class PaymentState extends State
{
    // …

    public static function config(): StateConfig
    {
        return parent::config()
            ->allowAllTransitions();
    }
}

Transitions can then be used like so:

$payment->state->transitionTo(Paid::class);

This line will only work when a valid transition was configured. If the initial state of $payment already was Paid, a \Spatie\ModelStates\Exceptions\TransitionNotFound will be thrown instead of changing the state.

Ignoring same state transitions

In some cases you may want to handle transition to same state without manually setting allowTransition, you can call ignoreSameState

Please note that the StateChanged event will fire anyway.

abstract class PaymentState extends State
{
    // …

    public static function config(): StateConfig
    {
        return parent::config()
            ->ignoreSameState()
            ->allowTransition([Created::class, Pending::class], Failed::class, ToFailed::class);
    }
}

It also works with IgnoreSameState Attribute

#[IgnoreSameState]
abstract class PaymentState extends State
{
    //...
}

Allow multiple transitions at once

A little shorthand allowTransitions can be used to allow multiple transitions at once:

abstract class PaymentState extends State
{
    // …

    public static function config(): StateConfig
    {
        return parent::config()
            ->allowTransitions([
                [Pending::class, Paid::class],
                [Pending::class, Failed::class, PendingToFailed::class],
            ]);
    }
}

Allowing multiple from states

If you've got multiple states that can transition to the same state, you can define all of them in one allowTransition call:

abstract class PaymentState extends State
{
    // …

    public static function config(): StateConfig
    {
        return parent::config()
            ->allowTransition([Created::class, Pending::class], Failed::class, ToFailed::class);
    }
}

Using transitions

Transitions can be used by calling the transitionTo method on the state field like so:

$payment->state->transitionTo(Paid::class);
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport