Skip to content
New issue

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

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DDC-3382] Allow orphan removal to be cancelled #1419

Merged
merged 1 commit into from
Jun 16, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions lib/Doctrine/ORM/PersistentCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,10 @@ public function set($key, $value)
parent::set($key, $value);

$this->changed();

if ($this->em) {
$this->em->getUnitOfWork()->cancelOrphanRemoval($value);
}
}

/**
Expand All @@ -481,6 +485,10 @@ public function add($value)

$this->changed();

if ($this->em) {
$this->em->getUnitOfWork()->cancelOrphanRemoval($value);
}

return true;
}

Expand Down
15 changes: 15 additions & 0 deletions lib/Doctrine/ORM/UnitOfWork.php
Original file line number Diff line number Diff line change
Expand Up @@ -2430,6 +2430,21 @@ public function scheduleOrphanRemoval($entity)
$this->orphanRemovals[spl_object_hash($entity)] = $entity;
}

/**
* INTERNAL:
* Cancels a previously scheduled orphan removal.
*
* @ignore
*
* @param object $entity
*
* @return void
*/
public function cancelOrphanRemoval($entity)
{
unset($this->orphanRemovals[spl_object_hash($entity)]);
}

/**
* INTERNAL:
* Schedules a complete collection for removal when this UnitOfWork commits.
Expand Down
48 changes: 45 additions & 3 deletions tests/Doctrine/Tests/ORM/Functional/OneToManyOrphanRemovalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,14 @@ protected function setUp()
$user->username = 'romanb';
$user->name = 'Roman B.';

$phone = new CmsPhonenumber;
$phone->phonenumber = '123456';
$phone1 = new CmsPhonenumber;
$phone1->phonenumber = '123456';

$user->addPhonenumber($phone);
$phone2 = new CmsPhonenumber;
$phone2->phonenumber = '234567';

$user->addPhonenumber($phone1);
$user->addPhonenumber($phone2);

$this->_em->persist($user);
$this->_em->flush();
Expand Down Expand Up @@ -55,6 +59,44 @@ public function testOrphanRemoval()
$this->assertEquals(0, count($result), 'CmsPhonenumber should be removed by orphanRemoval');
}

/**
* @group DDC-3382
*/
public function testOrphanRemovalRemoveFromCollection()
{
$user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);

$phonenumber = $user->getPhonenumbers()->remove(0);

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

$query = $this->_em->createQuery('SELECT p FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p');
$result = $query->getResult();

$this->assertEquals(1, count($result), 'CmsPhonenumber should be removed by orphanRemoval');
}

/**
* @group DDC-3382
*/
public function testOrphanRemovalClearCollectionAndReAdd()
{
$user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);

$phone1 = $user->getPhonenumbers()->first();

$user->getPhonenumbers()->clear();
$user->addPhonenumber($phone1);

$this->_em->flush();

$query = $this->_em->createQuery('SELECT p FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p');
$result = $query->getResult();

$this->assertEquals(1, count($result), 'CmsPhonenumber should be removed by orphanRemoval');
}

/**
* @group DDC-1496
*/
Expand Down
54 changes: 54 additions & 0 deletions tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1654Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ public function setUp()
));
}

public function tearDown()
{
$conn = static::$_sharedConn;
$conn->executeUpdate('DELETE FROM ddc1654post_ddc1654comment');
$conn->executeUpdate('DELETE FROM DDC1654Comment');
$conn->executeUpdate('DELETE FROM DDC1654Post');
}

public function testManyToManyRemoveFromCollectionOrphanRemoval()
{
$post = new DDC1654Post();
Expand Down Expand Up @@ -54,6 +62,29 @@ public function testManyToManyRemoveElementFromCollectionOrphanRemoval()
$this->assertEquals(0, count($comments));
}

/**
* @group DDC-3382
*/
public function testManyToManyRemoveElementFromReAddToCollectionOrphanRemoval()
{
$post = new DDC1654Post();
$post->comments[] = new DDC1654Comment();
$post->comments[] = new DDC1654Comment();

$this->_em->persist($post);
$this->_em->flush();

$comment = $post->comments[0];
$post->comments->removeElement($comment);
$post->comments->add($comment);

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

$comments = $this->_em->getRepository(__NAMESPACE__ . '\\DDC1654Comment')->findAll();
$this->assertEquals(2, count($comments));
}

public function testManyToManyClearCollectionOrphanRemoval()
{
$post = new DDC1654Post();
Expand All @@ -72,6 +103,29 @@ public function testManyToManyClearCollectionOrphanRemoval()
$this->assertEquals(0, count($comments));

}

/**
* @group DDC-3382
*/
public function testManyToManyClearCollectionReAddOrphanRemoval()
{
$post = new DDC1654Post();
$post->comments[] = new DDC1654Comment();
$post->comments[] = new DDC1654Comment();

$this->_em->persist($post);
$this->_em->flush();

$comment = $post->comments[0];
$post->comments->clear();
$post->comments->add($comment);

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

$comments = $this->_em->getRepository(__NAMESPACE__ . '\\DDC1654Comment')->findAll();
$this->assertEquals(1, count($comments));
}
}

/**
Expand Down