PageRenderTime 70ms CodeModel.GetById 44ms app.highlight 20ms RepoModel.GetById 1ms app.codeStats 0ms

/include/adodb5/session/adodb-session2.php

http://opixido-ocms.googlecode.com/
PHP | 949 lines | 586 code | 152 blank | 211 comment | 120 complexity | 59a37a88c2436e0938cdab41a4daa579 MD5 | raw file
  1<?php
  2
  3
  4/*
  5V5.16 26 Mar 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
  6         Contributed by Ross Smith (adodb@netebb.com). 
  7  Released under both BSD license and Lesser GPL library license.
  8  Whenever there is any discrepancy between the two licenses,
  9  the BSD license will take precedence.
 10	  Set tabs to 4 for best viewing.
 11	  
 12
 13*/
 14
 15/*
 16
 17CREATE Table SCripts
 18
 19Oracle
 20======
 21
 22CREATE TABLE SESSIONS2
 23(
 24  SESSKEY    VARCHAR2(48 BYTE)                  NOT NULL,
 25  EXPIRY     DATE                               NOT NULL,
 26  EXPIREREF  VARCHAR2(200 BYTE),
 27  CREATED    DATE                               NOT NULL,
 28  MODIFIED   DATE                               NOT NULL,
 29  SESSDATA   CLOB,
 30  PRIMARY KEY(SESSKEY)
 31);
 32
 33
 34CREATE INDEX SESS2_EXPIRY ON SESSIONS2(EXPIRY);
 35CREATE UNIQUE INDEX SESS2_PK ON SESSIONS2(SESSKEY);
 36CREATE INDEX SESS2_EXP_REF ON SESSIONS2(EXPIREREF);
 37
 38
 39 
 40 MySQL
 41 =====
 42 
 43CREATE TABLE sessions2(
 44	sesskey VARCHAR( 64 ) NOT NULL DEFAULT '',
 45	expiry TIMESTAMP NOT NULL ,
 46	expireref VARCHAR( 250 ) DEFAULT '',
 47	created TIMESTAMP NOT NULL ,
 48	modified TIMESTAMP NOT NULL ,
 49	sessdata LONGTEXT DEFAULT '',
 50	PRIMARY KEY ( sesskey ) ,
 51	INDEX sess2_expiry( expiry ),
 52	INDEX sess2_expireref( expireref )
 53)
 54
 55
 56*/
 57
 58if (!defined('_ADODB_LAYER')) {
 59	require realpath(dirname(__FILE__) . '/../adodb.inc.php');
 60}
 61
 62if (defined('ADODB_SESSION')) return 1;
 63
 64define('ADODB_SESSION', dirname(__FILE__));
 65define('ADODB_SESSION2', ADODB_SESSION);
 66
 67/* 
 68	Unserialize session data manually. See http://phplens.com/lens/lensforum/msgs.php?id=9821 
 69	
 70	From Kerr Schere, to unserialize session data stored via ADOdb. 
 71	1. Pull the session data from the db and loop through it. 
 72	2. Inside the loop, you will need to urldecode the data column. 
 73	3. After urldecode, run the serialized string through this function:
 74
 75*/
 76function adodb_unserialize( $serialized_string ) 
 77{
 78	$variables = array( );
 79	$a = preg_split( "/(\w+)\|/", $serialized_string, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE );
 80	for( $i = 0; $i < count( $a ); $i = $i+2 ) {
 81		$variables[$a[$i]] = unserialize( $a[$i+1] );
 82	}
 83	return( $variables );
 84}
 85
 86/*
 87	Thanks Joe Li. See http://phplens.com/lens/lensforum/msgs.php?id=11487&x=1
 88	Since adodb 4.61.
 89*/
 90function adodb_session_regenerate_id() 
 91{
 92	$conn = ADODB_Session::_conn();
 93	if (!$conn) return false;
 94
 95	$old_id = session_id();
 96	if (function_exists('session_regenerate_id')) {
 97		session_regenerate_id();
 98	} else {
 99		session_id(md5(uniqid(rand(), true)));
100		$ck = session_get_cookie_params();
101		setcookie(session_name(), session_id(), false, $ck['path'], $ck['domain'], $ck['secure']);
102		//@session_start();
103	}
104	$new_id = session_id();
105	$ok = $conn->Execute('UPDATE '. ADODB_Session::table(). ' SET sesskey='. $conn->qstr($new_id). ' WHERE sesskey='.$conn->qstr($old_id));
106	
107	/* it is possible that the update statement fails due to a collision */
108	if (!$ok) {
109		session_id($old_id);
110		if (empty($ck)) $ck = session_get_cookie_params();
111		setcookie(session_name(), session_id(), false, $ck['path'], $ck['domain'], $ck['secure']);
112		return false;
113	}
114	
115	return true;
116}
117
118/*
119    Generate database table for session data
120    @see http://phplens.com/lens/lensforum/msgs.php?id=12280
121    @return 0 if failure, 1 if errors, 2 if successful.
122	@author Markus Staab http://www.public-4u.de
123*/
124function adodb_session_create_table($schemaFile=null,$conn = null)
125{
126    // set default values
127    if ($schemaFile===null) $schemaFile = ADODB_SESSION . '/session_schema2.xml';
128    if ($conn===null) $conn = ADODB_Session::_conn();
129
130	if (!$conn) return 0;
131
132    $schema = new adoSchema($conn);
133    $schema->ParseSchema($schemaFile);
134    return $schema->ExecuteSchema();
135}
136
137/*!
138	\static
139*/
140class ADODB_Session {
141	/////////////////////
142	// getter/setter methods
143	/////////////////////
144	
145	/*
146	
147	function Lock($lock=null)
148	{
149	static $_lock = false;
150	
151		if (!is_null($lock)) $_lock = $lock;
152		return $lock;
153	}
154	*/
155	/*!
156	*/
157	static function driver($driver = null) 
158	{
159		static $_driver = 'mysql';
160		static $set = false;
161
162		if (!is_null($driver)) {
163			$_driver = trim($driver);
164			$set = true;
165		} elseif (!$set) {
166			// backwards compatibility
167			if (isset($GLOBALS['ADODB_SESSION_DRIVER'])) {
168				return $GLOBALS['ADODB_SESSION_DRIVER'];
169			}
170		}
171
172		return $_driver;
173	}
174
175	/*!
176	*/
177	static function host($host = null) {
178		static $_host = 'localhost';
179		static $set = false;
180
181		if (!is_null($host)) {
182			$_host = trim($host);
183			$set = true;
184		} elseif (!$set) {
185			// backwards compatibility
186			if (isset($GLOBALS['ADODB_SESSION_CONNECT'])) {
187				return $GLOBALS['ADODB_SESSION_CONNECT'];
188			}
189		}
190
191		return $_host;
192	}
193
194	/*!
195	*/
196	static function user($user = null) 
197	{
198		static $_user = 'root';
199		static $set = false;
200
201		if (!is_null($user)) {
202			$_user = trim($user);
203			$set = true;
204		} elseif (!$set) {
205			// backwards compatibility
206			if (isset($GLOBALS['ADODB_SESSION_USER'])) {
207				return $GLOBALS['ADODB_SESSION_USER'];
208			}
209		}
210
211		return $_user;
212	}
213
214	/*!
215	*/
216	static function password($password = null) 
217	{
218		static $_password = '';
219		static $set = false;
220
221		if (!is_null($password)) {
222			$_password = $password;
223			$set = true;
224		} elseif (!$set) {
225			// backwards compatibility
226			if (isset($GLOBALS['ADODB_SESSION_PWD'])) {
227				return $GLOBALS['ADODB_SESSION_PWD'];
228			}
229		}
230
231		return $_password;
232	}
233
234	/*!
235	*/
236	static function database($database = null) 
237	{
238		static $_database = '';
239		static $set = false;
240		
241		if (!is_null($database)) {
242			$_database = trim($database);
243			$set = true;
244		} elseif (!$set) {
245			// backwards compatibility
246			if (isset($GLOBALS['ADODB_SESSION_DB'])) {
247				return $GLOBALS['ADODB_SESSION_DB'];
248			}
249		}
250		return $_database;
251	}
252
253	/*!
254	*/
255	static function persist($persist = null) 
256	{
257		static $_persist = true;
258
259		if (!is_null($persist)) {
260			$_persist = trim($persist);
261		}
262
263		return $_persist;
264	}
265
266	/*!
267	*/
268	static function lifetime($lifetime = null) 
269	{
270		static $_lifetime;
271		static $set = false;
272
273		if (!is_null($lifetime)) {
274			$_lifetime = (int) $lifetime;
275			$set = true;
276		} elseif (!$set) {
277			// backwards compatibility
278			if (isset($GLOBALS['ADODB_SESS_LIFE'])) {
279				return $GLOBALS['ADODB_SESS_LIFE'];
280			}
281		}
282		if (!$_lifetime) {
283			$_lifetime = ini_get('session.gc_maxlifetime');
284			if ($_lifetime <= 1) {
285				// bug in PHP 4.0.3 pl 1  -- how about other versions?
286				//print "<h3>Session Error: PHP.INI setting <i>session.gc_maxlifetime</i>not set: $lifetime</h3>";
287				$_lifetime = 1440;
288			}
289		}
290
291		return $_lifetime;
292	}
293
294	/*!
295	*/
296	static function debug($debug = null) 
297	{
298		static $_debug = false;
299		static $set = false;
300
301		if (!is_null($debug)) {
302			$_debug = (bool) $debug;
303
304			$conn = ADODB_Session::_conn();
305			if ($conn) {
306				#$conn->debug = $_debug;
307			}
308			$set = true;
309		} elseif (!$set) {
310			// backwards compatibility
311			if (isset($GLOBALS['ADODB_SESS_DEBUG'])) {
312				return $GLOBALS['ADODB_SESS_DEBUG'];
313			}
314		}
315
316		return $_debug;
317	}
318
319	/*!
320	*/
321	static function expireNotify($expire_notify = null) 
322	{
323		static $_expire_notify;
324		static $set = false;
325
326		if (!is_null($expire_notify)) {
327			$_expire_notify = $expire_notify;
328			$set = true;
329		} elseif (!$set) {
330			// backwards compatibility
331			if (isset($GLOBALS['ADODB_SESSION_EXPIRE_NOTIFY'])) {
332				return $GLOBALS['ADODB_SESSION_EXPIRE_NOTIFY'];
333			}
334		}
335
336		return $_expire_notify;
337	}
338
339	/*!
340	*/
341	static function table($table = null) 
342	{
343		static $_table = 'sessions2';
344		static $set = false;
345
346		if (!is_null($table)) {
347			$_table = trim($table);
348			$set = true;
349		} elseif (!$set) {
350			// backwards compatibility
351			if (isset($GLOBALS['ADODB_SESSION_TBL'])) {
352				return $GLOBALS['ADODB_SESSION_TBL'];
353			}
354		}
355
356		return $_table;
357	}
358
359	/*!
360	*/
361	static function optimize($optimize = null) 
362	{
363		static $_optimize = false;
364		static $set = false;
365
366		if (!is_null($optimize)) {
367			$_optimize = (bool) $optimize;
368			$set = true;
369		} elseif (!$set) {
370			// backwards compatibility
371			if (defined('ADODB_SESSION_OPTIMIZE')) {
372				return true;
373			}
374		}
375
376		return $_optimize;
377	}
378
379	/*!
380	*/
381	static function syncSeconds($sync_seconds = null) {
382		//echo ("<p>WARNING: ADODB_SESSION::syncSeconds is longer used, please remove this function for your code</p>");
383		
384		return 0;
385	}
386
387	/*!
388	*/
389	static function clob($clob = null) {
390		static $_clob = false;
391		static $set = false;
392
393		if (!is_null($clob)) {
394			$_clob = strtolower(trim($clob));
395			$set = true;
396		} elseif (!$set) {
397			// backwards compatibility
398			if (isset($GLOBALS['ADODB_SESSION_USE_LOBS'])) {
399				return $GLOBALS['ADODB_SESSION_USE_LOBS'];
400			}
401		}
402
403		return $_clob;
404	}
405
406	/*!
407	*/
408	static function dataFieldName($data_field_name = null) {
409		//echo ("<p>WARNING: ADODB_SESSION::dataFieldName() is longer used, please remove this function for your code</p>");
410		return '';
411	}
412
413	/*!
414	*/
415	static function filter($filter = null) {
416		static $_filter = array();
417
418		if (!is_null($filter)) {
419			if (!is_array($filter)) {
420				$filter = array($filter);
421			}
422			$_filter = $filter;
423		}
424
425		return $_filter;
426	}
427
428	/*!
429	*/
430	static function encryptionKey($encryption_key = null) {
431		static $_encryption_key = 'CRYPTED ADODB SESSIONS ROCK!';
432
433		if (!is_null($encryption_key)) {
434			$_encryption_key = $encryption_key;
435		}
436
437		return $_encryption_key;
438	}
439
440	/////////////////////
441	// private methods
442	/////////////////////
443
444	/*!
445	*/
446	static function _conn($conn=null) {
447		return isset($GLOBALS['ADODB_SESS_CONN']) ? $GLOBALS['ADODB_SESS_CONN'] : false;
448	}
449
450	/*!
451	*/
452	static function _crc($crc = null) {
453		static $_crc = false;
454
455		if (!is_null($crc)) {
456			$_crc = $crc;
457		}
458
459		return $_crc;
460	}
461
462	/*!
463	*/
464	static function _init() {
465		session_module_name('user');
466		session_set_save_handler(
467			array('ADODB_Session', 'open'),
468			array('ADODB_Session', 'close'),
469			array('ADODB_Session', 'read'),
470			array('ADODB_Session', 'write'),
471			array('ADODB_Session', 'destroy'),
472			array('ADODB_Session', 'gc')
473		);
474	}
475
476
477	/*!
478	*/
479	static function _sessionKey() {
480		// use this function to create the encryption key for crypted sessions
481		// crypt the used key, ADODB_Session::encryptionKey() as key and session_id() as salt
482		return crypt(ADODB_Session::encryptionKey(), session_id());
483	}
484
485	/*!
486	*/
487	static function _dumprs(&$rs) {
488		$conn	= ADODB_Session::_conn();
489		$debug	= ADODB_Session::debug();
490
491		if (!$conn) {
492			return;
493		}
494
495		if (!$debug) {
496			return;
497		}
498
499		if (!$rs) {
500			echo "<br />\$rs is null or false<br />\n";
501			return;
502		}
503
504		//echo "<br />\nAffected_Rows=",$conn->Affected_Rows(),"<br />\n";
505
506		if (!is_object($rs)) {
507			return;
508		}
509		$rs = $conn->_rs2rs($rs);
510		
511		require_once ADODB_SESSION.'/../tohtml.inc.php';
512		rs2html($rs);
513		$rs->MoveFirst();
514	}
515
516	/////////////////////
517	// public methods
518	/////////////////////
519	
520	static function config($driver, $host, $user, $password, $database=false,$options=false)
521	{
522		ADODB_Session::driver($driver);
523		ADODB_Session::host($host);
524		ADODB_Session::user($user);
525		ADODB_Session::password($password);
526		ADODB_Session::database($database);
527		
528		if ($driver == 'oci8' || $driver == 'oci8po') $options['lob'] = 'CLOB';
529		
530		if (isset($options['table'])) ADODB_Session::table($options['table']);
531		if (isset($options['lob'])) ADODB_Session::clob($options['lob']);
532		if (isset($options['debug'])) ADODB_Session::debug($options['debug']);
533	}
534
535	/*!
536		Create the connection to the database.
537
538		If $conn already exists, reuse that connection
539	*/
540	static function open($save_path, $session_name, $persist = null) 
541	{
542		$conn = ADODB_Session::_conn();
543
544		if ($conn) {
545			return true;
546		}
547
548		$database	= ADODB_Session::database();
549		$debug		= ADODB_Session::debug();
550		$driver		= ADODB_Session::driver();
551		$host		= ADODB_Session::host();
552		$password	= ADODB_Session::password();
553		$user		= ADODB_Session::user();
554
555		if (!is_null($persist)) {
556			ADODB_Session::persist($persist);
557		} else {
558			$persist = ADODB_Session::persist();
559		}
560
561# these can all be defaulted to in php.ini
562#		assert('$database');
563#		assert('$driver');
564#		assert('$host');
565
566		$conn = ADONewConnection($driver);
567
568		if ($debug) {
569			$conn->debug = true;		
570			ADOConnection::outp( " driver=$driver user=$user db=$database ");
571		}
572		
573		if (empty($conn->_connectionID)) { // not dsn
574			if ($persist) {
575				switch($persist) {
576				default:
577				case 'P': $ok = $conn->PConnect($host, $user, $password, $database); break;
578				case 'C': $ok = $conn->Connect($host, $user, $password, $database); break;
579				case 'N': $ok = $conn->NConnect($host, $user, $password, $database); break;
580				}
581			} else {
582				$ok = $conn->Connect($host, $user, $password, $database);
583			}
584		}
585
586		if ($ok) $GLOBALS['ADODB_SESS_CONN'] = $conn;
587		else
588			ADOConnection::outp('<p>Session: connection failed</p>', false);
589		
590
591		return $ok;
592	}
593
594	/*!
595		Close the connection
596	*/
597	static function close() 
598	{
599/*
600		$conn = ADODB_Session::_conn();
601		if ($conn) $conn->Close();
602*/
603		return true;
604	}
605
606	/*
607		Slurp in the session variables and return the serialized string
608	*/
609	static function read($key) 
610	{
611		$conn	= ADODB_Session::_conn();
612		$filter	= ADODB_Session::filter();
613		$table	= ADODB_Session::table();
614
615		if (!$conn) {
616			return '';
617		}
618
619		//assert('$table');
620
621		$binary = $conn->dataProvider === 'mysql' ? '/*! BINARY */' : '';
622	
623		global $ADODB_SESSION_SELECT_FIELDS;
624		if (!isset($ADODB_SESSION_SELECT_FIELDS)) $ADODB_SESSION_SELECT_FIELDS = 'sessdata';		
625		$sql = "SELECT $ADODB_SESSION_SELECT_FIELDS FROM $table WHERE sesskey = $binary ".$conn->Param(0)." AND expiry >= " . $conn->sysTimeStamp;		
626		
627		/* Lock code does not work as it needs to hold transaction within whole page, and we don't know if 
628		  developer has commited elsewhere... :(
629		 */
630		#if (ADODB_Session::Lock())
631		#	$rs = $conn->RowLock($table, "$binary sesskey = $qkey AND expiry >= " . time(), sessdata);
632		#else
633			$rs = $conn->Execute($sql, array($key));
634		//ADODB_Session::_dumprs($rs);
635		if ($rs) {
636			if ($rs->EOF) {
637				$v = '';
638			} else {
639				$v = reset($rs->fields);
640				$filter = array_reverse($filter);
641				foreach ($filter as $f) {
642					if (is_object($f)) {
643						$v = $f->read($v, ADODB_Session::_sessionKey());
644					}
645				}
646				$v = rawurldecode($v);
647			}
648
649			$rs->Close();
650
651			ADODB_Session::_crc(strlen($v) . crc32($v));
652			return $v;
653		}
654
655		return '';
656	}
657
658	/*!
659		Write the serialized data to a database.
660
661		If the data has not been modified since the last read(), we do not write.
662	*/
663	static function write($key, $oval) 
664	{
665	global $ADODB_SESSION_READONLY;
666	
667		if (!empty($ADODB_SESSION_READONLY)) return;
668		
669		$clob			= ADODB_Session::clob();
670		$conn			= ADODB_Session::_conn();
671		$crc			= ADODB_Session::_crc();
672		$debug			= ADODB_Session::debug();
673		$driver			= ADODB_Session::driver();
674		$expire_notify	= ADODB_Session::expireNotify();
675		$filter			= ADODB_Session::filter();
676		$lifetime		= ADODB_Session::lifetime();
677		$table			= ADODB_Session::table();
678	
679		if (!$conn) {
680			return false;
681		}
682		if ($debug) $conn->debug = 1;
683		$sysTimeStamp = $conn->sysTimeStamp;
684		
685		//assert('$table');
686
687		$expiry = $conn->OffsetDate($lifetime/(24*3600),$sysTimeStamp);
688
689		$binary = $conn->dataProvider === 'mysql' ? '/*! BINARY */' : '';
690
691		// crc32 optimization since adodb 2.1
692		// now we only update expiry date, thx to sebastian thom in adodb 2.32
693		if ($crc !== false && $crc == (strlen($oval) . crc32($oval))) {
694			if ($debug) {
695				echo '<p>Session: Only updating date - crc32 not changed</p>';
696			}
697			
698			$expirevar = '';
699			if ($expire_notify) {
700				$var = reset($expire_notify);
701				global $$var;
702				if (isset($$var)) {
703					$expirevar = $$var;
704				}
705			}
706			
707			
708			$sql = "UPDATE $table SET expiry = $expiry ,expireref=".$conn->Param('0').", modified = $sysTimeStamp WHERE $binary sesskey = ".$conn->Param('1')." AND expiry >= $sysTimeStamp";
709			$rs = $conn->Execute($sql,array($expirevar,$key));
710			return true;
711		}
712		$val = rawurlencode($oval);
713		foreach ($filter as $f) {
714			if (is_object($f)) {
715				$val = $f->write($val, ADODB_Session::_sessionKey());
716			}
717		}
718
719		$expireref = '';
720		if ($expire_notify) {
721			$var = reset($expire_notify);
722			global $$var;
723			if (isset($$var)) {
724				$expireref = $$var;
725			}
726		} 
727
728		if (!$clob) {	// no lobs, simply use replace()
729			$rs = $conn->Execute("SELECT COUNT(*) AS cnt FROM $table WHERE $binary sesskey = ".$conn->Param(0),array($key));
730			if ($rs) $rs->Close();
731					
732			if ($rs && reset($rs->fields) > 0) {
733				$sql = "UPDATE $table SET expiry=$expiry, sessdata=".$conn->Param(0).", expireref= ".$conn->Param(1).",modified=$sysTimeStamp WHERE sesskey = ".$conn->Param(2);
734				
735			} else {
736				$sql = "INSERT INTO $table (expiry, sessdata, expireref, sesskey, created, modified) 
737					VALUES ($expiry,".$conn->Param('0').", ". $conn->Param('1').", ".$conn->Param('2').", $sysTimeStamp, $sysTimeStamp)";
738			}
739			
740	
741			$rs = $conn->Execute($sql,array($val,$expireref,$key));
742			
743		} else {
744			// what value shall we insert/update for lob row?
745			switch ($driver) {
746				// empty_clob or empty_lob for oracle dbs
747				case 'oracle':
748				case 'oci8':
749				case 'oci8po':
750				case 'oci805':
751					$lob_value = sprintf('empty_%s()', strtolower($clob));
752					break;
753
754				// null for all other
755				default:
756					$lob_value = 'null';
757					break;
758			}
759			
760			$conn->StartTrans();
761			
762			$rs = $conn->Execute("SELECT COUNT(*) AS cnt FROM $table WHERE $binary sesskey = ".$conn->Param(0),array($key));
763					
764			if ($rs && reset($rs->fields) > 0) {
765				$sql = "UPDATE $table SET expiry=$expiry, sessdata=$lob_value, expireref= ".$conn->Param(0).",modified=$sysTimeStamp WHERE sesskey = ".$conn->Param('1');
766				
767			} else {
768				$sql = "INSERT INTO $table (expiry, sessdata, expireref, sesskey, created, modified) 
769					VALUES ($expiry,$lob_value, ". $conn->Param('0').", ".$conn->Param('1').", $sysTimeStamp, $sysTimeStamp)";
770			}
771			
772			$rs = $conn->Execute($sql,array($expireref,$key));
773			
774			$qkey = $conn->qstr($key);
775			$rs2 = $conn->UpdateBlob($table, 'sessdata', $val, " sesskey=$qkey", strtoupper($clob));
776			if ($debug) echo "<hr>",htmlspecialchars($oval), "<hr>";
777			$rs = @$conn->CompleteTrans();
778			
779			
780		}
781
782		if (!$rs) {
783			ADOConnection::outp('<p>Session Replace: ' . $conn->ErrorMsg() . '</p>', false);
784			return false;
785		}  else {
786			// bug in access driver (could be odbc?) means that info is not committed
787			// properly unless select statement executed in Win2000
788			if ($conn->databaseType == 'access') {
789				$sql = "SELECT sesskey FROM $table WHERE $binary sesskey = $qkey";
790				$rs = $conn->Execute($sql);
791				ADODB_Session::_dumprs($rs);
792				if ($rs) {
793					$rs->Close();
794				}
795			}
796		}/*
797		if (ADODB_Session::Lock()) {
798			$conn->CommitTrans();
799		}*/
800		return $rs ? true : false;
801	}
802
803	/*!
804	*/
805	static function destroy($key) {
806		$conn			= ADODB_Session::_conn();
807		$table			= ADODB_Session::table();
808		$expire_notify	= ADODB_Session::expireNotify();
809
810		if (!$conn) {
811			return false;
812		}
813		$debug			= ADODB_Session::debug();
814		if ($debug) $conn->debug = 1;
815		//assert('$table');
816
817		$qkey = $conn->quote($key);
818		$binary = $conn->dataProvider === 'mysql' ? '/*! BINARY */' : '';
819
820		if ($expire_notify) {
821			reset($expire_notify);
822			$fn = next($expire_notify);
823			$savem = $conn->SetFetchMode(ADODB_FETCH_NUM);
824			$sql = "SELECT expireref, sesskey FROM $table WHERE $binary sesskey = $qkey";
825			$rs = $conn->Execute($sql);
826			ADODB_Session::_dumprs($rs);
827			$conn->SetFetchMode($savem);
828			if (!$rs) {
829				return false;
830			}
831			if (!$rs->EOF) {
832				$ref = $rs->fields[0];
833				$key = $rs->fields[1];
834				//assert('$ref');
835				//assert('$key');
836				$fn($ref, $key);
837			}
838			$rs->Close();
839		}
840
841		$sql = "DELETE FROM $table WHERE $binary sesskey = $qkey";
842		$rs = $conn->Execute($sql);
843		if ($rs) {
844			$rs->Close();
845		}
846
847		return $rs ? true : false;
848	}
849
850	/*!
851	*/
852	static function gc($maxlifetime) 
853	{
854		$conn			= ADODB_Session::_conn();
855		$debug			= ADODB_Session::debug();
856		$expire_notify	= ADODB_Session::expireNotify();
857		$optimize		= ADODB_Session::optimize();
858		$table			= ADODB_Session::table();
859
860		if (!$conn) {
861			return false;
862		}
863
864
865		$debug			= ADODB_Session::debug();
866		if ($debug) {
867			$conn->debug = 1;
868			$COMMITNUM = 2;
869		} else {
870			$COMMITNUM = 20;
871		}
872		
873		//assert('$table');
874
875		$time = $conn->OffsetDate(-$maxlifetime/24/3600,$conn->sysTimeStamp);
876		$binary = $conn->dataProvider === 'mysql' ? '/*! BINARY */' : '';
877
878		if ($expire_notify) {
879			reset($expire_notify);
880			$fn = next($expire_notify);
881		} else {
882			$fn = false;
883		}
884		
885		$savem = $conn->SetFetchMode(ADODB_FETCH_NUM);
886		$sql = "SELECT expireref, sesskey FROM $table WHERE expiry < $time ORDER BY 2"; # add order by to prevent deadlock
887		$rs = $conn->SelectLimit($sql,1000);
888		if ($debug) ADODB_Session::_dumprs($rs);
889		$conn->SetFetchMode($savem);
890		if ($rs) {
891			$tr = $conn->hasTransactions;
892			if ($tr) $conn->BeginTrans();
893			$keys = array();
894			$ccnt = 0;
895			while (!$rs->EOF) {
896				$ref = $rs->fields[0];
897				$key = $rs->fields[1];
898				if ($fn) $fn($ref, $key);
899				$del = $conn->Execute("DELETE FROM $table WHERE sesskey=".$conn->Param('0'),array($key));
900				$rs->MoveNext();
901				$ccnt += 1;
902				if ($tr && $ccnt % $COMMITNUM == 0) {
903					if ($debug) echo "Commit<br>\n";
904					$conn->CommitTrans();
905					$conn->BeginTrans();
906				}
907			}
908			$rs->Close();
909			
910			if ($tr) $conn->CommitTrans();
911		}
912		
913
914		// suggested by Cameron, "GaM3R" <gamr@outworld.cx>
915		if ($optimize) {
916			$driver = ADODB_Session::driver();
917
918			if (preg_match('/mysql/i', $driver)) {
919				$sql = "OPTIMIZE TABLE $table";
920			}
921			if (preg_match('/postgres/i', $driver)) {
922				$sql = "VACUUM $table";
923			}
924			if (!empty($sql)) {
925				$conn->Execute($sql);
926			}
927		}
928
929		
930		return true;
931	}
932}
933
934ADODB_Session::_init();
935if (empty($ADODB_SESSION_READONLY))
936	register_shutdown_function('session_write_close');
937
938// for backwards compatability only
939function adodb_sess_open($save_path, $session_name, $persist = true) {
940	return ADODB_Session::open($save_path, $session_name, $persist);
941}
942
943// for backwards compatability only
944function adodb_sess_gc($t)
945{	
946	return ADODB_Session::gc($t);
947}
948
949?>