src/Security/Voter/EnrollmentVoter.php line 13

  1. <?php
  2. namespace App\Security\Voter;
  3. use App\Entity\Enrollment;
  4. use App\Enum\RoleType;
  5. use Doctrine\ORM\NonUniqueResultException;
  6. use Symfony\Bundle\SecurityBundle\Security;
  7. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  8. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  9. use Symfony\Component\Security\Core\User\UserInterface;
  10. /**
  11. * @extends Voter<string, Enrollment>
  12. */
  13. class EnrollmentVoter extends Voter
  14. {
  15. public const EDIT = 'ENROLLMENT_EDIT';
  16. public const NEW = 'ENROLLMENT_NEW';
  17. public const VIEW = 'ENROLLMENT_VIEW';
  18. public const INDEX = 'ENROLLMENT_INDEX';
  19. public const SUBMIT = 'ENROLLMENT_SUBMIT';
  20. public const APPROVE = 'ENROLLMENT_APPROVE';
  21. public const RENEW = 'ENROLLMENT_RENEW';
  22. public function __construct(private readonly Security $security)
  23. {
  24. }
  25. protected function supports(string $attribute, mixed $subject): bool
  26. {
  27. if ($subject !== null) {
  28. return in_array($attribute, [self::EDIT, self::INDEX, self::VIEW, self::SUBMIT, self::APPROVE, self::RENEW])
  29. && $subject instanceof Enrollment;
  30. } else {
  31. return in_array($attribute, [
  32. self::EDIT,
  33. self::INDEX,
  34. self::VIEW,
  35. self::SUBMIT,
  36. self::APPROVE,
  37. self::RENEW
  38. ]);
  39. }
  40. }
  41. /**
  42. * @param mixed $subject is the Enrollment
  43. * @throws NonUniqueResultException
  44. */
  45. protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
  46. {
  47. $user = $token->getUser();
  48. // if the user is anonymous, do not grant access
  49. if (!$user instanceof UserInterface) {
  50. return false;
  51. }
  52. return match ($attribute) {
  53. // Who can view a certain enrollment and edit it:
  54. // Who can create and approve a new enrollment manually:
  55. 'ENROLLMENT_VIEW', 'ENROLLMENT_EDIT', 'ENROLLMENT_NEW', 'ENROLLMENT_APPROVE' =>
  56. $this->security->isGranted(RoleType::ROLE_PEDAGOGICAL_DIRECTOR) ||
  57. $this->security->isGranted(RoleType::ROLE_FINANCIAL_DIRECTOR) ||
  58. $this->security->isGranted(RoleType::ROLE_EMPLOYEE),
  59. // Who can view the list of enrollments:
  60. 'ENROLLMENT_INDEX' =>
  61. $this->security->isGranted(RoleType::ROLE_PEDAGOGICAL_DIRECTOR) ||
  62. $this->security->isGranted(RoleType::ROLE_FINANCIAL_DIRECTOR) ||
  63. $this->security->isGranted(RoleType::ROLE_EMPLOYEE) ||
  64. $this->security->isGranted(RoleType::ROLE_GUARDIAN),
  65. // Who can submit an enrollment:
  66. 'ENROLLMENT_SUBMIT' =>
  67. $this->security->isGranted(RoleType::ROLE_EMPLOYEE),
  68. // Who can renew an enrollment:
  69. 'ENROLLMENT_RENEW' =>
  70. $this->security->isGranted(RoleType::ROLE_EMPLOYEE) ||
  71. ($this->security->isGranted(RoleType::ROLE_GUARDIAN) &&
  72. $subject->getGuardian()->getUser()
  73. === $user), // Guardian(user) who submitted the enrollment
  74. default => false,
  75. };
  76. }
  77. }