<?php
namespace App\EventSubscriber;
use App\Entity\User;
use Symfony\Component\Security\Core\Security; // OK pour tes versions
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
class IdentityCompletionSubscriber implements EventSubscriberInterface
{
/**
* Laisser passer le back-office même si identité incomplète ?
* -> false : on bloque aussi /admin (recommandé)
*/
private const ALLOW_BACKOFFICE_BYPASS = false;
public function __construct(
private Security $security,
private UrlGeneratorInterface $url,
) {}
public static function getSubscribedEvents(): array
{
// priorité haute pour passer AVANT la sécurité
// Le firewall SecurityListener tourne classiquement autour de 8->0.
return [KernelEvents::REQUEST => ['onRequest', 200]];
}
public function onRequest(RequestEvent $event): void
{
if (!$event->isMainRequest()) {
return;
}
$request = $event->getRequest();
/** @var User|null $user */
$user = $this->security->getUser();
if (!$user instanceof User) {
return; // non connecté
}
// --- Whitelist (routes/paths jamais bloqués) ---
$route = (string) ($request->attributes->get('_route') ?? '');
$path = $request->getPathInfo();
$whitelistRoutes = [
'app_login',
'app_logout',
'app_identity_complete',
'_wdt',
'_profiler',
];
if (!str_starts_with($path, '/admin') && $route !== 'admin' && $route !== 'easyadmin') {
return;
}
if (in_array($route, $whitelistRoutes, true)) {
return;
}
if (
str_starts_with($path, '/_profiler') ||
str_starts_with($path, '/assets/') ||
str_starts_with($path, '/build/') ||
str_starts_with($path, '/uploads/') ||
str_starts_with($route, 'api_')
) {
return;
}
if (self::ALLOW_BACKOFFICE_BYPASS) {
if ($route === 'easyadmin' || $route === 'admin' || str_starts_with($path, '/admin')) {
return;
}
}
// --- Condition de blocage (robuste) ---
// allowSelfEdit via is* OU get* selon ton entité
$allowSelfEdit = false;
if (method_exists($user, 'isAllowSelfEdit')) {
$allowSelfEdit = (bool) $user->isAllowSelfEdit();
} elseif (method_exists($user, 'getAllowSelfEdit')) {
$allowSelfEdit = (bool) $user->getAllowSelfEdit();
}
// normalise les champs (trim pour éviter espaces/valeurs " ")
$ln = trim((string) ($user->getLastName() ?? ''));
$fn = trim((string) ($user->getFirstName() ?? ''));
$ec = trim((string) ($user->getEntityCode() ?? ''));
$missingCoreIdentity = ($ln === '' || $fn === '' || $ec === '');
$needsCompletion = $allowSelfEdit && $missingCoreIdentity;
error_log('[IdentityBlock] route='.$route.' path='.$path);
error_log('[IdentityBlock] allowSelfEdit='.($allowSelfEdit?'1':'0').' ln=['.$ln.'] fn=['.$fn.'] ec=['.$ec.']');
error_log('[IdentityBlock] needsCompletion='.($needsCompletion?'1':'0'));
if (!$needsCompletion) {
return;
}
// Mémorise la première cible pour retour après complétion
if (!$request->getSession()->has('_identity_target')) {
$request->getSession()->set('_identity_target', $request->getRequestUri());
}
// 🚦 Redirection immédiate vers la complétion
$event->setResponse(new RedirectResponse($this->url->generate('app_identity_complete')));
}
}