xref: /webtrees/app/Http/RequestHandlers/MediaFileDownload.php (revision 6577bfc3111b4789852b83f46e19d92c9b59921c)
1<?php
2
3/**
4 * webtrees: online genealogy
5 * Copyright (C) 2020 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\RequestHandlers;
21
22use Fig\Http\Message\StatusCodeInterface;
23use Fisharebest\Webtrees\Auth;
24use Fisharebest\Webtrees\Contracts\UserInterface;
25use Fisharebest\Webtrees\Exceptions\HttpNotFoundException;
26use Fisharebest\Webtrees\Factory;
27use Fisharebest\Webtrees\Tree;
28use Psr\Http\Message\ResponseInterface;
29use Psr\Http\Message\ServerRequestInterface;
30use Psr\Http\Server\RequestHandlerInterface;
31
32use function addcslashes;
33use function assert;
34use function redirect;
35use function response;
36use function strlen;
37
38/**
39 * Download a media file.
40 */
41class MediaFileDownload implements RequestHandlerInterface
42{
43    /**
44     * Download a non-image media file.
45     *
46     * @param ServerRequestInterface $request
47     *
48     * @return ResponseInterface
49     */
50    public function handle(ServerRequestInterface $request): ResponseInterface
51    {
52        $tree = $request->getAttribute('tree');
53        assert($tree instanceof Tree);
54
55        $user = $request->getAttribute('user');
56        assert($user instanceof UserInterface);
57
58        $image_factory = Factory::image();
59
60        $disposition = $request->getQueryParams()['disposition'] ?? 'inline';
61        assert($disposition === 'inline' || $disposition === 'attachment');
62
63        $params  = $request->getQueryParams();
64        $xref    = $params['xref'];
65        $fact_id = $params['fact_id'];
66        $media   = Factory::media()->make($xref, $tree);
67        $media   = Auth::checkMediaAccess($media);
68
69        foreach ($media->mediaFiles() as $media_file) {
70            if ($media_file->factId() === $fact_id) {
71                if ($media_file->isExternal()) {
72                    return redirect($media_file->filename());
73                }
74
75                $watermark = $media_file->isImage() && $image_factory->fileNeedsWatermark($media_file, $user);
76                $download  = $disposition === 'attachment';
77
78                return $image_factory->mediaFileResponse($media_file, $watermark, $download);
79            }
80        }
81
82        return $image_factory->replacementImageResponse((string) StatusCodeInterface::STATUS_NOT_FOUND);
83    }
84}
85