嗨,我有一个onflush侦听器:
<?php
namespace FMAppBundleEventListener;
use FMAdminBundleEntityAddressDeliveryAddress;
use DoctrineORMEventOnFlushEventArgs;
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: FMAppBundleEventListenerDeliveryAddressListener
tags:
- { name: doctrine.event_listener, event: onFlush }
我正在尝试将新的邮政编码设置为用户。但这似乎不起作用。
即使我添加$em->persist($user)
。
我正在通过此文档查看:http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/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 AppBundleEventSubscriber;
use DoctrineCommonEventSubscriber;
use DoctrineORMEventLifecycleEventArgs;
use DoctrineORMEventOnFlushEventArgs;
class EntitySubscriber implements EventSubscriber
{
private $now;
public function __construct()
{
$this->now = DateTime::createFromFormat('Y-m-d h:i:s', date('Y-m-d 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: AppBundleEventSubscriberEntitySubscriber
tags:
- { name: doctrine.event_subscriber, connection: default }
如果您需要创建一个对象,请坚持下去并在侦听器中刷新,那么Tlorens的答案将无法正常工作,因为教义文档提到了这一点,必须通过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).
这是实现这一目标的一种方法:
/**
* @param OnFlushEventArgs $eventArgs
*/
public function onFlush(OnFlushEventArgs $eventArgs)
{
$em = $eventArgs->getEntityManager();
$uow = $em->getUnitOfWork();
foreach ($uow->getScheduledEntityUpdates() as $entity) {
if ($entity instanceof User) {
$uow->computeChangeSets();
$changeSet = $uow->getEntityChangeSet($entity);
// In this exemple, User has a boolean property 'enabled' and a log will be created if it is passed to 'false'
if ($changeSet && isset($changeSet['enabled']) && $changeSet['enabled'][1] === false) {
$log = new Log();
$em->persist($log);
$uow->computeChangeSet($em->getClassMetadata(get_class($log)), $log);
}
}
}
当我使用它时它可以工作:
// Remove event, if we call $this->em->flush() now there is no infinite recursion loop!
$eventManager->removeEventListener('onFlush', $this);
我的听众
namespace FMAppBundleEventListener;
use FMAdminBundleEntityAddressDeliveryAddress;
use DoctrineORMEventOnFlushEventArgs;
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();
}
}