silasjoisten/sonata-multiupload-bundle
Sonata MultiUpload Bundle adds multiple-file upload support to Sonata Admin, letting you attach several files to a form field in one go with a drag-and-drop interface. It integrates a multi-upload widget into admin forms, simplifying media and document management in Symfony projects.
This is not a Laravel package — it is a Symfony bundle for Sonata Admin. You cannot install it into a Laravel application. Use it when you are maintaining a Symfony + Sonata Admin project and need multi-file uploads inside admin forms.
Minimum steps:
composer require silasjoisten/sonata-multiupload-bundle:^4.0.1
Register the bundle in config/bundles.php:
SilasJoisten\Sonata\MultiUploadBundle\SonataMultiUploadBundle::class => ['all' => true],
Then install/copy the bundle assets so the upload widget and modal behaviour work:
bin/console assets:install public
bin/console cache:clear
Where to look first:
README.md for the current supported Sonata/Symfony versions and configuration keys.src/Form/Type/ for the multi-upload form type and its options.src/Controller/ for the upload endpoint and controller-decoration behaviour.src/Resources/public/ for the JavaScript that drives the modal/collection upload UX.DependencyInjection/Configuration.php for available bundle config.First use case: add the bundle’s multi-upload form type to a Sonata Admin class that manages a collection of files or images:
use SilasJoisten\Sonata\MultiUploadBundle\Form\Type\MultiUploadType;
protected function configureFormFields(FormMapper $form): void
{
$form->add('files', MultiUploadType::class, [
'multiple' => true,
]);
}
Verify the full path: create an entity with a OneToMany file collection, add the form type, upload several files, save, and confirm both the file records and physical files are persisted.
Admin collection integration. The main pattern is a Sonata Admin form containing a collection of uploadable entities. Configure the Doctrine association with cascade: ['persist'], orphanRemoval: true, and use by_reference => false on the form field so Doctrine receives the updated collection.
Nested collection modals. The 4.0.1 fix prevents the multi-upload widget from rendering inside a collection modal where it should not appear. If your admin has a collection of galleries/items, each with its own file collection, this is the release to take. Test the modal open/save flow, not just the top-level form.
Custom upload controller. 4.0.1 makes decorating the default controller optional. If you previously fought the bundle because it replaced/decorated your own upload controller, use this release to disable the decoration and keep your controller. Look for the bundle’s controller service/configuration in debug:container and Configuration.php, then either:
This is the main extension point added in 4.0.1. Do not keep an old local service override that decorates the same controller unless you have verified it does not double-decorate.
Separate upload storage from display. Treat the bundle as the form/upload UI, not the whole file lifecycle. Move uploaded files in a service or Doctrine lifecycle callback, generate safe filenames, and store metadata (originalName, mimeType, size) on your entity. For richer media handling, Sonata Media Bundle is the heavier alternative; this bundle is a lighter fit when you already own the file entity.
Asset integration. If your admin uses Webpack Encore, AssetMapper, or a custom Sonata template, confirm the bundle’s JavaScript is loaded on pages where the widget appears. For dynamically loaded modal content, initialize or re-bind the widget after the modal Ajax response rather than relying only on DOMContentLoaded.
config/multiupload.php publish step, and no Laravel filesystem integration. This is Symfony/Sonata only.composer update, clear the Symfony cache, and reinstall/copy assets. Stale JavaScript is a common cause of “the fix didn’t work”.bin/console debug:container | grep -i multiupload
bin/console debug:router | grep -i upload
upload_max_filesize and post_max_size, plus Nginx’s client_max_body_size. A silent failure often means the request was rejected before Symfony saw it. Check server logs and the browser network tab.public/, ensure dangerous file types cannot be executed.cascade: persist means files appear uploaded but no records are saved. Missing orphanRemoval means deleted files remain. Missing by_reference => false can cause the collection not to update.var/log/dev.log, and verify the Sonata Admin template actually includes the bundle’s assets.How can I help you explore Laravel packages today?