mirror of
				https://github.com/yiisoft/yii2.git
				synced 2025-11-04 06:37:55 +08:00 
			
		
		
		
	* https://scrutinizer-ci.com/g/yiisoft/yii2/issues/master/files/framework/filters/AccessRule.php?selectedLabels%5B0%5D=2&selectedSeverities%5B0%5D=10&selectedSeverities%5B1%5D=5&orderField=path&order=asc&honorSelectedPaths=0 * https://scrutinizer-ci.com/g/yiisoft/yii2/issues/master/files/framework/helpers/BaseFileHelper.php?selectedLabels%5B0%5D=2&selectedSeverities%5B0%5D=10&selectedSeverities%5B1%5D=5&orderField=path&order=asc&honorSelectedPaths=0 * https://scrutinizer-ci.com/g/yiisoft/yii2/issues/master/files/framework/base/Application.php?selectedLabels%5B0%5D=7&selectedSeverities%5B0%5D=10&selectedSeverities%5B1%5D=5&orderField=path&order=asc&honorSelectedPaths=0 * https://scrutinizer-ci.com/g/yiisoft/yii2/issues/master/files/framework/base/Module.php?selectedLabels%5B0%5D=7&selectedSeverities%5B0%5D=10&selectedSeverities%5B1%5D=5&orderField=path&order=asc&honorSelectedPaths=0 * https://scrutinizer-ci.com/g/yiisoft/yii2/issues/master/files/framework/web/MultipartFormDataParser.php?selectedLabels%5B0%5D=7&selectedSeverities%5B0%5D=10&selectedSeverities%5B1%5D=5&orderField=path&order=asc&honorSelectedPaths=0 * https://scrutinizer-ci.com/g/yiisoft/yii2/issues/master/files/framework/web/Session.php?selectedLabels%5B0%5D=7&selectedSeverities%5B0%5D=10&selectedSeverities%5B1%5D=5&orderField=path&order=asc&honorSelectedPaths=0 * https://scrutinizer-ci.com/g/yiisoft/yii2/issues/master/files/framework/base/Controller.php?selectedLabels%5B0%5D=6&selectedSeverities%5B0%5D=10&selectedSeverities%5B1%5D=5&orderField=path&order=asc&honorSelectedPaths=0 * https://scrutinizer-ci.com/g/yiisoft/yii2/issues/master/files/framework/console/controllers/MigrateController.php?selectedLabels%5B0%5D=6&selectedSeverities%5B0%5D=10&selectedSeverities%5B1%5D=5&orderField=path&order=asc&honorSelectedPaths=0 * Added vardocs, and small refactor * https://scrutinizer-ci.com/g/yiisoft/yii2/issues/master/files/framework/db/conditions/InConditionBuilder.php?selectedLabels%5B0%5D=6&selectedSeverities%5B0%5D=10&selectedSeverities%5B1%5D=5&orderField=path&order=asc&honorSelectedPaths=0 * https://scrutinizer-ci.com/g/yiisoft/yii2/issues/master/files/framework/db/Connection.php?selectedLabels%5B0%5D=6&selectedSeverities%5B0%5D=10&selectedSeverities%5B1%5D=5&orderField=path&order=asc&honorSelectedPaths=0 * https://scrutinizer-ci.com/g/yiisoft/yii2/issues/master/files/framework/db/mssql/QueryBuilder.php?selectedLabels%5B0%5D=6&selectedSeverities%5B0%5D=10&selectedSeverities%5B1%5D=5&orderField=path&order=asc&honorSelectedPaths=0 * https://scrutinizer-ci.com/g/yiisoft/yii2/issues/master/files/framework/log/Logger.php?selectedLabels%5B0%5D=6&selectedSeverities%5B0%5D=10&selectedSeverities%5B1%5D=5&orderField=path&order=asc&honorSelectedPaths=0 * https://scrutinizer-ci.com/g/yiisoft/yii2/issues/master/files/framework/console/controllers/BaseMigrateController.php?selectedLabels%5B0%5D=18&selectedSeverities%5B0%5D=10&selectedSeverities%5B1%5D=5&orderField=path&order=asc&honorSelectedPaths=0 * Adding space between type * https://scrutinizer-ci.com/g/yiisoft/yii2/issues/master/files/framework/console/controllers/CacheController.php?selectedLabels%5B0%5D=18&selectedSeverities%5B0%5D=10&selectedSeverities%5B1%5D=5&orderField=path&order=asc&honorSelectedPaths=0 * https://scrutinizer-ci.com/g/yiisoft/yii2/issues/master/files/framework/console/controllers/FixtureController.php?selectedLabels%5B0%5D=18&selectedSeverities%5B0%5D=10&selectedSeverities%5B1%5D=5&orderField=path&order=asc&honorSelectedPaths=0 * https://scrutinizer-ci.com/g/yiisoft/yii2/issues/master/files/framework/console/controllers/MigrateController.php?selectedLabels%5B0%5D=18&selectedSeverities%5B0%5D=10&selectedSeverities%5B1%5D=5&orderField=path&order=asc&honorSelectedPaths=0 * Update framework/console/controllers/CacheController.php Co-authored-by: Alexander Makarov <sam@rmcreative.ru> * Update framework/console/controllers/CacheController.php Co-authored-by: Alexander Makarov <sam@rmcreative.ru> * Update framework/console/controllers/FixtureController.php Co-authored-by: Alexander Makarov <sam@rmcreative.ru> * Update framework/console/controllers/FixtureController.php Co-authored-by: Alexander Makarov <sam@rmcreative.ru> * Update framework/console/controllers/FixtureController.php Co-authored-by: Alexander Makarov <sam@rmcreative.ru> * Update framework/console/controllers/FixtureController.php Co-authored-by: Alexander Makarov <sam@rmcreative.ru> * Update framework/console/controllers/FixtureController.php Co-authored-by: Alexander Makarov <sam@rmcreative.ru> * Update framework/console/controllers/FixtureController.php Co-authored-by: Alexander Makarov <sam@rmcreative.ru> Co-authored-by: Alexander Makarov <sam@rmcreative.ru>
		
			
				
	
	
		
			1070 lines
		
	
	
		
			37 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			1070 lines
		
	
	
		
			37 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
/**
 | 
						|
 * @link http://www.yiiframework.com/
 | 
						|
 * @copyright Copyright (c) 2008 Yii Software LLC
 | 
						|
 * @license http://www.yiiframework.com/license/
 | 
						|
 */
 | 
						|
 | 
						|
namespace yii\web;
 | 
						|
 | 
						|
use Yii;
 | 
						|
use yii\base\Component;
 | 
						|
use yii\base\InvalidArgumentException;
 | 
						|
use yii\base\InvalidConfigException;
 | 
						|
 | 
						|
/**
 | 
						|
 * Session provides session data management and the related configurations.
 | 
						|
 *
 | 
						|
 * Session is a Web application component that can be accessed via `Yii::$app->session`.
 | 
						|
 *
 | 
						|
 * To start the session, call [[open()]]; To complete and send out session data, call [[close()]];
 | 
						|
 * To destroy the session, call [[destroy()]].
 | 
						|
 *
 | 
						|
 * Session can be used like an array to set and get session data. For example,
 | 
						|
 *
 | 
						|
 * ```php
 | 
						|
 * $session = new Session;
 | 
						|
 * $session->open();
 | 
						|
 * $value1 = $session['name1'];  // get session variable 'name1'
 | 
						|
 * $value2 = $session['name2'];  // get session variable 'name2'
 | 
						|
 * foreach ($session as $name => $value) // traverse all session variables
 | 
						|
 * $session['name3'] = $value3;  // set session variable 'name3'
 | 
						|
 * ```
 | 
						|
 *
 | 
						|
 * Session can be extended to support customized session storage.
 | 
						|
 * To do so, override [[useCustomStorage]] so that it returns true, and
 | 
						|
 * override these methods with the actual logic about using custom storage:
 | 
						|
 * [[openSession()]], [[closeSession()]], [[readSession()]], [[writeSession()]],
 | 
						|
 * [[destroySession()]] and [[gcSession()]].
 | 
						|
 *
 | 
						|
 * Session also supports a special type of session data, called *flash messages*.
 | 
						|
 * A flash message is available only in the current request and the next request.
 | 
						|
 * After that, it will be deleted automatically. Flash messages are particularly
 | 
						|
 * useful for displaying confirmation messages. To use flash messages, simply
 | 
						|
 * call methods such as [[setFlash()]], [[getFlash()]].
 | 
						|
 *
 | 
						|
 * For more details and usage information on Session, see the [guide article on sessions](guide:runtime-sessions-cookies).
 | 
						|
 *
 | 
						|
 * @property-read array $allFlashes Flash messages (key => message or key => [message1, message2]). This
 | 
						|
 * property is read-only.
 | 
						|
 * @property-read string $cacheLimiter Current cache limiter. This property is read-only.
 | 
						|
 * @property-read array $cookieParams The session cookie parameters. This property is read-only.
 | 
						|
 * @property-read int $count The number of session variables. This property is read-only.
 | 
						|
 * @property-write string $flash The key identifying the flash message. Note that flash messages and normal
 | 
						|
 * session variables share the same name space. If you have a normal session variable using the same name, its
 | 
						|
 * value will be overwritten by this method. This property is write-only.
 | 
						|
 * @property float $gCProbability The probability (percentage) that the GC (garbage collection) process is
 | 
						|
 * started on every session initialization.
 | 
						|
 * @property bool $hasSessionId Whether the current request has sent the session ID.
 | 
						|
 * @property string $id The current session ID.
 | 
						|
 * @property-read bool $isActive Whether the session has started. This property is read-only.
 | 
						|
 * @property-read SessionIterator $iterator An iterator for traversing the session variables. This property is
 | 
						|
 * read-only.
 | 
						|
 * @property string $name The current session name.
 | 
						|
 * @property string $savePath The current session save path, defaults to '/tmp'.
 | 
						|
 * @property int $timeout The number of seconds after which data will be seen as 'garbage' and cleaned up. The
 | 
						|
 * default value is 1440 seconds (or the value of "session.gc_maxlifetime" set in php.ini).
 | 
						|
 * @property bool|null $useCookies The value indicating whether cookies should be used to store session IDs.
 | 
						|
 * @property-read bool $useCustomStorage Whether to use custom storage. This property is read-only.
 | 
						|
 * @property-read bool $useStrictMode Whether strict mode is enabled or not. This property is read-only.
 | 
						|
 * @property bool $useTransparentSessionID Whether transparent sid support is enabled or not, defaults to
 | 
						|
 * false.
 | 
						|
 *
 | 
						|
 * @author Qiang Xue <qiang.xue@gmail.com>
 | 
						|
 * @since 2.0
 | 
						|
 */
 | 
						|
class Session extends Component implements \IteratorAggregate, \ArrayAccess, \Countable
 | 
						|
{
 | 
						|
    /**
 | 
						|
     * @var string|null Holds the original session module (before a custom handler is registered) so that it can be
 | 
						|
     * restored when a Session component without custom handler is used after one that has.
 | 
						|
     */
 | 
						|
    static protected $_originalSessionModule = null;
 | 
						|
    /**
 | 
						|
     * Polyfill for ini directive session.use-strict-mode for PHP < 5.5.2.
 | 
						|
     */
 | 
						|
    static private $_useStrictModePolyfill = false;
 | 
						|
    /**
 | 
						|
     * @var string the name of the session variable that stores the flash message data.
 | 
						|
     */
 | 
						|
    public $flashParam = '__flash';
 | 
						|
    /**
 | 
						|
     * @var \SessionHandlerInterface|array an object implementing the SessionHandlerInterface or a configuration array. If set, will be used to provide persistency instead of build-in methods.
 | 
						|
     */
 | 
						|
    public $handler;
 | 
						|
 | 
						|
    /**
 | 
						|
     * @var string|null Holds the session id in case useStrictMode is enabled and the session id needs to be regenerated
 | 
						|
     */
 | 
						|
    protected $_forceRegenerateId = null;
 | 
						|
 | 
						|
    /**
 | 
						|
     * @var array parameter-value pairs to override default session cookie parameters that are used for session_set_cookie_params() function
 | 
						|
     * Array may have the following possible keys: 'lifetime', 'path', 'domain', 'secure', 'httponly'
 | 
						|
     * @see https://secure.php.net/manual/en/function.session-set-cookie-params.php
 | 
						|
     */
 | 
						|
    private $_cookieParams = ['httponly' => true];
 | 
						|
    /**
 | 
						|
     * @var array|null is used for saving session between recreations due to session parameters update.
 | 
						|
     */
 | 
						|
    private $frozenSessionData;
 | 
						|
 | 
						|
 | 
						|
    /**
 | 
						|
     * Initializes the application component.
 | 
						|
     * This method is required by IApplicationComponent and is invoked by application.
 | 
						|
     */
 | 
						|
    public function init()
 | 
						|
    {
 | 
						|
        parent::init();
 | 
						|
        register_shutdown_function([$this, 'close']);
 | 
						|
        if ($this->getIsActive()) {
 | 
						|
            Yii::warning('Session is already started', __METHOD__);
 | 
						|
            $this->updateFlashCounters();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns a value indicating whether to use custom session storage.
 | 
						|
     * This method should be overridden to return true by child classes that implement custom session storage.
 | 
						|
     * To implement custom session storage, override these methods: [[openSession()]], [[closeSession()]],
 | 
						|
     * [[readSession()]], [[writeSession()]], [[destroySession()]] and [[gcSession()]].
 | 
						|
     * @return bool whether to use custom storage.
 | 
						|
     */
 | 
						|
    public function getUseCustomStorage()
 | 
						|
    {
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Starts the session.
 | 
						|
     */
 | 
						|
    public function open()
 | 
						|
    {
 | 
						|
        if ($this->getIsActive()) {
 | 
						|
            return;
 | 
						|
        }
 | 
						|
 | 
						|
        $this->registerSessionHandler();
 | 
						|
 | 
						|
        $this->setCookieParamsInternal();
 | 
						|
 | 
						|
        YII_DEBUG ? session_start() : @session_start();
 | 
						|
 | 
						|
        if ($this->getUseStrictMode() && $this->_forceRegenerateId) {
 | 
						|
            $this->regenerateID();
 | 
						|
            $this->_forceRegenerateId = null;
 | 
						|
        }
 | 
						|
 | 
						|
        if ($this->getIsActive()) {
 | 
						|
            Yii::info('Session started', __METHOD__);
 | 
						|
            $this->updateFlashCounters();
 | 
						|
        } else {
 | 
						|
            $error = error_get_last();
 | 
						|
            $message = isset($error['message']) ? $error['message'] : 'Failed to start session.';
 | 
						|
            Yii::error($message, __METHOD__);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Registers session handler.
 | 
						|
     * @throws \yii\base\InvalidConfigException
 | 
						|
     */
 | 
						|
    protected function registerSessionHandler()
 | 
						|
    {
 | 
						|
        $sessionModuleName = session_module_name();
 | 
						|
        if (static::$_originalSessionModule === null) {
 | 
						|
            static::$_originalSessionModule = $sessionModuleName;
 | 
						|
        }
 | 
						|
 | 
						|
        if ($this->handler !== null) {
 | 
						|
            if (!is_object($this->handler)) {
 | 
						|
                $this->handler = Yii::createObject($this->handler);
 | 
						|
            }
 | 
						|
            if (!$this->handler instanceof \SessionHandlerInterface) {
 | 
						|
                throw new InvalidConfigException('"' . get_class($this) . '::handler" must implement the SessionHandlerInterface.');
 | 
						|
            }
 | 
						|
            YII_DEBUG ? session_set_save_handler($this->handler, false) : @session_set_save_handler($this->handler, false);
 | 
						|
        } elseif ($this->getUseCustomStorage()) {
 | 
						|
            if (YII_DEBUG) {
 | 
						|
                session_set_save_handler(
 | 
						|
                    [$this, 'openSession'],
 | 
						|
                    [$this, 'closeSession'],
 | 
						|
                    [$this, 'readSession'],
 | 
						|
                    [$this, 'writeSession'],
 | 
						|
                    [$this, 'destroySession'],
 | 
						|
                    [$this, 'gcSession']
 | 
						|
                );
 | 
						|
            } else {
 | 
						|
                @session_set_save_handler(
 | 
						|
                    [$this, 'openSession'],
 | 
						|
                    [$this, 'closeSession'],
 | 
						|
                    [$this, 'readSession'],
 | 
						|
                    [$this, 'writeSession'],
 | 
						|
                    [$this, 'destroySession'],
 | 
						|
                    [$this, 'gcSession']
 | 
						|
                );
 | 
						|
            }
 | 
						|
        } elseif (
 | 
						|
            $sessionModuleName !== static::$_originalSessionModule
 | 
						|
            && static::$_originalSessionModule !== null
 | 
						|
            && static::$_originalSessionModule !== 'user'
 | 
						|
        ) {
 | 
						|
            session_module_name(static::$_originalSessionModule);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Ends the current session and store session data.
 | 
						|
     */
 | 
						|
    public function close()
 | 
						|
    {
 | 
						|
        if ($this->getIsActive()) {
 | 
						|
            YII_DEBUG ? session_write_close() : @session_write_close();
 | 
						|
        }
 | 
						|
 | 
						|
        $this->_forceRegenerateId = null;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Frees all session variables and destroys all data registered to a session.
 | 
						|
     *
 | 
						|
     * This method has no effect when session is not [[getIsActive()|active]].
 | 
						|
     * Make sure to call [[open()]] before calling it.
 | 
						|
     * @see open()
 | 
						|
     * @see isActive
 | 
						|
     */
 | 
						|
    public function destroy()
 | 
						|
    {
 | 
						|
        if ($this->getIsActive()) {
 | 
						|
            $sessionId = session_id();
 | 
						|
            $this->close();
 | 
						|
            $this->setId($sessionId);
 | 
						|
            $this->open();
 | 
						|
            session_unset();
 | 
						|
            session_destroy();
 | 
						|
            $this->setId($sessionId);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @return bool whether the session has started
 | 
						|
     */
 | 
						|
    public function getIsActive()
 | 
						|
    {
 | 
						|
        return session_status() === PHP_SESSION_ACTIVE;
 | 
						|
    }
 | 
						|
 | 
						|
    private $_hasSessionId;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns a value indicating whether the current request has sent the session ID.
 | 
						|
     * The default implementation will check cookie and $_GET using the session name.
 | 
						|
     * If you send session ID via other ways, you may need to override this method
 | 
						|
     * or call [[setHasSessionId()]] to explicitly set whether the session ID is sent.
 | 
						|
     * @return bool whether the current request has sent the session ID.
 | 
						|
     */
 | 
						|
    public function getHasSessionId()
 | 
						|
    {
 | 
						|
        if ($this->_hasSessionId === null) {
 | 
						|
            $name = $this->getName();
 | 
						|
            $request = Yii::$app->getRequest();
 | 
						|
            if (!empty($_COOKIE[$name]) && ini_get('session.use_cookies')) {
 | 
						|
                $this->_hasSessionId = true;
 | 
						|
            } elseif (!ini_get('session.use_only_cookies') && ini_get('session.use_trans_sid')) {
 | 
						|
                $this->_hasSessionId = $request->get($name) != '';
 | 
						|
            } else {
 | 
						|
                $this->_hasSessionId = false;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        return $this->_hasSessionId;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Sets the value indicating whether the current request has sent the session ID.
 | 
						|
     * This method is provided so that you can override the default way of determining
 | 
						|
     * whether the session ID is sent.
 | 
						|
     * @param bool $value whether the current request has sent the session ID.
 | 
						|
     */
 | 
						|
    public function setHasSessionId($value)
 | 
						|
    {
 | 
						|
        $this->_hasSessionId = $value;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Gets the session ID.
 | 
						|
     * This is a wrapper for [PHP session_id()](https://secure.php.net/manual/en/function.session-id.php).
 | 
						|
     * @return string the current session ID
 | 
						|
     */
 | 
						|
    public function getId()
 | 
						|
    {
 | 
						|
        return session_id();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Sets the session ID.
 | 
						|
     * This is a wrapper for [PHP session_id()](https://secure.php.net/manual/en/function.session-id.php).
 | 
						|
     * @param string $value the session ID for the current session
 | 
						|
     */
 | 
						|
    public function setId($value)
 | 
						|
    {
 | 
						|
        session_id($value);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Updates the current session ID with a newly generated one.
 | 
						|
     *
 | 
						|
     * Please refer to <https://secure.php.net/session_regenerate_id> for more details.
 | 
						|
     *
 | 
						|
     * This method has no effect when session is not [[getIsActive()|active]].
 | 
						|
     * Make sure to call [[open()]] before calling it.
 | 
						|
     *
 | 
						|
     * @param bool $deleteOldSession Whether to delete the old associated session file or not.
 | 
						|
     * @see open()
 | 
						|
     * @see isActive
 | 
						|
     */
 | 
						|
    public function regenerateID($deleteOldSession = false)
 | 
						|
    {
 | 
						|
        if ($this->getIsActive()) {
 | 
						|
            // add @ to inhibit possible warning due to race condition
 | 
						|
            // https://github.com/yiisoft/yii2/pull/1812
 | 
						|
            if (YII_DEBUG && !headers_sent()) {
 | 
						|
                session_regenerate_id($deleteOldSession);
 | 
						|
            } else {
 | 
						|
                @session_regenerate_id($deleteOldSession);
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Gets the name of the current session.
 | 
						|
     * This is a wrapper for [PHP session_name()](https://secure.php.net/manual/en/function.session-name.php).
 | 
						|
     * @return string the current session name
 | 
						|
     */
 | 
						|
    public function getName()
 | 
						|
    {
 | 
						|
        return session_name();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Sets the name for the current session.
 | 
						|
     * This is a wrapper for [PHP session_name()](https://secure.php.net/manual/en/function.session-name.php).
 | 
						|
     * @param string $value the session name for the current session, must be an alphanumeric string.
 | 
						|
     * It defaults to "PHPSESSID".
 | 
						|
     */
 | 
						|
    public function setName($value)
 | 
						|
    {
 | 
						|
        $this->freeze();
 | 
						|
        session_name($value);
 | 
						|
        $this->unfreeze();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Gets the current session save path.
 | 
						|
     * This is a wrapper for [PHP session_save_path()](https://secure.php.net/manual/en/function.session-save-path.php).
 | 
						|
     * @return string the current session save path, defaults to '/tmp'.
 | 
						|
     */
 | 
						|
    public function getSavePath()
 | 
						|
    {
 | 
						|
        return session_save_path();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Sets the current session save path.
 | 
						|
     * This is a wrapper for [PHP session_save_path()](https://secure.php.net/manual/en/function.session-save-path.php).
 | 
						|
     * @param string $value the current session save path. This can be either a directory name or a [path alias](guide:concept-aliases).
 | 
						|
     * @throws InvalidArgumentException if the path is not a valid directory
 | 
						|
     */
 | 
						|
    public function setSavePath($value)
 | 
						|
    {
 | 
						|
        $path = Yii::getAlias($value);
 | 
						|
        if (is_dir($path)) {
 | 
						|
            session_save_path($path);
 | 
						|
        } else {
 | 
						|
            throw new InvalidArgumentException("Session save path is not a valid directory: $value");
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @return array the session cookie parameters.
 | 
						|
     * @see https://secure.php.net/manual/en/function.session-get-cookie-params.php
 | 
						|
     */
 | 
						|
    public function getCookieParams()
 | 
						|
    {
 | 
						|
        return array_merge(session_get_cookie_params(), array_change_key_case($this->_cookieParams));
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Sets the session cookie parameters.
 | 
						|
     * The cookie parameters passed to this method will be merged with the result
 | 
						|
     * of `session_get_cookie_params()`.
 | 
						|
     * @param array $value cookie parameters, valid keys include: `lifetime`, `path`, `domain`, `secure` and `httponly`.
 | 
						|
     * Starting with Yii 2.0.21 `sameSite` is also supported. It requires PHP version 7.3.0 or higher.
 | 
						|
     * For securtiy, an exception will be thrown if `sameSite` is set while using an unsupported version of PHP.
 | 
						|
     * To use this feature across different PHP versions check the version first. E.g.
 | 
						|
     * ```php
 | 
						|
     * [
 | 
						|
     *     'sameSite' => PHP_VERSION_ID >= 70300 ? yii\web\Cookie::SAME_SITE_LAX : null,
 | 
						|
     * ]
 | 
						|
     * ```
 | 
						|
     * See https://www.owasp.org/index.php/SameSite for more information about `sameSite`.
 | 
						|
     *
 | 
						|
     * @throws InvalidArgumentException if the parameters are incomplete.
 | 
						|
     * @see https://secure.php.net/manual/en/function.session-set-cookie-params.php
 | 
						|
     */
 | 
						|
    public function setCookieParams(array $value)
 | 
						|
    {
 | 
						|
        $this->_cookieParams = $value;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Sets the session cookie parameters.
 | 
						|
     * This method is called by [[open()]] when it is about to open the session.
 | 
						|
     * @throws InvalidArgumentException if the parameters are incomplete.
 | 
						|
     * @see https://secure.php.net/manual/en/function.session-set-cookie-params.php
 | 
						|
     */
 | 
						|
    private function setCookieParamsInternal()
 | 
						|
    {
 | 
						|
        $data = $this->getCookieParams();
 | 
						|
        if (isset($data['lifetime'], $data['path'], $data['domain'], $data['secure'], $data['httponly'])) {
 | 
						|
            if (PHP_VERSION_ID >= 70300) {
 | 
						|
                session_set_cookie_params($data);
 | 
						|
            } else {
 | 
						|
                if (!empty($data['samesite'])) {
 | 
						|
                    $data['path'] .= '; samesite=' . $data['samesite'];
 | 
						|
                }
 | 
						|
                session_set_cookie_params($data['lifetime'], $data['path'], $data['domain'], $data['secure'], $data['httponly']);
 | 
						|
            }
 | 
						|
 | 
						|
        } else {
 | 
						|
            throw new InvalidArgumentException('Please make sure cookieParams contains these elements: lifetime, path, domain, secure and httponly.');
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the value indicating whether cookies should be used to store session IDs.
 | 
						|
     * @return bool|null the value indicating whether cookies should be used to store session IDs.
 | 
						|
     * @see setUseCookies()
 | 
						|
     */
 | 
						|
    public function getUseCookies()
 | 
						|
    {
 | 
						|
        if (ini_get('session.use_cookies') === '0') {
 | 
						|
            return false;
 | 
						|
        } elseif (ini_get('session.use_only_cookies') === '1') {
 | 
						|
            return true;
 | 
						|
        }
 | 
						|
 | 
						|
        return null;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Sets the value indicating whether cookies should be used to store session IDs.
 | 
						|
     *
 | 
						|
     * Three states are possible:
 | 
						|
     *
 | 
						|
     * - true: cookies and only cookies will be used to store session IDs.
 | 
						|
     * - false: cookies will not be used to store session IDs.
 | 
						|
     * - null: if possible, cookies will be used to store session IDs; if not, other mechanisms will be used (e.g. GET parameter)
 | 
						|
     *
 | 
						|
     * @param bool|null $value the value indicating whether cookies should be used to store session IDs.
 | 
						|
     */
 | 
						|
    public function setUseCookies($value)
 | 
						|
    {
 | 
						|
        $this->freeze();
 | 
						|
        if ($value === false) {
 | 
						|
            ini_set('session.use_cookies', '0');
 | 
						|
            ini_set('session.use_only_cookies', '0');
 | 
						|
        } elseif ($value === true) {
 | 
						|
            ini_set('session.use_cookies', '1');
 | 
						|
            ini_set('session.use_only_cookies', '1');
 | 
						|
        } else {
 | 
						|
            ini_set('session.use_cookies', '1');
 | 
						|
            ini_set('session.use_only_cookies', '0');
 | 
						|
        }
 | 
						|
        $this->unfreeze();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @return float the probability (percentage) that the GC (garbage collection) process is started on every session initialization.
 | 
						|
     */
 | 
						|
    public function getGCProbability()
 | 
						|
    {
 | 
						|
        return (float) (ini_get('session.gc_probability') / ini_get('session.gc_divisor') * 100);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @param float $value the probability (percentage) that the GC (garbage collection) process is started on every session initialization.
 | 
						|
     * @throws InvalidArgumentException if the value is not between 0 and 100.
 | 
						|
     */
 | 
						|
    public function setGCProbability($value)
 | 
						|
    {
 | 
						|
        $this->freeze();
 | 
						|
        if ($value >= 0 && $value <= 100) {
 | 
						|
            // percent * 21474837 / 2147483647 ≈ percent * 0.01
 | 
						|
            ini_set('session.gc_probability', floor($value * 21474836.47));
 | 
						|
            ini_set('session.gc_divisor', 2147483647);
 | 
						|
        } else {
 | 
						|
            throw new InvalidArgumentException('GCProbability must be a value between 0 and 100.');
 | 
						|
        }
 | 
						|
        $this->unfreeze();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @return bool whether transparent sid support is enabled or not, defaults to false.
 | 
						|
     */
 | 
						|
    public function getUseTransparentSessionID()
 | 
						|
    {
 | 
						|
        return ini_get('session.use_trans_sid') == 1;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @param bool $value whether transparent sid support is enabled or not.
 | 
						|
     */
 | 
						|
    public function setUseTransparentSessionID($value)
 | 
						|
    {
 | 
						|
        $this->freeze();
 | 
						|
        ini_set('session.use_trans_sid', $value ? '1' : '0');
 | 
						|
        $this->unfreeze();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @return int the number of seconds after which data will be seen as 'garbage' and cleaned up.
 | 
						|
     * The default value is 1440 seconds (or the value of "session.gc_maxlifetime" set in php.ini).
 | 
						|
     */
 | 
						|
    public function getTimeout()
 | 
						|
    {
 | 
						|
        return (int) ini_get('session.gc_maxlifetime');
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @param int $value the number of seconds after which data will be seen as 'garbage' and cleaned up
 | 
						|
     */
 | 
						|
    public function setTimeout($value)
 | 
						|
    {
 | 
						|
        $this->freeze();
 | 
						|
        ini_set('session.gc_maxlifetime', $value);
 | 
						|
        $this->unfreeze();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @var bool Whether strict mode is enabled or not.
 | 
						|
     * When `true` this setting prevents the session component to use an uninitialized session ID.
 | 
						|
     * Note: Enabling `useStrictMode` on PHP < 5.5.2 is only supported with custom storage classes.
 | 
						|
     * Warning! Although enabling strict mode is mandatory for secure sessions, the default value of 'session.use-strict-mode' is `0`.
 | 
						|
     * @see https://www.php.net/manual/en/session.configuration.php#ini.session.use-strict-mode
 | 
						|
     * @since 2.0.38
 | 
						|
     */
 | 
						|
    public function setUseStrictMode($value)
 | 
						|
    {
 | 
						|
        if (PHP_VERSION_ID < 50502) {
 | 
						|
            if ($this->getUseCustomStorage() || !$value) {
 | 
						|
                self::$_useStrictModePolyfill = $value;
 | 
						|
            } else {
 | 
						|
                throw new InvalidConfigException('Enabling `useStrictMode` on PHP < 5.5.2 is only supported with custom storage classes.');
 | 
						|
            }
 | 
						|
        } else {
 | 
						|
            $this->freeze();
 | 
						|
            ini_set('session.use_strict_mode', $value ? '1' : '0');
 | 
						|
            $this->unfreeze();
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @return bool Whether strict mode is enabled or not.
 | 
						|
     * @see setUseStrictMode()
 | 
						|
     * @since 2.0.38
 | 
						|
     */
 | 
						|
    public function getUseStrictMode()
 | 
						|
    {
 | 
						|
        if (PHP_VERSION_ID < 50502) {
 | 
						|
            return self::$_useStrictModePolyfill;
 | 
						|
        }
 | 
						|
 | 
						|
        return (bool)ini_get('session.use_strict_mode');
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Session open handler.
 | 
						|
     * This method should be overridden if [[useCustomStorage]] returns true.
 | 
						|
     * @internal Do not call this method directly.
 | 
						|
     * @param string $savePath session save path
 | 
						|
     * @param string $sessionName session name
 | 
						|
     * @return bool whether session is opened successfully
 | 
						|
     */
 | 
						|
    public function openSession($savePath, $sessionName)
 | 
						|
    {
 | 
						|
        return true;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Session close handler.
 | 
						|
     * This method should be overridden if [[useCustomStorage]] returns true.
 | 
						|
     * @internal Do not call this method directly.
 | 
						|
     * @return bool whether session is closed successfully
 | 
						|
     */
 | 
						|
    public function closeSession()
 | 
						|
    {
 | 
						|
        return true;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Session read handler.
 | 
						|
     * This method should be overridden if [[useCustomStorage]] returns true.
 | 
						|
     * @internal Do not call this method directly.
 | 
						|
     * @param string $id session ID
 | 
						|
     * @return string the session data
 | 
						|
     */
 | 
						|
    public function readSession($id)
 | 
						|
    {
 | 
						|
        return '';
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Session write handler.
 | 
						|
     * This method should be overridden if [[useCustomStorage]] returns true.
 | 
						|
     * @internal Do not call this method directly.
 | 
						|
     * @param string $id session ID
 | 
						|
     * @param string $data session data
 | 
						|
     * @return bool whether session write is successful
 | 
						|
     */
 | 
						|
    public function writeSession($id, $data)
 | 
						|
    {
 | 
						|
        return true;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Session destroy handler.
 | 
						|
     * This method should be overridden if [[useCustomStorage]] returns true.
 | 
						|
     * @internal Do not call this method directly.
 | 
						|
     * @param string $id session ID
 | 
						|
     * @return bool whether session is destroyed successfully
 | 
						|
     */
 | 
						|
    public function destroySession($id)
 | 
						|
    {
 | 
						|
        return true;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Session GC (garbage collection) handler.
 | 
						|
     * This method should be overridden if [[useCustomStorage]] returns true.
 | 
						|
     * @internal Do not call this method directly.
 | 
						|
     * @param int $maxLifetime the number of seconds after which data will be seen as 'garbage' and cleaned up.
 | 
						|
     * @return bool whether session is GCed successfully
 | 
						|
     */
 | 
						|
    public function gcSession($maxLifetime)
 | 
						|
    {
 | 
						|
        return true;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns an iterator for traversing the session variables.
 | 
						|
     * This method is required by the interface [[\IteratorAggregate]].
 | 
						|
     * @return SessionIterator an iterator for traversing the session variables.
 | 
						|
     */
 | 
						|
    public function getIterator()
 | 
						|
    {
 | 
						|
        $this->open();
 | 
						|
        return new SessionIterator();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the number of items in the session.
 | 
						|
     * @return int the number of session variables
 | 
						|
     */
 | 
						|
    public function getCount()
 | 
						|
    {
 | 
						|
        $this->open();
 | 
						|
        return count($_SESSION);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the number of items in the session.
 | 
						|
     * This method is required by [[\Countable]] interface.
 | 
						|
     * @return int number of items in the session.
 | 
						|
     */
 | 
						|
    public function count()
 | 
						|
    {
 | 
						|
        return $this->getCount();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the session variable value with the session variable name.
 | 
						|
     * If the session variable does not exist, the `$defaultValue` will be returned.
 | 
						|
     * @param string $key the session variable name
 | 
						|
     * @param mixed $defaultValue the default value to be returned when the session variable does not exist.
 | 
						|
     * @return mixed the session variable value, or $defaultValue if the session variable does not exist.
 | 
						|
     */
 | 
						|
    public function get($key, $defaultValue = null)
 | 
						|
    {
 | 
						|
        $this->open();
 | 
						|
        return isset($_SESSION[$key]) ? $_SESSION[$key] : $defaultValue;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Adds a session variable.
 | 
						|
     * If the specified name already exists, the old value will be overwritten.
 | 
						|
     * @param string $key session variable name
 | 
						|
     * @param mixed $value session variable value
 | 
						|
     */
 | 
						|
    public function set($key, $value)
 | 
						|
    {
 | 
						|
        $this->open();
 | 
						|
        $_SESSION[$key] = $value;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Removes a session variable.
 | 
						|
     * @param string $key the name of the session variable to be removed
 | 
						|
     * @return mixed the removed value, null if no such session variable.
 | 
						|
     */
 | 
						|
    public function remove($key)
 | 
						|
    {
 | 
						|
        $this->open();
 | 
						|
        if (isset($_SESSION[$key])) {
 | 
						|
            $value = $_SESSION[$key];
 | 
						|
            unset($_SESSION[$key]);
 | 
						|
 | 
						|
            return $value;
 | 
						|
        }
 | 
						|
 | 
						|
        return null;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Removes all session variables.
 | 
						|
     */
 | 
						|
    public function removeAll()
 | 
						|
    {
 | 
						|
        $this->open();
 | 
						|
        foreach (array_keys($_SESSION) as $key) {
 | 
						|
            unset($_SESSION[$key]);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * @param mixed $key session variable name
 | 
						|
     * @return bool whether there is the named session variable
 | 
						|
     */
 | 
						|
    public function has($key)
 | 
						|
    {
 | 
						|
        $this->open();
 | 
						|
        return isset($_SESSION[$key]);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Updates the counters for flash messages and removes outdated flash messages.
 | 
						|
     * This method should only be called once in [[init()]].
 | 
						|
     */
 | 
						|
    protected function updateFlashCounters()
 | 
						|
    {
 | 
						|
        $counters = $this->get($this->flashParam, []);
 | 
						|
        if (is_array($counters)) {
 | 
						|
            foreach ($counters as $key => $count) {
 | 
						|
                if ($count > 0) {
 | 
						|
                    unset($counters[$key], $_SESSION[$key]);
 | 
						|
                } elseif ($count == 0) {
 | 
						|
                    $counters[$key]++;
 | 
						|
                }
 | 
						|
            }
 | 
						|
            $_SESSION[$this->flashParam] = $counters;
 | 
						|
        } else {
 | 
						|
            // fix the unexpected problem that flashParam doesn't return an array
 | 
						|
            unset($_SESSION[$this->flashParam]);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns a flash message.
 | 
						|
     * @param string $key the key identifying the flash message
 | 
						|
     * @param mixed $defaultValue value to be returned if the flash message does not exist.
 | 
						|
     * @param bool $delete whether to delete this flash message right after this method is called.
 | 
						|
     * If false, the flash message will be automatically deleted in the next request.
 | 
						|
     * @return mixed the flash message or an array of messages if addFlash was used
 | 
						|
     * @see setFlash()
 | 
						|
     * @see addFlash()
 | 
						|
     * @see hasFlash()
 | 
						|
     * @see getAllFlashes()
 | 
						|
     * @see removeFlash()
 | 
						|
     */
 | 
						|
    public function getFlash($key, $defaultValue = null, $delete = false)
 | 
						|
    {
 | 
						|
        $counters = $this->get($this->flashParam, []);
 | 
						|
        if (isset($counters[$key])) {
 | 
						|
            $value = $this->get($key, $defaultValue);
 | 
						|
            if ($delete) {
 | 
						|
                $this->removeFlash($key);
 | 
						|
            } elseif ($counters[$key] < 0) {
 | 
						|
                // mark for deletion in the next request
 | 
						|
                $counters[$key] = 1;
 | 
						|
                $_SESSION[$this->flashParam] = $counters;
 | 
						|
            }
 | 
						|
 | 
						|
            return $value;
 | 
						|
        }
 | 
						|
 | 
						|
        return $defaultValue;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns all flash messages.
 | 
						|
     *
 | 
						|
     * You may use this method to display all the flash messages in a view file:
 | 
						|
     *
 | 
						|
     * ```php
 | 
						|
     * <?php
 | 
						|
     * foreach (Yii::$app->session->getAllFlashes() as $key => $message) {
 | 
						|
     *     echo '<div class="alert alert-' . $key . '">' . $message . '</div>';
 | 
						|
     * } ?>
 | 
						|
     * ```
 | 
						|
     *
 | 
						|
     * With the above code you can use the [bootstrap alert][] classes such as `success`, `info`, `danger`
 | 
						|
     * as the flash message key to influence the color of the div.
 | 
						|
     *
 | 
						|
     * Note that if you use [[addFlash()]], `$message` will be an array, and you will have to adjust the above code.
 | 
						|
     *
 | 
						|
     * [bootstrap alert]: http://getbootstrap.com/components/#alerts
 | 
						|
     *
 | 
						|
     * @param bool $delete whether to delete the flash messages right after this method is called.
 | 
						|
     * If false, the flash messages will be automatically deleted in the next request.
 | 
						|
     * @return array flash messages (key => message or key => [message1, message2]).
 | 
						|
     * @see setFlash()
 | 
						|
     * @see addFlash()
 | 
						|
     * @see getFlash()
 | 
						|
     * @see hasFlash()
 | 
						|
     * @see removeFlash()
 | 
						|
     */
 | 
						|
    public function getAllFlashes($delete = false)
 | 
						|
    {
 | 
						|
        $counters = $this->get($this->flashParam, []);
 | 
						|
        $flashes = [];
 | 
						|
        foreach (array_keys($counters) as $key) {
 | 
						|
            if (array_key_exists($key, $_SESSION)) {
 | 
						|
                $flashes[$key] = $_SESSION[$key];
 | 
						|
                if ($delete) {
 | 
						|
                    unset($counters[$key], $_SESSION[$key]);
 | 
						|
                } elseif ($counters[$key] < 0) {
 | 
						|
                    // mark for deletion in the next request
 | 
						|
                    $counters[$key] = 1;
 | 
						|
                }
 | 
						|
            } else {
 | 
						|
                unset($counters[$key]);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        $_SESSION[$this->flashParam] = $counters;
 | 
						|
 | 
						|
        return $flashes;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Sets a flash message.
 | 
						|
     * A flash message will be automatically deleted after it is accessed in a request and the deletion will happen
 | 
						|
     * in the next request.
 | 
						|
     * If there is already an existing flash message with the same key, it will be overwritten by the new one.
 | 
						|
     * @param string $key the key identifying the flash message. Note that flash messages
 | 
						|
     * and normal session variables share the same name space. If you have a normal
 | 
						|
     * session variable using the same name, its value will be overwritten by this method.
 | 
						|
     * @param mixed $value flash message
 | 
						|
     * @param bool $removeAfterAccess whether the flash message should be automatically removed only if
 | 
						|
     * it is accessed. If false, the flash message will be automatically removed after the next request,
 | 
						|
     * regardless if it is accessed or not. If true (default value), the flash message will remain until after
 | 
						|
     * it is accessed.
 | 
						|
     * @see getFlash()
 | 
						|
     * @see addFlash()
 | 
						|
     * @see removeFlash()
 | 
						|
     */
 | 
						|
    public function setFlash($key, $value = true, $removeAfterAccess = true)
 | 
						|
    {
 | 
						|
        $counters = $this->get($this->flashParam, []);
 | 
						|
        $counters[$key] = $removeAfterAccess ? -1 : 0;
 | 
						|
        $_SESSION[$key] = $value;
 | 
						|
        $_SESSION[$this->flashParam] = $counters;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Adds a flash message.
 | 
						|
     * If there are existing flash messages with the same key, the new one will be appended to the existing message array.
 | 
						|
     * @param string $key the key identifying the flash message.
 | 
						|
     * @param mixed $value flash message
 | 
						|
     * @param bool $removeAfterAccess whether the flash message should be automatically removed only if
 | 
						|
     * it is accessed. If false, the flash message will be automatically removed after the next request,
 | 
						|
     * regardless if it is accessed or not. If true (default value), the flash message will remain until after
 | 
						|
     * it is accessed.
 | 
						|
     * @see getFlash()
 | 
						|
     * @see setFlash()
 | 
						|
     * @see removeFlash()
 | 
						|
     */
 | 
						|
    public function addFlash($key, $value = true, $removeAfterAccess = true)
 | 
						|
    {
 | 
						|
        $counters = $this->get($this->flashParam, []);
 | 
						|
        $counters[$key] = $removeAfterAccess ? -1 : 0;
 | 
						|
        $_SESSION[$this->flashParam] = $counters;
 | 
						|
        if (empty($_SESSION[$key])) {
 | 
						|
            $_SESSION[$key] = [$value];
 | 
						|
        } elseif (is_array($_SESSION[$key])) {
 | 
						|
            $_SESSION[$key][] = $value;
 | 
						|
        } else {
 | 
						|
            $_SESSION[$key] = [$_SESSION[$key], $value];
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Removes a flash message.
 | 
						|
     * @param string $key the key identifying the flash message. Note that flash messages
 | 
						|
     * and normal session variables share the same name space.  If you have a normal
 | 
						|
     * session variable using the same name, it will be removed by this method.
 | 
						|
     * @return mixed the removed flash message. Null if the flash message does not exist.
 | 
						|
     * @see getFlash()
 | 
						|
     * @see setFlash()
 | 
						|
     * @see addFlash()
 | 
						|
     * @see removeAllFlashes()
 | 
						|
     */
 | 
						|
    public function removeFlash($key)
 | 
						|
    {
 | 
						|
        $counters = $this->get($this->flashParam, []);
 | 
						|
        $value = isset($_SESSION[$key], $counters[$key]) ? $_SESSION[$key] : null;
 | 
						|
        unset($counters[$key], $_SESSION[$key]);
 | 
						|
        $_SESSION[$this->flashParam] = $counters;
 | 
						|
 | 
						|
        return $value;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Removes all flash messages.
 | 
						|
     * Note that flash messages and normal session variables share the same name space.
 | 
						|
     * If you have a normal session variable using the same name, it will be removed
 | 
						|
     * by this method.
 | 
						|
     * @see getFlash()
 | 
						|
     * @see setFlash()
 | 
						|
     * @see addFlash()
 | 
						|
     * @see removeFlash()
 | 
						|
     */
 | 
						|
    public function removeAllFlashes()
 | 
						|
    {
 | 
						|
        $counters = $this->get($this->flashParam, []);
 | 
						|
        foreach (array_keys($counters) as $key) {
 | 
						|
            unset($_SESSION[$key]);
 | 
						|
        }
 | 
						|
        unset($_SESSION[$this->flashParam]);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns a value indicating whether there are flash messages associated with the specified key.
 | 
						|
     * @param string $key key identifying the flash message type
 | 
						|
     * @return bool whether any flash messages exist under specified key
 | 
						|
     */
 | 
						|
    public function hasFlash($key)
 | 
						|
    {
 | 
						|
        return $this->getFlash($key) !== null;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * This method is required by the interface [[\ArrayAccess]].
 | 
						|
     * @param mixed $offset the offset to check on
 | 
						|
     * @return bool
 | 
						|
     */
 | 
						|
    public function offsetExists($offset)
 | 
						|
    {
 | 
						|
        $this->open();
 | 
						|
 | 
						|
        return isset($_SESSION[$offset]);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * This method is required by the interface [[\ArrayAccess]].
 | 
						|
     * @param int $offset the offset to retrieve element.
 | 
						|
     * @return mixed the element at the offset, null if no element is found at the offset
 | 
						|
     */
 | 
						|
    public function offsetGet($offset)
 | 
						|
    {
 | 
						|
        $this->open();
 | 
						|
 | 
						|
        return isset($_SESSION[$offset]) ? $_SESSION[$offset] : null;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * This method is required by the interface [[\ArrayAccess]].
 | 
						|
     * @param int $offset the offset to set element
 | 
						|
     * @param mixed $item the element value
 | 
						|
     */
 | 
						|
    public function offsetSet($offset, $item)
 | 
						|
    {
 | 
						|
        $this->open();
 | 
						|
        $_SESSION[$offset] = $item;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * This method is required by the interface [[\ArrayAccess]].
 | 
						|
     * @param mixed $offset the offset to unset element
 | 
						|
     */
 | 
						|
    public function offsetUnset($offset)
 | 
						|
    {
 | 
						|
        $this->open();
 | 
						|
        unset($_SESSION[$offset]);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * If session is started it's not possible to edit session ini settings. In PHP7.2+ it throws exception.
 | 
						|
     * This function saves session data to temporary variable and stop session.
 | 
						|
     * @since 2.0.14
 | 
						|
     */
 | 
						|
    protected function freeze()
 | 
						|
    {
 | 
						|
        if ($this->getIsActive()) {
 | 
						|
            if (isset($_SESSION)) {
 | 
						|
                $this->frozenSessionData = $_SESSION;
 | 
						|
            }
 | 
						|
            $this->close();
 | 
						|
            Yii::info('Session frozen', __METHOD__);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Starts session and restores data from temporary variable
 | 
						|
     * @since 2.0.14
 | 
						|
     */
 | 
						|
    protected function unfreeze()
 | 
						|
    {
 | 
						|
        if (null !== $this->frozenSessionData) {
 | 
						|
 | 
						|
            YII_DEBUG ? session_start() : @session_start();
 | 
						|
 | 
						|
            if ($this->getIsActive()) {
 | 
						|
                Yii::info('Session unfrozen', __METHOD__);
 | 
						|
            } else {
 | 
						|
                $error = error_get_last();
 | 
						|
                $message = isset($error['message']) ? $error['message'] : 'Failed to unfreeze session.';
 | 
						|
                Yii::error($message, __METHOD__);
 | 
						|
            }
 | 
						|
 | 
						|
            $_SESSION = $this->frozenSessionData;
 | 
						|
            $this->frozenSessionData = null;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Set cache limiter
 | 
						|
     *
 | 
						|
     * @param string $cacheLimiter
 | 
						|
     * @since 2.0.14
 | 
						|
     */
 | 
						|
    public function setCacheLimiter($cacheLimiter)
 | 
						|
    {
 | 
						|
        $this->freeze();
 | 
						|
        session_cache_limiter($cacheLimiter);
 | 
						|
        $this->unfreeze();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns current cache limiter
 | 
						|
     *
 | 
						|
     * @return string current cache limiter
 | 
						|
     * @since 2.0.14
 | 
						|
     */
 | 
						|
    public function getCacheLimiter()
 | 
						|
    {
 | 
						|
        return session_cache_limiter();
 | 
						|
    }
 | 
						|
}
 |