laravel-image maintained by leilaakbari1996
Laravel Image
A lightweight, framework-agnostic image management package for Laravel applications. Attach, validate, store, and manage images for any Eloquent model — without coupling your project to a specific implementation.
Why this package?
Most Laravel projects end up rewriting the same image-upload logic for every model: validation, storage, database records, and cleanup. This package extracts that logic into a single, reusable, and testable layer built around Laravel's Service Container and SOLID principles.
Features
- 🔌 Polymorphic relations — attach images to any Eloquent model without the package knowing what that model is
- 🧩 Contract-based architecture — swap validation or storage logic without touching the core
- ⚙️ Configurable — disk, path, allowed mime types, max size/dimensions, all overridable per project
- 🗑️ Automatic file cleanup — deleting an image record removes the physical file too (configurable)
- ✅ Tested — Pest test suite covering upload, validation, and deletion
Installation
composer require leilaakbari1996/laravel-image
Publish the config file (optional):
php artisan vendor:publish --tag=laravel-image-config
Run the migrations:
php artisan migrate
Usage
1. Add the trait to any model
use Leilaakbari1996\LaravelImage\Traits\HasImages;
class Product extends Model
{
use HasImages;
}
2. Upload an image
use Leilaakbari1996\LaravelImage\Contracts\ImageUploaderContract;
public function store(Request $request, ImageUploaderContract $uploader)
{
$product = Product::create($request->validated());
$image = $uploader->upload($request->file('photo'), $product);
return response()->json(['url' => $image->url]);
}
3. Access images
$product->images; // all images (MorphMany collection)
$product->image(); // first image (e.g. for an avatar-like use case)
$image->url; // full public URL, disk-aware
4. Delete an image
$image->delete(); // also removes the physical file from storage, if configured
Configuration
After publishing, config/laravel-image.php lets you customize:
return [
'table_name' => 'laravel_image_images',
'disk' => env('LARAVEL_IMAGE_DISK', 'public'),
'path' => 'images',
'validation' => [
'allowed_mimes' => ['jpeg', 'jpg', 'png', 'webp', 'gif'],
'max_size' => 5120, // KB
'max_width' => 4000, // px
'max_height' => 4000, // px
],
'delete_file_on_model_delete' => true,
];
Architecture
The package is built around three contracts, so each concern can be swapped independently: