You are here

public function R4032LoginSubscriber::on403 in Redirect 403 to User Login 2.x

Same name and namespace in other branches
  1. 8 src/EventSubscriber/R4032LoginSubscriber.php \Drupal\r4032login\EventSubscriber\R4032LoginSubscriber::on403()

Redirects on 403 Access Denied kernel exceptions.

Parameters

\Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event: The Event to process.

File

src/EventSubscriber/R4032LoginSubscriber.php, line 96

Class

R4032LoginSubscriber
Redirect 403 to User Login event subscriber.

Namespace

Drupal\r4032login\EventSubscriber

Code

public function on403(GetResponseForExceptionEvent $event) {
  $config = $this->configFactory
    ->get('r4032login.settings');
  $request = $event
    ->getRequest();
  $currentPath = $request
    ->getPathInfo();

  // Check if the path should be ignored.
  if (($noRedirectPages = trim($config
    ->get('match_noredirect_pages'))) && $this->pathMatcher
    ->matchPath($currentPath, $noRedirectPages)) {
    return;
  }

  // Retrieve the redirect path depending if the user is logged or not.
  if ($this->currentUser
    ->isAnonymous()) {
    $redirectPath = $config
      ->get('user_login_path');
  }
  else {
    $redirectPath = $config
      ->get('redirect_authenticated_users_to');
  }
  if (!empty($redirectPath)) {

    // Determine if the redirect path is external.
    $externalRedirect = UrlHelper::isExternal($redirectPath);

    // Determine the url options.
    $options = [
      'absolute' => TRUE,
    ];

    // Determine the destination parameter
    // and add it as options for the url build.
    if ($config
      ->get('redirect_to_destination')) {
      if ($externalRedirect) {
        $destination = Url::fromUserInput($currentPath, [
          'absolute' => TRUE,
        ])
          ->toString();
      }
      elseif ($currentPath == '/') {
        $destination = $currentPath;
      }
      else {
        $destination = substr($currentPath, 1);
      }
      if ($queryString = $request
        ->getQueryString()) {
        $destination .= '?' . $queryString;
      }
      if (empty($config
        ->get('destination_parameter_override'))) {
        $options['query']['destination'] = $destination;
      }
      else {
        $options['query'][$config
          ->get('destination_parameter_override')] = $destination;
      }
    }

    // Remove the destination parameter to allow redirection.
    $request->query
      ->remove('destination');

    // Allow to alter the url or options before to redirect.
    $redirectEvent = new RedirectEvent($redirectPath, $options);
    $this->eventDispatcher
      ->dispatch(RedirectEvent::EVENT_NAME, $redirectEvent);
    $redirectPath = $redirectEvent
      ->getUrl();
    $options = $redirectEvent
      ->getOptions();

    // Perform the redirection.
    if ($externalRedirect) {
      $url = Url::fromUri($redirectPath, $options)
        ->toString();
      $response = new TrustedRedirectResponse($url);
    }
    else {

      // Show custom access denied message if set.
      if ($this->currentUser
        ->isAnonymous() && $config
        ->get('display_denied_message')) {
        $message = $config
          ->get('access_denied_message');
        $messageType = $config
          ->get('access_denied_message_type');
        $this->messenger
          ->addMessage(Markup::create(Xss::filterAdmin($message)), $messageType);
      }
      if ($redirectPath === '<front>') {
        $url = \Drupal::urlGenerator()
          ->generate('<front>');
      }
      else {
        $url = Url::fromUserInput($redirectPath, $options)
          ->toString();
      }
      $code = $config
        ->get('default_redirect_code');
      $response = new CacheableRedirectResponse($url, $code);
    }

    // Add caching dependencies so the cache of the redirection will be
    // updated when necessary.
    $cacheMetadata = new CacheableMetadata();
    $cacheMetadata
      ->addCacheTags([
      '4xx-response',
    ]);
    $cacheMetadata
      ->addCacheableDependency($config);
    $response
      ->addCacheableDependency($cacheMetadata);
    $event
      ->setResponse($response);
  }
}