changed user index logic
This commit is contained in:
parent
f1b953d005
commit
00e3003257
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -1,43 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\UserOrganizationApp;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
* @extends ServiceEntityRepository<UserOrganizationApp>
|
||||
*/
|
||||
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()
|
||||
// ;
|
||||
// }
|
||||
}
|
||||
|
|
@ -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<UsersOrganizations>
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
</div>
|
||||
</li>
|
||||
{# if user is Super Admin#}
|
||||
{% if is_granted('ROLE_SUPER_ADMIN') %}
|
||||
{% if is_granted('ROLE_ADMIN') %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ path('user_index') }}">
|
||||
<i class="icon-grid menu-icon">{{ ux_icon('bi:menu-up', {height: '15px', width: '15px'}) }}</i>
|
||||
|
|
|
|||
|
|
@ -3,46 +3,50 @@
|
|||
{% block title %}User Profile{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div class="w-100 h-100 p-5 m-auto " data-controller="user">
|
||||
<div class="w-100 h-100 p-5 m-auto" data-controller="user">
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h1>Gestion Utilisateurs</h1>
|
||||
<a href="{{ path('user_new') }}" class="btn btn-primary">Ajouter un utilisateur</a>
|
||||
</div>
|
||||
|
||||
|
||||
<table class="table align-middle shadow">
|
||||
<thead class="table-light shadow-sm">
|
||||
<tr>
|
||||
<th>Picture</th>
|
||||
<th>Surname</th>
|
||||
<th>Name</th>
|
||||
<th>Email</th>
|
||||
<th>Visualiser</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for user in users %}
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>{{ user.surname }}</td>
|
||||
<td>{{ user.name }}</td>
|
||||
<td>{{ user.email }}</td>
|
||||
<td>
|
||||
<a href="{{ path('user_show', {'id': user.id}) }}" class="p-3 align-middle">
|
||||
<i class="icon-grid menu-icon color-primary">
|
||||
{{ ux_icon('fa6-regular:eye', {height: '30px', width: '30px'}) }}
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% if users|length == 0 %}
|
||||
{% for org in usersByOrganization %}
|
||||
<h2 class="mt-5 mb-3">{{ org.organization_name|title }}</h2>
|
||||
<table class="table align-middle shadow">
|
||||
<thead class="table-light shadow-sm">
|
||||
<tr>
|
||||
<td colspan="5" class="text-center">Aucun utilisateur trouvé.</td>
|
||||
<th>Picture</th>
|
||||
<th>Surname</th>
|
||||
<th>Name</th>
|
||||
<th>Email</th>
|
||||
<th>Visualiser</th>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for user in org.users %}
|
||||
<tr>
|
||||
<td>
|
||||
{% if user.pictureUrl %}
|
||||
<img src="{{ asset(user.pictureUrl) }}" alt="User profile pic" class="rounded-circle" style="width:40px; height:40px;">
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{{ user.surname }}</td>
|
||||
<td>{{ user.name }}</td>
|
||||
<td>{{ user.email }}</td>
|
||||
<td>
|
||||
<a href="{{ path('user_show', {'id': user.id}) }}" class="p-3 align-middle">
|
||||
<i class="icon-grid menu-icon color-primary">
|
||||
{{ ux_icon('fa6-regular:eye', {height: '30px', width: '30px'}) }}
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% if org.users|length == 0 %}
|
||||
<tr>
|
||||
<td colspan="5" class="text-center">Aucun utilisateur trouvé.</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
Loading…
Reference in New Issue