index.php 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. <?php
  2. require_once "libs/fnMain.php";
  3. /**************************
  4. * VALIDATION DES DONNEES
  5. **************************/
  6. $isClassementValid = isset($_GET["classement"]) && (int) $_GET["classement"] !== 0;
  7. /**************************
  8. * Affichage du formulaire
  9. **************************/
  10. ?>
  11. <!doctype html>
  12. <html lang="fr">
  13. <head>
  14. <meta charset="UTF-8">
  15. <meta name="viewport"
  16. content="width=device-width, initial-scale=1.0">
  17. <meta http-equiv="X-UA-Compatible" content="ie=edge">
  18. <title>RangLimier</title>
  19. <link rel="icon" type="image/png" href="assets/favicon.png">
  20. <link rel="stylesheet" href="assets/fonts/material-icons.min.css">
  21. <link rel="stylesheet" href="assets/bootstrap.min.css">
  22. <link rel="stylesheet" href="assets/divers.css">
  23. <!-- Font Awesome icons (free version)-->
  24. <script src="https://use.fontawesome.com/releases/v5.15.1/js/all.js" crossorigin="anonymous"></script>
  25. <!-- Google fonts-->
  26. <link href="https://fonts.googleapis.com/css?family=Montserrat:400,700" rel="stylesheet" type="text/css" />
  27. <link href="https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic" rel="stylesheet" type="text/css" />
  28. </head>
  29. <body>
  30. <div id="navbar">
  31. <nav id="mainNav" class="navbar navbar-expand-lg text-uppercase sticky-top">
  32. <div class="container">
  33. <a href="https://asclepia.io/" class="navbar-brand">
  34. <div class="text-lowercase" style="font-family: no-name;">asclepia</div>
  35. </a>
  36. <button type="button" data-toggle="collapse" data-target="#navbarResponsive"
  37. aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation"
  38. class="navbar-toggler navbar-toggler-right text-uppercase font-weight-bold bg-primary text-white rounded collapsed">
  39. Menu
  40. <svg class="svg-inline--fa fa-bars fa-w-14" aria-hidden="true" focusable="false"
  41. data-prefix="fas" data-icon="bars" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"
  42. data-fa-i2svg="">
  43. <path fill="currentColor"
  44. d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"></path>
  45. </svg>
  46. </button>
  47. <div id="navbarResponsive" class="navbar-collapse collapse" style="">
  48. <ul class="navbar-nav ml-auto">
  49. <li class="nav-item mx-0 mx-lg-1">
  50. <a href="https://asclepia.io/utilisateur" class="nav-link py-3 px-0 px-lg-3 rounded js-scroll-trigger">Se connecter</a>
  51. </li>
  52. <li class="nav-item mx-0 mx-lg-1">
  53. <a href="https://asclepia.io/inscription" class="nav-link py-3 px-0 px-lg-3 rounded js-scroll-trigger">Découvrir</a>
  54. </li>
  55. </ul>
  56. </div>
  57. </div>
  58. </nav>
  59. </div>
  60. <div id="rangLimier">
  61. <br>
  62. <h1 style="text-align: center;">Rangs Limites</h1>
  63. <p>Cet outil permet d'apprécier les choix de postes accessibles pour un rang de classement donné sur les années post R3C (à partir des ECNi 2017 jusqu'aux derniers ECNi) <br>
  64. Sur un seul tableau<!--, qui'il est possible de restreindre à certains DES et/ou certaines subdivisions -->, est affiché, dans chaque case, le nombre d'année où le poste aurait été accessible.
  65. </p>
  66. <ul>
  67. <li>En rouge : Jamais accessible à ce classement</li>
  68. <li>En Jaune : Accessible sur au moins un an (mais pas toutes les années)</li>
  69. <li>En vert : Accessible toutes les années jusqu'aux derniers ECNi</li>
  70. </ul>
  71. <p>
  72. ⚠ <i> Ces informations sont données à titre indicatif et ne peuvent constituer une quelconque garantie pour les procédures de choix à venir</i>
  73. <br>
  74. <i>Toutes les données exploitées par cet outil proviennent du site <a href="https://www.cng.sante.fr/">cng.sante.fr</a> et de son application
  75. <a href="https://www.cngsante.fr/chiron/celine/">CELINE</a>. Pour toute information officielle, veuillez vous référer à ces derniers.</i>
  76. </p>
  77. <form action="index.php" method="get" class="d-flex flex-column align-items-left">
  78. <div class="form-group row align-items-center">
  79. <label for="classement" class="col-sm-2">Saisissez un rang de classement : </label>
  80. <div class="col-sm-1">
  81. <input type="text" name="classement" class="form-control rounded-pill" <?= ($isClassementValid === TRUE) ? 'value='.(int) $_GET["classement"] : "" ?>>
  82. </div>
  83. </div>
  84. <button type="submit" class="btn btn-info rounded-pill col-sm-2" >Envoyer</button>
  85. </form>
  86. <?php if ($isClassementValid) : ?>
  87. <!--
  88. <hr><h1>Tableau de classement</h1>
  89. <h2>Légende</h2>
  90. <table>
  91. <thead>
  92. <th colspan="5" style="text-align: center;">Légende (sur toutes les années)</th>
  93. </thead>
  94. <tbody>
  95. <tr>
  96. <td class="never-available">Jamais proposé</td>
  97. <td class="no-choice">Aucun choix</td>
  98. <td class="half-choices">Plusieurs choix</td>
  99. <td class="all-choices">Tous les choix</td>
  100. </tr>
  101. </tbody>
  102. </table>
  103. <p>
  104. Chaque nombre dans chaque case correspond au nombre d'années où ce choix était dispo au classement rentré <br>
  105. </p> -->
  106. <?php
  107. // $html = "<h2>Résultats</h2>";
  108. $html = "<br><br><br>";
  109. // On va récupérer tous les rangs limited dispo triés par idChoix
  110. //Mysql
  111. $reqRL = $db->query('SELECT idChoix, annee, rangLimite FROM dataset');
  112. //pgsql
  113. // $reqRL = $db->query('SELECT dataset."idChoix", annee, dataset."rangLimite" FROM dataset');
  114. $rangLimites = $reqRL->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_ASSOC);
  115. // Récupération des datasets
  116. $specialityDatasetAbrev = getCsvToArrayKeyValue($_SETTINGS["datasetFolder"]."/liste_specialites_abrev.csv");
  117. $specialityDataset = getCsvToArrayKeyValue($_SETTINGS["datasetFolder"]."/liste_specialites.csv");
  118. $cityDataset = getCsvToArrayKeyValue($_SETTINGS["datasetFolder"]."/liste_villes.csv");
  119. $inputClassement = (int) $_GET["classement"];
  120. // Calcul et affichage des données
  121. // Affichage de la 1ère ligne = Titre des colonnes
  122. $html .= "<table><thead><tr><th></th>";
  123. foreach ($specialityDatasetAbrev as $specialityName) {
  124. $html .= "<th scope='col'>".$specialityName."</th>";
  125. }
  126. $html .= "</tr></thead><tbody>";
  127. // Affichage de la suite du tableau avec le calcul
  128. foreach ($cityDataset as $cityId => $cityName) {
  129. // On gère la séparation des différentes régions entre elles (représentées dans le csv villes par les lignes XX_:XX)
  130. // La notation des lignes de séparation est sous forme XX_x car si on laissait XX, la fonction getCsvToArrayKeyValue
  131. // ne retourne la position que pour la 1ère occurence de XX;XX
  132. // La manière de fix ça de manière la plus opti et sale, c'est de faire un substr et de tester les 2 premiers charactères
  133. // si ils sont égaux à XX, on fait une séparation
  134. // TODO : Faire un parseur csv qui prend en compte chaque ligne du csv dans l'ordre du fichier
  135. if (strpos($cityId, "XX") !== FALSE) {
  136. $html .= "<tr><th></th>";
  137. foreach ($specialityDatasetAbrev as $specialityName) {
  138. $html .= "<th scope='col'>".$specialityName."</th>";
  139. }
  140. $html .= "</th>";
  141. continue;
  142. }
  143. $html .= "<tr><th scope='row'>".$cityName."</th>";
  144. foreach ($specialityDatasetAbrev AS $specialityId => $specialityName) {
  145. $idChoice = "0".$cityId.$specialityId;
  146. if (!isset($rangLimites[$idChoice])) {
  147. $nbAnneePropose = 0;
  148. $nbPossibleAnneePropose = 0;
  149. } else {
  150. $nbAnneePropose = count($rangLimites[$idChoice]);
  151. $nbPossibleAnneePropose = 0;
  152. foreach ($rangLimites[$idChoice] as $rangLimite) {
  153. if ((int) $rangLimite["rangLimite"] >= $inputClassement) {$nbPossibleAnneePropose++;}
  154. }
  155. }
  156. // Affichage de la cellule
  157. $html .= "<td class=\"";
  158. switch (TRUE) {
  159. case ($nbPossibleAnneePropose === 0 && $nbAnneePropose === 0):
  160. $html .= "never-available";
  161. break;
  162. case ($nbPossibleAnneePropose === 0):
  163. $html .= "no-choice";
  164. break;
  165. case ($nbAnneePropose > $nbPossibleAnneePropose && $nbPossibleAnneePropose === 1):
  166. $html .= "last-choice";
  167. break;
  168. case ($nbAnneePropose > $nbPossibleAnneePropose && $nbPossibleAnneePropose !== 1):
  169. $html .= "half-choices";
  170. break;
  171. case ($nbAnneePropose === $nbPossibleAnneePropose):
  172. $html .= "all-choices";
  173. break;
  174. }
  175. $html .= "\">";
  176. if ($nbPossibleAnneePropose > 0) {
  177. $html .= $nbPossibleAnneePropose;
  178. } else if ($nbPossibleAnneePropose === 0 && $nbAnneePropose !== 0) {
  179. $html .= "0";
  180. }
  181. $html .= "</td>";
  182. }
  183. $html .= "</tr>";
  184. }
  185. $html .= "</tbody></table><br>";
  186. echo $html;
  187. ?>
  188. <table>
  189. </table>
  190. <?php endif;?>
  191. </div>
  192. <!-- Bootstrap core JS-->
  193. <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  194. <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.bundle.min.js"></script>
  195. </body>
  196. </html>