I am using FilamentPHP and Spatie media library. Additionally, I am using the Spatie media library FilamentPHP plugin in order to show and upload the images in my admin panel.
However, the images are not being uploaded and stored at all!
This is my model:
use Illuminate\Database\Eloquent\Model;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
class OrderItem extends Model implements HasMedia
{
use InteractsWithMedia;
public function registerMediaCollections(): void
{
$this->addMediaCollection('designs')
->useDisk('designFiles');
}
}
My filesystem.php:
'designFiles' => [
'driver' => 'local',
'root' => storage_path('app/public/designs'),
'url' => env('APP_URL') . '/storage/designs',
'visibility' => 'public',
],
My filament resource:
SpatieMediaLibraryFileUpload::make('design')
->collection('designs')
->downloadable()
->multiple(),
The image I upload on my filament resource are being stored temporarily at storage/app/livewire-tmp
. However, there is no entry in my spatie media library media
table and the image is also not being saved to the desired disk (designFiles).
I have already tried to debug this problem but there is no error event being logged at all. I am using Laravel Valet and I have also added the port to my APP_URL variable with my .env
file as suggested here but it did not help me.
I have also run php artisan storage:link
but because I did run this command before already, it did not change anything. The image is still not being saved.
Those are the versions I use:
"php": "^8.2",
"filament/filament": "^3.2",
"filament/spatie-laravel-media-library-plugin": "^3.2",
"laravel/framework": "^11.9",
"spatie/laravel-medialibrary": "^11.8"
Anybody has an idea how to fix this problem?
Kind regards
UPDATE Added minimal reproducible example
Because it was requested, I have added a minimal reproducible example. Sadly, I am still facing the same issue! You can get it here: https://github.com/FrazeColder/example-app and login to Filament on /admin/login with the credentials you find in the database/seeders/DatabaseSeeder.php
This is not exactly a solution as I do not have a clear picture of your precise setup, but it may help you track down the problem.
I applied the parameters that you specified and my media files were successfully saved to the correct location (app/public/designs
). I however used "spatie/laravel-medialibrary": "^11.9"
Add the following code to have a finer-grained view of what is going on when you save an OrderItem
:
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Database\Events\QueryExecuted;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*/
public function boot(): void
{
DB::listen(function(QueryExecuted $query) {
$is_insert = strpos($query->sql, "insert into") !== false;
$is_orderitem = strpos($query->sql, "order_items") !== false;
$is_mediaitem = strpos($query->sql, "media") !== false;
if ($is_insert && ($is_orderitem || $is_mediaitem)) {
Log::info(
$query->sql,
[
'bindings' => $query->bindings,
'time' => $query->time
]
);
}
});
}
}
This should log any queries that insert to order_items
or a media
. I've assumed these are the names you have for the matching tables in your database. If the names you are using are different, then update the code accordingly.
The logged transactions can be viewed in storage/logs/laravel.log
. Newer log entries are at the very end of the file.
In the case of a successful creation of an OrderItem
, the log file should contain lines beginning with:
[TIME_STAMP] local.INFO: insert into 'order_items'...
[TIME_STAMP] local.INFO: insert into 'media'...
The media file gets copied to app/public/designs
after insert into 'media'...
has succeeded. Lastly, the uploaded temporary file is deleted from storage/app/livewire-tmp
.
With these insights, you can figure out at what point the problem is occurring. If order_items
has a new entry, but there isn't a matching one in media
, then the process failed before handling the media.
My best guess is that you have a file permissions problem that prevents the copying of storage/app/livewire-tmp/image.png
to app/public/designs/image.png
. And just to be sure, you can try to save an OrderItem
that does not have any media fields so as to establish there isn't any other non-media related issue.
Working with the minimal reproducible example that you supplied, I was able to track down the issue. You have the following implementation of the EditOrderItem::save()
method:
public function save(bool $shouldRedirect = true, bool $shouldSendSavedNotification = true): void
{
Notification::make()
->title('Saved successfully')
->success()
->send();
}
This implementation masks EditRecord::save()
, which is the parent method that should complete the save operation. You need to invoke the parent save()
method so it can do it's job as normal. Here's the code:
public function save(bool $shouldRedirect = true, bool $shouldSendSavedNotification = true): void
{
parent::save($shouldRedirect, $shouldSendSavedNotification);
Notification::make()
->title('Saved successfully')
->success()
->send();
}
This now allows the images to be copied to app/public/designs
as expected.