防止在回调中完成订单
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
方法中)。
/**
* {@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;
}
/**
* {@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();
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
方法中)。
/**
* {@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;
}
/**
* {@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();