Skip to content

Commit 0534ed0

Browse files
committed
Merge pull request #560
2 parents 1d4376c + d06c288 commit 0534ed0

File tree

4 files changed

+82
-0
lines changed

4 files changed

+82
-0
lines changed

src/functions.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
use MongoDB\Driver\WriteConcern;
2424
use MongoDB\Exception\InvalidArgumentException;
2525
use stdClass;
26+
use ReflectionClass;
2627

2728
/**
2829
* Applies a type map to a document.
@@ -216,5 +217,9 @@ function recursive_copy($element) {
216217
return $element;
217218
}
218219

220+
if ( ! (new ReflectionClass($element))->isCloneable()) {
221+
return $element;
222+
}
223+
219224
return clone $element;
220225
}

tests/Model/BSONArrayTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22

33
namespace MongoDB\Tests\Model;
44

5+
use MongoDB\BSON\ObjectId;
56
use MongoDB\Model\BSONArray;
67
use MongoDB\Model\BSONDocument;
78
use MongoDB\Tests\TestCase;
89
use stdClass;
10+
use ReflectionClass;
911

1012
class BSONArrayTest extends TestCase
1113
{
@@ -43,6 +45,36 @@ public function testClone()
4345
$this->assertNotSame($array[1][2][1], $arrayClone[1][2][1]);
4446
}
4547

48+
public function testCloneRespectsUncloneableObjects()
49+
{
50+
$this->assertFalse((new ReflectionClass(UncloneableObject::class))->isCloneable());
51+
52+
$array = new BSONArray([
53+
[new UncloneableObject],
54+
new BSONArray([new UncloneableObject]),
55+
]);
56+
$arrayClone = clone $array;
57+
58+
$this->assertNotSame($array, $arrayClone);
59+
$this->assertSame($array[0][0], $arrayClone[0][0]);
60+
$this->assertNotSame($array[1], $arrayClone[1]);
61+
$this->assertSame($array[1][0], $arrayClone[1][0]);
62+
}
63+
64+
public function testCloneSupportsBSONTypes()
65+
{
66+
/* Note: this test does not check that the BSON type itself is cloned,
67+
* as that is not yet supported in the driver (see: PHPC-1230). */
68+
$array = new BSONArray([
69+
[new ObjectId],
70+
new BSONArray([new ObjectId]),
71+
]);
72+
$arrayClone = clone $array;
73+
74+
$this->assertNotSame($array, $arrayClone);
75+
$this->assertNotSame($array[1], $arrayClone[1]);
76+
}
77+
4678
public function testJsonSerialize()
4779
{
4880
$document = new BSONArray([

tests/Model/BSONDocumentTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22

33
namespace MongoDB\Tests\Model;
44

5+
use MongoDB\BSON\ObjectId;
56
use MongoDB\Model\BSONArray;
67
use MongoDB\Model\BSONDocument;
78
use MongoDB\Tests\TestCase;
89
use ArrayObject;
910
use stdClass;
11+
use ReflectionClass;
1012

1113
class BSONDocumentTest extends TestCase
1214
{
@@ -51,6 +53,36 @@ public function testClone()
5153
$this->assertNotSame($document['b']['c'][1], $documentClone['b']['c'][1]);
5254
}
5355

56+
public function testCloneRespectsUncloneableObjects()
57+
{
58+
$this->assertFalse((new ReflectionClass(UncloneableObject::class))->isCloneable());
59+
60+
$document = new BSONDocument([
61+
'a' => ['a' => new UncloneableObject],
62+
'b' => new BSONDocument(['a' => new UncloneableObject]),
63+
]);
64+
$documentClone = clone $document;
65+
66+
$this->assertNotSame($document, $documentClone);
67+
$this->assertSame($document['a']['a'], $documentClone['a']['a']);
68+
$this->assertNotSame($document['b'], $documentClone['b']);
69+
$this->assertSame($document['b']['a'], $documentClone['b']['a']);
70+
}
71+
72+
public function testCloneSupportsBSONTypes()
73+
{
74+
/* Note: this test does not check that the BSON type itself is cloned,
75+
* as that is not yet supported in the driver (see: PHPC-1230). */
76+
$document = new BSONDocument([
77+
'a' => ['a' => new ObjectId],
78+
'b' => new BSONDocument(['a' => new ObjectId]),
79+
]);
80+
$documentClone = clone $document;
81+
82+
$this->assertNotSame($document, $documentClone);
83+
$this->assertNotSame($document['b'], $documentClone['b']);
84+
}
85+
5486
public function testJsonSerialize()
5587
{
5688
$document = new BSONDocument([

tests/Model/UncloneableObject.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace MongoDB\Tests\Model;
4+
5+
/**
6+
* This class is used by the BSONArray and BSONDocument clone tests.
7+
*/
8+
class UncloneableObject
9+
{
10+
private function __clone()
11+
{
12+
}
13+
}

0 commit comments

Comments
 (0)