From 6296cac9627e203b465d113ee3ed124203b006b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Tue, 24 Jan 2023 22:55:03 +0100 Subject: [PATCH] Fixed some ugly issues with entities where certain changes where not written to database, after the event logger subscriber were called. --- .../LogSystem/EventLoggerSubscriber.php | 14 +++++++++---- src/Services/LogSystem/EventLogger.php | 20 +++++++++++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/EventSubscriber/LogSystem/EventLoggerSubscriber.php b/src/EventSubscriber/LogSystem/EventLoggerSubscriber.php index 3e27c282..1f38c66c 100644 --- a/src/EventSubscriber/LogSystem/EventLoggerSubscriber.php +++ b/src/EventSubscriber/LogSystem/EventLoggerSubscriber.php @@ -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 @@ -217,7 +223,7 @@ class EventLoggerSubscriber implements EventSubscriber //The 4th param is important here, as we delete the element... $this->saveChangeSet($entity, $log, $em, true); } - $this->logger->log($log); + $this->logger->logFromOnFlush($log); //Check if we have to log CollectionElementDeleted entries if ($this->save_changed_data) { @@ -234,7 +240,7 @@ class EventLoggerSubscriber implements EventSubscriber if ($this->eventUndoHelper->isUndo()) { $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()) { $log->setUndoneEvent($this->eventUndoHelper->getUndoneEvent(), $this->eventUndoHelper->getMode()); } - $this->logger->log($log); + $this->logger->logFromOnFlush($log); } /** diff --git a/src/Services/LogSystem/EventLogger.php b/src/Services/LogSystem/EventLogger.php index 31f09b65..80ee067e 100644 --- a/src/Services/LogSystem/EventLogger.php +++ b/src/Services/LogSystem/EventLogger.php @@ -76,6 +76,26 @@ class EventLogger 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. *