8000 minor #41181 [FrameworkBundle] improve AbstractController::handleForm… · symfony/symfony@1921c78 · GitHub
[go: up one dir, main page]

Skip to content

Commit 1921c78

Browse files
minor #41181 [FrameworkBundle] improve AbstractController::handleForm() (nicolas-grekas)
This PR was merged into the 5.3-dev branch. Discussion ---------- [FrameworkBundle] improve AbstractController::handleForm() | Q | A | ------------- | --- | Branch? | 5.x | Bug fix? | no | New feature? | no | Deprecations? | no | Tickets | ( | License | MIT | Doc PR | - Related to #41178 Commits ------- 7c69682 [FrameworkBundle] improve AbstractController::handleForm()
2 parents 31bd00e + 7c69682 commit 1921c78

File tree

2 files changed

+40
-14
lines changed

2 files changed

+40
-14
lines changed

src/Symfony/Bundle/FrameworkBundle/Controller/AbstractController.php

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -297,23 +297,30 @@ protected function stream(string $view, array $parameters = [], StreamedResponse
297297
* * if the form is submitted but invalid, $render is called and a 422 HTTP status code is set if the current status hasn't been customized
298298
* * if the form is submitted and valid, $onSuccess is called, usually this method saves the data and returns a 303 HTTP redirection
299299
*
300-
* @param callable(FormInterface, mixed): Response $onSuccess
301-
* @param callable(FormInterface, mixed): Response $render
300+
* For both callables, instead of "mixed", you can use your form's data class as a type-hint for argument #2.
301+
*
302+
* @param callable(FormInterface, mixed, Request): Response $onSuccess
303+
* @param callable(FormInterface, mixed, Request): Response $render
302304
*/
303305
public function handleForm(FormInterface $form, Request $request, callable $onSuccess, callable $render): Response
304306
{
305307
$form->handleRequest($request);
306308

307309
$submitted = $form->isSubmitted();
308-
309310
$data = $form->getData();
310-
if ($submitted && $form->isValid()) {
311-
return $onSuccess($form, $data);
311+
312+
if ($isValid = $submitted && $form->isValid()) {
313+
$response = $onSuccess($form, $data, $request);
314+
} else {
315+
$response = $render($form, $data, $request);
316+
317+
if ($submitted && 200 === $response->getStatusCode()) {
318 8000 +
$response->setStatusCode(Response::HTTP_UNPROCESSABLE_ENTITY);
319+
}
312320
}
313321

314-
$response = $render($form, $data);
315-
if ($submitted && 200 === $response->getStatusCode()) {
316-
$response->setStatusCode(Response::HTTP_UNPROCESSABLE_ENTITY);
322+
if (!$response instanceof Response) {
323+
throw new \TypeError(sprintf('The "%s" callable passed to "%s::handleForm()" must return a Response, "%s" returned.', $isValid ? '$onSuccess' : '$render', get_debug_type($this), get_debug_type($response)));
317324
}
318325

319326
return $response;

src/Symfony/Bundle/FrameworkBundle/Tests/Controller/AbstractControllerTest.php

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -433,10 +433,10 @@ public function testHandleFormNotSubmitted()
433433
$response = $controller->handleForm(
434434
$form,
435435
Request::create('https://example.com'),
436-
function (FormInterface $form, $data): Response {
436+
function (FormInterface $form, $data, Request $request): Response {
437437
return new RedirectResponse('https://example.com/redir', Response::HTTP_SEE_OTHER);
438438
},
439-
function (FormInterface $form, $data): Response {
439+
function (FormInterface $form, $data, Request $request): Response {
440440
return new Response('rendered');
441441
}
442442
);
@@ -455,10 +455,10 @@ public function testHandleFormInvalid()
455455
$response = $controller->handleForm(
456456
$form,
457457
Request::create('https://example.com'),
458-
function (FormInterface $form): Response {
458+
function (FormInterface $form, $data, Request $request): Response {
459459
return new RedirectResponse('https://example.com/redir', Response::HTTP_SEE_OTHER);
460460
},
461-
function (FormInterface $form): Response {
461+
function (FormInterface $form, $data, Request $request): Response {
462462
return new Response('rendered');
463463
}
464464
);
@@ -477,10 +477,10 @@ public function testHandleFormValid()
477477
$response = $controller->handleForm(
478478
$form,
479479
Request::create('https://example.com'),
480-
function (FormInterface $form): Response {
480+
function (FormInterface $form, $data, Request $request): Response {
481481
return new RedirectResponse('https://example.com/redir', Response::HTTP_SEE_OTHER);
482482
},
483-
function (FormInterface $form): Response {
483+
function (FormInterface $form, $data, Request $request): Response {
484484
return new Response('rendered');
485485
}
486486
);
@@ -490,6 +490,25 @@ function (FormInterface $form): Response {
490490
$this->assertSame('https://example.com/redir', $response->getTargetUrl());
491491
}
492492

493+
public function testHandleFormTypeError()
494+
{
495+
$form = $this->createMock(FormInterface::class);
496+
$form->expects($this->once())->method('isSubmitted')->willReturn(true);
497+
$form->expects($this->once())->method('isValid')->willReturn(true);
498+
499+
$controller = $this->createController();
500+
501+
$this->expectException(\TypeError::class);
502+
$this->expectExceptionMessage('The "$onSuccess" callable passed to "Symfony\Bundle\FrameworkBundle\Tests\Controller\TestAbstractController::handleForm()" must return a Response, "string" returned.');
503+
504+
$response = $controller->handleForm(
505+
$form,
506+
Request::create('https://example.com'),
507+
function () { return 'abc'; },
508+
function () { return 'abc'; }
509+
);
510+
}
511+
493512
public function testRedirectToRoute()
494513
{
495514
$router = $this->createMock(RouterInterface::class);

0 commit comments

Comments
 (0)
0