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

Media Bundle Laravel Package

development-x/media-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require development-x/media-bundle
    

    Add to config/app.php under providers:

    DevelopmentX\MediaBundle\MediaBundle::class,
    
  2. Publish Configuration

    php artisan vendor:publish --provider="DevelopmentX\MediaBundle\MediaBundle" --tag="config"
    

    This generates config/media.php with default settings (e.g., storage paths, allowed MIME types).

  3. First Use Case: Uploading a File Create a form with enctype="multipart/form-data" and submit to a controller:

    use DevelopmentX\MediaBundle\Services\MediaService;
    
    public function upload(Request $request, MediaService $mediaService) {
        $file = $request->file('file');
        $media = $mediaService->upload($file, 'user_uploads'); // 'user_uploads' is a config key
        return response()->json($media);
    }
    

    The MediaService handles validation, storage, and returns a Media object with metadata (path, URL, MIME type).


Implementation Patterns

Core Workflows

  1. File Uploads with Validation

    $media = $mediaService->upload($file, 'user_uploads', [
        'allowed_mimes' => ['image/jpeg', 'image/png'],
        'max_size' => 5 * 1024 * 1024, // 5MB
    ]);
    
    • Uses config-defined rules from config/media.php (e.g., user_uploads.allowed_mimes).
    • Throws InvalidArgumentException for invalid files.
  2. Associating Media with Entities

    // In a User model
    public function media() {
        return $this->morphToMany(Media::class, 'model');
    }
    
    // Attach media to a user
    $user->media()->attach($media->id);
    
    • Leverages polymorphic relationships for flexible media-entity associations.
  3. Generating URLs

    $media->url(); // Returns full URL (e.g., "/storage/user_uploads/123.jpg")
    $media->thumbnailUrl('small'); // Generates thumbnail URL if configured.
    
  4. Batch Processing

    $mediaService->uploadMultiple($request->file('files'), 'user_uploads');
    
    • Returns a collection of Media objects.

Integration Tips

  • Storage Systems: Configure config/media.php to use local, s3, or ftp drivers:

    'disks' => [
        'user_uploads' => [
            'driver' => 's3',
            'bucket' => 'my-bucket',
            'key' => env('AWS_ACCESS_KEY_ID'),
        ],
    ],
    
  • Thumbnails: Enable via config/media.php:

    'thumbnails' => [
        'enabled' => true,
        'paths' => [
            'small' => 'thumbs/small',
            'large' => 'thumbs/large',
        ],
    ],
    

    Use MediaService::generateThumbnail() for custom sizes.

  • Events: Listen for upload events:

    // In EventServiceProvider
    protected $listen = [
        'media.uploaded' => [MediaUploadedListener::class, 'handle'],
    ];
    

Gotchas and Tips

Pitfalls

  1. Missing Configuration

    • If config/media.php is not published, the bundle throws RuntimeException on first use.
    • Fix: Always run php artisan vendor:publish --tag="config" after installation.
  2. Storage Permissions

    • The bundle defaults to storage/app/media. Ensure this directory is writable:
      chmod -R 775 storage/app/media
      
    • For S3/FTP, verify credentials in .env and config.
  3. MIME Type Validation

    • The bundle uses PHP’s finfo for MIME detection. If files are rejected unexpectedly:
      • Check config/media.php for allowed MIME types.
      • Debug with:
        $finfo = finfo_open(FILEINFO_MIME_TYPE);
        echo finfo_file($finfo, $file->getPathname());
        
  4. Polymorphic Relationships

    • Forgetting to define the inverse relationship (e.g., media()->morphTo()) causes HasManyThrough errors.
    • Tip: Use a trait for consistency:
      trait HasMedia {
          public function media() {
              return $this->morphToMany(Media::class, 'model');
          }
      }
      

Debugging

  1. Log Uploads Enable logging in config/media.php:

    'logging' => [
        'enabled' => true,
        'channel' => 'single',
    ],
    

    Check storage/logs/laravel.log for upload events.

  2. Validate File Paths Use MediaService::getStoragePath() to debug paths:

    $path = $mediaService->getStoragePath('user_uploads', $media->id);
    
  3. Thumbnail Generation

    • If thumbnails fail, verify:
      • imagemagick or graphicsmagick is installed (php -m | grep imagick).
      • The thumbnails.paths config points to a writable directory.

Extension Points

  1. Custom Storage Drivers Implement DevelopmentX\MediaBundle\Contracts\StorageDriver:

    class CustomDriver implements StorageDriver {
        public function store(File $file, string $path) { ... }
        public function url(string $path) { ... }
    }
    

    Register in config/media.php:

    'drivers' => [
        'custom' => \App\Services\CustomDriver::class,
    ],
    
  2. Override Media Model Extend DevelopmentX\MediaBundle\Models\Media to add custom fields:

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

    Bind the custom model in MediaBundleServiceProvider:

    $this->app->bind(Media::class, CustomMedia::class);
    
  3. Hooks for Post-Processing Use the media.uploaded event to add custom logic (e.g., OCR, metadata extraction):

    event(new MediaUploaded($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.
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
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