@@ -367,6 +367,41 @@ public function testDateMutationTimeToTime(): void
367367 $ this ->assertCloseEnoughString ($ dt ->format ('Y-m-d H:i:s ' ), $ time ->format ('Y-m-d H:i:s ' ));
368368 }
369369
370+ public function testToRawArrayConvertsDateTimeToString (): void
371+ {
372+ $ entity = new class () extends Entity {
373+ protected $ attributes = [
374+ 'created_at ' => null ,
375+ 'updated_at ' => null ,
376+ ];
377+ protected $ original = [
378+ 'created_at ' => null ,
379+ 'updated_at ' => null ,
380+ ];
381+ };
382+
383+ $ entity ->created_at = '2023-12-12 12:12:12 ' ;
384+ $ entity ->updated_at = '2023-12-13 13:13:13 ' ;
385+
386+ $ raw = $ entity ->toRawArray ();
387+
388+ // toRawArray() should return primitive types, not objects
389+ $ this ->assertIsString ($ raw ['created_at ' ]);
390+ $ this ->assertSame ('2023-12-12 12:12:12 ' , $ raw ['created_at ' ]);
391+ $ this ->assertIsString ($ raw ['updated_at ' ]);
392+ $ this ->assertSame ('2023-12-13 13:13:13 ' , $ raw ['updated_at ' ]);
393+
394+ // Attributes themselves should still contain Time objects
395+ $ attrs = $ this ->getPrivateProperty ($ entity , 'attributes ' );
396+ $ this ->assertInstanceOf (Time::class, $ attrs ['created_at ' ]);
397+ $ this ->assertInstanceOf (Time::class, $ attrs ['updated_at ' ]);
398+
399+ // toArray() should still return Time objects (no regression)
400+ $ array = $ entity ->toArray ();
401+ $ this ->assertInstanceOf (Time::class, $ array ['created_at ' ]);
402+ $ this ->assertInstanceOf (Time::class, $ array ['updated_at ' ]);
403+ }
404+
370405 public function testCastInteger (): void
371406 {
372407 $ entity = $ this ->getCastEntity ();
@@ -1421,6 +1456,93 @@ public function testToRawArrayOnlyChanged(): void
14211456 ], $ result );
14221457 }
14231458
1459+ public function testToRawArrayConvertsDateTimeToStringOnlyWhenNonRecursive (): void
1460+ {
1461+ $ entity = $ this ->getEntity ();
1462+
1463+ // Non-recursive: DateTime becomes string
1464+ $ entity ->created_at = '2024-03-15 10:30:00 ' ;
1465+ $ raw = $ entity ->toRawArray ();
1466+ $ this ->assertIsString ($ raw ['created_at ' ]);
1467+
1468+ // Recursive: DateTime stays Time
1469+ $ recursive = $ entity ->toRawArray (false , true );
1470+ $ this ->assertInstanceOf (Time::class, $ recursive ['created_at ' ]);
1471+
1472+ // Non-recursive onlyChanged: also converts to string
1473+ $ entity ->syncOriginal ();
1474+ $ entity ->created_at = '2024-06-15 14:30:00 ' ;
1475+ $ changed = $ entity ->toRawArray (true );
1476+ $ this ->assertIsString ($ changed ['created_at ' ]);
1477+
1478+ // Recursive onlyChanged: preserves Time
1479+ $ changedRecursive = $ entity ->toRawArray (true , true );
1480+ $ this ->assertInstanceOf (Time::class, $ changedRecursive ['created_at ' ]);
1481+
1482+ // Null values stay null regardless of mode
1483+ $ entity2 = $ this ->getEntity ();
1484+ $ this ->assertNull ($ entity2 ->toRawArray ()['created_at ' ]);
1485+ $ this ->assertNull ($ entity2 ->toRawArray (false , true )['created_at ' ]);
1486+
1487+ // toArray() should not be affected (still returns Time)
1488+ $ arr = $ entity ->toArray ();
1489+ $ this ->assertInstanceOf (Time::class, $ arr ['createdAt ' ]);
1490+ }
1491+
1492+ public function testToRawArrayRecursivePreservesTimeObjectsInNestedEntities (): void
1493+ {
1494+ $ child = $ this ->getEntity ();
1495+ $ child ->created_at = '2024-03-10 08:00:00 ' ;
1496+
1497+ $ parent = $ this ->getEntity ();
1498+ $ parent ->created_at = '2024-03-15 10:30:00 ' ;
1499+ $ parent ->entity = $ child ;
1500+
1501+ $ result = $ parent ->toRawArray (false , true );
1502+
1503+ $ this ->assertInstanceOf (Time::class, $ result ['created_at ' ]);
1504+ $ this ->assertIsArray ($ result ['entity ' ]);
1505+ $ this ->assertInstanceOf (Time::class, $ result ['entity ' ]['created_at ' ]);
1506+
1507+ // Non-recursive: converts to string
1508+ $ nonRecursive = $ parent ->toRawArray ();
1509+ $ this ->assertIsString ($ nonRecursive ['created_at ' ]);
1510+
1511+ // toArray() uses datamapped keys
1512+ $ arr = $ parent ->toArray ();
1513+ $ this ->assertInstanceOf (Time::class, $ arr ['createdAt ' ]);
1514+ }
1515+
1516+ public function testToRawArrayRecursiveWithMixedAttributes (): void
1517+ {
1518+ $ entity = new class () extends Entity {
1519+ protected $ attributes = [
1520+ 'name ' => null ,
1521+ 'created_at ' => null ,
1522+ 'count ' => null ,
1523+ ];
1524+ protected $ original = [
1525+ 'name ' => null ,
1526+ 'created_at ' => null ,
1527+ 'count ' => null ,
1528+ ];
1529+ };
1530+
1531+ $ entity ->name = 'test ' ;
1532+ $ entity ->count = 42 ;
1533+ $ entity ->created_at = '2024-08-20 16:45:00 ' ;
1534+
1535+ // Recursive: scalars unchanged, DateTime preserved as Time
1536+ $ result = $ entity ->toRawArray (false , true );
1537+ $ this ->assertSame ('test ' , $ result ['name ' ]);
1538+ $ this ->assertSame (42 , $ result ['count ' ]);
1539+ $ this ->assertInstanceOf (Time::class, $ result ['created_at ' ]);
1540+
1541+ // Non-recursive: DateTime converted to string
1542+ $ result2 = $ entity ->toRawArray ();
1543+ $ this ->assertIsString ($ result2 ['created_at ' ]);
1544+ }
1545+
14241546 public function testFilledConstruction (): void
14251547 {
14261548 $ data = [
0 commit comments