src/Security/Voter/WorkroomArenaVoter.php line 17

Open in your IDE?
  1. <?php
  2. namespace App\Security\Voter;
  3. use App\Entity\User;
  4. use App\Entity\UserWorkroom;
  5. use App\Entity\UserWorkroomArena;
  6. use App\Entity\WorkroomArena;
  7. use Doctrine\ORM\EntityManagerInterface;
  8. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  9. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  10. use Symfony\Component\Security\Core\User\UserInterface;
  11. /**
  12.  * Class WorkroomArenaVoter.
  13.  */
  14. class WorkroomArenaVoter extends Voter
  15. {
  16.     // Permissions.
  17.     const WORKROOM_ARENA_VIEW 'workroom__arena_view';
  18.     // Full list.
  19.     const PERMISSIONS = [
  20.         self::WORKROOM_ARENA_VIEW,
  21.     ];
  22.     private EntityManagerInterface $em;
  23.     public function __construct(EntityManagerInterface $em)
  24.     {
  25.         $this->em $em;
  26.     }
  27.     /**
  28.      * {@inheritdoc}
  29.      */
  30.     protected function supports($attribute$subject): bool
  31.     {
  32.         return in_array($attributeself::PERMISSIONS) && ($subject instanceof WorkroomArena);
  33.     }
  34.     /**
  35.      * {@inheritdoc}
  36.      */
  37.     protected function voteOnAttribute($attribute$subjectTokenInterface $token): bool
  38.     {
  39.         /** @var User $user */
  40.         $user $token->getUser();
  41.         // If the user is anonymous, do not grant access.
  42.         if (!$user instanceof UserInterface) {
  43.             return false;
  44.         }
  45.         // Check conditions and provide access bases on it.
  46.         switch ($attribute) {
  47.             case self::WORKROOM_ARENA_VIEW:
  48.                 return $this->canView($subject$user);
  49.             default:
  50.                 break;
  51.         }
  52.         return false;
  53.     }
  54.     /**
  55.      * Vérifie l'accès à une arène de workroom.
  56.      *
  57.      * Logique :
  58.      *  1. Si user explicitement dans `user_workroom_arena` → accès accordé (membre direct)
  59.      *  2. Sinon fallback : si user membre du **workroom parent** (`user_workroom`)
  60.      *     → accès accordé. L'arène est un canal de la workroom — tout membre du
  61.      *     workroom y a accès par défaut. Cette logique évite que des users importés
  62.      *     d'une vieille DB (sans `user_workroom_arena` rempli) soient bloqués.
  63.      *  3. Sinon refus.
  64.      *
  65.      * Les ROLE_ADMIN passent toujours (gestion).
  66.      */
  67.     public function canView(WorkroomArena $workroomArenaUser $user): bool
  68.     {
  69.         if (in_array('ROLE_ADMIN'$user->getRoles(), true)) return true;
  70.         // 1. Membre direct de l'arène
  71.         $userWorkroomArena $this->em->getRepository(UserWorkroomArena::class)->findBy([
  72.             'workroomArena' => $workroomArena->getId(),
  73.             'user' => $user->getId(),
  74.         ]);
  75.         if (!empty($userWorkroomArena)) return true;
  76.         // 2. Fallback : membre du workroom parent
  77.         $workroom $workroomArena->getWorkroom();
  78.         if (!$workroom) return false;
  79.         $userWorkroom $this->em->getRepository(UserWorkroom::class)->findBy([
  80.             'workroom' => $workroom->getId(),
  81.             'user' => $user->getId(),
  82.         ]);
  83.         return !empty($userWorkroom);
  84.     }
  85. }