iben12/laravel-statable

为 Laravel Eloquent 模型提供状态管理特性

v1.5.1 2021-07-15 21:15 UTC

This package is auto-updated.

Last update: 2024-09-16 04:18:39 UTC


README

Run tests StyleCI Scrutinizer Code Quality

本特性提供了基于 winzou/state-machinesebdesign/laravel-state-machine 服务提供者的状态机和状态历史管理功能,可以无缝集成到现有的 Eloquent 模型中。

安装

兼容性

如果您的 Laravel 版本低于 5.5,则需要显式要求 0.1 版本。对于 Laravel 低于 7 的版本,需要版本 v1.3

使用 composer 拉取包

$ composer require iben12/laravel-statable

发布数据库迁移和状态机配置

$ php artisan vendor:publish --provider="Iben\Statable\ServiceProvider"

迁移数据库

$ php artisan migrate

此迁移会创建一个存储模型历史记录的多态关系表。

用法

先决条件

  • 具有一些状态属性的模型类(示例中使用 last_state 属性)

配置

在这个指南中,我们将使用 Post 模型作为示例。

首先,您需要配置状态机图。打开 config/state-machine.php 并定义一个新的图

return [
    'post' => [
        'class' => App\Post::class,
        'graph' => 'post',

        'property_path' => 'last_state', // should exist on model

        'states' => [
            'draft',
            'published',
            'archived'
        ],
        'transitions' => [
            'publish' => [
                'from' => ['draft'],
                'to' => 'published'
            ],
            'unpublish' => [
                'from' => ['published'],
                'to' => 'draft'
            ],
            'archive' => [
                'from' => ['draft', 'published'],
                'to' => 'archived'
            ],
            'unarchive' => [
                'from' => ['archived'],
                'to' => 'draft'
            ]
        ],
        'callbacks' => [
            'after' => [
                'history' => [
                    'do' => 'StateHistoryManager@storeHistory'
                ]
            ]
        ]
    ]
]

现在您需要编辑 Post 模型

namespace App;

use \Illuminate\Database\Eloquent\Model;
use \Iben\Statable\Statable;

class Post extends Model
{
    use Statable;

    protected function getGraph()
    {
    	return 'post'; // the SM config to use
    }
}

就这样!

用法

现在您可以在模型上访问以下方法

$post = \App\Post::first();

$post->last_state; // returns current state

try {
    $post->apply('publish'); // applies transition
} catch (\SM\SMException $e) {
    abort(500, $e->getMessage()); // if transition is not allowed, throws exception
}

$post->canApply('publish'); // returns boolean

$post->stateHistory()->get(); // returns PostState collection for the given Post

$post->stateHistory()->where('user_id', \Auth::id())->get(); // you can query history as any Eloquent relation

注意:在应用转换时,历史记录会保存当前认证用户。这在大多数情况下是有意义的,但如果您不使用默认的 Laravel 认证,则可以重写 getActorId 方法来存储具有历史记录的用户。

class Post extends Model
{
    // ...

    public function getActorId()
    {
        // return id;
    }
}

如果模型是新建的(从未保存过),在应用转换时没有 id,则不会保存历史记录。如果您想确保所有转换都保存在历史记录中,可以在模型中添加此方法

    protected function saveBeforeTransition()
    {
        return true;
    }

状态机

sebdesign/laravel-state-machine 提供了许多功能

  • 使用权限和策略
  • 事件
  • 守卫或其它任务的回调

您可以在 仓库中 找到文档。

如果您想直接与模型的 StateMachine 对象交互,请调用 $model->stateMachine()

许可协议

MIT 许可协议(MIT)。有关更多信息,请参阅 许可文件