<?php
namespace App\Controller\Home;
use App\Entity\Consorci;
use App\Entity\Empresa;
use App\Entity\EntidadColaboradora;
use App\Entity\EntidadRepresentativa;
use App\Entity\Formador;
use App\Entity\Participante;
use App\Enum\RolEnum;
use App\Exception\InvalidParameterException;
use App\Interfaces\CursoRepositoryInterface;
use App\Interfaces\NoticiasRepositoryInterface;
use Doctrine\Common\Collections\Criteria;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Security;
use Symfony\Contracts\Translation\TranslatorInterface;
/**
* Controlador para la página principal del sitio
*/
class HomeController extends AbstractController
{
public function __construct(
private SessionInterface $session,
private NoticiasRepositoryInterface $noticiaRepository,
private LoggerInterface $logger
)
{
$this->noticiaRepository = $noticiaRepository->setGlobal(true);
}
/**
* Renderiza la página principal y gestiona la selección de rol/propietario activo.
*
* BUG-733-v2: ahora persiste 'propietario_contenido_id_activo' en sesion,
* deriva 'rol' de la clase del PropietarioContenido seleccionado y valida pertenencia
* al UsuarioHermes autenticado (403 si ajeno).
*
* @Route("/{_locale}/", name="home", defaults={"_locale" = "ca"}, requirements={"_locale": "es|ca"})
* @Route("/{_locale}/", name="home_", defaults={"_locale" = "ca"}, requirements={"_locale": "es|ca"})
*/
public function __invoke(Request $request): Response
{
$user = $this->getUser();
if ($user) {
$propietarioIdRaw = $request->request->get('propietario_contenido_id')
?? $request->query->get('propietario_contenido_id');
if ($propietarioIdRaw !== null && $propietarioIdRaw !== '') {
$propietarioId = (int) $propietarioIdRaw;
$propietario = null;
foreach ($user->getPropietarioContenidos() ?? [] as $p) {
if ((int) $p->getId() === $propietarioId) {
$propietario = $p;
break;
}
}
if ($propietario === null) {
$this->logger->warning('BUG-733-v2: intento de cambio de propietario ajeno', [
'usuario_hermes_id' => method_exists($user, 'getId') ? $user->getId() : null,
'propietario_id_solicitado' => $propietarioId,
]);
throw new AccessDeniedHttpException('Propietario no pertenece al usuario autenticado');
}
// Persistir propietario activo + rol derivado de la clase.
$this->session->set('propietario_contenido_id_activo', $propietarioId);
$rol = $this->derivarRolDePropietario($propietario);
if ($rol !== null) {
$this->session->set('rol', $rol);
}
if ($rol === RolEnum::PARTICIPANTE) {
return new RedirectResponse($this->generateUrl('home_participante'));
}
} else {
// Compat legacy: aceptar 'rol' suelto (flujos antiguos sin propietario_contenido_id).
$rol = $request->get('rol') ?? $this->session->get('rol');
if ($rol !== null) {
if (!in_array($rol, [
RolEnum::PARTICIPANTE,
RolEnum::FORMADOR,
RolEnum::EMPRESA,
RolEnum::CONSORCI,
RolEnum::ENTIDAD_REPRESENTATIVA,
RolEnum::ENTIDAD_COLABORATIVA,
], true)) {
throw new InvalidParameterException('Rol no válido');
}
$this->session->set('rol', $rol);
// Auto-seleccion: si N=1 propietario, fijarlo en sesion para no romper C2/C3.
$propietarios = $user->getPropietarioContenidos();
if ($propietarios !== null && count($propietarios) === 1
&& !$this->session->get('propietario_contenido_id_activo')) {
$unico = $propietarios->first();
if ($unico) {
$this->session->set('propietario_contenido_id_activo', (int) $unico->getId());
}
}
if ($rol === RolEnum::PARTICIPANTE
&& $user->getPropietarioContenidos()->filter(fn($p) => $p instanceof Participante)->count()) {
return new RedirectResponse($this->generateUrl('home_participante'));
}
} else {
$this->session->remove('rol');
}
}
}
$criteria = (new Criteria())
->setMaxResults(15)
->orderBy(['fechaNoticia' => 'DESC']);
$noticias = $this->noticiaRepository
->setGlobal(true)
->find($criteria);
return $this->render('home/home.html.twig', [
'noticias' => $noticias,
]);
}
/**
*/
private function derivarRolDePropietario($propietario): ?string
{
if ($propietario instanceof Participante) return RolEnum::PARTICIPANTE;
if ($propietario instanceof Formador) return RolEnum::FORMADOR;
if ($propietario instanceof Empresa) return RolEnum::EMPRESA;
if ($propietario instanceof Consorci) return RolEnum::CONSORCI;
if ($propietario instanceof EntidadRepresentativa) return RolEnum::ENTIDAD_REPRESENTATIVA;
if ($propietario instanceof EntidadColaboradora) return RolEnum::ENTIDAD_COLABORATIVA;
return null;
}
}