PHP Classes

File: engine/class.www-sessions.php

Recommend this page to a friend!
  Classes of Kristo Vaher   Wave Framework   engine/class.www-sessions.php   Download  
File: engine/class.www-sessions.php
Role: Class source
Content type: text/plain
Description: Sessions Class
Class: Wave Framework
MVC framework for building Web sites and APIs
Author: By
Last change: Update of engine/class.www-sessions.php
Date: 9 months ago
Size: 11,209 bytes
 

Contents

Class file image Download
<?php /** * Wave Framework <http://www.example.com> * Session Handler * * This is a project specific sessions handler that is used by Wave Framework. Custom sessions * handler is needed by Wave Framework because certain projects need distributed sessions or * other forms of session handling. Note that while you can edit this class to your liking, * you should not change the default method names and variables as these are called by State * class of Wave Framework. This class does not do garbage collection, it is recommended to use * Cleaner maintenance script to clean session storage every now and then. * * @package State * @author Kristo Vaher <kristo@waher.net> * @copyright Copyright (c) 2012, Kristo Vaher * @license GNU Lesser General Public License Version 3 * @tutorial /doc/pages/sessions.htm * @since 3.2.0 * @version 3.6.4 */ final class WWW_Sessions { /** * This is the default session name. Wave Framework does not use 'PHPSESSID' by default and * instead sets the session name (and cookie value) that starts with WWW prefix and is followed * by a number generated from system folder specific folders. */ public $sessionName='PHPSESSID'; /** * This carries the currently known session ID value. This is the value of the session cookie. */ public $sessionId=false; /** * This array stores session data. This data will be stored as serialized string in session storage * in filesystem or (if you rewrite methods of this class) in database. */ public $sessionData=array(); /** * This holds information about session cookie and its various configuration settings. These will * be used whenever sessions are created. */ public $sessionCookie=array( 'lifetime'=>0, 'path'=>'/', 'domain'=>false, 'secure'=>false, 'http-only'=>true ); /** * This is a true-false flag about whether session ID should be regenerated. This can be sent by * the system that uses the Session Handler at any time before sessions are commited. Wave * Framework uses this to regenerate cookies when it detects the cookie lifetime is about to end. */ public $regenerateId=false; /** * This tells Wave Framework to remove the old cookie if ID is being regenerated. */ public $regenerateRemoveOld=true; /** * This holds connection to database link. This is WWW_Database class by default, if database * connection is used. Thus you can use these values to log session creation or entirely replace * filesystem specific session creation with your own. */ private $databaseConnection=false; /** * This holds the cookie folder for the session. This is where the cookie will be stored in the * filesystem. */ private $cookieFolder=false; /** * This holds whether sessions are actually committed or not. This is set to true when Test Suite is run. */ private $noCommit=false; /** * Construction method of Session Handler takes two parameters. One for session name and another * for database connection link to (preferably) WWW_Database class. Construction also starts * sessions automatically if it detects that the user agent has provided a session cookie with * a value. * * @param string $sessionName session and cookie name * @param integer $sessionLifetime how long sessions last * @param boolean|object $databaseConnection database object * @param boolean $noCommit whether databases will actually be commited * @return WWW_Sessions */ public function __construct($sessionName='PHPSESSID',$sessionLifetime=0,$databaseConnection=false,$noCommit=false){ // This loads the same database connection that is loaded by Data and API Handlers if // the settings are used in Configuration file. Database is not used by Session Handler // by default, but it can be used for distributed database sessions. $this->databaseConnection=$databaseConnection; // Session name is what will be set as cookie name $this->sessionName=$sessionName; // Session name is what will be set as cookie name $this->noCommit=$noCommit; // Handler will attempt to load session data if session cookie is sent by the user agent if(isset($_COOKIE[$this->sessionName])){ $this->sessionOpen($this->sessionName,$sessionLifetime); } } /** * This method opens sessions. It checks if a previous session is active and closes it. This * method functions differently based on if session cookie is set or not. If session cookie * is set, then it attempts to populate session data from session storage if it finds a matching * session. If not, then it generates a new session ID and clears the session data array. * * @param boolean|string $sessionName if session name is sent, then sessions will be started with this name. * @param integer $sessionLifetime the age of token file to be still considered a valid token * @return boolean */ public function sessionOpen($sessionName=false,$sessionLifetime=0){ // Assigning session name, if sent if($sessionName){ // New session name based on the value sent $this->sessionName=$sessionName; } // If another session is already running, it is commited if($this->sessionId){ // This stores session data in filesystem or in database $this->sessionCommit(); // Defaults for regenerate values for the newly opened session $this->regenerateId=false; $this->regenerateRemoveOld=true; $this->sessionData=array(); } // If session cookie exists, then session data will be loaded if(isset($_COOKIE[$this->sessionName])){ // Making sure that the session does not include any dangerous characters before it is used to load session data $this->sessionId=preg_replace('/[^0-9a-z]/i','',$_COOKIE[$this->sessionName]); // Session storage address is based on session ID name in the filesystem $this->cookieFolder=__ROOT__.'filesystem'.DIRECTORY_SEPARATOR.'sessions'.DIRECTORY_SEPARATOR.substr($this->sessionId,0,2).DIRECTORY_SEPARATOR; // If file exists and is not older than the maximum allowed age for a session storage file, then session data is loaded from that file if(file_exists($this->cookieFolder.$this->sessionId.'.tmp') && ($sessionLifetime==0 || filemtime($this->cookieFolder.$this->sessionId.'.tmp')>($_SERVER['REQUEST_TIME']-$sessionLifetime))){ // Loading actual session data and casting the data to array $this->sessionData=json_decode(file_get_contents($this->cookieFolder.$this->sessionId.'.tmp'),true); // Updating the last-modified time of the session storage file if(!$this->noCommit){ touch($this->cookieFolder.$this->sessionId.'.tmp'); } } else { // Since session cookie was found, but there was no session storage anymore, // the session cookie is assigned to be regenerated $this->regenerateId=true; $this->regenerateRemoveOld=true; // Data array is also emptied $this->sessionData=array(); } } // Sessions are started return true; } /** * This method commits sessions to database. It uses current session configuration and * also creates or removes session cookies, if this is necessary. Wave Framework calls * this method ONLY if sessions have actually changed or if they are assigned to be * regenerated. This method is not the place to track if sessions are still active (use * the sessionOpen() method for that). * * @return boolean */ public function sessionCommit(){ // If session data is empty, then session storage is deleted and session cookie // is removed if the user agent has one set. if(isset($_COOKIE[$this->sessionName]) && empty($this->sessionData)){ // This is only done if sessions are actually commited and not just simulated if(!$this->noCommit){ // Removing the session storage file if(file_exists($this->cookieFolder.$this->sessionId.'.tmp')){ unlink($this->cookieFolder.$this->sessionId.'.tmp'); } // Removing session cookie if(isset($_COOKIE[$this->sessionName])){ setcookie($this->sessionName,false,1,$this->sessionCookie['path'],$this->sessionCookie['domain'],$this->sessionCookie['secure'],$this->sessionCookie['http-only']); } } } else { // This is only done if sessions are actually commited and not just simulated if(!$this->noCommit){ // If there is no session cookie from the user agent or it is set to be regenerated if(!isset($_COOKIE[$this->sessionName]) || $this->regenerateId){ // If the old storage is assigned to be deleted if($this->regenerateRemoveOld){ if(file_exists($this->cookieFolder.$this->sessionId.'.tmp')){ unlink($this->cookieFolder.$this->sessionId.'.tmp'); } } // Generating a new session ID $this->sessionId=$this->generateSessionId(); // Session storage address is based on session ID name in the filesystem $this->cookieFolder=__ROOT__.'filesystem'.DIRECTORY_SEPARATOR.'sessions'.DIRECTORY_SEPARATOR.substr($this->sessionId,0,2).DIRECTORY_SEPARATOR; // If lifetime is set to 0, then cookie will last as long as session lasts in browser if($this->sessionCookie['lifetime']==0){ setcookie($this->sessionName,$this->sessionId,0,$this->sessionCookie['path'],$this->sessionCookie['domain'],$this->sessionCookie['secure'],$this->sessionCookie['http-only']); } else { setcookie($this->sessionName,$this->sessionId,(time()+$this->sessionCookie['lifetime']),$this->sessionCookie['path'],$this->sessionCookie['domain'],$this->sessionCookie['secure'],$this->sessionCookie['http-only']); } } // If session cookie storage subfolder does not exist, then the handler creates it if(!is_dir($this->cookieFolder)){ if(!mkdir($this->cookieFolder,0755)){ trigger_error('Cannot create session folder in '.$this->cookieFolder,E_USER_ERROR); } } // Session data is stored in session storage if(!file_put_contents($this->cookieFolder.$this->sessionId.'.tmp',json_encode($this->sessionData))){ trigger_error('Cannot write session data to /filesystem/sessions/',E_USER_ERROR); } } } // Commit complete return true; } /** * This function simply sets session cookie configuration to Session Handler. This * is used by Session Handler to set session cookies. * * @param array $settings array of session cookie configuration * @return boolean */ public function sessionCookie($settings){ // Configuration must be an array if(is_array($settings)){ // Overloading the default cookie session data with the new settings $this->sessionCookie=$settings+$this->sessionCookie; return true; } else { return false; } } /** * This method generates a new session ID value. By default the SHA-1 hash string is generated * from user IP, server host address, request unique ID, microtime() and a custom salt. * * @param string $salt used for salting session hash * @return string */ private function generateSessionId($salt=''){ // Salt is not sent by default in Wave Framework return sha1(__IP__.$_SERVER['HTTP_HOST'].(isset($_SERVER['UNIQUE_ID'])?$_SERVER['UNIQUE_ID']:uniqid('www',true)).microtime().$salt); } } ?>