@@ -221,6 +221,14 @@ public function __set(string $key, $value = null)
221221 $ value = serialize ($ value );
222222 }
223223
224+ // JSON casting requires that we JSONize the value
225+ // when setting it so that it can easily be stored
226+ // back to the database.
227+ if (function_exists ('json_encode ' ) && array_key_exists ($ key , $ this ->_options ['casts ' ]) && ($ this ->_options ['casts ' ][$ key ] === 'json ' || $ this ->_options ['casts ' ][$ key ] === 'json-array ' ))
228+ {
229+ $ value = json_encode ($ value );
230+ }
231+
224232 // if a set* method exists for this key,
225233 // use that method to insert this value.
226234 $ method = 'set ' . str_replace (' ' , '' , ucwords (str_replace (['- ' , '_ ' ], ' ' , $ key )));
@@ -360,6 +368,7 @@ protected function mutateDate($value)
360368 *
361369 * @return mixed
362370 */
371+
363372 protected function castAs ($ value , string $ type )
364373 {
365374 switch ($ type )
@@ -390,6 +399,12 @@ protected function castAs($value, string $type)
390399
391400 $ value = (array )$ value ;
392401 break ;
402+ case 'json ' :
403+ $ value = $ this ->castAsJson ($ value , false );
404+ break ;
405+ case 'json-array ' :
406+ $ value = $ this ->castAsJson ($ value , true );
407+ break ;
393408 case 'datetime ' :
394409 return new \DateTime ($ value );
395410 break ;
@@ -400,4 +415,32 @@ protected function castAs($value, string $type)
400415
401416 return $ value ;
402417 }
418+
419+ //--------------------------------------------------------------------
420+
421+ /**
422+ * Cast as JSON
423+ *
424+ * @param mixed $value
425+ * @param bool $asArray
426+ *
427+ * @return mixed
428+ */
429+ private function castAsJson ($ value , bool $ asArray = false )
430+ {
431+ $ tmp = !is_null ($ value ) ? ($ asArray ? [] : new \stdClass ) : null ;
432+ if (function_exists ('json_decode ' ))
433+ {
434+ if ((is_string ($ value ) && (strpos ($ value , '[ ' ) === 0 || strpos ($ value , '{ ' ) === 0 || (strpos ($ value , '" ' ) === 0 && strrpos ($ value , '" ' ) === 0 ))) || is_numeric ($ value ))
435+ {
436+ $ tmp = json_decode ($ value , $ asArray );
437+
438+ if (json_last_error () !== JSON_ERROR_NONE )
439+ {
440+ throw CastException::forInvalidJsonFormatException (json_last_error ());
441+ }
442+ }
443+ }
444+ return $ tmp ;
445+ }
403446}
0 commit comments