<?php
namespace App\Controller;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
// Security
use Symfony\Component\Security\Core\Security;
// PDF
use Knp\Snappy\Pdf;
// DateTime
use DateTime;
// Files
use Symfony\Component\String\Slugger\SluggerInterface;
// Controller
use App\Controller\PretraitementController;
// Classes
use App\Entity\Utilisateur;
use App\Entity\Eleve;
use App\Entity\Enseignant;
use App\Entity\Enseignantcours;
use App\Entity\Cursus;
use App\Entity\Anneeuniversitaire;
use App\Entity\Semestre;
use App\Entity\Typecours;
use App\Entity\Qualification;
use App\Entity\Competence;
use App\Entity\Composante;
use App\Entity\Diplome;
use App\Entity\Note;
use App\Entity\Niveau;
use App\Entity\Fichier;
use App\Entity\Statutimport;
use App\Entity\Csvcours;
use App\Entity\Csvevaluationepreuve;
use App\Entity\Csvdiplome;
use App\Entity\Csveleve;
use App\Entity\Csvnote;
use App\Entity\Csvcoursgenerique;
use App\Entity\Csvepreuvegenerique;
use App\Entity\Csvenseignantgenerique;
use App\Entity\Csvenseignantcoursgenerique;
use App\Entity\Csvelevegenerique;
use App\Entity\Csvelevecoursgenerique;
use App\Entity\Cours;
use App\Entity\Epreuve;
use App\Entity\Evaluation;
use App\Entity\Evaluationeleve;
use App\Entity\Inscription;
use App\Entity\Typeimport;
use App\Entity\Modelenotif;
use App\Entity\Parametre;
#[Route('/secured')]
class EclacController extends AbstractController
{
public string $versionapp = "v1.2.0";
public string $app_env;
public bool $app_public;
public string $php_version;
public function __construct(
public Security $security,
private Pdf $knpSnappyPdf,
private EntityManagerInterface $entityManager,
private SluggerInterface $slugger,
private PretraitementController $PretraitementController,
private RequestStack $requestStack,
private UrlGeneratorInterface $urlGenerator,
private ParameterBagInterface $params,
) {
$this->app_env = $params->get('app_env');
$this->app_public = $params->get('app_public');
$this->php_version = $params->get('php_version');
if ($this->requestStack->getCurrentRequest() != null) {
if ($this->requestStack->getCurrentRequest()->hasSession()) {
$session = $this->requestStack->getSession();
// Variable session parametre
$parametre = $this->entityManager->getRepository(Parametre::class)->findOneBy(array(
'idparametre' => 1
));
$session->set('parametre', $parametre);
// Variable session Jeanne DUPONT
$jeanneDupont = $this->entityManager->getRepository(Eleve::class)->findOneBy(array(
'numeroidentification' => "DEMO"
));
if ($jeanneDupont != null) {
$session->set('jeanneDupont', true);
} else {
$session->set('jeanneDupont', false);
}
// Variable session Jean DUPONT
$jeanDupont = $this->entityManager->getRepository(Eleve::class)->findOneBy(array(
'numeroidentification' => "DEMOFINALE"
));
if ($jeanDupont != null) {
$session->set('jeanDupont', true);
} else {
$session->set('jeanDupont', false);
}
// Variable session anneeUniversitaire
$now = new DateTime('now');
if ($session->get('anneeUniversitaire') == null) {
$anneesuniversitaire = $entityManager->getRepository(Anneeuniversitaire::class)->findAll();
// On recherche si une année existe pour la date actuelle
$query = $entityManager
->createQuery(
'SELECT a
FROM App\Entity\Anneeuniversitaire a
WHERE a.datedebut <= :now
AND a.datefin >= :now'
)
->setParameter('now', $now);
$anneeUniversitaireQuery = $query->getResult();
// Si oui, on la définit en session
if (!empty($anneeUniversitaireQuery)) {
$session->set('anneeUniversitaire', $anneeUniversitaireQuery[0]);
} // Sinon on choisit la dernière année créée
else {
$session->set('anneeUniversitaire', $anneesuniversitaire[0]);
}
}
// Variable session cursus
if ($session->get('cursus') == null) {
$cursus = $entityManager->getRepository(Cursus::class)->findAll();
$query = $entityManager
->createQuery(
'SELECT c
FROM App\Entity\Cursus c
ORDER BY c.libellecursus ASC'
);
$cursus = $query->getResult();
$session->set('cursus', $cursus[0]);
}
$importsEnErreur = $this->entityManager->getRepository(Fichier::class)->findBy(array(
"statutimport" => 3,
));
if (!empty($importsEnErreur)) {
$session->set('importEnErreur', true);
} else {
$session->set('importEnErreur', false);
}
if ($parametre->isModemaintenance()) {
$session->set('modeMaintenance', true);
if ($session->get('droitadmin') != null) {
if (str_contains($this->requestStack->getMainRequest()->getRequestUri(), '/secured/')) {
if ($session->get('droitadmin') != true) {
if ($this->requestStack->getMainRequest()->attributes->get('_route') != "app_eclac_maintenance"
&& $this->requestStack->getMainRequest()->attributes->get('_route') != "app_eclac_secure-index"
&& str_contains($this->requestStack->getMainRequest()->getRequestUri(), '/secured/')) {
$response = new RedirectResponse($this->urlGenerator->generate('app_eclac_maintenance'));
$response->send();
}
}
}
}
} else {
$session->set('modeMaintenance', false);
}
if ($this->versionapp != $parametre->getVersionapp()) {
$session->set('afficheNavbarre', false);
$session->set('messageMaintenance', 'messages');
if ($this->requestStack->getMainRequest()->attributes->get('_route') != "app_eclac_maintenance") {
$session->set('afficheNavbarre', false);
$response = new RedirectResponse($this->urlGenerator->generate('app_eclac_maintenance'));
$response->send();
}
} else {
$session->set('afficheNavbarre', true);
$session->set('messageMaintenance', 'libelles');
}
}
}
}
#[Route('/maintenance', name: 'app_eclac_maintenance', methods: ['GET'])]
public function maintenance(Request $request): Response
{
return $this->render('eclac/maintenance.html.twig', []);
}
#[Route('/', name: 'app_eclac_secure-index', methods: ['GET'])]
public function secureIndex(Request $request): Response
{
// Variables communes
$entityManager = $this->entityManager;
$session = $request->getSession();
// On récupère l'utilisateur
$utilisateur = $entityManager->getRepository(Utilisateur::class)->findOneBy(array(
'idutilisateur' => $session->get('utilisateurconnecte')->getIdutilisateur()
));
// On regarde si la personne connectée est un élève
$eleve = $entityManager->getRepository(Eleve::class)->findOneBy(
array(
'utilisateur' => $utilisateur->getIdutilisateur()
)
);
if ($eleve != null) {
return $this->redirectToRoute('app_ecleleve_index', [], Response::HTTP_SEE_OTHER);
} else {
return $this->redirectToRoute('app_public_index', [], Response::HTTP_SEE_OTHER);
}
}
// Permet de se connecter à l'application
#[Route('/choix-espace/{switch}', name: 'app_eclac_choix-espace', methods: ['GET', 'POST'], defaults: ['switch' => 'switch'])]
public function choixEspace(Request $request, ?string $switch): Response
{
// La personne a besoin d'être identifiée pour accéder à la ressource
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_REMEMBERED');
// Variables communes
$entityManager = $this->entityManager;
$session = $request->getSession();
// RAZ des variables
$session->set('droitadmin', false);
$session->set('utilisateurconnecte', null);
$eleve = null;
$utilisateurCAS = $this->security->getUser();
// On regarde si la personne connectée est un élève
$utilisateur = $entityManager->getRepository(Utilisateur::class)->findOneBy(
array(
'login' => $utilisateurCAS->getUserIdentifier()
)
);
if ($utilisateur == null) {
// Login non trouvé
$this->addFlash('error', 'Identifiant non trouvé');
return $this->redirectToRoute('app_public_index', [], Response::HTTP_SEE_OTHER);
} else {
$session->set('utilisateurconnecte', $utilisateur);
// On regarde si la personne connectée est un élève
$eleve = $entityManager->getRepository(Eleve::class)->findOneBy(
array(
'utilisateur' => $utilisateur->getIdutilisateur()
)
);
if ($eleve != null) {
$session->set('utilisateur', $eleve);
$session->set('typeUtilisateur', 'Élève');
$session->set('droitadmin', false);
$session->set('vueAdministrateur', false);
}
// Sinon on regarde si c'est un enseignant
else {
$enseignant = $entityManager->getRepository(Enseignant::class)->findOneBy(
array(
'utilisateur' => $utilisateur->getIdutilisateur()
)
);
if ($enseignant != null) {
$session->set('utilisateur', $enseignant);
$session->set('typeUtilisateur', 'Enseignant');
$session->set('enseignant', $enseignant);
// On vérifie si l'enseignant est un administrateur
if ($enseignant->isAdministrateur()) {
$session->set('droitadmin', true);
if($switch == 'switch') {
if ($session->get('vueAdministrateur') == true) {
$session->set('vueAdministrateur', false);
} else {
$session->set('vueAdministrateur', true);
}
}
} else {
$session->set('droitadmin', false);
}
return $this->redirectToRoute('app_eclenseignant_index', [], Response::HTTP_SEE_OTHER);
}
// Sinon, il n'est ni élève, ni enseignant, il faut le déconnecter et contacter un administrateur
else {
return $this->redirectToRoute('app_logout', [], Response::HTTP_SEE_OTHER);
}
}
return $this->redirectToRoute('app_ecleleve_index', [], Response::HTTP_SEE_OTHER);
}
}
// Paramètres
#[Route('/parametre', name: 'app_eclac_parametre', methods: ['GET', 'POST'])]
public function parametre(Request $request): Response
{
// La personne a besoin d'être identifiée pour accéder à la ressource
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_REMEMBERED');
// Variables communes
$entityManager = $this->entityManager;
$session = $request->getSession();
if ($session->get('vueAdministrateur') != true) {
$this->addFlash('error', 'Vous n\'avez pas les droits d\'accéder à cette ressource');
return $this->redirectToRoute('app_eclac_choix-espace', [], Response::HTTP_SEE_OTHER);
}
$parametre = $entityManager->getRepository(Parametre::class)->findOneBy(array(
'idparametre' => 1
));
if (isset($_POST['activeMaintenance'])) {
$parametre->setModemaintenance(true);
$entityManager->persist($parametre);
$entityManager->flush();
$session->set('modeMaintenance', true);
}
if (isset($_POST['desactiveMaintenance'])) {
$parametre->setModemaintenance(false);
$entityManager->persist($parametre);
$entityManager->flush();
$session->set('modeMaintenance', false);
}
$session->set('parametre', $parametre);
$notif = $entityManager->getRepository(Modelenotif::class)->findOneBy(array(
'idmodelenotif' => 1
));
return $this->renderForm('eclac/parametre.html.twig', [
'modelnotif' => $notif,
]);
}
// Supprime les responsables du cours
public function supprResponsableCours(Cours $cours)
{
// Variables communes
$entityManager = $this->entityManager;
// Variables historisation
$result = true;
$query = $entityManager
->createQuery(
'SELECT ec
FROM App\Entity\Enseignantcours ec
JOIN ec.cours c
WHERE c.idcours IN (:idcours)'
)
->setParameters(array('idcours' => $cours->getIdcours()));
$listesEc = $query->getResult();
if (!empty($listesEc)) {
// On supprime toutes les lignes des fichiers
$query = $entityManager
->createQuery(
'DELETE
FROM App\Entity\Enseignantcours ec
WHERE ec.idenseignantcours IN (:idenseignantcours)'
)
->setParameters(array('idenseignantcours' => $listesEc));
if ($query->getResult() == false) {
$result = false;
}
}
return $result;
}
public static function overrideFile(string $file, string $contenu): void
{
// On vérifie que le fichier existe
if (!file_exists($file)) {
touch($file);
}
// On vérifie que le fichier est accessible en écriture
if (is_writable($file)) {
// On vérifie qu'on arrive à ouvrir le fichier
if (!$fp = fopen($file, 'w+')) {
throw new \Exception();
}
// On vérifie qu'on arrive à écrire le yaml dans le fichier
if (fwrite($fp, $contenu) === false) {
throw new \Exception();
}
fclose($fp);
} else {
throw new \Exception();
}
}
// Permet de récupérer les composantes d'un élève
public function getComposantesEleve(Eleve $eleve, bool $all)
{
$entityManager = $this->entityManager;
// On récupère les inscriptions de l'élève
$inscriptions = $entityManager->getRepository(Inscription::class)->findBy(array(
"eleve" => $eleve
));
// Puis tous les cours auquel il est inscrit
$arrayIdcours = array();
foreach ($inscriptions as $inscription) {
if (!in_array($inscription->getCours()->getIdcours(), $arrayIdcours)) {
array_push($arrayIdcours, $inscription->getCours()->getIdcours());
}
}
$cours = $entityManager->getRepository(Cours::class)->findBy(array(
'idcours' => $arrayIdcours
));
// On récupère toutes les épreuves de ces cours
$epreuves = $entityManager->getRepository(Epreuve::class)->findBy(array('cours' => $cours));
// On récupère toutes les composantes de ces épreuves
$arrayIdcomposantes = array();
foreach ($epreuves as $epreuve) {
if ($all) {
array_push($arrayIdcomposantes, $epreuve->getComposante()->getIdcomposante());
} else {
$arrayIdcomposantes[$epreuve->getComposante()->getCodecomposante()] = $epreuve->getComposante()->getIdcomposante();
}
}
$composantes = $entityManager->getRepository(Composante::class)->findBy(
array(
'idcomposante' => $arrayIdcomposantes,
),
array(
'codecomposante' => 'ASC',
'idcomposante' => 'ASC',
)
);
return $composantes;
}
// Rend propre une chaîne de caractère
public static function sanitizeString(string $string, bool $file = false): string
{
$array = [' ' => "_",
'.' => "_",
'\'' => "_",
'"' => "_",
'…' => "",
'«' => "",
'»' => "",
];
if ($file) {
$array = [' ' => "_",
'\'' => "_",
'"' => "_",
'…' => "",
'«' => "",
'»' => "",
];
}
return strtolower(
EclacController::replaceAccent(
strtr($string, $array)
)
);
}
// Remplace les accents
public static function replaceAccent(string $string): string
{
$unwanted_array = array(
'À' => 'A',
'Á' => 'A',
'Â' => 'A',
'Ã' => 'A',
'Ä' => 'A',
'Å' => 'A',
'Æ' => 'A',
'à' => 'a',
'á' => 'a',
'â' => 'a',
'ã' => 'a',
'ä' => 'a',
'å' => 'a',
'æ' => 'a',
'Ç' => 'C',
'ç' => 'c',
'È' => 'E',
'É' => 'E',
'Ê' => 'E',
'Ë' => 'E',
'è' => 'e',
'é' => 'e',
'ê' => 'e',
'ë' => 'e',
'Ì' => 'I',
'Í' => 'I',
'Î' => 'I',
'Ï' => 'I',
'ì' => 'i',
'í' => 'i',
'î' => 'i',
'ï' => 'i',
'Ñ' => 'N',
'ñ' => 'n',
'Ò' => 'O',
'Ó' => 'O',
'Ô' => 'O',
'Õ' => 'O',
'Ö' => 'O',
'Ø' => 'O',
'ð' => 'o',
'ò' => 'o',
'ó' => 'o',
'ô' => 'o',
'õ' => 'o',
'ö' => 'o',
'Š' => 'S',
'š' => 's',
'Ù' => 'U',
'Ú' => 'U',
'Û' => 'U',
'Ü' => 'U',
'ù' => 'u',
'ú' => 'u',
'û' => 'u',
'Ý' => 'Y',
'ý' => 'y',
'Ž' => 'Z',
'ž' => 'z',
'Þ' => 'B',
'ß' => 'Ss',
'þ' => 'b',
'ÿ' => 'y',
"\n" => ' '
);
$newString = strtr($string, $unwanted_array);
return $newString;
}
public static function verifPath(): void
{
// But : Aller dans le dossier /public
// Si le dossier /build n'existe pas, on n'est pas dans /public
if (!file_exists('./build')) {
// Si le dossier /web existe, on rentre dedans
if (file_exists('./web')) {
chdir('web/');
}
// Si le dossier /www existe, on rentre dedans
if (file_exists('./www')) {
chdir('www/');
}
// Si le dossier /html existe, on rentre dedans
if (file_exists('./html')) {
chdir('html/');
}
// Si le dossier /public existe, on rentre dedans
if (file_exists('./public')) {
chdir('public/');
}
// Sinon il y a un problème
else {
EclacController::logError("Dossier public introuvable", "verifPath");
}
}
}
public function createTempDoc(string $path, string $docName): string
{
$now = date_format(new DateTime(), ('Ymd'));
$outputPathBase = "";
$file = $path . $docName;
if (file_exists($file)) {
// On génère un random
$random = "";
for ($i = 1; $i < 15; $i++) {
$random .= mt_rand(1, 10);
}
if (!is_dir(getcwd() . "/../public/docs/tmp/")) {
if (!mkdir(getcwd() . "/../public/docs/tmp/", 0775, true)) {
$this->addFlash('error', 'Erreur à la création du dossier');
}
}
$pathRoot = getcwd();
$outputPath = "/../public/docs/tmp/";
$outputFile = "temp-" . $now . "-" . $random . "-" . $docName;
$outputComplet = $pathRoot . $outputPath . $outputFile;
$outputPathBase = "/docs/tmp/" . $outputFile;
if (!copy($file, $outputComplet)) {
$this->addFlash('error', 'Document non trouvé');
}
} else {
$this->addFlash('error', 'Document non trouvé');
}
return $outputPathBase;
}
public static function logError(string $string, string $typeLog): void
{
$now = date_format(new DateTime(), ('Y-m-d'));
$hours = date_format(new DateTime(), ('H:i'));
if ($string == '') {
$string = "Message d'erreur non défini";
}
if ($typeLog == '') {
$typeLog = "NC";
}
error_log($hours . " : " . $string . chr(13) . chr(10), 3, "../logs/" . $now . "_" . $typeLog . ".log");
}
public static function dateToMySQL(string $date): DateTime
{
$tabDate = explode('/', $date);
$date = $tabDate[2].'-'.$tabDate[1].'-'.$tabDate[0];
$date = new DateTime(date('Y-m-d H:i:s', strtotime($date)));
return $date;
}
// Permet de générer un PDF à partir d'une vue twig
public function generatePDF(string $html, string $path, string $url): bool
{
$knpSnappyPdf = $this->knpSnappyPdf;
$parametre = $this->entityManager->getRepository(Parametre::class)->findOneBy(array(
"idparametre" => 1,
));
$header = $this->renderView('pdf/header' . $parametre->getNompdf() . '.html.twig', [
"url" => $url,
'parametre' => $parametre,
]);
$footer = $this->renderView('pdf/footer' . $parametre->getNompdf() . '.html.twig', [
'parametre' => $parametre,
]);
try {
$knpSnappyPdf->setOptions(
[
'page-size' => 'A4',
'margin-top' => '1.5in',
'margin-right' => '0in',
'margin-bottom' => '0.7in',
'margin-left' => '0in',
'header-html' => $header,
'footer-html' => $footer,
'disable-smart-shrinking' => true,
'enable-local-file-access' => true,
'enable-external-links' => true,
'enable-internal-links' => true,
'enable-javascript' => true,
'debug-javascript' => true,
'javascript-delay' => 2000,
'no-stop-slow-scripts' => true,
'encoding' => 'UTF-8',
'toc' => false,
'dpi' => 96,
'zoom' => 1,
'viewport-size' => '1920x1080',
]
)
->generateFromHtml($html, $path);
return true;
} catch (\Exception $e) {
$this->logError($e->getMessage(), "generateAllDegrees");
return false;
}
}
}
/* Define a Read Filter class implementing \PhpOffice\PhpSpreadsheet\Reader\IReadFilter */
class ChunkReadFilter implements \PhpOffice\PhpSpreadsheet\Reader\IReadFilter
{
private $startRow = 0;
private $endRow = 0;
/** Set the list of rows that we want to read */
public function setRows($startRow, $chunkSize)
{
$this->startRow = $startRow;
$this->endRow = $startRow + $chunkSize;
}
public function readCell($columnAddress, $row, $worksheetName = '')
{
// Only read the heading row, and the configured rows
if (($row == 1) || ($row >= $this->startRow && $row < $this->endRow)) {
return true;
}
return false;
}
}