Verified Commit 92abbb59 authored by Lee Rowlands's avatar Lee Rowlands
Browse files

Issue #2950883 by acbramley, smustgrave, akalam, phenaproxima, idebr, raman.b,...

Issue #2950883 by acbramley, smustgrave, akalam, phenaproxima, idebr, raman.b, alexpott, bsztreha, douggreen, Suresh Prabhu Parkala, ExTexan, Kristen Pol, joachim, lauriii: Allow form redirects to ignore ?destination query parameter
parent f9b363c0
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -446,7 +446,7 @@ services:
  Drupal\Core\Form\FormValidatorInterface: '@form_validator'
  form_submitter:
    class: Drupal\Core\Form\FormSubmitter
    arguments: ['@request_stack', '@url_generator']
    arguments: ['@request_stack', '@url_generator', '@redirect_response_subscriber']
  Drupal\Core\Form\FormSubmitterInterface: '@form_submitter'
  form_error_handler:
    class: Drupal\Core\Form\FormErrorHandler
+19 −1
Original line number Diff line number Diff line
@@ -25,6 +25,13 @@ class RedirectResponseSubscriber implements EventSubscriberInterface {
   */
  protected $unroutedUrlAssembler;

  /**
   * Whether to ignore the destination query parameter when redirecting.
   *
   * @var bool
   */
  protected bool $ignoreDestination = FALSE;

  /**
   * The request context.
   */
@@ -58,7 +65,7 @@ public function checkRedirectUrl(ResponseEvent $event) {
      // If $response is already a SecuredRedirectResponse, it might reject the
      // new target as invalid, in which case proceed with the old target.
      $destination = $request->query->get('destination');
      if ($destination) {
      if ($destination && !$this->ignoreDestination) {
        // The 'Location' HTTP header must always be absolute.
        $destination = $this->getDestinationAsAbsoluteUrl($destination, $request->getSchemeAndHttpHost());
        try {
@@ -133,6 +140,17 @@ protected function getDestinationAsAbsoluteUrl($destination, $scheme_and_host) {
    return $destination;
  }

  /**
   * Set whether the redirect response will ignore the destination query param.
   *
   * @param bool $status
   *   (optional) TRUE if the destination query parameter should be ignored.
   *   FALSE if not. Defaults to TRUE.
   */
  public function setIgnoreDestination($status = TRUE) {
    $this->ignoreDestination = $status;
  }

  /**
   * Registers the methods in this class that should be listeners.
   *
+22 −0
Original line number Diff line number Diff line
@@ -136,6 +136,13 @@ class FormState implements FormStateInterface {
   */
  protected $response;

  /**
   * Used to ignore destination when redirecting.
   *
   * @var bool
   */
  protected bool $ignoreDestination = FALSE;

  /**
   * Used to redirect the form on submission.
   *
@@ -1057,6 +1064,21 @@ public function getRedirect() {
    return $this->redirect;
  }

  /**
   * {@inheritdoc}
   */
  public function setIgnoreDestination(bool $status = TRUE) {
    $this->ignoreDestination = $status;
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function getIgnoreDestination(): bool {
    return $this->ignoreDestination;
  }

  /**
   * Sets the global status of errors.
   *
+14 −0
Original line number Diff line number Diff line
@@ -611,6 +611,20 @@ public function getRedirect() {
    return $this->decoratedFormState->getRedirect();
  }

  /**
   * {@inheritdoc}
   */
  public function setIgnoreDestination(bool $status = TRUE) {
    return $this->decoratedFormState->setIgnoreDestination($status);
  }

  /**
   * {@inheritdoc}
   */
  public function getIgnoreDestination(): bool {
    return $this->decoratedFormState->getIgnoreDestination();
  }

  /**
   * {@inheritdoc}
   */
+20 −0
Original line number Diff line number Diff line
@@ -158,6 +158,26 @@ public function setRedirectUrl(Url $url);
   */
  public function getRedirect();

  /**
   * Determines whether the redirect respects the destination query parameter.
   *
   * @param bool $status
   *   (optional) TRUE if the redirect should take precedence over the
   *   destination query parameter. FALSE if not. Defaults to TRUE.
   *
   * @return $this
   */
  public function setIgnoreDestination(bool $status = TRUE);

  /**
   * Gets whether the redirect respects the destination query parameter.
   *
   * @return bool
   *   TRUE if the redirect should take precedence over the destination query
   *   parameter.
   */
  public function getIgnoreDestination(): bool;

  /**
   * Sets the entire set of arbitrary data.
   *
Loading