devanderson/filament-media-gallery
Composer 安装命令:
composer require devanderson/filament-media-gallery
包简介
A comprehensive media gallery plugin for Filament with image editing, video support, and thumbnail generation.
关键字:
README 文档
README
A complete media gallery plugin for Filament v4 with support for image and video uploads, integrated image editor, automatic video thumbnail generation, and much more.
🌟 Features
- ✅ Image Uploads - Support for JPG, PNG, WebP, GIF
- ✅ Video Uploads - Support for MP4, WebM, OGG
- ✅ Image Editor - Integrated editor with Cropper.js
- ✅ Video Thumbnails - Automatic generation using FFmpeg
- ✅ Paginated Gallery - Intuitive and responsive interface
- ✅ Dark Mode - Complete support for dark mode
- ✅ Multiple Selections - Select one or multiple media items
- ✅ Fully Configurable - Customize everything via config file
- ✅ Internationalization - Support for multiple languages
📋 Requirements
- PHP 8.1 or higher
- Laravel 11.0 or higher
- Filament 4.0 or higher
- FFmpeg (optional, for video thumbnails)
📦 Installation
1. Install via Composer
composer require devanderson/filament-media-gallery
2. Publish Migrations
php artisan vendor:publish --tag="filament-media-gallery-migrations"
php artisan migrate
3. Publish Configuration (Optional)
php artisan vendor:publish --tag="filament-media-gallery-config"
🚀 Basic Usage
Understanding the Component
The GalleryMediaField is a custom Filament form component designed to browse and select one or more media items (images or videos) from a pre-existing gallery. It stores the IDs of the selected media, which are then used to create a many-to-many relationship between your primary model and the media models (Image, Video) provided by the gallery package.
Step 1: Add the Component to Your Form
Add GalleryMediaField to your Filament form schema. You must specify the mediaType and a name for the field that will hold the selected IDs.
use Devanderson\FilamentMediaGallery\Forms\Components\GalleryMediaField; // In your Form schema GalleryMediaField::make('videos_ids') ->mediaType('video') ->allowMultiple() ->columnSpanFull()
Field Configuration:
make('videos_ids'): Defines the field name that will hold an array of selected video IDs. Use a different name likeimages_idsfor images.mediaType('video'): Specifies the type of media to display in the gallery. Use'image'for images.allowMultiple(): Allows the user to select more than one item.
Step 2: Create Pivot Tables
A many-to-many relationship requires a "pivot" table to link your model with the media model. You need one pivot table for each media type you want to associate.
Image Pivot Table Migration
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { public function up(): void { Schema::create('project_image_image', function (Blueprint $table) { // Foreign key to your primary model's table $table->foreignId('project_image_id')->constrained()->onDelete('cascade'); // Foreign key to the package's images table $table->foreignId('image_id')->constrained('images')->onDelete('cascade'); // Primary key to prevent duplicates $table->primary(['project_image_id', 'image_id']); }); } public function down(): void { Schema::dropIfExists('project_image_image'); } };
Video Pivot Table Migration
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { public function up(): void { Schema::create('project_image_video', function (Blueprint $table) { $table->foreignId('project_image_id')->constrained()->onDelete('cascade'); $table->foreignId('video_id')->constrained('videos')->onDelete('cascade'); $table->primary(['project_image_id', 'video_id']); }); } public function down(): void { Schema::dropIfExists('project_image_video'); } };
Step 3: Define Model Relationships
In your primary model, define the belongsToMany relationship for each media type. You must specify the custom pivot table name as the second argument.
<?php namespace App\Models; use Devanderson\FilamentMediaGallery\Models\Image; use Devanderson\FilamentMediaGallery\Models\Video; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsToMany; class ProjectImage extends Model { protected $fillable = [ 'title', 'description', // ... other fields ]; /** * Defines the many-to-many relationship with the Image model. * The second argument is the name of our pivot table. */ public function images(): BelongsToMany { return $this->belongsToMany(Image::class, 'project_image_image'); } /** * Defines the many-to-many relationship with the Video model. * The second argument is the name of our pivot table. */ public function videos(): BelongsToMany { return $this->belongsToMany(Video::class, 'project_image_video'); } }
Step 4: Integrate with Filament Resource Pages
To make the component work properly, you need to add logic to your Filament CreateRecord and EditRecord pages to handle saving and loading the relationship data.
Using the ProcessUploadGallery Trait
The package provides a convenient trait that handles all the synchronization logic:
CreateRecord Page:
<?php namespace App\Filament\Resources\ProjectImageResource\Pages; use App\Filament\Resources\ProjectImageResource; use Filament\Resources\Pages\CreateRecord; use Devanderson\FilamentMediaGallery\Traits\ProcessUploadGallery; class CreateProjectImage extends CreateRecord { use ProcessUploadGallery; protected static string $resource = ProjectImageResource::class; }
EditRecord Page:
<?php namespace App\Filament\Resources\ProjectImageResource\Pages; use App\Filament\Resources\ProjectImageResource; use Filament\Resources\Pages\EditRecord; use Devanderson\FilamentMediaGallery\Traits\ProcessUploadGallery; class EditProjectImage extends EditRecord { use ProcessUploadGallery; protected static string $resource = ProjectImageResource::class; /** * Load existing relationship IDs into form fields before filling the form */ protected function mutateFormDataBeforeFill(array $data): array { // Load images IDs $data['images_ids'] = $this->record->images()->pluck('images.id')->toArray(); // Load videos IDs $data['videos_ids'] = $this->record->videos()->pluck('videos.id')->toArray(); return $data; } }
What the Trait Does:
afterCreatehook: Synchronizes the selected media IDs with the model relationships after creating a new recordafterSavehook: Synchronizes the selected media IDs when editing an existing record
Complete Form Example
<?php namespace App\Filament\Resources\ProjectImageResource; use Filament\Forms; use Filament\Forms\Form; use Devanderson\FilamentMediaGallery\Forms\Components\GalleryMediaField; class ProjectImageForm { public static function form(Form $form): Form { return $form ->schema([ Forms\Components\TextInput::make('title') ->required() ->maxLength(255), Forms\Components\Textarea::make('description') ->rows(3) ->columnSpanFull(), // Gallery field for images GalleryMediaField::make('images_ids') ->label('Gallery Images') ->mediaType('image') ->allowMultiple() ->columnSpanFull(), // Gallery field for videos GalleryMediaField::make('videos_ids') ->label('Gallery Videos') ->mediaType('video') ->allowMultiple() ->columnSpanFull(), ]); } }
📝 Advanced Usage Examples
Single Image Selection (Avatar, Cover, etc)
GalleryMediaField::make('avatar_id') ->label('Profile Picture') ->mediaType('image') ->allowMultiple(false) ->required()
Limited Selection with Max Items
GalleryMediaField::make('featured_images') ->label('Featured Images') ->mediaType('image') ->allowMultiple() ->maxItems(5)
Video Gallery
GalleryMediaField::make('videos_ids') ->label('Video Gallery') ->mediaType('video') ->allowMultiple() ->maxItems(10)
⚙️ Configuration
The config/filament-media-gallery.php file offers various options:
return [ // Storage disk 'disk' => env('MEDIA_GALLERY_DISK', 'public'), // Storage path 'path' => env('MEDIA_GALLERY_PATH', 'gallery'), // Image settings 'image' => [ 'allowed_extensions' => ['jpg', 'jpeg', 'png', 'gif', 'webp'], 'max_size' => 10240, // KB 'editor' => [ 'enabled' => true, 'aspect_ratios' => ['16:9', '4:3', '1:1', '9:16'], ], ], // Video settings 'video' => [ 'allowed_extensions' => ['mp4', 'webm', 'ogg'], 'max_size' => 102400, // KB 'thumbnail' => [ 'enabled' => true, 'time' => 1.0, 'width' => 640, ], ], // Gallery pagination 'gallery' => [ 'per_page' => 24, 'allow_multiple' => true, 'max_items' => null, ], ];
🎬 FFmpeg Setup (Video Thumbnails)
To enable automatic thumbnail generation for videos, install FFmpeg:
Ubuntu/Debian
sudo apt-get install ffmpeg
macOS
brew install ffmpeg
Windows
Download from: https://ffmpeg.org/download.html
Configure in .env
FFMPEG_PATH=/usr/bin/ffmpeg FFPROBE_PATH=/usr/bin/ffprobe
⚠️ Important Notes
Modal Forms Limitation
This implementation has been designed for use in standard Filament CreateRecord and EditRecord pages. It has not been tested within the context of modal forms (e.g., createOptionForm or editOptionForm inside a Select component). Using this component in modals may require additional adjustments to correctly handle the component's state and data flow.
Relationship Synchronization
The ProcessUploadGallery trait automatically handles the synchronization of media relationships. It:
- Extracts field names ending with
_idsfrom the form data - Converts field names to relationship names (e.g.,
videos_ids→videos) - Syncs the selected IDs with the corresponding relationship
- Removes the temporary
_idsfields from the saved data
🌍 Internationalization
The plugin includes translations for:
- 🇧🇷 Portuguese (pt_BR)
- 🇺🇸 English (en)
To add new translations:
php artisan vendor:publish --tag="filament-media-gallery-translations"
🧪 Testing
composer test
📝 Changelog
See CHANGELOG for more information about recent changes.
🤝 Contributing
Contributions are welcome! See CONTRIBUTING for details.
🔒 Security
If you discover security issues, please email security@example.com.
📄 License
The MIT License (MIT). See License File for more information.
🙏 Credits
💡 Support
- 📖 Documentation
- 🐛 Issues
- 💬 Discussions
devanderson/filament-media-gallery 适用场景与选型建议
devanderson/filament-media-gallery 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 2 次下载、GitHub Stars 达 1, 最近一次更新时间为 2025 年 12 月 10 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「media」 「image」 「upload」 「thumbnail」 「video」 「laravel」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 devanderson/filament-media-gallery 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 devanderson/filament-media-gallery 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 devanderson/filament-media-gallery 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
The file manager intended for using Laravel with CKEditor / TinyMCE / Colorbox
Simple Sharing generates social media share links within CP entry pages, allowing you to quickly & easily share entries.
Yii2 LightBox image galary widget uses Lightbox v2.10.0 by Lokesh Dhakar
The Yii2 extension uses jQuery jquery.carousel-1.1.min.js and makes image carousel from php array of structure defined.
The Yii2 extension uses jQuery PrettyPhoto and OwlCarousel js and makes image galary from php array of structure defined.
Laravel Media Popup to upload/view the files
统计信息
- 总下载量: 2
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 1
- 点击次数: 24
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-12-10