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

File Bundle Laravel Package

wbx/file-bundle

A file management bundle for Laravel/PHP applications that simplifies handling uploads, storage, and file attachments. Provides reusable services and helpers for organizing, saving, and serving files across your project with minimal configuration.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install via Composer (the package predates Composer 2 conventions, so pin it explicitly):
    composer require wbx/file-bundle
    
  2. Register the bundle in app/AppKernel.php (Symfony 2/3 style — this is the era the bundle targets):
    $bundles = [
        // ...
        new Wbx\FileBundle\WbxFileBundle(),
    ];
    
  3. Look first at the bundle's Resources/config and its Doctrine subscriber/listener. This is where the upload lifecycle (move file, persist metadata, delete on remove) actually happens. Reading those services tells you more about real behavior than the README.
  4. Configure the upload target. Expect a config block defining a web-accessible directory (e.g. web/uploads) and a filesystem path. Set both to absolute, writable paths — the bundle moves files at the Doctrine event layer, not in your controller.
  5. First use case — attach one file to one entity. Map your entity to the bundle's file entity/trait (via association or inheritance, whichever the bundle documents), add a FileType-style form field, then persist/flush. If configured correctly, the file is copied to the upload directory and the stored path is written to your entity on flush with no controller code beyond the normal form flow.

Implementation Patterns

  • One-to-many attachments. Most day-to-day use is "an Article has many files." Model it as a OneToMany from your entity to the bundle's file entity, with a cascade={"persist","remove"} and a setter that stamps the owning side before adding. The bundle's listener only needs the file object to be flushed alongside its parent.
  • Form pattern. Use CollectionType for multi-file uploads and the bundle's file form type for each entry. Handle additions vs. removals explicitly in the form (allow_add, allow_delete, by_reference => false) so Doctrine sees new file objects rather than mutated collections the listener misses.
  • Controller flow. Keep controllers dumb: validate the form, flush(), redirect. The actual move_uploaded_file/rename happens inside the Doctrine lifecycle callback. This is the main ergonomic win — and the main thing to understand before debugging.
  • Replacing an existing file. Treat replacement as remove old + add new on the owning entity. If you try to overwrite the path in place, the listener has no way to know a new source file exists, and you'll end up with a stale file on disk.
  • Deletion. Rely on the Doctrine postRemove/preRemove hook to unlink from disk. Verify this works in your config — it depends on the bundle receiving the correct upload path. Where it doesn't fire reliably, add an explicit unlink in a service and treat the bundle hook as a fallback.
  • Integration tip — services over controllers. Wrap upload handling in a small service (FileManager) that owns the upload directory and naming convention. That gives you one seam to swap the bundle out later and one place to add virus scanning, image resizing, or S3 sync.

Gotchas and Tips

  • EOL stack. This is a Symfony 2/3-era bundle with its last release in 2019 and no dependents. It will not autowire or register cleanly on Symfony 4+. Budget for vendoring/adapter work before adopting; treat it as a reference implementation rather than a dependency.
  • Events fire at flush time, not at form submit. If the file appears missing or the path is null after persist(), check whether a later flush() is what actually triggers the move, and whether the entity was managed at that moment. Debugging almost always starts at the Doctrine listener.
  • Path configuration is the #1 failure mode. Relative paths resolve against the kernel root, not the web root, and permissions differ in dev vs. prod. Always configure absolute paths and assert is_writable() at boot in dev.
  • Orphaned files. If an entity is deleted without cascade, or a flush fails after the file has been moved, you get files on disk with no owner. Add a periodic reconciliation command; don't rely on the bundle alone.
  • No naming-strategy control by default. If you need deterministic or hashed filenames (for security or cache-busting), expect to subclass the file entity or wrap the upload in a service that pre-renames the source. Sanitize the original filename before it reaches the bundle — filename-based path traversal is a genuine risk in bundles of this vintage.
  • Extension points that are worth knowing: the Doctrine subscriber (override to change move/dedupe behavior), the file entity/trait (override naming and metadata), and the form type (override validation constraints). Everything else is thin glue; don't fight it, wrap it.
  • Debugging tip. Temporarily log inside the listener or attach an Xdebug breakpoint on the postPersist/postUpdate event — silently ignored exceptions in event subscribers are common here and leave you with an uploaded temp file that vanished and a null stored path.
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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin