shortcut.module
Same filename in other branches
File
-
core/
modules/ shortcut/ shortcut.module
View source
<?php
/**
* @file
*/
use Drupal\Component\Render\FormattableMarkup;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Url;
use Drupal\shortcut\ShortcutSetInterface;
/**
* Access callback for editing a shortcut set.
*
* @param Drupal\shortcut\ShortcutSetInterface $shortcut_set
* (optional) The shortcut set to be edited. If not set, the current user's
* shortcut set will be used.
*
* @return \Drupal\Core\Access\AccessResultInterface
* The access result.
*/
function shortcut_set_edit_access(?ShortcutSetInterface $shortcut_set = NULL) {
$account = \Drupal::currentUser();
// Shortcut administrators can edit any set.
if ($account->hasPermission('administer shortcuts')) {
return AccessResult::allowed()->cachePerPermissions();
}
// Sufficiently-privileged users can edit their currently displayed shortcut
// set, but not other sets. They must also be able to access shortcuts.
$may_edit_current_shortcut_set = $account->hasPermission('customize shortcut links') && $account->hasPermission('access shortcuts');
if ($may_edit_current_shortcut_set && isset($shortcut_set)) {
$displayed_shortcut_set = \Drupal::entityTypeManager()->getStorage('shortcut_set')
->getDisplayedToUser($account);
$may_edit_current_shortcut_set = $shortcut_set == $displayed_shortcut_set;
}
$result = AccessResult::allowedIf($may_edit_current_shortcut_set)->cachePerPermissions();
if (!$result->isAllowed()) {
$result->setReason("The shortcut set must be the currently displayed set for the user and the user must have 'access shortcuts' AND 'customize shortcut links' permissions.");
}
return $result;
}
/**
* Access callback for switching the shortcut set assigned to a user account.
*
* @param object $account
* (optional) The user account whose shortcuts will be switched. If not set,
* permissions will be checked for switching the logged-in user's own
* shortcut set.
*
* @return \Drupal\Core\Access\AccessResultInterface
* The access result.
*/
function shortcut_set_switch_access($account = NULL) {
$user = \Drupal::currentUser();
if ($user->hasPermission('administer shortcuts')) {
// Administrators can switch anyone's shortcut set.
return AccessResult::allowed()->cachePerPermissions();
}
if (!$user->hasPermission('access shortcuts')) {
// The user has no permission to use shortcuts.
return AccessResult::neutral()->cachePerPermissions();
}
if (!$user->hasPermission('switch shortcut sets')) {
// The user has no permission to switch anyone's shortcut set.
return AccessResult::neutral()->cachePerPermissions();
}
// Users with the 'switch shortcut sets' permission can switch their own
// shortcuts sets.
if (!isset($account)) {
return AccessResult::allowed()->cachePerPermissions();
}
elseif ($user->id() == $account->id()) {
return AccessResult::allowed()->cachePerPermissions()
->cachePerUser();
}
// No opinion.
return AccessResult::neutral()->cachePerPermissions();
}
/**
* Returns an array of shortcut links, suitable for rendering.
*
* @param \Drupal\shortcut\ShortcutSetInterface $shortcut_set
* (optional) An object representing the set whose links will be displayed.
* If not provided, the user's current set will be displayed.
*
* @return \Drupal\shortcut\ShortcutInterface[]
* An array of shortcut links, in the format returned by the menu system.
*/
function shortcut_renderable_links($shortcut_set = NULL) {
$shortcut_links = [];
if (!isset($shortcut_set)) {
$account = \Drupal::currentUser();
$shortcut_set = \Drupal::entityTypeManager()->getStorage('shortcut_set')
->getDisplayedToUser($account);
}
$cache_tags = [];
foreach ($shortcut_set->getShortcuts() as $shortcut) {
$shortcut = \Drupal::service('entity.repository')->getTranslationFromContext($shortcut);
$url = $shortcut->getUrl();
if ($url->access()) {
$links[$shortcut->id()] = [
'type' => 'link',
'title' => $shortcut->label(),
'url' => $shortcut->getUrl(),
];
$cache_tags = Cache::mergeTags($cache_tags, $shortcut->getCacheTags());
}
}
if (!empty($links)) {
$shortcut_links = [
'#theme' => 'links__toolbar_shortcuts',
'#links' => $links,
'#attributes' => [
'class' => [
'toolbar-menu',
],
],
'#cache' => [
'tags' => $cache_tags,
],
];
}
return $shortcut_links;
}
/**
* Implements hook_preprocess_HOOK() for block templates.
*/
function shortcut_preprocess_block(&$variables) : void {
if ($variables['configuration']['provider'] == 'shortcut') {
$variables['attributes']['role'] = 'navigation';
}
}
/**
* Implements hook_preprocess_HOOK() for page title templates.
*/
function shortcut_preprocess_page_title(&$variables) : void {
// Only display the shortcut link if the user has the ability to edit
// shortcuts, the feature is enabled for the current theme and if the page's
// actual content is being shown (for example, we do not want to display it on
// "access denied" or "page not found" pages).
if (shortcut_set_edit_access()->isAllowed() && theme_get_setting('third_party_settings.shortcut.module_link') && !\Drupal::request()->attributes
->has('exception')) {
$link = Url::fromRouteMatch(\Drupal::routeMatch())->getInternalPath();
$route_match = \Drupal::routeMatch();
// Replicate template_preprocess_html()'s processing to get the title in
// string form, so we can set the default name for the shortcut.
$name = $variables['title'] ?? '';
if (is_array($name)) {
$name = \Drupal::service('renderer')->render($name);
}
$query = [
'link' => $link,
'name' => trim(strip_tags($name)),
];
$shortcut_set = \Drupal::entityTypeManager()->getStorage('shortcut_set')
->getDisplayedToUser(\Drupal::currentUser());
// Pages with the add or remove shortcut button need cache invalidation when
// a shortcut is added, edited, or removed.
$cacheability_metadata = CacheableMetadata::createFromRenderArray($variables);
$cacheability_metadata->addCacheTags(\Drupal::entityTypeManager()->getDefinition('shortcut')
->getListCacheTags());
$cacheability_metadata->applyTo($variables);
// Check if $link is already a shortcut and set $link_mode accordingly.
$shortcuts = \Drupal::entityTypeManager()->getStorage('shortcut')
->loadByProperties([
'shortcut_set' => $shortcut_set->id(),
]);
/** @var \Drupal\shortcut\ShortcutInterface $shortcut */
foreach ($shortcuts as $shortcut) {
if (($shortcut_url = $shortcut->getUrl()) && $shortcut_url->isRouted() && $shortcut_url->getRouteName() == $route_match->getRouteName() && $shortcut_url->getRouteParameters() == $route_match->getRawParameters()
->all()) {
$shortcut_id = $shortcut->id();
break;
}
}
$link_mode = isset($shortcut_id) ? "remove" : "add";
if ($link_mode == "add") {
$link_text = shortcut_set_switch_access()->isAllowed() ? t('Add to %shortcut_set shortcuts', [
'%shortcut_set' => $shortcut_set->label(),
]) : t('Add to shortcuts');
$route_name = 'shortcut.link_add_inline';
$route_parameters = [
'shortcut_set' => $shortcut_set->id(),
];
}
else {
$query['id'] = $shortcut_id;
$link_text = shortcut_set_switch_access()->isAllowed() ? t('Remove from %shortcut_set shortcuts', [
'%shortcut_set' => $shortcut_set->label(),
]) : t('Remove from shortcuts');
$route_name = 'entity.shortcut.link_delete_inline';
$route_parameters = [
'shortcut' => $shortcut_id,
];
}
$query += \Drupal::destination()->getAsArray();
$variables['title_suffix']['add_or_remove_shortcut'] = [
'#attached' => [
'library' => [
'shortcut/drupal.shortcut',
],
],
'#type' => 'link',
'#title' => new FormattableMarkup('<span class="shortcut-action__icon"></span><span class="shortcut-action__message">@text</span>', [
'@text' => $link_text,
]),
'#url' => Url::fromRoute($route_name, $route_parameters),
'#options' => [
'query' => $query,
],
'#attributes' => [
'class' => [
'shortcut-action',
'shortcut-action--' . $link_mode,
],
],
];
}
}
Functions
Title | Deprecated | Summary |
---|---|---|
shortcut_preprocess_block | Implements hook_preprocess_HOOK() for block templates. | |
shortcut_preprocess_page_title | Implements hook_preprocess_HOOK() for page title templates. | |
shortcut_renderable_links | Returns an array of shortcut links, suitable for rendering. | |
shortcut_set_edit_access | Access callback for editing a shortcut set. | |
shortcut_set_switch_access | Access callback for switching the shortcut set assigned to a user account. |
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.