PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 1.3.1
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v1.3.1
5.11.1 5.11.0 5.10.2 5.10.1 trunk 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.3.2 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.1.1 4.1.2 4.1.3 4.10.0 4.11.0 4.12.0 4.13.0 4.13.2 4.13.3 4.13.4 4.13.5 4.14.0 4.14.1 4.14.2 4.15.0 4.15.1 4.15.2 4.15.3 4.2.0 4.3.0 4.3.1 4.4.1 4.4.2 4.5.0 4.6.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.10.0 5.2.0 5.2.1 5.2.2 5.3.0 5.3.1 5.3.2 5.3.3 5.6.0 5.6.1 5.7.0 5.7.1 5.8.0 5.8.1 5.8.2
matomo / app / libs / Zend / Session.php
matomo / app / libs / Zend Last commit date
Db 6 years ago Mail 6 years ago Mime 6 years ago Session 6 years ago Validate 6 years ago Config.php 6 years ago Db.php 6 years ago Exception.php 6 years ago LICENSE.txt 6 years ago Mail.php 6 years ago Mime.php 6 years ago Registry.php 6 years ago Session.php 6 years ago Validate.php 6 years ago Version.php 6 years ago
Session.php
915 lines
1 <?php
2
3 /**
4 * Zend Framework
5 *
6 * LICENSE
7 *
8 * This source file is subject to the new BSD license that is bundled
9 * with this package in the file LICENSE.txt.
10 * It is also available through the world-wide-web at this URL:
11 * http://framework.zend.com/license/new-bsd
12 * If you did not receive a copy of the license and are unable to
13 * obtain it through the world-wide-web, please send an email
14 * to license@zend.com so we can send you a copy immediately.
15 *
16 * @category Zend
17 * @package Zend_Session
18 * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
19 * @license http://framework.zend.com/license/new-bsd New BSD License
20 * @version $Id: Session.php 24196 2011-07-05 15:58:11Z matthew $
21 * @since Preview Release 0.2
22 */
23
24
25 /**
26 * @see Zend_Session_Abstract
27 */
28 // require_once 'Zend/Session/Abstract.php';
29
30 /**
31 * @see Zend_Session_Namespace
32 */
33 // require_once 'Zend/Session/Namespace.php';
34
35 /**
36 * @see Zend_Session_SaveHandler_Interface
37 */
38 // require_once 'Zend/Session/SaveHandler/Interface.php';
39
40
41 /**
42 * Zend_Session
43 *
44 * @category Zend
45 * @package Zend_Session
46 * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
47 * @license http://framework.zend.com/license/new-bsd New BSD License
48 */
49 class Zend_Session extends Zend_Session_Abstract
50 {
51 /**
52 * Whether or not Zend_Session is being used with unit tests
53 *
54 * @internal
55 * @var bool
56 */
57 public static $_unitTestEnabled = false;
58
59 /**
60 * $_throwStartupException
61 *
62 * @var bool|bitset This could also be a combiniation of error codes to catch
63 */
64 protected static $_throwStartupExceptions = true;
65
66 /**
67 * Check whether or not the session was started
68 *
69 * @var bool
70 */
71 private static $_sessionStarted = false;
72
73 /**
74 * Whether or not the session id has been regenerated this request.
75 *
76 * Id regeneration state
77 * <0 - regenerate requested when session is started
78 * 0 - do nothing
79 * >0 - already called session_regenerate_id()
80 *
81 * @var int
82 */
83 private static $_regenerateIdState = 0;
84
85 /**
86 * Private list of php's ini values for ext/session
87 * null values will default to the php.ini value, otherwise
88 * the value below will overwrite the default ini value, unless
89 * the user has set an option explicity with setOptions()
90 *
91 * @var array
92 */
93 private static $_defaultOptions = array(
94 'save_path' => null,
95 'name' => null, /* this should be set to a unique value for each application */
96 'save_handler' => null,
97 //'auto_start' => null, /* intentionally excluded (see manual) */
98 'gc_probability' => null,
99 'gc_divisor' => null,
100 'gc_maxlifetime' => null,
101 'serialize_handler' => null,
102 'cookie_lifetime' => null,
103 'cookie_path' => null,
104 'cookie_domain' => null,
105 'cookie_secure' => null,
106 'cookie_httponly' => null,
107 'use_cookies' => null,
108 'use_only_cookies' => 'on',
109 'referer_check' => null,
110 'entropy_file' => null,
111 'entropy_length' => null,
112 'cache_limiter' => null,
113 'cache_expire' => null,
114 'use_trans_sid' => null,
115 'bug_compat_42' => null,
116 'bug_compat_warn' => null,
117 'hash_function' => null,
118 'hash_bits_per_character' => null
119 );
120
121 /**
122 * List of options pertaining to Zend_Session that can be set by developers
123 * using Zend_Session::setOptions(). This list intentionally duplicates
124 * the individual declaration of static "class" variables by the same names.
125 *
126 * @var array
127 */
128 private static $_localOptions = array(
129 'strict' => '_strict',
130 'remember_me_seconds' => '_rememberMeSeconds',
131 'throw_startup_exceptions' => '_throwStartupExceptions'
132 );
133
134 /**
135 * Whether or not write close has been performed.
136 *
137 * @var bool
138 */
139 private static $_writeClosed = false;
140
141 /**
142 * Whether or not session id cookie has been deleted
143 *
144 * @var bool
145 */
146 private static $_sessionCookieDeleted = false;
147
148 /**
149 * Whether or not session has been destroyed via session_destroy()
150 *
151 * @var bool
152 */
153 private static $_destroyed = false;
154
155 /**
156 * Whether or not session must be initiated before usage
157 *
158 * @var bool
159 */
160 private static $_strict = false;
161
162 /**
163 * Default number of seconds the session will be remembered for when asked to be remembered
164 *
165 * @var int
166 */
167 private static $_rememberMeSeconds = 1209600; // 2 weeks
168
169 /**
170 * Whether the default options listed in Zend_Session::$_localOptions have been set
171 *
172 * @var bool
173 */
174 private static $_defaultOptionsSet = false;
175
176 /**
177 * A reference to the set session save handler
178 *
179 * @var Zend_Session_SaveHandler_Interface
180 */
181 private static $_saveHandler = null;
182
183
184 /**
185 * Constructor overriding - make sure that a developer cannot instantiate
186 */
187 protected function __construct()
188 {
189 }
190
191
192 /**
193 * setOptions - set both the class specified
194 *
195 * @param array $userOptions - pass-by-keyword style array of <option name, option value> pairs
196 * @throws Zend_Session_Exception
197 * @return void
198 */
199 public static function setOptions(array $userOptions = array())
200 {
201 // set default options on first run only (before applying user settings)
202 if (!self::$_defaultOptionsSet) {
203 foreach (self::$_defaultOptions as $defaultOptionName => $defaultOptionValue) {
204 if (isset(self::$_defaultOptions[$defaultOptionName])) {
205 @ini_set("session.$defaultOptionName", $defaultOptionValue);
206 }
207 }
208
209 self::$_defaultOptionsSet = true;
210 }
211
212 // set the options the user has requested to set
213 foreach ($userOptions as $userOptionName => $userOptionValue) {
214
215 $userOptionName = strtolower($userOptionName);
216
217 // set the ini based values
218 if (array_key_exists($userOptionName, self::$_defaultOptions)) {
219 @ini_set("session.$userOptionName", $userOptionValue);
220 }
221 elseif (isset(self::$_localOptions[$userOptionName])) {
222 self::${self::$_localOptions[$userOptionName]} = $userOptionValue;
223 }
224 else {
225 /** @see Zend_Session_Exception */
226 // require_once 'Zend/Session/Exception.php';
227 throw new Zend_Session_Exception("Unknown option: $userOptionName = $userOptionValue");
228 }
229 }
230 }
231
232 /**
233 * getOptions()
234 *
235 * @param string $optionName OPTIONAL
236 * @return array|string
237 */
238 public static function getOptions($optionName = null)
239 {
240 $options = array();
241 foreach (ini_get_all('session') as $sysOptionName => $sysOptionValues) {
242 $options[substr($sysOptionName, 8)] = $sysOptionValues['local_value'];
243 }
244 foreach (self::$_localOptions as $localOptionName => $localOptionMemberName) {
245 $options[$localOptionName] = self::${$localOptionMemberName};
246 }
247
248 if ($optionName) {
249 if (array_key_exists($optionName, $options)) {
250 return $options[$optionName];
251 }
252 return null;
253 }
254
255 return $options;
256 }
257
258 /**
259 * setSaveHandler() - Session Save Handler assignment
260 *
261 * @param Zend_Session_SaveHandler_Interface $interface
262 * @return void
263 */
264 public static function setSaveHandler(Zend_Session_SaveHandler_Interface $saveHandler)
265 {
266 self::$_saveHandler = $saveHandler;
267
268 if (self::$_unitTestEnabled) {
269 return;
270 }
271
272 session_set_save_handler(
273 array(&$saveHandler, 'open'),
274 array(&$saveHandler, 'close'),
275 array(&$saveHandler, 'read'),
276 array(&$saveHandler, 'write'),
277 array(&$saveHandler, 'destroy'),
278 array(&$saveHandler, 'gc')
279 );
280 }
281
282
283 /**
284 * getSaveHandler() - Get the session Save Handler
285 *
286 * @return Zend_Session_SaveHandler_Interface
287 */
288 public static function getSaveHandler()
289 {
290 return self::$_saveHandler;
291 }
292
293
294 /**
295 * regenerateId() - Regenerate the session id. Best practice is to call this after
296 * session is started. If called prior to session starting, session id will be regenerated
297 * at start time.
298 *
299 * @throws Zend_Session_Exception
300 * @return void
301 */
302 public static function regenerateId()
303 {
304 if (!self::$_unitTestEnabled && headers_sent($filename, $linenum)) {
305 /** @see Zend_Session_Exception */
306 // require_once 'Zend/Session/Exception.php';
307 throw new Zend_Session_Exception("You must call " . __CLASS__ . '::' . __FUNCTION__ .
308 "() before any output has been sent to the browser; output started in {$filename}/{$linenum}");
309 }
310
311 if ( !self::$_sessionStarted ) {
312 self::$_regenerateIdState = -1;
313 } else {
314 if (!self::$_unitTestEnabled) {
315 session_regenerate_id(true);
316 self::rewriteSessionCookieWithSameSiteDirective();
317 }
318 self::$_regenerateIdState = 1;
319 }
320 }
321
322 /**
323 * Check if there is a Set-Cookie header present - if so, overwrite it with
324 * a similar header which also includes a SameSite directive. This workaround
325 * is needed because the SameSite property on the session cookie is not supported
326 * by PHP until 7.3.
327 */
328 private static function rewriteSessionCookieWithSameSiteDirective()
329 {
330 $headers = headers_list();
331 $cookieHeader = '';
332 foreach ($headers as $header) {
333 if (strpos($header, 'Set-Cookie: ' . \Piwik\Session::SESSION_NAME) === 0) {
334 $cookieHeader = $header;
335 break;
336 }
337 }
338
339 if (! $cookieHeader) {
340 return;
341 }
342
343 if (stripos($cookieHeader, 'SameSite') === false) {
344 $cookieHeader .= '; SameSite=' . \Piwik\Session::getSameSiteCookieValue();
345 header($cookieHeader);
346 }
347 }
348
349 /**
350 * rememberMe() - Write a persistent cookie that expires after a number of seconds in the future. If no number of
351 * seconds is specified, then this defaults to self::$_rememberMeSeconds. Due to clock errors on end users' systems,
352 * large values are recommended to avoid undesirable expiration of session cookies.
353 *
354 * @param int $seconds OPTIONAL specifies TTL for cookie in seconds from present time
355 * @return void
356 */
357 public static function rememberMe($seconds = null)
358 {
359 $seconds = (int) $seconds;
360 $seconds = ($seconds > 0) ? $seconds : self::$_rememberMeSeconds;
361
362 self::rememberUntil($seconds);
363 }
364
365
366 /**
367 * forgetMe() - Write a volatile session cookie, removing any persistent cookie that may have existed. The session
368 * would end upon, for example, termination of a web browser program.
369 *
370 * @return void
371 */
372 public static function forgetMe()
373 {
374 self::rememberUntil(0);
375 }
376
377
378 /**
379 * rememberUntil() - This method does the work of changing the state of the session cookie and making
380 * sure that it gets resent to the browser via regenerateId()
381 *
382 * @param int $seconds
383 * @return void
384 */
385 public static function rememberUntil($seconds = 0)
386 {
387 if (self::$_unitTestEnabled) {
388 self::regenerateId();
389 return;
390 }
391
392 $cookieParams = session_get_cookie_params();
393
394 session_set_cookie_params(
395 $seconds,
396 $cookieParams['path'],
397 $cookieParams['domain'],
398 $cookieParams['secure']
399 );
400
401 // normally "rememberMe()" represents a security context change, so should use new session id
402 self::regenerateId();
403 }
404
405
406 /**
407 * sessionExists() - whether or not a session exists for the current request
408 *
409 * @return bool
410 */
411 public static function sessionExists()
412 {
413 if (ini_get('session.use_cookies') == '1' && isset($_COOKIE[session_name()])) {
414 return true;
415 } elseif (!empty($_REQUEST[session_name()])) {
416 return true;
417 } elseif (self::$_unitTestEnabled) {
418 return true;
419 }
420
421 return false;
422 }
423
424
425 /**
426 * Whether or not session has been destroyed via session_destroy()
427 *
428 * @return bool
429 */
430 public static function isDestroyed()
431 {
432 return self::$_destroyed;
433 }
434
435
436 /**
437 * start() - Start the session.
438 *
439 * @param bool|array $options OPTIONAL Either user supplied options, or flag indicating if start initiated automatically
440 * @throws Zend_Session_Exception
441 * @return void
442 */
443 public static function start($options = false)
444 {
445 if (self::$_sessionStarted && self::$_destroyed) {
446 // require_once 'Zend/Session/Exception.php';
447 throw new Zend_Session_Exception('The session was explicitly destroyed during this request, attempting to re-start is not allowed.');
448 }
449
450 if (self::$_sessionStarted) {
451 return; // already started
452 }
453
454 if (session_status() === PHP_SESSION_ACTIVE) {
455 parent::$_readable = true;
456 parent::$_writable = true;
457 self::$_sessionStarted = true;
458 return;
459 }
460
461 // make sure our default options (at the least) have been set
462 if (!self::$_defaultOptionsSet) {
463 self::setOptions(is_array($options) ? $options : array());
464 }
465
466 // In strict mode, do not allow auto-starting Zend_Session, such as via "new Zend_Session_Namespace()"
467 if (self::$_strict && $options === true) {
468 /** @see Zend_Session_Exception */
469 // require_once 'Zend/Session/Exception.php';
470 throw new Zend_Session_Exception('You must explicitly start the session with Zend_Session::start() when session options are set to strict.');
471 }
472
473 $filename = $linenum = null;
474 if (!self::$_unitTestEnabled && headers_sent($filename, $linenum)) {
475 /** @see Zend_Session_Exception */
476 // require_once 'Zend/Session/Exception.php';
477 throw new Zend_Session_Exception("Session must be started before any output has been sent to the browser;"
478 . " output started in {$filename}/{$linenum}");
479 }
480
481 /**
482 * Hack to throw exceptions on start instead of php errors
483 * @see http://framework.zend.com/issues/browse/ZF-1325
484 */
485
486 $errorLevel = (is_int(self::$_throwStartupExceptions)) ? self::$_throwStartupExceptions : E_ALL;
487
488 /** @see Zend_Session_Exception */
489 if (!self::$_unitTestEnabled) {
490
491 if (self::$_throwStartupExceptions) {
492 // require_once 'Zend/Session/Exception.php';
493 set_error_handler(array('Zend_Session_Exception', 'handleSessionStartError'), $errorLevel);
494 }
495
496 $startedCleanly = session_start();
497
498 if (self::$_throwStartupExceptions) {
499 restore_error_handler();
500 }
501
502 if (!$startedCleanly || !empty(Zend_Session_Exception::$sessionStartError)) {
503 if (self::$_throwStartupExceptions) {
504 set_error_handler(array('Zend_Session_Exception', 'handleSilentWriteClose'), $errorLevel);
505 }
506 session_write_close();
507 if (self::$_throwStartupExceptions) {
508 restore_error_handler();
509 throw new Zend_Session_Exception(__CLASS__ . '::' . __FUNCTION__ . '() - ' . Zend_Session_Exception::$sessionStartError . ' Warnings: ' . Zend_Session_Exception::$sessionStartWarning);
510 }
511 }
512 }
513
514 parent::$_readable = true;
515 parent::$_writable = true;
516 self::$_sessionStarted = true;
517 if (self::$_regenerateIdState === -1) {
518 self::regenerateId();
519 } else {
520 self::rewriteSessionCookieWithSameSiteDirective();
521 }
522
523 if (isset($_SESSION['data']) && is_string($_SESSION['data'])) {
524 $_SESSION = unserialize(base64_decode($_SESSION['data']));
525 }
526
527 // run validators if they exist
528 if (isset($_SESSION['__ZF']['VALID'])) {
529 self::_processValidators();
530 }
531
532 self::_processStartupMetadataGlobal();
533 }
534
535
536 /**
537 * _processGlobalMetadata() - this method initizes the sessions GLOBAL
538 * metadata, mostly global data expiration calculations.
539 *
540 * @return void
541 */
542 private static function _processStartupMetadataGlobal()
543 {
544 // process global metadata
545 if (isset($_SESSION['__ZF'])) {
546
547 // expire globally expired values
548 foreach ($_SESSION['__ZF'] as $namespace => $namespace_metadata) {
549
550 // Expire Namespace by Time (ENT)
551 if (isset($namespace_metadata['ENT']) && ($namespace_metadata['ENT'] > 0) && (time() > $namespace_metadata['ENT']) ) {
552 unset($_SESSION[$namespace]);
553 unset($_SESSION['__ZF'][$namespace]);
554 }
555
556 // Expire Namespace by Global Hop (ENGH) if it wasnt expired above
557 if (isset($_SESSION['__ZF'][$namespace]) && isset($namespace_metadata['ENGH']) && $namespace_metadata['ENGH'] >= 1) {
558
559 $_SESSION['__ZF'][$namespace]['ENGH']--;
560
561 if ($_SESSION['__ZF'][$namespace]['ENGH'] === 0) {
562 if (isset($_SESSION[$namespace])) {
563 parent::$_expiringData[$namespace] = $_SESSION[$namespace];
564 unset($_SESSION[$namespace]);
565 }
566 unset($_SESSION['__ZF'][$namespace]);
567 }
568 }
569
570 // Expire Namespace Variables by Time (ENVT)
571 if (isset($namespace_metadata['ENVT'])) {
572 foreach ($namespace_metadata['ENVT'] as $variable => $time) {
573 if (time() > $time) {
574 unset($_SESSION[$namespace][$variable]);
575 unset($_SESSION['__ZF'][$namespace]['ENVT'][$variable]);
576 }
577 }
578 if (empty($_SESSION['__ZF'][$namespace]['ENVT'])) {
579 unset($_SESSION['__ZF'][$namespace]['ENVT']);
580 }
581 }
582
583 // Expire Namespace Variables by Global Hop (ENVGH)
584 if (isset($namespace_metadata['ENVGH'])) {
585 foreach ($namespace_metadata['ENVGH'] as $variable => $hops) {
586 $_SESSION['__ZF'][$namespace]['ENVGH'][$variable]--;
587
588 if ($_SESSION['__ZF'][$namespace]['ENVGH'][$variable] === 0) {
589 if (isset($_SESSION[$namespace][$variable])) {
590 parent::$_expiringData[$namespace][$variable] = $_SESSION[$namespace][$variable];
591 unset($_SESSION[$namespace][$variable]);
592 }
593 unset($_SESSION['__ZF'][$namespace]['ENVGH'][$variable]);
594 }
595 }
596 if (empty($_SESSION['__ZF'][$namespace]['ENVGH'])) {
597 unset($_SESSION['__ZF'][$namespace]['ENVGH']);
598 }
599 }
600
601 if (isset($namespace) && empty($_SESSION['__ZF'][$namespace])) {
602 unset($_SESSION['__ZF'][$namespace]);
603 }
604 }
605 }
606
607 if (isset($_SESSION['__ZF']) && empty($_SESSION['__ZF'])) {
608 unset($_SESSION['__ZF']);
609 }
610 }
611
612
613 /**
614 * isStarted() - convenience method to determine if the session is already started.
615 *
616 * @return bool
617 */
618 public static function isStarted()
619 {
620 return self::$_sessionStarted;
621 }
622
623
624 /**
625 * isRegenerated() - convenience method to determine if session_regenerate_id()
626 * has been called during this request by Zend_Session.
627 *
628 * @return bool
629 */
630 public static function isRegenerated()
631 {
632 return ( (self::$_regenerateIdState > 0) ? true : false );
633 }
634
635
636 /**
637 * getId() - get the current session id
638 *
639 * @return string
640 */
641 public static function getId()
642 {
643 return session_id();
644 }
645
646
647 /**
648 * setId() - set an id to a user specified id
649 *
650 * @throws Zend_Session_Exception
651 * @param string $id
652 * @return void
653 */
654 public static function setId($id)
655 {
656 if (!self::$_unitTestEnabled && defined('SID')) {
657 /** @see Zend_Session_Exception */
658 // require_once 'Zend/Session/Exception.php';
659 throw new Zend_Session_Exception('The session has already been started. The session id must be set first.');
660 }
661
662 if (!self::$_unitTestEnabled && headers_sent($filename, $linenum)) {
663 /** @see Zend_Session_Exception */
664 // require_once 'Zend/Session/Exception.php';
665 throw new Zend_Session_Exception("You must call ".__CLASS__.'::'.__FUNCTION__.
666 "() before any output has been sent to the browser; output started in {$filename}/{$linenum}");
667 }
668
669 if (!is_string($id) || $id === '') {
670 /** @see Zend_Session_Exception */
671 // require_once 'Zend/Session/Exception.php';
672 throw new Zend_Session_Exception('You must provide a non-empty string as a session identifier.');
673 }
674
675 session_id($id);
676 }
677
678
679 /**
680 * registerValidator() - register a validator that will attempt to validate this session for
681 * every future request
682 *
683 * @param Zend_Session_Validator_Interface $validator
684 * @return void
685 */
686 public static function registerValidator(Zend_Session_Validator_Interface $validator)
687 {
688 $validator->setup();
689 }
690
691
692 /**
693 * stop() - Disable write access. Optionally disable read (not implemented).
694 *
695 * @return void
696 */
697 public static function stop()
698 {
699 parent::$_writable = false;
700 }
701
702
703 /**
704 * writeClose() - Shutdown the sesssion, close writing and detach $_SESSION from the back-end storage mechanism.
705 * This will complete the internal data transformation on this request.
706 *
707 * @param bool $readonly - OPTIONAL remove write access (i.e. throw error if Zend_Session's attempt writes)
708 * @return void
709 */
710 public static function writeClose($readonly = true)
711 {
712 if (self::$_unitTestEnabled) {
713 return;
714 }
715
716 if (self::$_writeClosed) {
717 return;
718 }
719
720 if ($readonly) {
721 parent::$_writable = false;
722 }
723
724 if (isset($_SESSION)) {
725 $sessionBkp = $_SESSION;
726 $_SESSION = array('data' => base64_encode(serialize($_SESSION)));
727 }
728
729 session_write_close();
730 self::$_writeClosed = true;
731
732 if (isset($sessionBkp)) {
733 $_SESSION = $sessionBkp;
734 }
735 }
736
737
738 /**
739 * destroy() - This is used to destroy session data, and optionally, the session cookie itself
740 *
741 * @param bool $remove_cookie - OPTIONAL remove session id cookie, defaults to true (remove cookie)
742 * @param bool $readonly - OPTIONAL remove write access (i.e. throw error if Zend_Session's attempt writes)
743 * @return void
744 */
745 public static function destroy($remove_cookie = true, $readonly = true)
746 {
747 if (self::$_unitTestEnabled) {
748 return;
749 }
750
751 if (self::$_destroyed) {
752 return;
753 }
754
755 if ($readonly) {
756 parent::$_writable = false;
757 }
758
759 session_destroy();
760 self::$_destroyed = true;
761
762 if ($remove_cookie) {
763 self::expireSessionCookie();
764 }
765 }
766
767
768 /**
769 * expireSessionCookie() - Sends an expired session id cookie, causing the client to delete the session cookie
770 *
771 * @return void
772 */
773 public static function expireSessionCookie()
774 {
775 if (self::$_unitTestEnabled) {
776 return;
777 }
778
779 if (self::$_sessionCookieDeleted) {
780 return;
781 }
782
783 self::$_sessionCookieDeleted = true;
784
785 if (isset($_COOKIE[session_name()])) {
786 $cookie_params = session_get_cookie_params();
787
788 \Piwik\Session::writeCookie(
789 session_name(),
790 false,
791 315554400, // strtotime('1980-01-01'),
792 $cookie_params['path'],
793 $cookie_params['domain'],
794 $cookie_params['secure'],
795 false,
796 \Piwik\Session::getSameSiteCookieValue()
797 );
798 }
799 }
800
801
802 /**
803 * _processValidator() - internal function that is called in the existence of VALID metadata
804 *
805 * @throws Zend_Session_Exception
806 * @return void
807 */
808 private static function _processValidators()
809 {
810 foreach ($_SESSION['__ZF']['VALID'] as $validator_name => $valid_data) {
811 if (!class_exists($validator_name)) {
812 // require_once 'Zend/Loader.php';
813 Zend_Loader::loadClass($validator_name);
814 }
815 $validator = new $validator_name;
816 if ($validator->validate() === false) {
817 /** @see Zend_Session_Exception */
818 // require_once 'Zend/Session/Exception.php';
819 throw new Zend_Session_Exception("This session is not valid according to {$validator_name}.");
820 }
821 }
822 }
823
824
825 /**
826 * namespaceIsset() - check to see if a namespace is set
827 *
828 * @param string $namespace
829 * @return bool
830 */
831 public static function namespaceIsset($namespace)
832 {
833 return parent::_namespaceIsset($namespace);
834 }
835
836
837 /**
838 * namespaceUnset() - unset a namespace or a variable within a namespace
839 *
840 * @param string $namespace
841 * @throws Zend_Session_Exception
842 * @return void
843 */
844 public static function namespaceUnset($namespace)
845 {
846 parent::_namespaceUnset($namespace);
847 Zend_Session_Namespace::resetSingleInstance($namespace);
848 }
849
850
851 /**
852 * namespaceGet() - get all variables in a namespace
853 * Deprecated: Use getIterator() in Zend_Session_Namespace.
854 *
855 * @param string $namespace
856 * @return array
857 */
858 public static function namespaceGet($namespace)
859 {
860 return parent::_namespaceGetAll($namespace);
861 }
862
863
864 /**
865 * getIterator() - return an iteratable object for use in foreach and the like,
866 * this completes the IteratorAggregate interface
867 *
868 * @throws Zend_Session_Exception
869 * @return ArrayObject
870 */
871 public static function getIterator()
872 {
873 if (parent::$_readable === false) {
874 /** @see Zend_Session_Exception */
875 // require_once 'Zend/Session/Exception.php';
876 throw new Zend_Session_Exception(parent::_THROW_NOT_READABLE_MSG);
877 }
878
879 $spaces = array();
880 if (isset($_SESSION)) {
881 $spaces = array_keys($_SESSION);
882 foreach($spaces as $key => $space) {
883 if (!strncmp($space, '__', 2) || !is_array($_SESSION[$space])) {
884 unset($spaces[$key]);
885 }
886 }
887 }
888
889 return new ArrayObject(array_merge($spaces, array_keys(parent::$_expiringData)));
890 }
891
892
893 /**
894 * isWritable() - returns a boolean indicating if namespaces can write (use setters)
895 *
896 * @return bool
897 */
898 public static function isWritable()
899 {
900 return parent::$_writable;
901 }
902
903
904 /**
905 * isReadable() - returns a boolean indicating if namespaces can write (use setters)
906 *
907 * @return bool
908 */
909 public static function isReadable()
910 {
911 return parent::$_readable;
912 }
913
914 }
915