JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
added session_unset() fixed kill_session() and session_purge_old()
[wfpl.git] / session.php
1 <?php
2
3 #  Copyright (C) 2006 Jason Woofenden
4 #
5 #  This file is part of wfpl.
6 #
7 #  wfpl is free software; you can redistribute it and/or modify it under the
8 #  terms of the GNU Lesser General Public License as published by the Free
9 #  Software Foundation; either version 2.1 of the License, or (at your option)
10 #  any later version.
11 #
12 #  wfpl is distributed in the hope that it will be useful, but WITHOUT ANY
13 #  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 #  FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
15 #  more details.
16 #
17 #  You should have received a copy of the GNU Lesser General Public License
18 #  along with wfpl; if not, write to the Free Software Foundation, Inc., 51
19 #  Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20
21 # you'll need this file that calles db_connect()
22 if(!isset($GLOBALS['wfpl_db_handle'])) {
23         if(file_exists('db_connect.php') {
24                 require_once('db_connect.php');
25         } elseif(file_exists('code/db_connect.php') {
26                 require_once('code/db_connect.php');
27         } else {
28                 die("session.php requires a file db_connect.php or that you call db_connect() first. See code/wfpl/db.php for more information.");
29         }
30 }
31
32 # and these database tables:
33 # create table wfpl_sessions (id int unique auto_increment, session_key varchar(16), length int, expires int);
34 # create table wfpl_session_data (id int unique auto_increment, session_id int, name varchar(100), value text);
35
36 # GLOSSARY
37 #
38 # session_key  16 digit string identifying the session
39 # session_id   integer id of the record in the "sessions" table of the database
40 # UNTIL_CLOSE  a constant passed as session length to indicate "until browser window closes"
41
42
43 # session_id is kept in $GLOBALS
44 # session_key is sent as a cookie, and thus appears in $_REQUEST. The clean version is in $GLOBALS
45
46 # generate a new random 16-character string
47 function session_generate_key() {
48         $character_set = "abcdefghijklmnopqrstuvwqyzABCDEFGHIJKLMNOPQRSTUVWQYZ0123456789";
49     $id = "                ";
50
51         # PHP 4.2.0 and up seed the random number generator for you.
52         # Lets hope that it seeds with something harder to guess than the clock.
53     for($i = 0; $i < 16; ++$i) {
54         $id{$i} = $character_set{mt_rand(0, 61)};
55     }
56
57     return $id;
58 }
59
60 # track this user with a session cookie (ie a cookie that goes away when the
61 # user closes the browser). The timestamp is how long to track the session in
62 # the database. Defaults to one day.
63 function session_new($length = 86400) {
64         $session_key = session_generate_key();
65
66         db_insert('wfpl_sessions', 'session_key,length', $session_key, $length);
67         $GLOBALS['session_id'] = db_auto_id();
68         $GLOBALS['session_key'] = $session_key;
69         $_REQUEST['session_key'] = $session_key; #just in case someone calls session_exists() after session_new()
70         session_touch($length);
71 }
72
73 # call to renew the timeout for the session.
74 # assumes there's a session. call session_init() if you'd like one auto-create one if not found.
75 function session_touch($length = false) {
76         if(!$length) {
77                 $length = db_get_value('wfpl_sessions', 'length', 'where id=%i', $GLOBALS['session_id']);
78         }
79         $expires = time() + $length;
80
81         header('Set-Cookie: session_key=' . $GLOBALS['session_key']);
82
83         db_update('wfpl_sessions', 'expires', $expires, 'where id=%i', $GLOBALS['session_id']);
84 }
85
86 # delete the current session
87 function kill_session() {
88         if(!session_exists()) {
89             return;
90         }
91         _kill_session($GLOBALS['session_id']);
92 }
93
94 # for internal use. use kill_session() above
95 function _kill_session($id) {
96         db_delete('wfpl_session_data', 'where session_id=%i', $id);
97         db_delete('wfpl_sessions', 'where id=%i', $id);
98 }
99
100 # delete expired sessions from database
101 function session_purge_old() {
102         $now = time();
103         $exired_sessions = db_get_column('wfpl_sessions', 'id', 'where expires < %i', $now);
104         if($expired_sessions) foreach($expired_sessions as $expired_session) {
105                 _kill_session($expired_session);
106         }
107 }
108
109 # return true if a session exists
110 function session_exists() {
111         if(!isset($_REQUEST['session_key'])) {
112                 return false;
113         }
114
115         $session_key = ereg_replace('[^a-zA-Z0-9]', '', $_REQUEST['session_key']);
116
117         if(!strlen($session_key) == 16) {
118                 return false;
119         }
120
121         $GLOBALS['session_key'] = $session_key;
122
123         session_purge_old();
124         $id = db_get_value('wfpl_sessions', 'id', 'where session_key=%"', $session_key);
125         if($id === false) {
126                 return false;
127         }
128
129         $GLOBALS['session_id'] = $id;
130         return true;
131 }
132
133 # return username if a session exists and is authenticated
134 function session_exists_and_authed() {
135         if(!session_exists()) {
136                 return false;
137         }
138
139         return session_get('auth_username');
140 }
141
142
143 # find existing session, or make one
144 function init_session() {
145         if(!session_exists()) {
146                 session_new();
147         }
148 }
149
150 # save a variable into the session
151 function session_set($name, $value) {
152         session_unset($name);
153         db_insert('wfpl_session_data', 'session_id,name,value', $GLOBALS['session_id'], $name, $value);
154 }
155
156 # remove variable from the session
157 function session_unset($name) {
158         db_delete('wfpl_session_data', 'where session_id=%i && name=%"', $GLOBALS['session_id'], $name);
159 }
160
161 # get a variable into the session
162 function session_get($name) {
163         return db_get_value('wfpl_session_data', 'value', 'where session_id=%i && name=%"', $GLOBALS['session_id'], $name);
164 }
165
166 ?>