Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Medialibrary Laravel Package

spatie/laravel-medialibrary

Attach and manage files on Eloquent models with an easy API. Handle uploads, store media on any Laravel filesystem (local, S3, etc.), organize collections, and generate image/PDF conversions and manipulations with built-in support for responsive images.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require spatie/laravel-medialibrary
    

    Publish the config and migrations:

    php artisan vendor:publish --provider="Spatie\MediaLibrary\MediaLibraryServiceProvider" --tag="medialibrary-config"
    php artisan migrate
    
  2. Model Setup: Use the HasMedia trait and RegistersMediaConversions trait in your Eloquent model:

    use Spatie\MediaLibrary\HasMedia;
    use Spatie\MediaLibrary\InteractsWithMedia;
    use Spatie\MediaLibrary\RegistersMediaConversions;
    
    class Post extends Model
    {
        use HasMedia, InteractsWithMedia, RegistersMediaConversions;
    
        // ...
    }
    
  3. First Upload: Attach a file to a model in a controller or form handler:

    $post = Post::find(1);
    $post->addMedia($request->file('image'))->toMediaCollection('images');
    

Key First Use Cases

  • Basic Upload: Store files in default collection (default).
  • Custom Collections: Organize files by context (e.g., thumbnails, documents).
  • Direct File Handling: Use addMedia() with a UploadedFile from a request.

Implementation Patterns

Core Workflows

  1. Adding Media:

    // From a file path
    $model->addMedia($path)->toMediaCollection('collection_name');
    
    // From a request file
    $model->addMedia($request->file('file'))->toMediaCollection('collection_name');
    
    // With custom disk (e.g., S3)
    $model->addMedia($file)->toMediaCollection('collection_name', 's3');
    
  2. Retrieving Media:

    // Get first media in collection
    $model->getFirstMedia('images');
    
    // Get all media in collection
    $model->getMedia('images');
    
    // Get media URL
    $model->getFirstMediaUrl('images');
    
    // Get converted media (e.g., thumbnail)
    $model->getFirstMedia('images')->getUrl('thumb');
    
  3. Deleting Media:

    // Delete single media
    $model->getFirstMedia('images')->delete();
    
    // Delete all media in collection
    $model->clearMediaCollection('images');
    
  4. Media Conversions: Define conversions in registerMediaConversions():

    protected function registerMediaConversions(Media $media = null): void
    {
        $this->addMediaConversion('thumb')
              ->width(100)
              ->height(100);
    }
    

    Use conversions:

    $media->getUrl('thumb');
    $media->getPath('thumb');
    

Advanced Patterns

  • Custom Path Generators: Override getPathGenerator() in your model or service provider:

    public function getPathGenerator(): PathGenerator
    {
        return new CustomPathGenerator();
    }
    
  • Temporary URLs: Generate time-limited URLs for private files:

    $model->getFirstMedia('images')->getTemporaryUrl(60); // 60 seconds
    
  • Batch Operations: Use Media model methods to query or manipulate media:

    $media = Media::where('model_type', Post::class)
                  ->where('model_id', 1)
                  ->first();
    
  • Event Handling: Listen for media events (e.g., MediaWasAdded, MediaWasDeleted) via Laravel events.

Integration Tips

  • Form Requests: Validate file uploads using Laravel’s validation:

    $request->validate([
        'image' => 'required|image|mimes:jpeg,png,jpg|max:2048',
    ]);
    
  • API Responses: Use toResponse() for API endpoints:

    return $model->getFirstMedia('images')->toResponse();
    
  • Frontend Integration: Generate responsive images or thumbnails dynamically:

    <img src="{{ $model->getFirstMediaUrl('images', 'thumb') }}" alt="Thumbnail">
    
  • Storage Optimization: Use different disks for different media types (e.g., local for thumbnails, s3 for large files).


Gotchas and Tips

Common Pitfalls

  1. Missing Migrations: Always run php artisan migrate after publishing the config. The media table is required.

  2. Incorrect Collection Names: Ensure collection names (e.g., 'images') match when adding/retrieving media. Typos will return null.

  3. File Path Issues:

    • S3 Double Encoding: Use the s3 disk with URL encoding disabled in Laravel’s filesystem config:
      'disks' => [
          's3' => [
              'url' => env('AWS_URL'),
              'encoding' => false, // Critical for S3
          ],
      ],
      
    • Custom Path Generators: Ensure paths are generated correctly for non-default storage. Test with getAvailablePathRelativeToRoot().
  4. Conversion Failures:

    • Missing Dependencies: Install required libraries (e.g., imagick, ffmpeg, vips) for conversions.
    • Permissions: Ensure the storage directory is writable by the web server user.
  5. Orphaned Media: Use php artisan media:clean to remove media no longer referenced by models. For large datasets, use the --hash flag for faster cleanup.

  6. Memory Limits: Large file conversions (e.g., PDFs, videos) may hit PHP memory limits. Adjust ini_set('memory_limit', '512M') or use deferred() conversions:

    $this->addMediaConversion('thumb')->deferred();
    

Debugging Tips

  • Log Media Events: Temporarily add logging in event listeners to track media operations:

    MediaWasAdded::class => function ($event) {
        Log::debug('Media added:', ['model' => $event->model, 'media' => $event->media]);
    },
    
  • Check Disk Config: Verify disk configurations in config/filesystems.php match your storage setup.

  • Validate Media Existence: Always check for null when retrieving media:

    $media = $model->getFirstMedia('images');
    if (!$media) {
        // Handle missing media
    }
    

Performance Optimizations

  • Lazy Loading: Use with() to eager-load media in queries:

    $posts = Post::with('media')->get();
    
  • Batch Conversions: For bulk operations, defer conversions or use queue jobs:

    $model->addMedia($file)->toMediaCollection('images')->deferred();
    
  • Cache Conversions: Cache converted media paths/URLs if conversions are expensive:

    $media->getUrl('thumb', [], true); // Force cache
    

Extension Points

  1. Custom Media Models: Extend the Media model to add custom fields or behaviors:

    class CustomMedia extends Media
    {
        protected $casts = [
            'custom_field' => 'boolean',
        ];
    }
    

    Update the config to use your custom model.

  2. Custom Conversions: Create custom conversion classes by extending Spatie\MediaLibrary\Conversions\Conversion:

    class CustomConversion extends Conversion
    {
        public function manipulate($image)
        {
            // Custom logic
        }
    }
    

    Register it in registerMediaConversions().

  3. Custom Path Generators: Implement Spatie\MediaLibrary\PathGenerators\PathGenerator for unique path logic:

    class CustomPathGenerator implements PathGenerator
    {
        public function getPath(Media $media): string
        {
            return "custom/{$media->model_type}/{$media->model_id}/{$media->name}";
        }
    }
    
  4. Custom Thumbnails: Use Laravel’s Image facade or libraries like Intervention Image for advanced manipulations:

    $this->addMediaConversion('custom_thumb')
          ->width(200)
          ->height(200)
          ->manipulate(function ($image) {
              $image->filter(new Vignette());
          });
    

Configuration Quirks

  • Default Disk: Set the default disk in config/medialibrary.php:

    'default_disk' => 's3',
    
  • Temporary URLs: Configure the expiration time and URL generation in the config:

    'temporary_url_expiration' => 60, // seconds
    
  • FFmpeg Path: If using video conversions, ensure the FFmpeg path is set in config/medialibrary.php:

    'ffmpeg' => [
        'binary' => '/usr
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
codraw/framework-extra-bundle
codraw/messenger
codraw/security
codraw/mailer
codraw/contracts
codraw/profiling
codraw/dependency-injection
codraw/tester
codraw/core
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony