Reputation: 5092
I have configured in my service.yml some event listener
registerproduct.listener:
class: App\AppBundle\Listener\RegisterProductListener
arguments: [ @service_container ]
tags:
- { name: doctrine.event_listener, event: prePersist }
- { name: doctrine.event_listener, event: preUpdate }
My method decrementProductQuantity() works really well when I do a prePersist but not with the preUpdate.
During the update the product quantity decrement well, but there is no changes in the database.
Here is my code for the events:
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());
}
}
Here is my update code in my controler:
/**
* @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())));
}
I have no idea why it works when I add something in the database, but not for the update.
Thanks for your help.
Upvotes: 1
Views: 761
Reputation: 5092
Because I didn't find the awnser I finally choose to do it directly in the controller:
/**
* @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);
}
If someone find the anwser, please tell me.
Upvotes: 0
Reputation: 1000
On your preUpdate listener you should to recompute changeset for product entity
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);
}
}
It happens because in your controller (or somewhere else) your code does not update a product entity. Before listener executing doctrine computes change sets for each entity. Hence in your preUpdate listener doctrine does not know anything about product (because it was not changed).
Upvotes: 0
Reputation: 3125
Try to change the signature of your preUpdate method:
use Doctrine\ORM\Event\PreUpdateEventArgs;
/.../
public function preUpdate(PreUpdateEventArgs $args)
{
$this->decrementProductQuantity($args);
}
/.../
Upvotes: 0