A simple laravel state machine to handle model transitions, based on a pre-defined list of rules

Overview

Latest Version on Packagist Total Downloads GitHub Actions GitHub Actions GitHub Actions

A simple state machine that allows transitioning model states based on pre-defined rules.

Installation

You can install the package via composer:

composer require jxckaroo/laravel-state-machine

Run the package migrations:

php artisan migrate

Usage

Add the Jxckaroo\StateMachine\Stateable trait to your model(s) that require state management & define your states on your model(s):

States & Rules

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] =>
)

Model Interactions

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();">
// 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:

isSuccessful()) { // Successful transition } else { // Get a collection of all rules that failed $order->stateErrors(); }">
$order = Order::find(1);

if ($order->transitionToState("complete")->isSuccessful()) {
    // Successful transition
} else {
    // Get a collection of all rules that failed
    $order->stateErrors();
}

Testing

composer test

Changelog

Please see CHANGELOG for more information what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security

If you discover any security related issues, please email [email protected] instead of using the issue tracker.

Credits

License

The MIT License (MIT). Please see License File for more information.

Laravel Package Boilerplate

This package was generated using the Laravel Package Boilerplate.

You might also like...
For using Laravel with a pre-existing MySQL Database

MySQL to Laravel This is a script to help with mapping an existing MySQL database to a new Laravel build. Place the script in the public folder of you

Git pre-commit hook for Laravel Pint

Laravel Pint githook Git pre-commit hook for Laravel Pint Automatically formats and saves code on commit You no longer need to run the ./vendor/bin/pi

Active State Helper for Laravel Blade

laravel-activehelper Active State Helper for Laravel Blade Lightweight and simple Introduction Basically we do like this. li class="sidebar {{ Reques

Livewire component that provides you with a modal that supports multiple child modals while maintaining state.
Livewire component that provides you with a modal that supports multiple child modals while maintaining state.

About LivewireUI Modal LivewireUI Modal is a Livewire component that provides you with a modal that supports multiple child modals while maintaining s

Livewire component that provides you with a modal that supports multiple child modals while maintaining state.
Livewire component that provides you with a modal that supports multiple child modals while maintaining state.

About Wire Elements Modal Wire Elements Modal is a Livewire component that provides you with a modal that supports multiple child modals while maintai

This tool gives you the ability to set the default collapse state for Nova 4.0 menu items.

Nova Menu Collapsed This tool gives you the ability to set the default collapse state for Nova 4.0 menu items. Requirements php: =8.0 laravel/nova: ^

States allows you to create PHP classes following the State Pattern in PHP.

States allows you to create PHP classes following the State Pattern in PHP. This can be a cleaner way for an object to change its behavior at runtime without resorting to large monolithic conditional statements and this improve maintainability and workflows writing.

Simple package to handle response properly in your API.

Simple package to handle response properly in your API. This package uses Fractal and is based on Build APIs You Won't Hate book.

A simple Laravel event log package for easy model based logging.

Karacraft Logman A simple Model Event Logging Package Usage Installation composer require karacraft/logman Migrate php artisan migrate Publish php a

Releases(v1.1.0)
Owner
Jack Mollart
Backend Engineer | Technology Enthusiast
Jack Mollart
A simple laravel package to handle multiple key based model route binding

Laravel Model UUID A simple package to handle the multiple key/column based route model binding for laravel package Installation Require the package u

null 13 Mar 2, 2022
A laravel package to handle cascade delete and restore on model relations.

Laravel Model Soft Cascade A laravel package to handle cascade delete and restore on model relations. This package not only handle the cascade delete

Touhidur Rahman 18 Apr 29, 2022
A laravel package to handle model specific additional meta fields in an elegant way.

Laravel Meta Fields A php package for laravel framework to handle model meta data in a elegant way. Installation Require the package using composer: c

Touhidur Rahman 26 Apr 5, 2022
A laravel package to generate model hashid based on model id column.

Laravel Model Hashid A package to generate model hash id from the model auto increment id for laravel models Installation Require the package using co

Touhidur Rahman 13 Jan 20, 2022
A package to filter laravel model based on query params or retrieved model collection

Laravel Filterable A package to filter laravel model based on query params or retrived model collection. Installation Require/Install the package usin

Touhidur Rahman 17 Jan 20, 2022
Library that offers Input Filtering based on Annotations for use with Objects. Check out 2.dev for 2.0 pre-release.

DMS Filter Component This library provides a service that can be used to filter object values based on annotations Install Use composer to add DMS\Fil

Rafael Dohms 89 Nov 28, 2022
A collection of pre-made simple Laravel Blade form components.

Laravel Form Components Library A collection of pre-made simple Laravel Blade form components. Installation & setup You can install the package via co

null 3 Oct 5, 2022
This Laravel package merges staudenmeir/eloquent-param-limit-fix and staudenmeir/laravel-adjacency-list to allow them being used in the same model.

This Laravel package merges staudenmeir/eloquent-param-limit-fix and staudenmeir/laravel-adjacency-list to allow them being used in the same model.

Jonas Staudenmeir 5 Jan 6, 2023
Turn any Eloquent model into a list!

Listify Turn any Eloquent model into a list! Description Listify provides the capabilities for sorting and reordering a number of objects in a list. T

Travis Vignon 138 Nov 28, 2022
Laravel-model-mapper - Map your model attributes to class properties with ease.

Laravel Model-Property Mapper This package provides functionality to map your model attributes to local class properties with the same names. The pack

Michael Rubel 15 Oct 29, 2022