<?php
namespace App\Security\Voter;
use App\Entity\CategoriaForo;
use App\Entity\MensajeForo;
use App\Entity\Tema;
use App\Entity\UsuarioHermes;
use App\Enum\RolEnum;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
class ForoVoter extends Voter
{
public const EDIT = 'EDIT';
public const DELETE = 'DELETE';
public const MANAGE_CATEGORIES = 'MANAGE_CATEGORIES';
// Inyectamos RequestStack para leer la sesión
public function __construct(private RequestStack $requestStack) {}
protected function supports(string $attribute, $subject): bool
{
// Soporte para EDIT y DELETE de entidades existentes
if (in_array($attribute, [self::EDIT, self::DELETE])) {
return $subject instanceof MensajeForo || $subject instanceof Tema || $subject instanceof CategoriaForo;
}
// Soporte para MANAGE_CATEGORIES (no requiere subject específico)
if ($attribute === self::MANAGE_CATEGORIES) {
return true;
}
return false;
}
protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
{
$user = $token->getUser();
if (!$user instanceof UsuarioHermes) {
return false;
}
// --- INICIO DE LA LÓGICA REVISADA ---
// Obtener el rol activo desde la sesión
$session = $this->requestStack->getSession();
$activeRole = $session->get('rol'); // Asumiendo que la clave de sesión es 'rol'
// CONDICIÓN 1: ¿El rol activo en la sesión es CONSORCI?
if ($activeRole === RolEnum::CONSORCI) {
return true; // Si es CONSORCI, tiene permiso para todo.
}
// CONDICIÓN ESPECIAL: Gestión de categorías - solo CONSORCI
if ($attribute === self::MANAGE_CATEGORIES) {
return false; // Solo CONSORCI puede gestionar categorías
}
// CONDICIÓN 2: ¿Es el autor del contenido?
// Obtenemos el PropietarioContenido del usuario
$propietarioContenidos = $user->getPropietarioContenidos();
if ($propietarioContenidos && !$propietarioContenidos->isEmpty()) {
$propietarioActivo = $propietarioContenidos->first();
// Verificar permisos según el tipo de subject
if ($subject instanceof MensajeForo) {
/** @var MensajeForo $mensaje */
$mensaje = $subject;
if ($mensaje->getPropietarioContenido() === $propietarioActivo) {
return true;
}
} elseif ($subject instanceof Tema) {
/** @var Tema $tema */
$tema = $subject;
if ($tema->getPropietarioContenido() === $propietarioActivo) {
return true;
}
} elseif ($subject instanceof CategoriaForo) {
/** @var CategoriaForo $categoria */
// Las categorías solo pueden ser gestionadas por CONSORCI
// Este caso no debería llegar aquí ya que se maneja arriba
return false;
}
}
// --- FIN DE LA LÓGICA REVISADA ---
return false;
}
}