Skip to content

Commit c394d37

Browse files
authored
PHPC-2443: Deprecate string argument and accept Int64 instances in UTCDateTime constructor (#1643)
* Refactor UTCDateTime initialisation logic * PHPC-2443: Deprecate passing string values to UTCDateTime constructor * PHPC-2443: Accept Int64 instances in UTCDateTime constructor * Use Int64 instances in tests * Use 64-bit value in UTCDateTime tests * Fix missing word in deprecation message * Extract init methods for utcdatetime_t
1 parent 7ba3371 commit c394d37

27 files changed

+120
-114
lines changed

src/BSON/UTCDateTime.c

Lines changed: 44 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,35 @@ static bool php_phongo_utcdatetime_init_from_date(php_phongo_utcdatetime_t* inte
104104
return true;
105105
}
106106

107+
static bool php_phongo_utcdatetime_init_from_object(php_phongo_utcdatetime_t* intern, zend_object* object)
108+
{
109+
if (instanceof_function(object->ce, php_date_get_interface_ce())) {
110+
php_phongo_utcdatetime_init_from_date(intern, php_date_obj_from_obj(object));
111+
112+
return true;
113+
}
114+
115+
if (instanceof_function(object->ce, php_phongo_int64_ce)) {
116+
php_phongo_utcdatetime_init(intern, php_int64_fetch_object(object)->integer);
117+
118+
return true;
119+
}
120+
121+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected instance of %s or %s, %s given", ZSTR_VAL(php_date_get_interface_ce()->name), ZSTR_VAL(php_phongo_int64_ce->name), ZSTR_VAL(object->ce->name));
122+
123+
return false;
124+
}
125+
126+
static bool php_phongo_utcdatetime_init_from_double(php_phongo_utcdatetime_t* intern, double milliseconds)
127+
{
128+
char tmp[24];
129+
int tmp_len;
130+
131+
tmp_len = snprintf(tmp, sizeof(tmp), "%.0f", milliseconds > 0 ? floor(milliseconds) : ceil(milliseconds));
132+
133+
return php_phongo_utcdatetime_init_from_string(intern, tmp, tmp_len);
134+
}
135+
107136
static HashTable* php_phongo_utcdatetime_get_properties_hash(phongo_compat_object_handler_type* object, bool is_temp)
108137
{
109138
php_phongo_utcdatetime_t* intern;
@@ -179,36 +208,27 @@ static PHP_METHOD(MongoDB_BSON_UTCDateTime, __construct)
179208
return;
180209
}
181210

182-
if (Z_TYPE_P(milliseconds) == IS_OBJECT) {
183-
if (instanceof_function(Z_OBJCE_P(milliseconds), php_date_get_interface_ce())) {
184-
php_phongo_utcdatetime_init_from_date(intern, Z_PHPDATE_P(milliseconds));
185-
} else {
186-
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected instance of DateTimeInterface, %s given", ZSTR_VAL(Z_OBJCE_P(milliseconds)->name));
187-
}
188-
return;
189-
}
190-
191-
if (Z_TYPE_P(milliseconds) == IS_LONG) {
192-
php_phongo_utcdatetime_init(intern, Z_LVAL_P(milliseconds));
193-
return;
194-
}
211+
switch (Z_TYPE_P(milliseconds)) {
212+
case IS_OBJECT:
213+
php_phongo_utcdatetime_init_from_object(intern, Z_OBJ_P(milliseconds));
214+
return;
195215

196-
if (Z_TYPE_P(milliseconds) == IS_DOUBLE) {
197-
char tmp[24];
198-
int tmp_len;
216+
case IS_LONG:
217+
php_phongo_utcdatetime_init(intern, Z_LVAL_P(milliseconds));
218+
return;
199219

200-
tmp_len = snprintf(tmp, sizeof(tmp), "%.0f", Z_DVAL_P(milliseconds) > 0 ? floor(Z_DVAL_P(milliseconds)) : ceil(Z_DVAL_P(milliseconds)));
220+
case IS_DOUBLE:
221+
php_phongo_utcdatetime_init_from_double(intern, Z_DVAL_P(milliseconds));
222+
return;
201223

202-
php_phongo_utcdatetime_init_from_string(intern, tmp, tmp_len);
203-
return;
204-
}
224+
case IS_STRING:
225+
php_error_docref(NULL, E_DEPRECATED, "Creating a %s instance with a string is deprecated and will be removed in ext-mongodb 2.0", ZSTR_VAL(php_phongo_utcdatetime_ce->name));
205226

206-
if (Z_TYPE_P(milliseconds) != IS_STRING) {
207-
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected integer or string, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(milliseconds));
208-
return;
227+
php_phongo_utcdatetime_init_from_string(intern, Z_STRVAL_P(milliseconds), Z_STRLEN_P(milliseconds));
228+
return;
209229
}
210230

211-
php_phongo_utcdatetime_init_from_string(intern, Z_STRVAL_P(milliseconds), Z_STRLEN_P(milliseconds));
231+
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected integer or string, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(milliseconds));
212232
}
213233

214234
static PHP_METHOD(MongoDB_BSON_UTCDateTime, __set_state)

src/BSON/UTCDateTime.stub.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
final class UTCDateTime implements UTCDateTimeInterface, \JsonSerializable, Type, \Serializable
1111
{
1212
#if PHP_VERSION_ID >= 80000
13-
final public function __construct(int|string|float|\DateTimeInterface|null $milliseconds = null) {}
13+
final public function __construct(int|string|float|\DateTimeInterface|Int64|null $milliseconds = null) {}
1414
#else
15-
/** @param int|string|float|\DateTimeInterface|null $milliseconds */
15+
/** @param int|string|float|\DateTimeInterface|Int64|null $milliseconds */
1616
final public function __construct($milliseconds = null) {}
1717
#endif
1818

src/BSON/UTCDateTime_arginfo.h

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/bson/bson-fromPHP-003.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ class MyDocument {
1212
}
1313

1414
$tests = array(
15-
array(new MongoDB\BSON\UTCDateTime('1416445411987')),
16-
array('x' => new MongoDB\BSON\UTCDateTime('1416445411987')),
15+
array(new MongoDB\BSON\UTCDateTime(new MongoDB\BSON\Int64('1416445411987'))),
16+
array('x' => new MongoDB\BSON\UTCDateTime(new MongoDB\BSON\Int64('1416445411987'))),
1717
array(new MyDocument),
1818
array('x' => new MyDocument),
1919
);

tests/bson/bson-fromPHP_error-003.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ $tests = array(
1616
new MongoDB\BSON\ObjectId,
1717
new MongoDB\BSON\Regex('regexp', 'i'),
1818
new MongoDB\BSON\Timestamp(1234, 5678),
19-
new MongoDB\BSON\UTCDateTime('1416445411987'),
19+
new MongoDB\BSON\UTCDateTime(new MongoDB\BSON\Int64('1416445411987')),
2020
);
2121

2222
foreach ($tests as $document) {

tests/bson/bson-toPHP-004.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ $tests = [
2929
new MongoDB\BSON\ObjectId('586c18d86118fd6c9012dec1'),
3030
new MongoDB\BSON\Regex('foo'),
3131
new MongoDB\BSON\Timestamp(1234, 5678),
32-
new MongoDB\BSON\UTCDateTime('1483479256924'),
32+
new MongoDB\BSON\UTCDateTime(new MongoDB\BSON\Int64('1483479256924')),
3333
];
3434

3535
foreach ($tests as $value) {

tests/bson/bson-utcdatetime-001.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ require_once __DIR__ . "/../utils/basic.inc";
1111

1212
$manager = create_test_manager();
1313

14-
$utcdatetime = new MongoDB\BSON\UTCDateTime("1416445411987");
14+
$utcdatetime = new MongoDB\BSON\UTCDateTime(new MongoDB\BSON\Int64('1416445411987'));
1515

1616
$bulk = new MongoDB\Driver\BulkWrite();
1717
$bulk->insert(array('_id' => 1, 'x' => $utcdatetime));

tests/bson/bson-utcdatetime-002.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ MongoDB\BSON\UTCDateTime debug handler
33
--FILE--
44
<?php
55

6-
$utcdatetime = new MongoDB\BSON\UTCDateTime('1416445411987');
6+
$utcdatetime = new MongoDB\BSON\UTCDateTime(new MongoDB\BSON\Int64('1416445411987'));
77

88
var_dump($utcdatetime);
99

@@ -13,6 +13,6 @@ var_dump($utcdatetime);
1313
--EXPECTF--
1414
object(MongoDB\BSON\UTCDateTime)#%d (%d) {
1515
["milliseconds"]=>
16-
%rint\(|string\(13\) "|%r1416445411987%r"|\)%r
16+
string(13) "1416445411987"
1717
}
1818
===DONE===

tests/bson/bson-utcdatetime-008.phpt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
MongoDB\BSON\UTCDateTime construction from 64-bit integer as string
3+
--FILE--
4+
<?php
5+
6+
require_once __DIR__ . '/../utils/basic.inc';
7+
8+
$utcdatetime = new MongoDB\BSON\UTCDateTime('1416445411987');
9+
10+
var_dump($utcdatetime);
11+
12+
?>
13+
===DONE===
14+
<?php exit(0); ?>
15+
--EXPECTF--
16+
Deprecated: MongoDB\BSON\UTCDateTime::__construct(): Creating a MongoDB\BSON\UTCDateTime instance with a string is deprecated and will be removed in ext-mongodb 2.0 in %s
17+
object(MongoDB\BSON\UTCDateTime)#%d (%d) {
18+
["milliseconds"]=>
19+
string(13) "1416445411987"
20+
}
21+
===DONE===

tests/bson/bson-utcdatetime-009.phpt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
MongoDB\BSON\UTCDateTime construction from Int64 object
3+
--FILE--
4+
<?php
5+
6+
require_once __DIR__ . '/../utils/basic.inc';
7+
8+
$utcdatetime = new MongoDB\BSON\UTCDateTime(new MongoDB\BSON\Int64('1416445411987'));
9+
10+
var_dump($utcdatetime);
11+
12+
?>
13+
===DONE===
14+
<?php exit(0); ?>
15+
--EXPECTF--
16+
object(MongoDB\BSON\UTCDateTime)#%d (%d) {
17+
["milliseconds"]=>
18+
string(13) "1416445411987"
19+
}
20+
===DONE===

tests/bson/bson-utcdatetime-clone-001.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ MongoDB\BSON\UTCDateTime can be cloned (PHP < 8.2)
88

99
require_once __DIR__ . "/../utils/basic.inc";
1010

11-
$utcdatetime = new MongoDB\BSON\UTCDateTime("1416445411987");
11+
$utcdatetime = new MongoDB\BSON\UTCDateTime(new MongoDB\BSON\Int64('1416445411987'));
1212

1313
$clone = clone $utcdatetime;
1414

tests/bson/bson-utcdatetime-clone-002.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ MongoDB\BSON\UTCDateTime can be cloned (PHP >= 8.2)
88

99
require_once __DIR__ . "/../utils/basic.inc";
1010

11-
$utcdatetime = new MongoDB\BSON\UTCDateTime("1416445411987");
11+
$utcdatetime = new MongoDB\BSON\UTCDateTime(new MongoDB\BSON\Int64('1416445411987'));
1212

1313
$clone = clone $utcdatetime;
1414

tests/bson/bson-utcdatetime-get_properties-001.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ MongoDB\BSON\UTCDateTime get_properties handler (get_object_vars)
33
--FILE--
44
<?php
55

6-
$utcdatetime = new MongoDB\BSON\UTCDateTime('1416445411987');
6+
$utcdatetime = new MongoDB\BSON\UTCDateTime(new MongoDB\BSON\Int64('1416445411987'));
77

88
var_dump(get_object_vars($utcdatetime));
99

tests/bson/bson-utcdatetime-get_properties-002.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ MongoDB\BSON\UTCDateTime get_properties handler (foreach)
33
--FILE--
44
<?php
55

6-
$utcdatetime = new MongoDB\BSON\UTCDateTime('1416445411987');
6+
$utcdatetime = new MongoDB\BSON\UTCDateTime(new MongoDB\BSON\Int64('1416445411987'));
77

88
foreach ($utcdatetime as $key => $value) {
99
var_dump($key);

tests/bson/bson-utcdatetime-int-size-001.phpt

Lines changed: 0 additions & 30 deletions
This file was deleted.

tests/bson/bson-utcdatetime-int-size-002.phpt

Lines changed: 0 additions & 32 deletions
This file was deleted.

tests/bson/bson-utcdatetime-serialization-003.phpt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ MongoDB\BSON\UTCDateTime serialization (__serialize and __unserialize)
44
<?php
55

66
$tests = [
7-
'0',
8-
'-1416445411987',
9-
'1416445411987',
7+
0,
8+
new MongoDB\BSON\Int64('-1416445411987'),
9+
new MongoDB\BSON\Int64('1416445411987'),
1010
];
1111

1212
foreach ($tests as $milliseconds) {

tests/bson/bson-utcdatetime-todatetime-001.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ date.timezone=America/Los_Angeles
55
--FILE--
66
<?php
77

8-
$utcdatetime = new MongoDB\BSON\UTCDateTime("1416445411987");
8+
$utcdatetime = new MongoDB\BSON\UTCDateTime(new MongoDB\BSON\Int64('1416445411987'));
99
$datetime = $utcdatetime->toDateTime();
1010
var_dump(get_class($datetime));
1111
var_dump($datetime->format(DATE_RSS));

tests/bson/bson-utcdatetime-todatetime-002.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ date.timezone=UTC
55
--FILE--
66
<?php
77

8-
$utcdatetime = new MongoDB\BSON\UTCDateTime("1416445411987");
8+
$utcdatetime = new MongoDB\BSON\UTCDateTime(new MongoDB\BSON\Int64('1416445411987'));
99
$datetime = $utcdatetime->toDateTime();
1010
var_dump(get_class($datetime));
1111
echo $datetime->format('U.u'), "\n";

tests/bson/bson-utcdatetime-todatetimeimmutable-001.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ date.timezone=America/Los_Angeles
55
--FILE--
66
<?php
77

8-
$utcdatetime = new MongoDB\BSON\UTCDateTime("1416445411987");
8+
$utcdatetime = new MongoDB\BSON\UTCDateTime(new MongoDB\BSON\Int64('1416445411987'));
99
$datetime = $utcdatetime->toDateTimeImmutable();
1010
var_dump(get_class($datetime));
1111
var_dump($datetime->format(DATE_RSS));

tests/bson/bson-utcdatetime-todatetimeimmutable-002.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ date.timezone=UTC
55
--FILE--
66
<?php
77

8-
$utcdatetime = new MongoDB\BSON\UTCDateTime("1416445411987");
8+
$utcdatetime = new MongoDB\BSON\UTCDateTime(new MongoDB\BSON\Int64('1416445411987'));
99
$datetime = $utcdatetime->toDateTimeImmutable();
1010
var_dump(get_class($datetime));
1111
echo $datetime->format('U.u'), "\n";

tests/bson/bson-utcdatetime-tostring-001.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ MongoDB\BSON\UTCDateTime::__toString()
33
--FILE--
44
<?php
55

6-
$utcdatetime = new MongoDB\BSON\UTCDateTime("1416445411987");
6+
$utcdatetime = new MongoDB\BSON\UTCDateTime(new MongoDB\BSON\Int64('1416445411987'));
77
var_dump((string) $utcdatetime);
88

99
?>

tests/bson/bson-utcdatetime_error-001.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@ echo throws(function() {
1414
<?php exit(0); ?>
1515
--EXPECT--
1616
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
17-
Expected instance of DateTimeInterface, stdClass given
17+
Expected instance of DateTimeInterface or MongoDB\BSON\Int64, stdClass given
1818
===DONE===

tests/bson/bson-utcdatetime_error-003.phpt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,20 @@ echo throws(function() {
2626
?>
2727
===DONE===
2828
<?php exit(0); ?>
29-
--EXPECT--
29+
--EXPECTF--
30+
Deprecated: MongoDB\BSON\UTCDateTime::__construct(): Creating a MongoDB\BSON\UTCDateTime instance with a string is deprecated and will be removed in ext-mongodb 2.0 in %s
3031
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
3132
Error parsing "1234.5678" as 64-bit integer for MongoDB\BSON\UTCDateTime initialization
33+
34+
Deprecated: MongoDB\BSON\UTCDateTime::__construct(): Creating a MongoDB\BSON\UTCDateTime instance with a string is deprecated and will be removed in ext-mongodb 2.0 in %s
3235
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
3336
Error parsing "9223372036854775808" as 64-bit integer for MongoDB\BSON\UTCDateTime initialization
37+
38+
Deprecated: MongoDB\BSON\UTCDateTime::__construct(): Creating a MongoDB\BSON\UTCDateTime instance with a string is deprecated and will be removed in ext-mongodb 2.0 in %s
3439
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
3540
Error parsing "-9223372036854775809" as 64-bit integer for MongoDB\BSON\UTCDateTime initialization
41+
42+
Deprecated: MongoDB\BSON\UTCDateTime::__construct(): Creating a MongoDB\BSON\UTCDateTime instance with a string is deprecated and will be removed in ext-mongodb 2.0 in %s
3643
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
3744
Error parsing "18446744073709551615" as 64-bit integer for MongoDB\BSON\UTCDateTime initialization
3845
===DONE===

0 commit comments

Comments
 (0)