segfaultinc/finite

此软件包已被 弃用 且不再维护。未建议替代软件包。

简单而强大的有限状态机实现

1.1.0 2019-10-12 15:02 UTC

This package is auto-updated.

Last update: 2021-10-12 19:51:30 UTC


README

使用方法

$order = new Order(); // see below
$graph = new Graph(); // see below

$graph->apply($order, 'transition-input');
use SegfaultInc\Finite\Subject;

class Order extends Model implements Subject
{
    public function setFiniteState($state)
    {
        $this->update([
            'status' => $state,
        ]);
    }

    public function getFiniteState($state)
    {
        return $this->status;
    }
}

图定义

(new Graph)
    ->setStates([

        State::initial('new')
            ->label('New')
            ->leaving(function (Order $order) {
                // This is executed every time the `in_progress` is **transitioned from**.
                // Useful if you want to do something that is "state" dependent

                $order->update([
                    'started_at' => now()
                ]);
            }),

        State::normal('in_progress')
            ->label('In Progress'),

        State::final('finished')
            ->label('Finised'),

        State::final('canceled')
            ->label('Canceled')
            ->entering(function (Order $order) {
                // If you transition to "canceled" state from multiple states,
                // this is the place to perform the common logic
            }),

    ])
    ->setTransitions([

        Transition::make('new', 'in_progress', 'progress')
            ->pre(function (Order $order) {
                if ($order->validate()) {
                    throw new OrderValidationException('When an exception is thrown in "pre" hook, the transition is not applied');
                }
            }),

        Transition::make('in_progress', 'finished', 'progress'),

        Transition::make('in_progress', 'canceled', 'cancel')
            ->post(function (Order $order) {
                $order->user->notify(new YourOrderWasCanceled);
            }),

    ]);

可视化

$graph->visualize()

// uses GraphViz under the hood