. */ declare(strict_types=1); namespace Fisharebest\Webtrees\Http\RequestHandlers; use Fig\Http\Message\StatusCodeInterface; use Fisharebest\Webtrees\Auth; use Fisharebest\Webtrees\Exceptions\HttpNotFoundException; use Fisharebest\Webtrees\Factory; use Fisharebest\Webtrees\Tree; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\RequestHandlerInterface; use function addcslashes; use function assert; use function redirect; use function response; use function strlen; /** * Download a media file. */ class MediaFileDownload implements RequestHandlerInterface { /** * Download a non-image media file. * * @param ServerRequestInterface $request * * @return ResponseInterface */ public function handle(ServerRequestInterface $request): ResponseInterface { $tree = $request->getAttribute('tree'); assert($tree instanceof Tree); $data_filesystem = Factory::filesystem()->data(); $disposition = $request->getQueryParams()['disposition'] ?? 'inline'; assert($disposition === 'inline' || $disposition === 'attachment'); $params = $request->getQueryParams(); $xref = $params['xref']; $fact_id = $params['fact_id']; $media = Factory::media()->make($xref, $tree); $media = Auth::checkMediaAccess($media); foreach ($media->mediaFiles() as $media_file) { if ($media_file->factId() === $fact_id) { if ($media_file->isExternal()) { return redirect($media_file->filename()); } if ($media_file->fileExists($data_filesystem)) { $data = $media_file->media()->tree()->mediaFilesystem($data_filesystem)->read($media_file->filename()); return response($data, StatusCodeInterface::STATUS_OK, [ 'Content-Type' => $media_file->mimeType(), 'Content-Length' => (string) strlen($data), 'Content-Disposition' => $disposition . '; filename="' . addcslashes($media_file->filename(), '"') . '"', ]); } } } throw new HttpNotFoundException(); } }