diff --git a/lib/Doctrine/ORM/Event/PreFlushEventArgs.php b/lib/Doctrine/ORM/Event/PreFlushEventArgs.php new file mode 100644 index 000000000..8ed39b6cb --- /dev/null +++ b/lib/Doctrine/ORM/Event/PreFlushEventArgs.php @@ -0,0 +1,56 @@ +. +*/ + +namespace Doctrine\ORM\Event; + +/** + * Provides event arguments for the preFlush event. + * + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @link www.doctrine-project.com + * @since 2.0 + * @version $Revision$ + * @author Roman Borschel + * @author Benjamin Eberlei + */ +class PreFlushEventArgs extends \Doctrine\Common\EventArgs +{ + /** + * @var EntityManager + */ + private $_em; + + //private $_entitiesToPersist = array(); + //private $_entitiesToRemove = array(); + + public function __construct($em) + { + $this->_em = $em; + } + + /** + * @return EntityManager + */ + public function getEntityManager() + { + return $this->_em; + } +} diff --git a/lib/Doctrine/ORM/Events.php b/lib/Doctrine/ORM/Events.php index e8c350aa6..8af7a9b61 100644 --- a/lib/Doctrine/ORM/Events.php +++ b/lib/Doctrine/ORM/Events.php @@ -109,6 +109,13 @@ final class Events */ const loadClassMetadata = 'loadClassMetadata'; + /** + * The preFlush event occurs when the EntityManager#flush() operation is invoked, + * but before any changes to managed entites have been calculated. This event is + * always raised right after EntityManager#flush() call. + */ + const preFlush = 'preFlush'; + /** * The onFlush event occurs when the EntityManager#flush() operation is invoked, * after any changes to managed entities have been determined but before any diff --git a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php index 36e3dcb01..b09cabc95 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php +++ b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php @@ -446,6 +446,10 @@ class AnnotationDriver implements Driver if (isset($annotations['Doctrine\ORM\Mapping\PostLoad'])) { $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postLoad); } + + if (isset($annotations['Doctrine\ORM\Mapping\PreFlush'])) { + $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::preFlush); + } } } } diff --git a/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php b/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php index e471a0d71..7f25ecbb1 100644 --- a/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php +++ b/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php @@ -387,3 +387,9 @@ final class PostRemove implements Annotation {} * @Target("METHOD") */ final class PostLoad implements Annotation {} + +/** + * @Annotation + * @Target("METHOD") + */ +final class PreFlush implements Annotation {} diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index 4366250dd..d8b640c47 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -259,6 +259,41 @@ class UnitOfWork implements PropertyChangedListener */ public function commit($entity = null) { + // Run preFlush lifecycle callback for new entities + foreach ($this->entityInsertions as $classEntity) { + $class = $this->em->getClassMetadata(get_class($classEntity)); + + // Skip class if instances are read-only + if ($class->isReadOnly) { + continue; + } + + if (isset($class->lifecycleCallbacks[Events::preFlush])) { + $class->invokeLifecycleCallbacks(Events::preFlush, $classEntity); + } + } + + // Run preFlush lifecycle callback for persisted entities + foreach ($this->identityMap as $className => $classEntities) { + $class = $this->em->getClassMetadata($className); + + // Skip class if instances are read-only + if ($class->isReadOnly) { + continue; + } + + if (isset($class->lifecycleCallbacks[Events::preFlush])) { + foreach ($classEntities as $classEntity) { + $class->invokeLifecycleCallbacks(Events::preFlush, $classEntity); + } + } + } + + // Raise preFlush + if ($this->evm->hasListeners(Events::preFlush)) { + $this->evm->dispatchEvent(Events::preFlush, new Event\PreFlushEventArgs($this->em)); + } + // Compute changes done since last commit. if ($entity === null) { $this->computeChangeSets();