Installation:
composer require apoutchika/media-bundle
Enable the bundle in config/bundles.php:
return [
// ...
Apoutchika\MediaBundle\ApoutchikaMediaBundle::class => ['all' => true],
];
Configure Storage (config/packages/apoutchika_media.yaml):
apoutchika_media:
db_driver: doctrine_orm
gaufrette:
adapter: local
filesystem: '%kernel.project_dir%/public/uploads'
Create a Media Entity:
php bin/console make:entity Media
Add Media trait to your entity:
use Apoutchika\MediaBundle\Entity\MediaTrait;
class YourEntity
{
use MediaTrait;
}
First Use Case: Add a media field to a form:
$builder->add('media', 'apoutchika_media', [
'context' => 'user:1', // Restrict access
'allowed_types' => ['image/jpeg', 'image/png'],
'allowed_mime_types' => ['image/*'],
'max_size' => 2048, // KB
]);
Form Integration:
// In a controller
$form = $this->createFormBuilder($entity)
->add('media', 'apoutchika_media', [
'label' => 'Profile Image',
'context' => 'user:'.$userId,
'allowed_types' => ['image/jpeg', 'image/png'],
'max_width' => 1024,
'max_height' => 1024,
])
->getForm();
Handling Uploads:
// After form submission
$media = $entity->getMedia();
if ($media) {
$media->setContext('user:'.$userId); // Update context if needed
$media->setFocus(50, 50); // Set focus point (x, y)
}
Twig Usage:
{% render_media media, 'thumb' %}
Define a thumb filter in config/packages/apoutchika_media.yaml:
apoutchika_media:
filters:
thumb:
filter: thumbnail
options:
size: [200, 200]
mode: outbound
Dynamic Filters:
// In a controller
return $this->render('media/show.html.twig', [
'media' => $media,
'filter' => 'thumb', // Pass dynamically
]);
# config/packages/apoutchika_media.yaml
apoutchika_media:
contexts:
- 'user:*' # User-specific media
- 'document:*' # Document-specific media
// In form options
'context' => 'document:'.$documentId
# config/packages/apoutchika_media.yaml
apoutchika_media:
ckeditor:
enabled: true
toolbar: [
{ name: 'document', items: ['Media'] },
]
{{ render(controller('ApoutchikaMediaBundle:Media:ckeditor')) }}
use Apoutchika\MediaBundle\Manager\MediaManager;
$mediaManager = $this->container->get('apoutchika_media.manager.media');
$media = $mediaManager->findBy(['context' => 'user:1']);
foreach ($media as $item) {
$item->applyFilter('thumb'); // Apply filter to all
$mediaManager->persist($item);
}
Permission Issues:
uploads directory is writable:
chmod -R 775 %kernel.project_dir%/public/uploads
config/packages/apoutchika_media.yaml:
gaufrette:
adapter: ftp
filesystem: 'ftp://user:pass@host/path'
Focus Point Errors:
setFocus() fails, ensure the image is loaded via applyFilter() first:
$media->applyFilter('original'); // Ensure image is processed
$media->setFocus(30, 40);
Context Mismatches:
user:1 vs user:12). Typos here will cause 403 errors.Filter Caching:
php bin/console cache:clear
Doctrine Proxy Issues:
MediaTrait and the Media entity is properly mapped:
/**
* @ORM\OneToOne(targetEntity="Apoutchika\MediaBundle\Entity\Media", cascade={"persist", "remove"})
*/
use MediaTrait;
Gaufrette Adapters:
Gaufrette\Adapter\AbstractAdapter and update config/packages/apoutchika_media.yaml:
gaufrette:
adapter: custom
filesystem: 's3://bucket-name'
MIME Type Restrictions:
allowed_mime_types for broader restrictions (e.g., ['image/*']) and allowed_types for specific types (e.g., ['image/jpeg']).IE8 Compatibility:
apoutchika_media:
ie8_compatibility: false
Custom Filters:
Apoutchika\MediaBundle\Filter\FilterInterface:
namespace App\Media\Filter;
use Apoutchika\MediaBundle\Filter\FilterInterface;
use Imagine\Image\ImageInterface;
class CustomFilter implements FilterInterface
{
public function apply(ImageInterface $image, array $options)
{
// Custom logic (e.g., grayscale)
return $image->effects()->grayscale();
}
}
config/packages/apoutchika_media.yaml:
filters:
custom:
filter: App\Media\Filter\CustomFilter
options: []
Event Listeners:
media.pre_upload):
// src/EventListener/MediaListener.php
use Apoutchika\MediaBundle\Event\MediaEvent;
class MediaListener
{
public function onPreUpload(MediaEvent $event)
{
if ($event->getMedia()->getMimeType() === 'image/jpeg') {
$event->setAllowed(true);
}
}
}
services.yaml:
services:
App\EventListener\MediaListener:
tags:
- { name: kernel.event_listener, event: apoutchika_media.pre_upload, method: onPreUpload }
Overriding Templates:
vendor/apoutchika/media-bundle/Resources/views/ to templates/apoutchika_media/ to customize:
Media/ckeditor.html.twigMedia/fields.html.twigMedia/list.html.twigDoctrine Lifecycle Callbacks:
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\PrePersist
* @ORM\PreUpdate
*/
public function preUpload()
{
if ($this->getMedia()) {
$this->getMedia()->applyFilter('thumb');
}
}
Lazy Loading:
apoutchika_media:
lazy_loading: false
Batch Processing:
MediaManager to process media in bulk (e.g., during cron jobs):
$mediaManager = $this->container->get('apoutchika_media.manager.media');
$
How can I help you explore Laravel packages today?