Привет, у меня есть слушатель onFlush:
<?php namespace FM\AppBundle\EventListener; use FM\AdminBundle\Entity\Address\DeliveryAddress; use Doctrine\ORM\Event\OnFlushEventArgs; class DeliveryAddressListener { /** * @param OnFlushEventArgs $args */ public function onFlush(OnFlushEventArgs $args) { $em = $args->getEntityManager(); $uow = $em->getUnitOfWork(); foreach ($uow->getScheduledEntityUpdates() as $entity) { if ($entity instanceof DeliveryAddress) { $this->addPostalToUser($entity, $args); } } } /** * @param DeliveryAddress $deliveryAddress * @param OnFlushEventArgs $args */ public function addPostalToUser(DeliveryAddress $deliveryAddress, OnFlushEventArgs $args) { $em = $args->getEntityManager(); $user = $deliveryAddress->getOwner(); $user->setPostalCode($deliveryAddress->getZipCode()); } }
service.yml:
delivery_address.listener: class: FM\AppBundle\EventListener\DeliveryAddressListener tags: - { name: doctrine.event_listener, event: onFlush }
Я пытаюсь установить новый zipCode для пользователя. Но, похоже, это не работает.
Даже когда я добавляю $em->persist($user)
.
Я просматриваю этот документ: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html#onflush
Но я не понимаю, как я могу заставить это работать с этим объяснением:
If you create and persist a new entity in onFlush, then calling EntityManager#persist() is not enough. You have to execute an additional call to $unitOfWork->computeChangeSet($classMetadata, $entity).
При манипулировании полями они должны выполняться в preUpdaet / prePersist.
AppBundle / EventSubscriber / EntitySubscriber.php
namespace AppBundle\EventSubscriber; use Doctrine\Common\EventSubscriber; use Doctrine\ORM\Event\LifecycleEventArgs; use Doctrine\ORM\Event\OnFlushEventArgs; class EntitySubscriber implements EventSubscriber { private $now; public function __construct() { $this->now = \DateTime::createFromFormat('Ymd h:i:s', date('Ymd h:i:s')); } public function getSubscribedEvents() { return [ 'prePersist', 'preUpdate' ]; } public function prePersist(LifecycleEventArgs $args) { $entity = $args->getEntity(); $entityManager = $args->getEntityManager(); if (method_exists($entity, 'setCreatedAt')) { $entity->setUpdatedAt($this->now); } if (method_exists($entity, 'setUpdatedAt')) { $entity->setUpdatedAt($this->now); } } public function preUpdate(LifecycleEventArgs $args) { $entity = $args->getEntity(); $entityManager = $args->getEntityManager(); if (method_exists($entity, 'setUpdatedAt')) { $entity->setUpdatedAt($this->now); } } }
services.yml
app.entity_subscriber: class: AppBundle\EventSubscriber\EntitySubscriber tags: - { name: doctrine.event_subscriber, connection: default }
Ну, это работает, когда я использую это:
// Remove event, if we call $this->em->flush() now there is no infinite recursion loop! $eventManager->removeEventListener('onFlush', $this);
Мой слушатель
namespace FM\AppBundle\EventListener; use FM\AdminBundle\Entity\Address\DeliveryAddress; use Doctrine\ORM\Event\OnFlushEventArgs; class DeliveryAddressListener { /** * @param OnFlushEventArgs $args */ public function onFlush(OnFlushEventArgs $args) { $em = $args->getEntityManager(); $uow = $em->getUnitOfWork(); $eventManager = $em->getEventManager(); // Remove event, if we call $this->em->flush() now there is no infinite recursion loop! $eventManager->removeEventListener('onFlush', $this); foreach ($uow->getScheduledEntityUpdates() as $entity) { if ($entity instanceof DeliveryAddress) { $this->addPostalToUser($entity, $args); } } } /** * @param DeliveryAddress $deliveryAddress * @param OnFlushEventArgs $args */ public function addPostalToUser(DeliveryAddress $deliveryAddress, OnFlushEventArgs $args) { $em = $args->getEntityManager(); $user = $deliveryAddress->getOwner(); $user->setPostalCode($deliveryAddress->getZipCode()); $em->flush(); } }