Я настроил в моем service.yml прослушиватель событий
registerproduct.listener:
class: App\AppBundle\Listener\RegisterProductListener
arguments: [ @service_container ]
tags:
- { name: doctrine.event_listener, event: prePersist }
- { name: doctrine.event_listener, event: preUpdate }
Мой метод decuctionProductQuantity() работает очень хорошо, когда я делаю prePersist, но не с preUpdate.
Во время обновления количество товара уменьшается, но изменений в базе данных нет.
Вот мой код для событий:
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())));
}
Я понятия не имею, почему это работает, когда я добавляю что-то в базу данных, но не для обновления.
Спасибо за вашу помощь.
На слушателе preUpdate вы должны перекомпилировать набор изменений для объекта продукта
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);
}
}
Это происходит потому, что в вашем контроллере (или где-то еще) ваш код не обновляет объект продукта. Перед тем как слушатель выполняет доктрину, вычисляет наборы изменений для каждого объекта. Следовательно, в вашей доктрине слушателя preUpdate ничего не известно о продукте (потому что он не был изменен).
Поскольку я не нашел тент, я, наконец, решил сделать это прямо в контроллере:
/**
* @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);
}
Если кто-то найдет собеседника, скажите, пожалуйста.
Попробуйте изменить подпись вашего метода preUpdate:
use Doctrine\ORM\Event\PreUpdateEventArgs;
/.../
public function preUpdate(PreUpdateEventArgs $args)
{
$this->decrementProductQuantity($args);
}
/.../