dor-denis/validated-statemachine

可配置的带有验证转换功能的状态机

0.0.4 2018-09-18 13:32 UTC

This package is not auto-updated.

Last update: 2024-09-14 18:53:14 UTC


README

一个具有验证转换功能的基本状态机。

用法

您可以使用此包提供的 StateMachine 特性将状态机行为添加到任何 PHP 类。

class StateMachineModel
{
    use StateMachine;

    public $stateId = 100;

    protected function getStateProperty()
    {
        return 'stateId';
    }
    
    protected function getSpecification()
    {
        return new ExampleStateMachineSpecification();
    }
}

您需要实现两个方法

  • getStateProperty() - 返回一个包含状态值属性名称的字符串
  • getSpecification() - 返回一个扩展 StateMachineSpecification 类的实例

状态属性

如果您的项目使用某种 ActiveRecord 方法来存储模型,状态值也可以持久化到数据库。要设置状态机的初始状态,请将属性的默认值设置为它。

状态机特性

状态机特性为您提供以下方法

  • setState() - 设置模型的当前状态
  • getState() - 获取模型的当前状态(作为 State 实例)
  • getAvailableTransitions() - 获取当前模型的可用转换(作为 Transition 对象的数组)
  • canExecuteTransition() - 是否可以执行给定的转换
  • executeTransition() - 执行转换,成功或失败时返回 truefalse
  • getValidationError() - 返回在最后一次转换尝试中失败的验证器类名。

例如,请参阅 example/ 文件夹

状态机规范

状态机规范基本上是您的状态机的配置,列出了所有可能的状态以及它们之间的转换。

以下是一个例子

class ExampleStateMachineSpecification extends StateMachineSpecification
{
    const STATE_1 = 100;
    const STATE_2 = 200;
    const STATE_3 = 300;
    const STATE_4 = 400;

    const TRANSITION_FROM1_TO_2 = "from_1_to_2";
    const TRANSITION_FROM3_TO_4 = "from_3_to_4";

    public function getStateDefinitions()
    {
        return [
            self::STATE_1 => [],
            self::STATE_2 => [],
            self::STATE_3 => [],
            self::STATE_4 => [],
        ];
    }

    public function getTransitionDefinitions()
    {
        return [
            self::TRANSITION_FROM1_TO_2 => [
                'from' => self::STATE_1,
                'to'   => self::STATE_2
            ],
            self::TRANSITION_FROM3_TO_4 => [
                'from' => self::STATE_3,
                'to'   => self::STATE_4,
                'validators' => [
                    ['app\Validator1', ['exampleParam']],
                    ['app\Validator2', []]
                ]
            ],
        ];
    }
}

我们将状态名称设置为数字,以便我们可以在以后按优先级对它们进行排序。您也可以使用字符串或数字。

StateMachineSpecification 类中,您需要实现两个方法

  • getStateDefinitions - 返回一个数组,其中键是状态名称,值是每个状态的有效载荷(将在您调用 StateMachine 模型的 getState() 方法时可用)。也可以是 State 对象的数组
  • getTransitionDefinitions - 返回一个数组,其中键是转换名称,值是包含以下必选键的数组
    • from - 模型可以通过此转换进入的 from 状态名称;
    • to - 模型可以通过此转换进入的 to 状态名称;
    • validators - 实现 Validator 接口的类名或类的实例,以及它们的参数(如下文所述)
    • 注意:也可以是 Transition 对象的数组

验证器

您可以通过在 getTransitionDefinitions() 结果数组的 'validators' 键中提及实现 Validator 接口的类来验证您的转换。

在执行转换时,验证器将被迭代和执行。如果至少有一个验证器在 validate() 方法中返回 false,状态机模型的 $error 属性将告诉您哪个验证器失败了,并且 executeTransition() 方法将返回 false。

验证器的示例

class Validator2 implements \ValidatedStatemachine\models\Validator
{
    public function validate(Transition $transition, $model)
    {
        return !empty($model->shouldExecuteTransition) && $model->shouldExecuteTransition === true;
    }
}

传递给验证器的参数是转换对象和状态机模型。

如果传递了参数给验证器(如示例中的 Validator1 中的 exampleParam),则这些参数将传递给验证器的 __constructor() 方法。

事件

抛出 Symfony 的 EventDispatcher 事件

  • transition.executed - 当过渡操作成功执行时
  • transition.failed - 如果过渡操作失败

要订阅事件,请使用 EventDispatcherSingleton::getDispatcher() 对象。有关 Symfony 事件分发器的更多信息,请查阅其文档。

可视化

使用 HtmlVisualization 类,您可以使用 sigma.js 库为您的状态机创建可视化。它使用 ForceAtlas2 算法来分布状态(图中的节点),然后您可以随意拖动它们。之后,您可以打印出结果。

State machine