1
0
mirror of synced 2025-01-18 06:21:40 +03:00

move listeners invocation from ClassMetadataInfo to ListenerInvoker

This commit is contained in:
Fabio B. Silva 2012-10-13 21:46:24 -03:00 committed by fabio.silva
parent c60e3e4ba4
commit 0d0f91a807
4 changed files with 103 additions and 94 deletions

View File

@ -0,0 +1,78 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license. For more information, see
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Event;
use Doctrine\ORM\Mapping\EntityListenerResolver;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\Common\EventArgs;
/**
* A method invoker based on entity lifecycle.
*
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
* @since 2.4
*/
class ListenersInvoker
{
/**
* @var \Doctrine\ORM\Mapping\EntityListenerResolver The Entity listener resolver.
*/
private $resolver;
/**
* @param \Doctrine\ORM\Mapping\EntityListenerResolver $resolver
*/
public function __construct(EntityListenerResolver $resolver)
{
$this->resolver = $resolver;
}
/**
* Dispatches the lifecycle event of the given entity to the registered lifecycle callbacks.
*
* @param string $eventName The entity lifecycle event.
* @param \Object $entity The Entity on which the event occured.
* @param \Doctrine\Common\EventArgs $event The Event args.
*/
public function invokeLifecycleCallbacks(ClassMetadata $metadata, $eventName, $entity, EventArgs $event)
{
foreach ($metadata->lifecycleCallbacks[$eventName] as $callback) {
$entity->$callback($event);
}
}
/**
* Dispatches the lifecycle event of the given entity to the registered entity listeners.
*
* @param string $eventName The entity lifecycle event.
* @param object $entity The Entity on which the event occured.
* @param \Doctrine\Common\EventArgs $event The Event args.
*/
public function invokeEntityListeners(ClassMetadata $metadata, $eventName, $entity, EventArgs $event)
{
foreach ($metadata->entityListeners[$eventName] as $listener) {
$class = $listener['class'];
$method = $listener['method'];
$instance = $this->resolver->resolve($class);
$instance->{$method}($entity, $event);
}
}
}

View File

@ -27,7 +27,6 @@ use ReflectionClass;
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
use Doctrine\Common\ClassLoader;
use Doctrine\Common\EventArgs;
use Doctrine\ORM\Mapping\EntityListenerResolver;
/**
* A <tt>ClassMetadata</tt> instance holds all the object-relational mapping metadata
@ -2426,6 +2425,8 @@ class ClassMetadataInfo implements ClassMetadata
* Dispatches the lifecycle event of the given entity to the registered
* lifecycle callbacks and lifecycle listeners.
*
* @deprecated Deprecated since version 2.4 in favor of \Doctrine\ORM\Event\ListenersInvoker
*
* @param string $lifecycleEvent The lifecycle event.
* @param object $entity The Entity on which the event occured.
*
@ -2513,25 +2514,6 @@ class ClassMetadataInfo implements ClassMetadata
);
}
/**
* Call the entity listeners.
*
* @param \Doctrine\ORM\Mapping\EntityListenerResolver $resolver The Entity listener resolver.
* @param string $eventName The event name.
* @param object $entity An instance of the mapped entity
* @param \Doctrine\Common\EventArgs $arg The Event args
*/
public function dispatchEntityListeners(EntityListenerResolver $resolver, $eventName, $entity, EventArgs $arg)
{
foreach ($this->entityListeners[$eventName] as $listener) {
$class = $listener['class'];
$method = $listener['method'];
$instance = $resolver->resolve($class);
$instance->{$method}($entity, $arg);
}
}
/**
* Sets the discriminator column definition.
*

View File

@ -36,6 +36,7 @@ use Doctrine\ORM\Event\PreUpdateEventArgs;
use Doctrine\ORM\Event\PreFlushEventArgs;
use Doctrine\ORM\Event\OnFlushEventArgs;
use Doctrine\ORM\Event\PostFlushEventArgs;
use Doctrine\ORM\Event\ListenersInvoker;
/**
* The UnitOfWork is responsible for tracking changes to objects during an
@ -219,11 +220,11 @@ class UnitOfWork implements PropertyChangedListener
private $evm;
/**
* The EntityListenerResolver used for dispatching events.
* The ListenersInvoker used for dispatching events.
*
* @var \Doctrine\ORM\Mapping\EntityListenerResolver
* @var \Doctrine\ORM\Event\ListenersInvoker
*/
private $entityListenerResolver;
private $listenersInvoker;
/**
* Orphaned entities that are scheduled for removal.
@ -255,7 +256,7 @@ class UnitOfWork implements PropertyChangedListener
{
$this->em = $em;
$this->evm = $em->getEventManager();
$this->entityListenerResolver = $em->getConfiguration()->getEntityListenerResolver();
$this->listenersInvoker = new ListenersInvoker($em->getConfiguration()->getEntityListenerResolver());
}
/**
@ -528,12 +529,12 @@ class UnitOfWork implements PropertyChangedListener
// Fire PreFlush lifecycle callbacks
if ($hasLifecycleCallbacks) {
$class->invokeLifecycleCallbacks(Events::preFlush, $entity, $event);
$this->listenersInvoker->invokeLifecycleCallbacks($class, Events::preFlush, $entity, $event);
}
// Fire PreFlush entity listeners
if ($hasEntityListeners) {
$class->dispatchEntityListeners($this->entityListenerResolver, Events::preFlush, $entity, $event);
$this->listenersInvoker->invokeEntityListeners($class, Events::preFlush, $entity, $event);
}
$actualData = array();
@ -840,11 +841,11 @@ class UnitOfWork implements PropertyChangedListener
}
if ($hasLifecycleCallbacks) {
$class->invokeLifecycleCallbacks(Events::prePersist, $entity, $event);
$this->listenersInvoker->invokeLifecycleCallbacks($class, Events::prePersist, $entity, $event);
}
if ($hasEntityListeners) {
$class->dispatchEntityListeners($this->entityListenerResolver, Events::prePersist, $entity, $event);
$this->listenersInvoker->invokeEntityListeners($class, Events::prePersist, $entity, $event);
}
if ($hasListeners) {
@ -990,11 +991,11 @@ class UnitOfWork implements PropertyChangedListener
}
if ($hasLifecycleCallbacks) {
$class->invokeLifecycleCallbacks(Events::postPersist, $entity, $event);
$this->listenersInvoker->invokeLifecycleCallbacks($class, Events::postPersist, $entity, $event);
}
if ($hasEntityListeners) {
$class->dispatchEntityListeners($this->entityListenerResolver, Events::postPersist, $entity, $event);
$this->listenersInvoker->invokeEntityListeners($class, Events::postPersist, $entity, $event);
}
if ($hasListeners) {
@ -1037,13 +1038,13 @@ class UnitOfWork implements PropertyChangedListener
}
if ($hasPreUpdateLifecycleCallbacks) {
$class->invokeLifecycleCallbacks(Events::preUpdate, $entity, $preEvent);
$this->listenersInvoker->invokeLifecycleCallbacks($class, Events::preUpdate, $entity, $preEvent);
$this->recomputeSingleEntityChangeSet($class, $entity);
}
if ($hasPreUpdateEntityListeners) {
$class->dispatchEntityListeners($this->entityListenerResolver, Events::preUpdate, $entity, $preEvent);
$this->listenersInvoker->invokeEntityListeners($class, Events::preUpdate, $entity, $preEvent);
}
if ($hasPreUpdateListeners) {
@ -1057,11 +1058,11 @@ class UnitOfWork implements PropertyChangedListener
unset($this->entityUpdates[$oid]);
if ($hasPostUpdateLifecycleCallbacks) {
$class->invokeLifecycleCallbacks(Events::postUpdate, $entity, $postEvent);
$this->listenersInvoker->invokeLifecycleCallbacks($class, Events::postUpdate, $entity, $postEvent);
}
if ($hasPostUpdateEntityListeners) {
$class->dispatchEntityListeners($this->entityListenerResolver, Events::postUpdate, $entity, $postEvent);
$this->listenersInvoker->invokeEntityListeners($class, Events::postUpdate, $entity, $postEvent);
}
if ($hasPostUpdateListeners) {
@ -1112,11 +1113,11 @@ class UnitOfWork implements PropertyChangedListener
}
if ($hasLifecycleCallbacks) {
$class->invokeLifecycleCallbacks(Events::postRemove, $entity, $event);
$this->listenersInvoker->invokeLifecycleCallbacks($class, Events::postRemove, $entity, $event);
}
if ($hasEntityListeners) {
$class->dispatchEntityListeners($this->entityListenerResolver, Events::postRemove, $entity, $event);
$this->listenersInvoker->invokeEntityListeners($class, Events::postRemove, $entity, $event);
}
if ($hasListeners) {
@ -1769,11 +1770,11 @@ class UnitOfWork implements PropertyChangedListener
}
if ($hasLifecycleCallbacks) {
$class->invokeLifecycleCallbacks(Events::preRemove, $entity, $event);
$this->listenersInvoker->invokeLifecycleCallbacks($class, Events::preRemove, $entity, $event);
}
if ($hasEntityListeners) {
$class->dispatchEntityListeners($this->entityListenerResolver, Events::preRemove, $entity, $event);
$this->listenersInvoker->invokeEntityListeners($class, Events::preRemove, $entity, $event);
}
if ($hasListeners) {
@ -2785,11 +2786,11 @@ class UnitOfWork implements PropertyChangedListener
}
if ($hasLifecycleCallbacks) {
$class->invokeLifecycleCallbacks(Events::postLoad, $entity, $event);
$this->listenersInvoker->invokeLifecycleCallbacks($class, Events::postLoad, $entity, $event);
}
if ($hasEntityListeners) {
$class->dispatchEntityListeners($this->entityListenerResolver, Events::postLoad, $entity, $event);
$this->listenersInvoker->invokeEntityListeners($class, Events::postLoad, $entity, $event);
}
if ($hasListeners) {

View File

@ -804,58 +804,6 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase
$this->assertEquals('Doctrine\Tests\Models\Company\CompanyFlexUltraContractListener', $prePersist['class']);
$this->assertEquals('prePersistHandler2', $prePersist['method']);
}
/**
* @group DDC-1955
*/
public function testCallEntityListeners()
{
$em = $this->_getTestEntityManager();
$factory = $this->createClassMetadataFactory($em);
$resolver = $em->getConfiguration()->getEntityListenerResolver();
$flexClass = $factory->getMetadataFor('Doctrine\Tests\Models\Company\CompanyFixContract');
$fixClass = $factory->getMetadataFor('Doctrine\Tests\Models\Company\CompanyFlexContract');
$ultraClass = $factory->getMetadataFor('Doctrine\Tests\Models\Company\CompanyFlexUltraContract');
$contractListener = $resolver->resolve('Doctrine\Tests\Models\Company\CompanyContractListener');
$ultraContractListener = $resolver->resolve('Doctrine\Tests\Models\Company\CompanyFlexUltraContractListener');
$contractListener->prePersistCalls = array();
$contractListener->postPersistCalls = array();
$ultraContractListener->prePersistCalls = array();
$fix = new CompanyFixContract();
$fixArg = new LifecycleEventArgs($fix, $em);
$flex = new CompanyFlexContract();
$flexArg = new LifecycleEventArgs($fix, $em);
$ultra = new CompanyFlexContract();
$ultraArg = new LifecycleEventArgs($ultra, $em);
$fixClass->dispatchEntityListeners($resolver, Events::prePersist, $fix, $fixArg);
$flexClass->dispatchEntityListeners($resolver, Events::prePersist, $flex, $flexArg);
$ultraClass->dispatchEntityListeners($resolver, Events::prePersist, $ultra, $ultraArg);
$this->assertCount(3, $contractListener->prePersistCalls);
$this->assertCount(2, $ultraContractListener->prePersistCalls);
$this->assertSame($fix, $contractListener->prePersistCalls[0][0]);
$this->assertSame($fixArg, $contractListener->prePersistCalls[0][1]);
$this->assertSame($flex, $contractListener->prePersistCalls[1][0]);
$this->assertSame($flexArg, $contractListener->prePersistCalls[1][1]);
$this->assertSame($ultra, $contractListener->prePersistCalls[2][0]);
$this->assertSame($ultraArg, $contractListener->prePersistCalls[2][1]);
$this->assertSame($ultra, $ultraContractListener->prePersistCalls[0][0]);
$this->assertSame($ultraArg, $ultraContractListener->prePersistCalls[0][1]);
$this->assertSame($ultra, $ultraContractListener->prePersistCalls[1][0]);
$this->assertSame($ultraArg, $ultraContractListener->prePersistCalls[1][1]);
$this->assertEmpty($contractListener->postPersistCalls);
}
}
/**