Php Symfony2事件侦听器预更新
我已在我的服务.yml中配置了一些事件侦听器Php Symfony2事件侦听器预更新,php,symfony,events,Php,Symfony,Events,我已在我的服务.yml中配置了一些事件侦听器 registerproduct.listener: class: App\AppBundle\Listener\RegisterProductListener arguments: [ @service_container ] tags: - { name: doctrine.event_listener, event: prePersist } - {
registerproduct.listener:
class: App\AppBundle\Listener\RegisterProductListener
arguments: [ @service_container ]
tags:
- { name: doctrine.event_listener, event: prePersist }
- { name: doctrine.event_listener, event: preUpdate }
我的方法decrementProductQuantity()在我做预写时效果非常好,但在预更新时效果不佳
在更新过程中,产品数量会很好地减少,但数据库中没有任何变化
以下是我的活动代码:
public function prePersist(LifecycleEventArgs $args)
{
$this->decrementProductQuantity($args);
}
public function preUpdate(LifecycleEventArgs $args)
{
$this->decrementProductQuantity($args);
}
public function decrementProductQuantity(LifecycleEventArgs $args)
{
/** @var RegisterProduct $registerProduct */
$registerProduct = $args->getEntity();
if (!($registerProduct instanceof RegisterProduct))
return;
if ($registerProduct->getStatus() == 'inscription') {
$product = $registerProduct->getProduct();
$product->setQuantityStock($product->getQuantityStock() - $registerProduct->getQuantity());
}
}
以下是我的控制器中的更新代码:
/**
* @param Register $register
* @return \Symfony\Component\HttpFoundation\Response
*/
public function confirmAction(Request $request, Register $register)
{
$em = $this->getDoctrine()->getManager();
foreach($register->getRegisterProducts() as $registerProduct){
$registerProduct->setStatus('inscription');
$em->persist($registerProduct);
$em->flush();
}
return $this->redirectWithMode($this->generateUrl('asc_activity_register_show', array('register' => $register->getId())));
}
我不知道当我在数据库中添加一些东西时它为什么会起作用,但对于更新却不起作用
感谢您的帮助。尝试更改您的预更新方法的签名:
use Doctrine\ORM\Event\PreUpdateEventArgs;
/.../
public function preUpdate(PreUpdateEventArgs $args)
{
$this->decrementProductQuantity($args);
}
/.../
在预更新侦听器上,您应该为产品实体重新计算变更集
public function decrementProductQuantity(LifecycleEventArgs $args)
{
/** @var RegisterProduct $registerProduct */
$registerProduct = $args->getEntity();
if (!($registerProduct instanceof RegisterProduct))
return;
if ($registerProduct->getStatus() == 'inscription') {
$product = $registerProduct->getProduct();
$product->setQuantityStock($product->getQuantityStock() - $registerProduct->getQuantity());
$em = $args->getEntityManager();
$uow = $em->getUnitOfWork();
$className = \Doctrine\Common\Util\ClassUtils::getClass($product);
$classMetadata = $em->getClassMetadata($className);
$uow->recomputeSingleEntityChangeSet($classMetadata, $product);
}
}
发生这种情况是因为在控制器(或其他地方)中,您的代码没有更新产品实体。在侦听器执行之前,原则为每个实体计算更改集。因此,在您的预更新中,侦听器原则对产品一无所知(因为它没有更改)。因为我没有找到awnser,所以我最终选择直接在控制器中执行此操作:
/**
* @param Register $register
* @return \Symfony\Component\HttpFoundation\Response
*/
public function confirmAction(Request $request, Register $register)
{
$mode = $this->getMode($request);
$em = $this->getDoctrine()->getManager();
foreach ($register->getRegisterProducts() as $registerProduct) {
if($registerProduct->getStatus() != 'inscription'){
$product = $registerProduct->getProduct();
$product->setQuantityStock($product->getQuantityStock() - $registerProduct->getQuantity());
}
$registerProduct->setStatus('inscription');
}
$em->flush();
return $this->redirectWithMode($this->generateUrl('asc_activity_register_show', array('register' => $register->getId())), $mode);
}
如果有人找到anwser,请告诉我。无论哪个签名描述侦听器方法,因为PreUpdateEventArgs扩展了LifecycleEventArgs。更新实体时不必调用“persist”方法,因为doctrine从db加载该方法,且实体已处于“managed”状态。感谢您的精彩介绍