Skip to content

Commit

Permalink
PHPC-2443: Deprecate string argument and accept Int64 instances in UT…
Browse files Browse the repository at this point in the history
…CDateTime 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
  • Loading branch information
alcaeus committed Sep 13, 2024
1 parent 7ba3371 commit c394d37
Show file tree
Hide file tree
Showing 27 changed files with 120 additions and 114 deletions.
68 changes: 44 additions & 24 deletions src/BSON/UTCDateTime.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,35 @@ static bool php_phongo_utcdatetime_init_from_date(php_phongo_utcdatetime_t* inte
return true;
}

static bool php_phongo_utcdatetime_init_from_object(php_phongo_utcdatetime_t* intern, zend_object* object)
{
if (instanceof_function(object->ce, php_date_get_interface_ce())) {
php_phongo_utcdatetime_init_from_date(intern, php_date_obj_from_obj(object));

return true;
}

if (instanceof_function(object->ce, php_phongo_int64_ce)) {
php_phongo_utcdatetime_init(intern, php_int64_fetch_object(object)->integer);

return true;
}

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));

return false;
}

static bool php_phongo_utcdatetime_init_from_double(php_phongo_utcdatetime_t* intern, double milliseconds)
{
char tmp[24];
int tmp_len;

tmp_len = snprintf(tmp, sizeof(tmp), "%.0f", milliseconds > 0 ? floor(milliseconds) : ceil(milliseconds));

return php_phongo_utcdatetime_init_from_string(intern, tmp, tmp_len);
}

static HashTable* php_phongo_utcdatetime_get_properties_hash(phongo_compat_object_handler_type* object, bool is_temp)
{
php_phongo_utcdatetime_t* intern;
Expand Down Expand Up @@ -179,36 +208,27 @@ static PHP_METHOD(MongoDB_BSON_UTCDateTime, __construct)
return;
}

if (Z_TYPE_P(milliseconds) == IS_OBJECT) {
if (instanceof_function(Z_OBJCE_P(milliseconds), php_date_get_interface_ce())) {
php_phongo_utcdatetime_init_from_date(intern, Z_PHPDATE_P(milliseconds));
} else {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected instance of DateTimeInterface, %s given", ZSTR_VAL(Z_OBJCE_P(milliseconds)->name));
}
return;
}

if (Z_TYPE_P(milliseconds) == IS_LONG) {
php_phongo_utcdatetime_init(intern, Z_LVAL_P(milliseconds));
return;
}
switch (Z_TYPE_P(milliseconds)) {
case IS_OBJECT:
php_phongo_utcdatetime_init_from_object(intern, Z_OBJ_P(milliseconds));
return;

if (Z_TYPE_P(milliseconds) == IS_DOUBLE) {
char tmp[24];
int tmp_len;
case IS_LONG:
php_phongo_utcdatetime_init(intern, Z_LVAL_P(milliseconds));
return;

tmp_len = snprintf(tmp, sizeof(tmp), "%.0f", Z_DVAL_P(milliseconds) > 0 ? floor(Z_DVAL_P(milliseconds)) : ceil(Z_DVAL_P(milliseconds)));
case IS_DOUBLE:
php_phongo_utcdatetime_init_from_double(intern, Z_DVAL_P(milliseconds));
return;

php_phongo_utcdatetime_init_from_string(intern, tmp, tmp_len);
return;
}
case IS_STRING:
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));

if (Z_TYPE_P(milliseconds) != IS_STRING) {
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected integer or string, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(milliseconds));
return;
php_phongo_utcdatetime_init_from_string(intern, Z_STRVAL_P(milliseconds), Z_STRLEN_P(milliseconds));
return;
}

php_phongo_utcdatetime_init_from_string(intern, Z_STRVAL_P(milliseconds), Z_STRLEN_P(milliseconds));
phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT, "Expected integer or string, %s given", PHONGO_ZVAL_CLASS_OR_TYPE_NAME_P(milliseconds));
}

static PHP_METHOD(MongoDB_BSON_UTCDateTime, __set_state)
Expand Down
4 changes: 2 additions & 2 deletions src/BSON/UTCDateTime.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
final class UTCDateTime implements UTCDateTimeInterface, \JsonSerializable, Type, \Serializable
{
#if PHP_VERSION_ID >= 80000
final public function __construct(int|string|float|\DateTimeInterface|null $milliseconds = null) {}
final public function __construct(int|string|float|\DateTimeInterface|Int64|null $milliseconds = null) {}
#else
/** @param int|string|float|\DateTimeInterface|null $milliseconds */
/** @param int|string|float|\DateTimeInterface|Int64|null $milliseconds */
final public function __construct($milliseconds = null) {}
#endif

Expand Down
4 changes: 2 additions & 2 deletions src/BSON/UTCDateTime_arginfo.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions tests/bson/bson-fromPHP-003.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ class MyDocument {
}

$tests = array(
array(new MongoDB\BSON\UTCDateTime('1416445411987')),
array('x' => new MongoDB\BSON\UTCDateTime('1416445411987')),
array(new MongoDB\BSON\UTCDateTime(new MongoDB\BSON\Int64('1416445411987'))),
array('x' => new MongoDB\BSON\UTCDateTime(new MongoDB\BSON\Int64('1416445411987'))),
array(new MyDocument),
array('x' => new MyDocument),
);
Expand Down
2 changes: 1 addition & 1 deletion tests/bson/bson-fromPHP_error-003.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ $tests = array(
new MongoDB\BSON\ObjectId,
new MongoDB\BSON\Regex('regexp', 'i'),
new MongoDB\BSON\Timestamp(1234, 5678),
new MongoDB\BSON\UTCDateTime('1416445411987'),
new MongoDB\BSON\UTCDateTime(new MongoDB\BSON\Int64('1416445411987')),
);

foreach ($tests as $document) {
Expand Down
2 changes: 1 addition & 1 deletion tests/bson/bson-toPHP-004.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ $tests = [
new MongoDB\BSON\ObjectId('586c18d86118fd6c9012dec1'),
new MongoDB\BSON\Regex('foo'),
new MongoDB\BSON\Timestamp(1234, 5678),
new MongoDB\BSON\UTCDateTime('1483479256924'),
new MongoDB\BSON\UTCDateTime(new MongoDB\BSON\Int64('1483479256924')),
];

foreach ($tests as $value) {
Expand Down
2 changes: 1 addition & 1 deletion tests/bson/bson-utcdatetime-001.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ require_once __DIR__ . "/../utils/basic.inc";

$manager = create_test_manager();

$utcdatetime = new MongoDB\BSON\UTCDateTime("1416445411987");
$utcdatetime = new MongoDB\BSON\UTCDateTime(new MongoDB\BSON\Int64('1416445411987'));

$bulk = new MongoDB\Driver\BulkWrite();
$bulk->insert(array('_id' => 1, 'x' => $utcdatetime));
Expand Down
4 changes: 2 additions & 2 deletions tests/bson/bson-utcdatetime-002.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ MongoDB\BSON\UTCDateTime debug handler
--FILE--
<?php

$utcdatetime = new MongoDB\BSON\UTCDateTime('1416445411987');
$utcdatetime = new MongoDB\BSON\UTCDateTime(new MongoDB\BSON\Int64('1416445411987'));

var_dump($utcdatetime);

Expand All @@ -13,6 +13,6 @@ var_dump($utcdatetime);
--EXPECTF--
object(MongoDB\BSON\UTCDateTime)#%d (%d) {
["milliseconds"]=>
%rint\(|string\(13\) "|%r1416445411987%r"|\)%r
string(13) "1416445411987"
}
===DONE===
21 changes: 21 additions & 0 deletions tests/bson/bson-utcdatetime-008.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
--TEST--
MongoDB\BSON\UTCDateTime construction from 64-bit integer as string
--FILE--
<?php

require_once __DIR__ . '/../utils/basic.inc';

$utcdatetime = new MongoDB\BSON\UTCDateTime('1416445411987');

var_dump($utcdatetime);

?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
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
object(MongoDB\BSON\UTCDateTime)#%d (%d) {
["milliseconds"]=>
string(13) "1416445411987"
}
===DONE===
20 changes: 20 additions & 0 deletions tests/bson/bson-utcdatetime-009.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
--TEST--
MongoDB\BSON\UTCDateTime construction from Int64 object
--FILE--
<?php

require_once __DIR__ . '/../utils/basic.inc';

$utcdatetime = new MongoDB\BSON\UTCDateTime(new MongoDB\BSON\Int64('1416445411987'));

var_dump($utcdatetime);

?>
===DONE===
<?php exit(0); ?>
--EXPECTF--
object(MongoDB\BSON\UTCDateTime)#%d (%d) {
["milliseconds"]=>
string(13) "1416445411987"
}
===DONE===
2 changes: 1 addition & 1 deletion tests/bson/bson-utcdatetime-clone-001.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ MongoDB\BSON\UTCDateTime can be cloned (PHP < 8.2)

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

$utcdatetime = new MongoDB\BSON\UTCDateTime("1416445411987");
$utcdatetime = new MongoDB\BSON\UTCDateTime(new MongoDB\BSON\Int64('1416445411987'));

$clone = clone $utcdatetime;

Expand Down
2 changes: 1 addition & 1 deletion tests/bson/bson-utcdatetime-clone-002.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ MongoDB\BSON\UTCDateTime can be cloned (PHP >= 8.2)

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

$utcdatetime = new MongoDB\BSON\UTCDateTime("1416445411987");
$utcdatetime = new MongoDB\BSON\UTCDateTime(new MongoDB\BSON\Int64('1416445411987'));

$clone = clone $utcdatetime;

Expand Down
2 changes: 1 addition & 1 deletion tests/bson/bson-utcdatetime-get_properties-001.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ MongoDB\BSON\UTCDateTime get_properties handler (get_object_vars)
--FILE--
<?php

$utcdatetime = new MongoDB\BSON\UTCDateTime('1416445411987');
$utcdatetime = new MongoDB\BSON\UTCDateTime(new MongoDB\BSON\Int64('1416445411987'));

var_dump(get_object_vars($utcdatetime));

Expand Down
2 changes: 1 addition & 1 deletion tests/bson/bson-utcdatetime-get_properties-002.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ MongoDB\BSON\UTCDateTime get_properties handler (foreach)
--FILE--
<?php

$utcdatetime = new MongoDB\BSON\UTCDateTime('1416445411987');
$utcdatetime = new MongoDB\BSON\UTCDateTime(new MongoDB\BSON\Int64('1416445411987'));

foreach ($utcdatetime as $key => $value) {
var_dump($key);
Expand Down
30 changes: 0 additions & 30 deletions tests/bson/bson-utcdatetime-int-size-001.phpt

This file was deleted.

32 changes: 0 additions & 32 deletions tests/bson/bson-utcdatetime-int-size-002.phpt

This file was deleted.

6 changes: 3 additions & 3 deletions tests/bson/bson-utcdatetime-serialization-003.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ MongoDB\BSON\UTCDateTime serialization (__serialize and __unserialize)
<?php

$tests = [
'0',
'-1416445411987',
'1416445411987',
0,
new MongoDB\BSON\Int64('-1416445411987'),
new MongoDB\BSON\Int64('1416445411987'),
];

foreach ($tests as $milliseconds) {
Expand Down
2 changes: 1 addition & 1 deletion tests/bson/bson-utcdatetime-todatetime-001.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ date.timezone=America/Los_Angeles
--FILE--
<?php

$utcdatetime = new MongoDB\BSON\UTCDateTime("1416445411987");
$utcdatetime = new MongoDB\BSON\UTCDateTime(new MongoDB\BSON\Int64('1416445411987'));
$datetime = $utcdatetime->toDateTime();
var_dump(get_class($datetime));
var_dump($datetime->format(DATE_RSS));
Expand Down
2 changes: 1 addition & 1 deletion tests/bson/bson-utcdatetime-todatetime-002.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ date.timezone=UTC
--FILE--
<?php

$utcdatetime = new MongoDB\BSON\UTCDateTime("1416445411987");
$utcdatetime = new MongoDB\BSON\UTCDateTime(new MongoDB\BSON\Int64('1416445411987'));
$datetime = $utcdatetime->toDateTime();
var_dump(get_class($datetime));
echo $datetime->format('U.u'), "\n";
Expand Down
2 changes: 1 addition & 1 deletion tests/bson/bson-utcdatetime-todatetimeimmutable-001.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ date.timezone=America/Los_Angeles
--FILE--
<?php

$utcdatetime = new MongoDB\BSON\UTCDateTime("1416445411987");
$utcdatetime = new MongoDB\BSON\UTCDateTime(new MongoDB\BSON\Int64('1416445411987'));
$datetime = $utcdatetime->toDateTimeImmutable();
var_dump(get_class($datetime));
var_dump($datetime->format(DATE_RSS));
Expand Down
2 changes: 1 addition & 1 deletion tests/bson/bson-utcdatetime-todatetimeimmutable-002.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ date.timezone=UTC
--FILE--
<?php

$utcdatetime = new MongoDB\BSON\UTCDateTime("1416445411987");
$utcdatetime = new MongoDB\BSON\UTCDateTime(new MongoDB\BSON\Int64('1416445411987'));
$datetime = $utcdatetime->toDateTimeImmutable();
var_dump(get_class($datetime));
echo $datetime->format('U.u'), "\n";
Expand Down
2 changes: 1 addition & 1 deletion tests/bson/bson-utcdatetime-tostring-001.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ MongoDB\BSON\UTCDateTime::__toString()
--FILE--
<?php

$utcdatetime = new MongoDB\BSON\UTCDateTime("1416445411987");
$utcdatetime = new MongoDB\BSON\UTCDateTime(new MongoDB\BSON\Int64('1416445411987'));
var_dump((string) $utcdatetime);

?>
Expand Down
2 changes: 1 addition & 1 deletion tests/bson/bson-utcdatetime_error-001.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ echo throws(function() {
<?php exit(0); ?>
--EXPECT--
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
Expected instance of DateTimeInterface, stdClass given
Expected instance of DateTimeInterface or MongoDB\BSON\Int64, stdClass given
===DONE===
9 changes: 8 additions & 1 deletion tests/bson/bson-utcdatetime_error-003.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,20 @@ echo throws(function() {
?>
===DONE===
<?php exit(0); ?>
--EXPECT--
--EXPECTF--
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
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
Error parsing "1234.5678" as 64-bit integer for MongoDB\BSON\UTCDateTime initialization

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
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
Error parsing "9223372036854775808" as 64-bit integer for MongoDB\BSON\UTCDateTime initialization

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
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
Error parsing "-9223372036854775809" as 64-bit integer for MongoDB\BSON\UTCDateTime initialization

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
OK: Got MongoDB\Driver\Exception\InvalidArgumentException
Error parsing "18446744073709551615" as 64-bit integer for MongoDB\BSON\UTCDateTime initialization
===DONE===
Loading

0 comments on commit c394d37

Please sign in to comment.