123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506 |
- <?php
- /**
- * Base session class.
- *
- * @package KO7
- * @category Session
- *
- * @copyright (c) 2007-2016 Kohana Team
- * @copyright (c) since 2016 Koseven Team
- * @license https://koseven.dev/LICENSE
- */
- abstract class KO7_Session {
- /**
- * @var string default session adapter
- */
- public static $default = 'native';
- /**
- * @var array session instances
- */
- public static $instances = [];
- /**
- * Creates a singleton session of the given type. Some session types
- * (native, database) also support restarting a session by passing a
- * session id as the second parameter.
- *
- * $session = Session::instance();
- *
- * [!!] [Session::write] will automatically be called when the request ends.
- *
- * @param string $type type of session (native, cookie, etc)
- * @param string $id session identifier
- * @return Session
- * @uses KO7::$config
- */
- public static function instance($type = NULL, $id = NULL)
- {
- if ($type === NULL)
- {
- // Use the default type
- $type = Session::$default;
- }
- if ( ! isset(Session::$instances[$type]))
- {
- // Load the configuration for this type
- $config = KO7::$config->load('session')->get($type);
- // Set the session class name
- $class = 'Session_'.ucfirst($type);
- // Create a new session instance
- Session::$instances[$type] = $session = new $class($config, $id);
- // Write the session at shutdown
- register_shutdown_function([$session, 'write']);
- }
- return Session::$instances[$type];
- }
- /**
- * @var string cookie name
- */
- protected $_name = 'session';
- /**
- * @var int cookie lifetime
- */
- protected $_lifetime = 0;
- /**
- * @var bool encrypt session data?
- */
- protected $_encrypted = FALSE;
- /**
- * @var array session data
- */
- protected $_data = [];
- /**
- * @var bool session destroyed?
- */
- protected $_destroyed = FALSE;
- /**
- * Overloads the name, lifetime, and encrypted session settings.
- *
- * [!!] Sessions can only be created using the [Session::instance] method.
- *
- * @param array $config configuration
- * @param string $id session id
- * @return void
- * @uses Session::read
- */
- public function __construct(array $config = NULL, $id = NULL)
- {
- if (isset($config['name']))
- {
- // Cookie name to store the session id in
- $this->_name = (string) $config['name'];
- }
- if (isset($config['lifetime']))
- {
- // Cookie lifetime
- $this->_lifetime = (int) $config['lifetime'];
- }
- if (isset($config['encrypted']))
- {
- if ($config['encrypted'] === TRUE)
- {
- // Use the default Encrypt instance
- $config['encrypted'] = 'default';
- }
- // Enable or disable encryption of data
- $this->_encrypted = $config['encrypted'];
- }
- // Load the session
- $this->read($id);
- }
- /**
- * Session object is rendered to a serialized string. If encryption is
- * enabled, the session will be encrypted. If not, the output string will
- * be encoded.
- *
- * echo $session;
- *
- * @return string
- * @uses Encrypt::encode
- */
- public function __toString()
- {
- // Serialize the data array
- $data = $this->_serialize($this->_data);
- if ($this->_encrypted)
- {
- // Encrypt the data using the default key
- $data = Encrypt::instance($this->_encrypted)->encode($data);
- }
- else
- {
- // Encode the data
- $data = $this->_encode($data);
- }
- return $data;
- }
- /**
- * Returns the current session array. The returned array can also be
- * assigned by reference.
- *
- * // Get a copy of the current session data
- * $data = $session->as_array();
- *
- * // Assign by reference for modification
- * $data =& $session->as_array();
- *
- * @return array
- */
- public function & as_array()
- {
- return $this->_data;
- }
- /**
- * Get the current session id, if the session supports it.
- *
- * $id = $session->id();
- *
- * [!!] Not all session types have ids.
- *
- * @return string
- * @since 3.0.8
- */
- public function id()
- {
- return NULL;
- }
- /**
- * Get the current session cookie name.
- *
- * $name = $session->name();
- *
- * @return string
- * @since 3.0.8
- */
- public function name()
- {
- return $this->_name;
- }
- /**
- * Get a variable from the session array.
- *
- * $foo = $session->get('foo');
- *
- * @param string $key variable name
- * @param mixed $default default value to return
- * @return mixed
- */
- public function get($key, $default = NULL)
- {
- return array_key_exists($key, $this->_data) ? $this->_data[$key] : $default;
- }
- /**
- * Get and delete a variable from the session array.
- *
- * $bar = $session->get_once('bar');
- *
- * @param string $key variable name
- * @param mixed $default default value to return
- * @return mixed
- */
- public function get_once($key, $default = NULL)
- {
- $value = $this->get($key, $default);
- unset($this->_data[$key]);
- return $value;
- }
- /**
- * Set a variable in the session array.
- *
- * $session->set('foo', 'bar');
- *
- * @param string $key variable name
- * @param mixed $value value
- * @return $this
- */
- public function set($key, $value)
- {
- $this->_data[$key] = $value;
- return $this;
- }
- /**
- * Set a variable by reference.
- *
- * $session->bind('foo', $foo);
- *
- * @param string $key variable name
- * @param mixed $value referenced value
- * @return $this
- */
- public function bind($key, & $value)
- {
- $this->_data[$key] =& $value;
- return $this;
- }
- /**
- * Removes a variable in the session array.
- *
- * $session->delete('foo');
- *
- * @param string $key,... variable name
- * @return $this
- */
- public function delete($key)
- {
- $args = func_get_args();
- foreach ($args as $key)
- {
- unset($this->_data[$key]);
- }
- return $this;
- }
- /**
- * Loads existing session data.
- *
- * $session->read();
- *
- * @param string $id session id
- * @return void
- */
- public function read($id = NULL)
- {
- $data = NULL;
- try
- {
- if (is_string($data = $this->_read($id)))
- {
- if ($this->_encrypted)
- {
- // Decrypt the data using the default key
- $data = Encrypt::instance($this->_encrypted)->decode($data);
- }
- else
- {
- // Decode the data
- $data = $this->_decode($data);
- }
- // Unserialize the data
- $data = $this->_unserialize($data);
- }
- else
- {
- // Ignore these, session is valid, likely no data though.
- }
- }
- catch (Exception $e)
- {
- // Error reading the session, usually a corrupt session.
- throw new Session_Exception('Error reading session data.', NULL, Session_Exception::SESSION_CORRUPT);
- }
- if (is_array($data))
- {
- // Load the data locally
- $this->_data = $data;
- }
- }
- /**
- * Generates a new session id and returns it.
- *
- * $id = $session->regenerate();
- *
- * @return string
- */
- public function regenerate()
- {
- return $this->_regenerate();
- }
- /**
- * Sets the last_active timestamp and saves the session.
- *
- * $session->write();
- *
- * [!!] Any errors that occur during session writing will be logged,
- * but not displayed, because sessions are written after output has
- * been sent.
- *
- * @return boolean
- * @uses KO7::$log
- */
- public function write()
- {
- if (headers_sent() OR $this->_destroyed)
- {
- // Session cannot be written when the headers are sent or when
- // the session has been destroyed
- return FALSE;
- }
- // Set the last active timestamp
- $this->_data['last_active'] = time();
- try
- {
- return $this->_write();
- }
- catch (Exception $e)
- {
- // Log & ignore all errors when a write fails
- KO7::$log->add(Log::ERROR, KO7_Exception::text($e))->write();
- return FALSE;
- }
- }
- /**
- * Completely destroy the current session.
- *
- * $success = $session->destroy();
- *
- * @return boolean
- */
- public function destroy()
- {
- if ($this->_destroyed === FALSE)
- {
- if ($this->_destroyed = $this->_destroy())
- {
- // The session has been destroyed, clear all data
- $this->_data = [];
- }
- }
- return $this->_destroyed;
- }
- /**
- * Restart the session.
- *
- * $success = $session->restart();
- *
- * @return boolean
- */
- public function restart()
- {
- if ($this->_destroyed === FALSE)
- {
- // Wipe out the current session.
- $this->destroy();
- }
- // Allow the new session to be saved
- $this->_destroyed = FALSE;
- return $this->_restart();
- }
- /**
- * Serializes the session data.
- *
- * @param array $data data
- * @return string
- */
- protected function _serialize($data)
- {
- return serialize($data);
- }
- /**
- * Unserializes the session data.
- *
- * @param string $data data
- * @return array
- */
- protected function _unserialize($data)
- {
- return unserialize($data);
- }
- /**
- * Encodes the session data using [base64_encode].
- *
- * @param string $data data
- * @return string
- */
- protected function _encode($data)
- {
- return base64_encode($data);
- }
- /**
- * Decodes the session data using [base64_decode].
- *
- * @param string $data data
- * @return string
- */
- protected function _decode($data)
- {
- return base64_decode($data);
- }
- /**
- * Loads the raw session data string and returns it.
- *
- * @param string $id session id
- * @return string
- */
- abstract protected function _read($id = NULL);
- /**
- * Generate a new session id and return it.
- *
- * @return string
- */
- abstract protected function _regenerate();
- /**
- * Writes the current session.
- *
- * @return boolean
- */
- abstract protected function _write();
- /**
- * Destroys the current session.
- *
- * @return boolean
- */
- abstract protected function _destroy();
- /**
- * Restarts the current session.
- *
- * @return boolean
- */
- abstract protected function _restart();
- }
|