vanilo/workflow

工作流引擎 / 状态机

1.2.0 2023-04-05 17:46 UTC

This package is auto-updated.

Last update: 2024-09-03 11:29:53 UTC


README

Tests Packagist Stable Version StyleCI Packagist downloads MIT Software License

这是一个PHP引擎,它可以接受一个具有枚举属性(无论是本地的PHP枚举还是Konekt Enum)的主题(实体、文档、数据库记录),该枚举属性代表主题的状态。

工作流是围绕可能的(枚举的值)状态定义的。

可以从一个状态定义到另一个状态的转换。

示例

class OrderWorkflow extends \Vanilo\Workflow\Draft
{
    private static string $enumClass = OrderStatus::class;
    private static string $property = 'status';

    private static array $graph = [
        'name' => 'Order Workflow',
        'transitions' => [
            'prepare' => [
                'from' => [OrderStatus::NEW, OrderStatus::PENDING],
                'to' => OrderStatus::PROCESSING,
            ],
            'ship' => [
                'from' => [OrderStatus::PROCESSING],
                'to' => OrderStatus::COMPLETED,
            ],
            'cancel' => [
                'from' => ['*'],
                'to' => OrderStatus::CANCELED,
            ],
        ],    
    ];
}

$order = Order::find(1);
echo $order->status->value;
// PROCESSING

$workflow = OrderWorkflow::for($order);
$workflow->can('prepare');
// false
$workflow->can('cancel');
// true

$workflow->allowedTransitions()
// ['ship, 'cancel']

$workflow->execute('ship');
echo $order->status->value;
// COMPLETED

编写显式转换

默认情况下,执行转换会将主题的状态更改为所需的目标状态。

但也可以显式定义将被调用的方法。

class OrderWorkflow extends \Vanilo\Workflow\Draft
{
    private static string $enumClass = OrderStatus::class;
    private static string $property = 'status';

    private static array $graph = [
        'transitions' => [
            'cancel' => [
                'from' => ['*'],
                'to' => OrderStatus::CANCELED,
            ],
        ],
    ];
    
    
    public function cancel(Order $order): void
    {
        foreach ($order->items as $item) {
            Inventory::release($item->sku, $item->quantity)
        }
    
        $order->status = OrderStatus::CANCELED;
        $orders->save();
        
        Event::dispatch(new OrderCanceled($order));  
    }
}