Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Added new Events: preMove and postMove #246

Merged
merged 9 commits into from Feb 23, 2013
@@ -26,9 +26,11 @@
const prePersist = 'prePersist';
const preRemove = 'preRemove';
const preUpdate = 'preUpdate';
+ const preMove = 'preMove';
const postRemove = 'postRemove';
const postPersist = 'postPersist';
const postUpdate = 'postUpdate';
+ const postMove = 'postMove';
const postLoad = 'postLoad';
const postFlush = 'postFlush';
const preFlush = 'preFlush';
@@ -0,0 +1,103 @@
+<?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\ODM\PHPCR\Event;
+
+/**
+ * MoveEventArgs
+ */
+class MoveEventArgs extends \Doctrine\Common\EventArgs
+{
+ /**
+ * @var object
+ */
+ private $document;
+
+ /**
+ * @var \Doctrine\ODM\PHPCR\DocumentManager
+ */
+ private $dm;
+
+ /**
+ * @var string
+ */
+ private $sourcePath;
+
+ /**
+ * @var string
+ */
+ private $targetPath;
+
+ /**
+ * Constructor
+ *
+ * @param object $document The object
+ * @param \Doctrine\ODM\PHPCR\DocumentManager $dm The document manager
+ * @param string $sourcePath The source path
+ * @param string $targetPath The target path
+ */
+ public function __construct($document, $dm, $sourcePath, $targetPath)
+ {
+ $this->document = $document;
+ $this->dm = $dm;
+ $this->sourcePath = $sourcePath;
+ $this->targetPath = $targetPath;
+ }
+
+ /**
+ * Get the document
+ *
+ * @return object
+ */
+ public function getDocument()
+ {
+ return $this->document;
+ }
+
+ /**
+ * Get the document manager
+ *
+ * @return \Doctrine\ODM\PHPCR\DocumentManager
+ */
+ public function getDocumentManager()
+ {
+ return $this->dm;
+ }
+
+ /**
+ * Get the source path
+ *
+ * @return string
+ */
+ public function getSourcePath()
+ {
+ return $this->sourcePath;
+ }
+
+ /**
+ * Get the target path
+ *
+ * @return string
+ */
+ public function getTargetPath()
+ {
+ return $this->targetPath;
+ }
+}
@@ -30,6 +30,7 @@
use Doctrine\ODM\PHPCR\Event\PreFlushEventArgs;
use Doctrine\ODM\PHPCR\Event\PostFlushEventArgs;
use Doctrine\ODM\PHPCR\Event\OnClearEventArgs;
+use Doctrine\ODM\PHPCR\Event\MoveEventArgs;
use Doctrine\ODM\PHPCR\Proxy\Proxy;
use Jackalope\Session as JackalopeSession;
@@ -640,6 +641,7 @@ public function scheduleMove($document, $targetPath)
$oid = spl_object_hash($document);
$state = $this->getDocumentState($document);
+
switch ($state) {
case self::STATE_NEW:
unset($this->scheduledInserts[$oid]);
@@ -1947,12 +1949,20 @@ private function executeMoves($documents)
list($document, $targetPath) = $value;
- $path = $this->getDocumentId($document);
- if ($path === $targetPath) {
+ $sourcePath = $this->getDocumentId($document);
+ if ($sourcePath === $targetPath) {
continue;
}
- $this->session->move($path, $targetPath);
+ if (isset($class->lifecycleCallbacks[Event::preMove])) {
+ $class->invokeLifecycleCallbacks(Event::preMove, $document);
+ }
+
+ if ($this->evm->hasListeners(Event::preMove)) {
+ $this->evm->dispatchEvent(Event::preMove, new MoveEventArgs($document, $this->dm, $sourcePath, $targetPath));
+ }
+
+ $this->session->move($sourcePath, $targetPath);
// update fields nodename and parentMapping if they exist in this type
$class = $this->dm->getClassMetadata(get_class($document));
@@ -1966,11 +1976,11 @@ private function executeMoves($documents)
// update all cached children of the document to reflect the move (path id changes)
foreach ($this->documentIds as $oid => $id) {
- if (0 !== strpos($id, $path)) {
+ if (0 !== strpos($id, $sourcePath)) {
continue;
}
- $newId = $targetPath.substr($id, strlen($path));
+ $newId = $targetPath.substr($id, strlen($sourcePath));
$this->documentIds[$oid] = $newId;
$document = $this->getDocumentById($id);
@@ -1991,6 +2001,14 @@ private function executeMoves($documents)
}
}
}
+
+ if (isset($class->lifecycleCallbacks[Event::postMove])) {
+ $class->invokeLifecycleCallbacks(Event::postMove, $document);
+ }
+
+ if ($this->evm->hasListeners(Event::postMove)) {
+ $this->evm->dispatchEvent(Event::postMove, new MoveEventArgs($document, $this->dm, $sourcePath, $targetPath));
+ }
}
}
@@ -21,7 +21,7 @@ public function setUp()
$this->listener = new TestEventDocumentChanger();
$this->dm = $this->createDocumentManager();
$this->node = $this->resetFunctionalNode($this->dm);
- $this->dm->getEventManager()->addEventListener(array('prePersist', 'postPersist', 'preUpdate', 'postUpdate'), $this->listener);
+ $this->dm->getEventManager()->addEventListener(array('prePersist', 'postPersist', 'preUpdate', 'postUpdate', 'preMove', 'postMove'), $this->listener);
}
public function testComputingBetweenEvents()
@@ -60,6 +60,20 @@ public function testComputingBetweenEvents()
$user = $this->dm->find('Doctrine\Tests\Models\CMS\CmsUser', $user->id);
$this->assertTrue($user->name=='preupdate');
+ // Move test, Before move the path is /functional/preudpate and I move to /preupdate
+ $targetPath = '/' . $user->name;
+ $this->dm->move($user, $targetPath);
+ $this->dm->flush();
+ $this->dm->clear();
+
+ $this->assertTrue($user->username == 'premove-postmove');
+
+ $user = $this->dm->find('Doctrine\Tests\Models\CMS\CmsUser', $targetPath);
+
+ // The document is moved and do not be modified
+ $this->assertTrue($user->name == 'preupdate');
+ $this->assertTrue($this->listener->preMove);
+
// Clean up
$this->dm->remove($user);
$this->dm->flush();
@@ -74,6 +88,8 @@ class TestEventDocumentChanger
public $postUpdate = false;
public $preRemove = false;
public $postRemove = false;
+ public $preMove = false;
+ public $postMove = false;
public $onFlush = false;
public function prePersist(EventArgs $e)
@@ -100,4 +116,17 @@ public function postUpdate(EventArgs $e)
$document->username = 'postupdate';
}
+ public function preMove(EventArgs $e)
+ {
+ $this->preMove = true;
+ $document = $e->getDocument();
+ $document->name = 'premove'; // I try to update the name of the document but after move, the document should never be modified
@dbu

dbu Feb 22, 2013

Member

you could set username to 'premove' and in postmove do $document->username .= '-postmove' and check if username became premove-postmove. that would check the proper order of events.

+ $document->username = 'premove';
+ }
+
+ public function postMove(EventArgs $e)
+ {
+ $document = $e->getDocument();
+ $document->username .= '-postmove';
+ }
}
@@ -28,8 +28,9 @@ public function setUp()
$this->dm = $this->createDocumentManager();
$this->node = $this->resetFunctionalNode($this->dm);
$this->dm->getEventManager()->addEventListener(array(
- 'prePersist', 'postPersist', 'preUpdate', 'postUpdate',
- 'preRemove', 'postRemove', 'onFlush', 'postFlush', 'preFlush'
+ 'prePersist', 'postPersist', 'preUpdate', 'postUpdate',
+ 'preRemove', 'postRemove', 'onFlush', 'postFlush', 'preFlush',
+ 'preMove', 'postMove'
), $this->listener);
}
@@ -59,7 +60,13 @@ public function testTriggerEvents()
$this->assertFalse($this->listener->pagePostRemove);
$this->assertFalse($this->listener->itemPreRemove);
$this->assertFalse($this->listener->itemPostRemove);
-
+
+ $this->dm->move($page, '/' . $page->title);
+ $this->dm->flush();
+
+ $this->assertTrue($this->listener->preMove);
+ $this->assertTrue($this->listener->postMove);
+
$item = new CmsItem();
$item->name = "my-item";
$item->documentTarget = $page;
@@ -108,7 +115,9 @@ class TestPersistenceListener
public $onFlush = false;
public $postFlush = false;
public $preFlush = false;
-
+ public $preMove = false;
+ public $postMove = false;
+
public function prePersist(EventArgs $e)
{
$document = $e->getDocument();
@@ -168,6 +177,16 @@ public function postRemove(EventArgs $e)
}
}
+ public function preMove(EventArgs $e)
+ {
+ $this->preMove = true;
+ }
+
+ public function postMove(EventArgs $e)
+ {
+ $this->postMove = true;
+ }
+
public function onFlush(EventArgs $e)
{
$this->onFlush = true;