src/Controller/Home/HomeController.php line 30

Open in your IDE?
  1. <?php
  2. namespace App\Controller\Home;
  3. use App\Entity\Consorci;
  4. use App\Entity\Empresa;
  5. use App\Entity\EntidadColaboradora;
  6. use App\Entity\EntidadRepresentativa;
  7. use App\Entity\Formador;
  8. use App\Entity\Participante;
  9. use App\Enum\RolEnum;
  10. use App\Exception\InvalidParameterException;
  11. use App\Interfaces\CursoRepositoryInterface;
  12. use App\Interfaces\NoticiasRepositoryInterface;
  13. use Doctrine\Common\Collections\Criteria;
  14. use Psr\Log\LoggerInterface;
  15. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  16. use Symfony\Component\HttpFoundation\RedirectResponse;
  17. use Symfony\Component\HttpFoundation\Request;
  18. use Symfony\Component\HttpFoundation\Response;
  19. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  20. use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
  21. use Symfony\Component\Routing\Annotation\Route;
  22. use Symfony\Component\Security\Core\Security;
  23. use Symfony\Contracts\Translation\TranslatorInterface;
  24. /**
  25. * Controlador para la página principal del sitio
  26. */
  27. class HomeController extends AbstractController
  28. {
  29. public function __construct(
  30. private SessionInterface $session,
  31. private NoticiasRepositoryInterface $noticiaRepository,
  32. private LoggerInterface $logger
  33. )
  34. {
  35. $this->noticiaRepository = $noticiaRepository->setGlobal(true);
  36. }
  37. /**
  38. * Renderiza la página principal y gestiona la selección de rol/propietario activo.
  39. *
  40. * BUG-733-v2: ahora persiste 'propietario_contenido_id_activo' en sesion,
  41. * deriva 'rol' de la clase del PropietarioContenido seleccionado y valida pertenencia
  42. * al UsuarioHermes autenticado (403 si ajeno).
  43. *
  44. * @Route("/{_locale}/", name="home", defaults={"_locale" = "ca"}, requirements={"_locale": "es|ca"})
  45. * @Route("/{_locale}/", name="home_", defaults={"_locale" = "ca"}, requirements={"_locale": "es|ca"})
  46. */
  47. public function __invoke(Request $request): Response
  48. {
  49. $user = $this->getUser();
  50. if ($user) {
  51. $propietarioIdRaw = $request->request->get('propietario_contenido_id')
  52. ?? $request->query->get('propietario_contenido_id');
  53. if ($propietarioIdRaw !== null && $propietarioIdRaw !== '') {
  54. $propietarioId = (int) $propietarioIdRaw;
  55. $propietario = null;
  56. foreach ($user->getPropietarioContenidos() ?? [] as $p) {
  57. if ((int) $p->getId() === $propietarioId) {
  58. $propietario = $p;
  59. break;
  60. }
  61. }
  62. if ($propietario === null) {
  63. $this->logger->warning('BUG-733-v2: intento de cambio de propietario ajeno', [
  64. 'usuario_hermes_id' => method_exists($user, 'getId') ? $user->getId() : null,
  65. 'propietario_id_solicitado' => $propietarioId,
  66. ]);
  67. throw new AccessDeniedHttpException('Propietario no pertenece al usuario autenticado');
  68. }
  69. // Persistir propietario activo + rol derivado de la clase.
  70. $this->session->set('propietario_contenido_id_activo', $propietarioId);
  71. $rol = $this->derivarRolDePropietario($propietario);
  72. if ($rol !== null) {
  73. $this->session->set('rol', $rol);
  74. }
  75. if ($rol === RolEnum::PARTICIPANTE) {
  76. return new RedirectResponse($this->generateUrl('home_participante'));
  77. }
  78. } else {
  79. // Compat legacy: aceptar 'rol' suelto (flujos antiguos sin propietario_contenido_id).
  80. $rol = $request->get('rol') ?? $this->session->get('rol');
  81. if ($rol !== null) {
  82. if (!in_array($rol, [
  83. RolEnum::PARTICIPANTE,
  84. RolEnum::FORMADOR,
  85. RolEnum::EMPRESA,
  86. RolEnum::CONSORCI,
  87. RolEnum::ENTIDAD_REPRESENTATIVA,
  88. RolEnum::ENTIDAD_COLABORATIVA,
  89. ], true)) {
  90. throw new InvalidParameterException('Rol no válido');
  91. }
  92. $this->session->set('rol', $rol);
  93. // Auto-seleccion: si N=1 propietario, fijarlo en sesion para no romper C2/C3.
  94. $propietarios = $user->getPropietarioContenidos();
  95. if ($propietarios !== null && count($propietarios) === 1
  96. && !$this->session->get('propietario_contenido_id_activo')) {
  97. $unico = $propietarios->first();
  98. if ($unico) {
  99. $this->session->set('propietario_contenido_id_activo', (int) $unico->getId());
  100. }
  101. }
  102. if ($rol === RolEnum::PARTICIPANTE
  103. && $user->getPropietarioContenidos()->filter(fn($p) => $p instanceof Participante)->count()) {
  104. return new RedirectResponse($this->generateUrl('home_participante'));
  105. }
  106. } else {
  107. $this->session->remove('rol');
  108. }
  109. }
  110. }
  111. $criteria = (new Criteria())
  112. ->setMaxResults(15)
  113. ->orderBy(['fechaNoticia' => 'DESC']);
  114. $noticias = $this->noticiaRepository
  115. ->setGlobal(true)
  116. ->find($criteria);
  117. return $this->render('home/home.html.twig', [
  118. 'noticias' => $noticias,
  119. ]);
  120. }
  121. /**
  122. */
  123. private function derivarRolDePropietario($propietario): ?string
  124. {
  125. if ($propietario instanceof Participante) return RolEnum::PARTICIPANTE;
  126. if ($propietario instanceof Formador) return RolEnum::FORMADOR;
  127. if ($propietario instanceof Empresa) return RolEnum::EMPRESA;
  128. if ($propietario instanceof Consorci) return RolEnum::CONSORCI;
  129. if ($propietario instanceof EntidadRepresentativa) return RolEnum::ENTIDAD_REPRESENTATIVA;
  130. if ($propietario instanceof EntidadColaboradora) return RolEnum::ENTIDAD_COLABORATIVA;
  131. return null;
  132. }
  133. }