'Error 500 while trying to upload an image using FilePond and Laravel Spatie
I'm trying to create items that have a picture/avatar using a form and insert them into my database, so I decided to use Laravel Spatie with the MediaCollection, but as soon as i implemented the library, I'm getting an error 500 when I submit my form.... any idea why? And how am I supposed to create my database fields so when I create a new item with a picture I submit, the picture is submitted in a "Picture" datatable and in my "item" datatable I have the foreign key "picture_id" referencing to the picture in the Picture datatable.
Item.php:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
class Item extends Model implements HasMedia
{
use HasFactory;
use InteractsWithMedia;
public function inventory_list()
{
return $this->belongsTo(InventoryList::class);
}
public function work_ticket()
{
return $this->belongsToMany(WorkTicket::class);
}
public function picture()
{
return $this->belongsTo(Picture::class);
}
}
ItemController.php:
<?php
namespace App\Http\Controllers;
use App\Models\InventoryList;
use App\Models\Item;
use App\Models\Picture;
use App\Models\TemporaryFile;
use Illuminate\Http\Request;
class ItemController extends Controller
{
public function index()
{
$inventory_lists = InventoryList::all();
$pictures = Picture::all();
return view('add-item', ['inventory_lists' => $inventory_lists,
'pictures' => $pictures]);
}
public function store(Request $request)
{
$item = new Item;
$item->name = $request->name;
$item->state = $request->state;
$item->observations = $request->observations;
$item->list_id = $request->list_id;
$item->picture_id = $request->picture_id;
$temporaryFile = TemporaryFile::where('folder', $request->avatar)->first();
if($temporaryFile){
$item->addMedia(storage_path('app/public/avatars/tmp/' . $request->avatar . '/' . $temporaryFile->filename))
->toMediaCollection('avatars');
rmdir('app/public/avatars/tmp/' . $request->avatar);
$temporaryFile->delete();
}
$item->save();
return redirect('add-item')->with('status', 'Item Form Data Has Been inserted');
}
}
add-item.blade.php:
<!DOCTYPE html>
<html>
<head>
<title>Créer un nouvel item</title>
<meta name="csrf-token" content="{{ csrf_token() }}">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<link href="https://unpkg.com/filepond/dist/filepond.css" rel="stylesheet">
</head>
<body>
<div class="container mt-4">
@if(session('status'))
<div class="alert alert-success">
{{ session('status') }}
</div>
@endif
<div class="card">
<div class="card-header text-center font-weight-bold">
Ajouter un nouvel item
</div>
<div class="card-body">
<form name="add-blog-post-form" id="add-blog-post-form" method="post" action="{{url('store-item')}}">
@csrf
<div class="form-group">
<label for="name">Nom</label>
<input type="text" id="name" name="name" class="form-control" required="">
</div>
<div class="form-group">
<label for="state">État</label>
<input type="text" id="state" name="state" class="form-control" required="">
</div>
<div class="form-group">
<label for="observations">Observations</label>
<textarea name="observations" class="form-control" required=""></textarea>
</div>
<div class="form-group">
Liste d'inventaire
<select name="list_id" class="form-control select2-multiple">
<option value=""></option>
@foreach($inventory_lists as $inventory_list)
<option value="{{$inventory_list->id}}">
{{$inventory_list->name}}
</option>
@endforeach
</select>
</div>
<div>
<label for="avatar">Photo</label>
<input type="file" name="avatar" id="avatar">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</div>
@section('scripts')
<script>
const inputElement = document.querySelector('input[id="avatar"]');
const pond = FilePond.create( inputElement );
FilePond.setOptions({
server: {
url: '/upload',
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}'
}
}
});
</script>
@endsection
</div>
<script src="https://unpkg.com/filepond/dist/filepond.js"></script>
@yield('scripts')
</body>
</html>
UploadController.php
<?php
namespace App\Http\Controllers;
use App\Models\TemporaryFile;
use Illuminate\Http\Request;
class UploadController extends Controller
{
public function store(Request $request)
{
if ($request->hasFile('avatar')) {
$file = $request->file('avatar');
$filename = $file->getClientOriginalName();
$folder = uniqid() . '-' .now()->timestamp;
$file->storeAs('avatars/tmp/' . $folder, $filename);
TemporaryFile::create([
'folder' => $folder,
'filename' => $filename
]);
return $folder;
}
return '';
}
}
2022_05_06_063218_create_temporary_files_table.php:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('temporary_files', function (Blueprint $table) {
$table->id();
$table->string('folder');
$table->string('filename');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('temporary_files');
}
};
Thanks in advance
Edit:
I got this error right before getting my Error 500, then I simply refreshed my page and I never got the following error again, just an error 500.
local.ERROR: Declaration of Spatie\MediaLibrary\MediaCollections\Models\Collections\MediaCollection::jsonSerialize() must be compatible with Illuminate\Support\Collection::jsonSerialize(): array {"exception":"[object] (Symfony\Component\ErrorHandler\Error\FatalError(code: 0): Declaration of Spatie\MediaLibrary\MediaCollections\Models\Collections\MediaCollection::jsonSerialize() must be compatible with Illuminate\Support\Collection::jsonSerialize(): array at /home/vagrant/code/vendor/spatie/laravel-medialibrary/src/MediaCollections/Models/Collections/MediaCollection.php:51) [stacktrace] #0 {main}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
