Easy_solution/src/Service/UserOrganizationAppService.php

211 lines
7.8 KiB
PHP

<?php
namespace App\Service;
use App\Entity\Apps;
use App\Entity\Roles;
use App\Entity\User;
use App\Entity\UserOrganizationApp;
use App\Entity\UsersOrganizations;
use App\Repository\UserOrganizationAppRepository;
use App\Repository\UsersOrganizationsRepository;
use App\Service\ActionService;
use App\Service\LoggerService;
use App\Service\UserService;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\SecurityBundle\Security;
class UserOrganizationAppService
{
public function __construct(private readonly EntityManagerInterface $entityManager,
private readonly ActionService $actionService,
private readonly Security $security,
private readonly UserService $userService,
private readonly LoggerInterface $logger,
private readonly LoggerService $loggerService,
private readonly UsersOrganizationsRepository $usersOrganizationsRepository,
private readonly UserOrganizationAppRepository $uoaRepository)
{
}
/**
* Groups UserOrganizationApp by application and ensures every app has a group (even if empty).
*
* @param array $userOrgApps Array of UserOrganizatonApp entities
* @param array $allApps Array of all Application entities
* @param int|null $defaultUoId The UserOrganization ID to use for apps with no UOA
* @return array Indexed by app ID: ['uoId' => int|null, 'application' => App, 'selectedRoleIds' => int[]]
*/
public function groupUserOrganizationAppsByApplication(
array $userOrgApps,
array $allApps,
?int $defaultUoId = null
): array {
$grouped = [];
foreach ($userOrgApps as $uoa) {
$app = $uoa->getApplication();
$appId = $app->getId();
$roleEntity = $uoa->getRole();
if (!isset($grouped[$appId])) {
$grouped[$appId] = [
'uoId' => $uoa->getUserOrganization()->getId(),
'application' => $app,
'selectedRoleIds' => [],
];
}
$grouped[$appId]['selectedRoleIds'][] = $roleEntity->getId();
}
// Ensure every app has a group
foreach ($allApps as $app) {
$appId = $app->getId();
if (!isset($grouped[$appId])) {
$grouped[$appId] = [
'uoId' => $defaultUoId,
'application' => $app,
'selectedRoleIds' => [],
];
}
}
return $grouped; // IMPORTANT: keep indexed by appId
}
/**
* Deactivates all the UserOrganizationApp entities for a given UserOrganization.
*
* @param UsersOrganizations $userOrganization
* @return void
*/
public function deactivateAllUserOrganizationsAppLinks(UsersOrganizations $userOrganization, Apps $app = null): void
{
if($app) {
$uoas = $this->uoaRepository->findBy(['userOrganization' => $userOrganization, 'application' => $app, 'isActive' => true]);
} else {
$uoas = $this->uoaRepository->findBy(['userOrganization' => $userOrganization, 'isActive' => true]);
}
foreach ($uoas as $uoa) {
try{
$uoa->setIsActive(false);
$this->actionService->createAction("Deactivate UOA link", $userOrganization->getUsers(),
$userOrganization->getOrganization(), "App: " . $uoa->getApplication()->getName());
$this->entityManager->persist($uoa);
$this->loggerService->logUOALinkDeactivated($uoa->getId(), $uoa->getApplication()->getId());
}catch (\Exception $exception){
$this->loggerService->logCritical("Error deactivating UOA link", [
'uoa_id' => $uoa->getId(),
'app_id' => $uoa->getApplication()->getId(),
'exception_message' => $exception->getMessage(),
]);
}
}
}
/**
* Get users applications links for a given user
*
* @param User $user
* @return Apps[]
*/
public function getUserApplications(User $user): array
{
$uos = $this->entityManager->getRepository(UsersOrganizations::class)->findBy(['users' => $user, 'isActive' => true]);
$apps = [];
foreach ($uos as $uo) {
$uoas = $this->uoaRepository->findBy(['userOrganization' => $uo, 'isActive' => true]);
foreach ($uoas as $uoa) {
$app = $uoa->getApplication();
if (!in_array($app, $apps, true)) {
$apps[] = $app;
}
}
}
return $apps;
}
public function getUserApplicationByOrganization(UsersOrganizations $uo): array
{
$uoas = $this->uoaRepository->findBy(['userOrganization' => $uo, 'isActive' => true]);
$apps = [];
foreach ($uoas as $uoa) {
$app = $uoa->getApplication();
if (!in_array($app, $apps, true)) {
$apps[] = $app;
}
}
return $apps;
}
public function syncUserApplicationsByOrganization(UsersOrganizations $uo, array $selectedApps): void
{
// 1. Get all currently active applications for this specific User-Organization link
$currentUolas = $this->uoaRepository->findBy([
'userOrganization' => $uo,
'isActive' => true
]);
// Track which app IDs are currently active in the DB
$currentAppIds = array_map(fn($uoa) => $uoa->getApplication()->getId(), $currentUolas);
// 2. REMOVAL: Deactivate apps that are in the DB but NOT in the new selection
foreach ($currentUolas as $uoa) {
$appId = $uoa->getApplication()->getId();
if (!in_array($appId, $selectedApps)) {
$uoa->setIsActive(false);
$this->actionService->createAction(
"Deactivate UOA link",
$uo->getUsers(),
$uo->getOrganization(),
"App: " . $uoa->getApplication()->getName()
);
}
}
// 3. ADDITION / REACTIVATION: Handle the selected apps
foreach ($selectedApps as $appId) {
$app = $this->entityManager->getRepository(Apps::class)->find($appId);
if (!$app) continue;
// Check if a record (active or inactive) already exists
$existingUOA = $this->uoaRepository->findOneBy([
'userOrganization' => $uo,
'application' => $app
]);
if (!$existingUOA) {
// Create new if it never existed
$newUOA = new UserOrganizationApp();
$newUOA->setUserOrganization($uo);
$newUOA->setApplication($app);
$newUOA->setIsActive(true);
$this->entityManager->persist($newUOA);
$this->actionService->createAction(
"Activate UOA link",
$uo->getUsers(),
$uo->getOrganization(),
"App: " . $app->getName()
);
} elseif (!$existingUOA->isActive()) {
// Reactivate if it was previously disabled
$existingUOA->setIsActive(true);
$this->actionService->createAction(
"Reactivate UOA link",
$uo->getUsers(),
$uo->getOrganization(),
"App: " . $app->getName()
);
}
}
$this->entityManager->flush();
}
}