summaryrefslogtreecommitdiffstats
path: root/library/vendor/Zend/Session.php
diff options
context:
space:
mode:
Diffstat (limited to 'library/vendor/Zend/Session.php')
-rw-r--r--library/vendor/Zend/Session.php895
1 files changed, 895 insertions, 0 deletions
diff --git a/library/vendor/Zend/Session.php b/library/vendor/Zend/Session.php
new file mode 100644
index 0000000..a1ed797
--- /dev/null
+++ b/library/vendor/Zend/Session.php
@@ -0,0 +1,895 @@
+<?php
+
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Session
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ * @since Preview Release 0.2
+ */
+
+
+/**
+ * @see Zend_Session_Abstract
+ */
+
+/**
+ * @see Zend_Session_Namespace
+ */
+
+/**
+ * @see Zend_Session_SaveHandler_Interface
+ */
+
+
+/**
+ * Zend_Session
+ *
+ * @category Zend
+ * @package Zend_Session
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Session extends Zend_Session_Abstract
+{
+ /**
+ * Whether or not Zend_Session is being used with unit tests
+ *
+ * @internal
+ * @var bool
+ */
+ public static $_unitTestEnabled = false;
+
+ /**
+ * $_throwStartupException
+ *
+ * @var bool|bitset This could also be a combiniation of error codes to catch
+ */
+ protected static $_throwStartupExceptions = true;
+
+ /**
+ * Check whether or not the session was started
+ *
+ * @var bool
+ */
+ private static $_sessionStarted = false;
+
+ /**
+ * Whether or not the session id has been regenerated this request.
+ *
+ * Id regeneration state
+ * <0 - regenerate requested when session is started
+ * 0 - do nothing
+ * >0 - already called session_regenerate_id()
+ *
+ * @var int
+ */
+ private static $_regenerateIdState = 0;
+
+ /**
+ * Private list of php's ini values for ext/session
+ * null values will default to the php.ini value, otherwise
+ * the value below will overwrite the default ini value, unless
+ * the user has set an option explicity with setOptions()
+ *
+ * @var array
+ */
+ private static $_defaultOptions = array(
+ 'save_path' => null,
+ 'name' => null, /* this should be set to a unique value for each application */
+ 'save_handler' => null,
+ //'auto_start' => null, /* intentionally excluded (see manual) */
+ 'gc_probability' => null,
+ 'gc_divisor' => null,
+ 'gc_maxlifetime' => null,
+ 'serialize_handler' => null,
+ 'cookie_lifetime' => null,
+ 'cookie_path' => null,
+ 'cookie_domain' => null,
+ 'cookie_secure' => null,
+ 'cookie_httponly' => null,
+ 'use_cookies' => null,
+ 'use_only_cookies' => 'on',
+ 'referer_check' => null,
+ 'entropy_file' => null,
+ 'entropy_length' => null,
+ 'cache_limiter' => null,
+ 'cache_expire' => null,
+ 'use_trans_sid' => null,
+ 'bug_compat_42' => null,
+ 'bug_compat_warn' => null,
+ 'hash_function' => null,
+ 'hash_bits_per_character' => null
+ );
+
+ /**
+ * List of options pertaining to Zend_Session that can be set by developers
+ * using Zend_Session::setOptions(). This list intentionally duplicates
+ * the individual declaration of static "class" variables by the same names.
+ *
+ * @var array
+ */
+ private static $_localOptions = array(
+ 'strict' => '_strict',
+ 'remember_me_seconds' => '_rememberMeSeconds',
+ 'throw_startup_exceptions' => '_throwStartupExceptions'
+ );
+
+ /**
+ * Whether or not write close has been performed.
+ *
+ * @var bool
+ */
+ private static $_writeClosed = false;
+
+ /**
+ * Whether or not session id cookie has been deleted
+ *
+ * @var bool
+ */
+ private static $_sessionCookieDeleted = false;
+
+ /**
+ * Whether or not session has been destroyed via session_destroy()
+ *
+ * @var bool
+ */
+ private static $_destroyed = false;
+
+ /**
+ * Whether or not session must be initiated before usage
+ *
+ * @var bool
+ */
+ private static $_strict = false;
+
+ /**
+ * Default number of seconds the session will be remembered for when asked to be remembered
+ *
+ * @var int
+ */
+ private static $_rememberMeSeconds = 1209600; // 2 weeks
+
+ /**
+ * Whether the default options listed in Zend_Session::$_localOptions have been set
+ *
+ * @var bool
+ */
+ private static $_defaultOptionsSet = false;
+
+ /**
+ * A reference to the set session save handler
+ *
+ * @var Zend_Session_SaveHandler_Interface
+ */
+ private static $_saveHandler = null;
+
+
+ /**
+ * Constructor overriding - make sure that a developer cannot instantiate
+ */
+ protected function __construct()
+ {
+ }
+
+
+ /**
+ * setOptions - set both the class specified
+ *
+ * @param array $userOptions - pass-by-keyword style array of <option name, option value> pairs
+ * @throws Zend_Session_Exception
+ * @return void
+ */
+ public static function setOptions(array $userOptions = array())
+ {
+ // set default options on first run only (before applying user settings)
+ if (!self::$_defaultOptionsSet) {
+ foreach (self::$_defaultOptions as $defaultOptionName => $defaultOptionValue) {
+ if (isset(self::$_defaultOptions[$defaultOptionName])) {
+ ini_set("session.$defaultOptionName", $defaultOptionValue);
+ }
+ }
+
+ self::$_defaultOptionsSet = true;
+ }
+
+ // set the options the user has requested to set
+ foreach ($userOptions as $userOptionName => $userOptionValue) {
+
+ $userOptionName = strtolower($userOptionName);
+
+ // set the ini based values
+ if (array_key_exists($userOptionName, self::$_defaultOptions)) {
+ ini_set("session.$userOptionName", $userOptionValue);
+ }
+ elseif (isset(self::$_localOptions[$userOptionName])) {
+ self::${self::$_localOptions[$userOptionName]} = $userOptionValue;
+ }
+ else {
+ /** @see Zend_Session_Exception */
+ throw new Zend_Session_Exception("Unknown option: $userOptionName = $userOptionValue");
+ }
+ }
+ }
+
+ /**
+ * getOptions()
+ *
+ * @param string $optionName OPTIONAL
+ * @return array|string
+ */
+ public static function getOptions($optionName = null)
+ {
+ $options = array();
+ foreach (ini_get_all('session') as $sysOptionName => $sysOptionValues) {
+ $options[substr($sysOptionName, 8)] = $sysOptionValues['local_value'];
+ }
+ foreach (self::$_localOptions as $localOptionName => $localOptionMemberName) {
+ $options[$localOptionName] = self::${$localOptionMemberName};
+ }
+
+ if ($optionName) {
+ if (array_key_exists($optionName, $options)) {
+ return $options[$optionName];
+ }
+ return null;
+ }
+
+ return $options;
+ }
+
+ /**
+ * setSaveHandler() - Session Save Handler assignment
+ *
+ * @param Zend_Session_SaveHandler_Interface $interface
+ * @throws Zend_Session_Exception When the session_set_save_handler call fails
+ * @return void
+ */
+ public static function setSaveHandler(Zend_Session_SaveHandler_Interface $saveHandler)
+ {
+ self::$_saveHandler = $saveHandler;
+
+ if (self::$_unitTestEnabled) {
+ return;
+ }
+
+ $result = session_set_save_handler(
+ array(&$saveHandler, 'open'),
+ array(&$saveHandler, 'close'),
+ array(&$saveHandler, 'read'),
+ array(&$saveHandler, 'write'),
+ array(&$saveHandler, 'destroy'),
+ array(&$saveHandler, 'gc')
+ );
+
+ if (!$result) {
+ throw new Zend_Session_Exception('Unable to set session handler');
+ }
+ }
+
+
+ /**
+ * getSaveHandler() - Get the session Save Handler
+ *
+ * @return Zend_Session_SaveHandler_Interface
+ */
+ public static function getSaveHandler()
+ {
+ return self::$_saveHandler;
+ }
+
+
+ /**
+ * regenerateId() - Regenerate the session id. Best practice is to call this after
+ * session is started. If called prior to session starting, session id will be regenerated
+ * at start time.
+ *
+ * @throws Zend_Session_Exception
+ * @return void
+ */
+ public static function regenerateId()
+ {
+ if (!self::$_unitTestEnabled && headers_sent($filename, $linenum)) {
+ /** @see Zend_Session_Exception */
+ throw new Zend_Session_Exception("You must call " . __CLASS__ . '::' . __FUNCTION__ .
+ "() before any output has been sent to the browser; output started in {$filename}/{$linenum}");
+ }
+
+ if ( !self::$_sessionStarted ) {
+ self::$_regenerateIdState = -1;
+ } else {
+ if (!self::$_unitTestEnabled) {
+ session_regenerate_id(true);
+ }
+ self::$_regenerateIdState = 1;
+ }
+ }
+
+
+ /**
+ * rememberMe() - Write a persistent cookie that expires after a number of seconds in the future. If no number of
+ * seconds is specified, then this defaults to self::$_rememberMeSeconds. Due to clock errors on end users' systems,
+ * large values are recommended to avoid undesirable expiration of session cookies.
+ *
+ * @param int $seconds OPTIONAL specifies TTL for cookie in seconds from present time
+ * @return void
+ */
+ public static function rememberMe($seconds = null)
+ {
+ $seconds = (int) $seconds;
+ $seconds = ($seconds > 0) ? $seconds : self::$_rememberMeSeconds;
+
+ self::rememberUntil($seconds);
+ }
+
+
+ /**
+ * forgetMe() - Write a volatile session cookie, removing any persistent cookie that may have existed. The session
+ * would end upon, for example, termination of a web browser program.
+ *
+ * @return void
+ */
+ public static function forgetMe()
+ {
+ self::rememberUntil(0);
+ }
+
+
+ /**
+ * rememberUntil() - This method does the work of changing the state of the session cookie and making
+ * sure that it gets resent to the browser via regenerateId()
+ *
+ * @param int $seconds
+ * @return void
+ */
+ public static function rememberUntil($seconds = 0)
+ {
+ if (self::$_unitTestEnabled) {
+ self::regenerateId();
+ return;
+ }
+
+ $cookieParams = session_get_cookie_params();
+
+ session_set_cookie_params(
+ $seconds,
+ $cookieParams['path'],
+ $cookieParams['domain'],
+ $cookieParams['secure']
+ );
+
+ // normally "rememberMe()" represents a security context change, so should use new session id
+ self::regenerateId();
+ }
+
+
+ /**
+ * sessionExists() - whether or not a session exists for the current request
+ *
+ * @return bool
+ */
+ public static function sessionExists()
+ {
+ if ((bool)ini_get('session.use_cookies') == true && isset($_COOKIE[session_name()])) {
+ return true;
+ } elseif ((bool)ini_get('session.use_only_cookies') == false && isset($_REQUEST[session_name()])) {
+ return true;
+ } elseif (self::$_unitTestEnabled) {
+ return true;
+ }
+
+ return false;
+ }
+
+
+ /**
+ * Whether or not session has been destroyed via session_destroy()
+ *
+ * @return bool
+ */
+ public static function isDestroyed()
+ {
+ return self::$_destroyed;
+ }
+
+
+ /**
+ * start() - Start the session.
+ *
+ * @param bool|array $options OPTIONAL Either user supplied options, or flag indicating if start initiated automatically
+ * @throws Zend_Session_Exception
+ * @return void
+ */
+ public static function start($options = false)
+ {
+ // Check to see if we've been passed an invalid session ID
+ if ( self::getId() && !self::_checkId(self::getId()) ) {
+ // Generate a valid, temporary replacement
+ self::setId(md5(self::getId()));
+ // Force a regenerate after session is started
+ self::$_regenerateIdState = -1;
+ }
+
+ if (self::$_sessionStarted && self::$_destroyed) {
+ throw new Zend_Session_Exception('The session was explicitly destroyed during this request, attempting to re-start is not allowed.');
+ }
+
+ if (self::$_sessionStarted) {
+ return; // already started
+ }
+
+ // make sure our default options (at the least) have been set
+ if (!self::$_defaultOptionsSet) {
+ self::setOptions(is_array($options) ? $options : array());
+ }
+
+ // In strict mode, do not allow auto-starting Zend_Session, such as via "new Zend_Session_Namespace()"
+ if (self::$_strict && $options === true) {
+ /** @see Zend_Session_Exception */
+ throw new Zend_Session_Exception('You must explicitly start the session with Zend_Session::start() when session options are set to strict.');
+ }
+
+ $filename = $linenum = null;
+ if (!self::$_unitTestEnabled && headers_sent($filename, $linenum)) {
+ /** @see Zend_Session_Exception */
+ throw new Zend_Session_Exception("Session must be started before any output has been sent to the browser;"
+ . " output started in {$filename}/{$linenum}");
+ }
+
+ // See http://www.php.net/manual/en/ref.session.php for explanation
+ if (!self::$_unitTestEnabled && defined('SID')) {
+ /** @see Zend_Session_Exception */
+ throw new Zend_Session_Exception('session has already been started by session.auto-start or session_start()');
+ }
+
+ /**
+ * Hack to throw exceptions on start instead of php errors
+ * @see http://framework.zend.com/issues/browse/ZF-1325
+ */
+
+ $errorLevel = (is_int(self::$_throwStartupExceptions)) ? self::$_throwStartupExceptions : E_ALL;
+
+ /** @see Zend_Session_Exception */
+ if (!self::$_unitTestEnabled) {
+
+ if (self::$_throwStartupExceptions) {
+ set_error_handler(array('Zend_Session_Exception', 'handleSessionStartError'), $errorLevel);
+ }
+
+ $startedCleanly = session_start();
+
+ if (self::$_throwStartupExceptions) {
+ restore_error_handler();
+ }
+
+ if (!$startedCleanly || Zend_Session_Exception::$sessionStartError != null) {
+ if (self::$_throwStartupExceptions) {
+ set_error_handler(array('Zend_Session_Exception', 'handleSilentWriteClose'), $errorLevel);
+ }
+ session_write_close();
+ if (self::$_throwStartupExceptions) {
+ restore_error_handler();
+ throw new Zend_Session_Exception(__CLASS__ . '::' . __FUNCTION__ . '() - ' . Zend_Session_Exception::$sessionStartError);
+ }
+ }
+ }
+
+ parent::$_readable = true;
+ parent::$_writable = true;
+ self::$_sessionStarted = true;
+ if (self::$_regenerateIdState === -1) {
+ self::regenerateId();
+ }
+
+ // run validators if they exist
+ if (isset($_SESSION['__ZF']['VALID'])) {
+ self::_processValidators();
+ }
+
+ self::_processStartupMetadataGlobal();
+ }
+
+ /**
+ * Perform a hash-bits check on the session ID
+ *
+ * @param string $id Session ID
+ * @return bool
+ */
+ protected static function _checkId($id)
+ {
+ $saveHandler = ini_get('session.save_handler');
+ if ($saveHandler == 'cluster') { // Zend Server SC, validate only after last dash
+ $dashPos = strrpos($id, '-');
+ if ($dashPos) {
+ $id = substr($id, $dashPos + 1);
+ }
+ }
+
+ $hashBitsPerChar = ini_get('session.hash_bits_per_character');
+ if (!$hashBitsPerChar) {
+ $hashBitsPerChar = 5; // the default value
+ }
+ switch($hashBitsPerChar) {
+ case 4: $pattern = '^[0-9a-f]*$'; break;
+ case 5: $pattern = '^[0-9a-v]*$'; break;
+ case 6: $pattern = '^[0-9a-zA-Z-,]*$'; break;
+ }
+ return preg_match('#'.$pattern.'#', $id);
+ }
+
+
+ /**
+ * _processGlobalMetadata() - this method initizes the sessions GLOBAL
+ * metadata, mostly global data expiration calculations.
+ *
+ * @return void
+ */
+ private static function _processStartupMetadataGlobal()
+ {
+ // process global metadata
+ if (isset($_SESSION['__ZF'])) {
+
+ // expire globally expired values
+ foreach ($_SESSION['__ZF'] as $namespace => $namespace_metadata) {
+
+ // Expire Namespace by Time (ENT)
+ if (isset($namespace_metadata['ENT']) && ($namespace_metadata['ENT'] > 0) && (time() > $namespace_metadata['ENT']) ) {
+ unset($_SESSION[$namespace]);
+ unset($_SESSION['__ZF'][$namespace]);
+ }
+
+ // Expire Namespace by Global Hop (ENGH) if it wasnt expired above
+ if (isset($_SESSION['__ZF'][$namespace]) && isset($namespace_metadata['ENGH']) && $namespace_metadata['ENGH'] >= 1) {
+
+ $_SESSION['__ZF'][$namespace]['ENGH']--;
+
+ if ($_SESSION['__ZF'][$namespace]['ENGH'] === 0) {
+ if (isset($_SESSION[$namespace])) {
+ parent::$_expiringData[$namespace] = $_SESSION[$namespace];
+ unset($_SESSION[$namespace]);
+ }
+ unset($_SESSION['__ZF'][$namespace]);
+ }
+ }
+
+ // Expire Namespace Variables by Time (ENVT)
+ if (isset($namespace_metadata['ENVT'])) {
+ foreach ($namespace_metadata['ENVT'] as $variable => $time) {
+ if (time() > $time) {
+ unset($_SESSION[$namespace][$variable]);
+ unset($_SESSION['__ZF'][$namespace]['ENVT'][$variable]);
+ }
+ }
+ if (empty($_SESSION['__ZF'][$namespace]['ENVT'])) {
+ unset($_SESSION['__ZF'][$namespace]['ENVT']);
+ }
+ }
+
+ // Expire Namespace Variables by Global Hop (ENVGH)
+ if (isset($namespace_metadata['ENVGH'])) {
+ foreach ($namespace_metadata['ENVGH'] as $variable => $hops) {
+ $_SESSION['__ZF'][$namespace]['ENVGH'][$variable]--;
+
+ if ($_SESSION['__ZF'][$namespace]['ENVGH'][$variable] === 0) {
+ if (isset($_SESSION[$namespace][$variable])) {
+ parent::$_expiringData[$namespace][$variable] = $_SESSION[$namespace][$variable];
+ unset($_SESSION[$namespace][$variable]);
+ }
+ unset($_SESSION['__ZF'][$namespace]['ENVGH'][$variable]);
+ }
+ }
+ if (empty($_SESSION['__ZF'][$namespace]['ENVGH'])) {
+ unset($_SESSION['__ZF'][$namespace]['ENVGH']);
+ }
+ }
+
+ if (isset($namespace) && empty($_SESSION['__ZF'][$namespace])) {
+ unset($_SESSION['__ZF'][$namespace]);
+ }
+ }
+ }
+
+ if (isset($_SESSION['__ZF']) && empty($_SESSION['__ZF'])) {
+ unset($_SESSION['__ZF']);
+ }
+ }
+
+
+ /**
+ * isStarted() - convenience method to determine if the session is already started.
+ *
+ * @return bool
+ */
+ public static function isStarted()
+ {
+ return self::$_sessionStarted;
+ }
+
+
+ /**
+ * isRegenerated() - convenience method to determine if session_regenerate_id()
+ * has been called during this request by Zend_Session.
+ *
+ * @return bool
+ */
+ public static function isRegenerated()
+ {
+ return ( (self::$_regenerateIdState > 0) ? true : false );
+ }
+
+
+ /**
+ * getId() - get the current session id
+ *
+ * @return string
+ */
+ public static function getId()
+ {
+ return session_id();
+ }
+
+
+ /**
+ * setId() - set an id to a user specified id
+ *
+ * @throws Zend_Session_Exception
+ * @param string $id
+ * @return void
+ */
+ public static function setId($id)
+ {
+ if (!self::$_unitTestEnabled && defined('SID')) {
+ /** @see Zend_Session_Exception */
+ throw new Zend_Session_Exception('The session has already been started. The session id must be set first.');
+ }
+
+ if (!self::$_unitTestEnabled && headers_sent($filename, $linenum)) {
+ /** @see Zend_Session_Exception */
+ throw new Zend_Session_Exception("You must call ".__CLASS__.'::'.__FUNCTION__.
+ "() before any output has been sent to the browser; output started in {$filename}/{$linenum}");
+ }
+
+ if (!is_string($id) || $id === '') {
+ /** @see Zend_Session_Exception */
+ throw new Zend_Session_Exception('You must provide a non-empty string as a session identifier.');
+ }
+
+ session_id($id);
+ }
+
+
+ /**
+ * registerValidator() - register a validator that will attempt to validate this session for
+ * every future request
+ *
+ * @param Zend_Session_Validator_Interface $validator
+ * @return void
+ */
+ public static function registerValidator(Zend_Session_Validator_Interface $validator)
+ {
+ $validator->setup();
+ }
+
+
+ /**
+ * stop() - Disable write access. Optionally disable read (not implemented).
+ *
+ * @return void
+ */
+ public static function stop()
+ {
+ parent::$_writable = false;
+ }
+
+
+ /**
+ * writeClose() - Shutdown the sesssion, close writing and detach $_SESSION from the back-end storage mechanism.
+ * This will complete the internal data transformation on this request.
+ *
+ * @param bool $readonly - OPTIONAL remove write access (i.e. throw error if Zend_Session's attempt writes)
+ * @return void
+ */
+ public static function writeClose($readonly = true)
+ {
+ if (self::$_unitTestEnabled) {
+ return;
+ }
+
+ if (self::$_writeClosed) {
+ return;
+ }
+
+ if ($readonly) {
+ parent::$_writable = false;
+ }
+
+ session_write_close();
+ self::$_writeClosed = true;
+ }
+
+
+ /**
+ * destroy() - This is used to destroy session data, and optionally, the session cookie itself
+ *
+ * @param bool $remove_cookie - OPTIONAL remove session id cookie, defaults to true (remove cookie)
+ * @param bool $readonly - OPTIONAL remove write access (i.e. throw error if Zend_Session's attempt writes)
+ * @return void
+ */
+ public static function destroy($remove_cookie = true, $readonly = true)
+ {
+ if (self::$_unitTestEnabled) {
+ return;
+ }
+
+ if (self::$_destroyed) {
+ return;
+ }
+
+ if ($readonly) {
+ parent::$_writable = false;
+ }
+
+ session_destroy();
+ self::$_destroyed = true;
+
+ if ($remove_cookie) {
+ self::expireSessionCookie();
+ }
+ }
+
+
+ /**
+ * expireSessionCookie() - Sends an expired session id cookie, causing the client to delete the session cookie
+ *
+ * @return void
+ */
+ public static function expireSessionCookie()
+ {
+ if (self::$_unitTestEnabled) {
+ return;
+ }
+
+ if (self::$_sessionCookieDeleted) {
+ return;
+ }
+
+ self::$_sessionCookieDeleted = true;
+
+ if (isset($_COOKIE[session_name()])) {
+ $cookie_params = session_get_cookie_params();
+
+ setcookie(
+ session_name(),
+ false,
+ 315554400, // strtotime('1980-01-01'),
+ $cookie_params['path'],
+ $cookie_params['domain'],
+ $cookie_params['secure']
+ );
+ }
+ }
+
+
+ /**
+ * _processValidator() - internal function that is called in the existence of VALID metadata
+ *
+ * @throws Zend_Session_Exception
+ * @return void
+ */
+ private static function _processValidators()
+ {
+ foreach ($_SESSION['__ZF']['VALID'] as $validator_name => $valid_data) {
+ if (!class_exists($validator_name)) {
+ Zend_Loader::loadClass($validator_name);
+ }
+ $validator = new $validator_name;
+ if ($validator->validate() === false) {
+ /** @see Zend_Session_Validator_Exception */
+ throw new Zend_Session_Validator_Exception("This session is not valid according to {$validator_name}.");
+ }
+ }
+ }
+
+
+ /**
+ * namespaceIsset() - check to see if a namespace is set
+ *
+ * @param string $namespace
+ * @return bool
+ */
+ public static function namespaceIsset($namespace)
+ {
+ return parent::_namespaceIsset($namespace);
+ }
+
+
+ /**
+ * namespaceUnset() - unset a namespace or a variable within a namespace
+ *
+ * @param string $namespace
+ * @throws Zend_Session_Exception
+ * @return void
+ */
+ public static function namespaceUnset($namespace)
+ {
+ parent::_namespaceUnset($namespace);
+ Zend_Session_Namespace::resetSingleInstance($namespace);
+ }
+
+
+ /**
+ * namespaceGet() - get all variables in a namespace
+ * Deprecated: Use getIterator() in Zend_Session_Namespace.
+ *
+ * @param string $namespace
+ * @return array
+ */
+ public static function namespaceGet($namespace)
+ {
+ return parent::_namespaceGetAll($namespace);
+ }
+
+
+ /**
+ * getIterator() - return an iteratable object for use in foreach and the like,
+ * this completes the IteratorAggregate interface
+ *
+ * @throws Zend_Session_Exception
+ * @return ArrayObject
+ */
+ public static function getIterator()
+ {
+ if (parent::$_readable === false) {
+ /** @see Zend_Session_Exception */
+ throw new Zend_Session_Exception(parent::_THROW_NOT_READABLE_MSG);
+ }
+
+ $spaces = array();
+ if (isset($_SESSION)) {
+ $spaces = array_keys($_SESSION);
+ foreach($spaces as $key => $space) {
+ if (!strncmp($space, '__', 2) || !is_array($_SESSION[$space])) {
+ unset($spaces[$key]);
+ }
+ }
+ }
+
+ return new ArrayObject(array_merge($spaces, array_keys(parent::$_expiringData)));
+ }
+
+
+ /**
+ * isWritable() - returns a boolean indicating if namespaces can write (use setters)
+ *
+ * @return bool
+ */
+ public static function isWritable()
+ {
+ return parent::$_writable;
+ }
+
+
+ /**
+ * isReadable() - returns a boolean indicating if namespaces can write (use setters)
+ *
+ * @return bool
+ */
+ public static function isReadable()
+ {
+ return parent::$_readable;
+ }
+
+}