Issue #3108967 by znerol, andypost, alexpott: Introduce a container tag to register session bags
parent
b978479e86
commit
d1daa7ec28
|
@ -2605,5 +2605,29 @@ function hook_validation_constraint_alter(array &$definitions) {
|
|||
* within contributed and custom code. Reserved attributes include:
|
||||
* - uid: The user ID for an authenticated user. The value of this attribute
|
||||
* cannot be modified.
|
||||
*
|
||||
* @section sec_custom_session_bags Custom session bags
|
||||
* Modules can register custom session bags in order to provide type safe
|
||||
* interfaces on module specific session data. A session bag must implement
|
||||
* \Symfony\Component\HttpFoundation\Session\SessionBagInterface. Custom session
|
||||
* bags are registered using a service entry tagged with the session_bag service
|
||||
* tag. Custom session bags can be accessed through the session retrieved from
|
||||
* the request object.
|
||||
*
|
||||
* Example service definition:
|
||||
* @code
|
||||
* session_test.session_bag:
|
||||
* class: Drupal\session_test\Session\TestSessionBag
|
||||
* tags:
|
||||
* - { name: session_bag }
|
||||
* @endcode
|
||||
*
|
||||
* Example of accessing a custom session bag:
|
||||
* @code
|
||||
* $bag = $request->getSession()->getBag(TestSessionBag::BAG_NAME);
|
||||
* $bag->setFlag();
|
||||
* @endcode
|
||||
* Session data must be deleted from custom session bags as soon as it is no
|
||||
* longer needed (see @ref sec_intro above).
|
||||
* @}
|
||||
*/
|
||||
|
|
|
@ -1512,6 +1512,8 @@ services:
|
|||
session:
|
||||
class: Symfony\Component\HttpFoundation\Session\Session
|
||||
arguments: ['@session_manager', '@session.attribute_bag', '@session.flash_bag']
|
||||
tags:
|
||||
- { name: service_collector, tag: session_bag, call: registerBag }
|
||||
session.flash_bag:
|
||||
class: Symfony\Component\HttpFoundation\Session\Flash\FlashBag
|
||||
public: false
|
||||
|
|
|
@ -131,3 +131,33 @@ session_test.set_session:
|
|||
test_value: '\s+'
|
||||
requirements:
|
||||
_permission: 'administer site configuration'
|
||||
|
||||
session_test.set_bag_flag:
|
||||
path: '/session-test/set-bag-flag'
|
||||
defaults:
|
||||
_title: 'Sets the test flag in the session test bag'
|
||||
_controller: '\Drupal\session_test\Controller\SessionTestController::setSessionBagFlag'
|
||||
options:
|
||||
no_cache: TRUE
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
session_test.clear_bag_flag:
|
||||
path: '/session-test/clear-bag-flag'
|
||||
defaults:
|
||||
_title: 'Clears the test flag in the session test bag'
|
||||
_controller: '\Drupal\session_test\Controller\SessionTestController::clearSessionBagFlag'
|
||||
options:
|
||||
no_cache: TRUE
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
session_test.has_bag_flag:
|
||||
path: '/session-test/has-bag-flag'
|
||||
defaults:
|
||||
_title: 'Prints a message if the flag in the session bag is set'
|
||||
_controller: '\Drupal\session_test\Controller\SessionTestController::hasSessionBagFlag'
|
||||
options:
|
||||
no_cache: TRUE
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
|
|
@ -14,3 +14,7 @@ services:
|
|||
- { name: session_handler_proxy, priority: 20 }
|
||||
session_test.session_handler_proxy_trace:
|
||||
class: ArrayObject
|
||||
session_test.session_bag:
|
||||
class: Drupal\session_test\Session\TestSessionBag
|
||||
tags:
|
||||
- { name: session_bag }
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
namespace Drupal\session_test\Controller;
|
||||
|
||||
use Drupal\Core\Controller\ControllerBase;
|
||||
use Drupal\session_test\Session\TestSessionBag;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
@ -195,4 +196,54 @@ class SessionTestController extends ControllerBase {
|
|||
return new JsonResponse(['session' => $session->all(), 'user' => $this->currentUser()->id()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the test flag in the session test bag.
|
||||
*
|
||||
* @param \Symfony\Component\HttpFoundation\Request $request
|
||||
* The request object.
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
* The response object.
|
||||
*/
|
||||
public function setSessionBagFlag(Request $request) {
|
||||
/** @var \Drupal\session_test\Session\TestSessionBag */
|
||||
$bag = $request->getSession()->getBag(TestSessionBag::BAG_NAME);
|
||||
$bag->setFlag();
|
||||
return new Response();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the test flag from the session test bag.
|
||||
*
|
||||
* @param \Symfony\Component\HttpFoundation\Request $request
|
||||
* The request object.
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
* The response object.
|
||||
*/
|
||||
public function clearSessionBagFlag(Request $request) {
|
||||
/** @var \Drupal\session_test\Session\TestSessionBag */
|
||||
$bag = $request->getSession()->getBag(TestSessionBag::BAG_NAME);
|
||||
$bag->clearFlag();
|
||||
return new Response();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a message if the flag in the session bag is set.
|
||||
*
|
||||
* @param \Symfony\Component\HttpFoundation\Request $request
|
||||
* The request object.
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
* The response object.
|
||||
*/
|
||||
public function hasSessionBagFlag(Request $request) {
|
||||
/** @var \Drupal\session_test\Session\TestSessionBag */
|
||||
$bag = $request->getSession()->getBag(TestSessionBag::BAG_NAME);
|
||||
return new Response(empty($bag->hasFlag())
|
||||
? $this->t('Flag is absent from session bag')
|
||||
: $this->t('Flag is present in session bag')
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\session_test\Session;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
|
||||
|
||||
/**
|
||||
* Test session container.
|
||||
*/
|
||||
class TestSessionBag implements SessionBagInterface {
|
||||
|
||||
/**
|
||||
* The bag name.
|
||||
*/
|
||||
const BAG_NAME = 'session_test';
|
||||
|
||||
/**
|
||||
* Key used when persisting the session.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $storageKey;
|
||||
|
||||
/**
|
||||
* Storage for data to save.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $attributes = [];
|
||||
|
||||
/**
|
||||
* Constructs a new TestSessionBag object.
|
||||
*
|
||||
* @param string $storage_key
|
||||
* The key used to store test attributes.
|
||||
*/
|
||||
public function __construct($storage_key = '_dp_session_test') {
|
||||
$this->storageKey = $storage_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the test flag.
|
||||
*/
|
||||
public function setFlag() {
|
||||
$this->attributes['test_flag'] = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns TRUE if the test flag is set.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE when flag is set, FALSE otherwise.
|
||||
*/
|
||||
public function hasFlag() {
|
||||
return !empty($this->attributes['test_flag']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the test flag.
|
||||
*/
|
||||
public function clearFlag() {
|
||||
unset($this->attributes['test_flag']);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName() {
|
||||
return self::BAG_NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function initialize(array &$attributes) {
|
||||
$this->attributes = &$attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getStorageKey() {
|
||||
return $this->storageKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function clear() {
|
||||
$return = $this->attributes;
|
||||
$this->attributes = [];
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
}
|
|
@ -295,6 +295,36 @@ class SessionTest extends BrowserTestBase {
|
|||
$this->assertResponse(403, 'An empty session ID is not allowed.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test session bag.
|
||||
*/
|
||||
public function testSessionBag() {
|
||||
$this->drupalGet('/session-test/has-bag-flag');
|
||||
$this->assertSessionCookie(FALSE);
|
||||
$this->assertSessionEmpty(TRUE);
|
||||
$this->assertResponse(200, 'Flag is absent from session bag');
|
||||
|
||||
$this->drupalGet('/session-test/set-bag-flag');
|
||||
$this->assertSessionCookie(TRUE);
|
||||
$this->assertSessionEmpty(TRUE);
|
||||
$this->assertResponse(200);
|
||||
|
||||
$this->drupalGet('/session-test/has-bag-flag');
|
||||
$this->assertSessionCookie(TRUE);
|
||||
$this->assertSessionEmpty(FALSE);
|
||||
$this->assertResponse(200, 'Flag is present in session bag');
|
||||
|
||||
$this->drupalGet('/session-test/clear-bag-flag');
|
||||
$this->assertSessionCookie(FALSE);
|
||||
$this->assertSessionEmpty(FALSE);
|
||||
$this->assertResponse(200);
|
||||
|
||||
$this->drupalGet('/session-test/has-bag-flag');
|
||||
$this->assertSessionCookie(FALSE);
|
||||
$this->assertSessionEmpty(TRUE);
|
||||
$this->assertResponse(200, 'Flag is absent from session bag');
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the cookie file so that it refers to the specified user.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue