src/Security/AlumnoVoter.php line 13

Open in your IDE?
  1. <?php
  2. namespace App\Security;
  3. use App\Entity\Alumno;
  4. use App\Entity\Usuario;
  5. use DateTime;
  6. use LogicException;
  7. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  8. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  9. use Symfony\Component\Security\Core\Security;
  10. class AlumnoVoter extends Voter
  11. {
  12. public const PUEDE_VER = 'VER_ALUMNO';
  13. public const VER_SEGUIMIENTO = 'VER_SEGUIMIENTO';
  14. public const PUEDE_HACER_TEST_EVALUACION = 'PUEDE_HACER_TEST_EVALUACION';
  15. public const PUEDE_SOLICITAR_BECA = 'PUEDE_SOLICITAR_BECA';
  16. public function __construct(private readonly Security $security)
  17. {
  18. }
  19. protected function supports(string $attribute, $subject): bool
  20. {
  21. if (!in_array($attribute, [self::PUEDE_VER, self::VER_SEGUIMIENTO, self::PUEDE_HACER_TEST_EVALUACION, self::PUEDE_SOLICITAR_BECA])) {
  22. return false;
  23. }
  24. if (!$subject instanceof Alumno) {
  25. return false;
  26. }
  27. return true;
  28. }
  29. protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
  30. {
  31. /** @var Usuario $user */
  32. $user = $token->getUser();
  33. if (!$user) {
  34. return false;
  35. }
  36. /** @var Alumno $alumno */
  37. $alumno = $subject;
  38. switch ($attribute) {
  39. case self::PUEDE_VER:
  40. return $this->puedeVer($alumno, $user);
  41. case self::VER_SEGUIMIENTO:
  42. return $this->verSeguimiento($alumno, $user);
  43. case self::PUEDE_HACER_TEST_EVALUACION:
  44. return $this->puedeHacerTestEvaluacion($alumno, $user);
  45. case self::PUEDE_SOLICITAR_BECA:
  46. return $this->puedeSolicitarBeca($alumno, $user);
  47. }
  48. throw new LogicException('This code should not be reached!');
  49. }
  50. // Comprobamos si la solicitud está marcada como "borrada", y si el estado de la solicitud está en borrador.
  51. private function estaBorrado(Alumno $alumno): bool
  52. {
  53. // Si esta marcada como "borrada" o su estado es "borrador".
  54. if ($alumno->getSolicitud()->isBorrado() || $alumno->getSolicitud()->getEstado()->getId() === 4) {
  55. return false;
  56. }
  57. return true;
  58. }
  59. // Comprobamos si está marcado como "borrado", y si es formador que el alumno pertenezca a un curso de su empresa.
  60. private function puedeVer(Alumno $alumno, Usuario $user): bool
  61. {
  62. if (!$this->estaBorrado($alumno)) {
  63. return false;
  64. }
  65. // Si es formador e intenta ver un alumno que no es de un curso de su empresa.
  66. if (!$this->security->isGranted('ROLE_ADMIN') &&
  67. $this->security->isGranted('ROLE_FORMADOR') &&
  68. $alumno->getSolicitud()->getUsuario()->getEmpresaFormacion() !== $user->getEmpresaFormacion()) {
  69. return false;
  70. }
  71. return true;
  72. }
  73. // Comprueba si se puede ver un seguimiento para el alumno. Retorna `true` si la fecha de llamada del mes del alumno ya ha llegado
  74. // o ha pasado respecto al momento actual. Retorna `false` si no hay fecha de llamada definida o si aún no se ha alcanzado.
  75. private function verSeguimiento(Alumno $alumno, Usuario $user): bool
  76. {
  77. if (!$this->puedeVer($alumno, $user)) {
  78. return false;
  79. }
  80. $now = new DateTime();
  81. if (!$alumno->getFechaLlamadaMes() || ($now < $alumno->getFechaLlamadaMes())) {
  82. return false;
  83. }
  84. return true;
  85. }
  86. // Comprueba si un alumno puede hacer un test de evaluación.
  87. private function puedeHacerTestEvaluacion(Alumno $alumno, Usuario $user): bool
  88. {
  89. // Si el usuario logueado intenta hacer un test que no le corresponde.
  90. if ($user !== $alumno->getSolicitud()->getUsuario()) {
  91. return false;
  92. }
  93. // Si tiene la solicitud borrada o en estado borrador.
  94. if (!$this->estaBorrado($alumno)) {
  95. return false;
  96. }
  97. // Si ya tiene el test hecho o el alumno se encuentra en estado a "Baja".
  98. if ($alumno->getTestEvaluacion() || $alumno->getEstado()->getId() === 3) {
  99. return false;
  100. }
  101. return true;
  102. }
  103. // Comprueba si un alumno puede solicitar una beca.
  104. private function puedeSolicitarBeca(Alumno $alumno, Usuario $user): bool
  105. {
  106. // Si el usuario logueado intenta solicitar una beca siendo otro alumno.
  107. if ($user !== $alumno->getSolicitud()->getUsuario()) {
  108. return false;
  109. }
  110. // Si tiene la solicitud borrada o en estado borrador.
  111. if (!$this->estaBorrado($alumno)) {
  112. return false;
  113. }
  114. // Si no tiene test de evaluación, no hay fecha max. definida o la fecha de la solicitud ya ha pasado.
  115. $now = new DateTime();
  116. $fechaMaximaSolicitudBeca = $alumno->getSolicitud()->getCurso()->getFechaMaximaSolicitudBeca();
  117. if ($alumno->getSolicitudBeca() || !$alumno->getTestEvaluacion() || !$fechaMaximaSolicitudBeca || $now >= $fechaMaximaSolicitudBeca) {
  118. return false;
  119. }
  120. return true;
  121. }
  122. }