14d7dd147SGreg Roach<?php 23976b470SGreg Roach 34d7dd147SGreg Roach/** 44d7dd147SGreg Roach * webtrees: online genealogy 54d7dd147SGreg Roach * Copyright (C) 2019 webtrees development team 64d7dd147SGreg Roach * This program is free software: you can redistribute it and/or modify 74d7dd147SGreg Roach * it under the terms of the GNU General Public License as published by 84d7dd147SGreg Roach * the Free Software Foundation, either version 3 of the License, or 94d7dd147SGreg Roach * (at your option) any later version. 104d7dd147SGreg Roach * This program is distributed in the hope that it will be useful, 114d7dd147SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of 124d7dd147SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 134d7dd147SGreg Roach * GNU General Public License for more details. 144d7dd147SGreg Roach * You should have received a copy of the GNU General Public License 154d7dd147SGreg Roach * along with this program. If not, see <http://www.gnu.org/licenses/>. 164d7dd147SGreg Roach */ 17fcfa147eSGreg Roach 184d7dd147SGreg Roachdeclare(strict_types=1); 194d7dd147SGreg Roach 204d7dd147SGreg Roachnamespace Fisharebest\Webtrees; 214d7dd147SGreg Roach 224d7dd147SGreg Roachuse Illuminate\Database\Capsule\Manager as DB; 234d7dd147SGreg Roachuse Psr\Http\Message\ServerRequestInterface; 244d7dd147SGreg Roachuse SessionHandlerInterface; 25*dfc849d2SGreg Roachuse stdClass; 264d7dd147SGreg Roach 274d7dd147SGreg Roach/** 284d7dd147SGreg Roach * Session handling - stores sessions in the database. 294d7dd147SGreg Roach */ 304d7dd147SGreg Roachclass SessionDatabaseHandler implements SessionHandlerInterface 314d7dd147SGreg Roach{ 324d7dd147SGreg Roach /** @var ServerRequestInterface */ 334d7dd147SGreg Roach private $request; 344d7dd147SGreg Roach 35*dfc849d2SGreg Roach /** @var stdClass|null The row from the session table */ 36*dfc849d2SGreg Roach private $row; 37*dfc849d2SGreg Roach 383b267247SGreg Roach public function __construct(ServerRequestInterface $request) 393b267247SGreg Roach { 404d7dd147SGreg Roach $this->request = $request; 414d7dd147SGreg Roach } 424d7dd147SGreg Roach 434d7dd147SGreg Roach /** 443976b470SGreg Roach * @param string $save_path 453976b470SGreg Roach * @param string $name 464d7dd147SGreg Roach * 474d7dd147SGreg Roach * @return bool 484d7dd147SGreg Roach */ 494d7dd147SGreg Roach public function open($save_path, $name): bool 504d7dd147SGreg Roach { 514d7dd147SGreg Roach return true; 524d7dd147SGreg Roach } 534d7dd147SGreg Roach 544d7dd147SGreg Roach /** 554d7dd147SGreg Roach * @return bool 564d7dd147SGreg Roach */ 574d7dd147SGreg Roach public function close(): bool 584d7dd147SGreg Roach { 594d7dd147SGreg Roach return true; 604d7dd147SGreg Roach } 614d7dd147SGreg Roach 624d7dd147SGreg Roach /** 634d7dd147SGreg Roach * @param string $id 644d7dd147SGreg Roach * 654d7dd147SGreg Roach * @return string 664d7dd147SGreg Roach */ 674d7dd147SGreg Roach public function read($id): string 684d7dd147SGreg Roach { 69*dfc849d2SGreg Roach $this->row = DB::table('session') 704d7dd147SGreg Roach ->where('session_id', '=', $id) 71*dfc849d2SGreg Roach ->first(); 72*dfc849d2SGreg Roach 73*dfc849d2SGreg Roach 74*dfc849d2SGreg Roach return $this->row->session_data ?? ''; 754d7dd147SGreg Roach } 764d7dd147SGreg Roach 774d7dd147SGreg Roach /** 784d7dd147SGreg Roach * @param string $id 794d7dd147SGreg Roach * @param string $data 804d7dd147SGreg Roach * 814d7dd147SGreg Roach * @return bool 824d7dd147SGreg Roach */ 834d7dd147SGreg Roach public function write($id, $data): bool 844d7dd147SGreg Roach { 85*dfc849d2SGreg Roach if ($this->row === null) { 86*dfc849d2SGreg Roach DB::table('session')->insert([ 874d7dd147SGreg Roach 'session_id' => $id, 884d7dd147SGreg Roach 'session_time' => Carbon::now(), 894d7dd147SGreg Roach 'user_id' => (int) Auth::id(), 904874f72dSGreg Roach 'ip_address' => $this->request->getAttribute('client-ip'), 914d7dd147SGreg Roach 'session_data' => $data, 924d7dd147SGreg Roach ]); 93*dfc849d2SGreg Roach } else { 94*dfc849d2SGreg Roach $updates = []; 95*dfc849d2SGreg Roach 96*dfc849d2SGreg Roach // The user ID can change if we masquerade as another user. 97*dfc849d2SGreg Roach if ((int) $this->row->user_id !== (int) Auth::id()) { 98*dfc849d2SGreg Roach $updates['user_id'] = (int) Auth::id(); 99*dfc849d2SGreg Roach } 100*dfc849d2SGreg Roach 101*dfc849d2SGreg Roach if ($this->row->ip_address !== $this->request->getAttribute('client-ip')) { 102*dfc849d2SGreg Roach $updates['ip_address'] = $this->request->getAttribute('client-ip'); 103*dfc849d2SGreg Roach } 104*dfc849d2SGreg Roach 105*dfc849d2SGreg Roach if ($this->row->session_data !== $data) { 106*dfc849d2SGreg Roach $updates['session_data'] = $data; 107*dfc849d2SGreg Roach } 108*dfc849d2SGreg Roach 109*dfc849d2SGreg Roach if (Carbon::now()->subMinute()->gt($this->row->session_time)) { 110*dfc849d2SGreg Roach $updates['session_time'] = Carbon::now(); 111*dfc849d2SGreg Roach } 112*dfc849d2SGreg Roach 113*dfc849d2SGreg Roach if ($updates !== []) { 114*dfc849d2SGreg Roach DB::table('session') 115*dfc849d2SGreg Roach ->where('session_id', '=', $id) 116*dfc849d2SGreg Roach ->update($updates); 117*dfc849d2SGreg Roach } 118*dfc849d2SGreg Roach } 1194d7dd147SGreg Roach 1204d7dd147SGreg Roach return true; 1214d7dd147SGreg Roach } 1224d7dd147SGreg Roach 1234d7dd147SGreg Roach /** 1244d7dd147SGreg Roach * @param string $id 1254d7dd147SGreg Roach * 1264d7dd147SGreg Roach * @return bool 1274d7dd147SGreg Roach */ 1284d7dd147SGreg Roach public function destroy($id): bool 1294d7dd147SGreg Roach { 1304d7dd147SGreg Roach DB::table('session') 1314d7dd147SGreg Roach ->where('session_id', '=', $id) 1324d7dd147SGreg Roach ->delete(); 1334d7dd147SGreg Roach 1344d7dd147SGreg Roach return true; 1354d7dd147SGreg Roach } 1364d7dd147SGreg Roach 1374d7dd147SGreg Roach /** 1384d7dd147SGreg Roach * @param int $maxlifetime 1394d7dd147SGreg Roach * 1404d7dd147SGreg Roach * @return bool 1414d7dd147SGreg Roach */ 1424d7dd147SGreg Roach public function gc($maxlifetime): bool 1434d7dd147SGreg Roach { 1444d7dd147SGreg Roach DB::table('session') 1454d7dd147SGreg Roach ->where('session_time', '<', Carbon::now()->subSeconds($maxlifetime)) 1464d7dd147SGreg Roach ->delete(); 1474d7dd147SGreg Roach 1484d7dd147SGreg Roach return true; 1494d7dd147SGreg Roach } 1504d7dd147SGreg Roach} 151