class SwitchUserListHelper
Switch user helper service.
Hierarchy
- class \Drupal\devel\SwitchUserListHelper uses \Drupal\Core\StringTranslation\StringTranslationTrait
Expanded class hierarchy of SwitchUserListHelper
2 files declare their use of SwitchUserListHelper
- SwitchUserBlock.php in src/
Plugin/ Block/ SwitchUserBlock.php - SwitchUserPageForm.php in src/
Form/ SwitchUserPageForm.php
1 string reference to 'SwitchUserListHelper'
1 service uses SwitchUserListHelper
File
-
src/
SwitchUserListHelper.php, line 20
Namespace
Drupal\develView source
class SwitchUserListHelper {
use StringTranslationTrait;
/**
* The Current User object.
*/
protected AccountInterface $currentUser;
/**
* The user storage.
*/
protected UserStorageInterface $userStorage;
/**
* The redirect destination service.
*/
protected RedirectDestinationInterface $redirectDestination;
/**
* The role storage.
*/
protected RoleStorageInterface $roleStorage;
/**
* Constructs a new SwitchUserListHelper service.
*
* @param \Drupal\Core\Session\AccountInterface $current_user
* Current user.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
* @param \Drupal\Core\Routing\RedirectDestinationInterface $redirect_destination
* The redirect destination service.
* @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation
* The translation manager.
*/
public function __construct(AccountInterface $current_user, EntityTypeManagerInterface $entity_type_manager, RedirectDestinationInterface $redirect_destination, TranslationInterface $string_translation) {
$this->currentUser = $current_user;
$this->userStorage = $entity_type_manager->getStorage('user');
$this->redirectDestination = $redirect_destination;
$this->stringTranslation = $string_translation;
$this->roleStorage = $entity_type_manager->getStorage('user_role');
}
/**
* Provides the list of accounts that can be used for the user switch.
*
* Inactive users are omitted from all of the following db selects. Users
* with 'switch users' permission and anonymous user if include_anon property
* is set to TRUE, are prioritized.
*
* @param int $limit
* The number of accounts to use for the list.
* @param bool $include_anonymous
* Whether or not to include the anonymous user.
*
* @return \Drupal\Core\Session\AccountInterface[]
* List of accounts to be used for the switch.
*/
public function getUsers(int $limit = 50, bool $include_anonymous = FALSE) {
$limit = $include_anonymous ? $limit - 1 : $limit;
// Users with 'switch users' permission are prioritized so get these first.
$query = $this->userStorage
->getQuery()
->condition('uid', 0, '>')
->condition('status', 0, '>')
->sort('access', 'DESC')
->accessCheck(FALSE)
->range(0, $limit);
/** @var array<string, RoleInterface> $roles */
$roles = $this->roleStorage
->loadMultiple();
unset($roles[AccountInterface::ANONYMOUS_ROLE]);
$roles = array_filter($roles, static fn($role): bool => $role->hasPermission('switch users'));
if ($roles !== [] && !isset($roles[RoleInterface::AUTHENTICATED_ID])) {
$query->condition('roles', array_keys($roles), 'IN');
}
$user_ids = $query->execute();
// If we don't have enough users with 'switch users' permission, add more
// users until we hit $limit.
if (count($user_ids) < $limit) {
$query = $this->userStorage
->getQuery()
->condition('uid', 0, '>')
->condition('status', 0, '>')
->sort('access', 'DESC')
->accessCheck(FALSE)
->range(0, $limit);
// Exclude the prioritized user ids if the previous query returned some.
if (!empty($user_ids)) {
$query->condition('uid', array_keys($user_ids), 'NOT IN');
$query->range(0, $limit - count($user_ids));
}
$user_ids += $query->execute();
}
/** @var \Drupal\Core\Session\AccountInterface[] $accounts */
$accounts = $this->userStorage
->loadMultiple($user_ids);
if ($include_anonymous) {
$anonymous = new AnonymousUserSession();
$accounts[$anonymous->id()] = $anonymous;
}
// Syntax comes from https://php.watch/versions/8.2/partially-supported-callable-deprecation.
uasort($accounts, self::class . '::sortUserList');
return $accounts;
}
/**
* Builds the user listing as renderable array.
*
* @param \Drupal\Core\Session\AccountInterface[] $accounts
* The accounts to be rendered in the list.
*
* @return array
* A renderable array.
*/
public function buildUserList(array $accounts) : array {
$links = [];
foreach ($accounts as $account) {
$links[$account->id()] = [
'title' => $account->getDisplayName(),
'url' => Url::fromRoute('devel.switch', [
'name' => $account->getAccountName(),
]),
'query' => $this->redirectDestination
->getAsArray(),
'attributes' => [
'title' => $account->hasPermission('switch users') ? $this->t('This user can switch back.') : $this->t('Caution: this user will be unable to switch back.'),
],
];
if ($account->isAnonymous()) {
$links[$account->id()]['url'] = Url::fromRoute('user.logout');
}
if ($this->currentUser
->id() === $account->id()) {
$links[$account->id()]['title'] = new FormattableMarkup('<strong>%user</strong>', [
'%user' => $account->getDisplayName(),
]);
}
}
return [
'#theme' => 'links',
'#links' => $links,
'#attached' => [
'library' => [
'devel/devel',
],
],
];
}
/**
* Helper callback for uasort() to sort accounts by last access.
*
* @param \Drupal\Core\Session\AccountInterface $a
* First account.
* @param \Drupal\Core\Session\AccountInterface $b
* Second account.
*
* @return int
* Result of comparing the last access times:
* - -1 if $a was more recently accessed
* - 0 if last access times compare equal
* - 1 if $b was more recently accessed
*/
public static function sortUserList(AccountInterface $a, AccountInterface $b) : int {
$a_access = (int) $a->getLastAccessedTime();
$b_access = (int) $b->getLastAccessedTime();
if ($a_access === $b_access) {
return 0;
}
// User never access to site.
if ($a_access === 0) {
return 1;
}
return $a_access > $b_access ? -1 : 1;
}
}
Members
Title Sort descending | Modifiers | Object type | Summary | Overrides |
---|---|---|---|---|
StringTranslationTrait::$stringTranslation | protected | property | The string translation service. | 3 |
StringTranslationTrait::formatPlural | protected | function | Formats a string containing a count of items. | |
StringTranslationTrait::getNumberOfPlurals | protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait::getStringTranslation | protected | function | Gets the string translation service. | |
StringTranslationTrait::setStringTranslation | public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait::t | protected | function | Translates a string to the current language or to a given language. | |
SwitchUserListHelper::$currentUser | protected | property | The Current User object. | |
SwitchUserListHelper::$redirectDestination | protected | property | The redirect destination service. | |
SwitchUserListHelper::$roleStorage | protected | property | The role storage. | |
SwitchUserListHelper::$userStorage | protected | property | The user storage. | |
SwitchUserListHelper::buildUserList | public | function | Builds the user listing as renderable array. | |
SwitchUserListHelper::getUsers | public | function | Provides the list of accounts that can be used for the user switch. | |
SwitchUserListHelper::sortUserList | public static | function | Helper callback for uasort() to sort accounts by last access. | |
SwitchUserListHelper::__construct | public | function | Constructs a new SwitchUserListHelper service. |