diff --git a/src/Controller/UserController.php b/src/Controller/UserController.php index 62f5d17..5655ac4 100644 --- a/src/Controller/UserController.php +++ b/src/Controller/UserController.php @@ -20,6 +20,7 @@ use Symfony\Component\Routing\Attribute\Route; class UserController extends AbstractController { private const NOT_FOUND = 'Entity not found'; + private const ACCESS_DENIED = 'Access denied'; public function __construct( private readonly UserOrganizationService $userOrganizationService, @@ -35,12 +36,16 @@ class UserController extends AbstractController public function index(EntityManagerInterface $entityManager): Response { if ($this->isGranted('ROLE_SUPER_ADMIN')) { - $users = $entityManager->getRepository(User::class)->getAllActiveUsers(); + $usersByOrganization = $entityManager->getRepository(UsersOrganizations::class)->getActiveUsersGroupedByOrganization(); + } else { - $users = 'Not Super Admin'; + $userIdentifier = $this->getUser()->getUserIdentifier(); + $organizations = $this->entityManager->getRepository(UsersOrganizations::class)->findOrganizationsByUserEmailAndRoleName($userIdentifier, 'ADMIN'); + $usersByOrganization = $this->entityManager->getRepository(UsersOrganizations::class) + ->findActiveUsersByOrganizations($organizations); } return $this->render('user/index.html.twig', [ - 'users' => $users, + 'usersByOrganization' => $usersByOrganization, 'controller_name' => 'IndexController', ]); } @@ -52,7 +57,7 @@ class UserController extends AbstractController public function show(int $id, EntityManagerInterface $entityManager): Response { if (!$this->isGranted('ROLE_SUPER_ADMIN')) { - throw $this->createAccessDeniedException('Access denied'); + throw $this->createAccessDeniedException(self::ACCESS_DENIED); } $user = $entityManager->getRepository(User::class)->find($id); @@ -108,7 +113,7 @@ class UserController extends AbstractController { //Handle access control if (!$this->isGranted('ROLE_SUPER_ADMIN')) { - throw $this->createAccessDeniedException('Access denied'); + throw $this->createAccessDeniedException(self::ACCESS_DENIED); } //Fetch user by ID and handle not found case @@ -148,7 +153,7 @@ class UserController extends AbstractController //Handle access control if (!$this->isGranted('ROLE_SUPER_ADMIN')) { - throw $this->createAccessDeniedException('Access denied'); + throw $this->createAccessDeniedException(self::ACCESS_DENIED); } //Fetch user by ID and handle not found case $user = $entityManager->getRepository(User::class)->find($id); @@ -171,7 +176,7 @@ class UserController extends AbstractController public function delete(int $id, EntityManagerInterface $entityManager): Response { if (!$this->isGranted('ROLE_SUPER_ADMIN')) { - throw $this->createAccessDeniedException('Access denied'); + throw $this->createAccessDeniedException(self::ACCESS_DENIED); } $user = $entityManager->getRepository(User::class)->find($id); diff --git a/src/Repository/UserOrganizationAppRepository.php b/src/Repository/UserOrganizationAppRepository.php deleted file mode 100644 index 8776484..0000000 --- a/src/Repository/UserOrganizationAppRepository.php +++ /dev/null @@ -1,43 +0,0 @@ - - */ -class UserOrganizationAppRepository extends ServiceEntityRepository -{ - public function __construct(ManagerRegistry $registry) - { - parent::__construct($registry, UserOrganizationApp::class); - } - -// /** -// * @return UserOrganizationApp[] Returns an array of UserOrganizationApp objects -// */ -// public function findByExampleField($value): array -// { -// return $this->createQueryBuilder('u') -// ->andWhere('u.exampleField = :val') -// ->setParameter('val', $value) -// ->orderBy('u.id', 'ASC') -// ->setMaxResults(10) -// ->getQuery() -// ->getResult() -// ; -// } - -// public function findOneBySomeField($value): ?UserOrganizationApp -// { -// return $this->createQueryBuilder('u') -// ->andWhere('u.exampleField = :val') -// ->setParameter('val', $value) -// ->getQuery() -// ->getOneOrNullResult() -// ; -// } -} diff --git a/src/Repository/UsersOrganizationsRepository.php b/src/Repository/UsersOrganizationsRepository.php index d7bd828..d65d117 100644 --- a/src/Repository/UsersOrganizationsRepository.php +++ b/src/Repository/UsersOrganizationsRepository.php @@ -2,11 +2,16 @@ namespace App\Repository; +use App\Entity\User; use App\Entity\UsersOrganizations; +use App\Entity\Organizations; +use App\Entity\Roles; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Persistence\ManagerRegistry; - +/** + * @extends ServiceEntityRepository + */ class UsersOrganizationsRepository extends ServiceEntityRepository { public function __construct(ManagerRegistry $registry) @@ -14,6 +19,12 @@ class UsersOrganizationsRepository extends ServiceEntityRepository parent::__construct($registry, UsersOrganizations::class); } + /** + * Find all distinct active organizations for a given user ID. + * + * @param int $userId + * @return UsersOrganizations[] + */ public function findAllDistinctOrganizationsByUserId(int $userId): array { return $this->createQueryBuilder('uo') @@ -28,4 +39,157 @@ class UsersOrganizationsRepository extends ServiceEntityRepository ->getResult(); } + /** + * Find all organizations where a user (by email) has a specific role. + * + * @param string $userEmail + * @param string $roleName + * @return Organizations[] + */ + public function findOrganizationsByUserEmailAndRoleName(string $userEmail, string $roleName): array + { + $results = $this->createQueryBuilder('uo') + ->innerJoin('uo.users', 'u') + ->innerJoin('uo.organization', 'o') + ->innerJoin('uo.role', 'r') + ->where('u.email = :email') + ->andWhere('r.name = :roleName') + ->andWhere('uo.isActive = :isActive') + ->setParameter('email', $userEmail) + ->setParameter('roleName', $roleName) + ->setParameter('isActive', true) + ->getQuery() + ->getResult(); + + return array_map(fn($uo) => $uo->getOrganization(), $results); + } + + /** + * Get all active users grouped by organization. + * Users with no organization are grouped under 'autre'. + * + * @return array + */ + public function getActiveUsersGroupedByOrganization(): array + { + $users = $this->getEntityManager()->getRepository(User::class)->getAllActiveUsers(); + $userOrgs = $this->getAllActiveUserOrganizationLinks(); + + $userToOrgs = $this->mapUserToOrganizations($userOrgs); + + $orgs = []; + foreach ($users as $user) { + $userId = $user['id']; + if (isset($userToOrgs[$userId])) { + foreach ($userToOrgs[$userId] as $orgInfo) { + $orgId = $orgInfo['organization_id']; + if (!isset($orgs[$orgId])) { + $orgs[$orgId] = [ + 'organization_id' => $orgId, + 'organization_name' => $orgInfo['organization_name'], + 'users' => [], + ]; + } + $orgs[$orgId]['users'][$userId] = $user; + } + } else { + if (!isset($orgs['autre'])) { + $orgs['autre'] = [ + 'organization_id' => null, + 'organization_name' => 'autre', + 'users' => [], + ]; + } + $orgs['autre']['users'][$userId] = $user; + } + } + + // Convert users arrays to indexed arrays + foreach ($orgs as &$org) { + $org['users'] = array_values($org['users']); + } + + return array_values($orgs); + } + + /** + * Get all active users for each organization in the given array. + * + * @param Organizations[] $organizations + * @return array + */ + public function findActiveUsersByOrganizations(array $organizations): array + { + if (empty($organizations)) { + return []; + } + + $userOrgs = $this->getAllActiveUserOrganizationLinks($organizations); + + $usersByOrg = []; + foreach ($userOrgs as $uo) { + $org = $uo->getOrganization(); + $orgId = $org->getId(); + if (!isset($usersByOrg[$orgId])) { + $usersByOrg[$orgId] = [ + 'organization_id' => $orgId, + 'organization_name' => $org->getName(), + 'users' => [], + ]; + } + $userId = $uo->getUsers()->getId(); + $usersByOrg[$orgId]['users'][$userId] = $uo->getUsers(); + } + + // Convert users arrays to indexed arrays + foreach ($usersByOrg as &$org) { + $org['users'] = array_values($org['users']); + } + + return array_values($usersByOrg); + } + + /** + * Helper: Get all active UsersOrganizations links, optionally filtered by organizations. + * + * @param Organizations[]|null $organizations + * @return UsersOrganizations[] + */ + private function getAllActiveUserOrganizationLinks(array $organizations = null): array + { + $qb = $this->createQueryBuilder('uo') + ->innerJoin('uo.organization', 'o') + ->innerJoin('uo.users', 'u') + ->where('uo.isActive = :isActive') + ->setParameter('isActive', true); + + if (!empty($organizations)) { + $qb->andWhere('o IN (:organizations)') + ->setParameter('organizations', $organizations); + } + + return $qb->getQuery()->getResult(); + } + + /** + * Helper: Map userId to their organizations (id and name), avoiding duplicates. + * + * @param UsersOrganizations[] $userOrgs + * @return array + */ + private function mapUserToOrganizations(array $userOrgs): array + { + $userToOrgs = []; + foreach ($userOrgs as $uo) { + $userId = $uo->getUsers()->getId(); + $org = $uo->getOrganization(); + $orgId = $org->getId(); + $orgName = $org->getName(); + $userToOrgs[$userId][$orgId] = [ + 'organization_id' => $orgId, + 'organization_name' => $orgName, + ]; + } + return $userToOrgs; + } } diff --git a/templates/elements/menu.html.twig b/templates/elements/menu.html.twig index 1a1ffb2..dfbfbed 100644 --- a/templates/elements/menu.html.twig +++ b/templates/elements/menu.html.twig @@ -23,7 +23,7 @@ {# if user is Super Admin#} - {% if is_granted('ROLE_SUPER_ADMIN') %} + {% if is_granted('ROLE_ADMIN') %}