PHPackages                             dor-denis/validated-statemachine - 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. dor-denis/validated-statemachine

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

dor-denis/validated-statemachine
================================

Configurable state machine with ability to validate transitions

0.0.4(7y ago)91.4kMITPHP

Since Sep 20Pushed 7y agoCompare

[ Source](https://github.com/dor-denis/validated-statemachine)[ Packagist](https://packagist.org/packages/dor-denis/validated-statemachine)[ RSS](/packages/dor-denis-validated-statemachine/feed)WikiDiscussions master Synced 4w ago

READMEChangelogDependencies (3)Versions (4)Used By (0)

Validated Statemachine for PHP
==============================

[](#validated-statemachine-for-php)

A simple statemachine with ability to validate transitions.

Usage
-----

[](#usage)

You can add the State Machine behavior to any PHP class by using *StateMachine* trait provided by this package.

```
class StateMachineModel
{
    use StateMachine;

    public $stateId = 100;

    protected function getStateProperty()
    {
        return 'stateId';
    }

    protected function getSpecification()
    {
        return new ExampleStateMachineSpecification();
    }
}
```

You'll need to implement two methods:

- `getStateProperty()` - returns a string with the name of property holding the state value
- `getSpecification()` - returns an instance of the class extending StateMachineSpecification

### State Property

[](#state-property)

If your project uses some kind of ActiveRecord approach to store models, the state value can be also persisted to the DB. To set initial state of the state machine, set default value of your property to it.

### State Machine Trait

[](#state-machine-trait)

StateMachine trait offers you next methods:

- *setState()* - sets current state of the model
- *getState()* - gets current state of the model (as *State* instance)
- *getAvailableTransitions()* - gets available transitions of the current model (as array of *Transition* objects)
- *canExecuteTransition()* - whether it is possible to execute a transition given as a param
- *executeTransition()* - execute the transition, returns `true` or `false` upon success/fail.
- *getValidationError()* - returns the validator class name which failed during last transition attempt.

For example of usage, see example/ folder

### State Machine Specification

[](#state-machine-specification)

The state machine specification is basically a configuration of your state machine which lists all possible states and transitions between them.

The example is listed below

```
class ExampleStateMachineSpecification extends StateMachineSpecification
{
    const STATE_1 = 100;
    const STATE_2 = 200;
    const STATE_3 = 300;
    const STATE_4 = 400;

    const TRANSITION_FROM1_TO_2 = "from_1_to_2";
    const TRANSITION_FROM3_TO_4 = "from_3_to_4";

    public function getStateDefinitions()
    {
        return [
            self::STATE_1 => [],
            self::STATE_2 => [],
            self::STATE_3 => [],
            self::STATE_4 => [],
        ];
    }

    public function getTransitionDefinitions()
    {
        return [
            self::TRANSITION_FROM1_TO_2 => [
                'from' => self::STATE_1,
                'to'   => self::STATE_2
            ],
            self::TRANSITION_FROM3_TO_4 => [
                'from' => self::STATE_3,
                'to'   => self::STATE_4,
                'validators' => [
                    ['app\Validator1', ['exampleParam']],
                    ['app\Validator2', []]
                ]
            ],
        ];
    }
}
```

We've set state names to numbers so we could later sort them in DB by priority. You can also use strings or that.

In *StateMachineSpecification* class, you need to implement two methods:

- *getStateDefinitions* - returns array where keys are state names and values are payloads of each state (will be available to you when you'll call the *getState()* methon on StateMachine model). Can be also an array of *State* objects
- *getTransitionDefinitions* - returns array where keys are transition names, and values are arrays with next obligatory keys:
    - *from* - the state name **from** which the model can go with this transition;
    - *to* - the state name **to** which the model can go with this transition;
    - *validators* - the class names or instances of classes implementing *Validator* interface, and params for them (discussed below)
    - Remark: can be also an array of *Transition* objects

### Validators

[](#validators)

You can validate your transitions by mentioning classes implementing *Validator* interface in `'validators'` key of `getTransitionDefinitions()`result array.

While performing the transition, the validators are being iterated and executed. If at least one validator returns false in the `validate()` method, the `$error` property of the state machine model will tell you which validator failed, and the `executeTransition()` method will return false

An example of the Validator:

```
class Validator2 implements \ValidatedStatemachine\models\Validator
{
    public function validate(Transition $transition, $model)
    {
        return !empty($model->shouldExecuteTransition) && $model->shouldExecuteTransition === true;
    }
}
```

The parameters passed to validator are Transition object and the state machine model.

If some params are passed to validator (like *exampleParam* in Validator1 in the example), they will be passed to `__constructor()`method of the validator.

### Events

[](#events)

The Symfony's EventDispatcher events are thrown:

- *transition.executed* - when the transition has been successfully executed
- *transition.failed* - if the transition failed

To subscribe to events, use `EventDispatcherSingleton::getDispatcher()` object. For more info on Symfony event dispatcher, check out it's documentation

### Visualization

[](#visualization)

The *HtmlVisualization* class allows you to create a visualization for your state machine using the [sigma.js](http://sigmajs.org/) library. It is using ForceAtlas2 algorithm to distribute the states (the nodes of the graph) and then you can drag them as you like. After that you can print the result.

[![State machine](https://github.com/dor-denis/validated-statemachine/raw/master/example/vizualize.png)](https://github.com/dor-denis/validated-statemachine/raw/master/example/vizualize.png)

###  Health Score

29

—

LowBetter than 57% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity20

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity55

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 50% 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 ~363 days

Total

3

Last Release

2841d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/7440760?v=4)[Denis Dorofeiev](/maintainers/dor-denis)[@dor-denis](https://github.com/dor-denis)

---

Top Contributors

[![denys-westwing](https://avatars.githubusercontent.com/u/75317693?v=4)](https://github.com/denys-westwing "denys-westwing (6 commits)")[![dor-denis](https://avatars.githubusercontent.com/u/7440760?v=4)](https://github.com/dor-denis "dor-denis (6 commits)")

---

Tags

eventstatestatemachinevalidate

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/dor-denis-validated-statemachine/health.svg)

```
[![Health](https://phpackages.com/badges/dor-denis-validated-statemachine/health.svg)](https://phpackages.com/packages/dor-denis-validated-statemachine)
```

###  Alternatives

[winzou/state-machine

A very lightweight yet powerful PHP state machine

52413.9M18](/packages/winzou-state-machine)[symfony/workflow

Provides tools for managing a workflow or finite state machine

62944.6M239](/packages/symfony-workflow)[sebdesign/laravel-state-machine

Winzou State Machine service provider for Laravel

3411.4M1](/packages/sebdesign-laravel-state-machine)[yohang/finite

A simple PHP Finite State Machine

1.3k3.6M10](/packages/yohang-finite)[iben12/laravel-statable

Statable trait for Laravel Eloquent models

96312.6k1](/packages/iben12-laravel-statable)[gomachan46/state-machine

simple state machine with annotations for PHP, inspired by AASM known as a Ruby state machine.

1896.3k](/packages/gomachan46-state-machine)

PHPackages © 2026

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