Files
pta/app/Core/PdfResponse.php
2026-08-20 13:22:49 +02:00

46 lines
1.6 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Core;
/**
* Émission d'un PDF généré par les services de app/Services/.
*
* Les points d'entrée PDF n'appellent PAS JsonResponse::bootstrap() : ils
* produisent un flux binaire, et un gestionnaire d'erreur qui écrirait du JSON
* au milieu corromprait le document.
*/
final class PdfResponse
{
/**
* Envoie le document en affichage direct dans le navigateur, puis TERMINE
* le script.
*
* @param string $content Octets du PDF déjà assemblé.
* @param string $filename Nom proposé ; il est assaini avant d'atterrir dans
* l'en-tête Content-Disposition, où un guillemet ou
* un retour ligne permettrait une injection d'en-tête.
*/
public static function inline(string $content, string $filename): void
{
$safeFilename = preg_replace('/[^A-Za-z0-9._-]+/', '_', $filename) ?: 'planning.pdf';
if (!str_ends_with(strtolower($safeFilename), '.pdf')) {
$safeFilename .= '.pdf';
}
if (!headers_sent()) {
header('Content-Type: application/pdf');
header('Content-Disposition: inline; filename="' . $safeFilename . '"');
header('Content-Length: ' . strlen($content));
// Un planning peut être revalidé d'une minute à l'autre : on interdit
// au navigateur de resservir une version périmée.
header('Cache-Control: private, max-age=0, must-revalidate');
header('Pragma: public');
}
echo $content;
exit;
}
}