Skip to content

Instantly share code, notes, and snippets.

@prpanto
Last active June 20, 2024 15:00
Show Gist options
  • Save prpanto/8215cada420b98c6d41ad363c81eae73 to your computer and use it in GitHub Desktop.
Save prpanto/8215cada420b98c6d41ad363c81eae73 to your computer and use it in GitHub Desktop.
Upload image with Laravel, Inertia, Vue, Filepond and Media Library
<?php
namespace App\Models;
use Spatie\MediaLibrary\HasMedia;
use Illuminate\Database\Eloquent\Model;
use Spatie\MediaLibrary\InteractsWithMedia;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Image extends Model implements HasMedia
{
use HasFactory, InteractsWithMedia;
protected $fillable = ['user_id'];
}
<?php
namespace App\Http\Controllers;
use Inertia\Inertia;
use App\Models\Image;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
class ImageController extends Controller
{
public function index()
{
$images = Image::where('user_id', auth()->id())->get();
return Inertia::render('Image/Index', ['images' => $images->map(function ($image) {
return [
'source' => $image->getMedia()[0]->getFullUrl(),
'options' => [
'type' => 'local'
]
];
})]);
}
public function store(Request $request)
{
$image = Image::create(['user_id' => auth()->id()]);
$image->addMedia($request->image, 'images')
->usingName(Str::random(10))
->toMediaCollection();
return redirect()->back();
}
public function revert(Request $request)
{
Storage::disk('images')->delete($request->getContent());
}
}
<?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('images', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('images');
}
};
<template>
<filepond
name="image"
ref="filepondRef"
label-idle="Upload your images..."
:allow-multiple="true"
accepted-file-types="image/*"
:files="images"
/>
</template>
<script setup>
import { ref } from 'vue';
import vueFilePond, { setOptions } from "vue-filepond";
import FilePondPluginFileValidateType from "filepond-plugin-file-validate-type";
import FilePondPluginImagePreview from "filepond-plugin-image-preview";
import { usePage } from '@inertiajs/inertia-vue3'
import axios from 'axios';
import 'filepond/dist/filepond.min.css';
import "filepond-plugin-image-preview/dist/filepond-plugin-image-preview.min.css";
const props = defineProps({
images: Object
});
const page = usePage();
const filepondRef = ref();
const images = ref([]);
const filepond = vueFilePond(
FilePondPluginFileValidateType,
FilePondPluginImagePreview
);
setOptions({
server: {
load: (source, load, error, progress, abort, headers) => {
axios.post(route('image.store')).then(res => res.blob()).then(load);
},
process: route('image.store'),
revert: route('image.revert'),
headers: { 'X-CSRF-TOKEN': page.props.value.token }
},
files: props.images
});
@gr1zix
Copy link

gr1zix commented Nov 21, 2023

Thank you! It saved me a lot of time

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment