1: <?php
2: /**
3: * Database Session save handler. Allows saving session information into a model.
4: *
5: * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
6: * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
7: *
8: * Licensed under The MIT License
9: * For full copyright and license information, please see the LICENSE.txt
10: * Redistributions of files must retain the above copyright notice.
11: *
12: * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
13: * @link http://cakephp.org CakePHP(tm) Project
14: * @package Cake.Model.Datasource.Session
15: * @since CakePHP(tm) v 2.0
16: * @license http://www.opensource.org/licenses/mit-license.php MIT License
17: */
18:
19: App::uses('CakeSessionHandlerInterface', 'Model/Datasource/Session');
20: App::uses('ClassRegistry', 'Utility');
21:
22: /**
23: * DatabaseSession provides methods to be used with CakeSession.
24: *
25: * @package Cake.Model.Datasource.Session
26: */
27: class DatabaseSession implements CakeSessionHandlerInterface {
28:
29: /**
30: * Reference to the model handling the session data
31: *
32: * @var Model
33: */
34: protected $_model;
35:
36: /**
37: * Number of seconds to mark the session as expired
38: *
39: * @var int
40: */
41: protected $_timeout;
42:
43: /**
44: * Constructor. Looks at Session configuration information and
45: * sets up the session model.
46: *
47: */
48: public function __construct() {
49: $modelName = Configure::read('Session.handler.model');
50:
51: if (empty($modelName)) {
52: $settings = array(
53: 'class' => 'Session',
54: 'alias' => 'Session',
55: 'table' => 'cake_sessions',
56: );
57: } else {
58: $settings = array(
59: 'class' => $modelName,
60: 'alias' => 'Session',
61: );
62: }
63: $this->_model = ClassRegistry::init($settings);
64: $this->_timeout = Configure::read('Session.timeout') * 60;
65: }
66:
67: /**
68: * Method called on open of a database session.
69: *
70: * @return bool Success
71: */
72: public function open() {
73: return true;
74: }
75:
76: /**
77: * Method called on close of a database session.
78: *
79: * @return bool Success
80: */
81: public function close() {
82: return true;
83: }
84:
85: /**
86: * Method used to read from a database session.
87: *
88: * @param int|string $id The key of the value to read
89: * @return mixed The value of the key or false if it does not exist
90: */
91: public function read($id) {
92: $row = $this->_model->find('first', array(
93: 'conditions' => array($this->_model->primaryKey => $id)
94: ));
95:
96: if (empty($row[$this->_model->alias]['data'])) {
97: return false;
98: }
99:
100: return $row[$this->_model->alias]['data'];
101: }
102:
103: /**
104: * Helper function called on write for database sessions.
105: *
106: * @param int $id ID that uniquely identifies session in database
107: * @param mixed $data The value of the data to be saved.
108: * @return bool True for successful write, false otherwise.
109: */
110: public function write($id, $data) {
111: if (!$id) {
112: return false;
113: }
114: $expires = time() + $this->_timeout;
115: $record = compact('id', 'data', 'expires');
116: $record[$this->_model->primaryKey] = $id;
117: return $this->_model->save($record);
118: }
119:
120: /**
121: * Method called on the destruction of a database session.
122: *
123: * @param int $id ID that uniquely identifies session in database
124: * @return bool True for successful delete, false otherwise.
125: */
126: public function destroy($id) {
127: return $this->_model->delete($id);
128: }
129:
130: /**
131: * Helper function called on gc for database sessions.
132: *
133: * @param int $expires Timestamp (defaults to current time)
134: * @return bool Success
135: */
136: public function gc($expires = null) {
137: if (!$expires) {
138: $expires = time();
139: } else {
140: $expires = time() - $expires;
141: }
142: return $this->_model->deleteAll(array($this->_model->alias . ".expires <" => $expires), false, false);
143: }
144:
145: }
146: