Skip to content

Commit

Permalink
Fix that invalid form returns http 422 status code (#388)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jupi007 authored Jul 24, 2024
1 parent 91b7157 commit 92bb873
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 3 deletions.
41 changes: 39 additions & 2 deletions Event/RequestListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@
use Sulu\Bundle\FormBundle\Form\HandlerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Contracts\Service\ResetInterface;

class RequestListener
class RequestListener implements ResetInterface
{
/**
* @var BuilderInterface
Expand All @@ -41,6 +44,14 @@ class RequestListener
*/
protected $eventDispatcher;

/**
* Flag set to true when an invalid form is submitted,
* so we can set the http return code to 422.
*
* @var bool
*/
protected $invalidSubmittedForm = false;

/**
* RequestListener constructor.
*/
Expand Down Expand Up @@ -73,10 +84,16 @@ public function onKernelRequest(RequestEvent $event): void
try {
$form = $this->formBuilder->buildByRequest($request);

if (!$form || !$form->isSubmitted() || !$form->isValid()) {
if (!$form || !$form->isSubmitted()) {
// do nothing when no form was found or not valid
return;
}

if (!$form->isValid()) {
$this->invalidSubmittedForm = true;

return;
}
} catch (\Exception $e) {
// Catch all exception on build form by request
return;
Expand All @@ -96,4 +113,24 @@ public function onKernelRequest(RequestEvent $event): void
$event->setResponse($response);
}
}

public function onKernelResponse(ResponseEvent $event): void
{
if (\method_exists($event, 'isMainRequest') ? !$event->isMainRequest() : !$event->isMasterRequest()) {
// do nothing if it's not the master request
return;
}

if ($this->invalidSubmittedForm) {
$response = $event->getResponse();
$response->setStatusCode(Response::HTTP_UNPROCESSABLE_ENTITY);

$event->setResponse($response);
}
}

public function reset(): void
{
$this->invalidSubmittedForm = false;
}
}
2 changes: 2 additions & 0 deletions Resources/config/services.xml
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@
<argument type="service" id="event_dispatcher" />

<tag name="kernel.event_listener" event="kernel.request" method="onKernelRequest" />
<tag name="kernel.event_listener" event="kernel.response" method="onKernelResponse" />
<tag name="kernel.reset" method="reset" />
</service>

<!-- List Builder -->
Expand Down
11 changes: 10 additions & 1 deletion Tests/Functional/Mail/HelperTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,22 @@ protected function doSendForm(Form $form): void
$formSelector = \sprintf('form[name=%s]', $formName);
$this->assertEquals(1, $crawler->filter($formSelector)->count());

$formElm = $crawler->filter($formSelector)->first()->form([
$formName . '[email]' => '',
$formName . '[email1]' => '',
]);

$this->client->enableProfiler();
$crawler = $this->client->submit($formElm);
$this->assertResponseStatusCodeSame(422);

$formElm = $crawler->filter($formSelector)->first()->form([
$formName . '[email]' => '[email protected]',
$formName . '[email1]' => '[email protected]',
]);

$this->client->enableProfiler();
$this->client->submit($formElm);
$this->assertResponseStatusCodeSame(302);
$this->assertResponseRedirects('?send=true');
}
}
5 changes: 5 additions & 0 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -805,6 +805,11 @@ parameters:
count: 1
path: Event/RequestListener.php

-
message: "#^Call to an undefined method Symfony\\\\Component\\\\HttpKernel\\\\Event\\\\ResponseEvent\\:\\:isMasterRequest\\(\\)\\.$#"
count: 1
path: Event/RequestListener.php

-
message: "#^In method \"Sulu\\\\Bundle\\\\FormBundle\\\\Event\\\\RequestListener\\:\\:onKernelRequest\", caught \"Exception\" must be rethrown\\. Either catch a more specific exception or add a \"throw\" clause in the \"catch\" block to propagate the exception\\. More info\\: http\\://bit\\.ly/failloud$#"
count: 1
Expand Down

0 comments on commit 92bb873

Please sign in to comment.