PHPackages                             lenderspender/laravel-state-transition-workflow - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. lenderspender/laravel-state-transition-workflow

ActiveLibrary

lenderspender/laravel-state-transition-workflow
===============================================

State transition workflow

4.2.0(1y ago)35.2k1MITPHPPHP ^8.2CI failing

Since Nov 27Pushed 1y ago5 watchersCompare

[ Source](https://github.com/lenderspender/laravel-state-transition-workflow)[ Packagist](https://packagist.org/packages/lenderspender/laravel-state-transition-workflow)[ RSS](/packages/lenderspender-laravel-state-transition-workflow/feed)WikiDiscussions master Synced yesterday

READMEChangelog (10)Dependencies (6)Versions (19)Used By (0)

Laravel State Transitions Workflow
==================================

[](#laravel-state-transitions-workflow)

This package adds state transitions workflows to your Laravel models. Allowing you to specify transitions and how to act on those transitions.

To show you how to use this package, let's sketch the following scenario.

A transaction can have three states `CREATED`, `FAILED` and `SUCCESS`. When transitioning between states you probably want to act on this transition e.g. send a success email. You probably only want to allow transitions from `SUCCESS` to `FAILED` and not the other way around.

The transaction model would look like:

```
use LenderSpender\StateTransitionWorkflow\HasStateTransitions;

/**
 * @property \App\Enums\TransactionState $state
 */
class Transaction extends Model
{
    use HasStateTransitions;

    protected function registerStateTransitions(): void
    {
        $this->addState('status')
            ->allowTransition(TransactionState::CREATED(), TransactionState::SUCCESS(), TransactionSuccessfullWorkflow::class)
            ->allowTransition(TransactionState::CREATED(), TransactionState::FAILED());
    }
}
```

Here is what the TransactionState enum looks like:

```
use LenderSpender\LaravelEnums\Enum;
use LenderSpender\StateTransitionWorkflow\TransitionState;

/**
 * @method static self CREATED()
 * @method static self SUCCESS()
 * @method static self FAILED()
 */
class FooStates extends Enum implements TransitionState
{
    private const CREATED = 'created';
    private const SUCCESS = 'success';
    private const FAILED = 'failed';
}
```

And here is what the TransactionSuccessfullWorkflow could look like:

```
use Illuminate\Database\Eloquent\Model;
use LenderSpender\StateTransitionWorkflow\Transition;
use LenderSpender\StateTransitionWorkflow\Workflow;

class TransactionSuccessfullWorkflow extends Workflow
{
    public function __construct(FakeMailer $mailer)
    {
        $this->mailer = $mailer;
    }

    /**
     * @param \App\Models\Transaction $model
     */
    public function execute(Model $transaction, Transition $transition): void
    {
         $this->mailer->mail($transaction->email, 'Payment was sucessfull');
    }
}
```

And here is how you use it:

```
$transaction = Transaction::find(1337);
$transaction->transitionStateTo(FooStates::SUCCESS());

$transaction->state == FooStates::SUCCESS; // true
```

Installation
------------

[](#installation)

You can install the package via composer:

```
composer require lenderspender/laravel-state-transition-workflow
```

Usage
-----

[](#usage)

The package provides a `HasStateTransitions` trait which you can use in any model where you want to support state.

State management
----------------

[](#state-management)

**Registering state field**

To setup states for the `$status` attribute you should add the `HasStateTransitions` trait to the model and implement the `registerStateTransitions` method.

```
use Illuminate\Database\Eloquent\Model;
use LenderSpender\StateTransitionWorkflow\HasStateTransitions;

/**
 * @property \App\Enums\TransactionState $state
 */
class Transaction extends Model
{
    use HasStateTransitions;

    protected function registerStateTransitions(): void
    {
        $this->addState('status');
    }
}
```

**Adding allowed transitions**

Transitions are used to transition the state field for a model from one to another. You need to specify which transitions are allowed and what workflow should be started on transition. By default all transitions are not allowed, to allow transitions you should call `allowTransition` on the added state.

Single transition from `State::FROM()` to `State::TO()`

```
class Transaction extends Model
{
    use HasStateTransitions;

    protected function registerStateTransitions(): void
    {
        $this->addState('status')
            ->allowTransitions(State::FROM(), State::TO());
    }
}
```

Allow transitions from `State::CREATED()` to `State::FAILED()` and `State::SUCCESS()`

```
use Illuminate\Database\Eloquent\Model;
use LenderSpender\StateTransitionWorkflow\HasStateTransitions;

class Transaction extends Model
{
    use HasStateTransitions;

    protected function registerStateTransitions(): void
    {
        $this->addState('status')
            ->allowTransitions(State::CREATED(), [State::FAILED(), State::SUCCESS());
    }
}
```

Allow transitions from `State::CREATED()` and `State::UPDATED()` to `State::FAILED()` and `State::SUCCESS()`

```
use LenderSpender\StateTransitionWorkflow\HasStateTransitions;

class Transaction extends Model
{
    use HasStateTransitions;

    protected function registerStateTransitions(): void
    {
        $this->addState('status')
            ->allowTransitions([State::CREATED(), State::UPDATED()], [State::FAILED(), State::SUCCESS()]);
    }
}
```

**Using transitions**

Transitions can be used by calling the `transitionStateTo` method on the model.

```
$transaction->transitionStateTo(State::SUCCESS());
```

By default the method uses the first registered state. When you've added multiple state fields you should specify which field to use.

```
$transaction->transitionStateTo(State::SUCCESS(), 'status');
```

When a state transitions is not allowed a `LenderSpender\StateTransitionWorkflow\Exceptions\TransitionNotAllowedException` is thrown.

**Listing allowed state transitions**

To know what allowed state transitions can be performed you could call the `getAvailableStateTransitions` on the model.

```
$transaction->getAvailableStateTransitions();
```

By default the method uses the first registered state. When you've added multiple state fields you should specify which field to use.

```
$transaction->getAvailableStateTransitions('status');
```

State workflows
---------------

[](#state-workflows)

When transitioning a model from one state to another you sometimes want to act on this transition. Or even prevent the transition from happening. That's where state workflows come into place.

**Creating a workflow**

Automatically handle the transition after workflow execution

```
use Illuminate\Database\Eloquent\Model;
use LenderSpender\StateTransitionWorkflow\Transition;
use LenderSpender\StateTransitionWorkflow\Workflow;

class PaidWorkflow extends Workflow
{
    /**
     * @param \App\Model\Transaction $model
     */
    public function execute(Model $transaction, Transition $transition): void
    {
         dump('This is executed before the transition');
    }
}
```

Handle the transition in the workflow

```
use Illuminate\Database\Eloquent\Model;
use LenderSpender\StateTransitionWorkflow\Transition;
use LenderSpender\StateTransitionWorkflow\Workflow;

class PaidWorkflow extends Workflow
{
    /**
     * @param \App\Model\Transaction $model
     */
    public function execute(Model $transaction, Transition $transition): void
    {
         dump('This is executed before the transition');
         $transition->execute();
         dump('This is executed after the transition');
    }
}
```

**Queuing transitions**

When you want to perform some heavy actions before or after the transition you could queue the transition by implementing the `ShouldQueue` interface on the workflow.

```
use Illuminate\Contracts\Queue\ShouldQueue;
use LenderSpender\StateTransitionWorkflow\Workflow;

class PaidWorkflow extends Workflow implements ShouldQueue
{
}
```

**Preventing transitions**

Transitions can be prevented when you override the `isAllowed` method and return false in the workflow.

```
use LenderSpender\StateTransitionWorkflow\Workflow;

class PaidWorkflow extends Workflow
{
    public function isAllowed(Transition $transition): bool
    {
        return false;
    }
}
```

**Registering a workflow to a state transition**

```
class Transaction extends Model
{
    use HasStateTransitions;

    protected function registerStateTransitions(): void
    {
        $this->addState('status')
            ->allowTransitions(State::CREATED(), State::SUCCESS(), PaidWorkflow::class);
    }
}
```

###  Health Score

43

—

FairBetter than 91% of packages

Maintenance44

Moderate activity, may be stable

Popularity22

Limited adoption so far

Community14

Small or concentrated contributor base

Maturity78

Established project with proven stability

 Bus Factor1

Top contributor holds 68.6% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~112 days

Recently: every ~264 days

Total

18

Last Release

440d ago

Major Versions

0.3.0 → 1.0.02020-03-02

1.4.0 → 2.0.02022-04-04

2.0.0 → 3.0.02023-03-07

3.0.0 → 4.0.02023-09-14

PHP version history (6 changes)0.1.0PHP ^7.3.0

1.0.0PHP ^7.4.0

1.0.3PHP ^7.4.0|^8.0

1.1.0PHP ^7.4.0 | ^8.0

1.4.0PHP ^8.1

3.0.0PHP ^8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/e2eae33c118381c1dbf6d8b453fea64da00f72fc2996f188126f3a533b32c4a4?d=identicon)[huubvdw](/maintainers/huubvdw)

---

Top Contributors

[![BertvanHoekelen](https://avatars.githubusercontent.com/u/7521173?v=4)](https://github.com/BertvanHoekelen "BertvanHoekelen (24 commits)")[![DanielGSoftware](https://avatars.githubusercontent.com/u/49187378?v=4)](https://github.com/DanielGSoftware "DanielGSoftware (7 commits)")[![huubvdw](https://avatars.githubusercontent.com/u/11613086?v=4)](https://github.com/huubvdw "huubvdw (3 commits)")[![dyhli](https://avatars.githubusercontent.com/u/5570221?v=4)](https://github.com/dyhli "dyhli (1 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/lenderspender-laravel-state-transition-workflow/health.svg)

```
[![Health](https://phpackages.com/badges/lenderspender-laravel-state-transition-workflow/health.svg)](https://phpackages.com/packages/lenderspender-laravel-state-transition-workflow)
```

###  Alternatives

[anourvalar/eloquent-serialize

Laravel Query Builder (Eloquent) serialization

11320.2M21](/packages/anourvalar-eloquent-serialize)[namu/wirechat

A Laravel Livewire messaging app for teams with private chats and group conversations.

54324.5k](/packages/namu-wirechat)[statamic-rad-pack/runway

Eloquently manage your database models in Statamic.

135192.6k5](/packages/statamic-rad-pack-runway)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
