Installation:
composer require sonata-project/media-bundle
Add to config/bundles.php:
return [
// ...
Sonata\MediaBundle\SonataMediaBundle::class => ['all' => true],
];
Database Setup:
Run migrations for the MediaBundle:
php bin/console doctrine:migrations:diff
php bin/console doctrine:migrations:migrate
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);
Upload Files:
Use the Media form type:
use Sonata\MediaBundle\Form\Type\MediaType;
$form = $this->createForm(MediaType::class, $media);
Display Media: Twig template example:
{% for media in medias %}
{{ sonata_media_embed_media(media, 'sonata.media.block.media', { 'width': 200, 'height': 200 }) }}
{% endfor %}
Post entity with a OneToMany relationship to Media:
/**
* @ORM\OneToMany(targetEntity="Sonata\MediaBundle\Model\Media", mappedBy="context", cascade={"persist"})
*/
private $images;
MediaType in your form to upload images:
$builder->add('images', MediaType::class, [
'provider' => 'sonata.media.provider.image',
'context' => 'blog_post',
'multiple' => true,
]);
image, file, video, youtube, vimeo.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;
}
}
config/packages/sonata_media.yaml:
sonata_media:
providers:
custom:
service: sonata.media.provider.custom
blog_post, product).$media->setContext('blog_post');
use Sonata\MediaBundle\Admin\MediaAdmin;
$adminPool->registerAdmin(MediaAdmin::class);
protected function configureDatagridFilters()
{
$this->datagrid->add('context', null, [
'field_type' => 'string',
'options' => ['eq' => 'blog_post'],
]);
}
sonata_media_embed_media Twig function:
{{ sonata_media_embed_media(media, 'sonata.media.block.media', {
'width': 800,
'height': 600,
'autoplay': true
}) }}
SonataMediaBundle:Block:block_media.html.twig.sonata.media.pre_persist):
$eventDispatcher->addListener('sonata.media.pre_persist', function ($event) {
$media = $event->getSubject();
$media->setAuthor($this->getUser());
});
GET /api/media (list media)POST /api/media (upload media)config/routes.yaml:
sonata_media_api:
resource: "@SonataMediaBundle/Resources/config/routing/api.xml"
prefix: /api
MediaType for file uploads in forms:
$builder->add('thumbnail', MediaType::class, [
'provider' => 'sonata.media.provider.image',
'context' => 'product',
'required' => false,
]);
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
/**
* @ORM\ManyToOne(targetEntity="Sonata\MediaBundle\Model\Media", cascade={"persist"})
*/
private $featuredImage;
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;
}
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;
}
<livewire:media-uploader wire:model="post.images" />
Provider Configuration:
sonata_media.yaml causes MediaNotFoundException.sonata_media:
providers:
image:
service: sonata.media.provider.image
File Permissions:
Permission denied errors.chmod -R 775 public/uploads/media
chown -R www-data:www-data public/uploads/media
Context Mismatch:
SELECT * FROM media WHERE context = 'blog_post';
CORS Issues:
.env:
CORS_ALLOW_ORIGIN=^https?://yourdomain\.com$
Media Deletion:
$eventDispatcher->addListener('sonata.media.pre_remove', function ($event) {
$media = $event->getSubject();
$provider = $this->get('sonata.media.provider.pool')->getProvider($media->getProviderName());
$provider->delete($media);
});
Memory Limits:
Allowed memory exhausted.upload_max_filesize and post_max_size in php.ini and set max_file_size in sonata_media.yaml:
sonata_media:
max_file_size
How can I help you explore Laravel packages today?