You are here

public function PreviewLinkRouteEventSubscriber::onException in Preview Link 2.x

Same name and namespace in other branches
  1. 2.0.x src/EventSubscriber/PreviewLinkRouteEventSubscriber.php \Drupal\preview_link\EventSubscriber\PreviewLinkRouteEventSubscriber::onException()

Redirects from canonical routes to preview link route.

Need to use GetResponseForExceptionEvent and getException method instead of ExceptionEvent::getThrowable() since these are in Symfony 4.4, and Drupal 8.9 supports Symfony 3.4.

Parameters

\Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event: The exception event.

File

src/EventSubscriber/PreviewLinkRouteEventSubscriber.php, line 87

Class

PreviewLinkRouteEventSubscriber
Modifies canonical entity routing to redirect to preview link.

Namespace

Drupal\preview_link\EventSubscriber

Code

public function onException(GetResponseForExceptionEvent $event) : void {
  $exception = $event
    ->getException();
  if ($exception instanceof PreviewLinkRerouteException) {
    $entity = $exception
      ->getEntity();
    $token = $exception
      ->getPreviewLink()
      ->getToken();
    $previewLinkUrl = Url::fromRoute('entity.' . $entity
      ->getEntityTypeId() . '.preview_link', [
      $entity
        ->getEntityTypeId() => $entity
        ->id(),
      'preview_token' => $token,
    ]);

    // Push the user back, but only if they have permission to view the
    // canonical route.
    // Redirect destination actually has the canonical route since thats
    // where we are right now.
    $removeUrl = Url::fromRoute('preview_link.session_tokens.remove');
    $destination = $this->redirectDestination
      ->get();
    try {
      $canonicalUrl = Url::fromUserInput($destination);
      if ($canonicalUrl
        ->access($this->currentUser)) {
        $removeUrl
          ->setOption('query', $this->redirectDestination
          ->getAsArray());
      }
    } catch (\InvalidArgumentException $e) {
    }

    // Message is designed to only be visible on canonical -> preview link
    // redirects, not on preview link routes accessed directly.
    $this->messenger
      ->addMessage($this
      ->t('You are viewing this page because a preview link granted you access. Click <a href="@remove_session_url">here</a> to remove token.', [
      '@remove_session_url' => $removeUrl
        ->toString(),
    ]));
    $this->logger
      ->debug('Redirecting to preview link of @entity', [
      '@entity' => $entity
        ->label(),
    ]);

    // 307: temporary.
    $response = (new TrustedRedirectResponse($previewLinkUrl
      ->toString(), TrustedRedirectResponse::HTTP_TEMPORARY_REDIRECT))
      ->addCacheableDependency($exception);
    $event
      ->setResponse($response);
    $event
      ->stopPropagation();
  }
}