JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
changed licence to lgpl, metaform includes wfpl in tarbal
[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 require_once('db_connect.php');
23
24 # and these database tables:
25 # create table sessions (id int unique auto_increment, session_key varchar(16), length int, expires int);
26 # create table session_data (id int unique auto_increment, session_id int, name varchar(100), value text);
27
28 # GLOSSARY
29 #
30 # session_key  16 digit string identifying the session
31 # session_id   integer id of the record in the "sessions" table of the database
32 # UNTIL_CLOSE  a constant passed as session length to indicate "until browser window closes"
33
34
35 # session_id is kept in $GLOBALS
36 # session_key is sent as a cookie, and thus appears in $_REQUEST. The clean version is in $GLOBALS
37
38 # generate a new random 16-character string
39 function session_generate_key() {
40         $character_set = "abcdefghijklmnopqrstuvwqyzABCDEFGHIJKLMNOPQRSTUVWQYZ0123456789";
41     $id = "                ";
42
43         # PHP 4.2.0 and up seed the random number generator for you.
44         # Lets hope that it seeds with something harder to guess than the clock.
45     for($i = 0; $i < 16; ++$i) {
46         $id{$i} = $character_set{mt_rand(0, 61)};
47     }
48
49     return $id;
50 }
51
52 # track this user with a session cookie (ie a cookie that goes away when the
53 # user closes the browser). The timestamp is how long to track the session in
54 # the database. Defaults to one day.
55 function session_new($length = 86400) {
56         $session_key = session_generate_key();
57
58         db_insert('sessions', 'session_key,length', $session_key, $length);
59         $GLOBALS['session_id'] = db_auto_id();
60         $GLOBALS['session_key'] = $session_key;
61         $_REQUEST['session_key'] = $session_key; #just in case someone calls session_exists() after session_new()
62         session_touch($length);
63 }
64
65 # call to renew the timeout for the session.
66 # assumes there's a session. call session_init() if you'd like one auto-create one if not found.
67 function session_touch($length = false) {
68         if(!$length) {
69                 $length = db_get_value('sessions', 'length', 'id = %i', $GLOBALS['session_id']);
70         }
71         $expires = time() + $length;
72
73         header('Set-Cookie: session_key=' . $GLOBALS['session_key']);
74
75         db_update('sessions', 'expires', $expires, 'id = %i', $GLOBALS['session_id']);
76 }
77
78 # delete expired sessions from database
79 function session_purge_old() {
80         $now = time();
81         $exired_sessions = db_get_column('sessions', 'id', 'expires < %i', $now);
82         db_delete('sessions', 'expires < %i', $now);
83         if($expired_sessions) {
84                 foreach($expired_sessions as $expired_session) {
85                         db_delete('session_data', 'session_id=%i', $expired_session);
86                 }
87         }
88 }
89
90 # return true if a session exists
91 function session_exists() {
92         if(!isset($_REQUEST['session_key'])) {
93                 return false;
94         }
95
96         $session_key = ereg_replace('[^a-zA-Z0-9]', '', $_REQUEST['session_key']);
97
98         if(!strlen($session_key) == 16) {
99                 return false;
100         }
101
102         $GLOBALS['session_key'] = $session_key;
103
104         session_purge_old();
105         $id = db_get_value('sessions', 'id', 'session_key = %"', $session_key);
106         if($id === false) {
107                 return false;
108         }
109
110         $GLOBALS['session_id'] = $id;
111         return true;
112 }
113
114 # return username if a session exists and is authenticated
115 function session_exists_and_authed() {
116         if(!session_exists()) {
117                 return false;
118         }
119
120         return session_get('auth_username');
121 }
122
123
124 # find existing session, or make one
125 function init_session() {
126         if(!session_exists()) {
127                 session_new();
128         }
129 }
130
131 # save a variable into the session
132 function session_set($name, $value) {
133         db_replace('session_data', 'name,value', $name, $value);
134 }
135
136 # get a variable into the session
137 function session_get($name) {
138         return db_get_value('session_data', 'value', 'name=%"', $name);
139 }
140
141 ?>