From d4c0aa1748d9df8857f009b2c5e4dec82386e685 Mon Sep 17 00:00:00 2001 From: dantleech Date: Sun, 27 Apr 2014 18:16:44 +0200 Subject: [PATCH 1/5] Added "endFlush" event --- lib/Doctrine/ODM/PHPCR/Event.php | 1 + lib/Doctrine/ODM/PHPCR/UnitOfWork.php | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/Doctrine/ODM/PHPCR/Event.php b/lib/Doctrine/ODM/PHPCR/Event.php index c7fe9cd5b..90ab4e5dd 100644 --- a/lib/Doctrine/ODM/PHPCR/Event.php +++ b/lib/Doctrine/ODM/PHPCR/Event.php @@ -33,6 +33,7 @@ final class Event const preFlush = 'preFlush'; const postFlush = 'postFlush'; + const endFlush = 'endFlush'; const onFlush = 'onFlush'; const onClear = 'onClear'; const loadClassMetadata = 'loadClassMetadata'; diff --git a/lib/Doctrine/ODM/PHPCR/UnitOfWork.php b/lib/Doctrine/ODM/PHPCR/UnitOfWork.php index f667f4380..cf35f98fc 100644 --- a/lib/Doctrine/ODM/PHPCR/UnitOfWork.php +++ b/lib/Doctrine/ODM/PHPCR/UnitOfWork.php @@ -2014,6 +2014,10 @@ public function commit($document = null) $this->visitedCollections = $this->documentChangesets = $this->changesetComputed = array(); + + if ($this->evm->hasListeners(Event::endFlush)) { + $this->evm->dispatchEvent(Event::endFlush, new ManagerEventArgs($this->dm)); + } } /** @@ -2208,7 +2212,7 @@ private function executeUpdates($documents, $dispatchEvents = true) } $class = $this->dm->getClassMetadata(get_class($document)); - $node = $this->session->getNode($this->getDocumentId($document)); + $node = $this->session->getNode($id = $this->getDocumentId($document)); if ($this->writeMetadata) { $this->documentClassMapper->writeMetadata($this->dm, $node, $class->name); From 3ee3bf398e59fcd6245c6cdab0d0fb15014a1d5a Mon Sep 17 00:00:00 2001 From: dantleech Date: Wed, 11 Jun 2014 16:19:22 +0200 Subject: [PATCH 2/5] Trying to avoid infinite loop --- lib/Doctrine/ODM/PHPCR/UnitOfWork.php | 16 +++++++++++++--- .../ODM/PHPCR/Functional/EventManagerTest.php | 12 ++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/lib/Doctrine/ODM/PHPCR/UnitOfWork.php b/lib/Doctrine/ODM/PHPCR/UnitOfWork.php index cf35f98fc..6684f034a 100644 --- a/lib/Doctrine/ODM/PHPCR/UnitOfWork.php +++ b/lib/Doctrine/ODM/PHPCR/UnitOfWork.php @@ -1942,6 +1942,18 @@ public function commit($document = null) } } + if (empty($this->scheduledInserts) && + empty($this->scheduledUpdates) && + empty($this->scheduledRemovals) && + empty($this->scheduledReorders) && + empty($this->scheduledMoves)) { + error_log('all empty'); + $this->invokeGlobalEvent(Event::onFlush, new ManagerEventArgs($this->dm)); + $this->invokeGlobalEvent(Event::postFlush, new ManagerEventArgs($this->dm)); + + return; // Nothing to do. + } + $this->invokeGlobalEvent(Event::onFlush, new ManagerEventArgs($this->dm)); try { @@ -2015,9 +2027,7 @@ public function commit($document = null) $this->documentChangesets = $this->changesetComputed = array(); - if ($this->evm->hasListeners(Event::endFlush)) { - $this->evm->dispatchEvent(Event::endFlush, new ManagerEventArgs($this->dm)); - } + $this->invokeGlobalEvent(Event::endFlush, new ManagerEventArgs($this->dm)); } /** diff --git a/tests/Doctrine/Tests/ODM/PHPCR/Functional/EventManagerTest.php b/tests/Doctrine/Tests/ODM/PHPCR/Functional/EventManagerTest.php index 6bc8d16cf..4939cd74d 100644 --- a/tests/Doctrine/Tests/ODM/PHPCR/Functional/EventManagerTest.php +++ b/tests/Doctrine/Tests/ODM/PHPCR/Functional/EventManagerTest.php @@ -57,6 +57,7 @@ public function testTriggerEvents() Event::preFlush, Event::preMove, Event::postMove, + Event::endFlush, ), $this->listener ); @@ -70,12 +71,14 @@ public function testTriggerEvents() $this->assertTrue($this->listener->pagePrePersist); $this->assertFalse($this->listener->itemPrePersist); $this->assertFalse($this->listener->postFlush); + $this->assertFalse($this->listener->endFlush); $this->assertFalse($this->listener->preFlush); $this->dm->flush(); $this->assertTrue($this->listener->onFlush); $this->assertTrue($this->listener->postFlush); + $this->assertTrue($this->listener->endFlush); $this->assertTrue($this->listener->preFlush); $this->assertFalse($this->listener->preUpdate); $this->assertFalse($this->listener->postUpdate); @@ -205,6 +208,7 @@ class TestPersistenceListener public $itemPostRemove = false; public $onFlush = false; public $postFlush = false; + public $endFlush = false; public $preFlush = false; public $itemPreMove = false; public $itemPostMove = false; @@ -306,6 +310,14 @@ public function postFlush(ManagerEventArgs $e) $this->postFlush = true; } + public function endFlush(ManagerEventArgs $e) + { + $this->endFlush = true; + $dm = $e->getObjectManager(); + + $dm->flush(); + } + public function preFlush(ManagerEventArgs $e) { $this->preFlush = true; From 05af81d51c36dd9f7b234c67877748eb5415bba4 Mon Sep 17 00:00:00 2001 From: dantleech Date: Thu, 12 Jun 2014 21:18:19 +0200 Subject: [PATCH 3/5] Modify a copy of actualData (changeSet) - Update the "originalData" to the "actualData" after computing the CS. This means the additional flushes do not register the difference in the actual data (which had previously had fields removed) as a change. --- lib/Doctrine/ODM/PHPCR/UnitOfWork.php | 104 +++++++++--------- .../ODM/PHPCR/Functional/EventManagerTest.php | 47 +++++++- 2 files changed, 101 insertions(+), 50 deletions(-) diff --git a/lib/Doctrine/ODM/PHPCR/UnitOfWork.php b/lib/Doctrine/ODM/PHPCR/UnitOfWork.php index 6684f034a..ac19b99f9 100644 --- a/lib/Doctrine/ODM/PHPCR/UnitOfWork.php +++ b/lib/Doctrine/ODM/PHPCR/UnitOfWork.php @@ -1157,18 +1157,20 @@ public function computeChangeSet(ClassMetadata $class, $document) $this->changesetComputed[] = $oid; $actualData = $this->getDocumentActualData($class, $document); + $changeSet = $actualData; + $id = $this->getDocumentId($document, false); $isNew = !isset($this->originalData[$oid]); if ($isNew) { // Document is New and should be inserted - $this->originalData[$oid] = $actualData; - $this->documentChangesets[$oid] = array('fields' => $actualData, 'reorderings' => array()); + $this->originalData[$oid] = $changeSet; + $this->documentChangesets[$oid] = array('fields' => $changeSet, 'reorderings' => array()); $this->scheduledInserts[$oid] = $document; } - if ($class->parentMapping && isset($actualData[$class->parentMapping])) { - $parent = $actualData[$class->parentMapping]; + if ($class->parentMapping && isset($changeSet[$class->parentMapping])) { + $parent = $changeSet[$class->parentMapping]; $parentClass = $this->dm->getClassMetadata(get_class($parent)); $state = $this->getDocumentState($parent); @@ -1178,33 +1180,34 @@ public function computeChangeSet(ClassMetadata $class, $document) } foreach ($class->childMappings as $fieldName) { - if ($actualData[$fieldName]) { - if (is_array($actualData[$fieldName]) || $actualData[$fieldName] instanceof Collection) { + if ($changeSet[$fieldName]) { + if (is_array($changeSet[$fieldName]) || $changeSet[$fieldName] instanceof Collection) { throw PHPCRException::childFieldIsArray( self::objToStr($document, $this->dm), $fieldName ); } - if (!is_object($actualData[$fieldName])) { + + if (!is_object($changeSet[$fieldName])) { throw PHPCRException::childFieldNoObject( self::objToStr($document, $this->dm), $fieldName, - gettype($actualData[$fieldName]) + gettype($changeSet[$fieldName]) ); } $mapping = $class->mappings[$fieldName]; - $actualData[$fieldName] = $this->computeChildChanges($mapping, $actualData[$fieldName], $id, $mapping['nodeName']); + $changeSet[$fieldName] = $this->computeChildChanges($mapping, $changeSet[$fieldName], $id, $mapping['nodeName']); } } - $this->computeAssociationChanges($class, $oid, $isNew, $actualData, 'reference'); - $this->computeAssociationChanges($class, $oid, $isNew, $actualData, 'referrer'); + $this->computeAssociationChanges($class, $oid, $isNew, $changeSet, 'reference'); + $this->computeAssociationChanges($class, $oid, $isNew, $changeSet, 'referrer'); foreach ($class->mixedReferrersMappings as $fieldName) { - if ($actualData[$fieldName] - && $actualData[$fieldName] instanceof PersistentCollection - && $actualData[$fieldName]->isDirty() + if ($changeSet[$fieldName] + && $changeSet[$fieldName] instanceof PersistentCollection + && $changeSet[$fieldName]->isDirty() ) { throw new PHPCRException("The immutable mixed referrer collection in field $fieldName is dirty"); } @@ -1213,8 +1216,8 @@ public function computeChangeSet(ClassMetadata $class, $document) if ($isNew) { // much simpler handling for children foreach ($class->childrenMappings as $fieldName) { - if ($actualData[$fieldName]) { - if (!is_array($actualData[$fieldName]) && !$actualData[$fieldName] instanceof Collection) { + if ($changeSet[$fieldName]) { + if (!is_array($changeSet[$fieldName]) && !$changeSet[$fieldName] instanceof Collection) { throw PHPCRException::childrenFieldNoArray( self::objToStr($document, $this->dm), $fieldName @@ -1222,7 +1225,7 @@ public function computeChangeSet(ClassMetadata $class, $document) } $mapping = $class->mappings[$fieldName]; - foreach ($actualData[$fieldName] as $originalNodename => $child) { + foreach ($changeSet[$fieldName] as $originalNodename => $child) { if (!is_object($child)) { throw PHPCRException::childrenContainsNonObject( self::objToStr($document, $this->dm), @@ -1232,9 +1235,9 @@ public function computeChangeSet(ClassMetadata $class, $document) } $nodename = $this->getChildNodename($id, $originalNodename, $child, $document); - $actualData[$fieldName][$nodename] = $this->computeChildChanges($mapping, $child, $id, $nodename, $document); + $changeSet[$fieldName][$nodename] = $this->computeChildChanges($mapping, $child, $id, $nodename, $document); if (0 !== strcmp($originalNodename, $nodename)) { - unset($actualData[$fieldName][$originalNodename]); + unset($changeSet[$fieldName][$originalNodename]); } $childNames[] = $nodename; } @@ -1245,30 +1248,30 @@ public function computeChangeSet(ClassMetadata $class, $document) $destPath = $destName = false; if (isset($this->originalData[$oid][$class->parentMapping]) - && isset($actualData[$class->parentMapping]) - && $this->originalData[$oid][$class->parentMapping] !== $actualData[$class->parentMapping] + && isset($changeSet[$class->parentMapping]) + && $this->originalData[$oid][$class->parentMapping] !== $changeSet[$class->parentMapping] ) { - $destPath = $this->getDocumentId($actualData[$class->parentMapping]); + $destPath = $this->getDocumentId($changeSet[$class->parentMapping]); } if (isset($this->originalData[$oid][$class->nodename]) - && isset($actualData[$class->nodename]) - && $this->originalData[$oid][$class->nodename] !== $actualData[$class->nodename] + && isset($changeSet[$class->nodename]) + && $this->originalData[$oid][$class->nodename] !== $changeSet[$class->nodename] ) { - $destName = $actualData[$class->nodename]; + $destName = $changeSet[$class->nodename]; } // there was assignment move if ($destPath || $destName) { // add the other field if only one was changed if (false === $destPath) { - $destPath = isset($actualData[$class->parentMapping]) - ? $this->getDocumentId($actualData[$class->parentMapping]) + $destPath = isset($changeSet[$class->parentMapping]) + ? $this->getDocumentId($changeSet[$class->parentMapping]) : PathHelper::getParentPath($this->getDocumentId($document)); } if (false === $destName) { - $destName = $actualData[$class->nodename] - ? $actualData[$class->nodename] + $destName = $changeSet[$class->nodename] + ? $changeSet[$class->nodename] : PathHelper::getNodeName($this->getDocumentId($document)); } @@ -1284,35 +1287,36 @@ public function computeChangeSet(ClassMetadata $class, $document) } if (isset($this->originalData[$oid][$class->identifier]) - && isset($actualData[$class->identifier]) - && $this->originalData[$oid][$class->identifier] !== $actualData[$class->identifier] + && isset($changeSet[$class->identifier]) + && $this->originalData[$oid][$class->identifier] !== $changeSet[$class->identifier] ) { - throw new PHPCRException('The Id is immutable ('.$this->originalData[$oid][$class->identifier].' !== '.$actualData[$class->identifier].'). Please use DocumentManager::move to move the document: '.self::objToStr($document, $this->dm)); + throw new PHPCRException('The Id is immutable ('.$this->originalData[$oid][$class->identifier].' !== '.$changeSet[$class->identifier].'). Please use DocumentManager::move to move the document: '.self::objToStr($document, $this->dm)); } foreach ($class->childrenMappings as $fieldName) { - if ($actualData[$fieldName] instanceof PersistentCollection) { - if (!$actualData[$fieldName]->isInitialized()) { + if ($changeSet[$fieldName] instanceof PersistentCollection) { + if (!$changeSet[$fieldName]->isInitialized()) { continue; } - $coid = spl_object_hash($actualData[$fieldName]); - $this->visitedCollections[$coid] = $actualData[$fieldName]; + $coid = spl_object_hash($changeSet[$fieldName]); + $this->visitedCollections[$coid] = $changeSet[$fieldName]; } + $mapping = $class->mappings[$fieldName]; $childNames = array(); $movedChildNames = array(); - if ($actualData[$fieldName]) { - if (!is_array($actualData[$fieldName]) && !$actualData[$fieldName] instanceof Collection) { + if ($changeSet[$fieldName]) { + if (!is_array($changeSet[$fieldName]) && !$changeSet[$fieldName] instanceof Collection) { throw PHPCRException::childrenFieldNoArray( self::objToStr($document, $this->dm), $fieldName ); } - foreach ($actualData[$fieldName] as $originalNodename => $child) { + foreach ($changeSet[$fieldName] as $originalNodename => $child) { if (!is_object($child)) { throw PHPCRException::childrenContainsNonObject( self::objToStr($document, $this->dm), @@ -1322,9 +1326,9 @@ public function computeChangeSet(ClassMetadata $class, $document) } $nodename = $this->getChildNodename($id, $originalNodename, $child, $document); - $actualData[$fieldName][$nodename] = $this->computeChildChanges($mapping, $child, $id, $nodename, $document); + $changeSet[$fieldName][$nodename] = $this->computeChildChanges($mapping, $child, $id, $nodename, $document); if (0 !== strcmp($originalNodename, $nodename)) { - unset($actualData[$fieldName][$originalNodename]); + unset($changeSet[$fieldName][$originalNodename]); $movedChildNames[] = (string) $originalNodename; } $childNames[] = $nodename; @@ -1370,8 +1374,8 @@ public function computeChangeSet(ClassMetadata $class, $document) if (!isset($this->documentLocales[$oid]) || $this->documentLocales[$oid]['current'] === $this->documentLocales[$oid]['original'] ) { - // remove anything from $actualData that did not change - foreach ($actualData as $fieldName => $fieldValue) { + // remove anything from $changeSet that did not change + foreach ($changeSet as $fieldName => $fieldValue) { if (isset($class->mappings[$fieldName])) { if ($this->originalData[$oid][$fieldName] !== $fieldValue) { continue; @@ -1385,17 +1389,20 @@ public function computeChangeSet(ClassMetadata $class, $document) } } - unset($actualData[$fieldName]); + unset($changeSet[$fieldName]); } } - if (count($actualData)) { + if (count($changeSet)) { if (empty($this->documentChangesets[$oid])) { - $this->documentChangesets[$oid] = array('fields' => $actualData, 'reorderings' => array()); - } else { - $this->documentChangesets[$oid]['fields'] = $actualData; + $this->documentChangesets[$oid] = array( + 'fields' => array(), + 'reorderings' => array() + ); } + $this->documentChangesets[$oid]['fields'] = $changeSet; + $this->originalData[$oid] = $actualData; $this->scheduledUpdates[$oid] = $document; } elseif (isset($this->documentChangesets[$oid])) { // make sure we don't keep an old changeset if an event changed @@ -1947,7 +1954,6 @@ public function commit($document = null) empty($this->scheduledRemovals) && empty($this->scheduledReorders) && empty($this->scheduledMoves)) { - error_log('all empty'); $this->invokeGlobalEvent(Event::onFlush, new ManagerEventArgs($this->dm)); $this->invokeGlobalEvent(Event::postFlush, new ManagerEventArgs($this->dm)); diff --git a/tests/Doctrine/Tests/ODM/PHPCR/Functional/EventManagerTest.php b/tests/Doctrine/Tests/ODM/PHPCR/Functional/EventManagerTest.php index 4939cd74d..96ff821ae 100644 --- a/tests/Doctrine/Tests/ODM/PHPCR/Functional/EventManagerTest.php +++ b/tests/Doctrine/Tests/ODM/PHPCR/Functional/EventManagerTest.php @@ -139,6 +139,52 @@ public function testTriggerEvents() $this->assertTrue($this->listener->itemPostRemove); } + public function testPreUpdate() + { + $this->dm + ->getEventManager() + ->addEventListener( + array( + Event::prePersist, + Event::postPersist, + Event::preUpdate, + Event::postUpdate, + Event::preRemove, + Event::postRemove, + Event::onFlush, + Event::postFlush, + Event::preFlush, + Event::preMove, + Event::postMove, + Event::endFlush, + ), + $this->listener + ); + + $page = new CmsPage(); + $page->title = "my-page"; + $page->content = "long story"; + + $item = new CmsItem(); + $item->name = "my-item"; + $item->documentTarget = $page; + + $this->dm->persist($page); + $this->dm->flush(); + + $page->content = "short story"; + $this->dm->persist($item); + $page->addItem($item); + + $this->dm->persist($page); + $this->dm->flush(); + + $this->assertTrue($this->listener->preUpdate); + $this->assertTrue($this->listener->itemPrePersist); + $this->assertTrue($this->listener->postUpdate); + $this->assertTrue($this->listener->itemPostPersist); + } + public function testTriggerTranslationEvents() { $this->dm @@ -314,7 +360,6 @@ public function endFlush(ManagerEventArgs $e) { $this->endFlush = true; $dm = $e->getObjectManager(); - $dm->flush(); } From 2f529e86ca6df3c7f5188c6397a7f2dfeee5e535 Mon Sep 17 00:00:00 2001 From: dantleech Date: Fri, 13 Jun 2014 07:35:06 +0200 Subject: [PATCH 4/5] Always call session#save and fixes to tests --- lib/Doctrine/ODM/PHPCR/UnitOfWork.php | 5 +++++ .../Translation/AttributeTranslationStrategyTest.php | 2 +- .../Functional/Translation/ChildTranslationStrategyTest.php | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/Doctrine/ODM/PHPCR/UnitOfWork.php b/lib/Doctrine/ODM/PHPCR/UnitOfWork.php index ac19b99f9..34dcf7a31 100644 --- a/lib/Doctrine/ODM/PHPCR/UnitOfWork.php +++ b/lib/Doctrine/ODM/PHPCR/UnitOfWork.php @@ -1953,10 +1953,15 @@ public function commit($document = null) empty($this->scheduledUpdates) && empty($this->scheduledRemovals) && empty($this->scheduledReorders) && + empty($this->documentTranslations) && empty($this->scheduledMoves)) { $this->invokeGlobalEvent(Event::onFlush, new ManagerEventArgs($this->dm)); $this->invokeGlobalEvent(Event::postFlush, new ManagerEventArgs($this->dm)); + // @deprecated This is to maintain BC with the old behavior, where users may call + // flush instead of PHPCR\SessionInterface#save + $this->session->save(); + return; // Nothing to do. } diff --git a/tests/Doctrine/Tests/ODM/PHPCR/Functional/Translation/AttributeTranslationStrategyTest.php b/tests/Doctrine/Tests/ODM/PHPCR/Functional/Translation/AttributeTranslationStrategyTest.php index b3c968823..8dfee4ae6 100644 --- a/tests/Doctrine/Tests/ODM/PHPCR/Functional/Translation/AttributeTranslationStrategyTest.php +++ b/tests/Doctrine/Tests/ODM/PHPCR/Functional/Translation/AttributeTranslationStrategyTest.php @@ -344,7 +344,7 @@ public function testQueryBuilder() ); $strategy->saveTranslation($data, $node, $this->metadata, 'fr'); - $this->dm->flush(); + $this->dm->getPhpcrSession()->save(); $qb = $this->dm->createQueryBuilder(); $qb->from()->document('Doctrine\Tests\Models\Translation\Article', 'a'); diff --git a/tests/Doctrine/Tests/ODM/PHPCR/Functional/Translation/ChildTranslationStrategyTest.php b/tests/Doctrine/Tests/ODM/PHPCR/Functional/Translation/ChildTranslationStrategyTest.php index 5cd738766..dc4a585e3 100644 --- a/tests/Doctrine/Tests/ODM/PHPCR/Functional/Translation/ChildTranslationStrategyTest.php +++ b/tests/Doctrine/Tests/ODM/PHPCR/Functional/Translation/ChildTranslationStrategyTest.php @@ -64,7 +64,7 @@ public function testSaveTranslation() $data['topic'] = 'Un sujet intéressant'; $strategy->saveTranslation($data, $node, $this->metadata, 'fr'); - $this->dm->flush(); + $this->dm->getPhpcrSession()->save(); // Then test we have what we expect in the content repository $node_en = $this->session->getNode($this->nodeNameForLocale('en')); From 04b0e5cbc438f3212e59347fa8abc102590721d5 Mon Sep 17 00:00:00 2001 From: dantleech Date: Fri, 13 Jun 2014 07:43:48 +0200 Subject: [PATCH 5/5] Fix --- lib/Doctrine/ODM/PHPCR/UnitOfWork.php | 2 +- .../ODM/PHPCR/Functional/EventManagerTest.php | 49 ++----------------- 2 files changed, 4 insertions(+), 47 deletions(-) diff --git a/lib/Doctrine/ODM/PHPCR/UnitOfWork.php b/lib/Doctrine/ODM/PHPCR/UnitOfWork.php index 34dcf7a31..56c00e40d 100644 --- a/lib/Doctrine/ODM/PHPCR/UnitOfWork.php +++ b/lib/Doctrine/ODM/PHPCR/UnitOfWork.php @@ -2233,7 +2233,7 @@ private function executeUpdates($documents, $dispatchEvents = true) } $class = $this->dm->getClassMetadata(get_class($document)); - $node = $this->session->getNode($id = $this->getDocumentId($document)); + $node = $this->session->getNode($this->getDocumentId($document)); if ($this->writeMetadata) { $this->documentClassMapper->writeMetadata($this->dm, $node, $class->name); diff --git a/tests/Doctrine/Tests/ODM/PHPCR/Functional/EventManagerTest.php b/tests/Doctrine/Tests/ODM/PHPCR/Functional/EventManagerTest.php index 96ff821ae..ee6ede29c 100644 --- a/tests/Doctrine/Tests/ODM/PHPCR/Functional/EventManagerTest.php +++ b/tests/Doctrine/Tests/ODM/PHPCR/Functional/EventManagerTest.php @@ -139,52 +139,6 @@ public function testTriggerEvents() $this->assertTrue($this->listener->itemPostRemove); } - public function testPreUpdate() - { - $this->dm - ->getEventManager() - ->addEventListener( - array( - Event::prePersist, - Event::postPersist, - Event::preUpdate, - Event::postUpdate, - Event::preRemove, - Event::postRemove, - Event::onFlush, - Event::postFlush, - Event::preFlush, - Event::preMove, - Event::postMove, - Event::endFlush, - ), - $this->listener - ); - - $page = new CmsPage(); - $page->title = "my-page"; - $page->content = "long story"; - - $item = new CmsItem(); - $item->name = "my-item"; - $item->documentTarget = $page; - - $this->dm->persist($page); - $this->dm->flush(); - - $page->content = "short story"; - $this->dm->persist($item); - $page->addItem($item); - - $this->dm->persist($page); - $this->dm->flush(); - - $this->assertTrue($this->listener->preUpdate); - $this->assertTrue($this->listener->itemPrePersist); - $this->assertTrue($this->listener->postUpdate); - $this->assertTrue($this->listener->itemPostPersist); - } - public function testTriggerTranslationEvents() { $this->dm @@ -360,6 +314,9 @@ public function endFlush(ManagerEventArgs $e) { $this->endFlush = true; $dm = $e->getObjectManager(); + + // endFlush can call ->flush(). The UOW should exit early if there is nothing + // to do, avoiding an infinite recursion. $dm->flush(); }