atikhasan2090 / laravel-media-gallery
A modern, professional, and UX-friendly Laravel File Manager & Media Gallery package with polymorphic image reuse, rich metadata (alt text, title, captions), and Blade & Vue.js components.
Package info
github.com/atikhasan2090/laravel-media-gallery
pkg:composer/atikhasan2090/laravel-media-gallery
Requires
- php: ^8.0 || ^8.1 || ^8.2 || ^8.3
- illuminate/contracts: ^8.0 || ^9.0 || ^10.0 || ^11.0
- illuminate/database: ^8.0 || ^9.0 || ^10.0 || ^11.0
- illuminate/filesystem: ^8.0 || ^9.0 || ^10.0 || ^11.0
- illuminate/http: ^8.0 || ^9.0 || ^10.0 || ^11.0
- illuminate/routing: ^8.0 || ^9.0 || ^10.0 || ^11.0
- illuminate/support: ^8.0 || ^9.0 || ^10.0 || ^11.0
- illuminate/view: ^8.0 || ^9.0 || ^10.0 || ^11.0
- intervention/image: ^2.7 || ^3.0
Requires (Dev)
- larastan/larastan: ^2.0
- mockery/mockery: ^1.4
- orchestra/testbench: ^6.0 || ^7.0 || ^8.0 || ^9.0
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^9.5 || ^10.0 || ^11.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-21 04:27:41 UTC
README
A modern, highly performant, and UX-friendly Media Gallery & File Manager package for Laravel. Designed as a drop-in, modern replacement for legacy file managers like unisharp/laravel-filemanager, offering polymorphic image reuse across any model, rich SEO metadata (Alt Text, Title, Captions), and zero-conflict Blade & Vue.js components.
๐ Key Features
- Infinite Image Reuse: Upload an image once and attach it anywhere (Products, Categories, Logos, Banners, Blog Posts, POS Quick-Buttons, User Avatars).
- SEO & Accessibility Ready: Manage Alt Text, Title, Caption, and Description with live inline auto-saving.
- Universal Component Support:
- Blade Component:
<x-media-gallery-picker>with instant thumbnail preview and remove button. - Vue.js Component:
<media-picker>supporting both Vue 2 and Vue 3. - Direct JavaScript API:
window.MediaGallery.open({...})for custom triggers, TinyMCE, CKEditor, Summernote, and TipTap.
- Blade Component:
- Zero CSS Conflicts: All styles are strictly scoped under
.lmg-*prefixes. Safely use it alongside Bootstrap 4/5, Tailwind CSS, or Element UI without broken layouts. - SaaS / Multi-Tenancy Ready: Automatically scopes media files and folders per tenant or user.
- Smart Image Transformation: Automatic thumbnail generation (thumb, medium, large), optional WebP conversion, and in-browser cropping/resizing.
- Folders & Organization: Create and manage folders to keep assets clean and organized.
- Drag & Drop Upload: Multi-file queue with real-time percentage progress bars.
๐ฆ Requirements
- PHP:
^8.0 || ^8.1 || ^8.2 || ^8.3 - Laravel Framework:
^8.0 || ^9.0 || ^10.0 || ^11.0
๐ ๏ธ Installation
1. Require via Composer
Once published to Packagist:
composer require atikhasan2090/laravel-media-gallery
Testing locally in your existing project before publishing: In your application's
composer.json(e.g. inakaar-pos-blade), add a path repository:"repositories": [ { "type": "path", "url": "../../../My Personal Projects/laravel-media-gallery" } ]Then run:
composer require atikhasan2090/laravel-media-gallery:dev-master
2. One-Command Setup
Run the interactive installer to publish the config, migrations, and assets:
php artisan media-gallery:install
Or publish manually:
php artisan vendor:publish --provider="Atikhasan\MediaGallery\MediaGalleryServiceProvider" --tag="media-gallery-config" php artisan vendor:publish --provider="Atikhasan\MediaGallery\MediaGalleryServiceProvider" --tag="media-gallery-migrations" php artisan vendor:publish --provider="Atikhasan\MediaGallery\MediaGalleryServiceProvider" --tag="media-gallery-assets" php artisan storage:link php artisan migrate
๐จ Asset Setup
Add the styles and scripts to your admin layout (e.g. resources/views/layouts/app.blade.php):
<head> <!-- Your existing CSS (Bootstrap, Tailwind, etc.) --> @mediaGalleryStyles </head> <body> <!-- Your Admin Content --> <!-- Before closing body tag --> @mediaGalleryScripts </body>
๐ฅ๏ธ Usage in Blade Forms
Single Image Picker (e.g., Category Image, Logo, Avatar)
<x-media-gallery-picker name="image_id" :value="$category->image_id" label="Category Image" />
Multiple Image Picker (e.g., Product Gallery)
<x-media-gallery-picker name="gallery_images" :value="$product->getMedia('gallery')->pluck('id')->toArray()" multiple="true" label="Product Gallery" />
โก Usage in Vue.js (Vue 2 & Vue 3)
Import and register the component in your app.js:
import MediaPicker from 'path-to-vendor/laravel-media-gallery/resources/js/components/MediaPicker.vue'; // Vue 2 Vue.component('media-picker', MediaPicker); // Or Vue 3 app.component('media-picker', MediaPicker);
Then in your Vue template:
<!-- Single Image --> <media-picker v-model="form.thumbnail_id" label="Product Thumbnail" :preview="form.thumbnail_url" /> <!-- Multiple Images --> <media-picker v-model="form.gallery_ids" :multiple="true" label="Product Gallery Images" />
๐๏ธ Eloquent Model Integration (HasMedia Trait)
Add the HasMedia trait to any Model:
namespace App\Models; use Illuminate\Database\Eloquent\Model; use Atikhasan\MediaGallery\Traits\HasMedia; use Atikhasan\MediaGallery\Contracts\HasMediaInterface; class Product extends Model implements HasMediaInterface { use HasMedia; // ... }
Attaching & Managing Media:
// Attach a single thumbnail $product->attachMedia($request->thumbnail_id, 'thumbnail'); // Sync multiple gallery images (replaces existing under 'gallery') $product->syncMedia($request->gallery_ids, 'gallery'); // Retrieve media $thumbnailUrl = $product->getFirstMediaUrl('thumbnail'); // Full URL $mediumThumb = $product->getFirstMediaUrl('thumbnail', 'medium'); // Medium size $altText = $product->getFirstMediaAlt('thumbnail', 'Default Product Title'); // Retrieve all gallery items $galleryItems = $product->getMedia('gallery'); foreach ($galleryItems as $media) { echo $media->url; echo $media->alt_text; } // Detach media $product->detachMedia(null, 'gallery'); // Detach all gallery images
๐ผ๏ธ WebP Conversion & Image Optimization
Automatic WebP conversion can be enabled in config/media-gallery.php or via .env:
MEDIA_GALLERY_AUTO_WEBP=true
When enabled, uploaded JPG, JPEG, and PNG images are automatically encoded to WebP and stored alongside the original asset. The WebP URL is available via:
$media->getUrl('webp');
๐ Permissions & Authorization
Granular permissions can be configured in config/media-gallery.php:
'permissions' => [ 'upload' => fn($user) => $user->can('upload-media'), 'delete' => fn($user) => $user->hasRole('admin'), 'create_folder' => null, // defaults to authenticated user (Auth::check()) 'update_metadata' => null, 'crop' => null, ],
โ ๏ธ SVG Policy & Security
By default, svg files are disabled in allowed_extensions and allowed_image_extensions to prevent stored Cross-Site Scripting (XSS) attacks.
If you opt-in to SVG uploads, add 'svg' back to your config/media-gallery.php arrays and ensure SVG content is sanitized using a library like enshrined/svg-sanitize.
๐ ๏ธ Asset Development & Build Script
The published assets in public/ are generated from source files in resources/. Do not edit files in public/ directly.
To rebuild published assets after modifying resources/js or resources/css:
./scripts/build-assets.sh
๐ JavaScript API (WYSIWYG / Custom Triggers)
You can trigger the media picker from any button, WYSIWYG editor (TinyMCE, CKEditor, Summernote), or script:
window.MediaGallery.open({ multiple: false, onSelect: function(item) { console.log('Selected Media:', item); // item contains: // item.id // item.url // item.thumbnail_url // item.alt_text // item.title // item.readable_size } });
๐ข SaaS & Multi-Tenancy Configuration
In config/media-gallery.php:
'multi_tenancy' => [ 'enabled' => true, 'tenant_column' => 'tenant_id', 'tenant_resolver' => function() { return auth()->user()->tenant_id; }, 'scope_by_user' => false, ],
When enabled, uploaded media and folders are completely isolated per tenant.
๐ Standalone Media Manager
Users can access the full standalone dashboard by navigating to:
http://your-app.test/media-gallery
(Route prefix and middleware are fully customizable in config/media-gallery.php).
๐งช Testing & Static Analysis
Run tests:
composer test
Run PHPStan level 5 static analysis:
composer analyse
๐ License
The MIT License (MIT). Please see LICENSE.md for more details.