Skip to content
Browse files

call listeners in UoW

  • Loading branch information...
1 parent ccc0a2a commit 315f7ba43b9c2226c9d801142ade87c4f5a8f56a @FabioBatSilva committed with fabio.silva Jul 30, 2012
View
131 lib/Doctrine/ORM/UnitOfWork.php
@@ -22,15 +22,21 @@
use Exception;
use InvalidArgumentException;
use UnexpectedValueException;
+
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\NotifyPropertyChanged;
use Doctrine\Common\PropertyChangedListener;
use Doctrine\Common\Persistence\ObjectManagerAware;
-use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Proxy\Proxy;
+use Doctrine\ORM\Event\LifecycleEventArgs;
+use Doctrine\ORM\Event\PreUpdateEventArgs;
+use Doctrine\ORM\Event\PreFlushEventArgs;
+use Doctrine\ORM\Event\OnFlushEventArgs;
+use Doctrine\ORM\Event\PostFlushEventArgs;
+
/**
* The UnitOfWork is responsible for tracking changes to objects during an
* "object-level" transaction and for writing out changes to the database
@@ -267,7 +273,7 @@ public function commit($entity = null)
{
// Raise preFlush
if ($this->evm->hasListeners(Events::preFlush)) {
- $this->evm->dispatchEvent(Events::preFlush, new Event\PreFlushEventArgs($this->em));
+ $this->evm->dispatchEvent(Events::preFlush, new PreFlushEventArgs($this->em));
}
// Compute changes done since last commit.
@@ -511,6 +517,11 @@ public function computeChangeSet(ClassMetadata $class, $entity)
$class->invokeLifecycleCallbacks(Events::preFlush, $entity);
}
+ // Fire PreFlush entity listeners
+ if (isset($class->entityListeners[Events::preFlush])) {
+ $class->dispatchEntityListeners(Events::preFlush, $entity, new PreFlushEventArgs($this->em));
+ }
+
$actualData = array();
foreach ($class->reflFields as $name => $refProp) {
@@ -798,21 +809,32 @@ private function computeAssociationChanges($assoc, $value)
}
/**
- * @param ClassMetadata $class
+ * @param \Doctrine\ORM\Mapping\ClassMetadata $class
* @param object $entity
*
* @return void
*/
private function persistNew($class, $entity)
{
- $oid = spl_object_hash($entity);
+ $oid = spl_object_hash($entity);
+ $hasListeners = $this->evm->hasListeners(Events::prePersist);
+ $hasEntityListeners = isset($class->entityListeners[Events::prePersist]);
+ $hasLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::prePersist]);
+
+ if ($hasListeners || $hasEntityListeners) {
+ $event = new LifecycleEventArgs($entity, $this->em);
+ }
- if (isset($class->lifecycleCallbacks[Events::prePersist])) {
+ if ($hasLifecycleCallbacks) {
$class->invokeLifecycleCallbacks(Events::prePersist, $entity);
}
- if ($this->evm->hasListeners(Events::prePersist)) {
- $this->evm->dispatchEvent(Events::prePersist, new LifecycleEventArgs($entity, $this->em));
+ if ($hasEntityListeners) {
+ $class->dispatchEntityListeners(Events::prePersist, $entity, $event);
+ }
+
+ if ($hasListeners) {
+ $this->evm->dispatchEvent(Events::prePersist, $event);
}
$idGen = $class->idGenerator;
@@ -913,6 +935,7 @@ private function executeInserts($class)
$entities = array();
$hasLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::postPersist]);
+ $hasEntityListeners = isset($class->entityListeners[Events::postPersist]);
$hasListeners = $this->evm->hasListeners(Events::postPersist);
foreach ($this->entityInsertions as $oid => $entity) {
@@ -924,7 +947,7 @@ private function executeInserts($class)
unset($this->entityInsertions[$oid]);
- if ($hasLifecycleCallbacks || $hasListeners) {
+ if ($hasLifecycleCallbacks || $hasEntityListeners || $hasListeners) {
$entities[] = $entity;
}
}
@@ -946,14 +969,23 @@ private function executeInserts($class)
$this->addToIdentityMap($entity);
}
}
-
+
foreach ($entities as $entity) {
+
+ if ($hasListeners || $hasEntityListeners) {
+ $event = new LifecycleEventArgs($entity, $this->em);
+ }
+
if ($hasLifecycleCallbacks) {
$class->invokeLifecycleCallbacks(Events::postPersist, $entity);
}
+ if ($hasEntityListeners) {
+ $class->dispatchEntityListeners(Events::postPersist, $entity, $event);
+ }
+
if ($hasListeners) {
- $this->evm->dispatchEvent(Events::postPersist, new LifecycleEventArgs($entity, $this->em));
+ $this->evm->dispatchEvent(Events::postPersist, $event);
}
}
}
@@ -971,27 +1003,38 @@ private function executeUpdates($class)
$persister = $this->getEntityPersister($className);
$hasPreUpdateLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::preUpdate]);
+ $hasPreUpdateEntityListeners = isset($class->entityListeners[Events::preUpdate]);
$hasPreUpdateListeners = $this->evm->hasListeners(Events::preUpdate);
$hasPostUpdateLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::postUpdate]);
+ $hasPostUpdateEntityListeners = isset($class->entityListeners[Events::postUpdate]);
$hasPostUpdateListeners = $this->evm->hasListeners(Events::postUpdate);
foreach ($this->entityUpdates as $oid => $entity) {
if ($this->em->getClassMetadata(get_class($entity))->name !== $className) {
continue;
}
+ if ($hasPreUpdateListeners || $hasPreUpdateEntityListeners) {
+ $preEvent = new PreUpdateEventArgs($entity, $this->em, $this->entityChangeSets[$oid]);
+ }
+
+ if ($hasPostUpdateListeners || $hasPostUpdateEntityListeners) {
+ $postEvent = new LifecycleEventArgs($entity, $this->em);
+ }
+
if ($hasPreUpdateLifecycleCallbacks) {
$class->invokeLifecycleCallbacks(Events::preUpdate, $entity);
$this->recomputeSingleEntityChangeSet($class, $entity);
}
+ if ($hasPreUpdateEntityListeners) {
+ $class->dispatchEntityListeners(Events::preUpdate, $entity, $preEvent);
+ }
+
if ($hasPreUpdateListeners) {
- $this->evm->dispatchEvent(
- Events::preUpdate,
- new Event\PreUpdateEventArgs($entity, $this->em, $this->entityChangeSets[$oid])
- );
+ $this->evm->dispatchEvent(Events::preUpdate, $preEvent);
}
if (!empty($this->entityChangeSets[$oid])) {
@@ -1004,8 +1047,12 @@ private function executeUpdates($class)
$class->invokeLifecycleCallbacks(Events::postUpdate, $entity);
}
+ if ($hasPostUpdateEntityListeners) {
+ $class->dispatchEntityListeners(Events::postUpdate, $entity, $postEvent);
+ }
+
if ($hasPostUpdateListeners) {
- $this->evm->dispatchEvent(Events::postUpdate, new LifecycleEventArgs($entity, $this->em));
+ $this->evm->dispatchEvent(Events::postUpdate, $postEvent);
}
}
}
@@ -1022,8 +1069,9 @@ private function executeDeletions($class)
$className = $class->name;
$persister = $this->getEntityPersister($className);
- $hasLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::postRemove]);
- $hasListeners = $this->evm->hasListeners(Events::postRemove);
+ $hasLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::postRemove]);
+ $hasEntityListeners = isset($class->entityListeners[Events::postRemove]);
+ $hasListeners = $this->evm->hasListeners(Events::postRemove);
foreach ($this->entityDeletions as $oid => $entity) {
if ($this->em->getClassMetadata(get_class($entity))->name !== $className) {
@@ -1046,12 +1094,20 @@ private function executeDeletions($class)
$class->reflFields[$class->identifier[0]]->setValue($entity, null);
}
+ if ($hasListeners || $hasEntityListeners) {
+ $event = new LifecycleEventArgs($entity, $this->em);
+ }
+
if ($hasLifecycleCallbacks) {
$class->invokeLifecycleCallbacks(Events::postRemove, $entity);
}
+ if ($hasEntityListeners) {
+ $class->dispatchEntityListeners(Events::postRemove, $entity, $event);
+ }
+
if ($hasListeners) {
- $this->evm->dispatchEvent(Events::postRemove, new LifecycleEventArgs($entity, $this->em));
+ $this->evm->dispatchEvent(Events::postRemove, $event);
}
}
}
@@ -1691,12 +1747,24 @@ private function doRemove($entity, array &$visited)
break;
case self::STATE_MANAGED:
- if (isset($class->lifecycleCallbacks[Events::preRemove])) {
+ $hasLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::preRemove]);
+ $hasEntityListeners = isset($class->entityListeners[Events::preRemove]);
+ $hasListeners = $this->evm->hasListeners(Events::preRemove);
+
+ if ($hasListeners || $hasEntityListeners) {
+ $event = new LifecycleEventArgs($entity, $this->em);
+ }
+
+ if ($hasLifecycleCallbacks) {
$class->invokeLifecycleCallbacks(Events::preRemove, $entity);
}
- if ($this->evm->hasListeners(Events::preRemove)) {
- $this->evm->dispatchEvent(Events::preRemove, new LifecycleEventArgs($entity, $this->em));
+ if ($hasEntityListeners) {
+ $class->dispatchEntityListeners(Events::preRemove, $entity, $event);
+ }
+
+ if ($hasListeners) {
+ $this->evm->dispatchEvent(Events::preRemove, $event);
}
$this->scheduleForDelete($entity);
@@ -2695,13 +2763,24 @@ public function createEntity($className, array $data, &$hints = array())
}
if ($overrideLocalValues) {
- if (isset($class->lifecycleCallbacks[Events::postLoad])) {
+ $hasLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::postLoad]);
+ $hasEntityListeners = isset($class->entityListeners[Events::postLoad]);
+ $hasListeners = $this->evm->hasListeners(Events::postLoad);
+
+ if ($hasListeners || $hasEntityListeners) {
+ $event = new LifecycleEventArgs($entity, $this->em);
+ }
+
+ if ($hasLifecycleCallbacks) {
$class->invokeLifecycleCallbacks(Events::postLoad, $entity);
}
+ if ($hasEntityListeners) {
+ $class->dispatchEntityListeners(Events::postLoad, $entity, $event);
+ }
- if ($this->evm->hasListeners(Events::postLoad)) {
- $this->evm->dispatchEvent(Events::postLoad, new LifecycleEventArgs($entity, $this->em));
+ if ($hasListeners) {
+ $this->evm->dispatchEvent(Events::postLoad, $event);
}
}
@@ -3177,14 +3256,14 @@ public function isReadOnly($object)
private function dispatchOnFlushEvent()
{
if ($this->evm->hasListeners(Events::onFlush)) {
- $this->evm->dispatchEvent(Events::onFlush, new Event\OnFlushEventArgs($this->em));
+ $this->evm->dispatchEvent(Events::onFlush, new OnFlushEventArgs($this->em));
}
}
private function dispatchPostFlushEvent()
{
if ($this->evm->hasListeners(Events::postFlush)) {
- $this->evm->dispatchEvent(Events::postFlush, new Event\PostFlushEventArgs($this->em));
+ $this->evm->dispatchEvent(Events::postFlush, new PostFlushEventArgs($this->em));
}
}
}
View
62 tests/Doctrine/Tests/Models/Company/ContractSubscriber.php
@@ -4,8 +4,19 @@
class ContractSubscriber
{
- static public $prePersistCalls;
static public $postPersistCalls;
+ static public $prePersistCalls;
+
+ static public $postUpdateCalls;
+ static public $preUpdateCalls;
+
+ static public $postRemoveCalls;
+ static public $preRemoveCalls;
+
+ static public $preFlushCalls;
+
+ static public $postLoadCalls;
+
static public $instances;
public function __construct()
@@ -28,4 +39,53 @@ public function prePersistHandler(CompanyContract $contract)
{
self::$prePersistCalls[] = func_get_args();
}
+
+ /**
+ * @PostUpdate
+ */
+ public function postUpdateHandler(CompanyContract $contract)
+ {
+ self::$postUpdateCalls[] = func_get_args();
+ }
+
+ /**
+ * @PreUpdate
+ */
+ public function preUpdateHandler(CompanyContract $contract)
+ {
+ self::$preUpdateCalls[] = func_get_args();
+ }
+
+ /**
+ * @PostRemove
+ */
+ public function postRemoveHandler(CompanyContract $contract)
+ {
+ self::$postRemoveCalls[] = func_get_args();
+ }
+
+ /**
+ * @PreRemove
+ */
+ public function preRemoveHandler(CompanyContract $contract)
+ {
+ self::$preRemoveCalls[] = func_get_args();
+ }
+
+ /**
+ * @PreFlush
+ */
+ public function preFlushHandler(CompanyContract $contract)
+ {
+ self::$preFlushCalls[] = func_get_args();
+ }
+
+ /**
+ * @PostLoad
+ */
+ public function postLoadHandler(CompanyContract $contract)
+ {
+ self::$postLoadCalls[] = func_get_args();
+ }
+
}
View
215 tests/Doctrine/Tests/ORM/Functional/EntityListenersDispatcherTest.php
@@ -2,22 +2,223 @@
namespace Doctrine\Tests\ORM\Functional;
-use Doctrine\ORM\Events;
-use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\Tests\Models\Company\CompanyFixContract;
-use Doctrine\Tests\Models\Company\CompanyFlexContract;
use Doctrine\Tests\Models\Company\ContractSubscriber;
require_once __DIR__ . '/../../TestInit.php';
+/**
+* @group DDC-1955
+*/
class EntityListenersDispatcherTest extends \Doctrine\Tests\OrmFunctionalTestCase
{
- /**
- * @group DDC-1955
- */
- public function testEntityListeners()
+ protected function setUp()
+ {
+ $this->useModelSet('company');
+ parent::setUp();
+ }
+
+ public function testPreFlushListeners()
+ {
+ $fix = new CompanyFixContract();
+ $fix->setFixPrice(2000);
+
+ ContractSubscriber::$preFlushCalls = array();
+
+ $this->_em->persist($fix);
+ $this->_em->flush();
+
+ $this->assertCount(1,ContractSubscriber::$instances);
+ $this->assertCount(1,ContractSubscriber::$preFlushCalls);
+
+ $this->assertSame($fix, ContractSubscriber::$preFlushCalls[0][0]);
+
+ $this->assertInstanceOf(
+ 'Doctrine\Tests\Models\Company\CompanyFixContract',
+ ContractSubscriber::$preFlushCalls[0][0]
+ );
+
+ $this->assertInstanceOf(
+ 'Doctrine\ORM\Event\PreFlushEventArgs',
+ ContractSubscriber::$preFlushCalls[0][1]
+ );
+ }
+
+ public function testPostLoadListeners()
{
$this->markTestIncomplete();
}
+
+ public function testPrePersistListeners()
+ {
+ $fix = new CompanyFixContract();
+ $fix->setFixPrice(2000);
+
+ ContractSubscriber::$prePersistCalls = array();
+
+ $this->_em->persist($fix);
+ $this->_em->flush();
+
+ $this->assertCount(1,ContractSubscriber::$instances);
+ $this->assertCount(1,ContractSubscriber::$prePersistCalls);
+
+ $this->assertSame($fix, ContractSubscriber::$prePersistCalls[0][0]);
+
+ $this->assertInstanceOf(
+ 'Doctrine\Tests\Models\Company\CompanyFixContract',
+ ContractSubscriber::$prePersistCalls[0][0]
+ );
+
+ $this->assertInstanceOf(
+ 'Doctrine\ORM\Event\LifecycleEventArgs',
+ ContractSubscriber::$prePersistCalls[0][1]
+ );
+ }
+
+ public function testPostPersistListeners()
+ {
+ $fix = new CompanyFixContract();
+ $fix->setFixPrice(2000);
+
+ ContractSubscriber::$postPersistCalls = array();
+
+ $this->_em->persist($fix);
+ $this->_em->flush();
+
+ $this->assertCount(1,ContractSubscriber::$instances);
+ $this->assertCount(1,ContractSubscriber::$postPersistCalls);
+
+ $this->assertSame($fix, ContractSubscriber::$postPersistCalls[0][0]);
+
+ $this->assertInstanceOf(
+ 'Doctrine\Tests\Models\Company\CompanyFixContract',
+ ContractSubscriber::$postPersistCalls[0][0]
+ );
+
+ $this->assertInstanceOf(
+ 'Doctrine\ORM\Event\LifecycleEventArgs',
+ ContractSubscriber::$postPersistCalls[0][1]
+ );
+ }
+
+ public function testPreUpdateListeners()
+ {
+ $fix = new CompanyFixContract();
+ $fix->setFixPrice(1000);
+
+ $this->_em->persist($fix);
+ $this->_em->flush();
+
+ ContractSubscriber::$preUpdateCalls = array();
+
+ $fix->setFixPrice(2000);
+
+ $this->_em->persist($fix);
+ $this->_em->flush();
+
+ $this->assertCount(1,ContractSubscriber::$instances);
+ $this->assertCount(1,ContractSubscriber::$preUpdateCalls);
+
+ $this->assertSame($fix, ContractSubscriber::$preUpdateCalls[0][0]);
+
+ $this->assertInstanceOf(
+ 'Doctrine\Tests\Models\Company\CompanyFixContract',
+ ContractSubscriber::$preUpdateCalls[0][0]
+ );
+
+ $this->assertInstanceOf(
+ 'Doctrine\ORM\Event\PreUpdateEventArgs',
+ ContractSubscriber::$preUpdateCalls[0][1]
+ );
+ }
+
+ public function testPostUpdateListeners()
+ {
+ $fix = new CompanyFixContract();
+ $fix->setFixPrice(1000);
+
+ $this->_em->persist($fix);
+ $this->_em->flush();
+
+ ContractSubscriber::$postUpdateCalls = array();
+
+ $fix->setFixPrice(2000);
+
+ $this->_em->persist($fix);
+ $this->_em->flush();
+
+ $this->assertCount(1,ContractSubscriber::$instances);
+ $this->assertCount(1,ContractSubscriber::$postUpdateCalls);
+
+ $this->assertSame($fix, ContractSubscriber::$postUpdateCalls[0][0]);
+
+ $this->assertInstanceOf(
+ 'Doctrine\Tests\Models\Company\CompanyFixContract',
+ ContractSubscriber::$postUpdateCalls[0][0]
+ );
+
+ $this->assertInstanceOf(
+ 'Doctrine\ORM\Event\LifecycleEventArgs',
+ ContractSubscriber::$postUpdateCalls[0][1]
+ );
+ }
+
+ public function testPreRemoveListeners()
+ {
+ $fix = new CompanyFixContract();
+ $fix->setFixPrice(1000);
+
+ $this->_em->persist($fix);
+ $this->_em->flush();
+
+ ContractSubscriber::$preRemoveCalls = array();
+
+ $this->_em->remove($fix);
+ $this->_em->flush();
+
+ $this->assertCount(1,ContractSubscriber::$instances);
+ $this->assertCount(1,ContractSubscriber::$preRemoveCalls);
+
+ $this->assertSame($fix, ContractSubscriber::$preRemoveCalls[0][0]);
+
+ $this->assertInstanceOf(
+ 'Doctrine\Tests\Models\Company\CompanyFixContract',
+ ContractSubscriber::$preRemoveCalls[0][0]
+ );
+
+ $this->assertInstanceOf(
+ 'Doctrine\ORM\Event\LifecycleEventArgs',
+ ContractSubscriber::$preRemoveCalls[0][1]
+ );
+ }
+
+ public function testPostRemoveListeners()
+ {
+ $fix = new CompanyFixContract();
+ $fix->setFixPrice(1000);
+
+ $this->_em->persist($fix);
+ $this->_em->flush();
+
+ ContractSubscriber::$postRemoveCalls = array();
+
+ $this->_em->remove($fix);
+ $this->_em->flush();
+
+ $this->assertCount(1,ContractSubscriber::$instances);
+ $this->assertCount(1,ContractSubscriber::$postRemoveCalls);
+
+ $this->assertSame($fix, ContractSubscriber::$postRemoveCalls[0][0]);
+
+ $this->assertInstanceOf(
+ 'Doctrine\Tests\Models\Company\CompanyFixContract',
+ ContractSubscriber::$postRemoveCalls[0][0]
+ );
+
+ $this->assertInstanceOf(
+ 'Doctrine\ORM\Event\LifecycleEventArgs',
+ ContractSubscriber::$postRemoveCalls[0][1]
+ );
+ }
}
View
8 tests/Doctrine/Tests/ORM/Mapping/AbstractMappingDriverTest.php
@@ -826,9 +826,9 @@ public function testCallEntityListeners()
$fixClass = $factory->getMetadataFor('Doctrine\Tests\Models\Company\CompanyFlexContract');
$ultraClass = $factory->getMetadataFor('Doctrine\Tests\Models\Company\CompanyFlexUltraContract');
- ContractSubscriber::$prePersistCalls = null;
- ContractSubscriber::$postPersistCalls = null;
- FlexUltraContractSubscriber::$prePersistCalls = null;
+ ContractSubscriber::$prePersistCalls = array();
+ ContractSubscriber::$postPersistCalls = array();
+ FlexUltraContractSubscriber::$prePersistCalls = array();
$fix = new CompanyFixContract();
$fixArg = new LifecycleEventArgs($fix, $em);
@@ -862,7 +862,7 @@ public function testCallEntityListeners()
$this->assertSame($ultraArg, FlexUltraContractSubscriber::$prePersistCalls[1][1]);
$this->assertCount(1, ContractSubscriber::$instances);
- $this->assertNull(ContractSubscriber::$postPersistCalls);
+ $this->assertEmpty(ContractSubscriber::$postPersistCalls);
}
}

0 comments on commit 315f7ba

Please sign in to comment.
Something went wrong with that request. Please try again.