Easy_solution/src/Repository/UsersOrganizationsRepositor...

275 lines
9.3 KiB
PHP

<?php
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)
{
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')
->select('DISTINCT uo')
->leftJoin('uo.organization', 'o')
->leftJoin('uo.role', 'r')
->addSelect('o', 'r')
->where('uo.users = :userId', 'uo.isActive = :isActive')
->setParameter('userId', $userId)
->setParameter('isActive', true)
->getQuery()
->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')
->andWhere('o.isActive = :orgIsActive') // Check if organization is active
->setParameter('email', $userEmail)
->setParameter('roleName', $roleName)
->setParameter('isActive', true)
->setParameter('orgIsActive', true) // Parameter for organization active status
->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;
}
/**
* Get the last 10 new active users for a specific organization.
* Users are ordered by creation date (most recent first).
*
* @param Organizations $organization
* @return array
*/
public function getLastNewActiveUsersByOrganization(Organizations $organization): array
{
$results = $this->createQueryBuilder('uo')
->select('u.id', 'u.surname', 'u.name', 'u.email', 'u.pictureUrl', 'u.isActive', 'uo.createdAt')
->innerJoin('uo.users', 'u')
->innerJoin('uo.organization', 'o')
->where('uo.isActive = :isActive')
->andWhere('u.isActive = :userIsActive')
->andWhere('o.isActive = :orgIsActive')
->andWhere('uo.organization = :organization')
->setParameter('isActive', true)
->setParameter('userIsActive', true)
->setParameter('orgIsActive', true)
->setParameter('organization', $organization)
->orderBy('uo.createdAt', 'DESC')
->setMaxResults(10)
->getQuery()
->getResult();
// Remove duplicates by user ID (in case user has multiple roles)
$uniqueUsers = [];
foreach ($results as $result) {
$userId = $result['id'];
if (!isset($uniqueUsers[$userId])) {
$uniqueUsers[$userId] = $result;
}
}
return array_values($uniqueUsers);
}
/**
* Get all active admin users for a specific organization.
* Returns users who have the 'ADMIN' role in the given organization.
*
* @param Organizations $organization
* @return array
*/
public function getAdminUsersByOrganization(Organizations $organization): array
{
$results = $this->createQueryBuilder('uo')
->select('u.id', 'u.surname', 'u.name', 'u.email', 'u.pictureUrl', 'u.isActive')
->innerJoin('uo.users', 'u')
->innerJoin('uo.organization', 'o')
->innerJoin('uo.role', 'r')
->where('uo.isActive = :isActive')
->andWhere('u.isActive = :userIsActive')
->andWhere('o.isActive = :orgIsActive')
->andWhere('uo.organization = :organization')
->andWhere('r.name = :roleName')
->setParameter('isActive', true)
->setParameter('userIsActive', true)
->setParameter('orgIsActive', true)
->setParameter('organization', $organization)
->setParameter('roleName', 'ADMIN')
->orderBy('u.surname', 'ASC')
->getQuery()
->getResult();
// Remove duplicates by user ID (in case user has multiple admin-related roles)
$uniqueUsers = [];
foreach ($results as $result) {
$userId = $result['id'];
if (!isset($uniqueUsers[$userId])) {
$uniqueUsers[$userId] = $result;
}
}
return array_values($uniqueUsers);
}
}