You are here

public function AnonymousLoginSubscriber::redirect in Anonymous login 8

Same name and namespace in other branches
  1. 8.2 src/EventSubscriber/AnonymousLoginSubscriber.php \Drupal\anonymous_login\EventSubscriber\AnonymousLoginSubscriber::redirect()

Perform the anonymous user redirection, if needed.

This method is called whenever the KernelEvents::REQUEST event is dispatched.

Parameters

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

File

src/EventSubscriber/AnonymousLoginSubscriber.php, line 149

Class

AnonymousLoginSubscriber
Class AnonymousLoginSubscriber.

Namespace

Drupal\anonymous_login\EventSubscriber

Code

public function redirect(GetResponseEvent $event) {

  // Skip if maintenance mode is enabled.
  if ($this->state
    ->get('system.maintenance_mode')) {
    return;
  }

  // Skip if running from the command-line.
  if ($this->sapi === 'cli') {
    return;
  }

  // Skip if no paths are configured for redirecting.
  if (!($paths = $this
    ->paths()) || empty($paths['include'])) {
    return;
  }

  // Skip if the user is not anonymous.
  if (!$this->currentUser
    ->isAnonymous()) {
    return;
  }

  // Get current request.
  $request = $event
    ->getRequest();

  // Determine the current path and alias.
  $current_path = $this->aliasManager
    ->getPathByAlias($this->currentPath
    ->getPath($request));
  $current = [
    'path' => $current_path,
    'alias' => $this->aliasManager
      ->getAliasByPath($current_path),
  ];

  // Ignore PHP file requests.
  if (substr($current['path'], -4) == '.php') {
    return;
  }
  $login_page = '/user/login';

  // Validate path to prevent system error if path doesn't exist
  // or it was deleted for some reason.
  $valid_url = $this->pathValidator
    ->getUrlIfValidWithoutAccessCheck($this->configFactory
    ->get('anonymous_login.settings')
    ->get('login_path'));
  if ($valid_url) {

    // We use this method to get the path with current language prefix
    // if site is multilingual.
    $login_page = Url::fromUserInput('/' . $valid_url
      ->getInternalPath())
      ->toString();
  }

  // Ignore the user login page.
  if ($current['path'] == $login_page) {
    return;
  }

  // Convert the path to the front page token, if needed.
  $front_page = $this->configFactory
    ->get('system.site')
    ->get('page.front');
  $current['path'] = $current['path'] != $front_page ? $current['path'] : '<front>';

  // Track if we should redirect.
  $redirect = FALSE;

  // Iterate the current path and alias.
  foreach ($current as &$check) {

    // Remove the leading or trailer slash.
    $check = $this
      ->pathSlashCut($check);

    // Redirect if the path is a match for included paths.
    if ($this->pathMatcher
      ->matchPath($check, implode(PHP_EOL, $paths['include']))) {
      $redirect = TRUE;
    }

    // Do not redirect if the path is a match for excluded paths.
    if (!empty($paths['exclude']) && $this->pathMatcher
      ->matchPath($check, implode(PHP_EOL, $paths['exclude']))) {
      $redirect = FALSE;

      // Matching an excluded path is a hard-stop.
      break;
    }
  }

  // See if we're going to redirect.
  if ($redirect) {

    // See if we have a message to display.
    if ($message = $this->configFactory
      ->get('anonymous_login.settings')
      ->get('message')) {
      drupal_set_message($message);
    }

    // Ensure the query is also passed along.
    $query = '';
    if ($request->query
      ->count()) {
      $query = '?' . str_replace('&', '%26', $request
        ->getQueryString());
    }

    // Remove destination parameter from current request
    // to prevent double redirection.
    if ($request->query
      ->has('destination')) {
      $request->query
        ->remove('destination');
    }

    // Redirect to the login, keeping the requested alias as the destination.
    $event
      ->setResponse(new RedirectResponse($login_page . '?destination=' . $current['alias'] . $query));
  }
}