class FormSubmitter

Same name and namespace in other branches
  1. 9 core/lib/Drupal/Core/Form/FormSubmitter.php \Drupal\Core\Form\FormSubmitter
  2. 8.9.x core/lib/Drupal/Core/Form/FormSubmitter.php \Drupal\Core\Form\FormSubmitter
  3. 11.x core/lib/Drupal/Core/Form/FormSubmitter.php \Drupal\Core\Form\FormSubmitter

Provides submission processing for forms.

Hierarchy

Expanded class hierarchy of FormSubmitter

1 string reference to 'FormSubmitter'
core.services.yml in core/core.services.yml
core/core.services.yml
1 service uses FormSubmitter
form_submitter in core/core.services.yml
Drupal\Core\Form\FormSubmitter

File

core/lib/Drupal/Core/Form/FormSubmitter.php, line 15

Namespace

Drupal\Core\Form
View source
class FormSubmitter implements FormSubmitterInterface {
  
  /**
   * The URL generator.
   *
   * @var \Drupal\Core\Routing\UrlGeneratorInterface
   */
  protected $urlGenerator;
  
  /**
   * The request stack.
   *
   * @var \Symfony\Component\HttpFoundation\RequestStack
   */
  protected $requestStack;
  
  /**
   * The redirect response subscriber.
   *
   * @var \Drupal\Core\EventSubscriber\RedirectResponseSubscriber
   */
  protected RedirectResponseSubscriber $redirectResponseSubscriber;
  
  /**
   * Constructs a new FormSubmitter.
   *
   * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
   *   The request stack.
   * @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator
   *   The URL generator.
   * @param \Drupal\Core\EventSubscriber\RedirectResponseSubscriber|null $redirect_response_subscriber
   *   The redirect response subscriber.
   */
  public function __construct(RequestStack $request_stack, UrlGeneratorInterface $url_generator, ?RedirectResponseSubscriber $redirect_response_subscriber = NULL) {
    $this->requestStack = $request_stack;
    $this->urlGenerator = $url_generator;
    if (is_null($redirect_response_subscriber)) {
      @trigger_error('Calling ' . __CLASS__ . '::__construct() without the $redirect_response_subscriber argument is deprecated in drupal:10.2.0 and is required in drupal:11.0.0. See https://www.drupal.org/node/3377297', E_USER_DEPRECATED);
      $redirect_response_subscriber = \Drupal::service('redirect_response_subscriber');
    }
    $this->redirectResponseSubscriber = $redirect_response_subscriber;
  }
  
  /**
   * {@inheritdoc}
   */
  public function doSubmitForm(&$form, FormStateInterface &$form_state) {
    if (!$form_state->isSubmitted()) {
      return;
    }
    // Execute form submit handlers.
    $this->executeSubmitHandlers($form, $form_state);
    // If batches were set in the submit handlers, we process them now,
    // possibly ending execution. We make sure we do not react to the batch
    // that is already being processed (if a batch operation performs a
    // \Drupal\Core\Form\FormBuilderInterface::submitForm).
    if (($batch =& $this->batchGet()) && !isset($batch['current_set'])) {
      // Store $form_state information in the batch definition.
      $batch['form_state'] = $form_state;
      $batch['progressive'] = !$form_state->isProgrammed();
      $response = batch_process();
      // If the batch has been completed and _batch_finished() called then
      // $batch will be NULL.
      if ($batch && $batch['progressive']) {
        return $response;
      }
      // Execution continues only for programmatic forms.
      // For 'regular' forms, we get redirected to the batch processing
      // page. Form redirection will be handled in _batch_finished(),
      // after the batch is processed.
    }
    // Set a flag to indicate the form has been processed and executed.
    $form_state->setExecuted();
    // If no response has been set, process the form redirect.
    if (!$form_state->getResponse() && ($redirect = $this->redirectForm($form_state))) {
      $form_state->setResponse($redirect);
    }
    // If there is a response was set, return it instead of continuing.
    if (($response = $form_state->getResponse()) && $response instanceof Response) {
      return $response;
    }
  }
  
  /**
   * {@inheritdoc}
   */
  public function executeSubmitHandlers(&$form, FormStateInterface &$form_state) {
    // If there was a button pressed, use its handlers.
    $handlers = $form_state->getSubmitHandlers();
    // Otherwise, check for a form-level handler.
    if (!$handlers && !empty($form['#submit'])) {
      $handlers = $form['#submit'];
    }
    foreach ($handlers as $callback) {
      // Check if a previous _submit handler has set a batch, but make sure we
      // do not react to a batch that is already being processed (for instance
      // if a batch operation performs a
      // \Drupal\Core\Form\FormBuilderInterface::submitForm()).
      if (($batch =& $this->batchGet()) && !isset($batch['id'])) {
        // Some previous submit handler has set a batch. To ensure correct
        // execution order, store the call in a special 'control' batch set.
        // See _batch_next_set().
        $batch['sets'][] = [
          'form_submit' => $callback,
        ];
        $batch['has_form_submits'] = TRUE;
      }
      else {
        call_user_func_array($form_state->prepareCallback($callback), [
          &$form,
          &$form_state,
        ]);
      }
    }
  }
  
  /**
   * {@inheritdoc}
   */
  public function redirectForm(FormStateInterface $form_state) {
    $redirect = $form_state->getRedirect();
    $this->redirectResponseSubscriber
      ->setIgnoreDestination($form_state->getIgnoreDestination());
    // Allow using redirect responses directly if needed.
    if ($redirect instanceof RedirectResponse) {
      return $redirect;
    }
    $url = NULL;
    // Check for a route-based redirection.
    if ($redirect instanceof Url) {
      $url = $redirect->setAbsolute()
        ->toString();
    }
    elseif ($redirect === NULL) {
      $request = $this->requestStack
        ->getCurrentRequest();
      $url = $this->urlGenerator
        ->generateFromRoute('<current>', [], [
        'query' => $request->query
          ->all(),
        'absolute' => TRUE,
      ]);
    }
    if ($url) {
      // According to RFC 7231, 303 See Other status code must be used to redirect
      // user agent (and not default 302 Found).
      // @see http://tools.ietf.org/html/rfc7231#section-6.4.4
      return new RedirectResponse($url, Response::HTTP_SEE_OTHER);
    }
  }
  
  /**
   * Wraps batch_get().
   */
  protected function &batchGet() {
    return batch_get();
  }

}

Members

Title Sort descending Modifiers Object type Summary Overriden Title
FormSubmitter::$redirectResponseSubscriber protected property The redirect response subscriber.
FormSubmitter::$requestStack protected property The request stack.
FormSubmitter::$urlGenerator protected property The URL generator.
FormSubmitter::batchGet protected function Wraps batch_get().
FormSubmitter::doSubmitForm public function Handles the submitted form, executing callbacks and processing responses. Overrides FormSubmitterInterface::doSubmitForm
FormSubmitter::executeSubmitHandlers public function Executes custom submission handlers for a given form. Overrides FormSubmitterInterface::executeSubmitHandlers
FormSubmitter::redirectForm public function Redirects the user to a URL after a form has been processed. Overrides FormSubmitterInterface::redirectForm
FormSubmitter::__construct public function Constructs a new FormSubmitter.

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