ringierimu / state-workflow
Laravel 的状态管理流程
2.3.0
2023-05-31 11:12 UTC
Requires
- php: ^7.3|^8.0
- illuminate/events: ^7|^8|^9|^10.0
- illuminate/support: ^7|^8|^9|^10.0
- symfony/event-dispatcher: ^5.1
- symfony/property-access: ^5.1
- symfony/workflow: ^5.1
Requires (Dev)
- funkjedi/composer-include-files: ^1.0
- laravel/legacy-factories: ^1.1
- mockery/mockery: ^1.3|^1.4.2
- orchestra/database: ^5|^6|^7
- orchestra/testbench: ^5|^6|^7|^8.0
- phpunit/phpunit: ^8|^9
This package is auto-updated.
Last update: 2024-09-01 14:45:29 UTC
README
在 Laravel 中实现 Symfony Workflow 组件
工作流程由状态和动作组成,用于从一个地方移动到另一个地方。动作被称为转换,它描述了如何从一个状态转换到另一个状态。
安装
$ composer require ringierimu/state-workflow
对于低于 5.5 版本的 Laravel,运行上述脚本后此步骤很重要。
- 打开您的 config/app.php 文件并添加自定义服务提供者
Ringierimu\StateWorkflow\StateWorkflowServiceProvider::class
发布 config/workflow.php
文件
$ php artisan vendor:publish --provider="Ringierimu\StateWorkflow\StateWorkflowServiceProvider"
运行迁移
$ php artisan migrate
配置
- 打开
config/workflow.php
并进行配置
// this should be your model name in camelcase. eg. PropertyListing::Class => propertyListing 'post' => [ // class of your domain object 'class' => \App\Post::class, // Register subscriber for this workflow which contains business rules. Uncomment line below to register subscriber //'subscriber' => \App\Listeners\UserEventSubscriber::class, // property of your object holding the actual state (default is "current_state") //'property_path' => 'current_state', //uncomment this line to override default value // list of all possible states 'states' => [ 'new', 'pending_activation', 'activated', 'deleted', 'blocked' ], // list of all possible transitions 'transitions' => [ 'create' => [ 'from' => ['new'], 'to' => 'pending_activation', ], 'activate' => [ 'from' => ['pending_activation'], 'to' => 'activated', ], 'block' => [ 'from' => ['pending_activation', 'activated'], 'to' => 'blocked' ], 'delete' => [ 'from' => ['pending_activation', 'activated', 'blocked'], 'to' => 'deleted', ], ], ],
- 将
HasWorkflowTrait
添加到您的模型类中以支持工作流程
<?php namespace App; use Illuminate\Database\Eloquent\Model; use Ringierimu\StateWorkflow\Traits\HasWorkflowTrait; /** * Class Post * @package App */ class Post extends Model { use HasWorkflowTrait; }
用法
管理状态/工作流程
<?php use App\Post; $post = new Post(); //Apply transition $post->applyTransition("create"); $post = $post->refresh(); //Return current_state value $post->state(); //pending_activation //Check if this transition is allowed $post->canTransition("activate"); // True //Return Model state history $post->stateHistory();
触发事件
每个步骤都会依次触发三个事件
- 针对每个工作流程的事件
- 针对相关工作流程的事件
- 针对具有特定转换或状态名称的相关工作流程的事件
在状态/工作流程转换期间,以下事件按以下顺序触发
- 验证转换是否始终允许。它们的事件监听器在每次调用
workflow()->can()
、workflow()->apply()
或workflow()->getEnabledTransitions()
时被调用。守卫事件
workflow.guard workflow.[workflow name].guard workflow.[workflow name].guard.[transition name]
- 主题即将离开一个状态。
离开事件
workflow.leave workflow.[workflow name].leave workflow.[workflow name].leave.[state name]
- 主题正在经历这个转换。
转换事件
workflow.transition workflow.[workflow name].transition workflow.[workflow name].transition.[transition name]
- 主题即将进入一个新的状态。此事件在主题状态更新之前触发。
进入事件
workflow.enter workflow.[workflow name].enter workflow.[workflow name].enter.[state name]
- 主题已进入状态并更新。
进入事件
workflow.entered workflow.[workflow name].entered workflow.[workflow name].entered.[state name]
- 主题已完成此转换。
完成事件
workflow.completed workflow.[workflow name].completed workflow.[workflow name].completed.[transition name]
订阅者
创建订阅类以侦听这些事件,并且该类应该 extends WorkflowSubscriberHandler
。
要在订阅者中注册用于侦听特定事件的方法,请使用以下格式的方法名
- on[Event] -
onGuard()
- on[Event][Transition/State name] -
onGuardActivate()
注意
- 方法名必须以
on
关键字开头,否则将被忽略。 Subscriber
类必须注册在workflow.php
配置文件中,并具有适当的流程配置。Subscriber
类必须扩展WorkflowSubscriberHandler
。Guard
、Transition
和Completed
事件使用转换名称。Leave
、Enter
和Entered
事件使用状态名称。
<?php namespace App\Listeners; use Ringierimu\StateWorkflow\Events\EnteredEvent; use Ringierimu\StateWorkflow\Events\EnterEvent; use Ringierimu\StateWorkflow\Events\GuardEvent; use Ringierimu\StateWorkflow\Events\LeaveEvent; use Ringierimu\StateWorkflow\Events\TransitionEvent; use Ringierimu\StateWorkflow\Subscribers\WorkflowSubscriberHandler; /** * Class PostEventSubscriber * @package App\Listeners */ class UserEventSubscriber extends WorkflowSubscriberHandler { /** * Handle workflow guard events. * * @param GuardEvent $event */ public function onGuardActivate($event) { $user = $event->getOriginalEvent()->getSubject(); if (empty($user->dob)) { // Users with no dob should not be allowed $event->getOriginalEvent()->setBlocked(true); } } /** * Handle workflow leave event. * * @param LeaveEvent $event */ public function onLeavePendingActivation($event) { } /** * Handle workflow transition event. * * @param TransitionEvent $event */ public function onTransitionActivate($event) { } /** * Handle workflow enter event. * * @param EnterEvent $event */ public function onEnterActivated($event) { } /** * Handle workflow entered event. * * @param EnteredEvent $event */ public function onEnteredActivated($event) { } }
事件方法
每个工作流程事件都有一个 Event
实例。这意味着每个事件都可以访问以下信息
getOriginalEvent()
:返回触发事件的父事件,该事件具有以下子方法getSubject()
:返回触发事件的对象。getTransition()
:返回触发事件的转换。getWorkflowName()
:返回触发事件的流程名称的字符串。isBlocked()
:如果转换被阻止则返回 true/false。setBlocked()
:设置阻止值。
Artisan 命令
Symfony 工作流使用 GraphvizDumper 通过 dot
命令创建工作流程图像。该 dot
命令是 Graphviz 的一部分。
您需要下载 dot
命令才能使用此命令。https://graphviz.gitlab.io/download/
用法
php artisan workflow:dump workflow_name