PageRenderTime 5ms CodeModel.GetById 18ms app.highlight 30ms RepoModel.GetById 1ms app.codeStats 0ms

/vendor/adodb/adodb-php/session/adodb-session.php

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