joggapp/eloquent-state-machines 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

joggapp/eloquent-state-machines

Composer 安装命令:

composer require joggapp/eloquent-state-machines

包简介

This Laravel package simplifies the creation of state machines for your Eloquent models

README 文档

README

This package simplifies state transitions for Eloquent models by centralizing the transition logic in a single StateMachine class. It allows you to define available transitions between states and handle actions during each transition. Additionally, it automatically records the history of all state transitions for a model.

Installation

Install the package via Composer:

composer require joggapp/eloquent-state-machines

Publish the package's configuration:

php artisan vendor:publish --provider="JoggApp\EloquentStateMachines\EloquentStateMachinesServiceProvider"

Run the migrations:

php artisan migrate

Usage

Defining a StateMachine

Consider an Invoice model with a status field that can have one of the following values: 'draft', 'open', 'paid', 'void', or 'un-collectable'.

We can manage these states and their transitions within a single StateMachine class. To create one, use the following command:

php artisan make:state-machine InvoiceStatusStateMachine

This command will create a new StateMachine class in the App\StateMachines directory.

Within this class, you can define the default state:

public static function defaultState(): ?string
{
    return 'draft';
}

Specify the allowed transitions:

public static function transitions(): array
{
    return [
        'draft' => ['open'],
        'open' => ['paid', 'void', 'un-collectable'],
        'un-collectable' => ['paid'],
        'paid' => null,
        'void' => null,
    ];
}

Enable or disable history logging:

public static function saveTransitions(): bool
{
    return true;
}

Registering the StateMachine

After defining the StateMachine, register it in the Invoice model using the $stateMachines property.

use App\StateMachines\InvoiceStatusStateMachine;
use JoggApp\EloquentStateMachines\Traits\HasStateMachines;

class Invoice extends Model
{
    use HasStateMachines;

    protected $stateMachines = [
        'status' => InvoiceStatusStateMachine::class,
    ];
}

State Machine Methods

By registering $stateMachines in your model, the HasStateMachines trait provides a method to interact with each state field. For example, $invoice->status() can be used to check the current state, apply transitions, and view state history.

Checking State

$invoice->status; // 'draft'

$invoice->status()->is('draft'); // true

$invoice->status()->isNot('draft'); // false

Verify transition

$invoice->status; // 'draft'

$invoice->status()->canTransitionTo('open'); // true

$invoice->status()->canTransitionTo('void'); // false

Transitioning States

To transition from one state to another, use the transitionTo method:

$invoice->status()->transitionTo('open');

You can also pass additional data if needed:

$invoice->status()->transitionTo('open', [
    'terms' => 'net30',
]);

The state machine will verify if the transition is allowed based on the defined transitions(). If the transition is not allowed, an exception will be thrown.

Querying History

If saveTransitions() is set to true in the StateMachine, each state transition will be recorded in the state_transitions table created during installation.

$invoice->status()->history();

Advanced Usage

Override canTransitionTo() Method

By default the canTransitionTo() method uses the transitions defined in our StateMachine's transitions() method. It is possible to override any of the transitions by adding a method with the naming convention canTransitionFrom{Studly Case From State}To{Studly Case To State}().

public function canTransitionFromDraftToOpen(array $data): bool
{
    return $this->model->tasks()->notCompleted()->isEmpty();
}

Override transitionTo() Method

Similar to the canTransitionTo() method, the transitionTo() method can also be modified for any transition. The naming convention for this is:

  • beforeTransitionFrom{Studly Case From State}To{Studly Case To State}()
  • beforeTransitionFrom{Studly Case From State}()
  • beforeTransitionTo{Studly Case To State}()
  • afterTransitionFrom{Studly Case From State}To{Studly Case To State}()
  • afterTransitionFrom{Studly Case From State}
  • afterTransitionTo{Studly Case To State}()
public function beforeTransitionFromDraftToOpen(array $data): void
{
    $this->model->sendPaymentNotification();
}

public function beforeTransitionFromOpen(array $data): void
{
    // Do something before transitioning away from "open" to any state
}

public function afterTransitionFromOpenToVoid(array $data): void
{
    $this->model->delete();
}

public function afterTranstionToPaid(array $data): void
{
    // Do something after transitioning to "paid" from any state
}

统计信息

  • 总下载量: 72
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 0
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 3
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-05-20

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固