Mercurial > hg > isophonics-drupal-site
comparison vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children | 7a779792577d |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
1 <?php | |
2 | |
3 /* | |
4 * This file is part of the Symfony package. | |
5 * | |
6 * (c) Fabien Potencier <fabien@symfony.com> | |
7 * | |
8 * For the full copyright and license information, please view the LICENSE | |
9 * file that was distributed with this source code. | |
10 */ | |
11 | |
12 namespace Symfony\Component\HttpFoundation\Session\Storage; | |
13 | |
14 use Symfony\Component\HttpFoundation\Session\SessionBagInterface; | |
15 use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeSessionHandler; | |
16 use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy; | |
17 use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy; | |
18 | |
19 /** | |
20 * This provides a base class for session attribute storage. | |
21 * | |
22 * @author Drak <drak@zikula.org> | |
23 */ | |
24 class NativeSessionStorage implements SessionStorageInterface | |
25 { | |
26 /** | |
27 * Array of SessionBagInterface. | |
28 * | |
29 * @var SessionBagInterface[] | |
30 */ | |
31 protected $bags; | |
32 | |
33 /** | |
34 * @var bool | |
35 */ | |
36 protected $started = false; | |
37 | |
38 /** | |
39 * @var bool | |
40 */ | |
41 protected $closed = false; | |
42 | |
43 /** | |
44 * @var AbstractProxy | |
45 */ | |
46 protected $saveHandler; | |
47 | |
48 /** | |
49 * @var MetadataBag | |
50 */ | |
51 protected $metadataBag; | |
52 | |
53 /** | |
54 * Constructor. | |
55 * | |
56 * Depending on how you want the storage driver to behave you probably | |
57 * want to override this constructor entirely. | |
58 * | |
59 * List of options for $options array with their defaults. | |
60 * | |
61 * @see http://php.net/session.configuration for options | |
62 * but we omit 'session.' from the beginning of the keys for convenience. | |
63 * | |
64 * ("auto_start", is not supported as it tells PHP to start a session before | |
65 * PHP starts to execute user-land code. Setting during runtime has no effect). | |
66 * | |
67 * cache_limiter, "" (use "0" to prevent headers from being sent entirely). | |
68 * cookie_domain, "" | |
69 * cookie_httponly, "" | |
70 * cookie_lifetime, "0" | |
71 * cookie_path, "/" | |
72 * cookie_secure, "" | |
73 * entropy_file, "" | |
74 * entropy_length, "0" | |
75 * gc_divisor, "100" | |
76 * gc_maxlifetime, "1440" | |
77 * gc_probability, "1" | |
78 * hash_bits_per_character, "4" | |
79 * hash_function, "0" | |
80 * name, "PHPSESSID" | |
81 * referer_check, "" | |
82 * serialize_handler, "php" | |
83 * use_strict_mode, "0" | |
84 * use_cookies, "1" | |
85 * use_only_cookies, "1" | |
86 * use_trans_sid, "0" | |
87 * upload_progress.enabled, "1" | |
88 * upload_progress.cleanup, "1" | |
89 * upload_progress.prefix, "upload_progress_" | |
90 * upload_progress.name, "PHP_SESSION_UPLOAD_PROGRESS" | |
91 * upload_progress.freq, "1%" | |
92 * upload_progress.min-freq, "1" | |
93 * url_rewriter.tags, "a=href,area=href,frame=src,form=,fieldset=" | |
94 * | |
95 * @param array $options Session configuration options | |
96 * @param AbstractProxy|NativeSessionHandler|\SessionHandlerInterface|null $handler | |
97 * @param MetadataBag $metaBag MetadataBag | |
98 */ | |
99 public function __construct(array $options = array(), $handler = null, MetadataBag $metaBag = null) | |
100 { | |
101 session_cache_limiter(''); // disable by default because it's managed by HeaderBag (if used) | |
102 ini_set('session.use_cookies', 1); | |
103 | |
104 session_register_shutdown(); | |
105 | |
106 $this->setMetadataBag($metaBag); | |
107 $this->setOptions($options); | |
108 $this->setSaveHandler($handler); | |
109 } | |
110 | |
111 /** | |
112 * Gets the save handler instance. | |
113 * | |
114 * @return AbstractProxy | |
115 */ | |
116 public function getSaveHandler() | |
117 { | |
118 return $this->saveHandler; | |
119 } | |
120 | |
121 /** | |
122 * {@inheritdoc} | |
123 */ | |
124 public function start() | |
125 { | |
126 if ($this->started) { | |
127 return true; | |
128 } | |
129 | |
130 if (\PHP_SESSION_ACTIVE === session_status()) { | |
131 throw new \RuntimeException('Failed to start the session: already started by PHP.'); | |
132 } | |
133 | |
134 if (ini_get('session.use_cookies') && headers_sent($file, $line)) { | |
135 throw new \RuntimeException(sprintf('Failed to start the session because headers have already been sent by "%s" at line %d.', $file, $line)); | |
136 } | |
137 | |
138 // ok to try and start the session | |
139 if (!session_start()) { | |
140 throw new \RuntimeException('Failed to start the session'); | |
141 } | |
142 | |
143 $this->loadSession(); | |
144 | |
145 return true; | |
146 } | |
147 | |
148 /** | |
149 * {@inheritdoc} | |
150 */ | |
151 public function getId() | |
152 { | |
153 return $this->saveHandler->getId(); | |
154 } | |
155 | |
156 /** | |
157 * {@inheritdoc} | |
158 */ | |
159 public function setId($id) | |
160 { | |
161 $this->saveHandler->setId($id); | |
162 } | |
163 | |
164 /** | |
165 * {@inheritdoc} | |
166 */ | |
167 public function getName() | |
168 { | |
169 return $this->saveHandler->getName(); | |
170 } | |
171 | |
172 /** | |
173 * {@inheritdoc} | |
174 */ | |
175 public function setName($name) | |
176 { | |
177 $this->saveHandler->setName($name); | |
178 } | |
179 | |
180 /** | |
181 * {@inheritdoc} | |
182 */ | |
183 public function regenerate($destroy = false, $lifetime = null) | |
184 { | |
185 // Cannot regenerate the session ID for non-active sessions. | |
186 if (\PHP_SESSION_ACTIVE !== session_status()) { | |
187 return false; | |
188 } | |
189 | |
190 if (null !== $lifetime) { | |
191 ini_set('session.cookie_lifetime', $lifetime); | |
192 } | |
193 | |
194 if ($destroy) { | |
195 $this->metadataBag->stampNew(); | |
196 } | |
197 | |
198 $isRegenerated = session_regenerate_id($destroy); | |
199 | |
200 // The reference to $_SESSION in session bags is lost in PHP7 and we need to re-create it. | |
201 // @see https://bugs.php.net/bug.php?id=70013 | |
202 $this->loadSession(); | |
203 | |
204 return $isRegenerated; | |
205 } | |
206 | |
207 /** | |
208 * {@inheritdoc} | |
209 */ | |
210 public function save() | |
211 { | |
212 session_write_close(); | |
213 | |
214 $this->closed = true; | |
215 $this->started = false; | |
216 } | |
217 | |
218 /** | |
219 * {@inheritdoc} | |
220 */ | |
221 public function clear() | |
222 { | |
223 // clear out the bags | |
224 foreach ($this->bags as $bag) { | |
225 $bag->clear(); | |
226 } | |
227 | |
228 // clear out the session | |
229 $_SESSION = array(); | |
230 | |
231 // reconnect the bags to the session | |
232 $this->loadSession(); | |
233 } | |
234 | |
235 /** | |
236 * {@inheritdoc} | |
237 */ | |
238 public function registerBag(SessionBagInterface $bag) | |
239 { | |
240 if ($this->started) { | |
241 throw new \LogicException('Cannot register a bag when the session is already started.'); | |
242 } | |
243 | |
244 $this->bags[$bag->getName()] = $bag; | |
245 } | |
246 | |
247 /** | |
248 * {@inheritdoc} | |
249 */ | |
250 public function getBag($name) | |
251 { | |
252 if (!isset($this->bags[$name])) { | |
253 throw new \InvalidArgumentException(sprintf('The SessionBagInterface %s is not registered.', $name)); | |
254 } | |
255 | |
256 if ($this->saveHandler->isActive() && !$this->started) { | |
257 $this->loadSession(); | |
258 } elseif (!$this->started) { | |
259 $this->start(); | |
260 } | |
261 | |
262 return $this->bags[$name]; | |
263 } | |
264 | |
265 /** | |
266 * Sets the MetadataBag. | |
267 * | |
268 * @param MetadataBag $metaBag | |
269 */ | |
270 public function setMetadataBag(MetadataBag $metaBag = null) | |
271 { | |
272 if (null === $metaBag) { | |
273 $metaBag = new MetadataBag(); | |
274 } | |
275 | |
276 $this->metadataBag = $metaBag; | |
277 } | |
278 | |
279 /** | |
280 * Gets the MetadataBag. | |
281 * | |
282 * @return MetadataBag | |
283 */ | |
284 public function getMetadataBag() | |
285 { | |
286 return $this->metadataBag; | |
287 } | |
288 | |
289 /** | |
290 * {@inheritdoc} | |
291 */ | |
292 public function isStarted() | |
293 { | |
294 return $this->started; | |
295 } | |
296 | |
297 /** | |
298 * Sets session.* ini variables. | |
299 * | |
300 * For convenience we omit 'session.' from the beginning of the keys. | |
301 * Explicitly ignores other ini keys. | |
302 * | |
303 * @param array $options Session ini directives array(key => value) | |
304 * | |
305 * @see http://php.net/session.configuration | |
306 */ | |
307 public function setOptions(array $options) | |
308 { | |
309 $validOptions = array_flip(array( | |
310 'cache_limiter', 'cookie_domain', 'cookie_httponly', | |
311 'cookie_lifetime', 'cookie_path', 'cookie_secure', | |
312 'entropy_file', 'entropy_length', 'gc_divisor', | |
313 'gc_maxlifetime', 'gc_probability', 'hash_bits_per_character', | |
314 'hash_function', 'name', 'referer_check', | |
315 'serialize_handler', 'use_strict_mode', 'use_cookies', | |
316 'use_only_cookies', 'use_trans_sid', 'upload_progress.enabled', | |
317 'upload_progress.cleanup', 'upload_progress.prefix', 'upload_progress.name', | |
318 'upload_progress.freq', 'upload_progress.min-freq', 'url_rewriter.tags', | |
319 )); | |
320 | |
321 foreach ($options as $key => $value) { | |
322 if (isset($validOptions[$key])) { | |
323 ini_set('session.'.$key, $value); | |
324 } | |
325 } | |
326 } | |
327 | |
328 /** | |
329 * Registers session save handler as a PHP session handler. | |
330 * | |
331 * To use internal PHP session save handlers, override this method using ini_set with | |
332 * session.save_handler and session.save_path e.g. | |
333 * | |
334 * ini_set('session.save_handler', 'files'); | |
335 * ini_set('session.save_path', '/tmp'); | |
336 * | |
337 * or pass in a NativeSessionHandler instance which configures session.save_handler in the | |
338 * constructor, for a template see NativeFileSessionHandler or use handlers in | |
339 * composer package drak/native-session | |
340 * | |
341 * @see http://php.net/session-set-save-handler | |
342 * @see http://php.net/sessionhandlerinterface | |
343 * @see http://php.net/sessionhandler | |
344 * @see http://github.com/drak/NativeSession | |
345 * | |
346 * @param AbstractProxy|NativeSessionHandler|\SessionHandlerInterface|null $saveHandler | |
347 * | |
348 * @throws \InvalidArgumentException | |
349 */ | |
350 public function setSaveHandler($saveHandler = null) | |
351 { | |
352 if (!$saveHandler instanceof AbstractProxy && | |
353 !$saveHandler instanceof NativeSessionHandler && | |
354 !$saveHandler instanceof \SessionHandlerInterface && | |
355 null !== $saveHandler) { | |
356 throw new \InvalidArgumentException('Must be instance of AbstractProxy or NativeSessionHandler; implement \SessionHandlerInterface; or be null.'); | |
357 } | |
358 | |
359 // Wrap $saveHandler in proxy and prevent double wrapping of proxy | |
360 if (!$saveHandler instanceof AbstractProxy && $saveHandler instanceof \SessionHandlerInterface) { | |
361 $saveHandler = new SessionHandlerProxy($saveHandler); | |
362 } elseif (!$saveHandler instanceof AbstractProxy) { | |
363 $saveHandler = new SessionHandlerProxy(new \SessionHandler()); | |
364 } | |
365 $this->saveHandler = $saveHandler; | |
366 | |
367 if ($this->saveHandler instanceof \SessionHandlerInterface) { | |
368 session_set_save_handler($this->saveHandler, false); | |
369 } | |
370 } | |
371 | |
372 /** | |
373 * Load the session with attributes. | |
374 * | |
375 * After starting the session, PHP retrieves the session from whatever handlers | |
376 * are set to (either PHP's internal, or a custom save handler set with session_set_save_handler()). | |
377 * PHP takes the return value from the read() handler, unserializes it | |
378 * and populates $_SESSION with the result automatically. | |
379 * | |
380 * @param array|null $session | |
381 */ | |
382 protected function loadSession(array &$session = null) | |
383 { | |
384 if (null === $session) { | |
385 $session = &$_SESSION; | |
386 } | |
387 | |
388 $bags = array_merge($this->bags, array($this->metadataBag)); | |
389 | |
390 foreach ($bags as $bag) { | |
391 $key = $bag->getStorageKey(); | |
392 $session[$key] = isset($session[$key]) ? $session[$key] : array(); | |
393 $bag->initialize($session[$key]); | |
394 } | |
395 | |
396 $this->started = true; | |
397 $this->closed = false; | |
398 } | |
399 } |