Last active
July 19, 2024 07:53
-
-
Save prpanto/8215cada420b98c6d41ad363c81eae73 to your computer and use it in GitHub Desktop.
Upload image with Laravel, Inertia, Vue, Filepond and Media Library
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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']; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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()); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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'); | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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 | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you! It saved me a lot of time