From 1127c3d2aab8830ebade0b2f42ee751a0e70bbc1 Mon Sep 17 00:00:00 2001 From: belmeopmenieuwesim Date: Wed, 27 Jul 2022 22:41:55 +0200 Subject: [PATCH] Return a proper 422 HTTP status code when the form submission fails This also brings support for Symfony UX Turbo --- src/Bundle/Controller/ControllerTrait.php | 31 ++++++++++++++++++++ src/Bundle/Controller/ResourceController.php | 8 ++--- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/Bundle/Controller/ControllerTrait.php b/src/Bundle/Controller/ControllerTrait.php index 9bcf20717..d73dc9cd6 100644 --- a/src/Bundle/Controller/ControllerTrait.php +++ b/src/Bundle/Controller/ControllerTrait.php @@ -17,6 +17,7 @@ use Symfony\Component\Form\Extension\Core\Type\FormType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormInterface; +use Symfony\Component\Form\FormView; use Symfony\Component\HttpFoundation\BinaryFileResponse; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\RedirectResponse; @@ -246,6 +247,36 @@ protected function render(string $view, array $parameters = [], Response $respon return $response; } + /** + * Renders a view and sets the appropriate status code when a form is listed in parameters. + * + * If an invalid form is found in the list of parameters, a 422 status code is returned. + */ + protected function renderForm(string $view, array $parameters = [], Response $response = null): Response + { + if (null === $response) { + $response = new Response(); + } + + foreach ($parameters as $k => $v) { + if ($v instanceof FormView) { + throw new \LogicException(sprintf('Passing a FormView to "%s::renderForm()" is not supported, pass directly the form instead for parameter "%s".', get_debug_type($this), $k)); + } + + if (!$v instanceof FormInterface) { + continue; + } + + $parameters[$k] = $v->createView(); + + if (200 === $response->getStatusCode() && $v->isSubmitted() && !$v->isValid()) { + $response->setStatusCode(422); + } + } + + return $this->render($view, $parameters, $response); + } + /** * Streams a view. * diff --git a/src/Bundle/Controller/ResourceController.php b/src/Bundle/Controller/ResourceController.php index 277435f35..e793bc9eb 100644 --- a/src/Bundle/Controller/ResourceController.php +++ b/src/Bundle/Controller/ResourceController.php @@ -223,12 +223,12 @@ public function createAction(Request $request): Response return $initializeEventResponse; } - return $this->render($configuration->getTemplate(ResourceActions::CREATE . '.html'), [ + return $this->renderForm($configuration->getTemplate(ResourceActions::CREATE . '.html'), [ 'configuration' => $configuration, 'metadata' => $this->metadata, 'resource' => $newResource, $this->metadata->getName() => $newResource, - 'form' => $form->createView(), + 'form' => $form, ]); } @@ -310,12 +310,12 @@ public function updateAction(Request $request): Response return $initializeEventResponse; } - return $this->render($configuration->getTemplate(ResourceActions::UPDATE . '.html'), [ + return $this->renderForm($configuration->getTemplate(ResourceActions::UPDATE . '.html'), [ 'configuration' => $configuration, 'metadata' => $this->metadata, 'resource' => $resource, $this->metadata->getName() => $resource, - 'form' => $form->createView(), + 'form' => $form, ]); }