Weave 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

deusz/media-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require deusz/media-bundle
    

    Add to config/bundles.php:

    return [
        // ...
        Deusz\MediaBundle\DeuszMediaBundle::class => ['all' => true],
    ];
    
  2. Database Migration Run the bundle’s migrations:

    php bin/console doctrine:migrations:diff
    php bin/console doctrine:migrations:migrate
    
  3. First Media Upload Configure a provider (e.g., sonata.media.provider.local for filesystem storage) in config/packages/deusz_media.yaml:

    deusz_media:
        providers:
            local:
                filesystem: '%kernel.project_dir%/public/uploads'
    

    Use in a controller:

    use Deusz\MediaBundle\Model\MediaInterface;
    use Deusz\MediaBundle\Model\MediaManagerInterface;
    
    public function uploadMedia(MediaManagerInterface $mediaManager)
    {
        $media = $mediaManager->create();
        $media->setProviderName('local');
        $media->setContext('default');
        $media->setEnabled(true);
    
        // Handle file upload (e.g., from a request)
        $file = $request->files->get('file');
        $media->setBinaryContent($file->getContent());
        $media->setOriginalFilename($file->getClientOriginalName());
    
        $mediaManager->save($media);
        return $media;
    }
    
  4. Display Media Use the Media entity in templates:

    {% for media in medias %}
        <img src="{{ media.thumbnail('media_default') }}" alt="{{ media.name }}">
    {% endfor %}
    

Implementation Patterns

Common Workflows

1. Media Upload & Processing

  • Provider-Specific Logic: Extend MediaProviderInterface for custom storage (e.g., S3, Cloudinary).

    namespace App\Media\Provider;
    
    use Deusz\MediaBundle\Model\MediaInterface;
    use Deusz\MediaBundle\Model\MediaProviderInterface;
    
    class CustomProvider implements MediaProviderInterface
    {
        public function generatePublicUrl(MediaInterface $media, $format = null)
        {
            return "https://custom-cdn.com/{$media->getId()}.{$format}";
        }
    }
    

    Register in deusz_media.yaml:

    deusz_media:
        providers:
            custom:
                class: App\Media\Provider\CustomProvider
    
  • Binary Handling: Use MediaManager to process files:

    $mediaManager->generateMedia($media, 'media_thumbnail', 'sonata.media.generator.thumbnail');
    

2. Media Embedding in Forms

  • Use MediaType for Symfony forms:
    use Deusz\MediaBundle\Form\Type\MediaType;
    
    $builder->add('media', MediaType::class, [
        'provider_name' => 'local',
        'context' => 'default',
        'multiple' => true,
    ]);
    

3. Media Querying

  • Use MediaRepository for filtering:
    $media = $mediaRepository->findBy([
        'context' => 'default',
        'enabled' => true,
    ]);
    

4. Thumbnail Generation

  • Define generators in config/packages/deusz_media.yaml:
    deusz_media:
        generators:
            thumbnail:
                service: sonata.media.generator.thumbnail
                extension: gif
                options:
                    size: [100, 100]
                    quality: 90
    
    Generate in code:
    $mediaManager->generateMedia($media, 'media_thumbnail', 'thumbnail');
    

5. Media Contexts

  • Use contexts to group media (e.g., products, blogs):
    $media->setContext('products');
    

Integration Tips

  • Event Listeners: Subscribe to MediaEvents for post-upload actions:

    use Deusz\MediaBundle\Event\MediaEvent;
    use Symfony\Component\EventDispatcher\EventSubscriberInterface;
    
    class MediaSubscriber implements EventSubscriberInterface
    {
        public static function getSubscribedEvents()
        {
            return [
                MediaEvent::POST_UPLOAD => 'onMediaUpload',
            ];
        }
    
        public function onMediaUpload(MediaEvent $event)
        {
            $media = $event->getMedia();
            // Add custom logic (e.g., log, notify)
        }
    }
    
  • API Responses: Serialize media for APIs:

    use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
    
    $serializer->normalize($media, 'json', [
        'groups' => ['media_read'],
    ]);
    
  • Caching: Cache generated thumbnails with sonata.media.cache.generic service.


Gotchas and Tips

Pitfalls

  1. Provider Configuration

    • Issue: Forgetting to set provider_name on a Media entity causes MediaManager::save() to fail.
    • Fix: Always validate provider_name exists in deusz_media.yaml:
      if (!$media->getProviderName() || !$mediaManager->hasProvider($media->getProviderName())) {
          throw new \InvalidArgumentException('Invalid provider');
      }
      
  2. File Permissions

    • Issue: Local storage fails if the upload directory lacks write permissions.
    • Fix: Ensure public/uploads is writable:
      chmod -R 775 public/uploads
      
  3. Generator Dependencies

    • Issue: Missing sonata.media.generator.thumbnail service breaks thumbnail generation.
    • Fix: Install sonata-media-bundle or manually define generators:
      services:
          sonata.media.generator.thumbnail:
              class: Sonata\MediaBundle\Generator\Generator
              arguments:
                  - sonata.media.generator.thumbnail
      
  4. Binary Content vs. Filesystem

    • Issue: Confusing setBinaryContent() (in-memory) with filesystem paths.
    • Fix: Use setBinaryContent() for direct uploads; setPath() for filesystem-based providers.
  5. Context Mismatches

    • Issue: Media not appearing in expected contexts due to typos or missing context definitions.
    • Fix: Validate contexts in MediaRepository:
      $media->setContext('valid_context'); // Ensure this matches your app's contexts.
      

Debugging Tips

  • Enable Debug Mode: Add to deusz_media.yaml:

    deusz_media:
        debug: true
    

    Logs provider calls and generator execution.

  • Check Events: Dump dispatched events:

    $dispatcher->addListener(MediaEvent::PRE_UPLOAD, function (MediaEvent $event) {
        error_log('Media upload event: ' . print_r($event->getMedia(), true));
    });
    
  • Validate Entities: Use Symfony’s validator:

    $errors = $validator->validate($media);
    if (count($errors) > 0) {
        throw new \RuntimeException((string) $errors);
    }
    

Extension Points

  1. Custom Providers

    • Extend MediaProviderInterface for cloud storage (e.g., AWS S3, Google Cloud Storage).
    • Example: Override generatePublicUrl() and delete() methods.
  2. Media Metadata

    • Add custom fields to the Media entity:
      /**
       * @ORM\Column(type="string", nullable=true)
       */
      private $customMetadata;
      
    • Update migrations and forms accordingly.
  3. Generator Services

    • Create custom generators (e.g., for PDF thumbnails):
      services:
          app.media.generator.pdf_thumbnail:
              class: App\Media\Generator\PdfThumbnailGenerator
              tags:
                  - { name: sonata.media.generator, type: pdf_thumbnail }
      
  4. Security

    • Restrict media access by context:
      $voter = new MediaVoter();
      $voter->supportsClass(Media::class) && $voter->vote($token, $media, ['READ']);
      
  5. Batch Processing

    • Use MediaManager in bulk:
      foreach ($mediaList as $media) {
          $mediaManager->generateMedia($media, 'media_thumbnail', 'thumbnail');
      }
      
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.
snowsoft/faker
meditationsteps/blogetc
animalyoung/laravel-influxdb
onix-solutions/sms-telera
lonely-lights/prosetta
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log
hsluv/hsluv
seampact/codegen