phpmob/media-bundle
Symfony bundle configuring media storage via a PHPCR-backed Flysystem filesystem. Provides ready-to-import YAML config and supports overriding the PHPCR UTF-8 connection parameter for media storage.
Installation
composer require phpmob/media-bundle
Publish the bundle’s configuration:
php artisan vendor:publish --provider="PhpMob\MediaBundle\MediaBundle" --tag=config
Configuration
Update config/media.php to define storage paths (local, S3, etc.) and allowed file types:
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app/media'),
],
],
'allowed_mimes' => ['image/jpeg', 'image/png', 'application/pdf'],
First Use Case: Uploading a File
Inject the MediaManager into a controller/service:
use PhpMob\MediaBundle\Manager\MediaManager;
public function upload(Request $request, MediaManager $mediaManager)
{
$file = $request->file('media');
$media = $mediaManager->upload($file, [
'disk' => 'local',
'path' => 'user_uploads',
]);
return response()->json($media);
}
Key Files to Review
config/media.php: Disk and validation rules.src/Manager/MediaManager.php: Core upload logic.src/Entity/Media.php: Media model structure.Uploading Media
// Basic upload
$media = $mediaManager->upload($file, ['disk' => 'local']);
// With custom path and metadata
$media = $mediaManager->upload($file, [
'disk' => 's3',
'path' => 'products/{year}',
'metadata' => ['product_id' => 123],
]);
Generating URLs
$url = $mediaManager->getUrl($media, 'thumb'); // Uses named presets
Deleting Media
$mediaManager->delete($media); // Soft or hard delete based on config
Batch Operations
$mediaManager->deleteMultiple([$media1, $media2]); // Bulk delete
s3, ftp) for flexibility.media.uploaded or media.deleted events for post-processing:
Event::listen('media.uploaded', function ($media) {
// Example: Log uploads or trigger notifications
});
PhpMob\MediaBundle\Validator\MediaValidator to add custom rules.config/media.php under presets:
'presets' => [
'thumb' => [
'width' => 200,
'height' => 200,
'fit' => 'crop',
],
],
| Use Case | Implementation Example |
|---|---|
| User Profile Avatars | Upload to users/{user_id}/avatar with disk: 's3'. |
| Product Images | Use presets (thumb, large) and store in products/{id}/images. |
| Document Management | Validate MIME types (e.g., application/pdf) and restrict access via policies. |
| Video Thumbnails | Generate thumbnails on upload using FFmpeg (if supported by the bundle). |
Disk Configuration
config/media.php or Laravel’s filesystems.php.php artisan storage:link # For local disk
php artisan vendor:publish --tag=media-config to reset defaults.File Validation
.jpg files with malicious content).ValidatesWhen or custom rules:
use PhpMob\MediaBundle\Rules\MimeType;
$request->validate([
'file' => ['required', new MimeType(['image/jpeg', 'image/png'])],
]);
Path Conflicts
path: 'uploads').$mediaManager->upload($file, [
'path' => 'uploads/' . now()->format('Y/m/d'),
]);
Event Listeners
boot() method:
public function boot()
{
Event::listen('media.uploaded', [MediaLogger::class, 'logUpload']);
}
Legacy Code
? for nullable properties if needed).bindIf).Str::slug() → Str::of($str)->slug()).MediaManager::upload():
\Log::debug('Uploading to disk', ['disk' => $config['disk'], 'path' => $path]);
chmod -R 775 storage/app/media
dd($mediaManager->getConfig()) to inspect active settings.Custom Storage Drivers
PhpMob\MediaBundle\Storage\DriverInterface for custom backends (e.g., Google Cloud Storage).Model Bindings
Media model to Eloquent for ORM features:
class Product extends Model
{
public function media()
{
return $this->morphMany(Media::class, 'model');
}
}
API Responses
Resource classes:
class MediaResource extends JsonResource
{
public function toArray($request)
{
return [
'id' => $this->id,
'url' => $this->url,
'size' => $this->size,
'presets' => $this->presets,
];
}
}
Queue Uploads
UploadJob::dispatch($file, $config)->onQueue('media');
(Requires custom job class and queue configuration.)MediaManager::deleteMultiple() for bulk deletes.$mediaManager->upload($file, [
'generate_presets' => true,
]);
How can I help you explore Laravel packages today?