防止在回调中完成订单

Prevent completion of an order in a callback

Sylius 使用 WinzouStateMachine 进行状态转换。

在订单完成之前,我有一个 "before" 回调定义如下:

sylius_order:
    callbacks:
        before:
            sylius_complete_order:
                on: ["create"]
                do: ["@my_bundle.cart_callback", "processComplete"]
                args: ["object"]

这个回调会检查一些东西,我希望能够在某些情况下阻止这个回调的完成(比如,产品不再可用),并将订单 return 发送到 cart 状态(并且不继续付款,因为它通常会这样做)。

显然,当回调被定义为 guard 但它需要一个 "guard" 功能,它还没有合并,所以它不起作用 ;(

这是否仍然可以通过其他解决方案实现,也许是在 Sylius 方面,而不是 Winzou 默认行为?是否有类似 $event->stopPropagation(); 但在回调中的订单? 谢谢!

查看实际代码,您可以侦听调度程序事件,然后拒绝该事件,这将阻止转换发生。

在当前代码 (0.2.3) 中,您可以收听 2 个调用(一个在 can 方法中,另一个在 apply 方法中)。

can method..

/**
 * {@inheritDoc}
 */
public function can($transition)
{
    //...

    if (null !== $this->dispatcher) {
        $event = new TransitionEvent($transition, $this->getState(), $this->config['transitions'][$transition], $this);
        $this->dispatcher->dispatch(SMEvents::TEST_TRANSITION, $event);

        return !$event->isRejected();
    }

    return true;
}

apply method..

/**
 * {@inheritDoc}
 */
public function apply($transition, $soft = false)
{
    //...

    $event = new TransitionEvent($transition, $this->getState(), $this->config['transitions'][$transition], $this);

    if (null !== $this->dispatcher) {
        $this->dispatcher->dispatch(SMEvents::PRE_TRANSITION, $event);

        if ($event->isRejected()) {
            return false;
        }
    }

    //...
}

使用这些事件调用,您可以收听 SMEvents::TEST_TRANSITIONSMEvents::PRE_TRANSITION,确定是否转换,然后在必要时使用 $event->setRejected(true); 拒绝事件。 TEST_TRANSITION 检查已经存在很长时间了,但是 PRE_TRANSITION 似乎是在 0.2 中引入的。

当 StateMachine 对象被传递到事件中时,您可以使用它来获取您的原始模型(您的订单),例如..

$order = $event->getStateMachine()->getObject();