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

moox/media

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Package Run the Moox installer to scaffold configurations and migrations:

    php artisan moox:install
    
    • Publishes migrations, config, and Spatie Media Library integration.
    • Sets up the custom Media model and PathGenerator.
  2. Configure Database Run migrations to create tables for media collections and translations:

    php artisan migrate
    
  3. First Use Case: Attach Media to a Model Extend a model with the required traits and interface:

    use Moox\Media\Traits\HasMediaUsable;
    use Spatie\MediaLibrary\HasMedia;
    use Spatie\MediaLibrary\InteractsWithMedia;
    
    class Post extends Model implements HasMedia
    {
        use HasMediaUsable, InteractsWithMedia;
    
        protected $fillable = ['image']; // JSON field for media metadata
    }
    
    • Use the MediaPicker component in Filament forms to attach media:
      use Moox\Media\Components\MediaPicker;
      
      MediaPicker::make('image')
          ->collection('images') // Optional: specify collection name
          ->required()
      

Implementation Patterns

Workflows

  1. Model Integration

    • Traits & Interface: Always implement HasMedia and use HasMediaUsable for translation support.
    • JSON Field: Define a JSON column (e.g., image) to store media metadata (e.g., {"id": 1, "url": "/path/to/image.jpg"}).
    • Accessing Media:
      $post->getMedia('image'); // Returns a Media model
      $post->getFirstMedia('image')->getUrl(); // Direct URL access
      
  2. Filament Integration

    • MediaPicker Component: Use in Filament forms for uploads:
      MediaPicker::make('hero_image')
          ->collection('hero_images')
          ->multiple() // Allow multiple files
          ->acceptedFileTypes(['image/jpeg', 'image/png'])
      
    • Displaying Media: Use the MediaViewer component to render media in Filament tables/panels:
      use Moox\Media\Components\MediaViewer;
      
      MediaViewer::make('image')
          ->collection('images')
          ->width(100)
          ->height(100)
      
  3. Collections and Organization

    • Define collections in the media config:
      'collections' => [
          'images' => [
              'disk' => 'public',
              'path' => 'images/posts',
          ],
          'documents' => [
              'disk' => 'public',
              'path' => 'documents',
          ],
      ],
      
    • Dynamically create collections via code:
      $post->addMedia($file)->usingCollection('custom_collection')->save();
      
  4. Translations

    • Translate media metadata (e.g., alt text, captions) using the translate() method:
      $media = $post->getFirstMedia('image');
      $media->translate('alt', 'en', 'Sunset Photo');
      $media->translate('alt', 'es', 'Foto del Atardecer');
      
    • Access translations:
      $altText = $media->getTranslation('alt', 'en');
      

Integration Tips

  • Custom Paths: Extend the PathGenerator to dynamically set paths based on model attributes:

    use Moox\Media\PathGenerators\PathGenerator;
    
    class CustomPathGenerator extends PathGenerator
    {
        public function getPath(Media $media): string
        {
            return "posts/{$media->model->id}/{$media->collection_name}";
        }
    }
    

    Register it in config/media.php:

    'path_generator' => \App\PathGenerators\CustomPathGenerator::class,
    
  • Validation: Validate media attachments in Filament forms:

    use Moox\Media\Rules\ValidMedia;
    
    $form->validate(
        ValidMedia::make()
            ->collection('images')
            ->maxSize(5 * 1024) // 5MB
    );
    
  • Events: Listen to media events (e.g., MediaWasAdded, MediaWasDeleted) for side effects:

    use Moox\Media\Events\MediaWasAdded;
    
    MediaWasAdded::listen(function (Media $media) {
        // Log or process the added media
    });
    

Gotchas and Tips

Pitfalls

  1. Missing JSON Column

    • Issue: Forgetting to add a JSON column (e.g., image) in the model’s $fillable or database schema.
    • Fix: Ensure the column exists and is cast as json in the model:
      protected $casts = [
          'image' => 'json',
      ];
      
  2. Collection Mismatch

    • Issue: Attempting to attach media to a non-existent collection.
    • Fix: Define collections in config/media.php or dynamically create them:
      $post->addMedia($file)->usingCollection('dynamic_collection')->save();
      
  3. Translation Conflicts

    • Issue: Overwriting translations or not handling fallback locales.
    • Fix: Use getTranslation() with a fallback locale:
      $altText = $media->getTranslation('alt', 'en', 'Default Alt Text');
      
  4. Filament Component Registration

    • Issue: MediaPicker/MediaViewer not appearing in Filament.
    • Fix: Ensure the package is registered in AppServiceProvider:
      Filament::serving(function () {
          Filament::registerComponents([
              \Moox\Media\Components\MediaPicker::class,
              \Moox\Media\Components\MediaViewer::class,
          ]);
      });
      
  5. Disk Configuration

    • Issue: Media not saving to the correct disk (e.g., public vs. local).
    • Fix: Verify the disk setting in config/media.php and ensure the disk is configured in config/filesystems.php.

Debugging

  • Check Media Existence:
    if ($post->getFirstMedia('image')) {
        // Media exists
    }
    
  • Log Media Paths:
    \Log::info('Media path:', [
        'url' => $media->getUrl(),
        'path' => $media->path,
    ]);
    
  • Validate Config: Run php artisan config:clear and check config/media.php for typos or missing settings.

Extension Points

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

    use Moox\Media\Models\Media as BaseMedia;
    
    class CustomMedia extends BaseMedia
    {
        protected $casts = [
            'custom_field' => 'string',
        ];
    }
    

    Update the config to use your model:

    'model' => \App\Models\CustomMedia::class,
    
  2. Dynamic Collections Create collections dynamically based on model attributes:

    $post->addMedia($file)
         ->usingCollection("posts_{$post->category->slug}")
         ->save();
    
  3. Presets and Conversions Use Spatie’s MediaLibrary presets for image resizing:

    $media = $post->addMedia($file)->toMediaCollection('images');
    $media->regeneratePresets();
    

    Define presets in config/media.php:

    'presets' => [
        'thumbnails' => [
            'width' => 200,
            'height' => 200,
            'fit' => \Spatie\Image\Enums\Fit::Crop,
        ],
    ],
    
  4. API Responses Serialize media data for APIs:

    $post->append(['media' => function ($post) {
        return $post->getMedia('image')->map->only(['id', 'url', 'alt']);
    }]);
    
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.
codeflextech/permission-manager
karnoweb/livewire-datepicker
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