1<?php
2/**
3 * Zend Framework (http://framework.zend.com/)
4 *
5 * @link      http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license   http://framework.zend.com/license/new-bsd New BSD License
8 */
9
10namespace Zend\Session\SaveHandler;
11
12use Zend\Db\TableGateway\TableGateway;
13
14/**
15 * DB Table Gateway session save handler
16 */
17class DbTableGateway implements SaveHandlerInterface
18{
19    /**
20     * Session Save Path
21     *
22     * @var string
23     */
24    protected $sessionSavePath;
25
26    /**
27     * Session Name
28     *
29     * @var string
30     */
31    protected $sessionName;
32
33    /**
34     * Lifetime
35     * @var int
36     */
37    protected $lifetime;
38
39    /**
40     * Zend Db Table Gateway
41     * @var TableGateway
42     */
43    protected $tableGateway;
44
45    /**
46     * DbTableGateway Options
47     * @var DbTableGatewayOptions
48     */
49    protected $options;
50
51    /**
52     * Constructor
53     *
54     * @param TableGateway $tableGateway
55     * @param DbTableGatewayOptions $options
56     */
57    public function __construct(TableGateway $tableGateway, DbTableGatewayOptions $options)
58    {
59        $this->tableGateway = $tableGateway;
60        $this->options      = $options;
61    }
62
63    /**
64     * Open Session
65     *
66     * @param  string $savePath
67     * @param  string $name
68     * @return bool
69     */
70    public function open($savePath, $name)
71    {
72        $this->sessionSavePath = $savePath;
73        $this->sessionName     = $name;
74        $this->lifetime        = ini_get('session.gc_maxlifetime');
75
76        return true;
77    }
78
79    /**
80     * Close session
81     *
82     * @return bool
83     */
84    public function close()
85    {
86        return true;
87    }
88
89    /**
90     * Read session data
91     *
92     * @param string $id
93     * @return string
94     */
95    public function read($id)
96    {
97        $rows = $this->tableGateway->select(array(
98            $this->options->getIdColumn()   => $id,
99            $this->options->getNameColumn() => $this->sessionName,
100        ));
101
102        if ($row = $rows->current()) {
103            if ($row->{$this->options->getModifiedColumn()} +
104                $row->{$this->options->getLifetimeColumn()} > time()) {
105                return $row->{$this->options->getDataColumn()};
106            }
107            $this->destroy($id);
108        }
109        return '';
110    }
111
112    /**
113     * Write session data
114     *
115     * @param string $id
116     * @param string $data
117     * @return bool
118     */
119    public function write($id, $data)
120    {
121        $data = array(
122            $this->options->getModifiedColumn() => time(),
123            $this->options->getDataColumn()     => (string) $data,
124        );
125
126        $rows = $this->tableGateway->select(array(
127            $this->options->getIdColumn()   => $id,
128            $this->options->getNameColumn() => $this->sessionName,
129        ));
130
131        if ($rows->current()) {
132            return (bool) $this->tableGateway->update($data, array(
133                $this->options->getIdColumn()   => $id,
134                $this->options->getNameColumn() => $this->sessionName,
135            ));
136        }
137        $data[$this->options->getLifetimeColumn()] = $this->lifetime;
138        $data[$this->options->getIdColumn()]       = $id;
139        $data[$this->options->getNameColumn()]     = $this->sessionName;
140
141        return (bool) $this->tableGateway->insert($data);
142    }
143
144    /**
145     * Destroy session
146     *
147     * @param  string $id
148     * @return bool
149     */
150    public function destroy($id)
151    {
152        return (bool) $this->tableGateway->delete(array(
153            $this->options->getIdColumn()   => $id,
154            $this->options->getNameColumn() => $this->sessionName,
155        ));
156    }
157
158    /**
159     * Garbage Collection
160     *
161     * @param int $maxlifetime
162     * @return true
163     */
164    public function gc($maxlifetime)
165    {
166        $platform = $this->tableGateway->getAdapter()->getPlatform();
167        return (bool) $this->tableGateway->delete(
168            sprintf(
169                '%s < %d',
170                $platform->quoteIdentifier($this->options->getModifiedColumn()),
171                (time() - $this->lifetime)
172            )
173        );
174    }
175}
176