src/Security/Voter/Promotions/LocalPromotionVoter.php line 16

Open in your IDE?
  1. <?php
  2. namespace App\Security\Voter\Promotions;
  3. use App\Entity\Promotions\LocalPromotion;
  4. use App\Entity\User;
  5. use App\Enum\MenuRolesAssociatedEnum;
  6. use App\Enum\MenuRolesManagerEnum;
  7. use App\Enum\UserRolesEnum;
  8. use App\Enum\VotersEnum;
  9. use LogicException;
  10. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  11. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  12. use Symfony\Component\Security\Core\Security;
  13. class LocalPromotionVoter extends Voter
  14. {
  15.     private Security $security;
  16.     private array $voters;
  17.     public function __construct(Security $security)
  18.     {
  19.         $this->security $security;
  20.         $this->voters = [
  21.             VotersEnum::LIST_LOCAL_PROMOTION,
  22.             VotersEnum::LIST_LOCAL_PROMOTION_ASSOCIATED,
  23.             VotersEnum::LIST_LOCAL_PROMOTION_COORDINATOR,
  24.             VotersEnum::CREATE_LOCAL_PROMOTION,
  25.             VotersEnum::READ,
  26.             VotersEnum::UPDATE,
  27.             VotersEnum::DELETE,
  28.         ];
  29.     }
  30.     protected function supports(string $attribute$subject): bool
  31.     {
  32.         // first check the $subject and last if the $attribute is supported,
  33.         // because there are attributes (with subject) used as well by other voters (like UPDATE, ...)
  34.         if ($subject && !$subject instanceof LocalPromotion) {
  35.             // only vote on these objects
  36.             return false;
  37.         }
  38.         if (in_array($attribute$this->voters)) {
  39.             // if the attribute is one we support
  40.             return true;
  41.         }
  42.         return false;
  43.     }
  44.     protected function voteOnAttribute(string $attribute$subjectTokenInterface $token): bool
  45.     {
  46.         $user $token->getUser();
  47.         if (!$user instanceof User) {
  48.             // the user must be logged in; if not, deny access
  49.             return false;
  50.         }
  51.         // you know $subject is a LocalPromotion object, thanks to `supports()`
  52.         /** @var LocalPromotion $localPromotion */
  53.         $localPromotion $subject;
  54.         switch ($attribute) {
  55.             case VotersEnum::LIST_LOCAL_PROMOTION:
  56.                 return $this->canList();
  57.             case VotersEnum::LIST_LOCAL_PROMOTION_ASSOCIATED:
  58.                 return $this->canListAssociated();
  59.             case VotersEnum::LIST_LOCAL_PROMOTION_COORDINATOR:
  60.                 return $this->canListCoordinator();
  61.             case VotersEnum::CREATE_LOCAL_PROMOTION:
  62.                 return $this->canCreate();
  63.             case VotersEnum::READ:
  64.                 return $this->canRead($localPromotion$user);
  65.             case VotersEnum::UPDATE:
  66.                 return $this->canUpdate($localPromotion$user);
  67.             case VotersEnum::DELETE:
  68.                 return $this->canDelete($localPromotion$user);
  69.         }
  70.         throw new LogicException('This code should not be reached!');
  71.     }
  72.     private function canList(): bool
  73.     {
  74.         return $this->isAdminUser();
  75.     }
  76.     private function canListAssociated(): bool
  77.     {
  78.         return $this->isAdminUser()
  79.             || $this->isAssociatedUser()
  80.             ;
  81.     }
  82.     private function canListCoordinator(): bool
  83.     {
  84.         return $this->isAdminUser()
  85.             || $this->isCoordinatorUser()
  86.             ;
  87.     }
  88.     private function canCreate(): bool
  89.     {
  90.         if ($this->isAdminUser()
  91.             || $this->isCoordinatorUser()
  92.             || $this->isAssociatedUser()) {
  93.             return true;
  94.         }
  95.         return false;
  96.     }
  97.     private function canRead(LocalPromotion $localPromotionUser $user): bool
  98.     {
  99.         return $this->isOwner($localPromotion$user);
  100.     }
  101.     private function canUpdate(LocalPromotion $localPromotionUser $user): bool
  102.     {
  103.         return $this->isOwner($localPromotion$user);
  104.     }
  105.     private function canDelete(LocalPromotion $localPromotionUser $user): bool
  106.     {
  107.         return $this->isOwner($localPromotion$user);
  108.     }
  109.     private function isOwner(LocalPromotion $localPromotionUser $user): bool
  110.     {
  111.         if ($this->isAdminUser()) {
  112.             return true;
  113.         } elseif ($this->isCoordinatorUser()) {
  114.             foreach ($user->getWorkProvinces() as $province) {
  115.                 if ($localPromotion->getGarage()->getAddress()->getProvince()->getId() === $province->getId()) {
  116.                     return true;
  117.                 }
  118.             }
  119.         } elseif ($this->isAssociatedUser()) {
  120.             if ($localPromotion->getGarage()->getOwner()->getId() === $user->getId()) {
  121.                 return true;
  122.             }
  123.         }
  124.         return false;
  125.     }
  126.     private function isAssociatedUser(): bool
  127.     {
  128.         return $this->security->isGranted(MenuRolesAssociatedEnum::ROLE_MENU_LOCAL_PROMOTIONS_ASSOCIATED);
  129.     }
  130.     private function isCoordinatorUser(): bool
  131.     {
  132.         return $this->security->isGranted(UserRolesEnum::ROLE_COORDINATOR_LONG);
  133.     }
  134.     private function isAdminUser(): bool
  135.     {
  136.         return $this->security->isGranted(MenuRolesManagerEnum::ROLE_MENU_LOCAL_PROMOTIONS);
  137.     }
  138. }