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:
|
* within contributed and custom code. Reserved attributes include:
|
||||||
* - uid: The user ID for an authenticated user. The value of this attribute
|
* - uid: The user ID for an authenticated user. The value of this attribute
|
||||||
* cannot be modified.
|
* 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:
|
session:
|
||||||
class: Symfony\Component\HttpFoundation\Session\Session
|
class: Symfony\Component\HttpFoundation\Session\Session
|
||||||
arguments: ['@session_manager', '@session.attribute_bag', '@session.flash_bag']
|
arguments: ['@session_manager', '@session.attribute_bag', '@session.flash_bag']
|
||||||
|
tags:
|
||||||
|
- { name: service_collector, tag: session_bag, call: registerBag }
|
||||||
session.flash_bag:
|
session.flash_bag:
|
||||||
class: Symfony\Component\HttpFoundation\Session\Flash\FlashBag
|
class: Symfony\Component\HttpFoundation\Session\Flash\FlashBag
|
||||||
public: false
|
public: false
|
||||||
|
|
|
@ -131,3 +131,33 @@ session_test.set_session:
|
||||||
test_value: '\s+'
|
test_value: '\s+'
|
||||||
requirements:
|
requirements:
|
||||||
_permission: 'administer site configuration'
|
_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 }
|
- { name: session_handler_proxy, priority: 20 }
|
||||||
session_test.session_handler_proxy_trace:
|
session_test.session_handler_proxy_trace:
|
||||||
class: ArrayObject
|
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;
|
namespace Drupal\session_test\Controller;
|
||||||
|
|
||||||
use Drupal\Core\Controller\ControllerBase;
|
use Drupal\Core\Controller\ControllerBase;
|
||||||
|
use Drupal\session_test\Session\TestSessionBag;
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
@ -195,4 +196,54 @@ class SessionTestController extends ControllerBase {
|
||||||
return new JsonResponse(['session' => $session->all(), 'user' => $this->currentUser()->id()]);
|
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.');
|
$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.
|
* Reset the cookie file so that it refers to the specified user.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue