Commit ae262e11 authored by catch's avatar catch

Issue #2899392 by idebr, neclimdul, rgpublic: user_hook_toolbar() makes all pages uncacheable

parent 3d6a12a9
......@@ -58,6 +58,18 @@ protected function setUp() {
$this->adminUser2 = $this->drupalCreateUser($this->perms);
}
/**
* Tests toolbar cache integration.
*/
public function testCacheIntegration() {
$this->installExtraModules(['dynamic_page_cache']);
$this->drupalLogin($this->adminUser);
$this->drupalGet('test-page');
$this->assertSame('MISS', $this->getSession()->getResponseHeader('X-Drupal-Dynamic-Cache'));
$this->drupalGet('test-page');
$this->assertSame('HIT', $this->getSession()->getResponseHeader('X-Drupal-Dynamic-Cache'));
}
/**
* Tests toolbar cache contexts.
*/
......
<?php
namespace Drupal\user;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Url;
/**
* ToolbarLinkBuilder fills out the placeholders generated in user_toolbar().
*/
class ToolbarLinkBuilder {
use StringTranslationTrait;
/**
* The current user.
*
* @var \Drupal\Core\Session\AccountProxyInterface
*/
protected $account;
/**
* ToolbarHandler constructor.
*
* @param \Drupal\Core\Session\AccountProxyInterface $account
* The current user.
*/
public function __construct(AccountProxyInterface $account) {
$this->account = $account;
}
/**
* Lazy builder callback for rendering toolbar links.
*
* @return array
* A renderable array as expected by the renderer service.
*/
public function renderToolbarLinks() {
$links = [
'account' => [
'title' => $this->t('View profile'),
'url' => Url::fromRoute('user.page'),
'attributes' => [
'title' => $this->t('User account'),
],
],
'account_edit' => [
'title' => $this->t('Edit profile'),
'url' => Url::fromRoute('entity.user.edit_form', ['user' => $this->account->id()]),
'attributes' => [
'title' => $this->t('Edit user account'),
],
],
'logout' => [
'title' => $this->t('Log out'),
'url' => Url::fromRoute('user.logout'),
],
];
$build = [
'#theme' => 'links__toolbar_user',
'#links' => $links,
'#attributes' => [
'class' => ['toolbar-menu'],
],
'#cache' => [
'contexts' => ['user'],
],
];
return $build;
}
/**
* Lazy builder callback for rendering the username.
*
* @return array
* A renderable array as expected by the renderer service.
*/
public function renderDisplayName() {
return [
'#markup' => $this->account->getDisplayName(),
];
}
}
......@@ -9,7 +9,6 @@
use Drupal\Component\Render\PlainTextOutput;
use Drupal\Component\Utility\Unicode;
use Drupal\Core\Asset\AttachedAssetsInterface;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Render\Element;
......@@ -1328,41 +1327,6 @@ function user_cookie_delete($cookie_name) {
function user_toolbar() {
$user = \Drupal::currentUser();
// Add logout & user account links or login link.
$links_cache_contexts = [];
if ($user->isAuthenticated()) {
$links = [
'account' => [
'title' => t('View profile'),
'url' => Url::fromRoute('user.page'),
'attributes' => [
'title' => t('User account'),
],
],
'account_edit' => [
'title' => t('Edit profile'),
'url' => Url::fromRoute('entity.user.edit_form', ['user' => $user->id()]),
'attributes' => [
'title' => t('Edit user account'),
],
],
'logout' => [
'title' => t('Log out'),
'url' => Url::fromRoute('user.logout'),
],
];
// The "Edit user account" link is per-user.
$links_cache_contexts[] = 'user';
}
else {
$links = [
'login' => [
'title' => t('Log in'),
'url' => Url::fromRoute('user.page'),
],
];
}
$items['user'] = [
'#type' => 'toolbar_item',
'tab' => [
......@@ -1374,26 +1338,12 @@ function user_toolbar() {
'class' => ['toolbar-icon', 'toolbar-icon-user'],
],
'#cache' => [
'contexts' => [
// Cacheable per user, because the current user's name is shown.
'user',
],
// Vary cache for anonymous and authenticated users.
'contexts' => ['user.roles:anonymous'],
],
],
'tray' => [
'#heading' => t('User account actions'),
'user_links' => [
'#cache' => [
// Cacheable per "authenticated or not", because the links to
// display depend on that.
'contexts' => Cache::mergeContexts(['user.roles:authenticated'], $links_cache_contexts),
],
'#theme' => 'links__toolbar_user',
'#links' => $links,
'#attributes' => [
'class' => ['toolbar-menu'],
],
],
],
'#weight' => 100,
'#attached' => [
......@@ -1403,6 +1353,32 @@ function user_toolbar() {
],
];
if ($user->isAnonymous()) {
$links = [
'login' => [
'title' => t('Log in'),
'url' => Url::fromRoute('user.page'),
],
];
$items['user']['tray']['user_links'] = [
'#theme' => 'links__toolbar_user',
'#links' => $links,
'#attributes' => [
'class' => ['toolbar-menu'],
],
];
}
else {
$items['user']['tab']['#title'] = [
'#lazy_builder' => ['user.toolbar_link_builder:renderDisplayName', []],
'#create_placeholder' => TRUE,
];
$items['user']['tray']['user_links'] = [
'#lazy_builder' => ['user.toolbar_link_builder:renderToolbarLinks', []],
'#create_placeholder' => TRUE,
];
}
return $items;
}
......
......@@ -68,3 +68,6 @@ services:
arguments: ['@current_user', '@entity.manager']
tags:
- { name: 'context_provider' }
user.toolbar_link_builder:
class: Drupal\user\ToolbarLinkBuilder
arguments: ['@current_user']
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment