AccountSwitcher.php

Same filename and directory in other branches
  1. 9 core/lib/Drupal/Core/Session/AccountSwitcher.php
  2. 10 core/lib/Drupal/Core/Session/AccountSwitcher.php
  3. 11.x core/lib/Drupal/Core/Session/AccountSwitcher.php

Namespace

Drupal\Core\Session

File

core/lib/Drupal/Core/Session/AccountSwitcher.php

View source
<?php

namespace Drupal\Core\Session;


/**
 * An implementation of AccountSwitcherInterface.
 *
 * This allows for safe switching of user accounts by ensuring that session
 * data for one user is not leaked in to others. It also provides a stack that
 * allows reverting to a previous user after switching.
 */
class AccountSwitcher implements AccountSwitcherInterface {
  
  /**
   * A stack of previous overridden accounts.
   *
   * @var \Drupal\Core\Session\AccountInterface[]
   */
  protected $accountStack = [];
  
  /**
   * The current user service.
   *
   * @var \Drupal\Core\Session\AccountProxyInterface
   */
  protected $currentUser = [];
  
  /**
   * The write-safe session handler.
   *
   * @var \Drupal\Core\Session\WriteSafeSessionHandlerInterface
   */
  protected $writeSafeHandler;
  
  /**
   * The original state of session saving prior to account switching.
   *
   * @var bool
   */
  protected $originalSessionSaving;
  
  /**
   * Constructs a new AccountSwitcher.
   *
   * @param \Drupal\Core\Session\AccountProxyInterface $current_user
   *   The current user service.
   * @param \Drupal\Core\Session\WriteSafeSessionHandlerInterface $write_safe_handler
   *   The write-safe session handler.
   */
  public function __construct(AccountProxyInterface $current_user, WriteSafeSessionHandlerInterface $write_safe_handler) {
    $this->currentUser = $current_user;
    $this->writeSafeHandler = $write_safe_handler;
  }
  
  /**
   * {@inheritdoc}
   */
  public function switchTo(AccountInterface $account) {
    // Prevent session information from being saved and push previous account.
    if (!isset($this->originalSessionSaving)) {
      // Ensure that only the first session saving status is saved.
      $this->originalSessionSaving = $this->writeSafeHandler
        ->isSessionWritable();
    }
    $this->writeSafeHandler
      ->setSessionWritable(FALSE);
    array_push($this->accountStack, $this->currentUser
      ->getAccount());
    $this->currentUser
      ->setAccount($account);
    return $this;
  }
  
  /**
   * {@inheritdoc}
   */
  public function switchBack() {
    // Restore the previous account from the stack.
    if (!empty($this->accountStack)) {
      $this->currentUser
        ->setAccount(array_pop($this->accountStack));
    }
    else {
      throw new \RuntimeException('No more accounts to revert to.');
    }
    // Restore original session saving status if all account switches are
    // reverted.
    if (empty($this->accountStack)) {
      if ($this->originalSessionSaving) {
        $this->writeSafeHandler
          ->setSessionWritable(TRUE);
      }
    }
    return $this;
  }

}

Classes

Title Deprecated Summary
AccountSwitcher An implementation of AccountSwitcherInterface.

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