move listeners invocation from ClassMetadataInfo to ListenerInvoker
This commit is contained in:
parent
c60e3e4ba4
commit
0d0f91a807
78
lib/Doctrine/ORM/Event/ListenersInvoker.php
Normal file
78
lib/Doctrine/ORM/Event/ListenersInvoker.php
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -27,7 +27,6 @@ use ReflectionClass;
|
|||||||
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
|
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
|
||||||
use Doctrine\Common\ClassLoader;
|
use Doctrine\Common\ClassLoader;
|
||||||
use Doctrine\Common\EventArgs;
|
use Doctrine\Common\EventArgs;
|
||||||
use Doctrine\ORM\Mapping\EntityListenerResolver;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A <tt>ClassMetadata</tt> instance holds all the object-relational mapping metadata
|
* 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
|
* Dispatches the lifecycle event of the given entity to the registered
|
||||||
* lifecycle callbacks and lifecycle listeners.
|
* 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 string $lifecycleEvent The lifecycle event.
|
||||||
* @param object $entity The Entity on which the event occured.
|
* @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.
|
* Sets the discriminator column definition.
|
||||||
*
|
*
|
||||||
|
@ -36,6 +36,7 @@ use Doctrine\ORM\Event\PreUpdateEventArgs;
|
|||||||
use Doctrine\ORM\Event\PreFlushEventArgs;
|
use Doctrine\ORM\Event\PreFlushEventArgs;
|
||||||
use Doctrine\ORM\Event\OnFlushEventArgs;
|
use Doctrine\ORM\Event\OnFlushEventArgs;
|
||||||
use Doctrine\ORM\Event\PostFlushEventArgs;
|
use Doctrine\ORM\Event\PostFlushEventArgs;
|
||||||
|
use Doctrine\ORM\Event\ListenersInvoker;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The UnitOfWork is responsible for tracking changes to objects during an
|
* The UnitOfWork is responsible for tracking changes to objects during an
|
||||||
@ -219,11 +220,11 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
private $evm;
|
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.
|
* Orphaned entities that are scheduled for removal.
|
||||||
@ -253,9 +254,9 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
*/
|
*/
|
||||||
public function __construct(EntityManager $em)
|
public function __construct(EntityManager $em)
|
||||||
{
|
{
|
||||||
$this->em = $em;
|
$this->em = $em;
|
||||||
$this->evm = $em->getEventManager();
|
$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
|
// Fire PreFlush lifecycle callbacks
|
||||||
if ($hasLifecycleCallbacks) {
|
if ($hasLifecycleCallbacks) {
|
||||||
$class->invokeLifecycleCallbacks(Events::preFlush, $entity, $event);
|
$this->listenersInvoker->invokeLifecycleCallbacks($class, Events::preFlush, $entity, $event);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fire PreFlush entity listeners
|
// Fire PreFlush entity listeners
|
||||||
if ($hasEntityListeners) {
|
if ($hasEntityListeners) {
|
||||||
$class->dispatchEntityListeners($this->entityListenerResolver, Events::preFlush, $entity, $event);
|
$this->listenersInvoker->invokeEntityListeners($class, Events::preFlush, $entity, $event);
|
||||||
}
|
}
|
||||||
|
|
||||||
$actualData = array();
|
$actualData = array();
|
||||||
@ -840,11 +841,11 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($hasLifecycleCallbacks) {
|
if ($hasLifecycleCallbacks) {
|
||||||
$class->invokeLifecycleCallbacks(Events::prePersist, $entity, $event);
|
$this->listenersInvoker->invokeLifecycleCallbacks($class, Events::prePersist, $entity, $event);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($hasEntityListeners) {
|
if ($hasEntityListeners) {
|
||||||
$class->dispatchEntityListeners($this->entityListenerResolver, Events::prePersist, $entity, $event);
|
$this->listenersInvoker->invokeEntityListeners($class, Events::prePersist, $entity, $event);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($hasListeners) {
|
if ($hasListeners) {
|
||||||
@ -990,11 +991,11 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($hasLifecycleCallbacks) {
|
if ($hasLifecycleCallbacks) {
|
||||||
$class->invokeLifecycleCallbacks(Events::postPersist, $entity, $event);
|
$this->listenersInvoker->invokeLifecycleCallbacks($class, Events::postPersist, $entity, $event);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($hasEntityListeners) {
|
if ($hasEntityListeners) {
|
||||||
$class->dispatchEntityListeners($this->entityListenerResolver, Events::postPersist, $entity, $event);
|
$this->listenersInvoker->invokeEntityListeners($class, Events::postPersist, $entity, $event);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($hasListeners) {
|
if ($hasListeners) {
|
||||||
@ -1037,13 +1038,13 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($hasPreUpdateLifecycleCallbacks) {
|
if ($hasPreUpdateLifecycleCallbacks) {
|
||||||
$class->invokeLifecycleCallbacks(Events::preUpdate, $entity, $preEvent);
|
$this->listenersInvoker->invokeLifecycleCallbacks($class, Events::preUpdate, $entity, $preEvent);
|
||||||
|
|
||||||
$this->recomputeSingleEntityChangeSet($class, $entity);
|
$this->recomputeSingleEntityChangeSet($class, $entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($hasPreUpdateEntityListeners) {
|
if ($hasPreUpdateEntityListeners) {
|
||||||
$class->dispatchEntityListeners($this->entityListenerResolver, Events::preUpdate, $entity, $preEvent);
|
$this->listenersInvoker->invokeEntityListeners($class, Events::preUpdate, $entity, $preEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($hasPreUpdateListeners) {
|
if ($hasPreUpdateListeners) {
|
||||||
@ -1057,11 +1058,11 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
unset($this->entityUpdates[$oid]);
|
unset($this->entityUpdates[$oid]);
|
||||||
|
|
||||||
if ($hasPostUpdateLifecycleCallbacks) {
|
if ($hasPostUpdateLifecycleCallbacks) {
|
||||||
$class->invokeLifecycleCallbacks(Events::postUpdate, $entity, $postEvent);
|
$this->listenersInvoker->invokeLifecycleCallbacks($class, Events::postUpdate, $entity, $postEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($hasPostUpdateEntityListeners) {
|
if ($hasPostUpdateEntityListeners) {
|
||||||
$class->dispatchEntityListeners($this->entityListenerResolver, Events::postUpdate, $entity, $postEvent);
|
$this->listenersInvoker->invokeEntityListeners($class, Events::postUpdate, $entity, $postEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($hasPostUpdateListeners) {
|
if ($hasPostUpdateListeners) {
|
||||||
@ -1112,11 +1113,11 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($hasLifecycleCallbacks) {
|
if ($hasLifecycleCallbacks) {
|
||||||
$class->invokeLifecycleCallbacks(Events::postRemove, $entity, $event);
|
$this->listenersInvoker->invokeLifecycleCallbacks($class, Events::postRemove, $entity, $event);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($hasEntityListeners) {
|
if ($hasEntityListeners) {
|
||||||
$class->dispatchEntityListeners($this->entityListenerResolver, Events::postRemove, $entity, $event);
|
$this->listenersInvoker->invokeEntityListeners($class, Events::postRemove, $entity, $event);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($hasListeners) {
|
if ($hasListeners) {
|
||||||
@ -1769,11 +1770,11 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($hasLifecycleCallbacks) {
|
if ($hasLifecycleCallbacks) {
|
||||||
$class->invokeLifecycleCallbacks(Events::preRemove, $entity, $event);
|
$this->listenersInvoker->invokeLifecycleCallbacks($class, Events::preRemove, $entity, $event);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($hasEntityListeners) {
|
if ($hasEntityListeners) {
|
||||||
$class->dispatchEntityListeners($this->entityListenerResolver, Events::preRemove, $entity, $event);
|
$this->listenersInvoker->invokeEntityListeners($class, Events::preRemove, $entity, $event);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($hasListeners) {
|
if ($hasListeners) {
|
||||||
@ -2785,11 +2786,11 @@ class UnitOfWork implements PropertyChangedListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($hasLifecycleCallbacks) {
|
if ($hasLifecycleCallbacks) {
|
||||||
$class->invokeLifecycleCallbacks(Events::postLoad, $entity, $event);
|
$this->listenersInvoker->invokeLifecycleCallbacks($class, Events::postLoad, $entity, $event);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($hasEntityListeners) {
|
if ($hasEntityListeners) {
|
||||||
$class->dispatchEntityListeners($this->entityListenerResolver, Events::postLoad, $entity, $event);
|
$this->listenersInvoker->invokeEntityListeners($class, Events::postLoad, $entity, $event);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($hasListeners) {
|
if ($hasListeners) {
|
||||||
|
@ -804,58 +804,6 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase
|
|||||||
$this->assertEquals('Doctrine\Tests\Models\Company\CompanyFlexUltraContractListener', $prePersist['class']);
|
$this->assertEquals('Doctrine\Tests\Models\Company\CompanyFlexUltraContractListener', $prePersist['class']);
|
||||||
$this->assertEquals('prePersistHandler2', $prePersist['method']);
|
$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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user