FormBase.php

Same filename in other branches
  1. 9 core/lib/Drupal/Core/Form/FormBase.php
  2. 8.9.x core/lib/Drupal/Core/Form/FormBase.php
  3. 11.x core/lib/Drupal/Core/Form/FormBase.php

Namespace

Drupal\Core\Form

File

core/lib/Drupal/Core/Form/FormBase.php

View source
<?php

namespace Drupal\Core\Form;

use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Core\Logger\LoggerChannelTrait;
use Drupal\Core\Routing\RedirectDestinationTrait;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\RequestStack;
use Drupal\Core\Messenger\MessengerTrait;

/**
 * Provides a base class for forms.
 *
 * This class exists as a mid-point between dependency injection through
 * ContainerInjectionInterface, and a less-structured use of traits which
 * default to using the \Drupal accessor for service discovery.
 *
 * To properly inject services, override create() and use the setters provided
 * by the traits to inject the needed services.
 *
 * @code
 * public static function create($container) {
 *   $form = new static();
 *   // In this example we only need string translation so we use the
 *   // setStringTranslation() method provided by StringTranslationTrait.
 *   $form->setStringTranslation($container->get('string_translation'));
 *   return $form;
 * }
 * @endcode
 *
 * Alternately, do not use FormBase. A class can implement FormInterface, use
 * the traits it needs, and inject services from the container as required.
 *
 * @ingroup form_api
 *
 * @see \Drupal\Core\DependencyInjection\ContainerInjectionInterface
 */
abstract class FormBase implements FormInterface, ContainerInjectionInterface {
    use DependencySerializationTrait;
    use LoggerChannelTrait;
    use MessengerTrait;
    use RedirectDestinationTrait;
    use StringTranslationTrait;
    
    /**
     * The request stack.
     *
     * @var \Symfony\Component\HttpFoundation\RequestStack
     */
    protected $requestStack;
    
    /**
     * The config factory.
     *
     * Subclasses should use the self::config() method, which may be overridden to
     * address specific needs when loading config, rather than this property
     * directly. See \Drupal\Core\Form\ConfigFormBase::config() for an example of
     * this.
     *
     * @var \Drupal\Core\Config\ConfigFactoryInterface
     */
    protected $configFactory;
    
    /**
     * The route match.
     *
     * @var \Drupal\Core\Routing\RouteMatchInterface
     */
    protected $routeMatch;
    
    /**
     * {@inheritdoc}
     */
    public static function create(ContainerInterface $container) {
        return new static();
    }
    
    /**
     * {@inheritdoc}
     */
    public function validateForm(array &$form, FormStateInterface $form_state) {
        // Validation is optional.
    }
    
    /**
     * Retrieves a configuration object.
     *
     * This is the main entry point to the configuration API. Calling
     * @code $this->config('my_module.admin') @endcode will return a configuration
     * object in which the my_module module can store its administrative settings.
     *
     * @param string $name
     *   The name of the configuration object to retrieve. The name corresponds to
     *   a configuration file. For @code \Drupal::config('my_module.admin') @endcode,
     *   the config object returned will contain the contents of my_module.admin
     *   configuration file.
     *
     * @return \Drupal\Core\Config\ImmutableConfig
     *   A configuration object.
     */
    protected function config($name) {
        return $this->configFactory()
            ->get($name);
    }
    
    /**
     * Gets the config factory for this form.
     *
     * When accessing configuration values, use $this->config(). Only use this
     * when the config factory needs to be manipulated directly.
     *
     * @return \Drupal\Core\Config\ConfigFactoryInterface
     */
    protected function configFactory() {
        if (!$this->configFactory) {
            $this->configFactory = $this->container()
                ->get('config.factory');
        }
        return $this->configFactory;
    }
    
    /**
     * Sets the config factory for this form.
     *
     * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
     *   The config factory.
     *
     * @return $this
     */
    public function setConfigFactory(ConfigFactoryInterface $config_factory) {
        $this->configFactory = $config_factory;
        return $this;
    }
    
    /**
     * Resets the configuration factory.
     */
    public function resetConfigFactory() {
        $this->configFactory = NULL;
    }
    
    /**
     * Gets the request object.
     *
     * @return \Symfony\Component\HttpFoundation\Request
     *   The request object.
     */
    protected function getRequest() {
        if (!$this->requestStack) {
            $this->requestStack = \Drupal::service('request_stack');
        }
        return $this->requestStack
            ->getCurrentRequest();
    }
    
    /**
     * Gets the route match.
     *
     * @return \Drupal\Core\Routing\RouteMatchInterface
     */
    protected function getRouteMatch() {
        if (!$this->routeMatch) {
            $this->routeMatch = \Drupal::routeMatch();
        }
        return $this->routeMatch;
    }
    
    /**
     * Sets the request stack object to use.
     *
     * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
     *   The request stack object.
     *
     * @return $this
     */
    public function setRequestStack(RequestStack $request_stack) {
        $this->requestStack = $request_stack;
        return $this;
    }
    
    /**
     * Gets the current user.
     *
     * @return \Drupal\Core\Session\AccountInterface
     *   The current user.
     */
    protected function currentUser() {
        return \Drupal::currentUser();
    }
    
    /**
     * Returns a redirect response object for the specified route.
     *
     * @param string $route_name
     *   The name of the route to which to redirect.
     * @param array $route_parameters
     *   (optional) Parameters for the route.
     * @param array $options
     *   (optional) An associative array of additional options.
     * @param int $status
     *   (optional) The HTTP redirect status code for the redirect. The default is
     *   302 Found.
     *
     * @return \Symfony\Component\HttpFoundation\RedirectResponse
     *   A redirect response object that may be returned by the controller.
     */
    protected function redirect($route_name, array $route_parameters = [], array $options = [], $status = 302) {
        $options['absolute'] = TRUE;
        return new RedirectResponse(Url::fromRoute($route_name, $route_parameters, $options)->toString(), $status);
    }
    
    /**
     * Returns the service container.
     *
     * This method is marked private to prevent sub-classes from retrieving
     * services from the container through it. Instead,
     * \Drupal\Core\DependencyInjection\ContainerInjectionInterface should be used
     * for injecting services.
     *
     * @return \Symfony\Component\DependencyInjection\ContainerInterface
     *   The service container.
     */
    private function container() {
        return \Drupal::getContainer();
    }
    
    /**
     * Gets the logger for a specific channel.
     *
     * This method exists for backward-compatibility between FormBase and
     * LoggerChannelTrait. Use LoggerChannelTrait::getLogger() instead.
     *
     * @param string $channel
     *   The name of the channel. Can be any string, but the general practice is
     *   to use the name of the subsystem calling this.
     *
     * @return \Psr\Log\LoggerInterface
     *   The logger for the given channel.
     */
    protected function logger($channel) {
        return $this->getLogger($channel);
    }

}

Classes

Title Deprecated Summary
FormBase Provides a base class for forms.

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.