Passed
Push — master ( cf9da5...dfc849 )
by Greg
05:08
created

SessionDatabaseHandler::write()   B

Complexity

Conditions 7
Paths 33

Size

Total Lines 38
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 22
c 1
b 0
f 0
nc 33
nop 2
dl 0
loc 38
rs 8.6346
1
<?php
2
3
/**
4
 * webtrees: online genealogy
5
 * Copyright (C) 2019 webtrees development team
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
 * GNU General Public License for more details.
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16
 */
17
18
declare(strict_types=1);
19
20
namespace Fisharebest\Webtrees;
21
22
use Illuminate\Database\Capsule\Manager as DB;
23
use Psr\Http\Message\ServerRequestInterface;
24
use SessionHandlerInterface;
25
use stdClass;
26
27
/**
28
 * Session handling - stores sessions in the database.
29
 */
30
class SessionDatabaseHandler implements SessionHandlerInterface
31
{
32
    /** @var ServerRequestInterface */
33
    private $request;
34
35
    /** @var stdClass|null The row from the session table */
36
    private $row;
37
38
    public function __construct(ServerRequestInterface $request)
39
    {
40
        $this->request = $request;
41
    }
42
43
    /**
44
     * @param string $save_path
45
     * @param string $name
46
     *
47
     * @return bool
48
     */
49
    public function open($save_path, $name): bool
50
    {
51
        return true;
52
    }
53
54
    /**
55
     * @return bool
56
     */
57
    public function close(): bool
58
    {
59
        return true;
60
    }
61
62
    /**
63
     * @param string $id
64
     *
65
     * @return string
66
     */
67
    public function read($id): string
68
    {
69
        $this->row = DB::table('session')
70
            ->where('session_id', '=', $id)
71
            ->first();
72
73
74
        return $this->row->session_data ?? '';
75
    }
76
77
    /**
78
     * @param string $id
79
     * @param string $data
80
     *
81
     * @return bool
82
     */
83
    public function write($id, $data): bool
84
    {
85
        if ($this->row === null) {
86
            DB::table('session')->insert([
87
                'session_id' => $id,
88
                'session_time' => Carbon::now(),
89
                'user_id'      => (int) Auth::id(),
90
                'ip_address'   => $this->request->getAttribute('client-ip'),
91
                'session_data' => $data,
92
            ]);
93
        } else {
94
            $updates = [];
95
96
            // The user ID can change if we masquerade as another user.
97
            if ((int) $this->row->user_id !== (int) Auth::id()) {
98
                $updates['user_id'] = (int) Auth::id();
99
            }
100
101
            if ($this->row->ip_address !== $this->request->getAttribute('client-ip')) {
102
                $updates['ip_address'] = $this->request->getAttribute('client-ip');
103
            }
104
105
            if ($this->row->session_data !== $data) {
106
                $updates['session_data'] = $data;
107
            }
108
109
            if (Carbon::now()->subMinute()->gt($this->row->session_time)) {
110
                $updates['session_time'] = Carbon::now();
111
            }
112
113
            if ($updates !== []) {
114
                DB::table('session')
115
                    ->where('session_id', '=', $id)
116
                    ->update($updates);
117
            }
118
        }
119
120
        return true;
121
    }
122
123
    /**
124
     * @param string $id
125
     *
126
     * @return bool
127
     */
128
    public function destroy($id): bool
129
    {
130
        DB::table('session')
131
            ->where('session_id', '=', $id)
132
            ->delete();
133
134
        return true;
135
    }
136
137
    /**
138
     * @param int $maxlifetime
139
     *
140
     * @return bool
141
     */
142
    public function gc($maxlifetime): bool
143
    {
144
        DB::table('session')
145
            ->where('session_time', '<', Carbon::now()->subSeconds($maxlifetime))
146
            ->delete();
147
148
        return true;
149
    }
150
}
151