diff --git a/src/Support/EloquentCasts/DataCollectionEloquentCast.php b/src/Support/EloquentCasts/DataCollectionEloquentCast.php index b1196bc3..16c81ca3 100644 --- a/src/Support/EloquentCasts/DataCollectionEloquentCast.php +++ b/src/Support/EloquentCasts/DataCollectionEloquentCast.php @@ -35,19 +35,17 @@ public function get($model, string $key, $value, array $attributes): ?DataCollec $data = json_decode($value, true, flags: JSON_THROW_ON_ERROR); - $isAbstract = $this->isAbstractClassCast(); - $data = array_map( - function (array $item) use ($isAbstract) { - if ($isAbstract) { - $dataClass = $this->dataConfig->morphMap->getMorphedDataClass($item['type']) ?? $item['type']; + $dataClass = $this->dataConfig->getDataClass($this->dataClass); - return $dataClass::from($item['data']); - } + $data = array_map(function (array $item) use ($dataClass) { + if ($dataClass->isAbstract && $dataClass->transformable) { + $morphedClass = $this->dataConfig->morphMap->getMorphedDataClass($item['type']) ?? $item['type']; - return ($this->dataClass)::from($item); - }, - $data - ); + return $morphedClass::from($item['data']); + } + + return ($this->dataClass)::from($item); + }, $data); return new ($this->dataCollectionClass)($this->dataClass, $data); } @@ -70,26 +68,24 @@ public function set($model, string $key, $value, array $attributes): ?string throw CannotCastData::shouldBeArray($model::class, $key); } - $isAbstract = $this->isAbstractClassCast(); - $data = array_map( - function (array | BaseData $item) use ($isAbstract) { - if ($isAbstract) { - $class = get_class($item); - - return [ - 'type' => $this->dataConfig->morphMap->getDataClassAlias($class) ?? $class, - 'data' => json_decode(json: $item->toJson(), associative: true, flags: JSON_THROW_ON_ERROR), - ]; - } - - return is_array($item) - ? ($this->dataClass)::from($item) - : $item; - }, - $value - ); - - if ($isAbstract) { + $dataClass = $this->dataConfig->getDataClass($this->dataClass); + + $data = array_map(function (array|BaseData $item) use ($dataClass) { + if ($dataClass->isAbstract && $item instanceof TransformableData) { + $class = get_class($item); + + return [ + 'type' => $this->dataConfig->morphMap->getDataClassAlias($class) ?? $class, + 'data' => json_decode(json: $item->toJson(), associative: true, flags: JSON_THROW_ON_ERROR), + ]; + } + + return is_array($item) + ? ($this->dataClass)::from($item) + : $item; + }, $value); + + if ($dataClass->isAbstract) { return json_encode($data); } diff --git a/tests/Support/EloquentCasts/DataCollectionEloquentCastTest.php b/tests/Support/EloquentCasts/DataCollectionEloquentCastTest.php index 8e3eb5a5..30ed128a 100644 --- a/tests/Support/EloquentCasts/DataCollectionEloquentCastTest.php +++ b/tests/Support/EloquentCasts/DataCollectionEloquentCastTest.php @@ -169,4 +169,7 @@ expect($model->abstract_collection) ->toBeInstanceOf(DataCollection::class) ->each->toBeInstanceOf(AbstractData::class); + + expect($model->abstract_collection[0])->toBeInstanceOf(AbstractDataA::class); + expect($model->abstract_collection[1])->toBeInstanceOf(AbstractDataB::class); });