1<?php defined('SYSPATH') OR die('No direct access allowed.');
2/**
3 * Session database driver.
4 *
5 * $Id: Database.php 3769 2008-12-15 00:48:56Z zombor $
6 *
7 * @package    Core
8 * @author     Kohana Team
9 * @copyright  (c) 2007-2008 Kohana Team
10 * @license    http://kohanaphp.com/license.html
11 */
12class Session_Database_Driver implements Session_Driver {
13
14	/*
15	CREATE TABLE sessions
16	(
17		session_id VARCHAR(127) NOT NULL,
18		last_activity INT(10) UNSIGNED NOT NULL,
19		data TEXT NOT NULL,
20		PRIMARY KEY (session_id)
21	);
22	*/
23
24	// Database settings
25	protected $db = 'default';
26	protected $table = 'sessions';
27
28	// Encryption
29	protected $encrypt;
30
31	// Session settings
32	protected $session_id;
33	protected $written = FALSE;
34
35	public function __construct()
36	{
37		// Load configuration
38		$config = Kohana::config('session');
39
40		if ( ! empty($config['encryption']))
41		{
42			// Load encryption
43			$this->encrypt = Encrypt::instance();
44		}
45
46		if (is_array($config['storage']))
47		{
48			if ( ! empty($config['storage']['group']))
49			{
50				// Set the group name
51				$this->db = $config['storage']['group'];
52			}
53
54			if ( ! empty($config['storage']['table']))
55			{
56				// Set the table name
57				$this->table = $config['storage']['table'];
58			}
59		}
60
61		// Load database
62		$this->db = Database::instance($this->db);
63
64		Kohana::log('debug', 'Session Database Driver Initialized');
65	}
66
67	public function open($path, $name)
68	{
69		return TRUE;
70	}
71
72	public function close()
73	{
74		return TRUE;
75	}
76
77	public function read($id)
78	{
79		// Load the session
80		$query = $this->db->from($this->table)->where('session_id', $id)->limit(1)->get()->result(TRUE);
81
82		if ($query->count() === 0)
83		{
84			// No current session
85			$this->session_id = NULL;
86
87			return '';
88		}
89
90		// Set the current session id
91		$this->session_id = $id;
92
93		// Load the data
94		$data = $query->current()->data;
95
96		return ($this->encrypt === NULL) ? base64_decode($data) : $this->encrypt->decode($data);
97	}
98
99	public function write($id, $data)
100	{
101		$data = array
102		(
103			'session_id' => $id,
104			'last_activity' => time(),
105			'data' => ($this->encrypt === NULL) ? base64_encode($data) : $this->encrypt->encode($data)
106		);
107
108		if ($this->session_id === NULL)
109		{
110			// Insert a new session
111			$query = $this->db->insert($this->table, $data);
112		}
113		elseif ($id === $this->session_id)
114		{
115			// Do not update the session_id
116			unset($data['session_id']);
117
118			// Update the existing session
119			$query = $this->db->update($this->table, $data, array('session_id' => $id));
120		}
121		else
122		{
123			// Update the session and id
124			$query = $this->db->update($this->table, $data, array('session_id' => $this->session_id));
125
126			// Set the new session id
127			$this->session_id = $id;
128		}
129
130		return (bool) $query->count();
131	}
132
133	public function destroy($id)
134	{
135		// Delete the requested session
136		$this->db->delete($this->table, array('session_id' => $id));
137
138		// Session id is no longer valid
139		$this->session_id = NULL;
140
141		return TRUE;
142	}
143
144	public function regenerate()
145	{
146		// Generate a new session id
147		session_regenerate_id();
148
149		// Return new session id
150		return session_id();
151	}
152
153	public function gc($maxlifetime)
154	{
155		// Delete all expired sessions
156		$query = $this->db->delete($this->table, array('last_activity <' => time() - $maxlifetime));
157
158		Kohana::log('debug', 'Session garbage collected: '.$query->count().' row(s) deleted.');
159
160		return TRUE;
161	}
162
163} // End Session Database Driver
164