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 Mediaman Laravel Package

emaia/laravel-mediaman

Laravel MediaMan is a UI-agnostic media manager for Laravel. Upload files via a fluent MediaUploader, organize them into virtual collections, attach media to any model through polymorphic associations, tag by channels, and run automatic image conversions.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation (unchanged):

    composer require emaia/laravel-mediaman
    php artisan mediaman:publish-config
    php artisan mediaman:publish-migration
    php artisan migrate
    php artisan storage:link
    
  2. First Upload with Size Limit (new):

    use Emaia\MediaMan\Facades\MediaUploader;
    
    $media = MediaUploader::source($request->file('file'))
        ->maxFileSize(5 * 1024 * 1024) // 5MB
        ->upload();
    
  3. Attach to Model (unchanged):

    $post = Post::find(1);
    $post->attachMedia($media, 'featured-image-channel');
    

Where to Look First

  • Configuration: config/mediaman.php (new max_file_size setting)
  • Models: app/Models/Media.php and app/Models/MediaCollection.php (static methods now)
  • Facade: MediaUploader (new maxFileSize() method)
  • Exceptions: FileSizeExceeded for upload validation

First Use Case (Updated)

Upload a file with size validation and attach to a model:

try {
    $media = MediaUploader::source($request->file('image'))
        ->useCollection('Blog Posts')
        ->maxFileSize(config('mediaman.max_file_size')) // Respect config
        ->upload();

    $post = Post::find(1);
    $post->attachMedia($media, 'featured-image');
} catch (FileSizeExceeded $e) {
    return back()->withError('File too large');
}

Implementation Patterns

Core Workflows

1. Uploading Media (Updated)

  • Size Validation:

    // Config (config/mediaman.php)
    'max_file_size' => 10 * 1024 * 1024, // 10MB default
    
    // Runtime
    $media = MediaUploader::source($file)
        ->maxFileSize(2 * 1024 * 1024) // Override
        ->upload();
    
  • Exception Handling:

    try {
        $media = MediaUploader::source($file)->upload();
    } catch (FileSizeExceeded $e) {
        // Handle error (e.g., return validation error)
    }
    

2. Managing Collections (Updated)

  • Static Collection Lookup (breaking change):

    // OLD (no longer works)
    $collection = MediaCollection::with('media')->findByName('Gallery');
    
    // NEW
    $collection = MediaCollection::findByName('Gallery'); // Lazy-loads relations
    $media = $collection->load('media')->media; // Explicit eager load
    
  • Batch Attachments (performance improvement):

    $post->syncMedia($mediaArray, 'gallery'); // Single bulk INSERT
    

3. Custom Width Calculators (breaking change)

  • Update Implementations:
    class CustomWidthCalculator implements WidthCalculator {
        public function calculateWidthsFromBinary(string $binary): Collection {
            // New required method
            return collect([100, 200, 300]); // Example widths
        }
    
        // ... existing methods
    }
    

4. Responsive Images (performance)

  • Generate with Optimized Pipeline:
    $media->generateResponsiveImages(); // No temp dir writes
    

Integration Tips

Validation (Updated)

$request->validate([
    'file' => [
        'required',
        'file',
        'max:10240', // Laravel's max:kb
        function ($attribute, $value, $fail) {
            $maxSize = config('mediaman.max_file_size') ?? 0;
            if ($maxSize > 0 && $value->getSize() > $maxSize) {
                $fail('The '.$attribute.' may not be greater than '.byteToHuman($maxSize).'.');
            }
        }
    ],
]);

Custom Models (Updated)

// Handle static method changes in tests
public function test_collection_lookup() {
    $collection = MediaCollection::findByName('Test');
    $this->assertNull($collection->media); // Not loaded
    $collection->load('media'); // Explicit load
}

Events (Unchanged)

use Emaia\MediaMan\Events\MediaCreated;

MediaCreated::subscribe(function ($media) {
    if ($media->size > config('mediaman.max_file_size')) {
        // Log oversized uploads
    }
});

Artisan Commands (Unchanged)

# Cleanup (unchanged)
php artisan mediaman:cleanup

# Generate responsive images (faster now)
php artisan mediaman:generate-responsive

Gotchas and Tips

Pitfalls

  1. Static Method Changes (breaking):

    • findByName() is now static. Chained queries like with()->findByName() fail.
    • Fix: Explicitly eager-load relations:
      $collection = MediaCollection::findByName('x')->load('media');
      
  2. Width Calculator Contract (breaking):

    • Custom calculators must implement calculateWidthsFromBinary().
    • Fix: Update implementations or extend DefaultWidthCalculator.
  3. File Size Validation:

    • maxFileSize() throws FileSizeExceeded (not a validation error).
    • Fix: Catch the exception or validate manually.
  4. Responsive Image Temp Files:

    • No longer writes to sys_get_temp_dir (performance fix).
    • Note: May affect custom image processors relying on temp files.
  5. Bulk Attach Performance:

    • syncMedia() now uses bulk INSERT (1 query vs N).
    • Note: Ensure your database supports bulk inserts.
  6. Null Returns:

    • findByName('non-existent') now returns null (was Builder).
    • Fix: Add null checks:
      $collection = MediaCollection::findByName('x') ?? throw new NotFoundException();
      

Debugging

  1. File Size Issues:

    // Log actual vs allowed size
    $fileSize = $request->file('file')->getSize();
    $maxSize = config('mediaman.max_file_size');
    \Log::debug('File size', compact('fileSize', 'maxSize'));
    
  2. Static Method Calls:

    // Check if collection exists before chaining
    if (!$collection = MediaCollection::findByName('x')) {
        abort(404);
    }
    $collection->load('media');
    
  3. Width Calculator:

    // Test custom calculator
    $calculator = new CustomWidthCalculator();
    $widths = $calculator->calculateWidthsFromBinary(file_get_contents($media->path));
    
  4. Bulk Attach:

    // Verify syncMedia works
    $post->syncMedia([$media1, $media2], 'gallery');
    $this->assertCount(2, $post->getMedia('gallery'));
    

Tips

  1. Configurable Size Limits:

    // config/mediaman.php
    'max_file_size' => env('MEDIAMAN_MAX_FILE_SIZE', 10 * 1024 * 1024),
    

    Set via .env:

    MEDIAMAN_MAX_FILE_SIZE=5242880 # 5MB
    
  2. Human-Readable Size Validation:

    use Emaia\MediaMan\Helpers\byteToHuman;
    
    $request->validate([
        'file' => [
            'max:10240',
            function ($attribute, $value, $fail) {
                $max = config('mediaman.max_file_size');
                if ($max > 0 && $value->getSize() > $max) {
                    $fail("File must be less than {$byteToHuman($max)}.");
                }
            }
        ]
    ]);
    
  3. Lazy-Loading Collections:

    // Avoid N+1 queries
    $collections = MediaCollection::all()->load('media');
    
  4. Custom Exceptions:

    // Extend FileSizeExceeded for custom messages
    class CustomFileSizeExceeded extends FileSizeExceeded {
        public function __construct($maxSize) {
            parent::__construct($maxSize);
            $this->message = "Files must be under {$byteToHuman($maxSize)}.";
        }
    }
    
  5. Testing Static Methods:

    public function test_static_find_by_name() {
        $collection = MediaCollection::findByName('Test');
        $this->assertInstanceOf(MediaCollection::class, $collection);
        $this->assertNull($collection->media);
    
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.
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium