<?php
/*
This file contains all the function definitions for the custom session
handler that uses an abstracted database using Metabase.
Last Modified: 2006-07-24
*/
if (defined('PSA_SESS_HANDLERS_INC')) return TRUE;
define('PSA_SESS_HANDLERS_INC',TRUE);
// let the server know that you want to set your session handling yourself.
// The manual is kind of funny with this. According to the ini_set page, this shouldn't
// work, but it does (and a user has posted that fact). However, I've also noticed this
// script working with session.save_handler = files. According to the
// session_set_save_handler page, it shouldn't - I added a note on this.
ini_set('session.save_handler','user');
// I don't like the idea of having stale sessions around. Having them removed may even
// enhance performance on the database table if it starts getting large. However, I don't
// think it is necessary to run it at 100 - unless you are _very_ paranoid.
ini_set('session.gc_probability','100');
// config file holds connection data
if(!defined('PSA_PATH')) define('PSA_PATH',dirname(__FILE__).'/..');
require_once PSA_PATH.'/include/config.php';
// the MDB include file
require_once 'MDB.php';
$PSA_SESS_SQL=FALSE; // MDB object to be used by sessions
// How long the sessions last. Defaults to the value in the php.ini file.
$PSA_SESS_LIFE=ini_get('session.gc_maxlifetime');
if(defined('PSA_SESS_DEBUG_FILE')) $psa_sess_fp=fopen(PSA_SESS_DEBUG_FILE,'a');
else $psa_sess_fp=NULL;
$PSA_SESS_SQL = &MDB::connect($PSA_SCR);
if(MDB::isError($PSA_SESS_SQL)){
if($psa_sess_fp){
fwrite($psa_sess_fp,' MDB Error: '.$PSA_SESS_SQL->getMessage()."\n");
}
return FALSE;
}
$PSA_SESS_SQL->setDatabase($PSA_SCR['database']);
if($psa_sess_fp) fwrite($psa_sess_fp,'Database Set to '.$PSA_SCR['database']."\n");
function sess_open(){
global $psa_sess_fp;
if($psa_sess_fp) fwrite($psa_sess_fp,'Open Session'."\n");
return TRUE;
}
function sess_close(){
global $psa_sess_fp;
if($psa_sess_fp) fwrite($psa_sess_fp,'Close Session'."\n");
return TRUE;
}
function sess_read($key){
global $psa_sess_fp, $PSA_SESS_SQL;
ob_start();
var_dump($PSA_SESS_SQL);
$tmp=ob_get_clean();
if($psa_sess_fp){
fwrite($psa_sess_fp,' MDB Dump: '.$tmp."\n");
}
$q='SELECT psa_sessions.value FROM psa_sessions WHERE psa_sessions.sesskey='.
$PSA_SESS_SQL->getTextValue($key).' AND psa_sessions.expiry > '.time();
if($psa_sess_fp){
fwrite($psa_sess_fp,' Read Session: '.$key."\n");
fwrite($psa_sess_fp,' '.$q."\n");
}
$result=$PSA_SESS_SQL->query($q);
if(MDB::isError($result)){
return FALSE;
}
if($PSA_SESS_SQL->numRows($result)){
$value=$PSA_SESS_SQL->fetch($result,0,0);
if($psa_sess_fp){
fwrite($psa_sess_fp,' Session Exists: '.$key."\n");
fwrite($psa_sess_fp,' Session Data: '.$value."\n");
}
return $value;
}else if($result){
if($psa_sess_fp) fwrite($psa_sess_fp,' No Session: '.$key."\n");
return '';
}else{
if($psa_sess_fp) fwrite($psa_sess_fp,' Error: '.$PSA_SESS_SQL->error()."\n");
return '';
}
}
function sess_write($key,$val){
global $psa_sess_fp, $PSA_SESS_SQL,$PSA_SESS_LIFE;
if($psa_sess_fp) fwrite($psa_sess_fp,' Write Session: '.$key."\n");
// Calculate the session end time
$expiry=time()+$PSA_SESS_LIFE;
$q='SELECT psa_sessions.sesskey FROM psa_sessions WHERE psa_sessions.sesskey='.$PSA_SESS_SQL->getTextValue($key);
if($psa_sess_fp){
fwrite($psa_sess_fp,' Check Session: '.$key."\n");
fwrite($psa_sess_fp,' Session Data: '.$val."\n");
fwrite($psa_sess_fp,' '.$q."\n");
}
$result=$PSA_SESS_SQL->query($q);
if(MDB::isError($result)){
if($psa_sess_fp) fwrite($psa_sess_fp,' Error: '.$PSA_SESS_SQL->error()."\n");
return FALSE;
}
if($PSA_SESS_SQL->numRows($result)){
$q='UPDATE psa_sessions SET psa_sessions.expiry='.$expiry.', psa_sessions.value='.$PSA_SESS_SQL->getTextValue($val).
' WHERE psa_sessions.sesskey='.$PSA_SESS_SQL->getTextValue($key).' AND psa_sessions.expiry > '.time();
if($psa_sess_fp){
fwrite($psa_sess_fp,' Key Exists: '.$key."\n");
fwrite($psa_sess_fp,' '.$q."\n");
}
$result=$PSA_SESS_SQL->query($q);
if($result && $PSA_SESS_SQL->affectedRows($result)){
if($psa_sess_fp){
fwrite($psa_sess_fp,' Session Data: '.$val."\n");
fwrite($psa_sess_fp,' Session Expire: '.$expiry."\n");
}
return strlen($val);
}else if($result){
if($psa_sess_fp) fwrite($psa_sess_fp,' Session has expired: '.$PSA_SESS_SQL->error()."\n");
return FALSE;
}else{
if($psa_sess_fp) fwrite($psa_sess_fp,' Error: '.$PSA_SESS_SQL->error()."\n");
return FALSE;
}
}else{
$q='INSERT INTO psa_sessions (sesskey, expiry, value) VALUES('.$PSA_SESS_SQL->getTextValue($key).','.$expiry.
','.$PSA_SESS_SQL->getTextValue($val).')';
if($psa_sess_fp){
fwrite($psa_sess_fp,' Non-existant session'."\n");
fwrite($psa_sess_fp,' New Key: '.$key."\n");
fwrite($psa_sess_fp,' '.$q."\n");
}
$result=$PSA_SESS_SQL->query($q);
if(MDB::isError($result)){
return FALSE;
}
if($PSA_SESS_SQL->affectedRows($result)){
if($psa_sess_fp) fwrite($psa_sess_fp,' Session Data: '.$val."\n");
return strlen($val);
}else{
if($psa_sess_fp) fwrite($psa_sess_fp,' Error: '.$PSA_SESS_SQL->error()."\n");
return FALSE;
}
}
}
function sess_destroy($sess_id){
global $psa_sess_fp, $PSA_SESS_SQL;
// delete the existing session
$q='DELETE FROM psa_sessions WHERE psa_sessions.sesskey='.$PSA_SESS_SQL->getTextValue($sess_id);
if($psa_sess_fp){
fwrite($psa_sess_fp,' Destroy session'."\n");
fwrite($psa_sess_fp,' '.$q."\n");
}
$result=$PSA_SESS_SQL->query($q);
if(MDB::isError($result)){
return FALSE;
}
return TRUE;
}
function sess_gc(){
global $psa_sess_fp, $PSA_SESS_SQL;
// delete all expired sessions
$q='DELETE FROM psa_sessions WHERE psa_sessions.expiry < '.time();
if($psa_sess_fp){
fwrite($psa_sess_fp,' Garbage Collection'."\n");
fwrite($psa_sess_fp,' '.$q."\n");
}
$result=$PSA_SESS_SQL->query($q);
if(MDB::isError($result)){
return FALSE;
}
if($PSA_SESS_SQL->affectedRows($result)){
$retVal=$PSA_SESS_SQL->affectedRows($result);
if($psa_sess_fp) fwrite($psa_sess_fp,' Affected Rows: '.$retVal."\n");
return $retVal;
}
}
session_set_save_handler('sess_open','sess_close','sess_read','sess_write','sess_destroy','sess_gc');
?>