src/Security/Voter/InvoiceVoter.php line 13

Open in your IDE?
  1. <?php
  2. namespace App\Security\Voter;
  3. use App\Entity\Gauge\Invoice;
  4. use App\Entity\User;
  5. use App\Repository\Gauge\InvoiceRepository;
  6. use Doctrine\ORM\EntityManagerInterface;
  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 InvoiceVoter extends Voter
  11. {
  12. const EDIT = 'edit';
  13. const DELETE = 'delete';
  14. /**
  15. * @var Security
  16. */
  17. private Security $security;
  18. /**
  19. * @var EntityManagerInterface
  20. */
  21. private EntityManagerInterface $entityManager;
  22. public function __construct(Security $security, EntityManagerInterface $entityManager)
  23. {
  24. $this->security = $security;
  25. $this->entityManager = $entityManager;
  26. }
  27. protected function supports(string $attribute, $subject): bool
  28. {
  29. // if the attribute isn't one we support, return false
  30. if (!in_array($attribute, [self::EDIT, self::DELETE], true)) {
  31. return false;
  32. }
  33. // only vote on `Invoice` objects
  34. if (!$subject instanceof Invoice) {
  35. return false;
  36. }
  37. return true;
  38. }
  39. protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
  40. {
  41. $loggedUser = $token->getUser();
  42. if (!$loggedUser instanceof User) {
  43. // the user must be logged in; if not, deny access
  44. return false;
  45. }
  46. /** @var Invoice $targetInvoice */
  47. $targetInvoice = $subject;
  48. switch ($attribute) {
  49. case self::EDIT:
  50. return $this->canEdit($targetInvoice);
  51. case self::DELETE:
  52. return $this->canDelete($targetInvoice);
  53. }
  54. throw new \LogicException('This code should not be reached!');
  55. }
  56. /**
  57. * @param Invoice $targetInvoice
  58. * @return bool
  59. */
  60. private function canEdit(Invoice $targetInvoice): bool
  61. {
  62. if (!$this->security->isGranted('view', $targetInvoice->getGauge())) {
  63. return false;
  64. }
  65. if ($this->security->isGranted('ROLE_CAN_EDIT_ALL_INVOICES')) {
  66. return true;
  67. }
  68. if ($this->isLast($targetInvoice) && $this->security->isGranted('ROLE_CAN_EDIT_LAST_INVOICES')) {
  69. return true;
  70. }
  71. return false;
  72. }
  73. /**
  74. * @param Invoice $targetInvoice
  75. * @return bool
  76. */
  77. private function canDelete(Invoice $targetInvoice): bool
  78. {
  79. if (!$this->security->isGranted('view', $targetInvoice->getGauge())) {
  80. return false;
  81. }
  82. if ($this->security->isGranted('ROLE_CAN_DELETE_ALL_INVOICES')) {
  83. return true;
  84. }
  85. if ($this->isLast($targetInvoice) && $this->security->isGranted('ROLE_CAN_DELETE_LAST_INVOICES')) {
  86. return true;
  87. }
  88. return false;
  89. }
  90. /**
  91. * @param Invoice $targetInvoice
  92. * @return bool
  93. */
  94. private function isLast(Invoice $targetInvoice): bool
  95. {
  96. /** @var InvoiceRepository $iRepository */
  97. $iRepository = $this->entityManager->getRepository(Invoice::class);
  98. $lastInv = $iRepository->getLastForGauge($targetInvoice->getGauge());
  99. if ($lastInv !== null && $lastInv->getId() === $targetInvoice->getId()) {
  100. return true;
  101. }
  102. return false;
  103. }
  104. }