Skip to content

Commit 8d0fe0e

Browse files
committed
PHPLIB-1489: Handle CursorId deprecations
1 parent 801f4d2 commit 8d0fe0e

File tree

3 files changed

+114
-5
lines changed

3 files changed

+114
-5
lines changed

src/ChangeStream.php

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
use Iterator;
2121
use MongoDB\BSON\Document;
22+
use MongoDB\BSON\Int64;
2223
use MongoDB\Codec\DocumentCodec;
2324
use MongoDB\Driver\CursorId;
2425
use MongoDB\Driver\Exception\ConnectionException;
@@ -32,6 +33,10 @@
3233
use function assert;
3334
use function call_user_func;
3435
use function in_array;
36+
use function sprintf;
37+
use function trigger_error;
38+
39+
use const E_USER_DEPRECATED;
3540

3641
/**
3742
* Iterator for a change stream.
@@ -105,10 +110,23 @@ public function current()
105110
return $this->codec->decode($value);
106111
}
107112

108-
/** @return CursorId */
109-
public function getCursorId()
113+
/** @return CursorId|Int64 */
114+
#[ReturnTypeWillChange]
115+
public function getCursorId(bool $asInt64 = false)
110116
{
111-
return $this->iterator->getInnerIterator()->getId();
117+
if (! $asInt64) {
118+
@trigger_error(
119+
sprintf(
120+
'The method "%s" will no longer return a "%s" instance in the future. Pass "true" as argument to change to the new behavior and receive a "%s" instance instead.',
121+
__METHOD__,
122+
CursorId::class,
123+
Int64::class,
124+
),
125+
E_USER_DEPRECATED,
126+
);
127+
}
128+
129+
return $this->iterator->getInnerIterator()->getId($asInt64);
112130
}
113131

114132
/**

src/Model/CodecCursor.php

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,20 @@
1919

2020
use Iterator;
2121
use MongoDB\BSON\Document;
22+
use MongoDB\BSON\Int64;
2223
use MongoDB\Codec\DocumentCodec;
2324
use MongoDB\Driver\Cursor;
2425
use MongoDB\Driver\CursorId;
2526
use MongoDB\Driver\CursorInterface;
2627
use MongoDB\Driver\Server;
28+
use ReturnTypeWillChange;
2729

2830
use function assert;
2931
use function iterator_to_array;
3032
use function sprintf;
3133
use function trigger_error;
3234

35+
use const E_USER_DEPRECATED;
3336
use const E_USER_WARNING;
3437

3538
/**
@@ -73,9 +76,23 @@ public static function fromCursor(Cursor $cursor, DocumentCodec $codec): self
7376
return new self($cursor, $codec);
7477
}
7578

76-
public function getId(): CursorId
79+
/** @return CursorId|Int64 */
80+
#[ReturnTypeWillChange]
81+
public function getId(bool $asInt64 = false)
7782
{
78-
return $this->cursor->getId();
83+
if (! $asInt64) {
84+
@trigger_error(
85+
sprintf(
86+
'The method "%s" will no longer return a "%s" instance in the future. Pass "true" as argument to change to the new behavior and receive a "%s" instance instead.',
87+
__METHOD__,
88+
CursorId::class,
89+
Int64::class,
90+
),
91+
E_USER_DEPRECATED,
92+
);
93+
}
94+
95+
return $this->cursor->getId($asInt64);
7996
}
8097

8198
public function getServer(): Server

tests/Model/CodecCursorFunctionalTest.php

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

33
namespace MongoDB\Tests\Model;
44

5+
use MongoDB\BSON\Int64;
56
use MongoDB\Codec\DocumentCodec;
7+
use MongoDB\Driver\CursorId;
68
use MongoDB\Model\CodecCursor;
79
use MongoDB\Tests\FunctionalTestCase;
810

11+
use function restore_error_handler;
12+
use function set_error_handler;
13+
14+
use const E_DEPRECATED;
15+
use const E_USER_DEPRECATED;
16+
917
class CodecCursorFunctionalTest extends FunctionalTestCase
1018
{
1119
public function setUp(): void
@@ -27,4 +35,70 @@ public function testSetTypeMap(): void
2735

2836
$codecCursor->setTypeMap(['root' => 'array']);
2937
}
38+
39+
public function testGetIdReturnTypeWithoutArgument(): void
40+
{
41+
$collection = self::createTestClient()->selectCollection($this->getDatabaseName(), $this->getCollectionName());
42+
$cursor = $collection->find();
43+
44+
$codecCursor = CodecCursor::fromCursor($cursor, $this->createMock(DocumentCodec::class));
45+
46+
$deprecations = [];
47+
48+
try {
49+
$previousErrorHandler = set_error_handler(
50+
function (...$args) use (&$previousErrorHandler, &$deprecations) {
51+
$deprecations[] = $args;
52+
53+
return true;
54+
},
55+
E_USER_DEPRECATED | E_DEPRECATED,
56+
);
57+
58+
$cursorId = $codecCursor->getId();
59+
} finally {
60+
restore_error_handler();
61+
}
62+
63+
self::assertInstanceOf(CursorId::class, $cursorId);
64+
65+
// Expect 2 deprecations: 1 from CodecCursor, one from Cursor
66+
self::assertCount(2, $deprecations);
67+
self::assertSame(
68+
'The method "MongoDB\Model\CodecCursor::getId" will no longer return a "MongoDB\Driver\CursorId" instance in the future. Pass "true" as argument to change to the new behavior and receive a "MongoDB\BSON\Int64" instance instead.',
69+
$deprecations[0][1],
70+
);
71+
self::assertSame(
72+
'MongoDB\Driver\Cursor::getId(): The method "MongoDB\Driver\Cursor::getId" will no longer return a "MongoDB\Driver\CursorId" instance in the future. Pass "true" as argument to change to the new behavior and receive a "MongoDB\BSON\Int64" instance instead.',
73+
$deprecations[1][1],
74+
);
75+
}
76+
77+
public function testGetIdReturnTypeWithArgument(): void
78+
{
79+
$collection = self::createTestClient()->selectCollection($this->getDatabaseName(), $this->getCollectionName());
80+
$cursor = $collection->find();
81+
82+
$codecCursor = CodecCursor::fromCursor($cursor, $this->createMock(DocumentCodec::class));
83+
84+
$deprecations = [];
85+
86+
try {
87+
$previousErrorHandler = set_error_handler(
88+
function (...$args) use (&$previousErrorHandler, &$deprecations) {
89+
$deprecations[] = $args;
90+
91+
return true;
92+
},
93+
E_USER_DEPRECATED | E_DEPRECATED,
94+
);
95+
96+
$cursorId = $codecCursor->getId(true);
97+
} finally {
98+
restore_error_handler();
99+
}
100+
101+
self::assertInstanceOf(Int64::class, $cursorId);
102+
self::assertCount(0, $deprecations);
103+
}
30104
}

0 commit comments

Comments
 (0)