ekim / media-library
A reusable Laravel Media Library package with Livewire components
Requires
- php: ^8.1
- illuminate/support: ^10.0|^11.0
- intervention/image: ^2.7|^3.0
- livewire/livewire: ^2.11|^3.0
This package is auto-updated.
Last update: 2026-03-29 01:14:14 UTC
README
A reusable Laravel Media Library package with Livewire components for managing file uploads, images, and documents.
Features
- Livewire Components: Ready-to-use
media-libraryandfeatured-imagecomponents - Image Processing: Automatic thumbnail generation with configurable sizes
- File Management: Upload, organize, and manage images and documents
- Authorization: Flexible authorization system with gate-based or custom authorization
- Configurable: Extensive configuration options for storage, file types, sizes, and more
- Morphable Relationships: Attach media to any model using the
HasMediatrait
Requirements
- PHP 8.1+
- Laravel 10.x or 11.x
- Livewire 2.11+ or 3.x
- Intervention Image 2.7+ or 3.x
Installation
Via Composer (from Packagist)
composer require ekim/media-library
Via Path Repository (for local development)
Add to your composer.json:
{
"repositories": [
{
"type": "path",
"url": "packages/ekim/media-library"
}
]
}
Then require the package:
composer require ekim/media-library:@dev
Run the Install Command
php artisan media-library:install
This will publish:
- Configuration file
- Migration file
- Asset files (file type icons)
Run Migrations
php artisan migrate
Configuration
After installation, you can customize the package by editing config/media-library.php:
return [ // Storage disk for media files 'disk' => 'public', // Base storage path 'path' => 'media', // User model class 'user_model' => 'App\\Models\\User', // Media model class (extend for customization) 'media_model' => 'Ekim\\MediaLibrary\\Models\\Media', // Allowed file types 'allowed_types' => [ 'images' => ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'svg', 'webp'], 'documents' => ['doc', 'docx', 'pdf', 'txt', 'xls', 'xlsx'], ], // Maximum file size in KB (default: 10MB) 'max_file_size' => 10240, // Image thumbnail sizes 'image_sizes' => [ 'large' => ['width' => 822, 'height' => 463, 'method' => 'fit'], 'medium' => ['width' => 392, 'height' => 220, 'method' => 'fit'], 'small' => ['width' => 118, 'height' => 66, 'method' => 'fit'], ], // Authorization settings 'authorization' => [ 'gate' => 'manage-media', 'class' => null, // Custom authorization class ], // Pagination settings 'pagination' => [ 'per_page' => 50, 'options' => [50, 100], ], ];
Authorization
Using Gates (Recommended)
Define a gate in your AuthServiceProvider:
use Illuminate\Support\Facades\Gate; public function boot(): void { Gate::define('manage-media', function ($user) { return $user->isAdmin() || $user->isEditor(); }); }
Using Custom Authorization
Create a custom authorization class implementing MediaAuthorizationInterface:
use Ekim\MediaLibrary\Contracts\MediaAuthorizationInterface; class CustomMediaAuthorization implements MediaAuthorizationInterface { public function canManageMedia(?Authenticatable $user): bool { // Your custom logic } public function canUpload(?Authenticatable $user): bool { // Your custom logic } public function canDelete(?Authenticatable $user, $media): bool { // Your custom logic } public function canEdit(?Authenticatable $user, $media): bool { // Your custom logic } }
Then update your config:
'authorization' => [ 'class' => App\Services\CustomMediaAuthorization::class, ],
Usage
Basic Media Library Component
@livewire('media-library')
With Selection Button
@livewire('media-library', ['buttonText' => 'Select Image'])
Featured Image Component
@livewire('featured-image', ['model' => $post])
With custom button text:
@livewire('featured-image', ['model' => $post, 'buttonText' => 'Choose Image'])
Using the HasMedia Trait
Add the trait to your models:
use Ekim\MediaLibrary\Traits\HasMedia; class Post extends Model { use HasMedia; }
Then you can use:
// Get the featured image $post->image; // Get all media $post->media; // Set featured image $post->setFeaturedImage($mediaId); // Remove featured image $post->removeFeaturedImage(); // Attach media $post->attachMedia($mediaId); // Check if has featured image $post->hasFeaturedImage(); // Get media count $post->getMediaCount();
Accessing Media Properties
$media = Media::find(1); // URLs $media->url; // Original file URL $media->large; // Large thumbnail URL $media->medium; // Medium thumbnail URL $media->small; // Small thumbnail URL $media->thumbnail; // Auto-selected thumbnail (small for images, icon for docs) // Get specific size $media->getSize('large'); // Check type $media->isImage(); $media->isDocument(); // Scopes Media::images()->get(); Media::documents()->get(); Media::forUser($userId)->get(); Media::search('filename')->get();
Customizing Views
Publish the views:
php artisan vendor:publish --tag=media-library-views
Views will be copied to resources/views/vendor/media-library/.
Extending the Media Model
Create your own Media model:
namespace App\Models; use Ekim\MediaLibrary\Models\Media as BaseMedia; class Media extends BaseMedia { // Add custom methods or override existing ones }
Update your config:
'media_model' => App\Models\Media::class,
Custom Image Processing
Create a custom image processor implementing ImageProcessorInterface:
use Ekim\MediaLibrary\Contracts\ImageProcessorInterface; class CustomImageProcessor implements ImageProcessorInterface { public function process($image, string $directory, string $filename, string $extension): array { // Your custom processing logic } public function createSize($image, string $path, int $width, int $height, string $method = 'fit'): string { // Your custom size creation logic } }
Bind it in a service provider:
$this->app->bind(ImageProcessorInterface::class, CustomImageProcessor::class);
Events
The package emits Livewire events that you can listen to:
mediaSelected- When a media item is selected (with button)updateLibrary- When the library should be refreshed
License
MIT License. See LICENSE for more information.