FormController.php 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. <?php
  2. namespace Drupal\Core\Controller;
  3. use Drupal\Core\DependencyInjection\DependencySerializationTrait;
  4. use Drupal\Core\Form\FormBuilderInterface;
  5. use Drupal\Core\Form\FormState;
  6. use Drupal\Core\Routing\RouteMatchInterface;
  7. use Symfony\Component\HttpFoundation\Request;
  8. /**
  9. * Common base class for form interstitial controllers.
  10. *
  11. * @todo Make this a trait in PHP 5.4.
  12. */
  13. abstract class FormController {
  14. use DependencySerializationTrait;
  15. /**
  16. * The controller resolver.
  17. *
  18. * @var \Drupal\Core\Controller\ControllerResolverInterface
  19. */
  20. protected $controllerResolver;
  21. /**
  22. * The form builder.
  23. *
  24. * @var \Drupal\Core\Form\FormBuilderInterface
  25. */
  26. protected $formBuilder;
  27. /**
  28. * Constructs a new \Drupal\Core\Controller\FormController object.
  29. *
  30. * @param \Drupal\Core\Controller\ControllerResolverInterface $controller_resolver
  31. * The controller resolver.
  32. * @param \Drupal\Core\Form\FormBuilderInterface $form_builder
  33. * The form builder.
  34. */
  35. public function __construct(ControllerResolverInterface $controller_resolver, FormBuilderInterface $form_builder) {
  36. $this->controllerResolver = $controller_resolver;
  37. $this->formBuilder = $form_builder;
  38. }
  39. /**
  40. * Invokes the form and returns the result.
  41. *
  42. * @param \Symfony\Component\HttpFoundation\Request $request
  43. * The request object.
  44. * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
  45. * The route match.
  46. *
  47. * @return array
  48. * The render array that results from invoking the controller.
  49. */
  50. public function getContentResult(Request $request, RouteMatchInterface $route_match) {
  51. $form_arg = $this->getFormArgument($route_match);
  52. $form_object = $this->getFormObject($route_match, $form_arg);
  53. // Add the form and form_state to trick the getArguments method of the
  54. // controller resolver.
  55. $form_state = new FormState();
  56. $request->attributes->set('form', []);
  57. $request->attributes->set('form_state', $form_state);
  58. $args = $this->controllerResolver->getArguments($request, [$form_object, 'buildForm']);
  59. $request->attributes->remove('form');
  60. $request->attributes->remove('form_state');
  61. // Remove $form and $form_state from the arguments, and re-index them.
  62. unset($args[0], $args[1]);
  63. $form_state->addBuildInfo('args', array_values($args));
  64. return $this->formBuilder->buildForm($form_object, $form_state);
  65. }
  66. /**
  67. * Extracts the form argument string from a request.
  68. *
  69. * Depending on the type of form the argument string may be stored in a
  70. * different request attribute.
  71. *
  72. * One example of a route definition is given below.
  73. * @code
  74. * defaults:
  75. * _form: Drupal\example\Form\ExampleForm
  76. * @endcode
  77. *
  78. * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
  79. * The route match object from which to extract a form definition string.
  80. *
  81. * @return string
  82. * The form definition string.
  83. */
  84. abstract protected function getFormArgument(RouteMatchInterface $route_match);
  85. /**
  86. * Returns the object used to build the form.
  87. *
  88. * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
  89. * The route match.
  90. * @param string $form_arg
  91. * Either a class name or a service ID.
  92. *
  93. * @return \Drupal\Core\Form\FormInterface
  94. * The form object to use.
  95. */
  96. abstract protected function getFormObject(RouteMatchInterface $route_match, $form_arg);
  97. }