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

sonata-project/media-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require sonata-project/media-bundle
    

    Add to config/bundles.php:

    return [
        // ...
        Sonata\MediaBundle\SonataMediaBundle::class => ['all' => true],
    ];
    
  2. Database Setup: Run migrations for the MediaBundle:

    php bin/console doctrine:migrations:diff
    php bin/console doctrine:migrations:migrate
    
  3. First Media Entity: Use the Media entity provided by the bundle:

    use Sonata\MediaBundle\Model\MediaInterface;
    use Sonata\MediaBundle\Model\MediaManagerInterface;
    
    // In a controller or service
    $mediaManager = $this->get('sonata.media.manager.media');
    $media = $mediaManager->create();
    $media->setProviderName('sonata.media.provider.image'); // Default provider
    $media->setEnabled(true);
    $mediaManager->save($media);
    
  4. Upload Files: Use the Media form type:

    use Sonata\MediaBundle\Form\Type\MediaType;
    
    $form = $this->createForm(MediaType::class, $media);
    
  5. Display Media: Twig template example:

    {% for media in medias %}
        {{ sonata_media_embed_media(media, 'sonata.media.block.media', { 'width': 200, 'height': 200 }) }}
    {% endfor %}
    

First Use Case: Blog Post with Images

  1. Create a Post entity with a OneToMany relationship to Media:
    /**
     * @ORM\OneToMany(targetEntity="Sonata\MediaBundle\Model\Media", mappedBy="context", cascade={"persist"})
     */
    private $images;
    
  2. Use the MediaType in your form to upload images:
    $builder->add('images', MediaType::class, [
        'provider' => 'sonata.media.provider.image',
        'context' => 'blog_post',
        'multiple' => true,
    ]);
    

Implementation Patterns

Common Workflows

1. Media Providers

  • Default Providers: image, file, video, youtube, vimeo.
  • Custom Providers: Extend Sonata\MediaBundle\Provider\Pool and implement Sonata\MediaBundle\Provider\ProviderInterface.
    class CustomProvider extends AbstractProvider
    {
        public function generateUrl($media, $format = 'reference')
        {
            return '/custom/path/' . $media->getId() . '.' . $format;
        }
    }
    
  • Register in config/packages/sonata_media.yaml:
    sonata_media:
        providers:
            custom:
                service: sonata.media.provider.custom
    

2. Media Contexts

  • Use contexts to organize media (e.g., blog_post, product).
  • Set context when creating media:
    $media->setContext('blog_post');
    

3. Media Blocks (Admin UI)

  • Use Sonata Admin to manage media via the admin panel:
    use Sonata\MediaBundle\Admin\MediaAdmin;
    
    $adminPool->registerAdmin(MediaAdmin::class);
    
  • Customize the admin class to filter media by context:
    protected function configureDatagridFilters()
    {
        $this->datagrid->add('context', null, [
            'field_type' => 'string',
            'options' => ['eq' => 'blog_post'],
        ]);
    }
    

4. Media Embedding in Twig

  • Use the sonata_media_embed_media Twig function:
    {{ sonata_media_embed_media(media, 'sonata.media.block.media', {
        'width': 800,
        'height': 600,
        'autoplay': true
    }) }}
    
  • Customize blocks by extending SonataMediaBundle:Block:block_media.html.twig.

5. Media Events

  • Listen to media events (e.g., sonata.media.pre_persist):
    $eventDispatcher->addListener('sonata.media.pre_persist', function ($event) {
        $media = $event->getSubject();
        $media->setAuthor($this->getUser());
    });
    

6. Media API (REST/JSON)

  • Use the built-in API endpoints:
    • GET /api/media (list media)
    • POST /api/media (upload media)
  • Customize routes in config/routes.yaml:
    sonata_media_api:
        resource: "@SonataMediaBundle/Resources/config/routing/api.xml"
        prefix: /api
    

Integration Tips

1. Symfony Forms

  • Use MediaType for file uploads in forms:
    $builder->add('thumbnail', MediaType::class, [
        'provider' => 'sonata.media.provider.image',
        'context' => 'product',
        'required' => false,
    ]);
    

2. VichUploaderBridge

  • Integrate with VichUploaderBundle for file handling:
    # config/packages/vich_uploader.yaml
    vich_uploader:
        db_driver: orm
        mappings:
            sonata_media:
                uri_prefix: /uploads/media
                upload_destination: '%kernel.project_dir%/public/uploads/media'
                namer: Vich\UploaderBundle\Naming\SmartUniqueNamer
    

3. Media in Entities

  • Reference media in your entities:
    /**
     * @ORM\ManyToOne(targetEntity="Sonata\MediaBundle\Model\Media", cascade={"persist"})
     */
    private $featuredImage;
    

4. Media in API Platform

  • Use ApiPlatform\Metadata\ApiResource with SonataMediaBundle:
    #[ApiResource(
        operations: [
            new GetCollection(),
            new Post(
                normalizationContext: ['groups' => ['media:read']],
                denormalizationContext: ['groups' => ['media:write']]
            )
        ]
    )]
    class Product
    {
        #[Groups(['media:read'])]
        #[Assert\Valid]
        private ?MediaInterface $image = null;
    }
    

5. Media in Livewire/Alpine

  • Use Livewire to upload media dynamically:
    public function uploadMedia()
    {
        $media = $this->get('sonata.media.manager.media')->create();
        $media->setProviderName('sonata.media.provider.image');
        $media->setEnabled(true);
        $this->get('sonata.media.manager.media')->save($media);
        return $media;
    }
    
  • Twig:
    <livewire:media-uploader wire:model="post.images" />
    

Gotchas and Tips

Pitfalls

  1. Provider Configuration:

    • Issue: Forgetting to configure providers in sonata_media.yaml causes MediaNotFoundException.
    • Fix: Ensure providers are registered:
      sonata_media:
          providers:
              image:
                  service: sonata.media.provider.image
      
  2. File Permissions:

    • Issue: Uploaded files fail with Permission denied errors.
    • Fix: Set correct permissions for the upload directory:
      chmod -R 775 public/uploads/media
      chown -R www-data:www-data public/uploads/media
      
  3. Context Mismatch:

    • Issue: Media not appearing in the admin panel due to incorrect context.
    • Fix: Verify context in the database and admin filters:
      SELECT * FROM media WHERE context = 'blog_post';
      
  4. CORS Issues:

    • Issue: API uploads fail with CORS errors.
    • Fix: Configure CORS in .env:
      CORS_ALLOW_ORIGIN=^https?://yourdomain\.com$
      
  5. Media Deletion:

    • Issue: Deleting a media entity doesn’t remove the file.
    • Fix: Implement a pre-remove event listener:
      $eventDispatcher->addListener('sonata.media.pre_remove', function ($event) {
          $media = $event->getSubject();
          $provider = $this->get('sonata.media.provider.pool')->getProvider($media->getProviderName());
          $provider->delete($media);
      });
      
  6. Memory Limits:

    • Issue: Large file uploads fail with Allowed memory exhausted.
    • Fix: Increase upload_max_filesize and post_max_size in php.ini and set max_file_size in sonata_media.yaml:
      sonata_media:
          max_file_size
      
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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky