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 traitInteractsWithMedia
. - 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 thegallery
array of files then we runforeach
statement to save files inproduct_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.