@@ -1135,6 +1135,49 @@ public function testFreshMethodOnCollection()
11351135 $ this ->assertEquals ($ users ->map ->fresh (), $ users ->fresh ());
11361136 }
11371137
1138+ public function testAttributesMayBeCastToObjects ()
1139+ {
1140+ $ model = new EloquentTestObjectCast ();
1141+
1142+ $ model ->token = new EloquentTestBase64Object ('Taylor ' );
1143+ $ this ->assertInstanceOf (EloquentTestBase64Object::class, $ model ->token );
1144+ $ this ->assertEquals ('Taylor ' , $ model ->token ->secret );
1145+ $ this ->assertEquals ('VGF5bG9y ' , $ model ->toArray ()['token ' ]);
1146+ $ this ->assertTrue ($ model ->hasCast ('token ' , 'base64 ' ));
1147+
1148+ $ model ->price = (new EloquentTestMoneyObject (10 ))->setCurrency ('BTC ' );
1149+ $ this ->assertInstanceOf (EloquentTestMoneyObject::class, $ model ->price );
1150+ $ this ->assertEquals (10 , $ model ->toArray ()['price ' ]);
1151+ $ this ->assertEquals ('BTC ' , $ model ->toArray ()['currency ' ]);
1152+ $ this ->assertTrue ($ model ->hasCast ('price ' , 'money ' ));
1153+
1154+ $ model ->price ->amount = 20 ;
1155+ $ this ->assertEquals (20 , $ model ->toArray ()['price ' ]);
1156+
1157+ $ model ->price = (new EloquentTestMoneyObject (30 ));
1158+ $ this ->assertEquals (30 , $ model ->toArray ()['price ' ]);
1159+ $ this ->assertNull ($ model ->toArray ()['currency ' ]);
1160+
1161+ $ model ->price = null ;
1162+ $ this ->assertNull ($ model ->price );
1163+ $ this ->assertNull ($ model ->toArray ()['price ' ]);
1164+ $ this ->assertNull ($ model ->toArray ()['currency ' ]);
1165+
1166+ $ model ->price = (new EloquentTestMoneyObject (10 ))->setCurrency ('BTC ' );
1167+ $ model ->forceFill (['price ' => null ]);
1168+ $ this ->assertNull ($ model ->price );
1169+ $ this ->assertNull ($ model ->toArray ()['price ' ]);
1170+ $ this ->assertNull ($ model ->toArray ()['currency ' ]);
1171+
1172+ $ model ->price = (new EloquentTestMoneyObject (10 ))->setCurrency ('BTC ' );
1173+ $ model ->price ->setCurrency ('XBT ' );
1174+ $ model = unserialize (serialize ($ model ));
1175+ $ this ->assertEquals ('XBT ' , $ model ->currency );
1176+
1177+ $ model ->meta = new EloquentTestStringifyableObject (['friends ' => ['Adam ' ]]);
1178+ $ this ->assertEquals ('{"friends":["Adam"]} ' , $ model ->toArray ()['meta ' ]);
1179+ }
1180+
11381181 /**
11391182 * Helpers...
11401183 */
@@ -1365,3 +1408,97 @@ public function level()
13651408 return $ this ->belongsTo (EloquentTestFriendLevel::class, 'friend_level_id ' );
13661409 }
13671410}
1411+
1412+ class EloquentTestBase64Object
1413+ {
1414+ public $ secret ;
1415+
1416+ public function __construct ($ secret )
1417+ {
1418+ $ this ->secret = empty ($ secret ) ? null : $ secret ;
1419+ }
1420+
1421+ public static function fromHash ($ secret )
1422+ {
1423+ return new static (empty ($ secret ) ? null : base64_decode ($ secret ));
1424+ }
1425+
1426+ public function hash ()
1427+ {
1428+ return empty ($ this ->secret ) ? null : base64_encode ($ this ->secret );
1429+ }
1430+ }
1431+
1432+ class EloquentTestStringifyableObject
1433+ {
1434+ public $ json ;
1435+
1436+ public function __construct ($ json )
1437+ {
1438+ $ this ->json = $ json ;
1439+ }
1440+
1441+ public static function fromString ($ string )
1442+ {
1443+ return new static (json_encode ($ string ));
1444+ }
1445+
1446+ public function __toString ()
1447+ {
1448+ return json_encode ($ this ->json );
1449+ }
1450+ }
1451+
1452+ class EloquentTestMoneyObject
1453+ {
1454+ public $ amount ;
1455+ public $ currency ;
1456+
1457+ public function __construct ($ amount )
1458+ {
1459+ $ this ->amount = $ amount ;
1460+ }
1461+
1462+ public function setCurrency ($ currency )
1463+ {
1464+ $ this ->currency = $ currency ;
1465+
1466+ return $ this ;
1467+ }
1468+ }
1469+
1470+ class EloquentTestObjectCast extends Eloquent
1471+ {
1472+ protected $ casts = [
1473+ 'meta ' => 'stringifyable ' ,
1474+ 'token ' => 'base64 ' ,
1475+ 'price ' => 'money:price,currency ' ,
1476+ ];
1477+
1478+ public function castToStringifyable ($ value )
1479+ {
1480+ return EloquentTestStringifyableObject::fromString ($ value );
1481+ }
1482+
1483+ public function castToBase64 ($ value )
1484+ {
1485+ return EloquentTestBase64Object::fromHash ($ value );
1486+ }
1487+
1488+ public function castFromBase64 ($ secret )
1489+ {
1490+ return $ secret ->hash ();
1491+ }
1492+
1493+ public function castToMoney ($ amount , $ currency )
1494+ {
1495+ return (new EloquentTestMoneyObject ($ amount ))->setCurrency ($ currency );
1496+ }
1497+
1498+ public function castFromMoney ($ money )
1499+ {
1500+ if ($ money ) {
1501+ return [$ money ->amount , $ money ->currency ];
1502+ }
1503+ }
1504+ }
0 commit comments