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.
composer require wbx/file-bundle
app/AppKernel.php (Symfony 2/3 style — this is the era the bundle targets):
$bundles = [
// ...
new Wbx\FileBundle\WbxFileBundle(),
];
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.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.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.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.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.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.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.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.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.is_writable() at boot in dev.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.How can I help you explore Laravel packages today?