Skip to content

Commit

Permalink
Fix serialisation of uninitialised PersistentCollection instances
Browse files Browse the repository at this point in the history
  • Loading branch information
alcaeus committed Jan 16, 2019
1 parent 181edb9 commit 533db68
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -566,15 +566,15 @@ public function slice($offset, $length = null)
}

/**
* Called by PHP when this collection is serialized. Ensures that only the
* elements are properly serialized.
* Called by PHP when this collection is serialized. Ensures that the
* internal state of the collection can be reproduced after serialization
*
* @internal Tried to implement Serializable first but that did not work well
* with circular references. This solution seems simpler and works well.
*/
public function __sleep()
{
return ['coll', 'initialized'];
return ['coll', 'initialized', 'mongoData', 'snapshot', 'isDirty', 'hints'];
}

/* ArrayAccess implementation */
Expand Down
49 changes: 49 additions & 0 deletions tests/Doctrine/ODM/MongoDB/Tests/PersistentCollectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Doctrine\ODM\MongoDB\PersistentCollection;
use Doctrine\ODM\MongoDB\UnitOfWork;
use Documents\User;
use MongoDB\BSON\ObjectId;
use stdClass;
use function serialize;
use function unserialize;
Expand Down Expand Up @@ -78,6 +79,54 @@ public function testGetTypeClassWorksAfterUnserialization()
$this->assertInstanceOf(ClassMetadata::class, $unserialized->getTypeClass());
}

public function testMongoDataIsPreservedDuringSerialization()
{
$mongoData = [
[
'$ref' => 'group',
'$id' => new ObjectId(),
],
[
'$ref' => 'group',
'$id' => new ObjectId(),
],
];

$collection = new PersistentCollection(new ArrayCollection(), $this->dm, $this->uow);
$collection->setMongoData($mongoData);

$serialized = serialize($collection);
/** @var PersistentCollection $unserialized */
$unserialized = unserialize($serialized);

$unserialized->setOwner(new User(), $this->dm->getClassMetadata(User::class)->getFieldMapping('groups'));
$unserialized->setDocumentManager($this->dm);

$this->assertCount(2, $unserialized->getMongoData());
}

public function testSnapshotIsPreservedDuringSerialization()
{
$collection = new PersistentCollection(new ArrayCollection(), $this->dm, $this->uow);
$collection->add(new stdClass());
$collection->takeSnapshot();

$this->assertCount(1, $collection->getSnapshot());
$this->assertFalse($collection->isDirty());
$this->assertCount(1, $collection->unwrap());

$serialized = serialize($collection);
/** @var PersistentCollection $unserialized */
$unserialized = unserialize($serialized);

$unserialized->setOwner(new User(), $this->dm->getClassMetadata(User::class)->getFieldMapping('groups'));
$unserialized->setDocumentManager($this->dm);

$this->assertCount(1, $unserialized->getSnapshot());
$this->assertFalse($unserialized->isDirty());
$this->assertCount(1, $unserialized->unwrap());
}

/**
* @param array $expected
* @param array $snapshot
Expand Down

0 comments on commit 533db68

Please sign in to comment.