diff --git a/src/Illuminate/Database/Eloquent/Casts/ArrayObject.php b/src/Illuminate/Database/Eloquent/Casts/ArrayObject.php new file mode 100644 index 000000000000..596ed836006b --- /dev/null +++ b/src/Illuminate/Database/Eloquent/Casts/ArrayObject.php @@ -0,0 +1,40 @@ +getArrayCopy()); + } + + /** + * Get the instance as an array. + * + * @return array + */ + public function toArray() + { + return $this->getArrayCopy(); + } + + /** + * Get the array that should be JSON serialized. + * + * @return array + */ + public function jsonSerialize() + { + return $this->getArrayCopy(); + } +} diff --git a/src/Illuminate/Database/Eloquent/Casts/AsArrayObject.php b/src/Illuminate/Database/Eloquent/Casts/AsArrayObject.php new file mode 100644 index 000000000000..8d950e2daff4 --- /dev/null +++ b/src/Illuminate/Database/Eloquent/Casts/AsArrayObject.php @@ -0,0 +1,35 @@ + json_encode($value)]; + } + + public function serialize($model, string $key, $value, array $attributes) + { + return $value->getArrayCopy(); + } + }; + } +} diff --git a/src/Illuminate/Database/Eloquent/Casts/AsCollection.php b/src/Illuminate/Database/Eloquent/Casts/AsCollection.php new file mode 100644 index 000000000000..e96834f6e4d3 --- /dev/null +++ b/src/Illuminate/Database/Eloquent/Casts/AsCollection.php @@ -0,0 +1,31 @@ + json_encode($value)]; + } + }; + } +} diff --git a/src/Illuminate/Database/Eloquent/Casts/AsEncryptedArrayObject.php b/src/Illuminate/Database/Eloquent/Casts/AsEncryptedArrayObject.php new file mode 100644 index 000000000000..b14fa8123e9b --- /dev/null +++ b/src/Illuminate/Database/Eloquent/Casts/AsEncryptedArrayObject.php @@ -0,0 +1,36 @@ + Crypt::encryptString(json_encode($value))]; + } + + public function serialize($model, string $key, $value, array $attributes) + { + return $value->getArrayCopy(); + } + }; + } +} diff --git a/src/Illuminate/Database/Eloquent/Casts/AsEncryptedCollection.php b/src/Illuminate/Database/Eloquent/Casts/AsEncryptedCollection.php new file mode 100644 index 000000000000..bb4f288d4196 --- /dev/null +++ b/src/Illuminate/Database/Eloquent/Casts/AsEncryptedCollection.php @@ -0,0 +1,32 @@ + Crypt::encryptString(json_encode($value))]; + } + }; + } +} diff --git a/tests/Integration/Database/DatabaseArrayObjectAndCollectionCustomCastTest.php b/tests/Integration/Database/DatabaseArrayObjectAndCollectionCustomCastTest.php new file mode 100644 index 000000000000..7f5b8e30f220 --- /dev/null +++ b/tests/Integration/Database/DatabaseArrayObjectAndCollectionCustomCastTest.php @@ -0,0 +1,75 @@ +increments('id'); + $table->text('array_object'); + $table->text('collection'); + $table->timestamps(); + }); + } + + public function test_array_object_and_collection_casting() + { + $model = new TestEloquentModelWithCustomArrayObjectCast; + + $model->array_object = ['name' => 'Taylor']; + $model->collection = collect(['name' => 'Taylor']); + + $model->save(); + + $model = $model->fresh(); + + $this->assertEquals(['name' => 'Taylor'], $model->array_object->toArray()); + $this->assertEquals(['name' => 'Taylor'], $model->collection->toArray()); + + $model->array_object['age'] = 34; + $model->array_object['meta']['title'] = 'Developer'; + + $model->save(); + + $model = $model->fresh(); + + $this->assertEquals([ + 'name' => 'Taylor', + 'age' => 34, + 'meta' => ['title' => 'Developer'], + ], $model->array_object->toArray()); + } +} + +class TestEloquentModelWithCustomArrayObjectCast extends Model +{ + /** + * The attributes that aren't mass assignable. + * + * @var string[] + */ + protected $guarded = []; + + /** + * The attributes that should be cast to native types. + * + * @var array + */ + protected $casts = [ + 'array_object' => AsArrayObject::class, + 'collection' => AsCollection::class, + ]; +}