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
-------
7c69682775
[FrameworkBundle] improve AbstractController::handleForm()
This commit is contained in:
commit
1921c78c7f
@ -297,24 +297,31 @@ abstract class AbstractController implements ServiceSubscriberInterface
|
|||||||
* * 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
|
* * 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
|
||||||
* * if the form is submitted and valid, $onSuccess is called, usually this method saves the data and returns a 303 HTTP redirection
|
* * if the form is submitted and valid, $onSuccess is called, usually this method saves the data and returns a 303 HTTP redirection
|
||||||
*
|
*
|
||||||
* @param callable(FormInterface, mixed): Response $onSuccess
|
* For both callables, instead of "mixed", you can use your form's data class as a type-hint for argument #2.
|
||||||
* @param callable(FormInterface, mixed): Response $render
|
*
|
||||||
|
* @param callable(FormInterface, mixed, Request): Response $onSuccess
|
||||||
|
* @param callable(FormInterface, mixed, Request): Response $render
|
||||||
*/
|
*/
|
||||||
public function handleForm(FormInterface $form, Request $request, callable $onSuccess, callable $render): Response
|
public function handleForm(FormInterface $form, Request $request, callable $onSuccess, callable $render): Response
|
||||||
{
|
{
|
||||||
$form->handleRequest($request);
|
$form->handleRequest($request);
|
||||||
|
|
||||||
$submitted = $form->isSubmitted();
|
$submitted = $form->isSubmitted();
|
||||||
|
|
||||||
$data = $form->getData();
|
$data = $form->getData();
|
||||||
if ($submitted && $form->isValid()) {
|
|
||||||
return $onSuccess($form, $data);
|
|
||||||
}
|
|
||||||
|
|
||||||
$response = $render($form, $data);
|
if ($isValid = $submitted && $form->isValid()) {
|
||||||
|
$response = $onSuccess($form, $data, $request);
|
||||||
|
} else {
|
||||||
|
$response = $render($form, $data, $request);
|
||||||
|
|
||||||
if ($submitted && 200 === $response->getStatusCode()) {
|
if ($submitted && 200 === $response->getStatusCode()) {
|
||||||
$response->setStatusCode(Response::HTTP_UNPROCESSABLE_ENTITY);
|
$response->setStatusCode(Response::HTTP_UNPROCESSABLE_ENTITY);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$response instanceof Response) {
|
||||||
|
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)));
|
||||||
|
}
|
||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
@ -433,10 +433,10 @@ class AbstractControllerTest extends TestCase
|
|||||||
$response = $controller->handleForm(
|
$response = $controller->handleForm(
|
||||||
$form,
|
$form,
|
||||||
Request::create('https://example.com'),
|
Request::create('https://example.com'),
|
||||||
function (FormInterface $form, $data): Response {
|
function (FormInterface $form, $data, Request $request): Response {
|
||||||
return new RedirectResponse('https://example.com/redir', Response::HTTP_SEE_OTHER);
|
return new RedirectResponse('https://example.com/redir', Response::HTTP_SEE_OTHER);
|
||||||
},
|
},
|
||||||
function (FormInterface $form, $data): Response {
|
function (FormInterface $form, $data, Request $request): Response {
|
||||||
return new Response('rendered');
|
return new Response('rendered');
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -455,10 +455,10 @@ class AbstractControllerTest extends TestCase
|
|||||||
$response = $controller->handleForm(
|
$response = $controller->handleForm(
|
||||||
$form,
|
$form,
|
||||||
Request::create('https://example.com'),
|
Request::create('https://example.com'),
|
||||||
function (FormInterface $form): Response {
|
function (FormInterface $form, $data, Request $request): Response {
|
||||||
return new RedirectResponse('https://example.com/redir', Response::HTTP_SEE_OTHER);
|
return new RedirectResponse('https://example.com/redir', Response::HTTP_SEE_OTHER);
|
||||||
},
|
},
|
||||||
function (FormInterface $form): Response {
|
function (FormInterface $form, $data, Request $request): Response {
|
||||||
return new Response('rendered');
|
return new Response('rendered');
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -477,10 +477,10 @@ class AbstractControllerTest extends TestCase
|
|||||||
$response = $controller->handleForm(
|
$response = $controller->handleForm(
|
||||||
$form,
|
$form,
|
||||||
Request::create('https://example.com'),
|
Request::create('https://example.com'),
|
||||||
function (FormInterface $form): Response {
|
function (FormInterface $form, $data, Request $request): Response {
|
||||||
return new RedirectResponse('https://example.com/redir', Response::HTTP_SEE_OTHER);
|
return new RedirectResponse('https://example.com/redir', Response::HTTP_SEE_OTHER);
|
||||||
},
|
},
|
||||||
function (FormInterface $form): Response {
|
function (FormInterface $form, $data, Request $request): Response {
|
||||||
return new Response('rendered');
|
return new Response('rendered');
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -490,6 +490,25 @@ class AbstractControllerTest extends TestCase
|
|||||||
$this->assertSame('https://example.com/redir', $response->getTargetUrl());
|
$this->assertSame('https://example.com/redir', $response->getTargetUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testHandleFormTypeError()
|
||||||
|
{
|
||||||
|
$form = $this->createMock(FormInterface::class);
|
||||||
|
$form->expects($this->once())->method('isSubmitted')->willReturn(true);
|
||||||
|
$form->expects($this->once())->method('isValid')->willReturn(true);
|
||||||
|
|
||||||
|
$controller = $this->createController();
|
||||||
|
|
||||||
|
$this->expectException(\TypeError::class);
|
||||||
|
$this->expectExceptionMessage('The "$onSuccess" callable passed to "Symfony\Bundle\FrameworkBundle\Tests\Controller\TestAbstractController::handleForm()" must return a Response, "string" returned.');
|
||||||
|
|
||||||
|
$response = $controller->handleForm(
|
||||||
|
$form,
|
||||||
|
Request::create('https://example.com'),
|
||||||
|
function () { return 'abc'; },
|
||||||
|
function () { return 'abc'; }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function testRedirectToRoute()
|
public function testRedirectToRoute()
|
||||||
{
|
{
|
||||||
$router = $this->createMock(RouterInterface::class);
|
$router = $this->createMock(RouterInterface::class);
|
||||||
|
Reference in New Issue
Block a user