<?php
namespace App\EventSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\RedirectResponse;
/**
* Bloque les nouveaux uploads SVG:
* - Retire tout UploadedFile SVG de la requête avant le binding des formulaires
* - Ajoute un flash d'information
* - Préserve un fichier déjà existant (champ réédité sans nouveau fichier)
* Ne touche pas aux SVG historiques déjà stockés (non UploadedFile).
*/
class BlockSvgUploadSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
// Priorité faible pour laisser le routage se faire mais avant la validation du formulaire.
return [KernelEvents::REQUEST => ['onRequest', 5]];
}
public function onRequest(RequestEvent $event): void
{
if (!$event->isMainRequest()) {
return;
}
$request = $event->getRequest();
if (0 === count($request->files)) {
return; // Rien à inspecter
}
$foundSvg = false;
$original = $request->files->all();
$cleanSvg = function (&$value) use (&$foundSvg, &$cleanSvg) {
if ($value instanceof UploadedFile) {
if ($value->getMimeType() === 'image/svg+xml') {
$foundSvg = true;
// On retire complètement le fichier (null) pour bloquer l'ajout.
$value = null;
}
} elseif (is_array($value)) {
foreach ($value as $k => $v) {
$cleanSvg($value[$k]);
}
}
};
foreach ($original as $k => $v) {
$cleanSvg($original[$k]);
}
foreach ($original as $k => $v) {
$request->files->set($k, $v);
}
if ($foundSvg) {
$session = $request->getSession();
if ($session instanceof Session) {
$session->getFlashBag()->add(
'warning',
'Upload SVG bloqué (sécurité). Utilisez PNG ou JPEG.'
);
}
// Annule le flush / traitement contrôleur: on renvoie l'utilisateur avant l'exécution du contrôleur
if ($request->isMethod('POST')) {
$referer = $request->headers->get('referer') ?: $request->getBaseUrl() ?: '/';
$event->setResponse(new RedirectResponse($referer, 303));
}
}
}
}