Commit 49dc0872 authored by catch's avatar catch

Issue #2533768 by Wim Leers, lauriii: Add the user entity cache tag to user.*...

Issue #2533768 by Wim Leers, lauriii: Add the user entity cache tag to user.* cache contexts that need it
parent 37c1ee8c
......@@ -57,7 +57,11 @@ public function getContext() {
*/
public function getCacheableMetadata() {
$cacheable_metadata = new CacheableMetadata();
$tags = [];
// The permissions hash changes when:
// - a user is updated to have different roles;
$tags = ['user:' . $this->user->id()];
// - a role is updated to have different permissions.
foreach ($this->user->getRoles() as $rid) {
$tags[] = "config:user.role.$rid";
}
......
......@@ -51,7 +51,7 @@ public function getContext($role = NULL) {
* {@inheritdoc}
*/
public function getCacheableMetadata($role = NULL) {
return new CacheableMetadata();
return (new CacheableMetadata())->setCacheTags(['user:' . $this->user->id()]);
}
}
......@@ -93,6 +93,11 @@ public function getCacheableMetadata($operation = NULL) {
return $cacheable_metadata;
}
// The node grants may change if the user is updated. (The max-age is set to
// zero below, but sites may override this cache context, and change it to a
// non-zero value. In such cases, this cache tag is needed for correctness.)
$cacheable_metadata->setCacheTags(['user:' . $this->user->id()]);
// If the site is using node grants, this cache context can not be
// optimized.
return $cacheable_metadata->setCacheMaxAge(0);
......
......@@ -80,4 +80,45 @@ public function testUserPermissionCacheContextOptimization() {
$this->assertEqual($output, 'this should be visible');
}
/**
* Ensures that 'user.roles' still works when it is optimized away.
*/
public function testUserRolesCacheContextOptimization() {
$root_user = $this->createUser();
$this->assertEqual($root_user->id(), 1);
$authenticated_user = $this->createUser(['administer permissions']);
$role = $authenticated_user->getRoles()[1];
$test_element = [
'#cache' => [
'keys' => ['test'],
'contexts' => ['user', 'user.roles'],
],
];
\Drupal::service('account_switcher')->switchTo($authenticated_user);
$element = $test_element;
$element['#markup'] = 'content for authenticated users';
$output = \Drupal::service('renderer')->renderRoot($element);
$this->assertEqual($output, 'content for authenticated users');
// Verify that the render caching is working so that other tests can be
// trusted.
$element = $test_element;
$element['#markup'] = 'this should not be visible';
$output = \Drupal::service('renderer')->renderRoot($element);
$this->assertEqual($output, 'content for authenticated users');
// Even though the cache contexts have been optimized to only include 'user'
// cache context, the element should have been changed because 'user.roles'
// cache context defined a cache tag for user entity changes23, which should
// have bubbled up for the element when it was optimized away.
$authenticated_user->removeRole($role);
$authenticated_user->save();
$element = $test_element;
$element['#markup'] = 'this should be visible';
$output = \Drupal::service('renderer')->renderRoot($element);
$this->assertEqual($output, 'this should be visible');
}
}
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