Skip to content

Commit d048d8a

Browse files
author
Drak
committed
[HttpFoundation] Give control over how session start on demand.
This allows control over how the session start on demand works 0: no start on demand when bags are accessed 1: start session if bags are accessed 2: no start on demand when bags are accessed but still return bag contents
1 parent 13faf04 commit d048d8a

8 files changed

+140
-20
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ CHANGELOG
44
2.3.0
55

66
* `UploadedFile::isValid` now returns false if the file was not uploaded via HTTP (in a non-test mode)
7+
* addded control for session start on demand.
78

89
2.2.0
910
-----

Session/Storage/MockArraySessionStorage.php

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,16 +63,23 @@ class MockArraySessionStorage implements SessionStorageInterface
6363
*/
6464
protected $bags;
6565

66+
/**
67+
* @var Boolean
68+
*/
69+
protected $mode;
70+
6671
/**
6772
* Constructor.
6873
*
69-
* @param string $name Session name
74+
* @param string $name Session name.
7075
* @param MetadataBag $metaBag MetadataBag instance.
76+
* @param integer $mode Session on demand mode.
7177
*/
72-
public function __construct($name = 'MOCKSESSID', MetadataBag $metaBag = null)
78+
public function __construct($name = 'MOCKSESSID', MetadataBag $metaBag = null, $mode = self::START_ON_DEMAND)
7379
{
7480
$this->name = $name;
7581
$this->setMetadataBag($metaBag);
82+
$this->mode = $mode;
7683
}
7784

7885
/**
@@ -197,11 +204,13 @@ public function registerBag(SessionBagInterface $bag)
197204
public function getBag($name)
198205
{
199206
if (!isset($this->bags[$name])) {
200-
throw new \InvalidArgumentException(sprintf('The SessionBagInterface %s is not registered.', $name));
207+
throw new \InvalidArgumentException(sprintf('The SessionBagInterface %s is not registered', $name));
201208
}
202209

203-
if (!$this->started) {
210+
if (!$this->started && self::START_ON_DEMAND === $this->mode) {
204211
$this->start();
212+
} elseif (!$this->started && self::NO_START_ON_DEMAND_STRICT === $this->mode) {
213+
throw new \RuntimeException('Cannot access session bags because the session has been started');
205214
}
206215

207216
return $this->bags[$name];

Session/Storage/MockFileSessionStorage.php

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,15 @@ class MockFileSessionStorage extends MockArraySessionStorage
2929
*/
3030
private $savePath;
3131

32-
/**
33-
* @var array
34-
*/
35-
private $sessionData;
36-
3732
/**
3833
* Constructor.
3934
*
4035
* @param string $savePath Path of directory to save session files.
4136
* @param string $name Session name.
4237
* @param MetadataBag $metaBag MetadataBag instance.
38+
* @param integer $mode Start on demand mode.
4339
*/
44-
public function __construct($savePath = null, $name = 'MOCKSESSID', MetadataBag $metaBag = null)
40+
public function __construct($savePath = null, $name = 'MOCKSESSID', MetadataBag $metaBag = null, $mode = self::START_ON_DEMAND)
4541
{
4642
if (null === $savePath) {
4743
$savePath = sys_get_temp_dir();
@@ -53,7 +49,7 @@ public function __construct($savePath = null, $name = 'MOCKSESSID', MetadataBag
5349

5450
$this->savePath = $savePath;
5551

56-
parent::__construct($name, $metaBag);
52+
parent::__construct($name, $metaBag, $mode);
5753
}
5854

5955
/**

Session/Storage/NativeSessionStorage.php

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,26 @@ class NativeSessionStorage implements SessionStorageInterface
5151
*/
5252
protected $metadataBag;
5353

54+
/**
55+
* @var Boolean
56+
*/
57+
protected $mode;
58+
59+
/**
60+
* @var Boolean
61+
*/
62+
protected $emulatePhp;
63+
5464
/**
5565
* Constructor.
5666
*
5767
* Depending on how you want the storage driver to behave you probably
5868
* want to override this constructor entirely.
5969
*
6070
* List of options for $options array with their defaults.
71+
*
6172
* @see http://php.net/session.configuration for options
62-
* but we omit 'session.' from the beginning of the keys for convenience.
73+
* but we omit 'session.' from the beginning of the keys for convenience.
6374
*
6475
* ("auto_start", is not supported as it tells PHP to start a session before
6576
* PHP starts to execute user-land code. Setting during runtime has no effect).
@@ -94,8 +105,9 @@ class NativeSessionStorage implements SessionStorageInterface
94105
* @param array $options Session configuration options.
95106
* @param object $handler SessionHandlerInterface.
96107
* @param MetadataBag $metaBag MetadataBag.
108+
* @param integer $mode Start on demand mode.
97109
*/
98-
public function __construct(array $options = array(), $handler = null, MetadataBag $metaBag = null)
110+
public function __construct(array $options = array(), $handler = null, MetadataBag $metaBag = null, $mode = self::START_ON_DEMAND)
99111
{
100112
ini_set('session.cache_limiter', ''); // disable by default because it's managed by HeaderBag (if used)
101113
ini_set('session.use_cookies', 1);
@@ -109,6 +121,7 @@ public function __construct(array $options = array(), $handler = null, MetadataB
109121
$this->setMetadataBag($metaBag);
110122
$this->setOptions($options);
111123
$this->setSaveHandler($handler);
124+
$this->mode = $mode;
112125
}
113126

114127
/**
@@ -253,13 +266,13 @@ public function registerBag(SessionBagInterface $bag)
253266
public function getBag($name)
254267
{
255268
if (!isset($this->bags[$name])) {
256-
throw new \InvalidArgumentException(sprintf('The SessionBagInterface %s is not registered.', $name));
269+
throw new \InvalidArgumentException(sprintf('The SessionBagInterface %s is not registered', $name));
257270
}
258271

259-
if ($this->saveHandler->isActive() && !$this->started) {
260-
$this->loadSession();
261-
} elseif (!$this->started) {
272+
if (!$this->started && self::START_ON_DEMAND === $this->mode) {
262273
$this->start();
274+
} elseif (!$this->started && self::NO_START_ON_DEMAND_STRICT === $this->mode) {
275+
throw new \RuntimeException('Cannot access session bags because the session has been started');
263276
}
264277

265278
return $this->bags[$name];

Session/Storage/SessionStorageInterface.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,22 @@
2424
*/
2525
interface SessionStorageInterface
2626
{
27+
/**
28+
* Do not start session on demand and throw exception if attempt
29+
* is make to read or write bag data.
30+
*/
31+
const NO_START_ON_DEMAND_STRICT = 0;
32+
33+
/**
34+
* Start the session on demand when accessing bag data.
35+
*/
36+
const START_ON_DEMAND = 1;
37+
38+
/**
39+
* Do not start session on demand but allow access to session bags.
40+
*/
41+
const NO_START_ON_DEMAND_LAX = 2;
42+
2743
/**
2844
* Starts the session.
2945
*

Tests/Session/Storage/MockArraySessionStorageTest.php

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,38 @@ public function testGetId()
9797
}
9898

9999
/**
100-
* @expectedException RuntimeException
100+
* @expectedException \RuntimeException
101101
*/
102102
public function testUnstartedSave()
103103
{
104104
$this->storage->save();
105105
}
106+
107+
/**
108+
* @expectedException \RuntimeException
109+
*/
110+
public function testtStartOnDemandException()
111+
{
112+
$storage = new MockArraySessionStorage('MOCKSESSID', null, MockArraySessionStorage::NO_START_ON_DEMAND_STRICT);
113+
$storage->registerBag(new AttributeBag);
114+
$this->assertFalse($storage->isStarted());
115+
$storage->getBag('attributes');
116+
}
117+
118+
public function testStartOnDemandDefaults()
119+
{
120+
$storage = new MockArraySessionStorage('MOCKSESSID');
121+
$storage->registerBag(new AttributeBag);
122+
$storage->getBag('attributes');
123+
$this->assertTrue($storage->isStarted());
124+
}
125+
126+
public function testNoStartOnDemandLax()
127+
{
128+
$storage = new MockArraySessionStorage('MOCKSESSID', null, MockArraySessionStorage::NO_START_ON_DEMAND_LAX);
129+
$storage->registerBag($bag = new AttributeBag);
130+
$bag->set('foo', 'bar');
131+
$storage->getBag('attributes');
132+
$this->assertEquals(array('foo' => 'bar'), $storage->getBag('attributes')->all());
133+
}
106134
}

Tests/Session/Storage/MockFileSessionStorageTest.php

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class MockFileSessionStorageTest extends \PHPUnit_Framework_TestCase
2828
private $sessionDir;
2929

3030
/**
31-
* @var FileMockSessionStorage
31+
* @var MockFileSessionStorage
3232
*/
3333
protected $storage;
3434

@@ -107,7 +107,7 @@ public function testMultipleInstances()
107107
}
108108

109109
/**
110-
* @expectedException RuntimeException
110+
* @expectedException \RuntimeException
111111
*/
112112
public function testSaveWithoutStart()
113113
{
@@ -123,4 +123,32 @@ private function getStorage()
123123

124124
return $storage;
125125
}
126+
127+
/**
128+
* @expectedException \RuntimeException
129+
*/
130+
public function testtStartOnDemandException()
131+
{
132+
$storage = new MockFileSessionStorage($this->sessionDir, 'MOCKSESSID', null, MockFileSessionStorage::NO_START_ON_DEMAND_STRICT);
133+
$storage->registerBag(new AttributeBag);
134+
$this->assertFalse($storage->isStarted());
135+
$storage->getBag('attributes');
136+
}
137+
138+
public function testStartOnDemandDefaults()
139+
{
140+
$storage = new MockFileSessionStorage($this->sessionDir, 'MOCKSESSID');
141+
$storage->registerBag(new AttributeBag);
142+
$storage->getBag('attributes');
143+
$this->assertTrue($storage->isStarted());
144+
}
145+
146+
public function testNoStartOnDemandLax()
147+
{
148+
$storage = new MockFileSessionStorage($this->sessionDir, 'MOCKSESSID', null, MockFileSessionStorage::NO_START_ON_DEMAND_LAX);
149+
$storage->registerBag($bag = new AttributeBag);
150+
$bag->set('foo', 'bar');
151+
$storage->getBag('attributes');
152+
$this->assertEquals(array('foo' => 'bar'), $storage->getBag('attributes')->all());
153+
}
126154
}

Tests/Session/Storage/NativeSessionStorageTest.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Symfony\Component\HttpFoundation\Session\Storage\Handler\NullSessionHandler;
1717
use Symfony\Component\HttpFoundation\Session\Flash\FlashBag;
1818
use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag;
19+
use Symfony\Component\HttpFoundation\Tests\Session\Storage\Handler\NativeSessionHandlerTest;
1920

2021
/**
2122
* Test class for NativeSessionStorage.
@@ -154,4 +155,32 @@ public function testSetSaveHandlerPHP54()
154155
$storage->setSaveHandler(new NullSessionHandler());
155156
$this->assertInstanceOf('Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy', $storage->getSaveHandler());
156157
}
158+
159+
/**
160+
* @expectedException \RuntimeException
161+
*/
162+
public function testtStartOnDemandException()
163+
{
164+
$storage = new NativeSessionStorage(array(), null, null, NativeSessionStorage::NO_START_ON_DEMAND_STRICT);
165+
$storage->registerBag(new AttributeBag);
166+
$this->assertFalse($storage->isStarted());
167+
$storage->getBag('attributes');
168+
}
169+
170+
public function testStartOnDemandDefaults()
171+
{
172+
$storage = new NativeSessionStorage();
173+
$storage->registerBag(new AttributeBag);
174+
$storage->getBag('attributes');
175+
$this->assertTrue($storage->isStarted());
176+
}
177+
178+
public function testNoStartOnDemandLax()
179+
{
180+
$storage = new NativeSessionStorage(array(), null, null, NativeSessionStorage::NO_START_ON_DEMAND_LAX);
181+
$storage->registerBag($bag = new AttributeBag);
182+
$bag->set('foo', 'bar');
183+
$storage->getBag('attributes');
184+
$this->assertEquals(array('foo' => 'bar'), $storage->getBag('attributes')->all());
185+
}
157186
}

0 commit comments

Comments
 (0)