<?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;
}
}