Issue #2671988 by Wim Leers: Add SessionExistsCacheContext ('session.exists')

8.1.x
Nathaniel Catchpole 2016-02-25 14:35:35 +09:00
parent 3a18d596b9
commit 4a67b9d4a8
5 changed files with 175 additions and 0 deletions

View File

@ -55,6 +55,11 @@ services:
arguments: ['@request_stack']
tags:
- { name: cache.context}
cache_context.session.exists:
class: Drupal\Core\Cache\Context\SessionExistsCacheContext
arguments: ['@session_configuration', '@request_stack']
tags:
- { name: cache.context}
cache_context.request_format:
class: Drupal\Core\Cache\Context\RequestFormatCacheContext
arguments: ['@request_stack']

View File

@ -0,0 +1,69 @@
<?php
/**
* @file
* Contains \Drupal\Core\Cache\Context\SessionExistsCacheContext.
*/
namespace Drupal\Core\Cache\Context;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Session\SessionConfigurationInterface;
use Symfony\Component\HttpFoundation\RequestStack;
/**
* Defines the SessionExistsCacheContext service, for "session or not" caching.
*
* Cache context ID: 'session.exists'.
*/
class SessionExistsCacheContext implements CacheContextInterface {
/**
* The session configuration.
*
* @var \Drupal\Core\Session\SessionConfigurationInterface
*/
protected $sessionConfiguration;
/**
* The request stack.
*
* @var \Symfony\Component\HttpFoundation\RequestStack
*/
protected $requestStack;
/**
* Constructs a new SessionExistsCacheContext class.
*
* @param \Drupal\Core\Session\SessionConfigurationInterface $session_configuration
* The session configuration.
* @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
* The request stack.
*/
public function __construct(SessionConfigurationInterface $session_configuration, RequestStack $request_stack) {
$this->sessionConfiguration = $session_configuration;
$this->requestStack = $request_stack;
}
/**
* {@inheritdoc}
*/
public static function getLabel() {
return t('Session exists');
}
/**
* {@inheritdoc}
*/
public function getContext() {
return $this->sessionConfiguration->hasSession($this->requestStack->getCurrentRequest()) ? '1' : '0';
}
/**
* {@inheritdoc}
*/
public function getCacheableMetadata() {
return new CacheableMetadata();
}
}

View File

@ -0,0 +1,71 @@
<?php
/**
* @file
* Contains \Drupal\system\Tests\Cache\SessionExistsCacheContextTest.
*/
namespace Drupal\system\Tests\Cache;
use Drupal\Core\Url;
use Drupal\simpletest\WebTestBase;
/**
* Tests the 'session.exists' cache context service.
*
* @group Cache
*/
class SessionExistsCacheContextTest extends WebTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['session_exists_cache_context_test'];
/**
* Tests \Drupal\Core\Cache\Context\SessionExistsCacheContext::getContext().
*/
public function testCacheContext() {
$this->dumpHeaders = TRUE;
// 1. No session (anonymous).
$this->assertSessionCookieOnClient(FALSE);
$this->drupalGet(Url::fromRoute('<front>'));
$this->assertSessionCookieOnClient(FALSE);
$this->assertRaw('Session does not exist!');
$this->assertRaw('[session.exists]=0');
// 2. Session (authenticated).
$this->assertSessionCookieOnClient(FALSE);
$this->drupalLogin($this->rootUser);
$this->assertSessionCookieOnClient(TRUE);
$this->assertRaw('Session exists!');
$this->assertRaw('[session.exists]=1');
$this->drupalLogout();
$this->assertSessionCookieOnClient(FALSE);
$this->assertRaw('Session does not exist!');
$this->assertRaw('[session.exists]=0');
// 3. Session (anonymous).
$this->assertSessionCookieOnClient(FALSE);
$this->drupalGet(Url::fromRoute('<front>', [], ['query' => ['trigger_session' => 1]]));
$this->assertSessionCookieOnClient(TRUE);
$this->assertRaw('Session does not exist!');
$this->assertRaw('[session.exists]=0');
$this->drupalGet(Url::fromRoute('<front>'));
$this->assertSessionCookieOnClient(TRUE);
$this->assertRaw('Session exists!');
$this->assertRaw('[session.exists]=1');
}
/**
* Asserts whether a session cookie is present on the client or not.
*/
function assertSessionCookieOnClient($expected_present) {
$non_deleted_cookies = array_filter($this->cookies, function ($item) { return $item['value'] !== 'deleted'; });
$this->assertEqual($expected_present, isset($non_deleted_cookies[$this->getSessionName()]), 'Session cookie exists.');
}
}

View File

@ -0,0 +1,6 @@
name: 'session.exists cache context test'
type: module
description: 'Support module for session.exists cache context testing.'
package: Testing
version: VERSION
core: 8.x

View File

@ -0,0 +1,24 @@
<?php
/**
* Implements hook_page_top().
*/
function session_exists_cache_context_test_page_top(array &$page_top) {
// Ensure this hook is invoked on every page load.
$page_top['#cache']['max-age'] = 0;
$request = \Drupal::request();
$session_exists = \Drupal::service('session_configuration')->hasSession($request);
$page_top['session_exists_cache_context_test'] = [
'label' => [
'#markup' => '<p>' . ($session_exists ? 'Session exists!' : 'Session does not exist!') . '</p>',
],
'cache_context_value' => [
'#markup' => '<code>[session.exists]=' . \Drupal::service('cache_context.session.exists')->getContext() . '</code>',
],
];
if (\Drupal::request()->query->get('trigger_session')) {
$_SESSION['session_exists_cache_context_test'] = TRUE;
}
}