How to upload & retrieve images by Laravel media library

Upload and retrieve by Laravel media library

Using the Laravel-media library package for handling media via Restful API makes it a piece of cake and a time saver. That is what we will learn in today’s tutorial.

I was coding an e-commerce dashboard in Laravel, Vue 3, and Bootstrap 5. The backend in this project is separated from the frontend and they are connected via RESTful API. And I want to create a product gallery. In fact, I wanted to use modern technics and ways to improve my skills. After a few searches, I decided that the Laravel-media library package would be a good choice for the backend and handling of the images. So let’s see how I use it.

Setting up Laravel-media library

We will install the package via composer as the following

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

I have faced a bug with Laravel-media library 10.0.0. So I upgraded to 10.0.7 and It works well for me. After that, we need to publish the migration files and migrate them.

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

I use the default setting for the package. In order to use it with your model, we need to add a couple of codes. In my case, the model will be “Product”. So my “Model\Product.php” file will be as the following.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;

class Product extends Model implements HasMedia
{
    use InteractsWithMedia;
    use HasFactory;

    protected $guarded =['id'];


    public function getGalleryAttribute()
   {
    $mediaItems = $this->getMedia('product_images');
    $gallery = [];
    if(!empty($mediaItems)){
       foreach($mediaItems as $image){
        array_push($gallery, $image->getUrl());
       }
    }
    return  $gallery;
   }
}
  • We associate our model with the package interface HasMedia and its trait InteractsWithMedia.
  • Also, we create a new attribute for the model so it can get us all the images Urls when we use $product->gallery as an array.

Now, Our model is ready to use.

Handling Images upload in Laravel controller.

For uploading the images, We need to create a route for receiving the uploading form request. Besides, the controller method for handling the form. And the Laravel-media library will handle the rest under the hood. And by default, the media library will store its files on Laravel’s public disk.

I suppose that you know how to create a route. So let’s see how the controller method will be.

public function store(ProductStoreRequest $request)
    {
//saving data
     $data = $request->validated();
     $product = Product::create($data);

// check if $request->gallery array has images. if true, we save them
    if($request->gallery){

       foreach($request->gallery as $image ){
        $product->addMedia($image) >toMediaCollection('product_images');
       }
    }

//sending the model data to the frontend
     $product->refresh();  
     $success['data'] =  new ProductResource($product);

    $success['success'] = true;
    return response()->json($success, 200);
   }
  • We validated the data via ProductStoreRequest
  • After that, we checked if $request has the gallery array of files then we run foreach statement to save files in product_images collection.
  • Then, we send back the model data in ProductResource($product)

To validate the gallery array we can use the below code in the rules function in the form request validation class ProductStoreRequest

 public function rules()
    {
        return [
              //
             'gallery.*' => ['image','mimes:jpg,png,jpeg,webp','max:2048'],
            //
        ];
    }

Finally, in your resource collection ProductResource we can retrieve the images URLs via 'gallery' => $this->gallery as the following.

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

use  App\Models\Product;
class ProductResource extends JsonResource
{
    
    public function toArray($request)
    {
        return [
            'id' => $this->id,

            'name' => $this->name,
            //

            'gallery' => $this->gallery

            //
        ];
    }
}

That’s all we need to upload and retrieve media in Laravel.