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