PHPackages                             masterfri/stateful - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. masterfri/stateful

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

masterfri/stateful
==================

Finite state machine implementation for Laravel 5

v1.1(8y ago)316MITPHPPHP &gt;=5.6.0

Since Jul 16Pushed 8y ago1 watchersCompare

[ Source](https://github.com/masterfri/stateful)[ Packagist](https://packagist.org/packages/masterfri/stateful)[ RSS](/packages/masterfri-stateful/feed)WikiDiscussions master Synced 3d ago

READMEChangelog (2)Dependencies (2)Versions (3)Used By (0)

Introduction
------------

[](#introduction)

Stateful is yet another implementation of finite state machine for Laravel 5. It allows turn any class into stateful entity with minimal efforts. Basic concept of this particular implementation is that changes of state of entities are triggered by signals, that can be sent to entity manually or can be mapped to events.

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

[](#installation)

Stateful can be installed via composer

```
composer require masterfri/stateful

```

If you want to map signals to events, you have to registed service provider in `config/app.php` as follow:

```
'providers' => [
    ...
    Masterfri\Stateful\Providers\StatefulServiceProvider::class,
]

```

Then you need to create `config/stateful.php` with content like this:

```
return [
  'event_mapping' => [
    'eloquent.saving: *' => 'save',
    ...
  ],
];

```

You can define as many relations between events and signals as you need. Different events can be bound to the same signal, as well as one event can trigger different signals.

Defining of stateful entity
---------------------------

[](#defining-of-stateful-entity)

Stateful must implement interface `Masterfri\Stateful\Contracts\Stateful`. Trait `Masterfri\Stateful\Traits\StatefulTrait` contains all necessary methods to control your entity, you only have to implement method `createStateMachine()` when your state machine is defined.

```
public function createStateMachine()
{
  return FSM::build([
    'states' => [ // list of states
      'state1', // state can be defined without options
      'state2' => [ // or with options
        'initial' => true, // optional, defines that state is initial, there must be exactly one initial state
        'enter' => function($entity) {}, // optional, this function is executed when entity enters the state
        'leave' => function($entity) {}, // optional, this function is executed when entity leaves the state
        'finite' => true, // optional, defines that state is finite, there may be any amount of finite states
      ],
    ],
    'transitions' => [ // list of transitions
      [
        'source', // source state name
        'destination', // destination state name
        'signal', // type of signal that can trigger this transition
        'condition' => function($entity, $signal) {}, // optional, this finction is an additional condition that defines if transition has to be triggered
        'transit' => function($entity) {}, // optional, this function is executed when entity goes through the transition
      ]
    ],
  ]);
}

```

Here is a simple example:

```
use Masterfri\Stateful\Contracts\Stateful;
use Masterfri\Stateful\Traits\StatefulTrait;
use Masterfri\Stateful\FSM;

class Order extends Model implements Stateful
{
  use StatefulTrait;
  ...
  public function createStateMachine()
  {
    return FSM::build([
      'states' => [
        'new' => ['initial' => true],
        'placed' => [
          'enter' => function($model) {
            $model->sendCustomerEmail('Your order has been placed', 'placed.tmpl');
          },
        ],
        'processed',
        'shipped' => [
          'enter' => function($model) {
            $model->sendCustomerEmail('Your order has been shipped', 'shipped.tmpl');
          },
        ],
        'completed' => ['finite' => true],
      ],
      'transitions' => [
        // Order is submitted by customer
        ['new', 'placed', 'submit'],
        // Manager processed the order
        ['placed', 'processed', 'process',
          'condition' => function($model) {
            return $model->canBeProcessed();
          }
        ],
        // Manager reviewed order and marked it as non-processable
        ['placed', 'completed', 'process',
          'condition' => function($model) {
            return !$model->canBeProcessed();
          },
          'transit' => function($model) {
            $model->sendCustomerEmail('Sorry your order can not be processed', 'rejected.tmpl');
            $model->markAsRejected();
          }
        ],
        // Manager received information from delivery service and filled out delivery information on the order
        ['processed', 'shipped', 'ship'],
        // Manager received feedback from customer
        ['shipped', 'completed', 'close']
      ]);
  }

```

###  Health Score

26

—

LowBetter than 43% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity9

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity59

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% 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 ~10 days

Total

2

Last Release

3215d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/1f854cc94473cbef444a834643dc9975b1ba2014fb8a3eef16e21363557e0175?d=identicon)[masterfri](/maintainers/masterfri)

---

Top Contributors

[![masterfri](https://avatars.githubusercontent.com/u/299635?v=4)](https://github.com/masterfri "masterfri (9 commits)")

---

Tags

laravelfsm

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/masterfri-stateful/health.svg)

```
[![Health](https://phpackages.com/badges/masterfri-stateful/health.svg)](https://phpackages.com/packages/masterfri-stateful)
```

###  Alternatives

[livewire/volt

An elegantly crafted functional API for Laravel Livewire.

4195.3M84](/packages/livewire-volt)[gehrisandro/tailwind-merge-laravel

TailwindMerge for Laravel merges multiple Tailwind CSS classes by automatically resolving conflicts between them

341682.2k18](/packages/gehrisandro-tailwind-merge-laravel)[nickurt/laravel-akismet

Akismet for Laravel 11.x/12.x/13.x

97139.6k2](/packages/nickurt-laravel-akismet)[whitecube/laravel-timezones

Store UTC dates in the database and work with custom timezones in the application.

106106.2k](/packages/whitecube-laravel-timezones)[sbine/route-viewer

A Laravel Nova tool to view your registered routes.

57215.9k](/packages/sbine-route-viewer)[forxer/laravel-gravatar

A library providing easy gravatar integration in a Laravel project.

4235.6k](/packages/forxer-laravel-gravatar)

PHPackages © 2026

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