Skip to content

Commit c5eb198

Browse files
committed
PHPC-344: Allow non-root Serializable to encode as BSON array
1 parent dea4ff9 commit c5eb198

File tree

3 files changed

+85
-9
lines changed

3 files changed

+85
-9
lines changed

src/bson.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -634,14 +634,22 @@ void object_to_bson(zval *object, php_phongo_bson_flags_t flags, const char *key
634634
tmp_ht->nApplyCount++;
635635
}
636636

637-
bson_append_document_begin(bson, key, key_len, &child);
638-
if (instanceof_function(Z_OBJCE_P(object), php_phongo_persistable_ce TSRMLS_CC)) {
639-
if (flags & PHONGO_BSON_ADD_CHILD_ODS) {
640-
bson_append_binary(&child, PHONGO_ODM_FIELD_NAME, -1, 0x80, (const uint8_t *)Z_OBJCE_P(object)->name, strlen(Z_OBJCE_P(object)->name));
637+
/* Persistable objects must always be serialized as BSON documents;
638+
* otherwise, infer based on bsonSerialize()'s return value. */
639+
if (instanceof_function(Z_OBJCE_P(object), php_phongo_persistable_ce TSRMLS_CC) || php_phongo_is_array_or_document(&obj_data TSRMLS_CC) == IS_OBJECT) {
640+
bson_append_document_begin(bson, key, key_len, &child);
641+
if (instanceof_function(Z_OBJCE_P(object), php_phongo_persistable_ce TSRMLS_CC)) {
642+
if (flags & PHONGO_BSON_ADD_CHILD_ODS) {
643+
bson_append_binary(&child, PHONGO_ODM_FIELD_NAME, -1, 0x80, (const uint8_t *)Z_OBJCE_P(object)->name, strlen(Z_OBJCE_P(object)->name));
644+
}
641645
}
646+
zval_to_bson(obj_data, flags, &child, NULL TSRMLS_CC);
647+
bson_append_document_end(bson, &child);
648+
} else {
649+
bson_append_array_begin(bson, key, key_len, &child);
650+
zval_to_bson(obj_data, flags, &child, NULL TSRMLS_CC);
651+
bson_append_array_end(bson, &child);
642652
}
643-
zval_to_bson(obj_data, flags, &child, NULL TSRMLS_CC);
644-
bson_append_document_end(bson, &child);
645653

646654
if (tmp_ht) {
647655
tmp_ht->nApplyCount--;

tests/bson/bson-encode-002.phpt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ $bson = fromPHP(array('embed' => new NumericArray));
6767
echo toJSON($bson), "\n";
6868
echo "Encoded BSON:\n";
6969
hex_dump($bson);
70-
$value = toPHP($bson, array("document" => 'NumericArray'));
70+
$value = toPHP($bson, array("array" => 'NumericArray'));
7171
echo "Decoded BSON:\n";
7272
var_dump($value);
7373

@@ -131,9 +131,9 @@ object(NumericArray)#%d (0) {
131131
}
132132

133133
Testing embedded NumericArray:
134-
{ "embed" : { "0" : 1, "1" : 2, "2" : 3 } }
134+
{ "embed" : [ 1, 2, 3 ] }
135135
Encoded BSON:
136-
0 : 26 00 00 00 03 65 6d 62 65 64 00 1a 00 00 00 10 [&....embed......]
136+
0 : 26 00 00 00 04 65 6d 62 65 64 00 1a 00 00 00 10 [&....embed......]
137137
10 : 30 00 01 00 00 00 10 31 00 02 00 00 00 10 32 00 [0......1......2.]
138138
20 : 03 00 00 00 00 00 [......]
139139
NumericArray::bsonUnserialize() was called with data:

tests/bson/bson-fromPHP-001.phpt

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
--TEST--
2+
BSON\fromPHP(): bsonSerialize() allows array and stdClass
3+
--SKIPIF--
4+
<?php require __DIR__ . "/../utils/basic-skipif.inc"?>
5+
--FILE--
6+
<?php
7+
use MongoDB\BSON as BSON;
8+
9+
require_once __DIR__ . "/../utils/basic.inc";
10+
11+
class MyDocument implements BSON\Serializable
12+
{
13+
private $data;
14+
15+
public function __construct($data = null)
16+
{
17+
$this->data = $data;
18+
}
19+
20+
public function bsonSerialize()
21+
{
22+
return $this->data;
23+
}
24+
}
25+
26+
$tests = array(
27+
array(1, 2, 3),
28+
array('foo' => 'bar'),
29+
(object) array(1, 2, 3),
30+
(object) array('foo' => 'bar'),
31+
);
32+
33+
echo "Testing top-level objects\n";
34+
35+
foreach ($tests as $test) {
36+
try {
37+
echo toJson(fromPHP(new MyDocument($test))), "\n";
38+
} catch (MongoDB\Driver\Exception\UnexpectedValueException $e) {
39+
echo $e->getMessage(), "\n";
40+
}
41+
}
42+
43+
echo "\nTesting nested objects\n";
44+
45+
foreach ($tests as $test) {
46+
try {
47+
echo toJson(fromPHP(new MyDocument(array('nested' => new MyDocument($test))))), "\n";
48+
} catch (MongoDB\Driver\Exception\UnexpectedValueException $e) {
49+
echo $e->getMessage(), "\n";
50+
}
51+
}
52+
53+
?>
54+
===DONE===
55+
<?php exit(0); ?>
56+
--EXPECTF--
57+
Testing top-level objects
58+
{ "0" : 1, "1" : 2, "2" : 3 }
59+
{ "foo" : "bar" }
60+
{ "0" : 1, "1" : 2, "2" : 3 }
61+
{ "foo" : "bar" }
62+
63+
Testing nested objects
64+
{ "nested" : [ 1, 2, 3 ] }
65+
{ "nested" : { "foo" : "bar" } }
66+
{ "nested" : { "0" : 1, "1" : 2, "2" : 3 } }
67+
{ "nested" : { "foo" : "bar" } }
68+
===DONE===

0 commit comments

Comments
 (0)