Weave 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

liverbool/media-bundle

liverbool/media-bundle is a Symfony bundle for managing media assets and uploads, offering storage integration, image processing, and flexible configuration for attaching files to application entities. It helps developers add reusable media handling to Symfony projects without building upload and fi...

View on GitHub
Deep Wiki
Context7

Getting Started

First, correct the premise. Despite the "Laravel package" framing, liverbool/dos-media-bundle (published as liverbool/media-bundle) is a Symfony/Sylius bundle from 2016 — zero stars, zero dependents, last release 2016-05-24. There is no ServiceProvider, no package discovery, and its composer.json will require symfony/*, doctrine/*, and sylius/*. The description.md feature list is boilerplate and should not be used to scope work.

Step 0 — confirm stack fit before anything else:

composer show liverbool/media-bundle          # requires/type, if already installed
composer require liverbool/media-bundle --dry-run   # expect resolution failure

If the second command doesn't produce a working dependency graph against your PHP/Symfony constraints (the expected result on anything modern), stop. Do not use --ignore-platform-reqs to force it.

If you inherited it in a legacy Sylius app, read in this order:

  1. composer.json — PHP/Symfony/Sylius constraints and transitive pins.
  2. DependencyInjection/Configuration.php — the authoritative config tree (the README, if any, is not).
  3. Model/ and Resources/config/doctrine/ — interfaces to implement and mapped superclasses to extend.
  4. Uploader/ (or equivalent), EventListener/, Form/Type/ — the actual upload flow.
  5. Resources/config/routing.* — only relevant if you use the built-in upload/download controllers.

The day-to-day Laravel answer: don't use this package — use spatie/laravel-medialibrary (polymorphic attachment, collections, conversions, multi-disk) on top of Storage/Flysystem. First use case to learn that stack: attach an image to a model and generate a thumbnail.

composer require spatie/laravel-medialibrary
php artisan vendor:publish --provider="Spatie\MediaLibrary\MediaLibraryServiceProvider" --tag=migrations
php artisan migrate
class Product extends Model implements HasMedia
{
    use InteractsWithMedia;

    public function registerMediaCollections(): void
    {
        $this->addMediaCollection('images')->useDisk('s3');
    }

    public function registerMediaConversions(?Media $media = null): void
    {
        $this->addMediaConversion('thumb')->width(300)->queued();
    }
}
$product->addMediaFromRequest('image')->toMediaCollection('images');
$product->getFirstMediaUrl('images', 'thumb');

That exercises the whole flow — model relation, disk config, derivative generation, URL rendering — and is the fastest way to see what this bundle would have done if it were maintained.

Concept mapping (for porting or reading the bundle as prior art):

Bundle concept Laravel equivalent
Media Doctrine entity, OneToOne/OneToMany media table + HasMedia polymorphic relation
upload_dir / upload_path config filesystems.disks.* + Storage::disk()
Uploader service writing to web root addMediaFromRequest()->toMediaCollection()
Path helper in Twig getFirstMediaUrl() / Storage::url()
Form type + upload listener Form request validation + addMediaFromRequest()

Implementation Patterns

Pattern A — replace, don't wrap (recommended). The bundle's capabilities are superseded on both stacks. On Laravel, reach for:

  • Spatie Media Library — attachments, collections, conversions, responsive images, multi-disk.
  • Laravel Filesystem + Flysystem — S3/GCS adapters, temporary/signed URLs.
  • Intervention Image or Glide — derivative generation, queued.

Workflow:

  1. Create a media table with polymorphic model_type/model_id, uuid, collection_name, disk, file_name, mime_type, size, generated_conversions.
  2. Model implements HasMedia; register collections and conversions per model.
  3. Validate uploads in a FormRequest (mimes, max, image dimensions) before the model touches the disk.
  4. Dispatch conversions on a queue; never generate derivatives on the request path.
  5. Serve private assets via temporaryUrl(), not a public /media path.

Pattern B — contain a legacy Sylius install, then retire it. When the bundle is already in production:

  1. Inventory — grep service IDs, entity classes, Twig helpers, routes, and config keys.
  2. Contain — vendor the source into the monorepo (or a private VCS fork) and pin the exact commit; freeze transitive dependencies with composer.lock committed and --prefer-dist disabled.
  3. Abstract — introduce an internal interface (store, retrieve, delete, url) at every call site so the bundle becomes swappable.
  4. Reimplement — back the interface with Sylius core media + Flysystem (Sylius side) or Spatie + Storage (Laravel side).
  5. Backfill / dual-write — copy existing media rows and files, verify checksums and public URLs, cut reads over.
  6. Decommission — remove from composer.json before the next framework upgrade, not during it.

Laravel-side integration tips:

  • Add ON DELETE CASCADE or a deleted model observer, plus $model->clearMediaCollection() on purge, to avoid orphaned files.
  • Normalize filenames (uuid/hash prefix) — never trust the client filename.
  • Keep public and private disks distinct; add a separate disk per collection.
  • Use Storage::fake() in tests and assert both rows and disk contents:
Storage::fake('images');
$product->addMediaFromString('x')->usingFileName('a.jpg')->toMediaCollection('images');
Storage::disk('images')->assertExists(...);
$this->assertDatabaseHas('media', ['model_id' => $product->id]);

Reference-only use. If you're designing an in-house media module, skim the bundle's Model/ layout (interface vs mapped superclass separation) in one sitting — then build against maintained libraries. Do not vendor it as a runtime dependency.

Gotchas and Tips

  • Trust the repo, not description.md. The feature list ("Laravel-friendly configuration", polymorphic Eloquent relations) is generated boilerplate. Verify claims against composer.json and source, every time.
  • Identity mismatch is the #1 trap. The repo is dos-media-bundle, published as media-bundle, vendored under liverbool. Don't infer bundle class names from the package name — grep -r "class .*Bundle" vendor/liverbool/media-bundle/src/ before touching the kernel.
  • No service provider, no discovery. In Laravel it will simply sit inert in vendor/ — or, worse, be autoloaded and register nothing, giving you false confidence. Confirm with composer show before assuming it can do anything.
  • Config split is error-prone in the original. upload_dir (filesystem root) vs upload_path (web path) must stay consistent, and %kernel.root_dir% vs %kernel.project_dir% differ across Symfony versions. In Laravel terms: treat the equivalent of "path on disk" and "public URL prefix" as separate, explicit config values.
  • Mapped superclass vs own entity. The bundle ships a base Media class you extend; getting Doctrine inheritance and the schema right when porting to a migration is a common source of silent column drift. Diff the generated schema against the new one before backfill.
  • Orphaned files. Deleting the owning entity usually doesn't delete the file, and replacing a file usually leaves the old row. Audit both directions before and after any port.
  • Filename collisions. Older uploaders frequently reuse the client-supplied name; two photo.jpg uploads overwrite each other. Assume collisions and generate unique names unconditionally.
  • Upload surface is the highest-risk area. Path traversal, unrestricted MIME types, and public serving of private files are all realistic failure modes here — and there are no advisory feeds covering a 2016 dependency graph. Add it to the supply-chain risk register.
  • Debugging (legacy Sylius): bin/console debug:container | grep -i media, debug:router, lint:yaml config, and clear the cache after any config change — many DI errors surface only at cache warmup.
  • Debugging (Laravel replacement): php artisan about, php artisan route:list, Storage::disk('x')->exists($path) as a ground-truth check, Event::fake() to isolate upload listeners, and Model::preventLazyLoading() to catch N+1s on media relations.
  • Extension points to plan for up front: custom path generator, custom URL generator, per-collection disk selection, custom conversions. Spatie exposes all four; if you build in-house, expose the same seams so you don't rewrite call sites later.
  • Never force-install. --ignore-platform-reqs on a decade-old dependency produces compile-time container errors and Doctrine incompatibilities that aren't worth the debugging debt. Verify with --dry-run and walk away on failure.
  • Sequencing, if inherited: removal of this bundle must land before the framework upgrade, otherwise the unresolvable package blocks the upgrade entirely.
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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource