leilaakbari1996 / laravel-image
A reusable image management package for Laravel applications.
Requires
- php: ^8.2
- illuminate/database: ^10.0|^11.0|^12.0
- illuminate/http: ^10.0|^11.0|^12.0
- illuminate/support: ^10.0|^11.0|^12.0
Requires (Dev)
- orchestra/testbench: ^8.0|^9.0|^10.0
- pestphp/pest: ^2.0|^3.0
- pestphp/pest-plugin-laravel: ^2.0|^3.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
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: