@@ -271,6 +271,124 @@ public function testUpsert()
271271 self ::assertEquals ('English ' , $ documents [1 ]->language );
272272 }
273273
274+ public function testToArrayWithNestedDocumentFromMongo ()
275+ {
276+ $ client = $ this ->getDatabase ();
277+
278+ // Insert a document with nested object data
279+ $ client ->insert ('movies_nested ' , [
280+ '_id ' => 'nested-test-1 ' ,
281+ 'title ' => 'Inception ' ,
282+ 'director ' => [
283+ 'name ' => 'Christopher Nolan ' ,
284+ 'born ' => 1970 ,
285+ ],
286+ 'cast ' => [
287+ ['name ' => 'Leonardo DiCaprio ' , 'role ' => 'Cobb ' ],
288+ ['name ' => 'Tom Hardy ' , 'role ' => 'Eames ' ],
289+ ],
290+ ]);
291+
292+ // Read back from MongoDB — cursor returns stdClass with nested stdClass
293+ $ result = $ client ->find ('movies_nested ' , ['_id ' => 'nested-test-1 ' ])->cursor ->firstBatch [0 ] ?? null ;
294+ self ::assertNotNull ($ result );
295+ self ::assertInstanceOf (\stdClass::class, $ result );
296+ self ::assertInstanceOf (\stdClass::class, $ result ->director );
297+
298+ // Convert via toArray — nested stdClass must become arrays
299+ $ array = $ client ->toArray ($ result );
300+ self ::assertIsArray ($ array );
301+ self ::assertIsArray ($ array ['director ' ]);
302+ self ::assertEquals ('Christopher Nolan ' , $ array ['director ' ]['name ' ]);
303+ self ::assertEquals (1970 , $ array ['director ' ]['born ' ]);
304+ self ::assertIsArray ($ array ['cast ' ]);
305+ self ::assertIsArray ($ array ['cast ' ][0 ]);
306+ self ::assertEquals ('Leonardo DiCaprio ' , $ array ['cast ' ][0 ]['name ' ]);
307+ self ::assertIsArray ($ array ['cast ' ][1 ]);
308+ self ::assertEquals ('Tom Hardy ' , $ array ['cast ' ][1 ]['name ' ]);
309+
310+ // Also test via lastDocument
311+ $ last = $ client ->lastDocument ('movies_nested ' );
312+ self ::assertIsArray ($ last );
313+ self ::assertIsArray ($ last ['director ' ]);
314+ self ::assertEquals ('Christopher Nolan ' , $ last ['director ' ]['name ' ]);
315+
316+ $ client ->dropCollection ('movies_nested ' );
317+ }
318+
319+ public function testToArrayNestedConversion ()
320+ {
321+ $ client = $ this ->getDatabase ();
322+
323+ // Nested stdClass (simulates MongoDB BSON result)
324+ $ nested = new \stdClass ();
325+ $ nested ->name = 'John ' ;
326+ $ nested ->age = 30 ;
327+
328+ $ root = new \stdClass ();
329+ $ root ->id = 'doc-1 ' ;
330+ $ root ->author = $ nested ;
331+ $ root ->tags = ['php ' , 'mongo ' ];
332+
333+ $ result = $ client ->toArray ($ root );
334+
335+ self ::assertIsArray ($ result );
336+ self ::assertEquals ('doc-1 ' , $ result ['id ' ]);
337+ self ::assertIsArray ($ result ['author ' ]);
338+ self ::assertEquals ('John ' , $ result ['author ' ]['name ' ]);
339+ self ::assertEquals (30 , $ result ['author ' ]['age ' ]);
340+ self ::assertIsArray ($ result ['tags ' ]);
341+
342+ // Deeply nested stdClass
343+ $ deep = new \stdClass ();
344+ $ deep ->value = 'deep ' ;
345+
346+ $ mid = new \stdClass ();
347+ $ mid ->child = $ deep ;
348+
349+ $ top = new \stdClass ();
350+ $ top ->mid = $ mid ;
351+
352+ $ result = $ client ->toArray ($ top );
353+
354+ self ::assertIsArray ($ result );
355+ self ::assertIsArray ($ result ['mid ' ]);
356+ self ::assertIsArray ($ result ['mid ' ]['child ' ]);
357+ self ::assertEquals ('deep ' , $ result ['mid ' ]['child ' ]['value ' ]);
358+
359+ // Non-stdClass objects should NOT be converted
360+ $ root = new \stdClass ();
361+ $ root ->created = new \DateTime ('2024-01-01 ' );
362+ $ root ->name = 'test ' ;
363+
364+ $ result = $ client ->toArray ($ root );
365+
366+ self ::assertIsArray ($ result );
367+ self ::assertInstanceOf (\DateTime::class, $ result ['created ' ]);
368+
369+ // stdClass inside an array (simulates nested documents in a list)
370+ $ item = new \stdClass ();
371+ $ item ->id = 'item-1 ' ;
372+ $ item ->label = 'Tag ' ;
373+
374+ $ root = new \stdClass ();
375+ $ root ->id = 'doc-5 ' ;
376+ $ root ->items = [$ item ];
377+
378+ $ result = $ client ->toArray ($ root );
379+
380+ self ::assertIsArray ($ result );
381+ self ::assertIsArray ($ result ['items ' ]);
382+ self ::assertIsArray ($ result ['items ' ][0 ]);
383+ self ::assertEquals ('item-1 ' , $ result ['items ' ][0 ]['id ' ]);
384+
385+ // Null handling
386+ self ::assertNull ($ client ->toArray (null ));
387+
388+ // Scalar wrapping
389+ self ::assertEquals ([42 ], $ client ->toArray (42 ));
390+ }
391+
274392 public function testCountMethod ()
275393 {
276394 $ collectionName = 'count_test ' ;
0 commit comments