Finite State Machine
Finite State Machine implementation in PHP, (*1)
Installation
Install via composer
Add dependency to your composer.json
file and run composer update
., (*2)
"szykra/state-machine": "~0.1.0"
or just run, (*3)
composer require szykra/state-machine
Usage
Prepare your entity to be stateful
Your entity should implements interface StatefulInterface
. It requires two new methods, (*4)
public function getState();
public function setState($state);
Of course you should add new property named e.g. state., (*5)
To control your entity by StateMachine you have to define:, (*6)
- States
- Transitions between States
State
State object simply represents a state. It has name and list of available transitions., (*7)
$stateDraft = new State('draft');
$statePublished = new State('published');
Transition
Transition is like single action which someone performs on an object. It means transition from one state to another state., (*8)
$stateDraft->addTransition('publish', 'draft', 'published');
$transitionReject = new Transition('reject', 'published', 'rejected');
$statePublished->putTransition($transitionReject);
Each state has own transitions so available transitions depend on the current state of object., (*9)
StateMachine
StateMachine is a controller used to change state of stateful object. First you should create a StateMachine object and set up it by adding a valid States., (*10)
$stateMachine = new StateMachine();
// api inconsistent, should called putState
$stateMachine->addState($stateDraft);
$stateMachine->addState($statePublished);
Initialize a State Machine
When your StateMachine is ready you could initialize it by Stateful Object., (*11)
$document = new Document();
$stateMachine->initialize($document);
Now you could change state of $document
by $stateMachine
. To check if transition can be performed use the can($transition)
method, e.g. if current state of $document
is draft the results will be as follows, (*12)
$stateMachine->can('publish'); // true
$stateMachine->can('reject'); // false
To change state of object you should use run($transition)
method. If transition not exists TransitionNotFoundException
will be thrown., (*13)
echo $document->getState(); // draft
$stateMachine->run('publish');
echo $document->getState(); // published
If you want to see a complete example please see tests/ directory., (*14)
To do
- [ ] Ability to setup callbacks before/after change states
- [ ] List all states
- [ ] List all transitions
- [ ] Add configurable loader to StateMachine
- [ ] Add configurable conditionals to transitions
License
The MIT License. Copyright © 2015 by Szymon Krajewski, (*15)