spatie / laravel-medialibrary

Associate files with Eloquent models
https://spatie.be/docs/laravel-medialibrary
MIT License
5.78k stars 1.08k forks source link

Error doing json_decode to a MediaCollection after form validation fail #3650

Closed fabiomlferreira closed 5 months ago

fabiomlferreira commented 5 months ago

I have a form with a field named "cover" and that form is for a Demo model that have a Media Collection we can access like this $demo->getMedia('cover').

When I open if I do json_encode($demo->getMedia('cover')) it calls jsonSerialize() from Spatie\MediaLibrary\MediaCollections\Models\Collections\MediaCollection

This works but if I have some field missing and the cover input have any value the the json_encode($demo->getMedia('cover')) will crash, because the jsonSerialize() method is like this

public function jsonSerialize(): array
{
    if (config('media-library.use_default_collection_serialization')) {
        return parent::jsonSerialize();
    }

    if (! ($this->formFieldName ?? $this->collectionName)) {
        return [];
    }

    return old($this->formFieldName ?? $this->collectionName) ?? $this->map(function (Media $media) {
        return [
            'name' => $media->name,
            'file_name' => $media->file_name,
            'uuid' => $media->uuid,
            'preview_url' => $media->preview_url,
            'original_url' => $media->original_url,
            'order' => $media->order_column,
            'custom_properties' => $media->custom_properties,
            'extension' => $media->extension,
            'size' => $media->size,
        ];
    })->keyBy('uuid')->toArray();
}

In this case this method will return what is inside old('cover') in my case this is a string with the name of the file and a string is not an array and I get an error. I this this code should be improved to prevent to return something that is not an array where this is my suggestion:

public function jsonSerialize(): array
{
    if (config('media-library.use_default_collection_serialization')) {
        return parent::jsonSerialize();
    }

    if (! ($this->formFieldName ?? $this->collectionName)) {
        return [];
    }

    $old = old($this->formFieldName ?? $this->collectionName);
    if (is_array($old)) {
        return $old;
    } else {
        return $this->map(function (Media $media) {
            return [
                'name' => $media->name,
                'file_name' => $media->file_name,
                'uuid' => $media->uuid,
                'preview_url' => $media->preview_url,
                'original_url' => $media->original_url,
                'order' => $media->order_column,
                'custom_properties' => $media->custom_properties,
                'extension' => $media->extension,
                'size' => $media->size,
            ];
        })->keyBy('uuid')->toArray();
    }
}