I am using laravel v12 with filament panel v3 for admin panel and laravel cloud for server. For media management, I use Spatie media library. For media files, I use Object Storage from the laravel cloud server(S3 AWS Bucket) with Read and Write permissions.
composer.json file
"php": "^8.2",
"filament/filament": "^3.2",
"filament/spatie-laravel-media-library-plugin": "^3.2",
"laravel/framework": "^12.0",
"laravel/tinker": "^2.10.1",
"league/flysystem-aws-s3-v3": "^3.0",
"livewire/livewire": "^3.6",
"spatie/laravel-medialibrary": "^11.12"
Game.php model:
<?php
namespace App\Models;
use App\Observers\GameObserver;
use Illuminate\Database\Eloquent\Attributes\ObservedBy;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\MorphOne;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
#[ObservedBy([GameObserver::class])]
class Game extends Model implements HasMedia
{
use InteractsWithMedia;
/**
* The attributes that aren't mass assignable.
*
* @var array<string>|bool
*/
protected $guarded = ['id'];
/**
* Register media collections for spatie media library
*/
public function registerMediaCollections(): void
{
$this->addMediaCollection('image')
->useDisk('s3');
}
}
filesystems.php -> disks configuration
's3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
'url' => env('AWS_URL'),
'endpoint' => env('AWS_ENDPOINT'),
'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false),
'throw' => false,
'report' => false,
],
I made a custom path generator for spatie media library for saving my files in directories for each model:
<?php
namespace App\Support\Media;
use Spatie\MediaLibrary\MediaCollections\Models\Media;
use Spatie\MediaLibrary\Support\PathGenerator\DefaultPathGenerator;
class PathGenerator extends DefaultPathGenerator
{
/**
* Get the path for the given media, relative to the root storage path.
*/
public function getPath(Media $media): string
{
$model = $media->model;
if ($model) {
$folder = strtolower(class_basename($model));
return "{$folder}/{$model->id}/";
}
return "others/{$media->id}/";
}
}
media-library.php config
/*
* The class that contains the strategy for determining a media file's path.
*/
'path_generator' => \App\Support\Media\PathGenerator::class,
This is the structure of the folders in the S3 bucket:
game/ 5/... 6/... user/ 1/... 2/...
This is how i get the files in the .blade file, and it's work
Storage::disk($media->disk)
->temporaryUrl("game/{$game->id}/{$media->file_name}", now()->addMinutes(5));
In filament panel, when i create a new resource it's work fine.
GameResource -> filament panel
class GameResource extends Resource
{
...
public static function form(Form $form): Form
{
return $form
->schema([
//--- --- Image -----------------------------------------------------------------------------------------
SpatieMediaLibraryFileUpload::make('media')
->collection('image')
->disk('s3')
->label(__('game.fields.image'))
->image()
->maxSize(4096)
->required()
->columnSpanFull(),
.....
}
}
Everything works correctly when creating a game, the problem is when I try to edit this resource, because filament panel doesn't know how to fetch it from the cloud (to generate a practical temporary url).
Can you give me some advice on how to handle this situation?
Thanks in advance.