How to Upload Images with Spatie Media Library in LARAVEL 10

Spread the love

Hello Guys,

This guide will walk you through the process of using Spatie Media Library with Laravel 10 to effortlessly upload images in your Laravel application. You’ll also discover how to seamlessly integrate the Spatie Media Library into your Laravel project.

We’ll delve into the world of Laravel Spatie Media Library to create a simple registration form featuring fields for name, email, and avatar image uploads. You’ll gain insights into how to upload avatar images alongside other essential form elements.

Laravel stands out as a remarkable PHP framework, offering robust solutions for building web applications and APIs. While it provides a comprehensive toolkit for web development, it lacks a built-in image upload feature. In this article, we’ll guide you on how to implement image and avatar uploads within a Laravel form using the Spatie Media Library.

To initiate the process of uploading images with Spatie, we’ll begin by setting up the Laravel Media Library in your Laravel project. This library offers a plethora of features, and you can explore its full potential by referring to the official Laravel Media Library documentation. It’s a valuable resource that seamlessly complements Laravel’s expressive development style.

Example of Upload Images with Spatie Media Library:

Also Read: How to Send Mail using Sendgrid API in Laravel 10?

Step 1: Install Laravel App

composer create-project laravel/laravel my-demo-app --prefer-dist

Step 2: Update Your Database Details

Make sure to keep your database information up to date by editing the .env file. This includes adjusting the database name, username, and password as specified.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=your_database_name
DB_USERNAME=root
DB_PASSWORD=

Step 3: Install Spatie Medialibrary Package

If you’re looking to make the most of the basic package, simply follow the provided command. Adding the Media library to your setup is a straightforward process and can be accomplished using Composer.

Also Read: How to Generate SITEMAP in laravel 10

composer require "spatie/laravel-medialibrary:^10.0.0"

To create the database, you need to perform two key steps: initiate a migration and set up a media table.

php artisan vendor:publish --provider="Spatie\MediaLibrary\MediaLibraryServiceProvider" --tag="migrations"

To initiate migrations, you must execute a specific command.

php artisan migrate

Step 4: Set Up Migration and Model File

To efficiently generate both the migration and model files for the “Post” entity, follow the recommended command.

php artisan make:model Post -m

The table schema should be specified within the model file created by the recommended command.

Also Read: How to Get All Routes in Laravel 10

app/Models/Post.php.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Spatie\MediaLibrary\InteractsWithMedia;
use Spatie\MediaLibrary\HasMedia;

class Post extends Model implements HasMedia
{
    use HasFactory, InteractsWithMedia;
    
    protected $fillable = [
        'name',
        'slug',
        'description',
    ];
}

Be sure to include the InteractsWithMedia and HasMedia services. Additionally, add the “implements” keyword to the HasMedia service and declare InteractsWithMedia in the model file, positioning it right beneath HasFactory.

Now, move on to the app/database/migrations/create_posts_table.php file and incorporate the table values into the migration file using a similar approach.

app/database/migrations/create_posts_table.php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePostTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('slug');
            $table->text('description');            
            $table->timestamps();
        });
    }
    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('posts');
    }
}

Step 5: Create a Controller File

php artisan make:controller PostController

In this file, we’ll utilize the PostController class to save a post form while simultaneously uploading images into the database and storing them in the MediaLibrary storage. This action takes place after importing the Post model.

app/Http/Controllers/PostController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Post;

class PostController extends Controller
{
    public function index()
    {    
        $posts= Post::latest()->get();
        return view('index', compact('posts'));
    }
    public function create()
    {
        return view('create');
    }
    
    public function store(Request $request)
    {
        $input = $request->all();
        $post = Post::create($input);
        if($request->hasFile('featured_image') && $request->file('featured_image')->isValid()){
            $post->addMediaFromRequest('featured_image')->toMediaCollection('avatar');
        }
        return redirect()->route('post');
    }
}

Step 6: Add a Route

Once you’ve configured the controller, it’s time to establish new routes to manage the controller’s tasks. Navigate to the ‘routes/web.php‘ file and define the three routes using both the GET and POST methods.

Also Read: How to use One to Many Eloquent Relationship in LARAVEL 10

routes/web.php
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PostController;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
*/

Route::get('post',[PostController::class,'index'])->name('post');
Route::get('post/create',[PostController::class,'create'])->name('post.create');
Route::post('post/store',[PostController::class,'store'])->name('post.store');

Step 7: Create Blade View Files

Our next step is to establish a data presentation file, which will showcase the retrieved posts from the database, thus giving rise to two distinct view files.

To enhance your web interface, we’ll incorporate Bootstrap 5. By creating the form tag and setting the action attribute in line with the designated route, your database will seamlessly populate.

Moving forward, we’ll build ‘create.blade.php,’ and implement the necessary code to optimize the functionality.

app/resources/views/create.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Add Spatie Medialibrary in Laravel 10</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body class="bg-info">
    <div class="container">
        <div class="d-flex p-2 bd-highlight mb-3">
            <a href="{{ route('post') }}" class="btn btn-outline-danger btn-sm">Go Back</a>
        </div>
        <div>
            <form action="{{ route('post.store') }}" enctype="multipart/form-data" method="post">
                @csrf
                <div class="mb-3">
                    <label>Name</label>
                    <input type="text" name="name" class="form-control">
                </div>
                <div class="mb-3">
                    <label>Description</label>
                    <textarea name="description" class="form-control"></textarea>
                </div>
                <div class="mb-3">
                    <label>Image:</label>
                    <input type="file" name="avatar" class="form-control">
                </div>
                <div class="d-grid">
                    <button class="btn btn-primary">Save</button>
                </div>
            </form>
        </div>
    </div>
</body>
</html>
app/resources/views/index.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Integrate Spatie Medialibrary in Laravel 10</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <div class="container">
        <div class="d-flex p-2 bd-highlight mb-3">
            <a href="{{ route('post.create') }}" class="btn btn-dark">Add</a>
        </div>
        <table class="table">
            <thead>
                <tr>
                    <th>#</th>
                    <th>Name</th>
                    <th width="30%">Image</th>
                </tr>
            </thead>
            <tbody>
                @foreach($posts as $key=>$item)
                <tr>
                    <td>{{ ++$key }}</td>
                    <td>{{ $item->name }}</td>
                    <td><img src="{{$item->getFirstMediaUrl('featured_image', 'thumb')}}" width="120px"></td>
                </tr>
                @endforeach
            </tbody>
        </table>
    </div>
</body>
</html>

Step 8: Run your laravel app

The default choice for the public disk is the local driver, and it keeps its files stored in the storage/app/public directory. To enable internet access to these files,

you should create a symbolic link connecting public/storage to storage/app/public.

Also Read: How to use Ajax Autocomplete Search using JQUERY UI in laravel 10

You can utilize the artisan command to create a symbolic link for public access to your storage location.

php artisan storage:link

After finishing the tutorial, use the php artisan command to launch the application:

php artisan serve

This link will enable you to test the app by opening it in a browser.

http://localhost:8000/post or http://127.0.0.1:8000/post

Dive into our collection of Laravel blogs – your go-to source for expert insights.

Leave a Comment