1
0
Fork 0
mirror of synced 2025-04-01 12:26:11 +03:00

call listeners in UoW

This commit is contained in:
Fabio B. Silva 2012-07-30 22:26:55 -03:00 committed by fabio.silva
parent ccc0a2a94f
commit 315f7ba43b
4 changed files with 378 additions and 38 deletions

View file

@ -22,15 +22,21 @@ namespace Doctrine\ORM;
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 @@ class UnitOfWork implements PropertyChangedListener
{
// 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 @@ class UnitOfWork implements PropertyChangedListener
$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 @@ class UnitOfWork implements PropertyChangedListener
}
/**
* @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 (isset($class->lifecycleCallbacks[Events::prePersist])) {
if ($hasListeners || $hasEntityListeners) {
$event = new LifecycleEventArgs($entity, $this->em);
}
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 @@ class UnitOfWork implements PropertyChangedListener
$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 @@ class UnitOfWork implements PropertyChangedListener
unset($this->entityInsertions[$oid]);
if ($hasLifecycleCallbacks || $hasListeners) {
if ($hasLifecycleCallbacks || $hasEntityListeners || $hasListeners) {
$entities[] = $entity;
}
}
@ -946,14 +969,23 @@ class UnitOfWork implements PropertyChangedListener
$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,9 +1003,11 @@ class UnitOfWork implements PropertyChangedListener
$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) {
@ -981,17 +1015,26 @@ class UnitOfWork implements PropertyChangedListener
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 @@ class UnitOfWork implements PropertyChangedListener
$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 @@ class UnitOfWork implements PropertyChangedListener
$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 @@ class UnitOfWork implements PropertyChangedListener
$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 @@ class UnitOfWork implements PropertyChangedListener
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 @@ class UnitOfWork implements PropertyChangedListener
}
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 @@ class UnitOfWork implements PropertyChangedListener
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 file

@ -4,8 +4,19 @@ namespace Doctrine\Tests\Models\Company;
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 @@ class ContractSubscriber
{
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 file

@ -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 file

@ -826,9 +826,9 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase
$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 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase
$this->assertSame($ultraArg, FlexUltraContractSubscriber::$prePersistCalls[1][1]);
$this->assertCount(1, ContractSubscriber::$instances);
$this->assertNull(ContractSubscriber::$postPersistCalls);
$this->assertEmpty(ContractSubscriber::$postPersistCalls);
}
}