]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/DbSession/ADODB.php
Use __construct
[SourceForge/phpwiki.git] / lib / DbSession / ADODB.php
1 <?php
2 /*
3  * Copyright 2005 $ThePhpWikiProgrammingTeam
4  *
5  * This file is part of PhpWiki.
6  *
7  * PhpWiki is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * PhpWiki is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with PhpWiki; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21
22 /**
23  * ADODB db sessions, based on pear DB Sessions.
24  *
25  * @author: Reini Urban
26  */
27 class DbSession_ADODB
28     extends DbSession
29 {
30     public $_backend_type = "ADODB";
31
32     function __construct($dbh, $table)
33     {
34         $this->_dbh = $dbh;
35         $this->_table = $table;
36
37         ini_set('session.save_handler', 'user');
38         session_module_name('user'); // new style
39         session_set_save_handler(array(&$this, 'open'),
40             array(&$this, 'close'),
41             array(&$this, 'read'),
42             array(&$this, 'write'),
43             array(&$this, 'destroy'),
44             array(&$this, 'gc'));
45     }
46
47     function & _connect()
48     {
49         global $request;
50         static $parsed = false;
51         $dbh = &$this->_dbh;
52         if (!$dbh or !is_resource($dbh->_connectionID)) {
53             if (!$parsed) $parsed = parseDSN($request->_dbi->getParam('dsn'));
54             $this->_dbh =& ADONewConnection($parsed['phptype']); // Probably only MySql works just now
55             $this->_dbh->Connect($parsed['hostspec'], $parsed['username'],
56                 $parsed['password'], $parsed['database']);
57             $dbh = &$this->_dbh;
58         }
59         return $dbh;
60     }
61
62     function query($sql)
63     {
64         return $this->_dbh->Execute($sql);
65     }
66
67     function quote($string)
68     {
69         return $this->_dbh->qstr($string);
70     }
71
72     function _disconnect()
73     {
74         if (0 and $this->_dbh)
75             $this->_dbh->close();
76     }
77
78     /**
79      * Opens a session.
80      *
81      * Actually this function is a fake for session_set_save_handle.
82      * @param  string  $save_path    a path to stored files
83      * @param  string  $session_name a name of the concrete file
84      * @return boolean true just a variable to notify PHP that everything
85      * is good.
86      */
87     public function open($save_path, $session_name)
88     {
89         //$this->log("_open($save_path, $session_name)");
90         return true;
91     }
92
93     /**
94      * Closes a session.
95      *
96      * This function is called just after <i>write</i> call.
97      *
98      * @return boolean true just a variable to notify PHP that everything
99      * is good.
100      */
101     public function close()
102     {
103         //$this->log("_close()");
104         return true;
105     }
106
107     /**
108      * Reads the session data from DB.
109      *
110      * @param  string $id an id of current session
111      * @return string
112      */
113     public function read($id)
114     {
115         //$this->log("_read($id)");
116         $dbh = $this->_connect();
117         $table = $this->_table;
118         $qid = $dbh->qstr($id);
119         $res = '';
120         $row = $dbh->GetRow("SELECT sess_data FROM $table WHERE sess_id=$qid");
121         if ($row)
122             $res = $row[0];
123         $this->_disconnect();
124         if (!empty($res) and preg_match('|^[a-zA-Z0-9/+=]+$|', $res))
125             $res = base64_decode($res);
126         if (strlen($res) > 4000) {
127             trigger_error("Overlarge session data! " . strlen($res) .
128                 " gt. 4000", E_USER_WARNING);
129             $res = preg_replace('/s:6:"_cache";O:12:"WikiDB_cache".+}$/', "", $res);
130             $res = preg_replace('/s:12:"_cached_html";s:.+",s:4:"hits"/', 's:4:"hits"', $res);
131             if (strlen($res) > 4000) $res = '';
132         }
133         return $res;
134     }
135
136     /**
137      * Saves the session data into DB.
138      *
139      * Just  a  comment:       The  "write"  handler  is  not
140      * executed until after the output stream is closed. Thus,
141      * output from debugging statements in the "write" handler
142      * will  never be seen in the browser. If debugging output
143      * is  necessary, it is suggested that the debug output be
144      * written to a file instead.
145      *
146      * @param  string  $id
147      * @param  string  $sess_data
148      * @return boolean true if data saved successfully  and false
149      * otherwise.
150      */
151     public function write($id, $sess_data)
152     {
153         if (defined("WIKI_XMLRPC") or defined("WIKI_SOAP")) return false;
154
155         $dbh = $this->_connect();
156         $table = $this->_table;
157         $qid = $dbh->qstr($id);
158         $qip = $dbh->qstr($GLOBALS['request']->get('REMOTE_ADDR'));
159         $time = $dbh->qstr(time());
160
161         // postgres can't handle binary data in a TEXT field.
162         if (isa($dbh, 'ADODB_postgres64'))
163             $sess_data = base64_encode($sess_data);
164         $qdata = $dbh->qstr($sess_data);
165
166         /* AffectedRows with sessions seems to be instable on certain platforms.
167          * Enable the safe and slow USE_SAFE_DBSESSION then.
168          */
169         if (USE_SAFE_DBSESSION) {
170             $dbh->Execute("DELETE FROM $table"
171                 . " WHERE sess_id=$qid");
172             $rs = $dbh->Execute("INSERT INTO $table"
173                 . " (sess_id, sess_data, sess_date, sess_ip)"
174                 . " VALUES ($qid, $qdata, $time, $qip)");
175         } else {
176             $rs = $dbh->Execute("UPDATE $table"
177                 . " SET sess_data=$qdata, sess_date=$time, sess_ip=$qip"
178                 . " WHERE sess_id=$qid");
179             $result = $dbh->Affected_Rows();
180             if ($result === false or $result < 1) { // false or int > 0
181                 $rs = $dbh->Execute("INSERT INTO $table"
182                     . " (sess_id, sess_data, sess_date, sess_ip)"
183                     . " VALUES ($qid, $qdata, $time, $qip)");
184             }
185         }
186         $result = !$rs->EOF;
187         if ($result) $rs->free();
188         $this->_disconnect();
189         return $result;
190     }
191
192     /**
193      * Destroys a session.
194      *
195      * Removes a session from the table.
196      *
197      * @param  string  $id
198      * @return boolean true
199      */
200     public function destroy($id)
201     {
202         $dbh = $this->_connect();
203         $table = $this->_table;
204         $qid = $dbh->qstr($id);
205
206         $dbh->Execute("DELETE FROM $table WHERE sess_id=$qid");
207
208         $this->_disconnect();
209         return true;
210     }
211
212     /**
213      * Cleans out all expired sessions.
214      *
215      * @param  int     $maxlifetime session's time to live.
216      * @return boolean true
217      */
218     public function gc($maxlifetime)
219     {
220         $dbh = $this->_connect();
221         $table = $this->_table;
222         $threshold = time() - $maxlifetime;
223
224         $dbh->Execute("DELETE FROM $table WHERE sess_date < $threshold");
225
226         $this->_disconnect();
227         return true;
228     }
229
230     // WhoIsOnline support.
231     // TODO: ip-accesstime dynamic blocking API
232     function currentSessions()
233     {
234         $sessions = array();
235         $dbh = $this->_connect();
236         $table = $this->_table;
237         $rs = $dbh->Execute("SELECT sess_data,sess_date,sess_ip FROM $table ORDER BY sess_date DESC");
238         if ($rs->EOF) {
239             $rs->free();
240             return $sessions;
241         }
242         while (!$rs->EOF) {
243             $row = $rs->fetchRow();
244             $data = $row[0];
245             $date = $row[1];
246             $ip = $row[2];
247             if (preg_match('|^[a-zA-Z0-9/+=]+$|', $data))
248                 $data = base64_decode($data);
249             if ($date < 908437560 or $date > 1588437560)
250                 $date = 0;
251             // session_data contains the <variable name> + "|" + <packed string>
252             // we need just the wiki_user object (might be array as well)
253             $user = strstr($data, "wiki_user|");
254             $sessions[] = array('wiki_user' => substr($user, 10), // from "O:" onwards
255                 'date' => $date,
256                 'ip' => $ip);
257             $rs->MoveNext();
258         }
259         $rs->free();
260         $this->_disconnect();
261         return $sessions;
262     }
263 }
264
265 // Local Variables:
266 // mode: php
267 // tab-width: 8
268 // c-basic-offset: 4
269 // c-hanging-comment-ender-p: nil
270 // indent-tabs-mode: nil
271 // End: