src/Security/Voter/PagePermissionVoter.php line 14

Open in your IDE?
  1. <?php
  2. namespace App\Security\Voter;
  3. use App\Entity\User;
  4. use App\Repository\ActionRepository;
  5. use App\Repository\RolePermissionRepository;
  6. use App\Repository\RolesRepository;
  7. use Symfony\Component\HttpFoundation\RequestStack;
  8. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  9. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  10. use Symfony\Component\Security\Core\Security;
  11. class PagePermissionVoter extends Voter
  12. {
  13.     private RolePermissionRepository $rolePermissionRepository;
  14.     private RolesRepository $rolesRepository;
  15.     private ActionRepository $actionRepository;
  16.     private Security $security;
  17.     private RequestStack $requestStack;
  18.     private ?array $supportedActions null;
  19.     public function __construct(
  20.         RolePermissionRepository $rolePermissionRepository,
  21.         RolesRepository $rolesRepository,
  22.         ActionRepository $actionRepository,
  23.         Security $security,
  24.         RequestStack $requestStack
  25.     ) {
  26.         $this->rolePermissionRepository $rolePermissionRepository;
  27.         $this->rolesRepository $rolesRepository;
  28.         $this->actionRepository $actionRepository;
  29.         $this->security $security;
  30.         $this->requestStack $requestStack;
  31.     }
  32.     /**
  33.      * Récupère dynamiquement les actions depuis la base de données
  34.      */
  35.     private function getSupportedActions(): array
  36.     {
  37.         if ($this->supportedActions === null) {
  38.             $actions $this->actionRepository->findAll();
  39.             $this->supportedActions array_map(fn($action) => $action->getCode(), $actions);
  40.         }
  41.         return $this->supportedActions;
  42.     }
  43.     protected function supports(string $attributemixed $subject): bool
  44.     {
  45.         // Supporte toutes les actions présentes dans la table Action
  46.         // Subject doit être une string (code de la page) ou null
  47.         return in_array($attribute$this->getSupportedActions())
  48.             && (is_string($subject) || $subject === null);
  49.     }
  50.     protected function voteOnAttribute(string $attributemixed $subjectTokenInterface $token): bool
  51.     {
  52.         $user $token->getUser();
  53.         // Si l'utilisateur n'est pas connecté, refuser l'accès
  54.         if (!$user instanceof User) {
  55.             return false;
  56.         }
  57.         // Vérifier si l'utilisateur est super admin
  58.         if (in_array('ROLE_SUPER_ADMIN'$user->getRoles())) {
  59.             return true;
  60.         }
  61.         // $subject = code de la page (ex: 'pages', 'users', 'blog_posts')
  62.         $pageCode $subject;
  63.         if (!$pageCode) {
  64.             return false;
  65.         }
  66.         // Rendre insensible à la casse
  67.         $pageCode strtolower($pageCode);
  68.         // Récupérer les permissions depuis la session
  69.         $session $this->requestStack->getSession();
  70.         $userPermissions $session->get('user_permissions', []);
  71.         // Si pas en session, charger depuis la BDD (fallback)
  72.         if (empty($userPermissions)) {
  73.             $userPermissions $this->loadUserPermissionsFromDatabase($user);
  74.             $session->set('user_permissions'$userPermissions);
  75.         }
  76.         // Vérifier si la permission existe
  77.         return isset($userPermissions[$pageCode]) && 
  78.                in_array($attribute$userPermissions[$pageCode]);
  79.     }
  80.     private function loadUserPermissionsFromDatabase(User $user): array
  81.     {
  82.         $permissions = [];
  83.         $userRoles $user->getRoles();
  84.         foreach ($userRoles as $roleString) {
  85.             $roleEntity $this->rolesRepository->findOneBy(['code' => $roleString]);
  86.             
  87.             if (!$roleEntity) {
  88.                 continue;
  89.             }
  90.             $rolePermissions $this->rolePermissionRepository->findBy(['role' => $roleEntity]);
  91.             foreach ($rolePermissions as $rolePermission) {
  92.                 $permission $rolePermission->getPermission();
  93.                 
  94.                 if (!$permission) {
  95.                     continue;
  96.                 }
  97.                 $page $permission->getPage();
  98.                 $action $permission->getAction();
  99.                 if ($page && $action) {
  100.                     $pageCode strtolower($page->getCode());
  101.                     $actionCode strtoupper($action->getCode());
  102.                     if (!isset($permissions[$pageCode])) {
  103.                         $permissions[$pageCode] = [];
  104.                     }
  105.                     if (!in_array($actionCode$permissions[$pageCode])) {
  106.                         $permissions[$pageCode][] = $actionCode;
  107.                     }
  108.                 }
  109.             }
  110.         }
  111.         return $permissions;
  112.     }
  113. }