1: <?php
2:
3: namespace Mapbender\DrupalIntegrationBundle\Session;
4:
5: use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
6: use Symfony\Component\HttpFoundation\Session\Storage\MetadataBag;
7: use Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy;
8: use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy;
9: use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy;
10: use Symfony\Component\HttpFoundation\Session\Storage\SessionStorageInterface;
11:
12: class DrupalSessionStorage implements SessionStorageInterface
13: {
14: 15: 16: 17: 18:
19: protected $bags;
20:
21: 22: 23:
24: protected $started = false;
25:
26: 27: 28:
29: protected $closed = false;
30:
31: 32: 33:
34: protected $saveHandler;
35:
36: 37: 38:
39: protected $metadataBag;
40:
41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84:
85: public function __construct(array $options = array(), $handler = null, MetadataBag $metaBag = null)
86: {
87: ini_set('session.cache_limiter', '');
88: ini_set('session.use_cookies', 1);
89:
90: if (version_compare(phpversion(), '5.4.0', '>=')) {
91: session_register_shutdown();
92: } else {
93: register_shutdown_function('session_write_close');
94: }
95:
96: $this->setMetadataBag($metaBag);
97: $this->setOptions($options);
98: $this->setSaveHandler($handler);
99: }
100:
101: 102: 103: 104: 105:
106: public function getSaveHandler()
107: {
108: return $this->saveHandler;
109: }
110:
111: 112: 113:
114: public function start()
115: {
116: $this->loadSession();
117: if (!$this->saveHandler->isWrapper() && !$this->saveHandler->isSessionHandlerInterface()) {
118: $this->saveHandler->setActive(false);
119: }
120:
121: $this->started = true;
122:
123: return true;
124: }
125:
126: 127: 128:
129: public function getId()
130: {
131: if (!$this->started) {
132: return '';
133: }
134:
135: return $this->saveHandler->getId();
136: }
137:
138: 139: 140:
141: public function setId($id)
142: {
143: $this->saveHandler->setId($id);
144: }
145:
146: 147: 148:
149: public function getName()
150: {
151: return $this->saveHandler->getName();
152: }
153:
154: 155: 156:
157: public function setName($name)
158: {
159: $this->saveHandler->setName($name);
160: }
161:
162: 163: 164:
165: public function regenerate($destroy = false, $lifetime = null)
166: {
167: if (null !== $lifetime) {
168: ini_set('session.cookie_lifetime', $lifetime);
169: }
170:
171: if ($destroy) {
172: $this->metadataBag->stampNew();
173: }
174:
175: return session_regenerate_id($destroy);
176: }
177:
178: 179: 180:
181: public function save()
182: {
183: session_write_close();
184:
185: if (!$this->saveHandler->isWrapper() && !$this->getSaveHandler()->isSessionHandlerInterface()) {
186: $this->saveHandler->setActive(false);
187: }
188:
189: $this->closed = true;
190: }
191:
192: 193: 194:
195: public function clear()
196: {
197:
198: foreach ($this->bags as $bag) {
199: $bag->clear();
200: }
201:
202:
203: $_SESSION = array();
204:
205:
206: $this->loadSession();
207: }
208:
209: 210: 211:
212: public function registerBag(SessionBagInterface $bag)
213: {
214: $this->bags[$bag->getName()] = $bag;
215: }
216:
217: 218: 219:
220: public function getBag($name)
221: {
222: if (!isset($this->bags[$name])) {
223: throw new \InvalidArgumentException(sprintf('The SessionBagInterface %s is not registered.', $name));
224: }
225:
226: if ($this->saveHandler->isActive() && !$this->started) {
227: $this->loadSession();
228: } elseif (!$this->started) {
229: $this->start();
230: }
231:
232: return $this->bags[$name];
233: }
234:
235: 236: 237: 238: 239:
240: public function setMetadataBag(MetadataBag $metaBag = null)
241: {
242: if (null === $metaBag) {
243: $metaBag = new MetadataBag();
244: }
245:
246: $this->metadataBag = $metaBag;
247: }
248:
249: 250: 251: 252: 253:
254: public function getMetadataBag()
255: {
256: return $this->metadataBag;
257: }
258:
259: 260: 261:
262: public function isStarted()
263: {
264: return $this->started;
265: }
266:
267: 268: 269: 270: 271: 272: 273: 274: 275: 276:
277: public function setOptions(array $options)
278: {
279: $validOptions = array_flip(array(
280: 'cache_limiter', 'cookie_domain', 'cookie_httponly',
281: 'cookie_lifetime', 'cookie_path', 'cookie_secure',
282: 'entropy_file', 'entropy_length', 'gc_divisor',
283: 'gc_maxlifetime', 'gc_probability', 'hash_bits_per_character',
284: 'hash_function', 'name', 'referer_check',
285: 'serialize_handler', 'use_cookies',
286: 'use_only_cookies', 'use_trans_sid', 'upload_progress.enabled',
287: 'upload_progress.cleanup', 'upload_progress.prefix', 'upload_progress.name',
288: 'upload_progress.freq', 'upload_progress.min-freq', 'url_rewriter.tags',
289: ));
290:
291: foreach ($options as $key => $value) {
292: if (isset($validOptions[$key])) {
293: ini_set('session.'.$key, $value);
294: }
295: }
296: }
297:
298: 299: 300: 301: 302: 303: 304: 305: 306: 307: 308: 309: 310: 311: 312:
313: public function setSaveHandler($saveHandler = null)
314: {
315:
316: if (!$saveHandler instanceof AbstractProxy && $saveHandler instanceof \SessionHandlerInterface) {
317: $saveHandler = new SessionHandlerProxy($saveHandler);
318: } elseif (!$saveHandler instanceof AbstractProxy) {
319: $saveHandler = new NativeProxy();
320: }
321:
322: $this->saveHandler = $saveHandler;
323:
324: if ($this->saveHandler instanceof \SessionHandlerInterface) {
325: if (version_compare(phpversion(), '5.4.0', '>=')) {
326: session_set_save_handler($this->saveHandler, false);
327: } else {
328: session_set_save_handler(
329: array($this->saveHandler, 'open'),
330: array($this->saveHandler, 'close'),
331: array($this->saveHandler, 'read'),
332: array($this->saveHandler, 'write'),
333: array($this->saveHandler, 'destroy'),
334: array($this->saveHandler, 'gc')
335: );
336: }
337: }
338: }
339:
340: 341: 342: 343: 344: 345: 346: 347: 348: 349:
350: protected function loadSession(array &$session = null)
351: {
352: if (null === $session) {
353: $session = &$_SESSION;
354: }
355:
356:
357:
358:
359: $bags = array_merge($this->bags, array($this->metadataBag));
360:
361: foreach ($bags as $bag) {
362: $key = $bag->getStorageKey();
363: $session[$key] = isset($session[$key]) ? $session[$key] : array();
364: $bag->initialize($session[$key]);
365: }
366:
367: $this->started = true;
368: $this->closed = false;
369: }
370: }
371: