Installation Add the bundle via Composer:
composer require discutea/media-bundle
Enable the bundle in config/bundles.php (Symfony):
return [
// ...
Discutea\MediaBundle\DiscuteaMediaBundle::class => ['all' => true],
];
Configuration Publish the default configuration:
php bin/console discutea:media:install
Update config/packages/discutea_media.yaml to define:
local, s3).image/*, application/pdf).uploads).First Upload
Use the MediaManager service in a controller:
use Discutea\MediaBundle\Manager\MediaManager;
class UploadController extends AbstractController
{
public function upload(MediaManager $mediaManager): Response
{
$file = $this->request->files->get('file');
$media = $mediaManager->upload($file, 'default_directory');
return $this->json($media->getUrl());
}
}
Verify
Check the public/uploads (or configured) directory for uploaded files.
config/packages/discutea_media.yaml for default settings.php bin/console list discutea to see available commands (e.g., discutea:media:install, discutea:media:clear).MediaManager, MediaRepository, and StorageAdapter in src/Manager/ and src/Repository/.Media entity (src/Entity/Media.php) for properties like url, mimeType, and size.Upload a file with MIME type validation and store metadata:
$file = $this->request->files->get('document');
$media = $mediaManager->upload($file, 'documents', [
'allowed_mimes' => ['application/pdf'],
'max_size' => 10 * 1024 * 1024, // 10MB
]);
return $this->json([
'url' => $media->getUrl(),
'size' => $media->getSize(),
]);
Uploading Files
$media = $mediaManager->upload($file, 'directory_name');
storage_adapters in discutea_media.yaml to use S3, FTP, etc.:
storage_adapters:
s3:
type: 'aws'
options:
bucket: 'my-bucket'
region: 'us-east-1'
Then pass the adapter name:
$media = $mediaManager->upload($file, 'directory', null, 's3');
Retrieving Media
$media = $mediaRepository->find($mediaId);
$mediaList = $mediaRepository->findBy(['directory' => 'documents']);
Deleting Media
$mediaManager->delete($media);
php bin/console discutea:media:clear documents
Symfony Forms
Use the MediaType field for file uploads in forms:
use Discutea\MediaBundle\Form\Type\MediaType;
$builder->add('document', MediaType::class, [
'label' => 'Upload PDF',
'directory' => 'documents',
'allowed_mimes' => ['application/pdf'],
]);
Event Listeners
Subscribe to media events (e.g., MediaUploadEvent) to trigger actions post-upload:
// src/EventListener/MediaListener.php
public function onMediaUpload(MediaUploadEvent $event)
{
$media = $event->getMedia();
// Add custom logic (e.g., generate thumbnails)
}
Register in services.yaml:
services:
App\EventListener\MediaListener:
tags:
- { name: 'kernel.event_listener', event: 'media.upload', method: 'onMediaUpload' }
API Endpoints Create RESTful endpoints for media operations:
// src/Controller/MediaApiController.php
#[Route('/api/media', name: 'api_media_')]
class MediaApiController extends AbstractController
{
#[Route('/upload', name: 'upload', methods: ['POST'])]
public function upload(MediaManager $manager, Request $request): JsonResponse
{
$file = $request->files->get('file');
$media = $manager->upload($file, 'uploads');
return $this->json($media->toArray());
}
}
Twig Integration Display media URLs in templates:
{% for media in mediaList %}
<img src="{{ media.getUrl() }}" alt="{{ media.name }}">
{% endfor %}
Custom Storage Adapters
Extend StorageAdapterInterface to support new backends (e.g., Google Cloud Storage):
class GcsAdapter implements StorageAdapterInterface
{
public function upload(UploadedFile $file, string $directory, string $filename): string
{
// Implement GCS upload logic
}
// ... other methods
}
Register in discutea_media.yaml:
storage_adapters:
gcs:
type: 'gcs'
options:
bucket: 'my-gcs-bucket'
Media Processing
Use the MediaProcessor service to resize images or generate thumbnails:
$processor = $this->container->get('discutea_media.processor');
$thumbnail = $processor->resize($media, 200, 200);
Batch Operations Process multiple files in bulk:
$files = $request->files->get('files');
$results = [];
foreach ($files as $file) {
$media = $mediaManager->upload($file, 'batch_uploads');
$results[] = $media->getUrl();
}
Directory Permissions
public/uploads) is writable by the web server user:
chmod -R 775 public/uploads
chown -R www-data:www-data public/uploads.MIME Type Spoofing
$media = $mediaManager->upload($file, 'directory', [
'allowed_mimes' => ['image/jpeg', 'image/png'],
]);
Memory Limits
upload_max_filesize or post_max_size. Adjust in php.ini:
upload_max_filesize = 20M
post_max_size = 25M
Database Bloat
Media entity stores metadata (e.g., url, size). For high-volume uploads, consider archiving old media or using a database partition.CORS Issues
location /uploads/ {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET';
}
Upload Failures
var/log/dev.log for exceptions. Common causes:
allowed_mimes).discutea:media:install).Missing Media
url field in the media table matches the actual file path.base_url is correct in discutea_media.yaml.Performance Issues
PROFILER to trace slow uploads:
$media = $mediaManager->upload($file
How can I help you explore Laravel packages today?