. */ declare(strict_types=1); /** * This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony). * * Copyright (C) 2019 - 2022 Jan Böhmer (https://github.com/jbtronics) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ namespace App\Helpers; use DateTime; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use function ord; class LabelResponse extends Response { public function __construct($content = '', int $status = 200, array $headers = []) { parent::__construct($content, $status, $headers); } public function setContent($content): static { parent::setContent($content); $this->setAutoEtag(); $this->setAutoLastModified(); return $this; } public function prepare(Request $request): static { parent::prepare($request); $this->headers->set('Content-Type', 'application/pdf'); if ('HTTP/1.0' !== $request->server->get('SERVER_PROTOCOL')) { $this->setProtocolVersion('1.1'); } $this->ensureIEOverSSLCompatibility($request); return $this; } /** * Automatically sets the Last-Modified header according the file modification date. */ public function setAutoLastModified(): LabelResponse { $this->setLastModified(new \DateTimeImmutable()); return $this; } /** * Automatically sets the ETag header according to the checksum of the file. */ public function setAutoEtag(): LabelResponse { $this->setEtag(base64_encode(hash('sha256', $this->content, true))); return $this; } /** * Sets the Content-Disposition header with the given filename. * * @param string $disposition ResponseHeaderBag::DISPOSITION_INLINE or ResponseHeaderBag::DISPOSITION_ATTACHMENT * @param string $filename Optionally use this UTF-8 encoded filename instead of the real name of the file * @param string $filenameFallback A fallback filename, containing only ASCII characters. Defaults to an automatically encoded filename * * @return $this */ public function setContentDisposition(string $disposition, string $filename, string $filenameFallback = ''): self { if ('' === $filenameFallback && (!preg_match('/^[\x20-\x7e]*$/', $filename) || str_contains($filename, '%'))) { $encoding = mb_detect_encoding($filename, null, true) ?: '8bit'; for ($i = 0, $filenameLength = mb_strlen($filename, $encoding); $i < $filenameLength; ++$i) { $char = mb_substr($filename, $i, 1, $encoding); if ('%' === $char || ord($char) < 32 || ord($char) > 126) { $filenameFallback .= '_'; } else { $filenameFallback .= $char; } } } $dispositionHeader = $this->headers->makeDisposition($disposition, $filename, $filenameFallback); $this->headers->set('Content-Disposition', $dispositionHeader); return $this; } }