<?php

require_once 'PEAR.php';
require_once 
'DB.php';

// The pc_DB_Session code was taken verbatim from
// The PHP Cookbook by David Sklar & Adam Trachtenberg,
// O'Reilly & Assoc., 2003
class pc_DB_Session extends PEAR {

   var 
$_gc_maxlifetime;
   var 
$_table;
   var 
$_dbh;
   var 
$_prh_read;
   var 
$_connected false;
   var 
$error null;

   
/**
    * Constructor
    */
   
function pc_DB_Session($dsn null) {
      if ( 
is_null$dsn ) ) {
         
$this->error PEAR::raiseError('No DSN specified');
         return;
      }

      
$this->_gc_maxlifetime ini_get('session.gc_maxlifetime');
      
// Sessions last for a day unless otherwise specified.
      
if (! $this->_gc_maxlifetime) {
         
$this->_gc_maxlifetime 86400;
      }

      
$this->_table ini_get('session.save_path');
      if ((! 
$this->_table) || ('/tmp' == $this->_table)) {
         
$this->_table 'php_session';
      }

      
$this->_dbh DB::connect($dsn);
      if ( 
DB::isError$this->_dbh ) ) {
         
$this->error $this->_dbh;
         return;
      }

      
$this->_prh_read $this->_dbh->prepare(
         
"SELECT data FROM $this->_table WHERE id LIKE ? AND last_access >= ?");
      if (
DB::isError($this->_prh_read)) {
         
$this->error $this->_prh_read;
         return;
      }

      if (! 
session_set_save_handler(array( &$this,'_open'),
                                     array( &
$this,'_close'),
                                     array( &
$this,'_read'),
                                     array( &
$this,'_write'),
                                     array( &
$this,'_destroy'),
                                     array( &
$this,'_gc')))
      {
         
$this->error PEAR::raiseError('session_set_save_handler() failed');
         return;
      }

      return 
$this->_connected true;
   }

   function 
_open() {
      return 
$this->_connected;
   }

   function 
_close() {
      return 
$this->_connected;
   }

   function 
_read($id) {
      if (! 
$this->_connected) { return false; }
      
$sth =
         
$this->_dbh->execute($this->_prh_read,
                              array( 
$idtime() - $this->_gc_maxlifetime ));
      if (
DB::isError($sth)) {
         
$this->error $sth;
         return 
'';
      } else {
         if ((
$sth->numRows() == 1) &&
             (
$ar $sth->fetchRow(DB_FETCHMODE_ORDERED)))
         {
            return 
$ar[0];
         } else {
            return 
'';
         }
      }
   }

   function 
_write$id$data ) {
      
$sth $this->_dbh->query(
         
"REPLACE INTO $this->_table (id,data,last_access) VALUES (?,?,?)",
         array( 
$id$datatime() ));
      if (
DB::isError($sth)) {
         
$this->error $sth;
         return 
false;
      } else {
         return 
true;
      }
   }

   function 
_destroy($id) {
      
$sth $this->_dbh->query(
         
"DELETE FROM $this->_table WHERE id LIKE ?",
         array(
$id));
      if (
DB::isError($sth)) {
         
$this->error $sth;
         return 
false;
      } else {
         return 
true;
      }
   }

   function 
_gc($maxlifetime) {
      
$sth $this->_dbh->query(
         
"DELETE FROM $this->_table WHERE last_access < ?",
         array(
time() - $maxlifetime));

      if (
DB::isError($sth)) {
         
$this->error $sth;
         return 
false;
      } else {
         return 
true;
      }
   }
}

?>