xref: /webtrees/app/Http/Middleware/UseSession.php (revision e873f434551745f888937263ff89e80db3b0f785)
1<?php
2
3/**
4 * webtrees: online genealogy
5 * Copyright (C) 2023 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 <https://www.gnu.org/licenses/>.
16 */
17
18declare(strict_types=1);
19
20namespace Fisharebest\Webtrees\Http\Middleware;
21
22use Fisharebest\Webtrees\Auth;
23use Fisharebest\Webtrees\Contracts\UserInterface;
24use Fisharebest\Webtrees\Registry;
25use Fisharebest\Webtrees\Session;
26use Fisharebest\Webtrees\Webtrees;
27use Psr\Http\Message\ResponseInterface;
28use Psr\Http\Message\ServerRequestInterface;
29use Psr\Http\Server\MiddlewareInterface;
30use Psr\Http\Server\RequestHandlerInterface;
31
32use function session_destroy;
33use function session_status;
34use function time;
35
36use const PHP_SESSION_ACTIVE;
37
38/**
39 * Middleware to activate sessions.
40 */
41class UseSession implements MiddlewareInterface
42{
43    // To avoid read-write contention on the wt_user_setting table, don't update the last-active time on every request.
44    private const int UPDATE_ACTIVITY_INTERVAL = 60;
45
46    /**
47     * @param ServerRequestInterface  $request
48     * @param RequestHandlerInterface $handler
49     *
50     * @return ResponseInterface
51     */
52    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
53    {
54        // Some sites (e.g. Wordpress/NinjaFirewall) use the PHP auto_prepend_file
55        // setting to run their own startup code - which may start a session.
56        if (session_status() === PHP_SESSION_ACTIVE) {
57            session_destroy();
58        }
59
60        // Sessions
61        Session::start($request);
62
63        $user = Auth::user();
64
65        // Update the last-login time.
66        if (Session::get('masquerade') === null) {
67            $last = (int) $user->getPreference(UserInterface::PREF_TIMESTAMP_ACTIVE);
68
69            if (time() - $last >= self::UPDATE_ACTIVITY_INTERVAL) {
70                $user->setPreference(UserInterface::PREF_TIMESTAMP_ACTIVE, (string) time());
71            }
72        }
73
74        // Allow request handlers, modules, etc. to have a dependency on the current user.
75        Registry::container()->set(UserInterface::class, $user);
76
77        $request = $request->withAttribute('user', $user);
78
79        $response = $handler->handle($request);
80
81        Session::save();
82
83        return $response;
84    }
85}
86