FormController.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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. use Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface;
  9. /**
  10. * Common base class for form interstitial controllers.
  11. */
  12. abstract class FormController {
  13. use DependencySerializationTrait;
  14. /**
  15. * The argument resolver.
  16. *
  17. * @var \Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface
  18. */
  19. protected $argumentResolver;
  20. /**
  21. * The controller resolver.
  22. *
  23. * @var \Drupal\Core\Controller\ControllerResolverInterface
  24. *
  25. * @deprecated
  26. * Deprecated property that is only assigned when the 'controller_resolver'
  27. * service is used as the first parameter to FormController::__construct().
  28. *
  29. * @see https://www.drupal.org/node/2959408
  30. * @see \Drupal\Core\Controller\FormController::__construct()
  31. */
  32. protected $controllerResolver;
  33. /**
  34. * The form builder.
  35. *
  36. * @var \Drupal\Core\Form\FormBuilderInterface
  37. */
  38. protected $formBuilder;
  39. /**
  40. * Constructs a new \Drupal\Core\Controller\FormController object.
  41. *
  42. * @param \Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface $argument_resolver
  43. * The argument resolver.
  44. * @param \Drupal\Core\Form\FormBuilderInterface $form_builder
  45. * The form builder.
  46. */
  47. public function __construct(ArgumentResolverInterface $argument_resolver, FormBuilderInterface $form_builder) {
  48. $this->argumentResolver = $argument_resolver;
  49. if ($argument_resolver instanceof ControllerResolverInterface) {
  50. @trigger_error("Using the 'controller_resolver' service as the first argument is deprecated, use the 'http_kernel.controller.argument_resolver' instead. If your subclass requires the 'controller_resolver' service add it as an additional argument. See https://www.drupal.org/node/2959408.", E_USER_DEPRECATED);
  51. $this->controllerResolver = $argument_resolver;
  52. }
  53. $this->formBuilder = $form_builder;
  54. }
  55. /**
  56. * Invokes the form and returns the result.
  57. *
  58. * @param \Symfony\Component\HttpFoundation\Request $request
  59. * The request object.
  60. * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
  61. * The route match.
  62. *
  63. * @return array
  64. * The render array that results from invoking the controller.
  65. */
  66. public function getContentResult(Request $request, RouteMatchInterface $route_match) {
  67. $form_arg = $this->getFormArgument($route_match);
  68. $form_object = $this->getFormObject($route_match, $form_arg);
  69. // Add the form and form_state to trick the getArguments method of the
  70. // controller resolver.
  71. $form_state = new FormState();
  72. $request->attributes->set('form', []);
  73. $request->attributes->set('form_state', $form_state);
  74. $args = $this->argumentResolver->getArguments($request, [$form_object, 'buildForm']);
  75. $request->attributes->remove('form');
  76. $request->attributes->remove('form_state');
  77. // Remove $form and $form_state from the arguments, and re-index them.
  78. unset($args[0], $args[1]);
  79. $form_state->addBuildInfo('args', array_values($args));
  80. return $this->formBuilder->buildForm($form_object, $form_state);
  81. }
  82. /**
  83. * Extracts the form argument string from a request.
  84. *
  85. * Depending on the type of form the argument string may be stored in a
  86. * different request attribute.
  87. *
  88. * One example of a route definition is given below.
  89. * @code
  90. * defaults:
  91. * _form: Drupal\example\Form\ExampleForm
  92. * @endcode
  93. *
  94. * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
  95. * The route match object from which to extract a form definition string.
  96. *
  97. * @return string
  98. * The form definition string.
  99. */
  100. abstract protected function getFormArgument(RouteMatchInterface $route_match);
  101. /**
  102. * Returns the object used to build the form.
  103. *
  104. * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
  105. * The route match.
  106. * @param string $form_arg
  107. * Either a class name or a service ID.
  108. *
  109. * @return \Drupal\Core\Form\FormInterface
  110. * The form object to use.
  111. */
  112. abstract protected function getFormObject(RouteMatchInterface $route_match, $form_arg);
  113. }