<?php
namespace App\Controller\Api\v3;
use App\Entity\QuestionAnswer;
use App\Entity\SaltOperation;
use App\Entity\Survey;
use App\Entity\SurveyAnswer;
use App\Entity\SurveyQuestion;
use App\Entity\SurveyQuestionChoice;
use App\Entity\ThinClient;
use App\Entity\ThinClientCommand;
use App\Service\PollManagerService;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Serializer\SerializerInterface;
#[Route(path: '/api/v3')]
class ThinclientController extends AbstractController
{
#[Route("/thinclients/{token}", methods: ["POST"])]
public function startThinclients(String $token, Request $request, ManagerRegistry $doctrine): JsonResponse
{
$thinclient = $doctrine->getRepository(ThinClient::class)->findOneBySoftwareId($token);
// --- Gestion de la mise à jour des données de l'écran:
$startData = json_decode($request->getContent(), true);
if ($thinclient) {
$thinclient->setLastStatusUpdate(new \DateTime());
if ($startData["action"] == "start") {
$thinclient->setSoftwareVersion($startData["app_version"]);
$thinclient->setToken($startData["sys_version"]);
}
// Gestion de la qualité réseau :
if (array_key_exists('network_quality', $startData)) {
$thinclient->setNetworkQuality($startData["network_quality"]);
}
$doctrine->getManager()->persist($thinclient);
$doctrine->getManager()->flush();
}
return new JsonResponse([
"thinclient_id" => $thinclient ? $thinclient->getSoftwareId() : 0,
"thinclient_accept" => $thinclient ? $thinclient->getRegistration() : null,
"thinclient_name" => $thinclient ? $thinclient->getName() : null,
"thinclient_attach" => $thinclient
? $thinclient->getEntrance() ? $thinclient->getEntrance()->getId() : null
: null,
]);
}
#[Route("/thinclients/register/{token}", methods: ["POST"])]
public function registerThinclients(String $token, Request $request, ManagerRegistry $doctrine): JsonResponse
{
$registerData = json_decode($request->getContent(), true);
$thinclient = $doctrine->getRepository(ThinClient::class)->findOneBySoftwareId($token);
if ($thinclient) {
return new JsonResponse([
"error" => "THINCLIENT EXISTING",
]);
}
$thinClient = new ThinClient();
$thinClient->setName($registerData["screen_name"]);
$thinClient->setSoftwareVersion($registerData["screen_app_version"]);
$thinClient->setMacAddress($registerData["connection_mode"]);
$thinClient->setImsi($registerData["sim_card"]);
$thinClient->setToken($registerData["sys_version"]);
$thinClient->setLastKnownStatus(ThinClient::STATUS_UNACCEPTED);
$thinClient->resetDataConsumption();
$thinClient->setSoftwareId($token);
$thinClient->setIpAddress(date('j n Y h:i:s A'));
$registerOperation = new SaltOperation();
$registerOperation->setStatus(2);
$registerOperation->setDate(new \DateTime('now', new \DateTimeZone('UTC')));
$registerOperation->setType('production');
$registerOperation->setThinclient($thinClient);
$thinClient->addSaltOperation($registerOperation);
$doctrine->getManager()->persist($thinClient);
$doctrine->getManager()->persist($registerOperation);
$doctrine->getManager()->flush();
return new JsonResponse([
"error" => null,
"test" => $registerData["screen_name"],
]);
}
#[Route("/thinclients/poll/{token}", methods: ["POST"])]
public function pollThinclients(String $token, Request $request, ManagerRegistry $doctrine, PollManagerService $pollManager): JsonResponse
{
$thinclient = $doctrine->getRepository(ThinClient::class)->findOneBySoftwareId($token);
// --- Mise à jour du status et de la date du ping:
$thinClientStatus = $thinclient->getLastKnownStatus();
if (ThinClient::STATUS_UNKNOWN == $thinClientStatus) {
$thinclient->setLastKnownStatus(ThinClient::STATUS_UP);
}
$thinclient->setLastStatusUpdate(new \DateTime());
// --- Décompte des pings:
$lastCounter_db = $thinclient->getIpVpn();
$counter = null;
$lastCounter = null;
$now = new \DateTime();
if ($lastCounter_db == "nc" || !$lastCounter_db) {
$counter = [];
$counter["timestamp"] = $now->setTime(23, 0, 0)->getTimestamp();
$counter["value"] = 1;
} else {
$lastCounter = json_decode($lastCounter_db, true);
if ($now->getTimestamp() > $lastCounter["timestamp"]) {
$counter["value"] = 1;
$counter["timestamp"] = $now->setTime(23, 0, 0)->getTimestamp();
} else {
$counter["timestamp"] = $lastCounter["timestamp"];
$counter["value"] = $lastCounter["value"] + 1;
}
}
$thinclient->setIpVpn(json_encode($counter));
$doctrine->getManager()->persist($thinclient);
$doctrine->getManager()->flush();
$pollData = json_decode($request->getContent(), true);
$result = $pollManager->processThinclientRequest($thinclient, $pollData);
// Gestion de la qualité réseau :
if (array_key_exists('network_quality', $pollData)) {
$thinclient->setNetworkQuality($pollData["network_quality"]);
$doctrine->getManager()->persist($thinclient);
$doctrine->getManager()->flush();
}
// Gestion des commandes:
if (array_key_exists('commands', $pollData)) {
$returnCommands = $pollData["commands"];
for ($i=0; $i < (is_countable($returnCommands) ? count($returnCommands) : 0); $i++) {
$cmd = $doctrine->getRepository(ThinClientCommand::class)->find($returnCommands[$i]["id"]);
if ($returnCommands[$i]["result"] == 1) {
$cmd->setStatus(1);
$cmd->setDateSuccess(new \DateTime());
} else {
$cmd->setStatus(2);
}
$doctrine->getManager()->persist($cmd);
$doctrine->getManager()->flush();
}
}
$commandsList = [];
$commands = $doctrine->getRepository(ThinClientCommand::class)->findBy(
["thinclient" => $thinclient->getId()]
);
for ($i=0; $i < count($commands); $i++) {
if ($commands[$i]->getStatus() == 0) {
$cmd = [];
$cmd["id"] = $commands[$i]->getId();
$cmd["operation"] = $commands[$i]->getOperation();
array_push($commandsList, $cmd);
}
}
// --- Gestion des enquêtes reçues :
$surveysSaved = [];
if (array_key_exists('surveys', $pollData)) {
$returnSurveys = $pollData["surveys"];
for ($i=0; $i < count($returnSurveys); $i++) {
// --- Création d'une nouvelle réponse à une enquête :
$surveyAnswer = new SurveyAnswer();
$date = (new \DateTimeImmutable())->createFromFormat("Y-m-d\TH:i:s.u\Z", $returnSurveys[$i]["date"]);
$surveyAnswer->setCreatedAt($date);
$survey = $doctrine->getRepository(Survey::class)->find($returnSurveys[$i]["surveyId"]);
if ($survey) {
$surveyAnswer->setSurvey($survey);
}
// --- Création des réponses aux questions de l'enquête :
for ($j=0; $j < count($returnSurveys[$i]["answers"]); $j++) {
$questionAnswer = new QuestionAnswer();
$questionAnswer->setSurveyAnswer($surveyAnswer);
$questionAnswer->setCreatedAt($date);
$asw = $returnSurveys[$i]["answers"][$j];
$choice = $doctrine->getRepository(SurveyQuestionChoice::class)->find($asw["id"]);
$questionAnswer->setSelectedChoice($choice);
$questionAnswer->setQuestion($choice->getSurveyQuestion());
$doctrine->getManager()->persist($questionAnswer);
}
$doctrine->getManager()->persist($surveyAnswer);
$doctrine->getManager()->flush();
array_push($surveysSaved, $returnSurveys[$i]["id"]);
}
}
$pollingFrequency = $thinclient && $thinclient->getEntrance() && $thinclient->getEntrance()->getPollingFrequency()
? $thinclient->getEntrance()->getPollingFrequency()
: 3 * 60;
return new JsonResponse([
"error" => null,
"pullserver_token" => time() + $pollingFrequency,
"data" => $result['data'],
"data_v2" => $result['data_v2'],
"commands" => $commandsList,
"surveys_saved" => $surveysSaved,
"thinclient_attach" => $thinclient
? $thinclient->getEntrance() ? $thinclient->getEntrance()->getId() : null
: null
]);
}
}