Fixed some ugly issues with entities where certain changes where not written to database, after the event logger subscriber were called.

This commit is contained in:
Jan Böhmer 2023-01-24 22:55:03 +01:00
parent d06701fa87
commit 6296cac962
2 changed files with 30 additions and 4 deletions

View file

@ -117,7 +117,13 @@ class EventLoggerSubscriber implements EventSubscriber
} }
} }
$uow->computeChangeSets(); /* Do not call $uow->computeChangeSets() in this function, only individual entities should be computed!
* Otherwise we will run into very strange issues, that some entity changes are no longer updated!
* This is almost impossible to debug, because it only happens in some cases, and it looks very unrelated to
* this code (which caused the problem and which took me very long time to find out).
* So just do not call $uow->computeChangeSets() here ever, even if it is tempting!!
* If you need to log something from inside here, just call logFromOnFlush() instead of the normal log() function.
*/
} }
public function postPersist(LifecycleEventArgs $args): void public function postPersist(LifecycleEventArgs $args): void
@ -217,7 +223,7 @@ class EventLoggerSubscriber implements EventSubscriber
//The 4th param is important here, as we delete the element... //The 4th param is important here, as we delete the element...
$this->saveChangeSet($entity, $log, $em, true); $this->saveChangeSet($entity, $log, $em, true);
} }
$this->logger->log($log); $this->logger->logFromOnFlush($log);
//Check if we have to log CollectionElementDeleted entries //Check if we have to log CollectionElementDeleted entries
if ($this->save_changed_data) { if ($this->save_changed_data) {
@ -234,7 +240,7 @@ class EventLoggerSubscriber implements EventSubscriber
if ($this->eventUndoHelper->isUndo()) { if ($this->eventUndoHelper->isUndo()) {
$log->setUndoneEvent($this->eventUndoHelper->getUndoneEvent(), $this->eventUndoHelper->getMode()); $log->setUndoneEvent($this->eventUndoHelper->getUndoneEvent(), $this->eventUndoHelper->getMode());
} }
$this->logger->log($log); $this->logger->logFromOnFlush($log);
} }
} }
} }
@ -271,7 +277,7 @@ class EventLoggerSubscriber implements EventSubscriber
if ($this->eventUndoHelper->isUndo()) { if ($this->eventUndoHelper->isUndo()) {
$log->setUndoneEvent($this->eventUndoHelper->getUndoneEvent(), $this->eventUndoHelper->getMode()); $log->setUndoneEvent($this->eventUndoHelper->getUndoneEvent(), $this->eventUndoHelper->getMode());
} }
$this->logger->log($log); $this->logger->logFromOnFlush($log);
} }
/** /**

View file

@ -76,6 +76,26 @@ class EventLogger
return false; return false;
} }
/**
* Same as log(), but this function can be safely called from within the onFlush() doctrine event, as it
* updated the changesets of the unit of work.
* @param AbstractLogEntry $logEntry
* @return bool
*/
public function logFromOnFlush(AbstractLogEntry $logEntry): bool
{
if ($this->log($logEntry)) {
$uow = $this->em->getUnitOfWork();
//As we call it from onFlush, we have to recompute the changeset here, according to https://www.doctrine-project.org/projects/doctrine-orm/en/2.14/reference/events.html#reference-events-on-flush
$uow->computeChangeSet($this->em->getClassMetadata(get_class($logEntry)), $logEntry);
return true;
}
//If the normal log function does not added the log entry, we just do nothing
return false;
}
/** /**
* Adds the given log entry to the Log, if the entry fullfills the global configured criterias and flush afterwards. * Adds the given log entry to the Log, if the entry fullfills the global configured criterias and flush afterwards.
* *