From 8980ee53f03721428c21b0b32ef662f85b277403 Mon Sep 17 00:00:00 2001 From: Ruben Van Assche Date: Thu, 25 Jul 2024 13:17:35 +0200 Subject: [PATCH] Fix issue where abstract eloquent casts were not encrypted --- .../EloquentCasts/DataEloquentCast.php | 11 +++--- .../Models/DummyModelWithEncryptedCasts.php | 4 +++ .../EloquentCasts/DataEloquentCastTest.php | 34 ++++++++++++++----- 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/src/Support/EloquentCasts/DataEloquentCast.php b/src/Support/EloquentCasts/DataEloquentCast.php index e0e170d4..6e709573 100644 --- a/src/Support/EloquentCasts/DataEloquentCast.php +++ b/src/Support/EloquentCasts/DataEloquentCast.php @@ -68,14 +68,13 @@ public function set($model, string $key, $value, array $attributes): ?string throw CannotCastData::shouldBeTransformableData($model::class, $key); } - if ($isAbstractClassCast) { - return json_encode([ + $value = $isAbstractClassCast + ? json_encode([ 'type' => $this->dataConfig->morphMap->getDataClassAlias($value::class) ?? $value::class, 'data' => json_decode($value->toJson(), associative: true, flags: JSON_THROW_ON_ERROR), - ]); - } - - $value = $value->toJson(); + ]) + : $value->toJson(); + ; if (in_array('encrypted', $this->arguments)) { return Crypt::encryptString($value); diff --git a/tests/Fakes/Models/DummyModelWithEncryptedCasts.php b/tests/Fakes/Models/DummyModelWithEncryptedCasts.php index 668afa10..251bcb30 100644 --- a/tests/Fakes/Models/DummyModelWithEncryptedCasts.php +++ b/tests/Fakes/Models/DummyModelWithEncryptedCasts.php @@ -3,6 +3,8 @@ namespace Spatie\LaravelData\Tests\Fakes\Models; use Illuminate\Database\Eloquent\Model; +use Spatie\LaravelData\DataCollection; +use Spatie\LaravelData\Tests\Fakes\AbstractData\AbstractData; use Spatie\LaravelData\Tests\Fakes\SimpleData; use Spatie\LaravelData\Tests\Fakes\SimpleDataCollection; @@ -11,6 +13,8 @@ class DummyModelWithEncryptedCasts extends Model protected $casts = [ 'data' => SimpleData::class.':encrypted', 'data_collection' => SimpleDataCollection::class.':'.SimpleData::class.',encrypted', + 'abstract_data' => AbstractData::class.':encrypted', + 'abstract_collection' => DataCollection::class . ':' . AbstractData::class.',encrypted', ]; protected $table = 'dummy_model_with_casts'; diff --git a/tests/Support/EloquentCasts/DataEloquentCastTest.php b/tests/Support/EloquentCasts/DataEloquentCastTest.php index 72215fd2..4b291512 100644 --- a/tests/Support/EloquentCasts/DataEloquentCastTest.php +++ b/tests/Support/EloquentCasts/DataEloquentCastTest.php @@ -135,17 +135,12 @@ }); it('can save an encrypted data object', function () { - // Save the encrypted data to the database - DummyModelWithEncryptedCasts::create([ + $model = DummyModelWithEncryptedCasts::create([ 'data' => new SimpleData('Test'), ]); - // Retrieve the model from the database without Eloquent casts - $model = DB::table('dummy_model_with_casts') - ->first(); - try { - Crypt::decryptString($model->data); + Crypt::decryptString($model->getRawOriginal('data')); $isEncrypted = true; } catch (DecryptException $e) { $isEncrypted = false; @@ -155,7 +150,6 @@ }); it('can load an encrypted data object', function () { - // Save the encrypted data to the database DummyModelWithEncryptedCasts::create([ 'data' => new SimpleData('Test'), ]); @@ -165,3 +159,27 @@ expect($model->data)->toEqual(new SimpleData('Test')); }); + +it('can load and save an abstract defined data object', function () { + $abstractA = new AbstractDataA('A\A'); + + $modelId = DummyModelWithEncryptedCasts::create([ + 'abstract_data' => $abstractA, + ])->id; + + $model = DummyModelWithEncryptedCasts::find($modelId); + + expect($model->abstract_data) + ->toBeInstanceOf(AbstractDataA::class) + ->a->toBe('A\A'); + + + try { + Crypt::decryptString($model->getRawOriginal('abstract_data')); + $isEncrypted = true; + } catch (DecryptException $e) { + $isEncrypted = false; + } + + expect($isEncrypted)->toBeTrue(); +});