Skip to content

Commit 92bb873

Browse files
authored
Fix that invalid form returns http 422 status code (#388)
1 parent 91b7157 commit 92bb873

File tree

4 files changed

+56
-3
lines changed

4 files changed

+56
-3
lines changed

Event/RequestListener.php

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,12 @@
1717
use Sulu\Bundle\FormBundle\Form\HandlerInterface;
1818
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
1919
use Symfony\Component\HttpFoundation\RedirectResponse;
20+
use Symfony\Component\HttpFoundation\Response;
2021
use Symfony\Component\HttpKernel\Event\RequestEvent;
22+
use Symfony\Component\HttpKernel\Event\ResponseEvent;
23+
use Symfony\Contracts\Service\ResetInterface;
2124

22-
class RequestListener
25+
class RequestListener implements ResetInterface
2326
{
2427
/**
2528
* @var BuilderInterface
@@ -41,6 +44,14 @@ class RequestListener
4144
*/
4245
protected $eventDispatcher;
4346

47+
/**
48+
* Flag set to true when an invalid form is submitted,
49+
* so we can set the http return code to 422.
50+
*
51+
* @var bool
52+
*/
53+
protected $invalidSubmittedForm = false;
54+
4455
/**
4556
* RequestListener constructor.
4657
*/
@@ -73,10 +84,16 @@ public function onKernelRequest(RequestEvent $event): void
7384
try {
7485
$form = $this->formBuilder->buildByRequest($request);
7586

76-
if (!$form || !$form->isSubmitted() || !$form->isValid()) {
87+
if (!$form || !$form->isSubmitted()) {
7788
// do nothing when no form was found or not valid
7889
return;
7990
}
91+
92+
if (!$form->isValid()) {
93+
$this->invalidSubmittedForm = true;
94+
95+
return;
96+
}
8097
} catch (\Exception $e) {
8198
// Catch all exception on build form by request
8299
return;
@@ -96,4 +113,24 @@ public function onKernelRequest(RequestEvent $event): void
96113
$event->setResponse($response);
97114
}
98115
}
116+
117+
public function onKernelResponse(ResponseEvent $event): void
118+
{
119+
if (\method_exists($event, 'isMainRequest') ? !$event->isMainRequest() : !$event->isMasterRequest()) {
120+
// do nothing if it's not the master request
121+
return;
122+
}
123+
124+
if ($this->invalidSubmittedForm) {
125+
$response = $event->getResponse();
126+
$response->setStatusCode(Response::HTTP_UNPROCESSABLE_ENTITY);
127+
128+
$event->setResponse($response);
129+
}
130+
}
131+
132+
public function reset(): void
133+
{
134+
$this->invalidSubmittedForm = false;
135+
}
99136
}

Resources/config/services.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@
104104
<argument type="service" id="event_dispatcher" />
105105

106106
<tag name="kernel.event_listener" event="kernel.request" method="onKernelRequest" />
107+
<tag name="kernel.event_listener" event="kernel.response" method="onKernelResponse" />
108+
<tag name="kernel.reset" method="reset" />
107109
</service>
108110

109111
<!-- List Builder -->

Tests/Functional/Mail/HelperTestCase.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,22 @@ protected function doSendForm(Form $form): void
7272
$formSelector = \sprintf('form[name=%s]', $formName);
7373
$this->assertEquals(1, $crawler->filter($formSelector)->count());
7474

75+
$formElm = $crawler->filter($formSelector)->first()->form([
76+
$formName . '[email]' => '',
77+
$formName . '[email1]' => '',
78+
]);
79+
80+
$this->client->enableProfiler();
81+
$crawler = $this->client->submit($formElm);
82+
$this->assertResponseStatusCodeSame(422);
83+
7584
$formElm = $crawler->filter($formSelector)->first()->form([
7685
$formName . '[email]' => 'test@example.org',
7786
$formName . '[email1]' => 'jon@example.org',
7887
]);
7988

80-
$this->client->enableProfiler();
8189
$this->client->submit($formElm);
90+
$this->assertResponseStatusCodeSame(302);
8291
$this->assertResponseRedirects('?send=true');
8392
}
8493
}

phpstan-baseline.neon

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -805,6 +805,11 @@ parameters:
805805
count: 1
806806
path: Event/RequestListener.php
807807

808+
-
809+
message: "#^Call to an undefined method Symfony\\\\Component\\\\HttpKernel\\\\Event\\\\ResponseEvent\\:\\:isMasterRequest\\(\\)\\.$#"
810+
count: 1
811+
path: Event/RequestListener.php
812+
808813
-
809814
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$#"
810815
count: 1

0 commit comments

Comments
 (0)