xref: /webtrees/app/SessionDatabaseHandler.php (revision dfc849d226fb4bd64f14664478a941ef05c27b61)
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