src/Security/Voter/PointsCatalog/CatalogOrderVoter.php line 17

Open in your IDE?
  1. <?php
  2. namespace App\Security\Voter\PointsCatalog;
  3. use App\Entity\Garages\Garage;
  4. use App\Entity\PointsCatalog\CatalogOrder;
  5. use App\Entity\Province;
  6. use App\Entity\User;
  7. use App\Enum\MenuRolesAssociatedEnum;
  8. use App\Enum\MenuRolesManagerEnum;
  9. use App\Enum\UserRolesEnum;
  10. use App\Enum\VotersEnum;
  11. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  12. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  13. use Symfony\Component\Security\Core\Security;
  14. class CatalogOrderVoter extends Voter
  15. {
  16.     private Security $security;
  17.     private array $voters;
  18.     public function __construct(Security $security)
  19.     {
  20.         $this->security $security;
  21.         $this->voters = [
  22.             VotersEnum::LIST_CATALOG_ORDER,
  23.             VotersEnum::VIEW,
  24.             VotersEnum::DELETE,
  25.             VotersEnum::PROCESS,
  26.             VotersEnum::REOPEN,
  27.             VotersEnum::EXPORT_CATALOG_ORDER,
  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 CatalogOrder) {
  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.         switch ($attribute) {
  52.             case VotersEnum::LIST_CATALOG_ORDER:
  53.                 return $this->canList();
  54.             case VotersEnum::VIEW:
  55.                 return $this->canView($subject$user);
  56.             case VotersEnum::DELETE:
  57.                 return $this->canDelete($subject$user);
  58.             case VotersEnum::PROCESS:
  59.                 return $this->canProcessOrder($subject);
  60.             case VotersEnum::REOPEN:
  61.                 return $this->canReopenOrder($subject);
  62.             case VotersEnum::EXPORT_CATALOG_ORDER:
  63.                 return $this->canExport();
  64.         }
  65.         throw new \LogicException('This code should not be reached!');
  66.     }
  67.     private function canList(): bool
  68.     {
  69.         return $this->isAdminUser()
  70.             || $this->isCoordinatorUser()
  71.             || $this->isAssociatedManagerUser()
  72.             || $this->isAssociatedUser();
  73.     }
  74.     private function canView(CatalogOrder $catalogOrderUser $user): bool
  75.     {
  76.         return $this->isAdminUser()
  77.             || $this->isCoordinatorUser()
  78.             || $this->isAssociatedManagerUser()
  79.             || ($this->isAssociatedUser() && $this->isOwner($catalogOrder$user));
  80.     }
  81.     private function canDelete(CatalogOrder $catalogOrderUser $user): bool
  82.     {
  83.         return $this->isOwner($catalogOrder$user) && $catalogOrder->isPending();
  84.     }
  85.     private function canProcessOrder(CatalogOrder $catalogOrder): bool
  86.     {
  87.         return $this->isAdminUser() && $catalogOrder->isPending();
  88.     }
  89.     private function canReopenOrder(CatalogOrder $catalogOrder): bool
  90.     {
  91.         return $this->isAdminUser() && $catalogOrder->isPending();
  92.     }
  93.     private function canExport(): bool
  94.     {
  95.         return $this->isAdminUser();
  96.     }
  97.     private function isOwner(CatalogOrder $catalogOrderUser $user): bool
  98.     {
  99.         if ($this->isAdminUser()) {
  100.             return true;
  101.         } elseif ($this->security->isGranted(UserRolesEnum::ROLE_COORDINATOR_LONG)) {
  102.             /** @var Province $province */
  103.             foreach ($user->getWorkProvinces() as $province) {
  104.                 if ($catalogOrder->getGarage()->getAddress() && $catalogOrder->getGarage()->getAddress()->getProvince() && $province->getId() === $catalogOrder->getGarage()->getAddress()->getProvince()->getId()) {
  105.                     return true;
  106.                 }
  107.             }
  108.         } elseif ($user->hasRole(UserRolesEnum::ROLE_ASSOCIATED_LONG) || ($user->hasRole(UserRolesEnum::ROLE_ASSOCIATED_MANAGER_LONG) && !$user->hasRole(MenuRolesManagerEnum::ROLE_MENU_CATALOG_POINTS))) {
  109.             // orders make by admins take their own user id, instead of the garage user id  =/=> $result = $catalogOrder->getUser()->getId() === $user->getId();
  110.             /** @var Garage $garage */
  111.             foreach ($user->getGarages() as $garage) {
  112.                 if ($catalogOrder->getGarage()->getId() === $garage->getId()) {
  113.                     return true;
  114.                 }
  115.             }
  116.         }
  117.         return false;
  118.     }
  119.     private function isAssociatedUser(): bool
  120.     {
  121.         return $this->security->isGranted(MenuRolesAssociatedEnum::ROLE_MENU_CATALOG_POINTS_ASSOCIATED);
  122.     }
  123.     private function isAssociatedManagerUser(): bool
  124.     {
  125.         return $this->security->isGranted(UserRolesEnum::ROLE_ASSOCIATED_MANAGER_LONG);
  126.     }
  127.     private function isCoordinatorUser(): bool
  128.     {
  129.         return $this->security->isGranted(UserRolesEnum::ROLE_COORDINATOR_LONG);
  130.     }
  131.     private function isAdminUser(): bool
  132.     {
  133.         return $this->security->isGranted(MenuRolesManagerEnum::ROLE_MENU_CATALOG_POINTS);
  134.     }
  135. }