]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/DbSession.php
enabled require_all check in WikiPoll
[SourceForge/phpwiki.git] / lib / DbSession.php
1 <?php rcs_id('$Id: DbSession.php,v 1.3 2003-03-04 05:33:00 dairiki Exp $');
2
3 /**
4  * Store sessions data in Pear DB.
5  *
6  * History
7  *
8  * Originally by Stanislav Shramko <stanis@movingmail.com>
9  * Minor rewrite by Reini Urban <rurban@x-ray.at> for Phpwiki.
10  * Quasi-major rewrite/decruft/fix by Jeff Dairiki <dairiki@dairiki.org>.
11  */
12 class DB_Session
13 {
14     /**
15      * Constructor
16      *
17      * @param mixed $dbh
18      * Pear DB handle, or WikiDB object (from which the Pear DB handle will
19      * be extracted.
20      *
21      * @param string $table
22      * Name of SQL table containing session data.
23      */
24     function DB_Session(&$dbh, $table = 'session') {
25
26         // Coerce WikiDB to Pear DB.
27         if (isa($dbh, 'WikiDB')) {
28             $backend = &$dbh->_backend;
29             if (!isa($backend, 'WikiDB_backend_PearDB')) {
30                 trigger_error('Your WikiDB does not seem to be using a Pear DB backend',
31                               E_USER_ERROR);
32                 return;
33             }
34             $dbh = &$backend->_dbh;
35         }
36     
37         $this->_dbh = &$dbh;
38         $this->_table = $table;
39
40         ini_set('session.save_handler','user');
41
42         session_set_save_handler(array(&$this, 'do_open'),
43                                  array(&$this, 'do_close'),
44                                  array(&$this, 'do_read'),
45                                  array(&$this, 'do_write'),
46                                  array(&$this, 'do_destroy'),
47                                  array(&$this, 'do_gc'));
48     }
49
50     function _connect() {
51         $dbh = &$this->_dbh;
52         $this->_connected = (bool)$dbh->connection;
53         if (!$this->_connected) {
54             $res = $dbh->connect($dbh->dsn);
55             if (DB::isError($res)) {
56                 error_log("PhpWiki::DB_Session::_connect: " . $res->getMessage());
57             }
58         }
59         return $dbh;
60     }
61
62     function _disconnect() {
63         if (!$this->_connected)
64             $this->_dbh->disconnect();
65     }
66     
67     /**
68      * Opens a session.
69      *
70      * Actually this function is a fake for session_set_save_handle.
71      * @param  string $save_path a path to stored files
72      * @param  string $session_name a name of the concrete file
73      * @return boolean true just a variable to notify PHP that everything 
74      * is good.
75      * @access private
76      */
77     function do_open ($save_path, $session_name) {
78         //$this->log("_do_open($save_path, $session_name)");
79         return true;
80     }
81
82     /**
83      * Closes a session.
84      *
85      * This function is called just after <i>do_write</i> call.
86      *
87      * @return boolean true just a variable to notify PHP that everything 
88      * is good.
89      * @access private
90      */
91     function do_close() {
92         //$this->log("_do_close()");
93         return true;
94     }
95
96     /**
97      * Reads the session data from DB.
98      *
99      * @param  string $id an id of current session
100      * @return string
101      * @access private
102      */
103     function do_read ($id) {
104         //$this->log("_do_read($id)");
105         $dbh = &$this->_connect();
106         $table = $this->_table;
107         $qid = $dbh->quote($id);
108     
109         $res = $dbh->getOne("SELECT sess_data FROM $table WHERE sess_id=$qid");
110
111         $this->_disconnect();
112         if (DB::isError($res) || empty($res))
113             return '';
114         if (preg_match('|^[a-zA-Z0-9/+=]+$|', $res))
115             $res = base64_decode($res);
116         return $res;
117     }
118   
119     /**
120      * Saves the session data into DB.
121      *
122      * Just  a  comment:       The  "write"  handler  is  not 
123      * executed until after the output stream is closed. Thus,
124      * output from debugging statements in the "write" handler
125      * will  never be seen in the browser. If debugging output
126      * is  necessary, it is suggested that the debug output be
127      * written to a file instead.
128      *
129      * @param  string $id
130      * @param  string $sess_data
131      * @return boolean true if data saved successfully  and false
132      * otherwise.
133      * @access private
134      */
135     function do_write ($id, $sess_data) {
136         
137         $dbh = &$this->_connect();
138         $table = $this->_table;
139         $qid = $dbh->quote($id);
140         $time = time();
141
142         // postgres can't handle binary data in a TEXT field.
143         if (isa($dbh, 'DB_pgsql'))
144             $sess_data = base64_encode($sess_data);
145         $qdata = $dbh->quote($sess_data);
146         
147         $res = $dbh->query("UPDATE $table"
148                            . " SET sess_data=$qdata, sess_date=$time"
149                            . " WHERE sess_id=$qid");
150
151         if ($dbh->affectedRows() == 0)
152             $res = $dbh->query("INSERT INTO $table"
153                                . " (sess_id, sess_data, sess_date)"
154                                . " VALUES ($qid, $qdata, $time)");
155
156         $this->_disconnect();
157         return ! DB::isError($res);
158     }
159
160     /**
161      * Destroys a session.
162      *
163      * Removes a session from the table.
164      *
165      * @param  string $id
166      * @return boolean true 
167      * @access private
168      */
169     function do_destroy ($id) {
170         $dbh = &$this->_connect();
171         $table = $this->_table;
172         $qid = $dbh->quote($id);
173
174         $dbh->query("DELETE FROM $table WHERE sess_id=$qid");
175
176         $this->_disconnect();
177         return true;     
178     }
179
180     /**
181      * Cleans out all expired sessions.
182      *
183      * @param  int $maxlifetime session's time to live.
184      * @return boolean true
185      * @access private
186      */
187     function do_gc ($maxlifetime) {
188         $dbh = &$this->_connect();
189         $table = $this->_table;
190         $threshold = time() - $maxlifetime;
191
192         $dbh->query("DELETE FROM $table WHERE sess_date < $threshold");
193
194         $this->_disconnect();
195         return true;
196     }
197 }
198
199
200 // Local Variables:
201 // mode: php
202 // tab-width: 8
203 // c-basic-offset: 4
204 // c-hanging-comment-ender-p: nil
205 // indent-tabs-mode: nil
206 // End:
207 ?>