Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 26
0.00% covered (danger)
0.00%
0 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
Session
0.00% covered (danger)
0.00%
0 / 26
0.00% covered (danger)
0.00%
0 / 7
182
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getBySessionId
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 readSession
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
20
 writeSession
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 destroySession
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 garbageCollect
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 expirationCallback
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3/**
4 * Table Definition for session
5 *
6 * PHP version 8
7 *
8 * Copyright (C) Villanova University 2010.
9 * Copyright (C) The National Library of Finland 2016.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2,
13 * as published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
23 *
24 * @category VuFind
25 * @package  Db_Table
26 * @author   Demian Katz <demian.katz@villanova.edu>
27 * @author   Ere Maijala <ere.maijala@helsinki.fi>
28 * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
29 * @link     https://vufind.org Main Page
30 */
31
32namespace VuFind\Db\Table;
33
34use Laminas\Db\Adapter\Adapter;
35use VuFind\Db\Row\RowGateway;
36use VuFind\Exception\SessionExpired as SessionExpiredException;
37
38use function intval;
39
40/**
41 * Table Definition for session
42 *
43 * @category VuFind
44 * @package  Db_Table
45 * @author   Demian Katz <demian.katz@villanova.edu>
46 * @author   Ere Maijala <ere.maijala@helsinki.fi>
47 * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
48 * @link     https://vufind.org Main Site
49 */
50class Session extends Gateway
51{
52    use ExpirationTrait;
53
54    /**
55     * Constructor
56     *
57     * @param Adapter       $adapter Database adapter
58     * @param PluginManager $tm      Table manager
59     * @param array         $cfg     Laminas configuration
60     * @param RowGateway    $rowObj  Row prototype object (null for default)
61     * @param string        $table   Name of database table to interface with
62     */
63    public function __construct(
64        Adapter $adapter,
65        PluginManager $tm,
66        $cfg,
67        ?RowGateway $rowObj = null,
68        $table = 'session'
69    ) {
70        parent::__construct($adapter, $tm, $cfg, $rowObj, $table);
71    }
72
73    /**
74     * Retrieve an object from the database based on session ID; create a new
75     * row if no existing match is found.
76     *
77     * @param string $sid    Session ID to retrieve
78     * @param bool   $create Should we create rows that don't already exist?
79     *
80     * @return ?\VuFind\Db\Row\Session
81     */
82    public function getBySessionId($sid, $create = true)
83    {
84        $row = $this->select(['session_id' => $sid])->current();
85        if ($create && empty($row)) {
86            $row = $this->createRow();
87            $row->session_id = $sid;
88            $row->created = date('Y-m-d H:i:s');
89        }
90        return $row;
91    }
92
93    /**
94     * Retrieve data for the given session ID.
95     *
96     * @param string $sid      Session ID to retrieve
97     * @param int    $lifetime Session lifetime (in seconds)
98     *
99     * @throws SessionExpiredException
100     * @return string     Session data
101     */
102    public function readSession($sid, $lifetime)
103    {
104        $s = $this->getBySessionId($sid);
105
106        // enforce lifetime of this session data
107        if (!empty($s->last_used) && $s->last_used + $lifetime <= time()) {
108            throw new SessionExpiredException('Session expired!');
109        }
110
111        // if we got this far, session is good -- update last access time, save
112        // changes, and return data.
113        $s->last_used = time();
114        $s->save();
115        return empty($s->data) ? '' : $s->data;
116    }
117
118    /**
119     * Store data for the given session ID.
120     *
121     * @param string $sid  Session ID to retrieve
122     * @param string $data Data to store
123     *
124     * @return void
125     */
126    public function writeSession($sid, $data)
127    {
128        $s = $this->getBySessionId($sid);
129        $s->last_used = time();
130        $s->data = $data;
131        $s->save();
132    }
133
134    /**
135     * Destroy data for the given session ID.
136     *
137     * @param string $sid Session ID to erase
138     *
139     * @return void
140     */
141    public function destroySession($sid)
142    {
143        $s = $this->getBySessionId($sid, false);
144        if (!empty($s)) {
145            $s->delete();
146        }
147    }
148
149    /**
150     * Garbage collect expired sessions.
151     *
152     * @param int $sess_maxlifetime Maximum session lifetime.
153     *
154     * @return void
155     */
156    public function garbageCollect($sess_maxlifetime)
157    {
158        $callback = function ($select) use ($sess_maxlifetime) {
159            $select->where
160                ->lessThan('last_used', time() - intval($sess_maxlifetime));
161        };
162        $this->delete($callback);
163    }
164
165    /**
166     * Update the select statement to find records to delete.
167     *
168     * @param Select $select    Select clause
169     * @param string $dateLimit Date threshold of an "expired" record in format
170     * 'Y-m-d H:i:s'.
171     *
172     * @return void
173     */
174    protected function expirationCallback($select, $dateLimit)
175    {
176        $select->where->lessThan('last_used', strtotime($dateLimit));
177    }
178}