runroom-packages/form-handler-bundle
Symfony bundle that streamlines form handling with reusable handler services, typed form objects, and validation wiring so controllers stay thin. Integrates with Symfony Forms and Doctrine to process submissions and keep business logic out of controllers.
composer require runroom-packages/form-handler-bundle. If you're on Symfony Flex and a recipe exists, the bundle registers itself; otherwise add Runroom\Packages\FormHandlerBundle\RunroomFormHandlerBundle::class => ['all' => true] to config/bundles.php.vendor/runroom-packages/form-handler-bundle/). The public surface is small — read the FormHandler interface and the abstract base class before anything else, then the service definitions under Resources/config/config. The bundle's real job is to give you a typed object that owns "what happens after $form->isValid()", so the interface is the whole contract.composer.json constraints for the PHP and Symfony versions you're running. This is a low-traffic package, so it will not have been tested against every Symfony minor.handleRequest → isSubmitted && isValid → $handler->handle($form).EntityManagerInterface (or repositories, mailers, dispatchers), implement the handler method, and let it do only the side effects. The FormType stays a pure description of the form; the handler stays a pure description of the consequences.if ($entity->getId() === null) branching inside one controller.$em->wrapInTransaction(...) (or your own beginTransaction/commit with rollback in catch) when the handler performs more than one write. The bundle will not do this for you.void, add a thin wrapper service rather than forking the interface.$this->createForm(...) in a KernelTestCase, submit valid data, assert flush() was called exactly once and the expected flash/event happened.validate → call service → flash → redirect.vcs repository entry, or vendor-patch it.composer.json and be prepared to own it.$em->flush() and then also flush in the controller (or rely on handleRequest doing so). Pick one place. Same for $em->persist() — persist in the handler, flush once, at the end.isValid() is true; if you find yourself throwing domain exceptions for user-input problems, the constraint is missing.FormError, and re-render; let truly unexpected exceptions bubble to the error handler.bin/console debug:container --tag=<handler tag> (check the bundle's service definitions for the exact tag) tells you whether your handler was picked up. If it isn't, you probably forgot the interface implementation or the service isn't public/autoconfigured under services.yaml.bin/console debug:container Your\Handler shows the injected arguments — the fastest way to spot a wrong entity manager (e.g. a second connection) or a missing mailer.Configuration.php). Read it before assuming options exist; do not copy config snippets from blog posts against a different version.handle() bodies back into command/Domain services. Keep your handlers free of bundle-specific types (other than the interface) so that removal is mechanical.How can I help you explore Laravel packages today?