[2.0] DDC-358 - Refactored UnitOfWork Event triggering capabilities
This commit is contained in:
parent
30712c6cb5
commit
ac62e4d9bb
@ -11,7 +11,7 @@ class ArrayType extends Type
|
||||
{
|
||||
public function getSqlDeclaration(array $fieldDeclaration, \Doctrine\DBAL\Platforms\AbstractPlatform $platform)
|
||||
{
|
||||
return $platform->getClobDeclarationSql($fieldDeclaration);
|
||||
return $platform->getClobTypeDeclarationSql($fieldDeclaration);
|
||||
}
|
||||
|
||||
public function convertToDatabaseValue($value, \Doctrine\DBAL\Platforms\AbstractPlatform $platform)
|
||||
|
@ -1,26 +1,66 @@
|
||||
<?php
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* 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 LGPL. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\ORM\Event;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
|
||||
/**
|
||||
* Lifecycle Events are triggered by the UnitOfWork
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.com
|
||||
* @since 1.0
|
||||
* @version $Revision$
|
||||
* @author Roman Borschel <roman@code-factory.de>
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
class LifecycleEventArgs extends \Doctrine\Common\EventArgs
|
||||
{
|
||||
//private $_em;
|
||||
/**
|
||||
* @var EntityManager
|
||||
*/
|
||||
private $_em;
|
||||
|
||||
/**
|
||||
* @var object
|
||||
*/
|
||||
private $_entity;
|
||||
|
||||
public function __construct($entity)
|
||||
public function __construct($entity, EntityManager $em)
|
||||
{
|
||||
$this->_entity = $entity;
|
||||
$this->_em = $em;
|
||||
}
|
||||
|
||||
public function getEntity()
|
||||
{
|
||||
return $this->_entity;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
/**
|
||||
* @return EntityManager
|
||||
*/
|
||||
public function getEntityManager()
|
||||
{
|
||||
return $this->_em;
|
||||
}
|
||||
*/
|
||||
}
|
@ -365,6 +365,29 @@ class UnitOfWork implements PropertyChangedListener
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method can be used to compute the change-set of any entity.
|
||||
*
|
||||
* @Internal
|
||||
*
|
||||
* @Todo inline _computeChangeSet to here?
|
||||
*
|
||||
* @param ClassMetadata $class
|
||||
* @param object $entity
|
||||
* @return void
|
||||
*/
|
||||
public function computeChangeSet($class, $entity)
|
||||
{
|
||||
$this->_computeEntityChanges($class, $entity);
|
||||
// Look for changes in associations of the entity
|
||||
foreach ($class->associationMappings as $assoc) {
|
||||
$val = $class->reflFields[$assoc->sourceFieldName]->getValue($entity);
|
||||
if ($val !== null) {
|
||||
$this->_computeAssociationChanges($assoc, $val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes all the changes that have been done to entities and collections
|
||||
* since the last commit and stores these changes in the _entityChangeSet map
|
||||
@ -375,14 +398,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
// Compute changes for INSERTed entities first. This must always happen.
|
||||
foreach ($this->_entityInsertions as $entity) {
|
||||
$class = $this->_em->getClassMetadata(get_class($entity));
|
||||
$this->_computeEntityChanges($class, $entity);
|
||||
// Look for changes in associations of the entity
|
||||
foreach ($class->associationMappings as $assoc) {
|
||||
$val = $class->reflFields[$assoc->sourceFieldName]->getValue($entity);
|
||||
if ($val !== null) {
|
||||
$this->_computeAssociationChanges($assoc, $val);
|
||||
}
|
||||
}
|
||||
$this->computeChangeSet($class, $entity);
|
||||
}
|
||||
|
||||
// Compute changes for other MANAGED entities. Change tracking policies take effect here.
|
||||
@ -406,14 +422,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
// Only MANAGED entities that are NOT SCHEDULED FOR INSERTION are processed here.
|
||||
$oid = spl_object_hash($entity);
|
||||
if ( ! isset($this->_entityInsertions[$oid]) && isset($this->_entityStates[$oid])) {
|
||||
$this->_computeEntityChanges($class, $entity);
|
||||
// Look for changes in associations of the entity
|
||||
foreach ($class->associationMappings as $assoc) {
|
||||
$val = $class->reflFields[$assoc->sourceFieldName]->getValue($entity);
|
||||
if ($val !== null) {
|
||||
$this->_computeAssociationChanges($assoc, $val);
|
||||
}
|
||||
}
|
||||
$this->computeChangeSet($class, $entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -528,11 +537,26 @@ class UnitOfWork implements PropertyChangedListener
|
||||
}
|
||||
}
|
||||
if ($changeSet) {
|
||||
if ($entityIsDirty) {
|
||||
$this->_entityUpdates[$oid] = $entity;
|
||||
}
|
||||
$this->_entityChangeSets[$oid] = $changeSet;
|
||||
$this->_originalEntityData[$oid] = $actualData;
|
||||
|
||||
if ($entityIsDirty) {
|
||||
$hasPreUpdateListeners = $this->_evm->hasListeners(Events::preUpdate);
|
||||
if (isset($class->lifecycleCallbacks[Events::preUpdate])) {
|
||||
$class->invokeLifecycleCallbacks(Events::preUpdate, $entity);
|
||||
if ( ! $hasPreUpdateListeners) {
|
||||
// Need to recompute entity changeset to detect changes made in the callback.
|
||||
$this->recomputeSingleEntityChangeSet($class, $entity);
|
||||
}
|
||||
}
|
||||
if ($hasPreUpdateListeners) {
|
||||
$this->_evm->dispatchEvent(Events::preUpdate, new LifecycleEventArgs($entity, $this->_em));
|
||||
// Need to recompute entity changeset to detect changes made in the listener.
|
||||
$this->recomputeSingleEntityChangeSet($class, $entity);
|
||||
}
|
||||
|
||||
$this->_entityUpdates[$oid] = $entity;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -576,7 +600,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
$targetClass->invokeLifecycleCallbacks(Events::prePersist, $entry);
|
||||
}
|
||||
if ($this->_evm->hasListeners(Events::prePersist)) {
|
||||
$this->_evm->dispatchEvent(Events::prePersist, new LifecycleEventArgs($entry));
|
||||
$this->_evm->dispatchEvent(Events::prePersist, new LifecycleEventArgs($entry, $this->_em));
|
||||
}
|
||||
|
||||
// Get identifier, if possible (not post-insert)
|
||||
@ -595,15 +619,8 @@ class UnitOfWork implements PropertyChangedListener
|
||||
|
||||
// NEW entities are INSERTed within the current unit of work.
|
||||
$this->_entityInsertions[$oid] = $entry;
|
||||
|
||||
$this->_computeEntityChanges($targetClass, $entry);
|
||||
// Look for changes in associations of the entity
|
||||
foreach ($targetClass->associationMappings as $assoc2) {
|
||||
$val = $targetClass->reflFields[$assoc2->sourceFieldName]->getValue($entry);
|
||||
if ($val !== null) {
|
||||
$this->_computeAssociationChanges($assoc2, $val);
|
||||
}
|
||||
}
|
||||
|
||||
$this->computeChangeSet($targetClass, $entry);
|
||||
|
||||
} else if ($state == self::STATE_REMOVED) {
|
||||
throw ORMException::removedEntityInCollectionDetected($entity, $assoc);
|
||||
@ -627,7 +644,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
* @param object $entity The entity for which to (re)calculate the change set.
|
||||
* @throws InvalidArgumentException If the passed entity is not MANAGED.
|
||||
*/
|
||||
public function computeSingleEntityChangeSet($class, $entity)
|
||||
public function recomputeSingleEntityChangeSet($class, $entity)
|
||||
{
|
||||
$oid = spl_object_hash($entity);
|
||||
|
||||
@ -718,7 +735,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
$class->invokeLifecycleCallbacks(Events::postPersist, $entity);
|
||||
}
|
||||
if ($hasListeners) {
|
||||
$this->_evm->dispatchEvent(Events::postPersist, new LifecycleEventArgs($entity));
|
||||
$this->_evm->dispatchEvent(Events::postPersist, new LifecycleEventArgs($entity, $this->_em));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -734,26 +751,11 @@ class UnitOfWork implements PropertyChangedListener
|
||||
$className = $class->name;
|
||||
$persister = $this->getEntityPersister($className);
|
||||
|
||||
$hasPreUpdateLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::preUpdate]);
|
||||
$hasPreUpdateListeners = $this->_evm->hasListeners(Events::preUpdate);
|
||||
$hasPostUpdateLifecycleCallbacks = isset($class->lifecycleCallbacks[Events::postUpdate]);
|
||||
$hasPostUpdateListeners = $this->_evm->hasListeners(Events::postUpdate);
|
||||
|
||||
foreach ($this->_entityUpdates as $oid => $entity) {
|
||||
if (get_class($entity) == $className || $entity instanceof Proxy && $entity instanceof $className) {
|
||||
if ($hasPreUpdateLifecycleCallbacks) {
|
||||
$class->invokeLifecycleCallbacks(Events::preUpdate, $entity);
|
||||
if ( ! $hasPreUpdateListeners) {
|
||||
// Need to recompute entity changeset to detect changes made in the callback.
|
||||
$this->computeSingleEntityChangeSet($class, $entity);
|
||||
}
|
||||
}
|
||||
if ($hasPreUpdateListeners) {
|
||||
$this->_evm->dispatchEvent(Events::preUpdate, new LifecycleEventArgs($entity));
|
||||
// Need to recompute entity changeset to detect changes made in the listener.
|
||||
$this->computeSingleEntityChangeSet($class, $entity);
|
||||
}
|
||||
|
||||
if (get_class($entity) == $className || $entity instanceof Proxy && $entity instanceof $className) {
|
||||
$persister->update($entity);
|
||||
unset($this->_entityUpdates[$oid]);
|
||||
|
||||
@ -761,7 +763,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
$class->invokeLifecycleCallbacks(Events::postUpdate, $entity);
|
||||
}
|
||||
if ($hasPostUpdateListeners) {
|
||||
$this->_evm->dispatchEvent(Events::postUpdate, new LifecycleEventArgs($entity));
|
||||
$this->_evm->dispatchEvent(Events::postUpdate, new LifecycleEventArgs($entity, $this->_em));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -796,7 +798,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
$class->invokeLifecycleCallbacks(Events::postRemove, $entity);
|
||||
}
|
||||
if ($hasListeners) {
|
||||
$this->_evm->dispatchEvent(Events::postRemove, new LifecycleEventArgs($entity));
|
||||
$this->_evm->dispatchEvent(Events::postRemove, new LifecycleEventArgs($entity, $this->_em));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1198,7 +1200,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
$class->invokeLifecycleCallbacks(Events::prePersist, $entity);
|
||||
}
|
||||
if ($this->_evm->hasListeners(Events::prePersist)) {
|
||||
$this->_evm->dispatchEvent(Events::prePersist, new LifecycleEventArgs($entity));
|
||||
$this->_evm->dispatchEvent(Events::prePersist, new LifecycleEventArgs($entity, $this->_em));
|
||||
}
|
||||
|
||||
$idGen = $class->idGenerator;
|
||||
@ -1276,7 +1278,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
$class->invokeLifecycleCallbacks(Events::preRemove, $entity);
|
||||
}
|
||||
if ($this->_evm->hasListeners(Events::preRemove)) {
|
||||
$this->_evm->dispatchEvent(Events::preRemove, new LifecycleEventArgs($entity));
|
||||
$this->_evm->dispatchEvent(Events::preRemove, new LifecycleEventArgs($entity, $this->_em));
|
||||
}
|
||||
$this->scheduleForDelete($entity);
|
||||
break;
|
||||
@ -1835,7 +1837,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
$class->invokeLifecycleCallbacks(Events::postLoad, $entity);
|
||||
}
|
||||
if ($this->_evm->hasListeners(Events::postLoad)) {
|
||||
$this->_evm->dispatchEvent(Events::postLoad, new LifecycleEventArgs($entity));
|
||||
$this->_evm->dispatchEvent(Events::postLoad, new LifecycleEventArgs($entity, $this->_em));
|
||||
}
|
||||
|
||||
return $entity;
|
||||
|
Loading…
x
Reference in New Issue
Block a user