1<?php 2 /* libraries/session.php 3 * 4 * Copyright (C) by Hugo Leisink <hugo@leisink.net> 5 * This file is part of the Banshee PHP framework 6 * http://www.banshee-php.org/ 7 * 8 * Don't change this file, unless you know what you are doing. 9 */ 10 11 final class session { 12 private $db = null; 13 private $settings = null; 14 private $id = null; 15 private $session_id = null; 16 private $use_database = null; 17 18 /* Constructor 19 * 20 * INPUT: object database, objection settings 21 * OUTPUT: - 22 * ERROR: - 23 */ 24 public function __construct($db, $settings) { 25 $this->db = $db; 26 $this->settings = $settings; 27 28 $this->use_database = ($this->settings->session_timeout >= ini_get("session.gc_maxlifetime")); 29 30 if ($this->use_database) { 31 $this->db->query("delete from sessions where expire<=now()"); 32 } 33 34 $this->start(); 35 } 36 37 /* Destructor 38 * 39 * INPUT: - 40 * OUTPUT: - 41 * ERROR: - 42 */ 43 public function __destruct() { 44 if ($this->use_database == false) { 45 session_write_close(); 46 return; 47 } else if ($this->id === null) { 48 return; 49 } else if ($this->db->connected == false) { 50 return; 51 } 52 53 $session_data = array( 54 "content" => json_encode($_SESSION), 55 "ip_address" => $_SERVER["REMOTE_ADDR"]); 56 if (is_true($this->settings->session_persistent) == false) { 57 $session_data["expire"] = date("Y-m-d H:i:s", time() + $this->settings->session_timeout); 58 } 59 60 $this->db->update("sessions", $this->id, $session_data); 61 62 $_SESSION = array(); 63 } 64 65 /* Magic method get 66 * 67 * INPUT: string key 68 * OUTPUT: mixed value 69 * ERROR: null 70 */ 71 public function __get($key) { 72 switch ($key) { 73 case "using_database": return $this->use_database; 74 } 75 76 return null; 77 } 78 79 /* Start session 80 * 81 * INPUT: - 82 * OUTPUT: true 83 * ERROR: false 84 */ 85 private function start() { 86 if ($this->use_database) { 87 /* Use database 88 */ 89 $query = "select * from sessions where session_id=%s"; 90 91 if (isset($_COOKIE[SESSION_NAME]) == false) { 92 /* New session 93 */ 94 if ($this->new_session() == false) { 95 return false; 96 } 97 } else if (($sessions = $this->db->execute($query, $_COOKIE[SESSION_NAME])) != false) { 98 /* Existing session 99 */ 100 $this->id = (int)$sessions[0]["id"]; 101 $this->session_id = $_COOKIE[SESSION_NAME]; 102 $_SESSION = json_decode($sessions[0]["content"], true); 103 } else { 104 /* Unknown session 105 */ 106 if ($this->new_session() == false) { 107 return false; 108 } 109 } 110 } else { 111 /* Use PHP's session handling 112 */ 113 session_name(SESSION_NAME); 114 if (is_true($this->settings->session_persistent)) { 115 session_set_cookie_params($this->settings->session_timeout); 116 } 117 118 if (ctype_print($_COOKIE[SESSION_NAME]) == false) { 119 unset($_COOKIE[SESSION_NAME]); 120 } 121 122 if (session_start() == false) { 123 return false; 124 } 125 126 $this->session_id = session_id(); 127 } 128 129 return true; 130 } 131 132 /* Start a new session stored in the database 133 * 134 * INPUT; - 135 * OUTPUT: true 136 * ERROR: false 137 */ 138 private function new_session() { 139 /* Create new session id 140 */ 141 $attempts = 3; 142 $query = "select id from sessions where session_id=%s"; 143 144 do { 145 if ($attempts-- == 0) { 146 return false; 147 } 148 149 $session_id = hash("sha512", random_string(128)); 150 151 if (($result = $this->db->execute($query, $session_id)) === false) { 152 return false; 153 } 154 } while ($result != false); 155 156 /* Store session in database 157 */ 158 $session_data = array( 159 "id" => null, 160 "session_id" => $session_id, 161 "content" => null, 162 "expire" => date("Y-m-d H:i:s", time() + $this->settings->session_timeout), 163 "user_id" => null, 164 "ip_address" => $_SERVER["REMOTE_ADDR"], 165 "name" => null); 166 167 if ($this->db->insert("sessions", $session_data) === false) { 168 return false; 169 } 170 171 $this->id = $this->db->last_insert_id; 172 $this->session_id = $session_id; 173 174 /* Place session id in cookie 175 */ 176 $timeout = is_true($this->settings->session_persistent) ? time() + $this->settings->session_timeout : null; 177 setcookie(SESSION_NAME, $this->session_id, $timeout, "/", "", is_true(ENFORCE_HTTPS), true); 178 $_COOKIE[SESSION_NAME] = $this->session_id; 179 180 return true; 181 } 182 183 /* Update user_id in session record 184 * 185 * INPUT: int user id 186 * OUTPUT: true 187 * ERROR: false 188 */ 189 public function set_user_id($user_id) { 190 if ($this->use_database == false) { 191 return true; 192 } else if ($this->id === null) { 193 return false; 194 } 195 196 $user_data = array("user_id" => (int)$user_id); 197 198 return $this->db->update("sessions", $this->id, $user_data) !== false; 199 } 200 201 /* Reset session 202 * 203 * INPUT: - 204 * OUTPUT: true 205 * ERROR: false 206 */ 207 public function reset() { 208 unset($_COOKIE[SESSION_NAME]); 209 $_SESSION = array(); 210 if ($this->use_database) { 211 $this->db->query("delete from sessions where id=%d", $this->id); 212 } else { 213 session_unset(); 214 session_destroy(); 215 } 216 217 return $this->start(); 218 } 219 } 220?> 221