<?php
namespace App\Security;
use App\Entity\Curso;
use App\Entity\Usuario;
use LogicException;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\Security;
class CursoVoter extends Voter
{
public const PUEDE_VER = 'VER_CURSO';
public const PUEDE_INSCRIBIRSE = 'INSCRIBIRSE_CURSO';
public const ESTA_BORRADO = 'ESTA_BORRADO';
public function __construct(private readonly Security $security)
{
}
protected function supports(string $attribute, $subject): bool
{
if (!in_array($attribute, [self::PUEDE_VER, self::ESTA_BORRADO, self::PUEDE_INSCRIBIRSE])) {
return false;
}
if (!$subject instanceof Curso) {
return false;
}
return true;
}
protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
{
/** @var Usuario $user */
$user = $token->getUser();
if (!$user) {
return false;
}
/** @var Curso $curso */
$curso = $subject;
switch ($attribute) {
case self::PUEDE_VER:
return $this->puedeVer($curso, $user);
case self::PUEDE_INSCRIBIRSE:
return $this->puedeInscribirse($curso, $user);
case self::ESTA_BORRADO:
return !$this->estaBorrado($curso);
}
throw new LogicException('This code should not be reached!');
}
// Comprobamos si esta marcado como "borrado".
private function estaBorrado(Curso $curso): bool
{
return $curso->isBorrado();
}
// Comprobamos si está marcado como "borrado", y si es formador que el curso perteneza a su empresa.
private function puedeVer(Curso $curso, Usuario $user): bool
{
if ($this->estaBorrado($curso)) {
return false;
}
// Los formadores solo si pertenece a su empresa.
if (!$this->security->isGranted('ROLE_ADMIN') &&
$this->security->isGranted('ROLE_FORMADOR') &&
$curso->getEmpresaFormacion() !== $user->getEmpresaFormacion()) {
return false;
}
return true;
}
// Comprobamos si está marcado como "borrado", y si el usuario logueado puede inscribirse.
private function puedeInscribirse(Curso $curso, Usuario $user): bool
{
if ($this->estaBorrado($curso)) {
return false;
}
// Solamente los usuarios normales.
return $this->security->isGranted('IS_AUTHENTICATED') && $user->getRoles()[0] === 'ROLE_USER';
}
}