FormBase.php 6.4 KB

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