PageRenderTime 89ms CodeModel.GetById 27ms app.highlight 55ms RepoModel.GetById 1ms app.codeStats 0ms

/sondage/classes/adodb/session/adodb-session2.php

https://bitbucket.org/bontiv/insomnia
PHP | 945 lines | 583 code | 151 blank | 211 comment | 119 complexity | fb0916eb6173a92930813a57e7609822 MD5 | raw file
  1<?php
  2
  3
  4/*
  5 V5.10 10 Nov 2009   (c) 2000-2009 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(
 24SESSKEY    VARCHAR2(48 BYTE)                  NOT NULL,
 25EXPIRY     DATE                               NOT NULL,
 26EXPIREREF  VARCHAR2(200 BYTE),
 27CREATED    DATE                               NOT NULL,
 28MODIFIED   DATE                               NOT NULL,
 29SESSDATA   CLOB,
 30PRIMARY 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
 40MySQL
 41=====
 42
 43CREATE TABLE sessions2(
 44sesskey VARCHAR( 64 ) NOT NULL DEFAULT '',
 45expiry TIMESTAMP NOT NULL ,
 46expireref VARCHAR( 250 ) DEFAULT '',
 47created TIMESTAMP NOT NULL ,
 48modified TIMESTAMP NOT NULL ,
 49sessdata LONGTEXT DEFAULT '',
 50PRIMARY KEY ( sesskey ) ,
 51INDEX sess2_expiry( expiry ),
 52INDEX 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 ($persist) {
574            switch($persist) {
575                default:
576                case 'P': $ok = $conn->PConnect($host, $user, $password, $database); break;
577                case 'C': $ok = $conn->Connect($host, $user, $password, $database); break;
578                case 'N': $ok = $conn->NConnect($host, $user, $password, $database); break;
579            }
580        } else {
581            $ok = $conn->Connect($host, $user, $password, $database);
582        }
583
584        if ($ok) $GLOBALS['ADODB_SESS_CONN'] = $conn;
585        else
586        ADOConnection::outp('<p>Session: connection failed</p>', false);
587
588
589        return $ok;
590    }
591
592    /*!
593     Close the connection
594     */
595    static function close()
596    {
597        /*
598         $conn = ADODB_Session::_conn();
599         if ($conn) $conn->Close();
600         */
601        return true;
602    }
603
604    /*
605     Slurp in the session variables and return the serialized string
606     */
607    static function read($key)
608    {
609        $conn	= ADODB_Session::_conn();
610        $filter	= ADODB_Session::filter();
611        $table	= ADODB_Session::table();
612
613        if (!$conn) {
614            return '';
615        }
616
617        //assert('$table');
618
619        $binary = $conn->dataProvider === 'mysql' ? '/*! BINARY */' : '';
620
621        $sql = "SELECT sessdata FROM $table WHERE sesskey = $binary ".$conn->Param(0)." AND expiry >= " . $conn->sysTimeStamp;
622        /* Lock code does not work as it needs to hold transaction within whole page, and we don't know if
623         developer has commited elsewhere... :(
624         */
625        #if (ADODB_Session::Lock())
626        #	$rs = $conn->RowLock($table, "$binary sesskey = $qkey AND expiry >= " . time(), sessdata);
627        #else
628        $rs = $conn->Execute($sql, array($key));
629        //ADODB_Session::_dumprs($rs);
630        if ($rs) {
631            if ($rs->EOF) {
632                $v = '';
633            } else {
634                $v = reset($rs->fields);
635                $filter = array_reverse($filter);
636                foreach ($filter as $f) {
637                    if (is_object($f)) {
638                        $v = $f->read($v, ADODB_Session::_sessionKey());
639                    }
640                }
641                $v = rawurldecode($v);
642            }
643
644            $rs->Close();
645
646            ADODB_Session::_crc(strlen($v) . crc32($v));
647            return $v;
648        }
649
650        return '';
651    }
652
653    /*!
654     Write the serialized data to a database.
655
656     If the data has not been modified since the last read(), we do not write.
657     */
658    static function write($key, $oval)
659    {
660        global $ADODB_SESSION_READONLY;
661
662        if (!empty($ADODB_SESSION_READONLY)) return;
663
664        $clob			= ADODB_Session::clob();
665        $conn			= ADODB_Session::_conn();
666        $crc			= ADODB_Session::_crc();
667        $debug			= ADODB_Session::debug();
668        $driver			= ADODB_Session::driver();
669        $expire_notify	= ADODB_Session::expireNotify();
670        $filter			= ADODB_Session::filter();
671        $lifetime		= ADODB_Session::lifetime();
672        $table			= ADODB_Session::table();
673
674        if (!$conn) {
675            return false;
676        }
677        if ($debug) $conn->debug = 1;
678        $sysTimeStamp = $conn->sysTimeStamp;
679
680        //assert('$table');
681
682        $expiry = $conn->OffsetDate($lifetime/(24*3600),$sysTimeStamp);
683
684        $binary = $conn->dataProvider === 'mysql' ? '/*! BINARY */' : '';
685
686        // crc32 optimization since adodb 2.1
687        // now we only update expiry date, thx to sebastian thom in adodb 2.32
688        if ($crc !== false && $crc == (strlen($oval) . crc32($oval))) {
689            if ($debug) {
690                echo '<p>Session: Only updating date - crc32 not changed</p>';
691            }
692
693            $expirevar = '';
694            if ($expire_notify) {
695                $var = reset($expire_notify);
696                global $$var;
697                if (isset($$var)) {
698                    $expirevar = $$var;
699                }
700            }
701
702
703            $sql = "UPDATE $table SET expiry = $expiry ,expireref=".$conn->Param('0').", modified = $sysTimeStamp WHERE $binary sesskey = ".$conn->Param('1')." AND expiry >= $sysTimeStamp";
704            $rs = $conn->Execute($sql,array($expirevar,$key));
705            return true;
706        }
707        $val = rawurlencode($oval);
708        foreach ($filter as $f) {
709            if (is_object($f)) {
710                $val = $f->write($val, ADODB_Session::_sessionKey());
711            }
712        }
713
714        $expireref = '';
715        if ($expire_notify) {
716            $var = reset($expire_notify);
717            global $$var;
718            if (isset($$var)) {
719                $expireref = $$var;
720            }
721        }
722
723        if (!$clob) {	// no lobs, simply use replace()
724            $rs = $conn->Execute("SELECT COUNT(*) AS cnt FROM $table WHERE $binary sesskey = ".$conn->Param(0),array($key));
725            if ($rs) $rs->Close();
726
727            if ($rs && reset($rs->fields) > 0) {
728                $sql = "UPDATE $table SET expiry=$expiry, sessdata=".$conn->Param(0).", expireref= ".$conn->Param(1).",modified=$sysTimeStamp WHERE sesskey = ".$conn->Param('2');
729
730            } else {
731                $sql = "INSERT INTO $table (expiry, sessdata, expireref, sesskey, created, modified)
732					VALUES ($expiry,".$conn->Param('0').", ". $conn->Param('1').", ".$conn->Param('2').", $sysTimeStamp, $sysTimeStamp)";
733            }
734
735
736            $rs = $conn->Execute($sql,array($val,$expireref,$key));
737
738        } else {
739            // what value shall we insert/update for lob row?
740            switch ($driver) {
741                // empty_clob or empty_lob for oracle dbs
742                case 'oracle':
743                case 'oci8':
744                case 'oci8po':
745                case 'oci805':
746                    $lob_value = sprintf('empty_%s()', strtolower($clob));
747                    break;
748
749                    // null for all other
750                default:
751                    $lob_value = 'null';
752                    break;
753            }
754
755            $conn->StartTrans();
756
757            $rs = $conn->Execute("SELECT COUNT(*) AS cnt FROM $table WHERE $binary sesskey = ".$conn->Param(0),array($key));
758            if ($rs) $rs->Close();
759
760            if ($rs && reset($rs->fields) > 0) {
761                $sql = "UPDATE $table SET expiry=$expiry, sessdata=$lob_value, expireref= ".$conn->Param(0).",modified=$sysTimeStamp WHERE sesskey = ".$conn->Param('1');
762
763            } else {
764                $sql = "INSERT INTO $table (expiry, sessdata, expireref, sesskey, created, modified)
765					VALUES ($expiry,$lob_value, ". $conn->Param('0').", ".$conn->Param('1').", $sysTimeStamp, $sysTimeStamp)";
766            }
767
768            $rs = $conn->Execute($sql,array($expireref,$key));
769
770            $qkey = $conn->qstr($key);
771            $rs2 = $conn->UpdateBlob($table, 'sessdata', $val, " sesskey=$qkey", strtoupper($clob));
772            if ($debug) echo "<hr>",htmlspecialchars($oval), "<hr>";
773            $rs = @$conn->CompleteTrans();
774
775
776        }
777
778        if (!$rs) {
779            ADOConnection::outp('<p>Session Replace: ' . $conn->ErrorMsg() . '</p>', false);
780            return false;
781        }  else {
782            // bug in access driver (could be odbc?) means that info is not committed
783            // properly unless select statement executed in Win2000
784            if ($conn->databaseType == 'access') {
785                $sql = "SELECT sesskey FROM $table WHERE $binary sesskey = $qkey";
786                $rs = $conn->Execute($sql);
787                ADODB_Session::_dumprs($rs);
788                if ($rs) {
789                    $rs->Close();
790                }
791            }
792        }/*
793        if (ADODB_Session::Lock()) {
794        $conn->CommitTrans();
795        }*/
796        return $rs ? true : false;
797    }
798
799    /*!
800     */
801    static function destroy($key) {
802        $conn			= ADODB_Session::_conn();
803        $table			= ADODB_Session::table();
804        $expire_notify	= ADODB_Session::expireNotify();
805
806        if (!$conn) {
807            return false;
808        }
809        $debug			= ADODB_Session::debug();
810        if ($debug) $conn->debug = 1;
811        //assert('$table');
812
813        $qkey = $conn->quote($key);
814        $binary = $conn->dataProvider === 'mysql' ? '/*! BINARY */' : '';
815
816        if ($expire_notify) {
817            reset($expire_notify);
818            $fn = next($expire_notify);
819            $savem = $conn->SetFetchMode(ADODB_FETCH_NUM);
820            $sql = "SELECT expireref, sesskey FROM $table WHERE $binary sesskey = $qkey";
821            $rs = $conn->Execute($sql);
822            ADODB_Session::_dumprs($rs);
823            $conn->SetFetchMode($savem);
824            if (!$rs) {
825                return false;
826            }
827            if (!$rs->EOF) {
828                $ref = $rs->fields[0];
829                $key = $rs->fields[1];
830                //assert('$ref');
831                //assert('$key');
832                $fn($ref, $key);
833            }
834            $rs->Close();
835        }
836
837        $sql = "DELETE FROM $table WHERE $binary sesskey = $qkey";
838        $rs = $conn->Execute($sql);
839        if ($rs) {
840            $rs->Close();
841        }
842
843        return $rs ? true : false;
844    }
845
846    /*!
847     */
848    static function gc($maxlifetime)
849    {
850        $conn			= ADODB_Session::_conn();
851        $debug			= ADODB_Session::debug();
852        $expire_notify	= ADODB_Session::expireNotify();
853        $optimize		= ADODB_Session::optimize();
854        $table			= ADODB_Session::table();
855
856        if (!$conn) {
857            return false;
858        }
859
860
861        $debug			= ADODB_Session::debug();
862        if ($debug) {
863            $conn->debug = 1;
864            $COMMITNUM = 2;
865        } else {
866            $COMMITNUM = 20;
867        }
868
869        //assert('$table');
870
871        $time = $conn->OffsetDate(-$maxlifetime/24/3600,$conn->sysTimeStamp);
872        $binary = $conn->dataProvider === 'mysql' ? '/*! BINARY */' : '';
873
874        if ($expire_notify) {
875            reset($expire_notify);
876            $fn = next($expire_notify);
877        } else {
878            $fn = false;
879        }
880
881        $savem = $conn->SetFetchMode(ADODB_FETCH_NUM);
882        $sql = "SELECT expireref, sesskey FROM $table WHERE expiry < $time ORDER BY 2"; # add order by to prevent deadlock
883        $rs = $conn->SelectLimit($sql,1000);
884        ADODB_Session::_dumprs($rs);
885        if ($debug) $conn->SetFetchMode($savem);
886        if ($rs) {
887            $tr = $conn->hasTransactions;
888            if ($tr) $conn->BeginTrans();
889            $keys = array();
890            $ccnt = 0;
891            while (!$rs->EOF) {
892                $ref = $rs->fields[0];
893                $key = $rs->fields[1];
894                if ($fn) $fn($ref, $key);
895                $del = $conn->Execute("DELETE FROM $table WHERE sesskey=".$conn->Param('0'),array($key));
896                $rs->MoveNext();
897                $ccnt += 1;
898                if ($tr && $ccnt % $COMMITNUM == 0) {
899                    if ($debug) echo "Commit<br>\n";
900                    $conn->CommitTrans();
901                    $conn->BeginTrans();
902                }
903            }
904            $rs->Close();
905
906            if ($tr) $conn->CommitTrans();
907        }
908
909
910        // suggested by Cameron, "GaM3R" <gamr@outworld.cx>
911        if ($optimize) {
912            $driver = ADODB_Session::driver();
913
914            if (preg_match('/mysql/i', $driver)) {
915                $sql = "OPTIMIZE TABLE $table";
916            }
917            if (preg_match('/postgres/i', $driver)) {
918                $sql = "VACUUM $table";
919            }
920            if (!empty($sql)) {
921                $conn->Execute($sql);
922            }
923        }
924
925
926        return true;
927    }
928}
929
930ADODB_Session::_init();
931if (empty($ADODB_SESSION_READONLY))
932register_shutdown_function('session_write_close');
933
934// for backwards compatability only
935function adodb_sess_open($save_path, $session_name, $persist = true) {
936    return ADODB_Session::open($save_path, $session_name, $persist);
937}
938
939// for backwards compatability only
940function adodb_sess_gc($t)
941{
942    return ADODB_Session::gc($t);
943}
944
945?>