troojaan/laravel-state-machine

Winzou 状态机服务提供者,适用于 Laravel

v1.2.4 2018-02-17 17:34 UTC

This package is not auto-updated.

Last update: 2024-09-29 05:31:42 UTC


README

Latest Version on Packagist Software License Build Status Scrutinizer Code Quality StyleCI

这是一个用于 winzou/state-machine 的 Laravel 服务提供者。

特性

  • 它为 StateMachineFactory 提供依赖注入。

  • 您可以使用 Laravel 的服务容器来解析回调函数的方法及其依赖项。

  • 它允许您使用 Laravel 的事件调度器监听转换事件。

  • 还提供了一个门面,方便使用。

安装

您可以通过 composer 安装此包。此包需要 Laravel 5.1 或更高版本。

composer require troojaan/laravel-state-machine

从版本 5.5 开始,Laravel 使用包自动发现,因此您不需要手动添加 ServiceProvider 和门面。如果您不使用自动发现或使用的是旧版本,请在 config/app.php 中添加 ServiceProvider 和门面。

<?php

'providers' => [
    troojaan\SM\ServiceProvider::class,
],

'aliases' => [
    'StateMachine' => troojaan\SM\Facade::class,
],

配置

发布配置文件 config/state-machine.php

php artisan vendor:publish --provider="troojaan\SM\ServiceProvider"

有关所有可用选项,请参阅 StateMachineBundle 的文档。

用法

<?php

// Get the article
$article = App\Article::find($id);

// Get the state machine for this article, and graph called "simple"

// Using the facade
$stateMachine = StateMachine::get($article, 'simple');

// Or using the service container with dependency injection
public function method(SM\Factory\FactoryInterface $factory)
{
    $stateMachine = $factory->get($article, 'simple');
}

现在您可以使用 $stateMachine$article 的状态进行交互。

<?php

// Get the actual state of the object
$stateMachine->getState();

// Get all available transitions
$stateMachine->getPossibleTransitions();

// Check if a transition can be applied: returns true or false
$stateMachine->can('approve');

// Apply a transition
$stateMachine->apply('publish');

回调

回调用于保护转换或在应用转换前后执行一些代码。

此包增加了从 Laravel 的服务容器中解析回调并注入其依赖项的能力。

定义回调

在您的配置中 callbacks.guard 数组下,添加一个关联数组来定义回调。数组的键可以是您想要的任何内容(例如,guard_on_submitting)。此数组必须有一个条款、一个回调,并且可以有一些参数。

条款

首先,您需要指定一个条款,以确定何时调用回调。条款有一个键(fromtoonexcluded_fromexcluded_toexcluded_on)和其值是应满足条款的状态或转换。

例如,'on' => 'submit_changes' 将在检查或应用转换 submit changes 时触发。

回调

其次,您需要在 do 键下指定将被调用的回调。回调必须是 callable,可以是以下之一

闭包
'do' => function () {
    // 
},
作为字符串的内置或用户定义函数
`do` => 'abort',
作为数组的类方法

类通过服务容器及其依赖项解析。

'do' => ['MyService', 'handle'],
作为字符串的类方法
`do` => 'MyService@handle',
参数
使用依赖注入

默认情况下,如果您在数组中 指定 args 键,所有回调方法参数将通过 Laravel 的服务容器自动注入,就像 Route/Controller 方法一样。

类型提示

所有类型提示参数都从容器中解析,例如 App $app

状态机中的对象

如果参数与关联到状态机的对象具有相同的类型提示,例如 App\Article $article,则将注入实例。

状态机事件

如果参数具有状态机事件类型提示,例如 SM\Event\TransitionEvent $e,则将注入在状态机中触发的事件。或者,您也可以定义一个不带类型提示的名为 $event 的参数。

使用 ExpressionLanguage 语法

否则,您可以通过使用 args 键来定义一个或多个将按给定顺序显式传递给回调的参数。此包使用 Symfony 的 ExpressionLanguage 语法来评估表达式。

以下是一些示例

<?php

// The callback won't be passed any argument
'args' => [],

// You can pass strings and arrays as JSON-like strings.
'args' => ['"approved"', '["foo", "bar"]', '{"foo": "bar"}'],

// The callback will receive the object that is associated with the state machine,
// e.g. the `$article`.
'args' => ['object'],

// The callback will receive the `SM\Event\TransitionEvent` instance.
'args' => ['event'],

示例

您需要在MyService类上调用handle方法来确定状态机是否可以应用submit_changes转换。handle方法将状态机对象作为第一个参数接收,将转换事件作为第二个参数接收。

<?php

'callbacks' => [
    // will be called when testing a transition
    'guard' => [
        'guard_on_submitting' => [
            // call the callback on a specific transition
            'on' => 'submit_changes',

            // will call the method of this class
            'do' => ['MyService', 'handle'],

            // arguments for the callback
            'args' => ['object', 'event'],
        ],
    ],
],

事件

在检查转换是否可以应用时,将触发SM\Event\SMEvents::TEST_TRANSITION事件。

在应用转换之前和之后,分别触发SM\Event\SMEvents::PRE_TRANSITIONSM\Event\SMEvents::POST_TRANSITION事件。

所有事件都接收一个SM\Event\TransitionEvent实例。

如果您希望使用相同的监听器监听所有事件,可以使用winzou.state_machine.*通配符参数。

您可以在应用的EventServiceProvider中定义自己的监听器。例如:

<?php

use SM\Event\SMEvents;

/**
 * The event listener mappings for the application.
 *
 * @var array
 */
protected $listen = [
    SMEvents::TEST_TRANSITION => [
        \App\Listeners\CheckTransition::class,
    ],
    SMEvents::PRE_TRANSITION => [
        \App\Listeners\BeforeTransition::class,
    ],
    SMEvents::POST_TRANSITION => [
        \App\Listeners\AfterTransition::class,
    ],
    'winzou.state_machine.*' => [
        \App\Listeners\Transition::class,
    ],
];

调试命令

包含了一个用于调试图的artisan命令。它接受图名作为参数。如果没有传递参数,将交互式地询问图名。

$ php artisan winzou:state-machine:debug simple

+--------------------+
| Configured States: |
+--------------------+
| new                |
| pending_review     |
| awaiting_changes   |
| accepted           |
| published          |
| rejected           |
+--------------------+
+-----------------+------------------+------------------+
| Transition      | From(s)          | To               |
+-----------------+------------------+------------------+
| create          | new              | pending_review   |
+-----------------+------------------+------------------+
| ask_for_changes | pending_review   | awaiting_changes |
|                 | accepted         |                  |
+-----------------+------------------+------------------+
| cancel_changes  | awaiting_changes | pending_review   |
+-----------------+------------------+------------------+
| submit_changes  | awaiting_changes | pending_review   |
+-----------------+------------------+------------------+
| approve         | pending_review   | accepted         |
|                 | rejected         |                  |
+-----------------+------------------+------------------+
| publish         | accepted         | published        |
+-----------------+------------------+------------------+

变更日志

请参阅变更日志了解最近有哪些更改。

测试

$ composer test

贡献

有关详细信息,请参阅贡献指南

安全

如果您发现任何与安全相关的问题,请通过电子邮件将问题发送至Sébastien(info@sebdesign.eu),而不是使用问题跟踪器。

鸣谢

许可证

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