Skip to content

Commit

Permalink
Merge pull request #811 from Inventis/jan/fix-children-getting-remove…
Browse files Browse the repository at this point in the history
…d-on-move-when-pre-update-listener-is-present

fix children getting removed on move when pre update listener is present
  • Loading branch information
dbu authored Jan 28, 2020
2 parents cf64c5e + bbba2aa commit 15fcb43
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 2 deletions.
10 changes: 8 additions & 2 deletions lib/Doctrine/ODM/PHPCR/UnitOfWork.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
use PHPCR\Util\NodeHelper;
use PHPCR\Util\PathHelper;
use PHPCR\Util\UUIDHelper;
use function spl_object_hash;

/**
* Unit of work class
Expand Down Expand Up @@ -1437,8 +1438,13 @@ private function computeChildrenChanges($document, $class, $oid, $isNew, $change
// check moved children to not accidentally remove a child that simply moved away.
if (!(in_array($childName, $childNames) || in_array($childName, $movedChildNames))) {
$child = $this->getDocumentById($id.'/'.$childName);
$this->scheduleRemove($child);
unset($originalNames[$key]);
// make sure that when the child move is already processed and another compute is triggered
// we don't remove that child
$childOid = spl_object_hash($child);
if (!isset($this->scheduledMoves[$childOid])) {
$this->scheduleRemove($child);
unset($originalNames[$key]);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace Doctrine\Tests\Models\References;

use Doctrine\ODM\PHPCR\Mapping\Annotations as PHPCRODM;

/**
* @PHPCRODM\Document(referenceable=true)
*/
class ParentWithChildrenTestObj
{
/** @PHPCRODM\Id(strategy="parent") */
public $id;
/** @PHPCRODM\ParentDocument */
public $parent;
/** @PHPCRODM\Nodename */
public $nodename;
/** @PHPCRODM\Field(type="string") */
public $name;
/** @PHPCRODM\Children() */
public $children;

public function getParentDocument()
{
return $this->parent;
}

public function setParentDocument($parent)
{
$this->parent = $parent;
}
}
56 changes: 56 additions & 0 deletions tests/Doctrine/Tests/ODM/PHPCR/Functional/UnitOfWorkTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
namespace Doctrine\Tests\ODM\PHPCR\Functional;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\EventSubscriber;
use Doctrine\ODM\PHPCR\DocumentManager;
use Doctrine\ODM\PHPCR\Event;
use Doctrine\ODM\PHPCR\Exception\OutOfBoundsException;
use Doctrine\ODM\PHPCR\UnitOfWork;
use Doctrine\Tests\Models\CMS\CmsAddress;
Expand All @@ -16,6 +18,7 @@
use Doctrine\Tests\Models\CMS\CmsUser;
use Doctrine\Tests\Models\References\ParentNoNodeNameTestObj;
use Doctrine\Tests\Models\References\ParentTestObj;
use Doctrine\Tests\Models\References\ParentWithChildrenTestObj;
use Doctrine\Tests\Models\Translation\Comment;
use Doctrine\Tests\ODM\PHPCR\PHPCRFunctionalTestCase;

Expand Down Expand Up @@ -124,6 +127,59 @@ public function testMoveParentNoNodeName()
}
}

public function testMoveChildThroughNodeNameChangeWithPreUpdateListener()
{
// preparing
$functional = $this->dm->find(null, 'functional');
$root = new ParentWithChildrenTestObj();
$root->nodename = 'root';
$root->name = 'root';
$root->setParentDocument($functional);
$this->dm->persist($root);

$parent = new ParentWithChildrenTestObj();
$parent->nodename = 'parent';
$parent->name = 'parent';
$parent->setParentDocument($root);
$this->dm->persist($parent);

$child = new ParentTestObj();
$child->setParentDocument($parent);
$child->nodename = $child->name = 'child';
$this->dm->persist($child);

$child2 = new ParentTestObj();
$child2->setParentDocument($parent);
$child2->nodename = $child2->name = 'child2';
$this->dm->persist($child2);

$this->dm->flush();
$this->dm->clear();

$parent = $this->dm->find(null, '/functional/root/parent');
$parent->children->toArray(); // force container init
$child2 = $this->dm->find(null, '/functional/root/parent/child2');

// testing
$this->dm->getEventManager()->addEventSubscriber(new class() implements EventSubscriber {
public function getSubscribedEvents()
{
return [Event::preUpdate];
}

public function preUpdate()
{
}
});
$child2->nodename = 'moved-child2';
$this->dm->persist($child2);

$this->dm->flush();

$movedChild = $this->dm->find(null, '/functional/root/parent/moved-child2');
$this->assertInstanceOf(ParentTestObj::class, $movedChild);
}

public function testGetScheduledReorders()
{
// TODO: do some real test
Expand Down

0 comments on commit 15fcb43

Please sign in to comment.