acacha / stateful-eloquent by acacha
forked from mikerice/stateful-eloquent

State machines for Eloquent classes
7,151
11
3
Package Data
Maintainer Username: acacha
Maintainer Contact: mike.hj.rice@gmail.com (Mike Rice)
Package Create Date: 2016-11-20
Package Last Update: 2018-01-12
Language: PHP
License: MIT
Last Refreshed: 2024-11-22 03:13:13
Package Statistics
Total Downloads: 7,151
Monthly Downloads: 4
Daily Downloads: 0
Total Stars: 11
Total Watchers: 3
Total Forks: 6
Total Open Issues: 1

Laravel 5 Eloquent State Machine

If you're familiar with my AASM, then this is a similar take – just implemented in Laravel 5 for Eloquent classes.

References

Forked from https://github.com/mikerice/stateful-eloquent

Installation

Step 1: Install Through Composer

composer require acacha/stateful-eloquent

Step 2: Add the Service Provider

Acacha\Stateful\Providers\StatefulServiceProvider::class,

Step 3: Update your Eloquent Model

Your models should use the Stateful trait and interface

use Acacha\Stateful\Traits\StatefulTrait;
use Acacha\Stateful\Contracts\Stateful;

class Transaction extends Model implements Stateful
{
    use StatefulTrait;
}

Step 4: Create your Model States

Your models should have an array name $states that define your model states.

/**
 * Transaction States
 *
 * @var array
 */
protected $states = [
    'draft' => ['initial' => true],
    'processing',
    'errored',
    'active',
    'closed' => ['final' => true]
];

Step 5: Create your Model State Transitions

/**
 * Transaction State Transitions
 *
 * @var array
 */
protected $transitions = [
    'process' => [
        'from' => ['draft', 'errored'],
        'to' => 'processing'
    ],
    'activate' => [
        'from' => 'processing',
        'to' => 'active'
    ],
    'fail' => [
        'from' => 'processing',
        'to' => 'errored'
    ],
    'close' => [
        'from' => 'active',
        'to' => 'close'
    ]
];

    /**
     * @return bool
     */
    protected function validateProcess()
    {
        $validate = true;
        if (!$validate) {
            $this->addValidateProcessMessage();
        }

        return $validate;
    }

    /**
     * @return bool
     */
    protected function validateActivate()
    {
        //dd("validateActivate");
        return true;
    }

    /**
     * @return bool
     */
    protected function validateFail()
    {
        //dd("validateFail");
        return true;
    }

    /**
     * @return bool
     */
    protected function validateClose()
    {
        //dd("validateClose");
        return true;
    }

    protected function beforeProcess() {
        //dd("doing something before entering processing state");
    }

    protected function afterProcess() {
        //dd("doing something after leaving processing state");
    }

Database configuration

You model migration should have a state field like:

class CreateModelTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('model', function (Blueprint $table) {
            $table->increments('id');
            ...
            $table->string('state');
            ...
            $table->timestamps();
        });
    }

Usage

$transaction = new Transaction();

//Execute transition
$transaction->process();

//Check if a state is active (return true or false)
$transaction->active();