3 namespace Drupal\Core\Form;
5 use Drupal\Core\Config\ConfigFactoryInterface;
6 use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
7 use Drupal\Core\DependencyInjection\DependencySerializationTrait;
8 use Drupal\Core\Logger\LoggerChannelTrait;
9 use Drupal\Core\Routing\LinkGeneratorTrait;
10 use Drupal\Core\Routing\RedirectDestinationTrait;
11 use Drupal\Core\Routing\UrlGeneratorTrait;
12 use Drupal\Core\StringTranslation\StringTranslationTrait;
13 use Symfony\Component\DependencyInjection\ContainerInterface;
14 use Symfony\Component\HttpFoundation\RequestStack;
15 use Drupal\Core\Messenger\MessengerTrait;
18 * Provides a base class for forms.
20 * This class exists as a mid-point between dependency injection through
21 * ContainerInjectionInterface, and a less-structured use of traits which
22 * default to using the \Drupal accessor for service discovery.
24 * To properly inject services, override create() and use the setters provided
25 * by the traits to inject the needed services.
28 * public static function create($container) {
29 * $form = new static();
30 * // In this example we only need string translation so we use the
31 * // setStringTranslation() method provided by StringTranslationTrait.
32 * $form->setStringTranslation($container->get('string_translation'));
37 * Alternately, do not use FormBase. A class can implement FormInterface, use
38 * the traits it needs, and inject services from the container as required.
42 * @see \Drupal\Core\DependencyInjection\ContainerInjectionInterface
44 abstract class FormBase implements FormInterface, ContainerInjectionInterface {
46 use DependencySerializationTrait;
47 use LinkGeneratorTrait;
48 use LoggerChannelTrait;
50 use RedirectDestinationTrait;
51 use StringTranslationTrait;
52 use UrlGeneratorTrait;
57 * @var \Symfony\Component\HttpFoundation\RequestStack
59 protected $requestStack;
64 * Subclasses should use the self::config() method, which may be overridden to
65 * address specific needs when loading config, rather than this property
66 * directly. See \Drupal\Core\Form\ConfigFormBase::config() for an example of
69 * @var \Drupal\Core\Config\ConfigFactoryInterface
71 protected $configFactory;
76 * @var \Drupal\Core\Routing\RouteMatchInterface
78 protected $routeMatch;
83 public static function create(ContainerInterface $container) {
90 public function validateForm(array &$form, FormStateInterface $form_state) {
91 // Validation is optional.
95 * Retrieves a configuration object.
97 * This is the main entry point to the configuration API. Calling
98 * @code $this->config('book.admin') @endcode will return a configuration
99 * object in which the book module can store its administrative settings.
101 * @param string $name
102 * The name of the configuration object to retrieve. The name corresponds to
103 * a configuration file. For @code \Drupal::config('book.admin') @endcode,
104 * the config object returned will contain the contents of book.admin
105 * configuration file.
107 * @return \Drupal\Core\Config\ImmutableConfig
108 * A configuration object.
110 protected function config($name) {
111 return $this->configFactory()->get($name);
115 * Gets the config factory for this form.
117 * When accessing configuration values, use $this->config(). Only use this
118 * when the config factory needs to be manipulated directly.
120 * @return \Drupal\Core\Config\ConfigFactoryInterface
122 protected function configFactory() {
123 if (!$this->configFactory) {
124 $this->configFactory = $this->container()->get('config.factory');
126 return $this->configFactory;
130 * Sets the config factory for this form.
132 * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
133 * The config factory.
137 public function setConfigFactory(ConfigFactoryInterface $config_factory) {
138 $this->configFactory = $config_factory;
143 * Resets the configuration factory.
145 public function resetConfigFactory() {
146 $this->configFactory = NULL;
150 * Gets the request object.
152 * @return \Symfony\Component\HttpFoundation\Request
153 * The request object.
155 protected function getRequest() {
156 if (!$this->requestStack) {
157 $this->requestStack = \Drupal::service('request_stack');
159 return $this->requestStack->getCurrentRequest();
163 * Gets the route match.
165 * @return \Drupal\Core\Routing\RouteMatchInterface
167 protected function getRouteMatch() {
168 if (!$this->routeMatch) {
169 $this->routeMatch = \Drupal::routeMatch();
171 return $this->routeMatch;
175 * Sets the request stack object to use.
177 * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
178 * The request stack object.
182 public function setRequestStack(RequestStack $request_stack) {
183 $this->requestStack = $request_stack;
188 * Gets the current user.
190 * @return \Drupal\Core\Session\AccountInterface
193 protected function currentUser() {
194 return \Drupal::currentUser();
198 * Returns the service container.
200 * This method is marked private to prevent sub-classes from retrieving
201 * services from the container through it. Instead,
202 * \Drupal\Core\DependencyInjection\ContainerInjectionInterface should be used
203 * for injecting services.
205 * @return \Symfony\Component\DependencyInjection\ContainerInterface
206 * The service container.
208 private function container() {
209 return \Drupal::getContainer();
213 * Gets the logger for a specific channel.
215 * This method exists for backward-compatibility between FormBase and
216 * LoggerChannelTrait. Use LoggerChannelTrait::getLogger() instead.
218 * @param string $channel
219 * The name of the channel. Can be any string, but the general practice is
220 * to use the name of the subsystem calling this.
222 * @return \Psr\Log\LoggerInterface
223 * The logger for the given channel.
225 protected function logger($channel) {
226 return $this->getLogger($channel);