ekim/media-library

A reusable Laravel Media Library package with Livewire components

Maintainers

Package info

github.com/ekim941/media-library

pkg:composer/ekim/media-library

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

dev-master 2026-01-29 15:48 UTC

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-library and featured-image components
  • 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 HasMedia trait

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.