Hello Friend !
in this tutorial you will see how to upload image with spatie mediaLibrary package.
you will also learn how to upload image,image edit,image delete.today you will see all in one place
I’m pretty sure many of you may have found yourself gotten into the situation where you do not edit,
or delete image with post
Laravel image Upload full crud with spatie mediaLibrary package
- Step 1: Set Up Laravel Project
- Step 2: Set Up Database Details in ENV
- Step 3: Create Model and Migration
- Step 4: Install laravel-medialibrary
- Step 5: Set Up laravel-medialibrary
- Step 6: Perform Crud Operations
Set Up Laravel Project
Installing a fresh new laravel application, so head over to the terminal, type the command, and create a new laravel app.
composer create-project --prefer-dist laravel/laravel laravel_image_crud
Now, You have to move to the project folder:
cd laravel_image_crud
Set Up Database Details in ENV
Now, you have to connect the laravel app to the database, hence open the .env configuration file and add the database credentials as suggested below.
.env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=database_name
DB_USERNAME=database_user_name
DB_PASSWORD=database_password
Create Model and Migration
In the terminal screen, type the recommended command and execute it to generate model and migration files.
php artisan make:model Image -m
You need to add the $fillable array and add the table values app/Models/Image.php file.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Spatie\MediaLibrary\HasMedia\HasMediaTrait;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
class Image extends Model implements HasMedia
{
use HasFactory, InteractsWithMedia;
protected $fillable = [
'name'
];
}
Now , add name in migration file.
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateImagesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('images', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('images');
}
}
Install laravel-medialibrary
in this project we are use 9.0.0 you can use older version if you like
composer require "spatie/laravel-medialibrary:^9.0.0"
Set Up laravel-medialibrary
Now, You need to publish the migration to create the media table:
php artisan vendor:publish --provider="Spatie\MediaLibrary\MediaLibraryServiceProvider" --tag="migrations"
Now,we to migrate
php artisan migrate
Migration table created successfully.
Migrating: 2021_05_18_105041_create_images_table
Migrated: 2021_05_18_105041_create_images_table (21.92ms)
Migrating: 2021_05_18_112243_create_media_table
Migrated: 2021_05_18_112243_create_media_table (45.90ms)
you can see we got new table meadia database/migrations/create_media_table.php file.
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateMediaTable extends Migration
{
public function up()
{
Schema::create('media', function (Blueprint $table) {
$table->bigIncrements('id');
$table->morphs('model');
$table->uuid('uuid')->nullable()->unique();
$table->string('collection_name');
$table->string('name');
$table->string('file_name');
$table->string('mime_type')->nullable();
$table->string('disk');
$table->string('conversions_disk')->nullable();
$table->unsignedBigInteger('size');
$table->json('manipulations');
$table->json('custom_properties');
$table->json('generated_conversions');
$table->json('responsive_images');
$table->unsignedInteger('order_column')->nullable();
$table->nullableTimestamps();
});
}
}
Set Up laravel-medialibrary
Now, you need to add few class laravel-medialibrary (HasMediaTrait , HasMedia, InteractsWithMedia)
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Spatie\MediaLibrary\HasMedia\HasMediaTrait;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
class Image extends Model implements HasMedia
{
use HasFactory, InteractsWithMedia;
protected $fillable = [
'name'
];
}
Now , you need to link storage, so type the command in the terminal and run the command.
php artisan storage:link
Notice: we need to set url path like 8000, or your current server
APP_URL=http://localhost
to
APP_URL=http://localhost:8000
in production you need to your Domain otherwise you are not seen image
Perform Crud Operations
Next, step to generate Controller and routes , so type the command in the terminal and run the command.
php artisan make:controller ImageController -r
Create routes
we are using resource route for save time and much shorter code.
<?php
use App\Http\Controllers\ImageController;
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return view('welcome');
});
Route::resource('images', ImageController::class);
let implements code.
<?php
namespace App\Http\Controllers;
use App\Models\Image;
use Illuminate\Http\Request;
class ImageController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$images = Image::all();
return view('images.index', compact('images'));
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
return view('images.create');
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$this->validate($request, [
'name' => 'required'
]);
$image = Image::create([
'name' => $request->name
]);
if ($image) {
if ($request->hasFile('image')) {
$image->addMediaFromRequest('image')->toMediaCollection('images');
}
}
session()->flash('success', 'Image create successfully');
return redirect()->route('images.index');
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
$image = Image::find($id);
return view('images.edit', compact('image'));
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
$this->validate($request, [
'name' => 'required'
]);
$image = Image::find($id);
$image->name = $request->name;
$image->save();
if ($image) {
if ($request->hasFile('image')) {
$image->clearMediaCollection('images');
$image->addMediaFromRequest('image')->toMediaCollection('images');
}
}
session()->flash('success', 'Image Update successfully');
return redirect()->route('images.index');
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
$image = Image::find($id);
$image->delete();
session()->flash('success', 'Image Delete successfully');
return redirect()->route('images.index');
}
}
On Image Store you can see we are store image toMediaCollection to save file
if ($image) {
if ($request->hasFile('image')) {
$image->addMediaFromRequest('image')->toMediaCollection('images');
}
}
On Update Image you can see we are clear old image using clearMediaCollection first then store new image.
if ($image) {
if ($request->hasFile('image')) {
$image->clearMediaCollection('images');
$image->addMediaFromRequest('image')->toMediaCollection('images');
}
}
Now,let see blade file view/images/index.blade.php.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Laravel image Upload full crud with spatie mediaLibrary package</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container mt-5">
<div class="row">
@if ($message = Session::get('success'))
<div class="alert alert-success alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
{{ $message }}
</div>
@endif
<div class="col-md-12">
<h2>Laravel image Upload full crud with spatie mediaLibrary package</h2>
<div class="card">
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
<a href="{{ route('images.create') }}" class="btn btn-success">Create</a>
<h6 class="m-0 font-weight-bold text-primary">Image List</h6>
</div>
</div>
<table class="table">
<thead>
<tr>
<th>#</th>
<th>Name</th>
<th>Image</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
@foreach ($images as $image)
<tr>
<td>{{ $image->id }}</td>
<td>{{ $image->name }}</td>
<td><img src="{{ $image->getFirstMediaUrl('images') }}" alt="no image" width="100" height="100"></td>
<td>
<a class="btn btn-xs btn-primary" href="{{ route('images.edit',$image->id) }}">
Edit
</a>
</td>
<td>
<form action="{{ route('images.destroy',$image->id) }}" method="POST" onsubmit="return confirm('{{ trans('are You Sure ? ') }}');"
style="display: inline-block;">
<input type="hidden" name="_method" value="DELETE">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<input type="submit" class="btn btn-xs btn-danger" value="Delete">
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>
view/images/index.blade.php
Now,let see blade file view/images/create.blade.php.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Laravel image Upload full crud with spatie mediaLibrary package</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container mt-5">
<div class="row">
<div class="col-md-12">
<h2>Create</h2>
<div class="card">
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
<a href="{{ route('images.create') }}" class="btn btn-success">Create</a>
<h6 class="m-0 font-weight-bold text-primary">Create Image</h6>
</div>
</div>
</div>
</div>
<div class="card-body">
<form action="{{ route("images.store") }}" method="POST" enctype="multipart/form-data">
@csrf
<div class="form-group">
<label for="Name">Name</label>
<input type="text" name="name" class="form-control" placeholder="name">
@if($errors->has('name'))
<strong class="text-danger">{{ $errors->first('name') }}</strong>
@endif
</div>
<div class="form-group">
<div class="mb-3">
<label>image file</label>
<input type="file" name="image" class="form-control">
@if($errors->has('image'))
<strong class="text-danger">{{ $errors->first('image') }}</strong>
@endif
</div>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</div>
</body>
</html>
view/images/create.blade.php
Now,let see blade file view/images/edit.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<title>Laravel image Upload full crud with spatie mediaLibrary package</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container mt-5">
<div class="row">
<div class="col-md-12">
<h2>Edit</h2>
<div class="card">
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
<a href="{{ route('images.create') }}" class="btn btn-success">Create</a>
<h6 class="m-0 font-weight-bold text-primary">Edit Image</h6>
</div>
</div>
</div>
</div>
<div class="card-body">
<form action="{{ route("images.update",$image->id) }}" method="POST" enctype="multipart/form-data">
@csrf
@method('put')
<div class="form-group">
<label for="Name">Name</label>
<input type="text" name="name" class="form-control" placeholder="name"
value="{{ old('name',$image->name )}}">
@if($errors->has('name'))
<strong class="text-danger">{{ $errors->first('name') }}</strong>
@endif
</div>
<div class="form-group">
<div class="mb-3">
<label>image file</label>
<input type="file" name="image" class="form-control">
@if($errors->has('image'))
<strong class="text-danger">{{ $errors->first('image') }}</strong>
@endif
<img src="{{ $image->getFirstMediaUrl('images') }}" alt="no image" width="100" height="100">
</div>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</div>
</body>
</html>
view/images/edit.blade.php
Read Also
Laravel 9 Upload Multiple Image Using Spatie Media Library
How To Upload Multiple Images In Laravel 9 With Intervention
Laravel 9 Upload Multiple Images Tutorial Example
How to update multiple images in laravel 9
Upload Images with Spatie Media Library in Laravel 9