108 lines
4.2 KiB
Markdown
108 lines
4.2 KiB
Markdown
A very lightweight yet powerful PHP state machine
|
|
=================================================
|
|
|
|
Define your states, define your transitions and your callbacks: we do the rest.
|
|
The era of hard-coded states is over!
|
|
|
|
[](https://travis-ci.org/winzou/state-machine)
|
|
|
|
Installation (via composer)
|
|
---------------
|
|
|
|
```js
|
|
{
|
|
"require": {
|
|
"winzou/state-machine": "~0.1"
|
|
}
|
|
}
|
|
```
|
|
|
|
Usage
|
|
-----
|
|
|
|
### Configure a state machine graph
|
|
|
|
In order to use the state machine, you first need to define a graph. A graph is a definition of states, transitions and optionnally callbacks ; all attached on an object from your domain. Multiple graphes can be attached to the same object.
|
|
|
|
Let's define a graph called *myGraphA* for our `DomainObject` object:
|
|
|
|
```php
|
|
$config = array(
|
|
'graph' => 'myGraphA', // Name of the current graph - there can be many of them attached to the same object
|
|
'property_path' => 'stateA', // Property path of the object actually holding the state
|
|
'states' => array(
|
|
'checkout',
|
|
'pending',
|
|
'confirmed',
|
|
'cancelled'
|
|
),
|
|
'transitions' => array(
|
|
'create' => array(
|
|
'from' => array('checkout'),
|
|
'to' => 'pending'
|
|
),
|
|
'confirm' => array(
|
|
'from' => array('checkout', 'pending'),
|
|
'to' => 'confirmed'
|
|
),
|
|
'cancel' => array(
|
|
'from' => array('confirmed'),
|
|
'to' => 'cancelled'
|
|
)
|
|
),
|
|
'callbacks' => array(
|
|
'guard' => array(
|
|
'guard-cancel' => array(
|
|
'to' => array('cancelled'), // Will be called only for transitions going to this state
|
|
'do' => function() { var_dump('guarding to cancelled state'); return false; }
|
|
)
|
|
),
|
|
'before' => array(
|
|
'from-checkout' => array(
|
|
'from' => array('checkout'), // Will be called only for transitions coming from this state
|
|
'do' => function() { var_dump('from checkout transition'); }
|
|
)
|
|
),
|
|
'after' => array(
|
|
'on-confirm' => array(
|
|
'on' => array('confirm'), // Will be called only on this transition
|
|
'do' => function() { var_dump('on confirm transition'); }
|
|
),
|
|
'to-cancelled' => array(
|
|
'to' => array('cancelled'), // Will be called only for transitions going to this state
|
|
'do' => function() { var_dump('to cancel transition'); }
|
|
),
|
|
'cancel-date' => array(
|
|
'to' => array('cancelled'),
|
|
'do' => array('object', 'setCancelled'),
|
|
),
|
|
)
|
|
)
|
|
);
|
|
```
|
|
|
|
So, in the previous example, the graph has 6 possible states, and those can be achieved by applying some transitions to the object. For example, when creating a new `DomainObject`, you would apply the 'create' transition to the object, and after that the state of it would become *pending*.
|
|
|
|
### Using the state machine
|
|
|
|
#### Definitions
|
|
|
|
The state machine is the object actually manipulating your object. By using the state machine you can test if a transition can be applied, actually apply a transition, retrieve the current state, etc. *A state machine is specific to a couple object + graph.* It means that if you want to manipulate another object, or the same object with another graph, *you need another state machine*.
|
|
|
|
The factory helps you to get the state machine for these couples object + graph. You give an object and a graph name to it, and it will return you the state machine for this couple. If you want to have this factory as a service in your Symfony2 application, please see the [corresponding StateMachineBundle](https://github.com/winzou/StateMachineBundle).
|
|
|
|
#### Usage
|
|
|
|
Please refer to the several examples in the `examples` folder.
|
|
|
|
#### Callbacks
|
|
|
|
Callbacks are used to guard transitions or execute some code before or after applying transitions.
|
|
|
|
Guarding callbacks must return a `bool`. If a guard returns `false`, a transition cannot be performed.
|
|
|
|
|
|
##### Credits
|
|
|
|
This library has been highly inspired by [https://github.com/yohang/Finite](https://github.com/yohang/Finite), but has taken another direction.
|