src/Security/Voter/PromptTemplateVoter.php line 20

  1. <?php
  2. namespace App\Security\Voter;
  3. use App\Entity\CRM\Admin;
  4. use App\Entity\CRM\Branch;
  5. use App\Entity\CRM\PromptTemplate;
  6. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  7. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  8. use Symfony\Component\Security\Core\User\UserInterface;
  9. /**
  10.  * Reguły dostępu do PromptTemplate:
  11.  *  - prompty SYSTEM (każdy branch i globalny) - edycja tylko ROLE_SUPER,
  12.  *  - pozostałe prompty (SALES/SENTIMENT/OVERALL):
  13.  *      * globalne (tenant=null) - tylko ROLE_SUPER,
  14.  *      * branch-specific - ROLE_SUPER albo ROLE_ADMIN przypisany do tego branchu,
  15.  *  - VIEW dostępny dla ROLE_ADMIN i ROLE_SUPER.
  16.  */
  17. class PromptTemplateVoter extends Voter
  18. {
  19.     public const VIEW 'PROMPT_VIEW';
  20.     public const EDIT 'PROMPT_EDIT';
  21.     protected function supports(string $attributemixed $subject): bool
  22.     {
  23.         if (!in_array($attribute, [self::VIEWself::EDIT], true)) {
  24.             return false;
  25.         }
  26.         return $subject instanceof PromptTemplate;
  27.     }
  28.     protected function voteOnAttribute(string $attributemixed $subjectTokenInterface $token): bool
  29.     {
  30.         $user $token->getUser();
  31.         if (!$user instanceof Admin) {
  32.             return false;
  33.         }
  34.         /** @var PromptTemplate $subject */
  35.         return match ($attribute) {
  36.             self::VIEW => $this->canView($user),
  37.             self::EDIT => $this->canEdit($subject$user),
  38.             default => false,
  39.         };
  40.     }
  41.     public function canView(UserInterface $user): bool
  42.     {
  43.         if (!$user instanceof Admin) {
  44.             return false;
  45.         }
  46.         return $this->hasRole($user'ROLE_SUPER') || $this->hasRole($user'ROLE_ADMIN');
  47.     }
  48.     public function canEdit(PromptTemplate $templateUserInterface $user): bool
  49.     {
  50.         if (!$user instanceof Admin) {
  51.             return false;
  52.         }
  53.         if ($this->hasRole($user'ROLE_SUPER')) {
  54.             return true;
  55.         }
  56.         if (!$this->hasRole($user'ROLE_ADMIN')) {
  57.             return false;
  58.         }
  59.         // Tylko ROLE_SUPER może dotykać SYSTEM-u albo promptów globalnych.
  60.         if ($template->requiresSuperAdmin()) {
  61.             return false;
  62.         }
  63.         if ($template->getTenant() === null) {
  64.             return false;
  65.         }
  66.         return $this->adminHasBranch($user$template->getTenant());
  67.     }
  68.     private function hasRole(UserInterface $userstring $role): bool
  69.     {
  70.         return in_array($role$user->getRoles(), true);
  71.     }
  72.     private function adminHasBranch(Admin $adminBranch $branch): bool
  73.     {
  74.         $branchId $branch->getId();
  75.         if ($branchId === null) {
  76.             return false;
  77.         }
  78.         if (!method_exists($admin'getBranches')) {
  79.             return false;
  80.         }
  81.         foreach ($admin->getBranches() as $assigned) {
  82.             if ($assigned instanceof Branch && $assigned->getId() === $branchId) {
  83.                 return true;
  84.             }
  85.         }
  86.         return false;
  87.     }
  88. }