[2.0] First draft for onFlush event.
This commit is contained in:
parent
7badced187
commit
a1a8093888
@ -72,7 +72,7 @@ class AnnotationReader
|
||||
$this->_parser = new Parser;
|
||||
$this->_cache = $cache ?: new Doctrine\Common\Cache\ArrayCache;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the default namespace that the AnnotationReader should assume for annotations
|
||||
* with not fully qualified names.
|
||||
@ -83,7 +83,7 @@ class AnnotationReader
|
||||
{
|
||||
$this->_parser->setDefaultAnnotationNamespace($defaultNamespace);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets an alias for an annotation namespace.
|
||||
*
|
||||
@ -94,7 +94,7 @@ class AnnotationReader
|
||||
{
|
||||
$this->_parser->setAnnotationNamespaceAlias($namespace, $alias);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the annotations applied to a class.
|
||||
*
|
||||
|
@ -249,7 +249,7 @@ class Parser
|
||||
$name = implode('\\', $nameParts);
|
||||
}
|
||||
|
||||
// If it really an annotation class?
|
||||
// Is it really an annotation class?
|
||||
if (
|
||||
(! $this->_isNestedAnnotation && $this->_lexer->lookahead != null &&
|
||||
! $this->_lexer->isNextToken(Lexer::T_OPEN_PARENTHESIS) &&
|
||||
|
@ -22,7 +22,8 @@
|
||||
namespace Doctrine\ORM\Event;
|
||||
|
||||
/**
|
||||
* Lifecycle Events are triggered by the UnitOfWork
|
||||
* Lifecycle Events are triggered by the UnitOfWork during lifecycle transitions
|
||||
* of entities.
|
||||
*
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @link www.doctrine-project.com
|
||||
|
78
lib/Doctrine/ORM/Event/OnFlushEventArgs.php
Normal file
78
lib/Doctrine/ORM/Event/OnFlushEventArgs.php
Normal file
@ -0,0 +1,78 @@
|
||||
<?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;
|
||||
|
||||
/**
|
||||
* 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 <roman@code-factory.de>
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
class OnFlushEventArgs 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;
|
||||
}
|
||||
|
||||
/*
|
||||
public function addEntityToPersist($entity)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function addEntityToRemove($entity)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function addEntityToUpdate($entity)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function getEntitiesToPersist()
|
||||
{
|
||||
return $this->_entitiesToPersist;
|
||||
}
|
||||
*/
|
||||
}
|
@ -108,4 +108,15 @@ final class Events
|
||||
* @var string
|
||||
*/
|
||||
const loadClassMetadata = 'loadClassMetadata';
|
||||
|
||||
/**
|
||||
* The onFlush event occurs when the EntityManager#flush() operation is invoked,
|
||||
* after any changes to managed entities have been determined but before any
|
||||
* actual database operations are executed. The event is only raised if there is
|
||||
* actually something to do for the underlying UnitOfWork. If nothing needs to be done,
|
||||
* the onFlush event is not raised.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const onFlush = 'onFlush';
|
||||
}
|
@ -339,10 +339,10 @@ class StandardEntityPersister
|
||||
if (isset($this->_class->associationMappings[$field])) {
|
||||
$assocMapping = $this->_class->associationMappings[$field];
|
||||
// Only owning side of x-1 associations can have a FK column.
|
||||
if ( ! $assocMapping->isOneToOne() || ! $assocMapping->isOwningSide) {
|
||||
if ( ! $assocMapping->isOwningSide || ! $assocMapping->isOneToOne()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if ($newVal !== null) {
|
||||
$oid = spl_object_hash($newVal);
|
||||
if (isset($this->_queuedInserts[$oid]) || $uow->isScheduledForInsert($newVal)) {
|
||||
|
@ -271,6 +271,11 @@ class UnitOfWork implements PropertyChangedListener
|
||||
}
|
||||
}
|
||||
|
||||
// Raise onFlush
|
||||
if ($this->_evm->hasListeners(Events::onFlush)) {
|
||||
$this->_evm->dispatchEvent(Events::onFlush, new Event\OnFlushEventArgs($this->_em));
|
||||
}
|
||||
|
||||
// Now we need a commit order to maintain referential integrity
|
||||
$commitOrder = $this->_getCommitOrder();
|
||||
|
||||
@ -945,7 +950,8 @@ class UnitOfWork implements PropertyChangedListener
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a deleted entity.
|
||||
* INTERNAL:
|
||||
* Schedules an entity for deletion.
|
||||
*
|
||||
* @param object $entity
|
||||
*/
|
||||
@ -2064,4 +2070,34 @@ class UnitOfWork implements PropertyChangedListener
|
||||
$this->_entityUpdates[$oid] = $entity;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the currently scheduled entity insertions in this UnitOfWork.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getScheduledEntityInsertions()
|
||||
{
|
||||
return $this->_entityInsertions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the currently scheduled entity updates in this UnitOfWork.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getScheduledEntityUpdates()
|
||||
{
|
||||
return $this->_entityUpdates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the currently scheduled entity deletions in this UnitOfWork.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getScheduledEntityDeletions()
|
||||
{
|
||||
return $this->_entityDeletions;
|
||||
}
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ DOCBLOCK;
|
||||
*/
|
||||
public function testAnnotationNamespaceAlias()
|
||||
{
|
||||
$parser = new Parser;
|
||||
$parser = $this->createTestParser();
|
||||
$parser->setAnnotationNamespaceAlias('Doctrine\Tests\Common\Annotations\\', 'alias');
|
||||
$docblock = <<<DOCBLOCK
|
||||
/**
|
||||
|
94
tests/Doctrine/Tests/ORM/Functional/FlushEventTest.php
Normal file
94
tests/Doctrine/Tests/ORM/Functional/FlushEventTest.php
Normal file
@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional;
|
||||
|
||||
use Doctrine\Tests\Models\CMS\CmsUser;
|
||||
use Doctrine\Tests\Models\CMS\CmsPhonenumber;
|
||||
use Doctrine\ORM\Event\OnFlushEventArgs;
|
||||
use Doctrine\ORM\Events;
|
||||
|
||||
require_once __DIR__ . '/../../TestInit.php';
|
||||
|
||||
/**
|
||||
* FlushEventTest
|
||||
*
|
||||
* @author robo
|
||||
*/
|
||||
class FlushEventTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp() {
|
||||
$this->useModelSet('cms');
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
public function testPersistNewEntitiesOnPreFlush()
|
||||
{
|
||||
//$this->_em->getConnection()->getConfiguration()->setSqlLogger(new \Doctrine\DBAL\Logging\EchoSqlLogger);
|
||||
$this->_em->getEventManager()->addEventListener(Events::onFlush, new OnFlushListener);
|
||||
|
||||
$user = new CmsUser;
|
||||
$user->username = 'romanb';
|
||||
$user->name = 'Roman';
|
||||
$user->status = 'Dev';
|
||||
|
||||
$this->_em->persist($user);
|
||||
|
||||
$this->assertEquals(0, $user->phonenumbers->count());
|
||||
|
||||
$this->_em->flush();
|
||||
|
||||
$this->assertEquals(1, $user->phonenumbers->count());
|
||||
$this->assertTrue($this->_em->contains($user->phonenumbers->get(0)));
|
||||
$this->assertTrue($user->phonenumbers->get(0)->getUser() === $user);
|
||||
|
||||
$this->assertFalse($user->phonenumbers->isDirty());
|
||||
|
||||
// Can be used together with SQL Logging to check that a subsequent flush has
|
||||
// nothing to do. This proofs the correctness of the changes that happened in onFlush.
|
||||
//echo "SECOND FLUSH";
|
||||
//$this->_em->flush();
|
||||
}
|
||||
}
|
||||
|
||||
class OnFlushListener
|
||||
{
|
||||
public function onFlush(OnFlushEventArgs $args)
|
||||
{
|
||||
//echo "---preFlush".PHP_EOL;
|
||||
|
||||
$em = $args->getEntityManager();
|
||||
$uow = $em->getUnitOfWork();
|
||||
|
||||
foreach ($uow->getScheduledEntityInsertions() as $entity) {
|
||||
|
||||
if ($entity instanceof CmsUser) {
|
||||
// Adds a phonenumber to every newly persisted CmsUser ...
|
||||
|
||||
$phone = new CmsPhonenumber;
|
||||
$phone->phonenumber = 12345;
|
||||
// Update object model
|
||||
$entity->addPhonenumber($phone);
|
||||
// Invoke regular persist call
|
||||
$em->persist($phone);
|
||||
// Explicitly calculate the changeset since onFlush is raised
|
||||
// after changeset calculation!
|
||||
$uow->computeChangeSet($em->getClassMetadata(get_class($phone)), $phone);
|
||||
|
||||
// Take a snapshot because the UoW wont do this for us, because
|
||||
// the UoW did not visit this collection.
|
||||
// Alternatively we could provide an ->addVisitedCollection() method
|
||||
// on the UoW.
|
||||
$entity->getPhonenumbers()->takeSnapshot();
|
||||
}
|
||||
|
||||
/*foreach ($uow->getEntityChangeSet($entity) as $field => $change) {
|
||||
list ($old, $new) = $change;
|
||||
|
||||
var_dump($old);
|
||||
}*/
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user