<?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 DateInterval;
use DateTime;
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('universal_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;
}
}