You are here

class AccountSwitcher in Drupal 8

Same name and namespace in other branches
  1. 9 core/lib/Drupal/Core/Session/AccountSwitcher.php \Drupal\Core\Session\AccountSwitcher

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.

Hierarchy

Expanded class hierarchy of AccountSwitcher

1 string reference to 'AccountSwitcher'
core.services.yml in core/core.services.yml
core/core.services.yml
1 service uses AccountSwitcher
account_switcher in core/core.services.yml
Drupal\Core\Session\AccountSwitcher

File

core/lib/Drupal/Core/Session/AccountSwitcher.php, line 12

Namespace

Drupal\Core\Session
View source
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;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
AccountSwitcher::$accountStack protected property A stack of previous overridden accounts.
AccountSwitcher::$currentUser protected property The current user service.
AccountSwitcher::$originalSessionSaving protected property The original state of session saving prior to account switching.
AccountSwitcher::$writeSafeHandler protected property The write-safe session handler.
AccountSwitcher::switchBack public function Reverts to a previous account after switching. Overrides AccountSwitcherInterface::switchBack
AccountSwitcher::switchTo public function Safely switches to another account. Overrides AccountSwitcherInterface::switchTo
AccountSwitcher::__construct public function Constructs a new AccountSwitcher.