minor #41190 [FrameworkBundle] improve AbstractController::renderForm() (nicolas-grekas)
This PR was merged into the 5.3-dev branch.
Discussion
----------
[FrameworkBundle] improve AbstractController::renderForm()
| Q | A
| ------------- | ---
| Branch? | 5.x
| Bug fix? | no
| New feature? | no
| Deprecations? | no
| Tickets | -
| License | MIT
| Doc PR | -
Even better than #41178, this requires a simple change on apps, and is compatible with multiple forms.
Usage:
```diff
- return $this->render('thing/new.html.twig', [
+ return $this->renderForm('thing/new.html.twig', [
'thing' => $thing,
- 'form' => $form->createView(),
+ 'form' => $form,
]);
```
In 5.4, we could even deprecate passing a FormView to render() so that we can always set the 422.
Commits
-------
e244d31fb0
[FrameworkBundle] improve AbstractController::renderForm()
This commit is contained in:
commit
2ac23c6a33
@ -7,11 +7,11 @@ CHANGELOG
|
|||||||
* Deprecate the `session.storage` alias and `session.storage.*` services, use the `session.storage.factory` alias and `session.storage.factory.*` services instead
|
* Deprecate the `session.storage` alias and `session.storage.*` services, use the `session.storage.factory` alias and `session.storage.factory.*` services instead
|
||||||
* Deprecate the `framework.session.storage_id` configuration option, use the `framework.session.storage_factory_id` configuration option instead
|
* Deprecate the `framework.session.storage_id` configuration option, use the `framework.session.storage_factory_id` configuration option instead
|
||||||
* Deprecate the `session` service and the `SessionInterface` alias, use the `Request::getSession()` or the new `RequestStack::getSession()` methods instead
|
* Deprecate the `session` service and the `SessionInterface` alias, use the `Request::getSession()` or the new `RequestStack::getSession()` methods instead
|
||||||
* Added `AbstractController::renderForm()` to render a form and set the appropriate HTTP status code
|
* Add `AbstractController::renderForm()` to render a form and set the appropriate HTTP status code
|
||||||
* Added support for configuring PHP error level to log levels
|
* Add support for configuring PHP error level to log levels
|
||||||
* Added the `dispatcher` option to `debug:event-dispatcher`
|
* Add the `dispatcher` option to `debug:event-dispatcher`
|
||||||
* Added the `event_dispatcher.dispatcher` tag
|
* Add the `event_dispatcher.dispatcher` tag
|
||||||
* Added `assertResponseFormatSame()` in `BrowserKitAssertionsTrait`
|
* Add `assertResponseFormatSame()` in `BrowserKitAssertionsTrait`
|
||||||
* Add support for configuring UUID factory services
|
* Add support for configuring UUID factory services
|
||||||
* Add tag `assets.package` to register asset packages
|
* Add tag `assets.package` to register asset packages
|
||||||
* Add support to use a PSR-6 compatible cache for Doctrine annotations
|
* Add support to use a PSR-6 compatible cache for Doctrine annotations
|
||||||
|
@ -20,6 +20,7 @@ use Symfony\Component\Form\Extension\Core\Type\FormType;
|
|||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use Symfony\Component\Form\FormFactoryInterface;
|
use Symfony\Component\Form\FormFactoryInterface;
|
||||||
use Symfony\Component\Form\FormInterface;
|
use Symfony\Component\Form\FormInterface;
|
||||||
|
use Symfony\Component\Form\FormView;
|
||||||
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
use Symfony\Component\HttpFoundation\BinaryFileResponse;
|
||||||
use Symfony\Component\HttpFoundation\Exception\SessionNotFoundException;
|
use Symfony\Component\HttpFoundation\Exception\SessionNotFoundException;
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
@ -267,21 +268,33 @@ abstract class AbstractController implements ServiceSubscriberInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders a view for a form.
|
* Renders a view and sets the appropriate status code when a form is listed in parameters.
|
||||||
*
|
*
|
||||||
* The FormView instance is passed to the template in a variable named
|
* If an invalid form is found in the list of parameters, a 422 status code is returned.
|
||||||
* "form" (can be changed via $formVar argument).
|
|
||||||
* If the form is invalid, a 422 status code is returned.
|
|
||||||
*/
|
*/
|
||||||
protected function renderForm(string $view, FormInterface $form, array $parameters = [], Response $response = null, string $formVar = 'form'): Response
|
protected function renderForm(string $view, array $parameters = [], Response $response = null): Response
|
||||||
{
|
{
|
||||||
$response = $this->render($view, [$formVar => $form->createView()] + $parameters, $response);
|
if (null === $response) {
|
||||||
|
$response = new Response();
|
||||||
if ($form->isSubmitted() && !$form->isValid()) {
|
|
||||||
$response->setStatusCode(422);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -420,7 +420,7 @@ class AbstractControllerTest extends TestCase
|
|||||||
$form->expects($this->once())->method('createView')->willReturn($formView);
|
$form->expects($this->once())->method('createView')->willReturn($formView);
|
||||||
|
|
||||||
$twig = $this->getMockBuilder(Environment::class)->disableOriginalConstructor()->getMock();
|
$twig = $this->getMockBuilder(Environment::class)->disableOriginalConstructor()->getMock();
|
||||||
$twig->expects($this->once())->method('render')->with('foo', ['form' => $formView, 'bar' => 'bar'])->willReturn('bar');
|
$twig->expects($this->once())->method('render')->with('foo', ['bar' => $formView])->willReturn('bar');
|
||||||
|
|
||||||
$container = new Container();
|
$container = new Container();
|
||||||
$container->set('twig', $twig);
|
$container->set('twig', $twig);
|
||||||
@ -428,7 +428,7 @@ class AbstractControllerTest extends TestCase
|
|||||||
$controller = $this->createController();
|
$controller = $this->createController();
|
||||||
$controller->setContainer($container);
|
$controller->setContainer($container);
|
||||||
|
|
||||||
$response = $controller->renderForm('foo', $form, ['bar' => 'bar']);
|
$response = $controller->renderForm('foo', ['bar' => $form]);
|
||||||
|
|
||||||
$this->assertTrue($response->isSuccessful());
|
$this->assertTrue($response->isSuccessful());
|
||||||
$this->assertSame('bar', $response->getContent());
|
$this->assertSame('bar', $response->getContent());
|
||||||
@ -444,7 +444,7 @@ class AbstractControllerTest extends TestCase
|
|||||||
$form->expects($this->once())->method('isValid')->willReturn(false);
|
$form->expects($this->once())->method('isValid')->willReturn(false);
|
||||||
|
|
||||||
$twig = $this->getMockBuilder(Environment::class)->disableOriginalConstructor()->getMock();
|
$twig = $this->getMockBuilder(Environment::class)->disableOriginalConstructor()->getMock();
|
||||||
$twig->expects($this->once())->method('render')->with('foo', ['myForm' => $formView, 'bar' => 'bar'])->willReturn('bar');
|
$twig->expects($this->once())->method('render')->with('foo', ['bar' => $formView])->willReturn('bar');
|
||||||
|
|
||||||
$container = new Container();
|
$container = new Container();
|
||||||
$container->set('twig', $twig);
|
$container->set('twig', $twig);
|
||||||
@ -452,7 +452,7 @@ class AbstractControllerTest extends TestCase
|
|||||||
$controller = $this->createController();
|
$controller = $this->createController();
|
||||||
$controller->setContainer($container);
|
$controller->setContainer($container);
|
||||||
|
|
||||||
$response = $controller->renderForm('foo', $form, ['bar' => 'bar'], null, 'myForm');
|
$response = $controller->renderForm('foo', ['bar' => $form]);
|
||||||
|
|
||||||
$this->assertSame(422, $response->getStatusCode());
|
$this->assertSame(422, $response->getStatusCode());
|
||||||
$this->assertSame('bar', $response->getContent());
|
$this->assertSame('bar', $response->getContent());
|
||||||
|
Reference in New Issue
Block a user