<?php
namespace App\Controller\Front;
use App\Constants\Platform;
use App\Constants\Setting as ConstSetting;
use App\Entity\User;
use App\Services\Common\Point\UserPointService;
use App\Services\Common\PlatformService;
use App\Services\Common\Point\UserPointServiceInterface;
use App\Services\Common\SettingService;
use App\Services\Common\User\WorkflowUser;
use App\Services\Portal\PortalService;
use App\Services\Security\EncryptionManager;
use Doctrine\ORM\EntityManagerInterface;
use Exception;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\KernelInterface;
class HomePageController extends AbstractController
{
private UserPointServiceInterface $userPointService;
private EntityManagerInterface $em;
private PlatformService $platformService;
private WorkflowUser $workflowUser;
private PortalService $portalService;
private SettingService $settingService;
private KernelInterface $kernel;
private EncryptionManager $encryptionManager;
/**
* @throws Exception
*/
public function __construct(
EntityManagerInterface $em,
PlatformService $platformService,
WorkflowUser $workflowUser,
UserPointService $userPointService,
PortalService $portalService,
SettingService $settingService,
KernelInterface $kernel,
EncryptionManager $encryptionManager
) {
$this->userPointService = $userPointService;
$this->em = $em;
$this->platformService = $platformService;
$this->workflowUser = $workflowUser;
$this->portalService = $portalService;
$this->settingService = $settingService;
$this->kernel = $kernel;
$this->encryptionManager = $encryptionManager;
}
/**
* Page d'accueil pour les utilisateurs identifiés
*
* @param Request $request
*
* @return Response
*
* @throws Exception
*/
public function show(Request $request): Response
{
if ($this->platformService->getType() === 'dtv') {
return $this->redirectToRoute('dtv_back_dashboard_show');
}
/** @var User $currentUser */
$currentUser = $this->getUser();
$t = $this->userPointService->getLevel($currentUser);
$totalMovement = [
"debit" => $this->userPointService->getSpendedPoints($currentUser),
"credit" => $this->userPointService->getFidelityPoints($currentUser),
'expired' => $this->userPointService->getExpiredPoints($currentUser),
'exceptional' => $this->userPointService->getExceptionalPoints($currentUser),
];
if ($request->getMethod() === 'POST')
{
$choice = $request->request->get('donneesPersonnellesChoice');
$currentUser->setDonneesPersonnelles($choice);
if ($choice === FALSE)
{
$this->workflowUser->unsubscribeUser($currentUser);
return $this->redirectToRoute('saml_logout');
}
$this->em->flush();
}
$data = ['totalPoint' => $totalMovement, 't' => $t];
if ($this->platformService->getType() === Platform::PORTAIL)
{
$platforms = $this->settingService->getValueFromName(ConstSetting::PORTAL_PARENT);
$listToClose = $listWithoutGroup = $listGroups = [];
$hasGroups = true;
$listWithAlert = [];
$now = new \DateTime();
$now30days = new \DateTime();
$now30days->add(new \DateInterval("P30D"));
if(isset($platforms[ 'children' ]))
{
foreach ($platforms[ 'children' ] as $key => $child)
{
if (!$currentUser->isDeveloperOrSuperAdmin())
{
$continue = true;
if(!empty($child[ 'roles']))
{
foreach($currentUser->getRoles() as $role)
{
if(in_array($role, $child['roles']))
{
$continue = false;
break;
}
}
// controle strict sur le role
// if($continue) continue;
}
if($continue && !empty($child['jobs']) && !in_array($currentUser->getJob(), $child['jobs'])) continue;
}
$platformInfo = $this->portalService->fetchChildrenPlatformFromApi($currentUser, $child[ 'url' ]);
if ($platformInfo->getStatusCode() === Response::HTTP_INTERNAL_SERVER_ERROR)
{
$listWithAlert[] = [
'url' => $child[ 'url' ],
'code' => $platformInfo->getStatusCode(),
'content' => json_decode($platformInfo->getContent(), TRUE) ?? $platformInfo->getContent(),
];
continue;
}
$response = json_decode($platformInfo->getContent(), TRUE);
$response = $response['content'];
$response['platform']['roles'] = $child['roles'];
$response['platform']['jobs'] = $child['jobs'];
$startDate = $response[ 'platform' ][ 'startDate' ] ?? null;
$endDate = $response[ 'platform' ][ 'endDate' ] ?? null;
if(!empty($endDate)) $endDate = new \DateTime($endDate);
if(!empty($startDate)) $startDate = new \DateTime($startDate);
// On ne prend pas en compte les plateformes fermées
if (!$currentUser->isDeveloperOrSuperAdmin() && isset($response[ 'platform' ][ 'enabled' ]) && $response[ 'platform' ][ 'enabled' ] === "0") {
continue;
}
// On ne prend pas en compte dont la date est inferieur à la date d'ouverture de la plateforme
if (!$currentUser->isDeveloperOrSuperAdmin() && $startDate && $now < $startDate) continue;
// On ne prend pas en compte dont la date de fin est dépassée
if (!$currentUser->isDeveloperOrSuperAdmin() && $endDate && $now > $endDate) continue;
// On autorise l'accès par défaut au référent pour tous les users, sinon on autorise par défaut les admins, superadmins et développeurs
if ($child[ 'referent' ] || $currentUser->isAdmin() || $currentUser->isDeveloperOrSuperAdmin()) {
$response[ 'platform' ][ 'canAccess' ] = TRUE;
}
$response[ 'platform' ][ 'referent' ] = $child[ 'referent' ];
$childUrl = base64_encode($child[ 'url' ]);
$response[ 'platform' ][ 'login_url' ] = $this->generateUrl('create_user_on_children_via_api', [
'child' => $childUrl,
'userNotFound' => $response[ 'platform' ][ 'userNotFound' ] ?? FALSE,
]);
$groupe = $child['groupe'];
if(empty($groupe))
{
$groupe = 'Autre Plateformes';
$platforms[ 'children' ][$key]['groupe'] = $groupe;
}
$listGroups[$groupe][] = $response;
$listWithoutGroup[] = $response;
if($endDate < $now30days) $listToClose[] = $response;
}
}
$list = $listGroups;
$this->orderPlatform($listWithoutGroup);
if(count($listGroups) === 1)
{
$list = $listWithoutGroup;
$hasGroups = false;
}
if($hasGroups)
{
foreach($list as $groupe => $plts)
{
$this->orderPlatform($plts);
$list[$groupe] = $plts;
}
if (!$currentUser->isDeveloperOrSuperAdmin())
{
uasort($list, function ($groupeA, $groupeB) use($currentUser)
{
$scoreA = $scoreB = 0;
$this->scoreGroup($groupeA, $scoreA, $currentUser);
$this->scoreGroup($groupeB, $scoreB, $currentUser);
if($scoreA === $scoreB) return 0;
return ($scoreA < $scoreB) ? 1 : -1;
});
}
}
$data[ 'portailData' ][ 'list' ] = $list;
$data[ 'portailData' ][ 'listWithoutGroup' ] = $listWithoutGroup;
$data[ 'portailData' ][ 'listWithAlert' ] = $listWithAlert;
$data[ 'portailData' ][ 'listToClose' ] = $listToClose;
$data[ 'portailData' ][ 'hasGroups' ] = $hasGroups;
}
return $this->render('front/homepage/show.html.twig', $data);
}
private function scoreGroup(array $group, int &$score, User $user)
{
foreach ($group as $plateforme)
{
$plateforme = $plateforme['platform'];
if(!empty($plateforme['roles']))
{
foreach($user->getRoles() as $role)
{
if(in_array($role, $plateforme['roles']))
{
$score ++;
}
}
}
if(!empty($plateforme['jobs']) && in_array($user->getJob(), $plateforme['jobs'])) $score += 2;
}
}
/**
* Ordonne la liste des enfants du portail, indique si la plateforme est référente, retourne la liste des plateformes fermant dans les 30j ours
*
* @param $platforms
*
* @return array
*/
private function orderPlatform(&$platforms): array
{
// Fonction de comparaison pour le tri
usort($platforms, static function ($a, $b) {
// Si l'objet a la clé "referent" à TRUE, le placer en première position
if (isset($a[ 'platform' ][ 'referent' ]) && $a[ 'platform' ][ 'referent' ] === TRUE) {
return -1;
}
if (isset($b[ 'platform' ][ 'referent' ]) && $b[ 'platform' ][ 'referent' ] === TRUE) {
return 1;
}
// Sinon, trier par startDate
if(isset($a[ 'platform' ][ 'startDate' ]) && isset($b[ 'platform' ][ 'startDate' ]))
{
return strtotime($a[ 'platform' ][ 'startDate' ]) - strtotime($b[ 'platform' ][ 'startDate' ]);
}
return -1;
});
// Obtenez la date actuelle
$currentDate = time();
$list = [];
// Parcoure le tableau trié
foreach ($platforms as $object)
{
if(isset($object[ 'platform' ][ 'endDate' ]))
{
// Convertissez la date de fin en timestamp
$endDateTimestamp = strtotime($object[ 'platform' ][ 'endDate' ]);
// Vérifiez si la date de fin est inférieure à 30 jours de la date actuelle
if ($endDateTimestamp < ($currentDate + (30 * 24 * 60 * 60))) {
$list[] = $object;
}
}
}
if(isset($a[ 'platform' ][ 'endDate' ]) && isset($b[ 'platform' ][ 'endDate' ]))
{
usort($list, static function ($a, $b) {
return strtotime($a[ 'platform' ][ 'endDate' ]) - strtotime($b[ 'platform' ][ 'endDate' ]);
});
}
return $list;
}
}