Wim Leers
Principal Software Engineer
's Office of the CTO
inputs | → 🤖…💪…🤖…💪…🤖…💪 | → output | |
inputs | → cache ID → read | → output |
tags | stored data | 🏓 → 🏂 |
contexts | circumstances | ☂️ ↔ ☔️ |
max-age | freshness | 🕰️ 📈 |
/**
* @Block(id = "journey_talk_uncacheable_block")
*/
class UncacheableBlock extends BlockBase {
public function build() {
usleep(250*1000); // Pretend we're computing a better forecast 👍
return [
'#markup' => $this->t('Weather forecast at @time: ☔️.
', [
'@time' => (int) microtime(TRUE),
]),
];
}
public function getCacheMaxAge() {
return 0;
}
}
/**
* @Block(id = "journey_talk_personalized_per_session_block")
*/
class PersonalizedPerSessionBlock extends BlockBase {
public function build() {
$funny_emojis = ['🤷', '😂', '🙈', '🐷', '🐑'];
return [
'#markup' => $this->t('Funny emoji just for you: @emoji
(Hand-picked at @time!)
', [
'@emoji' => $funny_emojis[rand(0, count($funny_emojis) - 1)],
'@time' => (int) microtime(TRUE),
]),
];
}
public function getCacheContexts() {
return ['session'];
}
}
/**
* @Block(id = "journey_talk_personalized_per_user_block")
*/
class PersonalizedPerUserBlock extends BlockBase {
public function build() {
$funny_emojis = ['🤷', '😂', '🙈', '🐷', '🐑'];
return [
'#markup' => $this->t('Today\'s funny emoji just for you: @emoji
(Hand-picked at @time!)
', [
'@emoji' => $funny_emojis[rand(0, count($funny_emojis) - 1)],
'@time' => (int) microtime(TRUE),
]),
];
}
public function getCacheContexts() {
return ['user'];
}
public function getCacheMaxAge() {
return 86400;
}
}
/**
* @Block(id = "journey_talk_cacheable_block")
*/
class CacheableBlock extends BlockBase {
public function build() {
return [
'#markup' => $this->t('%name runs this site!', [
'%name' => User::load(1)->getAccountName(),
]),
];
}
protected function blockAccess(AccountInterface $account) {
return AccessResult::allowedIf($account->id() != 1);
}
public function getCacheTags() {
return ['user:1'];
}
}
👩💻
👇
class CacheTagsTest extends BrowserTestBase {
// Tests that for cached pages, content changes are visible immediately.
public function testBlackbox() {
$this->assertThing('initial title');
Node::load(1)->setTitle('foobar')->save();
$this->assertThing('foobar');
}
protected function assertThing($title) {
$this->drupalGet('/some/path');
$this->assertRaw($title);
}
}
class CacheTagsTest extends BrowserTestBase {
// Tests that for cached pages, content changes are visible immediately.
public function testWhitebox() {
$this->assertThing('initial title', 'MISS', 'MISS');
$this->assertThing('initial title', 'HIT', 'HIT');
Node::load(1)->setTitle('foobar')->save();
$this->assertThing('foobar', 'MISS', 'MISS');
$this->assertThing('foobar', 'HIT', 'HIT');
}
protected function assertThing($title, $dpc, $pc) {
$this->drupalGet('/some/path');
$this->assertRaw($title);
$this->assertCacheTags(['node:1']);
$this->assertSame($this->drupalGetHeader('X-Drupal-Dynamic-Cache'), $dpc);
$this->assertSame($this->drupalGetHeader('X-Drupal-Cache'), $pc);
}
}
class CacheContextsTest extends BrowserTestBase {
// Tests that for cached pages, permission-dependent access is respected.
public function testBlackbox() {
$this->assertAsAdminAndAnon(TRUE, TRUE);
Node::load(1)->setUnpublished()->save();
$this->assertAsAdminAndAnon(TRUE, FALSE);
}
protected function assertAsAdminAndAnon($visible_for_admin, $visible_for_anon) {
$this->drupalLogin($this->administrator);
$this->assertThing($visible_for_admin);
$this->drupalLogout();
$this->assertThing($visible_for_anon);
}
protected function assertThing($is_visible) {
$this->drupalGet('/some/path');
$is_visible
? $this->assertRaw('initial title')
: $this->assertNoRaw('initial title');
}
}
class CacheContextsTest extends BrowserTestBase {
// Tests that for cached pages, permission-dependent access is respected.
public function testWhitebox() {
$this->assertAsAdminAndAnon(TRUE, TRUE);
Node::load(1)->setUnpublished()->save();
$this->assertAsAdminAndAnon(TRUE, FALSE);
}
protected function assertAsAdminAndAnon($visible_for_admin, $visible_for_anon) {
$this->drupalLogin($this->administrator);
$this->assertThing($visible_for_admin, 'MISS', NULL);
$this->assertThing($visible_for_admin, 'HIT', NULL);
$this->drupalLogout();
$this->assertThing($visible_for_anon, 'MISS', 'MISS');
$this->assertThing($visible_for_anon, 'HIT', 'HIT');
}
protected function assertThing($is_visible, $dpc, $pc) {
parent::assertThing($is_visible);
$this->assertCacheContexts(['user.permissions']);
$this->assertSame($this->drupalGetHeader('X-Drupal-Dynamic-Cache'), $dpc);
$this->assertSame($this->drupalGetHeader('X-Drupal-Cache'), $pc);
}
}
?