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