xref: /webtrees/app/Http/Middleware/DoHousekeeping.php (revision e3c147d0d53873311b7c137c41b4439e01d4189e)
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
18declare(strict_types=1);
19
20namespace Fisharebest\Webtrees\Http\Middleware;
21
22use Fig\Http\Message\RequestMethodInterface;
23use Fisharebest\Webtrees\Services\HousekeepingService;
24use League\Flysystem\FilesystemInterface;
25use Psr\Http\Message\ResponseInterface;
26use Psr\Http\Message\ServerRequestInterface;
27use Psr\Http\Server\MiddlewareInterface;
28use Psr\Http\Server\RequestHandlerInterface;
29
30use function assert;
31
32/**
33 * Run the housekeeping service at irregular intervals.
34 */
35class DoHousekeeping implements MiddlewareInterface
36{
37    // Delete old thumbnails after 90 days.
38    private const THUMBNAIL_DIR     = 'thumbnail-cache';
39    private const MAX_THUMBNAIL_AGE = 60 * 60 * 24 * 90;
40
41    // Delete files in /data/tmp after 1 hour.
42    private const TMP_DIR          = 'data/tmp';
43    private const MAX_TMP_FILE_AGE = 60 * 60;
44
45    // Delete error logs after 90 days.
46    private const MAX_LOG_AGE = 60 * 60 * 24 * 90;
47
48    // Delete inactive sessions after 1 day.
49    private const MAX_SESSION_AGE = 60 * 60 * 24;
50
51    // Run the cleanup every N requests.
52    private const PROBABILITY = 250;
53
54    /** @var HousekeepingService */
55    private $housekeeping_service;
56
57    /**
58     * Housekeeping constructor.
59     *
60     * @param HousekeepingService $housekeeping_service
61     */
62    public function __construct(HousekeepingService $housekeeping_service)
63    {
64        $this->housekeeping_service = $housekeeping_service;
65    }
66
67    /**
68     * @param ServerRequestInterface  $request
69     * @param RequestHandlerInterface $handler
70     *
71     * @return ResponseInterface
72     */
73    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
74    {
75        $data_filesystem = $request->getAttribute('filesystem.data');
76        assert($data_filesystem instanceof FilesystemInterface);
77
78        $root_filesystem = $request->getAttribute('filesystem.root');
79        assert($root_filesystem instanceof FilesystemInterface);
80
81        $response = $handler->handle($request);
82
83        // Run the cleanup after random page requests.
84        if ($request->getMethod() === RequestMethodInterface::METHOD_GET && random_int(1, self::PROBABILITY) === 1) {
85            $this->runHousekeeping($data_filesystem, $root_filesystem);
86        }
87
88        return $response;
89    }
90
91    /**
92     * Run the various housekeeping services.
93     *
94     * @param FilesystemInterface $data_filesystem
95     * @param FilesystemInterface $root_filesystem
96     *
97     * @return void
98     */
99    private function runHousekeeping(FilesystemInterface $data_filesystem, FilesystemInterface $root_filesystem): void
100    {
101        // Clear old thumbnails
102        $this->housekeeping_service->deleteOldFiles($data_filesystem, self::THUMBNAIL_DIR, self::MAX_THUMBNAIL_AGE);
103
104        // Clear temporary files
105        $this->housekeeping_service->deleteOldFiles($root_filesystem, self::TMP_DIR, self::MAX_TMP_FILE_AGE);
106
107        // Clear entries in database tables
108        $this->housekeeping_service->deleteOldLogs(self::MAX_LOG_AGE);
109
110        $this->housekeeping_service->deleteOldSessions(self::MAX_SESSION_AGE);
111    }
112}
113