source: trunk/phpgwapi/inc/adodb/session/adodb-session.php @ 2

Revision 2, 16.9 KB checked in by niltonneto, 17 years ago (diff)

Removida todas as tags usadas pelo CVS ($Id, $Source).
Primeira versão no CVS externo.

  • Property svn:eol-style set to native
  • Property svn:executable set to *
Line 
1<?php
2
3
4/*
5V4.01 23 Oct 2003  (c) 2000-2004 John Lim (jlim@natsoft.com.my). 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        You may want to rename the 'data' field to 'session_data' as
15        'data' appears to be a reserved word for one or more of the following:
16                ANSI SQL
17                IBM DB2
18                MS SQL Server
19                Postgres
20                SAP
21
22        If you do, then execute:
23
24                ADODB_Session::dataFieldName('session_data');
25
26*/
27
28if (!defined('_ADODB_LAYER')) {
29        require_once realpath(dirname(__FILE__) . '/../adodb.inc.php');
30}
31
32if (defined('ADODB_SESSION')) return 1;
33
34define('ADODB_SESSION', dirname(__FILE__));
35
36/*!
37        \static
38*/
39class ADODB_Session {
40        /////////////////////
41        // getter/setter methods
42        /////////////////////
43
44        /*!
45        */
46        function driver($driver = null) {
47                static $_driver = 'mysql';
48                static $set = false;
49
50                if (!is_null($driver)) {
51                        $_driver = trim($driver);
52                        $set = true;
53                } elseif (!$set) {
54                        // backwards compatibility
55                        if (isset($GLOBALS['ADODB_SESSION_DRIVER'])) {
56                                return $GLOBALS['ADODB_SESSION_DRIVER'];
57                        }
58                }
59
60                return $_driver;
61        }
62
63        /*!
64        */
65        function host($host = null) {
66                static $_host = 'localhost';
67                static $set = false;
68
69                if (!is_null($host)) {
70                        $_host = trim($host);
71                        $set = true;
72                } elseif (!$set) {
73                        // backwards compatibility
74                        if (isset($GLOBALS['ADODB_SESSION_CONNECT'])) {
75                                return $GLOBALS['ADODB_SESSION_CONNECT'];
76                        }
77                }
78
79                return $_host;
80        }
81
82        /*!
83        */
84        function user($user = null) {
85                static $_user = 'root';
86                static $set = false;
87
88                if (!is_null($user)) {
89                        $_user = trim($user);
90                        $set = true;
91                } elseif (!$set) {
92                        // backwards compatibility
93                        if (isset($GLOBALS['ADODB_SESSION_USER'])) {
94                                return $GLOBALS['ADODB_SESSION_USER'];
95                        }
96                }
97
98                return $_user;
99        }
100
101        /*!
102        */
103        function password($password = null) {
104                static $_password = '';
105                static $set = false;
106
107                if (!is_null($password)) {
108                        $_password = $password;
109                        $set = true;
110                } elseif (!$set) {
111                        // backwards compatibility
112                        if (isset($GLOBALS['ADODB_SESSION_PWD'])) {
113                                return $GLOBALS['ADODB_SESSION_PWD'];
114                        }
115                }
116
117                return $_password;
118        }
119
120        /*!
121        */
122        function database($database = null) {
123                static $_database = 'xphplens_2';
124                static $set = false;
125
126                if (!is_null($database)) {
127                        $_database = trim($database);
128                        $set = true;
129                } elseif (!$set) {
130                        // backwards compatibility
131                        if (isset($GLOBALS['ADODB_SESSION_DB'])) {
132                                return $GLOBALS['ADODB_SESSION_DB'];
133                        }
134                }
135
136                return $_database;
137        }
138
139        /*!
140        */
141        function persist($persist = null) {
142                static $_persist = true;
143
144                if (!is_null($persist)) {
145                        $_persist = trim($persist);
146                }
147
148                return $_persist;
149        }
150
151        /*!
152        */
153        function lifetime($lifetime = null) {
154                static $_lifetime;
155                static $set = false;
156
157                if (!is_null($lifetime)) {
158                        $_lifetime = (int) $lifetime;
159                        $set = true;
160                } elseif (!$set) {
161                        // backwards compatibility
162                        if (isset($GLOBALS['ADODB_SESS_LIFE'])) {
163                                return $GLOBALS['ADODB_SESS_LIFE'];
164                        }
165                }
166                if (!$_lifetime) {
167                        $_lifetime = ini_get('session.gc_maxlifetime');
168                        if ($_lifetime <= 1) {
169                                // bug in PHP 4.0.3 pl 1  -- how about other versions?
170                                //print "<h3>Session Error: PHP.INI setting <i>session.gc_maxlifetime</i>not set: $lifetime</h3>";
171                                $_lifetime = 1440;
172                        }
173                }
174
175                return $_lifetime;
176        }
177
178        /*!
179        */
180        function debug($debug = null) {
181                static $_debug = false;
182                static $set = false;
183
184                if (!is_null($debug)) {
185                        $_debug = (bool) $debug;
186
187                        $conn = ADODB_Session::_conn();
188                        if ($conn) {
189                                $conn->debug = $_debug;
190                        }
191                        $set = true;
192                } elseif (!$set) {
193                        // backwards compatibility
194                        if (isset($GLOBALS['ADODB_SESS_DEBUG'])) {
195                                return $GLOBALS['ADODB_SESS_DEBUG'];
196                        }
197                }
198
199                return $_debug;
200        }
201
202        /*!
203        */
204        function expireNotify($expire_notify = null) {
205                static $_expire_notify;
206                static $set = false;
207
208                if (!is_null($expire_notify)) {
209                        $_expire_notify = $expire_notify;
210                        $set = true;
211                } elseif (!$set) {
212                        // backwards compatibility
213                        if (isset($GLOBALS['ADODB_SESSION_EXPIRE_NOTIFY'])) {
214                                return $GLOBALS['ADODB_SESSION_EXPIRE_NOTIFY'];
215                        }
216                }
217
218                return $_expire_notify;
219        }
220
221        /*!
222        */
223        function table($table = null) {
224                static $_table = 'sessions';
225                static $set = false;
226
227                if (!is_null($table)) {
228                        $_table = trim($table);
229                        $set = true;
230                } elseif (!$set) {
231                        // backwards compatibility
232                        if (isset($GLOBALS['ADODB_SESSION_TBL'])) {
233                                return $GLOBALS['ADODB_SESSION_TBL'];
234                        }
235                }
236
237                return $_table;
238        }
239
240        /*!
241        */
242        function optimize($optimize = null) {
243                static $_optimize = false;
244                static $set = false;
245
246                if (!is_null($optimize)) {
247                        $_optimize = (bool) $optimize;
248                        $set = true;
249                } elseif (!$set) {
250                        // backwards compatibility
251                        if (defined('ADODB_SESSION_OPTIMIZE')) {
252                                return true;
253                        }
254                }
255
256                return $_optimize;
257        }
258
259        /*!
260        */
261        function syncSeconds($sync_seconds = null) {
262                static $_sync_seconds = 60;
263                static $set = false;
264
265                if (!is_null($sync_seconds)) {
266                        $_sync_seconds = (int) $sync_seconds;
267                        $set = true;
268                } elseif (!$set) {
269                        // backwards compatibility
270                        if (defined('ADODB_SESSION_SYNCH_SECS')) {
271                                return ADODB_SESSION_SYNCH_SECS;
272                        }
273                }
274
275                return $_sync_seconds;
276        }
277
278        /*!
279        */
280        function clob($clob = null) {
281                static $_clob = false;
282                static $set = false;
283
284                if (!is_null($clob)) {
285                        $_clob = strtolower(trim($clob));
286                        $set = true;
287                } elseif (!$set) {
288                        // backwards compatibility
289                        if (isset($GLOBALS['ADODB_SESSION_USE_LOBS'])) {
290                                return $GLOBALS['ADODB_SESSION_USE_LOBS'];
291                        }
292                }
293
294                return $_clob;
295        }
296
297        /*!
298        */
299        function dataFieldName($data_field_name = null) {
300                static $_data_field_name = 'data';
301
302                if (!is_null($data_field_name)) {
303                        $_data_field_name = trim($data_field_name);
304                }
305
306                return $_data_field_name;
307        }
308
309        /*!
310        */
311        function filter($filter = null) {
312                static $_filter = array();
313
314                if (!is_null($filter)) {
315                        if (!is_array($filter)) {
316                                $filter = array($filter);
317                        }
318                        $_filter = $filter;
319                }
320
321                return $_filter;
322        }
323
324        /*!
325        */
326        function encryptionKey($encryption_key = null) {
327                static $_encryption_key = 'CRYPTED ADODB SESSIONS ROCK!';
328
329                if (!is_null($encryption_key)) {
330                        $_encryption_key = $encryption_key;
331                }
332
333                return $_encryption_key;
334        }
335
336        /////////////////////
337        // private methods
338        /////////////////////
339
340        /*!
341        */
342        function &_conn($conn=null) {
343                return $GLOBALS['ADODB_SESS_CONN'];
344        }
345
346        /*!
347        */
348        function _crc($crc = null) {
349                static $_crc = false;
350
351                if (!is_null($crc)) {
352                        $_crc = $crc;
353                }
354
355                return $_crc;
356        }
357
358        /*!
359        */
360        function _init() {
361                session_module_name('user');
362                session_set_save_handler(
363                        array('ADODB_Session', 'open'),
364                        array('ADODB_Session', 'close'),
365                        array('ADODB_Session', 'read'),
366                        array('ADODB_Session', 'write'),
367                        array('ADODB_Session', 'destroy'),
368                        array('ADODB_Session', 'gc')
369                );
370        }
371
372
373        /*!
374        */
375        function _sessionKey() {
376                // use this function to create the encryption key for crypted sessions
377                // crypt the used key, ADODB_Session::encryptionKey() as key and session_id() as salt
378                return crypt(ADODB_Session::encryptionKey(), session_id());
379        }
380
381        /*!
382        */
383        function _dumprs($rs) {
384                $conn   =& ADODB_Session::_conn();
385                $debug  = ADODB_Session::debug();
386
387                if (!$conn) {
388                        return;
389                }
390
391                if (!$debug) {
392                        return;
393                }
394
395                if (!$rs) {
396                        echo "<br />\$rs is null or false<br />\n";
397                        return;
398                }
399
400                //echo "<br />\nAffected_Rows=",$conn->Affected_Rows(),"<br />\n";
401
402                if (!is_object($rs)) {
403                        return;
404                }
405
406                require_once ADODB_SESSION.'/../tohtml.inc.php';
407                rs2html($rs);
408        }
409
410        /////////////////////
411        // public methods
412        /////////////////////
413
414        /*!
415                Create the connection to the database.
416
417                If $conn already exists, reuse that connection
418        */
419        function open($save_path, $session_name, $persist = null) {
420                $conn =& ADODB_Session::_conn();
421
422                if ($conn) {
423                        return true;
424                }
425
426                $database       = ADODB_Session::database();
427                $debug          = ADODB_Session::debug();
428                $driver         = ADODB_Session::driver();
429                $host           = ADODB_Session::host();
430                $password       = ADODB_Session::password();
431                $user           = ADODB_Session::user();
432
433                if (!is_null($persist)) {
434                        $persist = (bool) $persist;
435                        ADODB_Session::persist($persist);
436                } else {
437                        $persist = ADODB_Session::persist();
438                }
439
440# these can all be defaulted to in php.ini
441#               assert('$database');
442#               assert('$driver');
443#               assert('$host');
444
445                // cannot use =& below - do not know why...
446                $conn = ADONewConnection($driver);
447
448                if ($debug) {
449                        $conn->debug = true;
450//                      ADOConnection::outp( " driver=$driver user=$user pwd=$password db=$database ");
451                }
452
453                if ($persist) {
454                        $ok = $conn->PConnect($host, $user, $password, $database);
455                } else {
456                        $ok = $conn->Connect($host, $user, $password, $database);
457                }
458
459                if ($ok) $GLOBALS['ADODB_SESS_CONN'] =& $conn;
460                else
461                        ADOConnection::outp('<p>Session: connection failed</p>', false);
462               
463
464                return $ok;
465        }
466
467        /*!
468                Close the connection
469        */
470        function close() {
471                $conn =& ADODB_Session::_conn();
472
473                if ($conn) {
474                        $conn->Close();
475                }
476
477                return true;
478        }
479
480        /*
481                Slurp in the session variables and return the serialized string
482        */
483        function read($key) {
484                $conn   =& ADODB_Session::_conn();
485                $data   = ADODB_Session::dataFieldName();
486                $filter = ADODB_Session::filter();
487                $table  = ADODB_Session::table();
488
489                if (!$conn) {
490                        return '';
491                }
492
493                assert('$table');
494
495                $qkey = $conn->quote($key);
496                $binary = $conn->dataProvider === 'mysql' ? '/*! BINARY */' : '';
497
498                $sql = "SELECT $data FROM $table WHERE $binary sesskey = $qkey AND expiry >= " . time();
499                $rs =& $conn->Execute($sql);
500                //ADODB_Session::_dumprs($rs);
501                if ($rs) {
502                        if ($rs->EOF) {
503                                $v = '';
504                        } else {
505                                $v = reset($rs->fields);
506                                $filter = array_reverse($filter);
507                                foreach ($filter as $f) {
508                                        if (is_object($f)) {
509                                                $v = $f->read($v, ADODB_Session::_sessionKey());
510                                        }
511                                }
512                                $v = rawurldecode($v);
513                        }
514
515                        $rs->Close();
516
517                        ADODB_Session::_crc(strlen($v) . crc32($v));
518                        return $v;
519                }
520
521                return '';
522        }
523
524        /*!
525                Write the serialized data to a database.
526
527                If the data has not been modified since the last read(), we do not write.
528        */
529        function write($key, $val) {
530                $clob                   = ADODB_Session::clob();
531                $conn                   =& ADODB_Session::_conn();
532                $crc                    = ADODB_Session::_crc();
533                $data                   = ADODB_Session::dataFieldName();
534                $debug                  = ADODB_Session::debug();
535                $driver                 = ADODB_Session::driver();
536                $expire_notify  = ADODB_Session::expireNotify();
537                $filter                 = ADODB_Session::filter();
538                $lifetime               = ADODB_Session::lifetime();
539                $table                  = ADODB_Session::table();
540
541                if (!$conn) {
542                        return false;
543                }
544
545                assert('$table');
546
547                $expiry = time() + $lifetime;
548
549                $qkey = $conn->quote($key);
550                $binary = $conn->dataProvider === 'mysql' ? '/*! BINARY */' : '';
551
552                // crc32 optimization since adodb 2.1
553                // now we only update expiry date, thx to sebastian thom in adodb 2.32
554                if ($crc !== false && $crc == (strlen($val) . crc32($val))) {
555                        if ($debug) {
556                                echo '<p>Session: Only updating date - crc32 not changed</p>';
557                        }
558                        $sql = "UPDATE $table SET expiry = $expiry WHERE $binary sesskey = $qkey AND expiry >= " . time();
559                        $rs =& $conn->Execute($sql);
560                        ADODB_Session::_dumprs($rs);
561                        if ($rs) {
562                                $rs->Close();
563                        }
564                        return true;
565                }
566                $val = rawurlencode($val);
567                foreach ($filter as $f) {
568                        if (is_object($f)) {
569                                $val = $f->write($val, ADODB_Session::_sessionKey());
570                        }
571                }
572
573                $arr = array('sesskey' => $key, 'expiry' => $expiry, $data => $val, 'expireref' => '');
574                if ($expire_notify) {
575                        $var = reset($expire_notify);
576                        global $$var;
577                        if (isset($$var)) {
578                                $arr['expireref'] = $$var;
579                        }
580                }
581
582                if (!$clob) {   // no lobs, simply use replace()
583                        $arr[$data] = $conn->qstr($val);
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?>
Note: See TracBrowser for help on using the repository browser.