XState is a state machine library to play with any complex behavior of your PHP objects (inspired by xstate.js)
The recommended way to install Xstate is through Composer
composer require mouadziani/xstate
Let's say we want to define a state machine workflow for a video object, generally a video may have 3 states (playing, stopped, paused),
as a first step you have to create a new object from StateMachine
class
use \Mouadziani\XState\StateMachine;
$video = StateMachine::make();
Then you have to define the allowed states as well as the default state
$video
->defaultState('stopped')
->states(['playing', 'stopped', 'paused']);
And finally the transitions
use \Mouadziani\XState\Transition;
$video->transitions([
new Transition('PLAY', ['stopped', 'paused'], 'playing'),
new Transition('STOP', 'playing', 'stopped'),
new Transition('PAUSE', 'playing', 'paused'),
new Transition('RESUME', 'paused', 'playing'),
]);
The Transition
class expect 3 required params:
- Trigger: As a name of the transition which will be used to trigger a specific transition (should be unique)
- From: Expect a string for a single / or array for multiple initial allowed states
- To: Expect string which is the next target state (should match one of the defined allowed states)
You can either define a guard callback for a specific transition using guard
method, which must return a bool. If a guard returns false, the transition cannot be performed.
use \Mouadziani\XState\Transition;
$video->transitions([
(new Transition('PLAY', ['stopped', 'paused'], 'playing'))
->guard(function ($from, $to) {
return true;
})
]);
$video = StateMachine::make()
->defaultState('playing')
->states(['playing', 'stopped', 'paused'])
->transitions([
new Transition('PLAY', ['stopped', 'paused'], 'playing'),
new Transition('STOP', 'playing', 'stopped'),
new Transition('PAUSE', 'playing', 'paused'),
]);
There are two ways to trigger a specific defined transition
1- Using transitionTo
method and specify the name of the transition as an argument
$video->transitionTo('PLAY');
2- Or just calling the name of the transition from your machine object as a method
$video->play();
Occasionally triggering a transition may throw an exception if the target transition is not defined /or not allowed:
use \Mouadziani\XState\Exceptions;
try {
$video->transitionTo('RESUME');
} catch (Exceptions\TransitionNotDefinedException $ex) {
// the target transition is not defined
} catch (Exceptions\TransitionNotAllowedException $ex) {
// the target transition is not allowed
}
echo $video->currentState(); // playing
$video->allowedTransitions(); // ['STOP', 'PAUSE']
$video->addTransition(new Transition('TURN_OFF', 'playing', 'stopped'));
- Add the ability to define guard for a specific transition
- Define/handle hooks before/after triggering transition
composer test
Please review our security policy on how to report security vulnerabilities.
The MIT License (MIT). Please see License File for more information.
featured_repository