FormBase.php 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. <?php
  2. namespace Drupal\Core\Form;
  3. use Drupal\Core\Config\ConfigFactoryInterface;
  4. use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
  5. use Drupal\Core\DependencyInjection\DependencySerializationTrait;
  6. use Drupal\Core\Logger\LoggerChannelTrait;
  7. use Drupal\Core\Routing\LinkGeneratorTrait;
  8. use Drupal\Core\Routing\RedirectDestinationTrait;
  9. use Drupal\Core\Routing\UrlGeneratorTrait;
  10. use Drupal\Core\StringTranslation\StringTranslationTrait;
  11. use Drupal\Core\Url;
  12. use Symfony\Component\DependencyInjection\ContainerInterface;
  13. use Symfony\Component\HttpFoundation\RedirectResponse;
  14. use Symfony\Component\HttpFoundation\RequestStack;
  15. use Drupal\Core\Messenger\MessengerTrait;
  16. /**
  17. * Provides a base class for forms.
  18. *
  19. * This class exists as a mid-point between dependency injection through
  20. * ContainerInjectionInterface, and a less-structured use of traits which
  21. * default to using the \Drupal accessor for service discovery.
  22. *
  23. * To properly inject services, override create() and use the setters provided
  24. * by the traits to inject the needed services.
  25. *
  26. * @code
  27. * public static function create($container) {
  28. * $form = new static();
  29. * // In this example we only need string translation so we use the
  30. * // setStringTranslation() method provided by StringTranslationTrait.
  31. * $form->setStringTranslation($container->get('string_translation'));
  32. * return $form;
  33. * }
  34. * @endcode
  35. *
  36. * Alternately, do not use FormBase. A class can implement FormInterface, use
  37. * the traits it needs, and inject services from the container as required.
  38. *
  39. * @ingroup form_api
  40. *
  41. * @see \Drupal\Core\DependencyInjection\ContainerInjectionInterface
  42. */
  43. abstract class FormBase implements FormInterface, ContainerInjectionInterface {
  44. use DependencySerializationTrait;
  45. use LinkGeneratorTrait;
  46. use LoggerChannelTrait;
  47. use MessengerTrait;
  48. use RedirectDestinationTrait;
  49. use StringTranslationTrait;
  50. use UrlGeneratorTrait;
  51. /**
  52. * The request stack.
  53. *
  54. * @var \Symfony\Component\HttpFoundation\RequestStack
  55. */
  56. protected $requestStack;
  57. /**
  58. * The config factory.
  59. *
  60. * Subclasses should use the self::config() method, which may be overridden to
  61. * address specific needs when loading config, rather than this property
  62. * directly. See \Drupal\Core\Form\ConfigFormBase::config() for an example of
  63. * this.
  64. *
  65. * @var \Drupal\Core\Config\ConfigFactoryInterface
  66. */
  67. protected $configFactory;
  68. /**
  69. * The route match.
  70. *
  71. * @var \Drupal\Core\Routing\RouteMatchInterface
  72. */
  73. protected $routeMatch;
  74. /**
  75. * {@inheritdoc}
  76. */
  77. public static function create(ContainerInterface $container) {
  78. return new static();
  79. }
  80. /**
  81. * {@inheritdoc}
  82. */
  83. public function validateForm(array &$form, FormStateInterface $form_state) {
  84. // Validation is optional.
  85. }
  86. /**
  87. * Retrieves a configuration object.
  88. *
  89. * This is the main entry point to the configuration API. Calling
  90. * @code $this->config('book.admin') @endcode will return a configuration
  91. * object in which the book module can store its administrative settings.
  92. *
  93. * @param string $name
  94. * The name of the configuration object to retrieve. The name corresponds to
  95. * a configuration file. For @code \Drupal::config('book.admin') @endcode,
  96. * the config object returned will contain the contents of book.admin
  97. * configuration file.
  98. *
  99. * @return \Drupal\Core\Config\ImmutableConfig
  100. * A configuration object.
  101. */
  102. protected function config($name) {
  103. return $this->configFactory()->get($name);
  104. }
  105. /**
  106. * Gets the config factory for this form.
  107. *
  108. * When accessing configuration values, use $this->config(). Only use this
  109. * when the config factory needs to be manipulated directly.
  110. *
  111. * @return \Drupal\Core\Config\ConfigFactoryInterface
  112. */
  113. protected function configFactory() {
  114. if (!$this->configFactory) {
  115. $this->configFactory = $this->container()->get('config.factory');
  116. }
  117. return $this->configFactory;
  118. }
  119. /**
  120. * Sets the config factory for this form.
  121. *
  122. * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
  123. * The config factory.
  124. *
  125. * @return $this
  126. */
  127. public function setConfigFactory(ConfigFactoryInterface $config_factory) {
  128. $this->configFactory = $config_factory;
  129. return $this;
  130. }
  131. /**
  132. * Resets the configuration factory.
  133. */
  134. public function resetConfigFactory() {
  135. $this->configFactory = NULL;
  136. }
  137. /**
  138. * Gets the request object.
  139. *
  140. * @return \Symfony\Component\HttpFoundation\Request
  141. * The request object.
  142. */
  143. protected function getRequest() {
  144. if (!$this->requestStack) {
  145. $this->requestStack = \Drupal::service('request_stack');
  146. }
  147. return $this->requestStack->getCurrentRequest();
  148. }
  149. /**
  150. * Gets the route match.
  151. *
  152. * @return \Drupal\Core\Routing\RouteMatchInterface
  153. */
  154. protected function getRouteMatch() {
  155. if (!$this->routeMatch) {
  156. $this->routeMatch = \Drupal::routeMatch();
  157. }
  158. return $this->routeMatch;
  159. }
  160. /**
  161. * Sets the request stack object to use.
  162. *
  163. * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
  164. * The request stack object.
  165. *
  166. * @return $this
  167. */
  168. public function setRequestStack(RequestStack $request_stack) {
  169. $this->requestStack = $request_stack;
  170. return $this;
  171. }
  172. /**
  173. * Gets the current user.
  174. *
  175. * @return \Drupal\Core\Session\AccountInterface
  176. * The current user.
  177. */
  178. protected function currentUser() {
  179. return \Drupal::currentUser();
  180. }
  181. /**
  182. * Returns a redirect response object for the specified route.
  183. *
  184. * @param string $route_name
  185. * The name of the route to which to redirect.
  186. * @param array $route_parameters
  187. * (optional) Parameters for the route.
  188. * @param array $options
  189. * (optional) An associative array of additional options.
  190. * @param int $status
  191. * (optional) The HTTP redirect status code for the redirect. The default is
  192. * 302 Found.
  193. *
  194. * @return \Symfony\Component\HttpFoundation\RedirectResponse
  195. * A redirect response object that may be returned by the controller.
  196. */
  197. protected function redirect($route_name, array $route_parameters = [], array $options = [], $status = 302) {
  198. $options['absolute'] = TRUE;
  199. return new RedirectResponse(Url::fromRoute($route_name, $route_parameters, $options)->toString(), $status);
  200. }
  201. /**
  202. * Returns the service container.
  203. *
  204. * This method is marked private to prevent sub-classes from retrieving
  205. * services from the container through it. Instead,
  206. * \Drupal\Core\DependencyInjection\ContainerInjectionInterface should be used
  207. * for injecting services.
  208. *
  209. * @return \Symfony\Component\DependencyInjection\ContainerInterface
  210. * The service container.
  211. */
  212. private function container() {
  213. return \Drupal::getContainer();
  214. }
  215. /**
  216. * Gets the logger for a specific channel.
  217. *
  218. * This method exists for backward-compatibility between FormBase and
  219. * LoggerChannelTrait. Use LoggerChannelTrait::getLogger() instead.
  220. *
  221. * @param string $channel
  222. * The name of the channel. Can be any string, but the general practice is
  223. * to use the name of the subsystem calling this.
  224. *
  225. * @return \Psr\Log\LoggerInterface
  226. * The logger for the given channel.
  227. */
  228. protected function logger($channel) {
  229. return $this->getLogger($channel);
  230. }
  231. }