| 
<?php/**
 * A minimal sessions++ stack component
 * Does nothing except calling the next in the chain
 */
 if (!defined('E_USER_DEBUG')) {
 define('E_USER_DEBUG',0);
 }
 class stackSess {
 public $shStackNext;
 /**
 * Its important for all tiers in the stack to know the
 * last mod time on the session. The $lastAccess member
 * variable MUST be populated by the
 * read method
 */
 public $lastAccess;
 /**
 * allows the injection of a custom logger
 * %%%% needs update to PSR
 */
 public $logger;
 
 function __construct($shNext=false)
 {
 if (false!==$shNext) {
 $this->addNext($shNext);
 }
 }
 
 function setLogger($logr)
 {
 $this->logger=$logr;
 $this->logit(get_class($this) . "::setLogger() installed logger",E_USER_DEBUG);
 }
 
 function lastAccessed($lastAccess=false)
 {
 if ($this->shNext && is_callable(array($this->shNext, 'lastAccessed'))) {
 $lastAccess=$this->shNext->lastAccessed($lastAccess);
 }
 return $lastAccess;
 }
 function install()
 {
 $this->logit(get_class($this) . "::install", E_USER_DEBUG);
 if (version_compare(PHP_VERSION, '5.5.1') >=0) {
 return session_set_save_handler(
 array($this, 'open'),
 array($this, 'close'),
 array($this, 'read'),
 array($this, 'write'),
 array($this, 'destroy'),
 array($this, 'gc'),
 array($this, 'create_sid')
 );
 } else {
 $this->logit(get_class($this) . "::install() This version of PHP does not have a hook for create_sid", E_USER_NOTICE);
 return session_set_save_handler(
 array($this, 'open'),
 array($this, 'close'),
 array($this, 'read'),
 array($this, 'write'),
 array($this, 'destroy'),
 array($this, 'gc') /*,
 array($this, 'create_sid')*/
 );
 }
 }
 
 function logit($msg)
 {
 if (is_callable($this->logger)) {
 return call_user_func($this->logger,$msg);
 }
 return false;
 }
 
 function close ()
 {
 if ($this->shStackNext) {
 return $this->shStackNext->close();
 } else {
 return false;
 }
 }
 function destroy($session_id)
 {
 if ($this->shStackNext) {
 return $this->shStackNext->destroy($session_id);
 } else {
 return false;
 }
 }
 function gc($maxlifetime)
 {
 if ($this->shStackNext) {
 return $this->shStackNext->gc($maxlifetime);
 } else {
 return false;
 }
 }
 function open($save_path, $name)
 {
 if ($this->shStackNext) {
 return $this->shStackNext->open($save_path, $name);
 } else {
 $this->logit(get_class($this) . "::open() No storage handler at botton of session stack!", E_USER_ERROR);
 return false;
 }
 }
 function read($session_id)
 {
 if ($this->shStackNext) {
 return $this->shStackNext->read($session_id);
 } else {
 return $session_str;
 }
 }
 function write($session_id, $session_data)
 {
 if ($this->shStackNext) {
 return $this->shStackNext->write($session_id, $session_data);
 } else {
 return $session_str;
 }
 }
 function create_sid($newlyCreatedSid=false)
 {
 $this->logit(get_class($this) . "::create_sid() called", E_USER_DEBUG);
 if (is_callable(array($this->shStackNext,'create_sid'))) {
 // we always send down the stack
 $newlyCreatedSid=$this->shStackNext->create_sid($newlyCreatedSid);
 } else if (false==$newlyCreatedSid) {
 $newlyCreatedSid=uniqid('', true);
 }
 return $newlyCreatedSid;
 }
 /**
 * Adds a session++ handler below this one
 *
 */
 function addNext($shNext)
 {
 if (false==$shNext || is_callable(array($shNext, 'gc'))) {
 $this->shStackNext=$shNext;
 } else {
 trigger_error("Each entry in the session stack must have sessp as a parent", E_USER_ERROR);
 }
 }
 /**
 * returns the class names in the stack of session handlers
 * below (and including) this one (deepest first
 */
 function getStack()
 {
 if ($this->shStackNext) {
 $stack=$this->shStackNext->getStack();
 } else {
 $stack=array();
 }
 array_push($stack,array(
 'class'=>get_class(),
 'instance'=>$this
 ));
 return $stack;
 }
 }
 
 |