防止在回调中完成订单

时间:2016-10-17 19:10:11

标签: symfony sylius

Sylius使用 WinzouStateMachine 进行状态转换。

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

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

这个回调检查一些东西,我希望能够在某些情况下阻止完成此回调(比如,产品不再可用),并使订单返回到cart状态( 并且不会像通常那样进行付款)。

显然,当回调被定义为false时,返回guard应该可以解决问题(根据https://github.com/winzou/state-machine#callbacks处的文档),但它需要一个“保护”功能并且它没有合并然而,它不起作用;(

这是否仍然可以使用另一种解决方案,可能在Sylius方面,而不是Winzou默认行为?是否有类似$event->stopPropagation();的东西,但在回调中,对于订单? 谢谢!

1 个答案:

答案 0 :(得分:1)

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

在当前代码(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_TRANSITION& SMEvents::PRE_TRANSITION,确定是否过渡,然后在必要时使用$event->setRejected(true);拒绝该事件。 TEST_TRANSITION检查已存在多年,但PRE_TRANSITION似乎已在0.2中引入。

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

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