PageRenderTime 57ms CodeModel.GetById 2ms app.highlight 49ms RepoModel.GetById 0ms app.codeStats 1ms

/library/adodb/session/adodb-session.php

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