. */ declare(strict_types=1); namespace Fisharebest\Webtrees\Http\Middleware; use Fig\Http\Message\RequestMethodInterface; use Fisharebest\Webtrees\Registry; use Fisharebest\Webtrees\Services\HousekeepingService; use League\Flysystem\FilesystemInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface; /** * Run the housekeeping service at irregular intervals. */ class DoHousekeeping implements MiddlewareInterface { // Delete old thumbnails after 90 days. private const THUMBNAIL_DIR = 'thumbnail-cache'; private const MAX_THUMBNAIL_AGE = 60 * 60 * 24 * 90; // Delete files in /data/tmp after 1 hour. private const TMP_DIR = 'data/tmp'; private const MAX_TMP_FILE_AGE = 60 * 60; // Delete error logs after 90 days. private const MAX_LOG_AGE = 60 * 60 * 24 * 90; // Delete inactive sessions after 1 day. private const MAX_SESSION_AGE = 60 * 60 * 24; // Run the cleanup every N requests. private const PROBABILITY = 250; /** @var HousekeepingService */ private $housekeeping_service; /** * Housekeeping constructor. * * @param HousekeepingService $housekeeping_service */ public function __construct(HousekeepingService $housekeeping_service) { $this->housekeeping_service = $housekeeping_service; } /** * @param ServerRequestInterface $request * @param RequestHandlerInterface $handler * * @return ResponseInterface */ public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface { $response = $handler->handle($request); // Run the cleanup after random page requests. if ($request->getMethod() === RequestMethodInterface::METHOD_GET && random_int(1, self::PROBABILITY) === 1) { $this->runHousekeeping(Registry::filesystem()->data(), Registry::filesystem()->root()); } return $response; } /** * Run the various housekeeping services. * * @param FilesystemInterface $data_filesystem * @param FilesystemInterface $root_filesystem * * @return void */ private function runHousekeeping(FilesystemInterface $data_filesystem, FilesystemInterface $root_filesystem): void { // Clear old thumbnails $this->housekeeping_service->deleteOldFiles($data_filesystem, self::THUMBNAIL_DIR, self::MAX_THUMBNAIL_AGE); // Clear temporary files $this->housekeeping_service->deleteOldFiles($root_filesystem, self::TMP_DIR, self::MAX_TMP_FILE_AGE); // Clear entries in database tables $this->housekeeping_service->deleteOldLogs(self::MAX_LOG_AGE); $this->housekeeping_service->deleteOldSessions(self::MAX_SESSION_AGE); } }