A simple state machine that allows transitioning model states based on pre-defined rules.
You can install the package via composer:
composer require jxckaroo/laravel-state-machine
Run the package migrations:
php artisan migrate
Add the Jxckaroo\StateMachine\Stateable
trait to your model(s) that require state management & define your states on your model(s):
Below is an example of a ready-to-go model.
use Illuminate\Database\Eloquent\Model;
use Jxckaroo\StateMachine\Stateable;
class Order extends Model
{
use Stateable;
protected array $states = [
'factory' => ExampleRule::class,
'complete' => [
ExampleRule::class,
ExampleRuleFalse::class
]
];
// ...
}
When defining your states, you can specify either one or many rules as above. Your rules must extend Jxckaroo\StateMachine\Contracts\StateRule
and must contain a validate
method as per the below example:
class ExampleRule extends StateRule
{
public function validate(Model $model): bool
{
return $model->getKey() !== null;
}
}
You can also add specific error messages when a validation fails, like so:
class ExampleRuleFailure extends StateRule
{
public function validate(Model $model): bool
{
if (!$model->isProductionReady()) {
$this->addError("Model is not ready for production.");
return false;
}
return true;
}
}
These error messages can then be retrieved by calling $model->stateErrors()
after attempting to transition state, resulting in a collection of errors returning, like below:
Illuminate\Support\Collection Object
(
[items:protected] => Array
(
[0] => Array
(
[message] => Model is not ready for production.
[rule] => Jxckaroo\StateMachine\Rules\ExampleRuleFailure
)
)
[escapeWhenCastingToString:protected] =>
)
// Get model
$order = Order::find(1);
// Get current state of a model
$order->state;
// Get the state history of a model
$order->stateHistory;
// Attempt to transition model to one of your defined states
$order->transitionToState("factory");
// Attempt to transition model to previous state as defined in $order->states
$order->transitionToPreviousState();
// Attempt to transition model to next state as defined in $order->states
$order->transitionToNextState();
// Get all available states on model
$order->states();
Check if a state transition is successful:
$order = Order::find(1);
if ($order->transitionToState("complete")->isSuccessful()) {
// Successful transition
} else {
// Get a collection of all rules that failed
$order->stateErrors();
}
composer test
Please see CHANGELOG for more information what has changed recently.
Please see CONTRIBUTING for details.
If you discover any security related issues, please email [email protected] instead of using the issue tracker.
The MIT License (MIT). Please see License File for more information.
This package was generated using the Laravel Package Boilerplate.