diff --git a/Dashboard.php b/Dashboard.php
new file mode 100755
index 0000000..9ba739c
--- /dev/null
+++ b/Dashboard.php
@@ -0,0 +1,41 @@
+
+
+
+
+
+ Tableau de bord
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Docs/BDD.sql b/Docs/BDD.sql
new file mode 100644
index 0000000..b90db3e
--- /dev/null
+++ b/Docs/BDD.sql
@@ -0,0 +1,84 @@
+-- MySQL Workbench Forward Engineering
+
+SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
+SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
+SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES';
+
+-- -----------------------------------------------------
+-- Schema projetphp
+-- -----------------------------------------------------
+
+-- -----------------------------------------------------
+-- Schema projetphp
+-- -----------------------------------------------------
+CREATE SCHEMA IF NOT EXISTS `projetphp` DEFAULT CHARACTER SET utf8 ;
+USE `projetphp` ;
+
+-- -----------------------------------------------------
+-- Table `projetphp`.`Medecin`
+-- -----------------------------------------------------
+CREATE TABLE IF NOT EXISTS `projetphp`.`Medecin` (
+ `id` INT NOT NULL AUTO_INCREMENT,
+ `Civilite` CHAR(1) NOT NULL,
+ `Prenom` VARCHAR(45) NOT NULL,
+ `Nom` VARCHAR(45) NOT NULL,
+ PRIMARY KEY (`id`),
+ UNIQUE INDEX `id_UNIQUE` (`id` ASC))
+ENGINE = InnoDB;
+
+
+-- -----------------------------------------------------
+-- Table `projetphp`.`Patient`
+-- -----------------------------------------------------
+CREATE TABLE IF NOT EXISTS `projetphp`.`Patient` (
+ `Civilite` CHAR(1) NOT NULL,
+ `Nom` VARCHAR(45) CHARACTER SET 'big5' NOT NULL,
+ `Prenom` VARCHAR(45) NOT NULL,
+ `Adresse` VARCHAR(100) NOT NULL,
+ `Ville` VARCHAR(50) NOT NULL,
+ `CodePostal` SMALLINT(4) NOT NULL,
+ `DateNaissance` DATE NOT NULL,
+ `LieuNaissance` VARCHAR(50) NOT NULL,
+ `NumSecuriteSociale` INT(15) NOT NULL,
+ `Id` INT NOT NULL AUTO_INCREMENT,
+ `MedecinTraitant` INT NULL,
+ UNIQUE INDEX `NumSecuriteSociale_UNIQUE` (`NumSecuriteSociale` ASC),
+ PRIMARY KEY (`Id`),
+ UNIQUE INDEX `Id_UNIQUE` (`Id` ASC),
+ INDEX `fk_Patient_Medecin_idx` (`MedecinTraitant` ASC),
+ CONSTRAINT `fk_Patient_Medecin`
+ FOREIGN KEY (`MedecinTraitant`)
+ REFERENCES `projetphp`.`Medecin` (`id`)
+ ON DELETE NO ACTION
+ ON UPDATE NO ACTION)
+ENGINE = InnoDB;
+
+
+-- -----------------------------------------------------
+-- Table `projetphp`.`RDV`
+-- -----------------------------------------------------
+CREATE TABLE IF NOT EXISTS `projetphp`.`RDV` (
+ `id` INT NOT NULL,
+ `DateRDV` TIMESTAMP NULL,
+ `Duree` TIME NULL,
+ `Patient_Id` INT NOT NULL,
+ `Medecin_id` INT NOT NULL,
+ PRIMARY KEY (`id`),
+ INDEX `fk_RDV_Patient1_idx` (`Patient_Id` ASC),
+ INDEX `fk_RDV_Medecin1_idx` (`Medecin_id` ASC),
+ CONSTRAINT `fk_RDV_Patient1`
+ FOREIGN KEY (`Patient_Id`)
+ REFERENCES `projetphp`.`Patient` (`Id`)
+ ON DELETE NO ACTION
+ ON UPDATE NO ACTION,
+ CONSTRAINT `fk_RDV_Medecin1`
+ FOREIGN KEY (`Medecin_id`)
+ REFERENCES `projetphp`.`Medecin` (`id`)
+ ON DELETE NO ACTION
+ ON UPDATE NO ACTION)
+ENGINE = InnoDB;
+
+
+SET SQL_MODE=@OLD_SQL_MODE;
+SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
+SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
diff --git a/Docs/Model.mwb b/Docs/Model.mwb
new file mode 100644
index 0000000..d746949
Binary files /dev/null and b/Docs/Model.mwb differ
diff --git a/autoloader.php b/autoloader.php
index dbfecc3..da6f80f 100755
--- a/autoloader.php
+++ b/autoloader.php
@@ -4,18 +4,27 @@
* fonction d'autoloading : prend en paramètre le nom de la classe et s'occupe d'inclure les fichiers correspondant aux classes
*/
+//pour l'inclusion dans le dossier src
+$GLOBALS['managers_dir'] = dirname(__FILE__).DIRECTORY_SEPARATOR.'src';
+
function autoloader($class) {
- //si on charge le StaticRepo
- if(strpos($class, 'StaticRepo') !== FALSE){
- require_once dirname(__FILE__).DIRECTORY_SEPARATOR.'repositories'.DIRECTORY_SEPARATOR.$class . '.php';
- }
- //si on charge un Repo
- elseif(strpos($class, 'Repo') !== FALSE){
- require_once dirname(__FILE__).DIRECTORY_SEPARATOR.'repositories'.DIRECTORY_SEPARATOR.'repos'.DIRECTORY_SEPARATOR.$class . '.php';
+ //si on charge le StaticRepo
+ if(strpos($class, 'StaticRepo') !== FALSE){
+ require_once dirname(__FILE__).DIRECTORY_SEPARATOR.'repositories'.DIRECTORY_SEPARATOR.$class . '.php';
+ }
+ //si on charge un Repo
+ elseif(strpos($class, 'Repo') !== FALSE){
+ require_once dirname(__FILE__).DIRECTORY_SEPARATOR.'repositories'.DIRECTORY_SEPARATOR.'repos'.DIRECTORY_SEPARATOR.$class . '.php';
- //cas particuliers pas identifiable par nom de classe
- }
+ //cas particuliers pas identifiable par nom de classe
+ }else{
+ //si on charge un manager
+ if(is_file(dirname(__FILE__).DIRECTORY_SEPARATOR.'src'.DIRECTORY_SEPARATOR.$class . '.php')){
+ require_once dirname(__FILE__).DIRECTORY_SEPARATOR.'src'.DIRECTORY_SEPARATOR.$class . '.php';
+
+ }
+ }
}
//enregistrememnt de la fonction tout en bas de la pile pour ne pas casser l'autoloader de phpUnit
diff --git a/css/global.css b/css/global.css
new file mode 100755
index 0000000..03ba01c
--- /dev/null
+++ b/css/global.css
@@ -0,0 +1,185 @@
+*{ margin: 0; padding: 0; }
+
+a{
+ /* remove-a default properties */
+ text-decoration: none;
+ color: inherit;
+}
+
+
+
+body{
+ /* position */
+ display: block;
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+
+ /* background */
+ background-color: #e8e8e8;
+
+ /* foreground */
+ font-size: 14px;
+ font-family: 'Open Sans', 'sans serif';
+ color: #000;
+}
+
+
+
+/* WRAPPER DE LA PAGE */
+#WRAPPER{
+ /* position */
+ display: block;
+ position: absolute;
+ top: 1em;
+ left: calc( 50% - 512px - 1em );
+ width: 1024px;
+ min-height: 50%;
+ margin: 2em;
+
+ /* border */
+ border: 1px solid #e2e2e2;
+ box-shadow: 0 0 5px #e2e2e2;
+
+ /* background */
+ background-color: #fff;
+}
+
+
+/* MENU DE LA PAGE */
+#WRAPPER > #MENU{
+ /* position */
+ display: block;
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 225px;
+ height: 100%;
+
+ /* border */
+ border-right: 1px solid #e2e2e2;
+ border-bottom: 1px solid #e2e2e2;
+
+ /* background */
+ background-color: #fafafa;
+}
+
+
+/* LOGO DANS LE MENU */
+#WRAPPER > #MENU > #ICON{
+ /* position */
+ position: relative;
+ width: 100%;
+ height: 100px;
+
+ /* background */
+ background-color: red;
+}
+
+/* LES LIENS DU MENU */
+#WRAPPER > #MENU > a{
+ /* position */
+ display: inline-block;
+ position: relative;
+ width: calc( 100% - 3em );
+ padding-left: 3em;
+ padding-bottom: 1px;
+
+ /* background */
+ background-color: transparent;
+
+ /* foreground */
+ line-height: 2.5em;
+
+ /* extra */
+ cursor: pointer;
+}
+
+/* :hover / .active */
+#WRAPPER > #MENU > a:hover,
+#WRAPPER > #MENU > a.active{
+ background-color: #efefef !important;
+ color: #818181;
+}
+
+
+/* @first/@last */
+#WRAPPER > #MENU > a:nth-child(2){ margin-top: 1em; }
+#WRAPPER > #MENU > a:last-child{ margin-bottom: 1em; }
+
+
+/* icones associées aux liens */
+#WRAPPER > #MENU > a#consultations{
+ background: url(../src/consultation.svg) left 1em center no-repeat;
+ background-size: auto 1.5em;
+}
+
+#WRAPPER > #MENU > a#doctor{
+ background: url(../src/doctor.svg) left 1em center no-repeat;
+ background-size: auto 1.5em;
+}
+
+#WRAPPER > #MENU > a#dashboard{
+ background: url(../src/dashboard.svg) left 1em center no-repeat;
+ background-size: auto 1.5em;
+}
+
+
+
+
+/*************/
+/* CONTAINER */
+/*************/
+#WRAPPER > #CONTAINER{
+ /* position */
+ display: block;
+ position: absolute;
+ top: 0;
+ left: 225px;
+ width: calc( 100% - 225px );
+ height: 100%;
+}
+
+
+/* FIL D'ARIANE */
+#WRAPPER > #CONTAINER > #BREADCRUMB{
+ /* position */
+ display: inline-block;
+ position: relative;
+ width: calc( 100% - 2*2em - 2*.6em );
+ margin: 2em;
+ padding: .6em;
+
+ /* background */
+ background-color: #eee;
+
+ /* foreground */
+ color: #333;
+}
+
+#WRAPPER > #CONTAINER > #BREADCRUMB a:hover{
+ text-decoration: underline;
+}
+
+/* chevrons */
+#WRAPPER > #CONTAINER > #BREADCRUMB a:before{
+ content: '';
+ /* position */
+ display: inline-block;
+ position: relative;
+ width: 1em;
+ height: .7em;
+
+ background: url(../src/right-arrow.svg) center center no-repeat;
+ background-size: 40% auto;
+}
+
+/* premier: maison au lien de chevron */
+#WRAPPER > #CONTAINER > #BREADCRUMB a:first-child:before{
+ margin-right: 1em;
+ height: 1em;
+ background-image: url(../src/home.svg);
+ background-size: auto 100%;
+}
diff --git a/css/login.css b/css/login.css
new file mode 100755
index 0000000..55400fe
--- /dev/null
+++ b/css/login.css
@@ -0,0 +1,128 @@
+/*******************************/
+/*** RECTIFICATIONS GLOBALES ***/
+/*******************************/
+*{ margin: 0; padding: 0; }
+
+body{
+ /* position */
+ display: block;
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+
+ /* background */
+ background-color: #233342;
+
+ /* foreground */
+ font: 16px 'Open Sans';
+ color: #fff;
+}
+
+
+
+/*******************/
+/*** FORMULAIRES ***/
+/*******************/
+form{
+ /* position */
+ display: block;
+ position: absolute;
+ left: calc( 50% - 20em/2 );
+ width: 20em;
+ height: auto;
+ margin: 2em;
+ padding: 2em;
+
+ /* border */
+ border-radius: 5px;
+ box-shadow: inset 0 0 10px #0a0f14;
+
+ /* background */
+ background-color: #151f28;
+}
+
+
+
+
+/************************/
+/*** CHAMPS DE SAISIE ***/
+/************************/
+input{
+ /* position */
+ display: inline-block;
+ padding: 1em 2em;
+ margin: 1em;
+ width: calc( 100% - 2*2em - 5px - 2*1em );
+
+ /* border */
+ border-radius: 3px 0 0 3px;
+ border: 0;
+ border-right: 5px solid #aaa;
+
+ /* background */
+ background-color: #ddd;
+
+ /* animation */
+ transition: all .2s ease-in-out;
+ -moz-transition: all .2s ease-in-out;
+ -webkit-transition: all .2s ease-in-out;
+ -ms-transition: all .2s ease-in-out;
+ -o-transition: all .2s ease-in-out;
+}
+
+/* @hover */
+input:focus { background-color: #fff; }
+input:nth-child(4n+0):focus{ border-right-color: #f45b2a; }
+input:nth-child(4n+1):focus{ border-right-color: #1b84db; }
+input:nth-child(4n+2):focus{ border-right-color: #f4b92a; }
+input:nth-child(4n+3):focus{ border-right-color: #b62af4; }
+
+
+/*****************************/
+/*** BOUTONS DE VALIDATION ***/
+/*****************************/
+input[type=submit],
+input[type=button]{
+ /* position */
+ width: auto;
+ float: right;
+
+ /* foreground */
+ font-weight: bold;
+}
+
+input[type=submit]:hover,
+input[type=button]:hover{
+
+ /* border */
+ border-right-color: #1b84db;
+
+ /* background */
+ background-color: #fff;
+
+ /* foreground */
+ color: #1b84db;
+
+ /* extra */
+ cursor: pointer;
+}
+
+
+/****************/
+/*** MESSAGES ***/
+/****************/
+.error{
+ font-size: .8em;
+ padding: 1em 1em;
+ color: #f14973;
+ text-shadow: 1px 1px 0 #000;
+}
+
+.success{
+ font-size: .8em;
+ padding: 1em 1em;
+ color: #49f16b;
+ text-shadow: 1px 1px 0 #000;
+}
\ No newline at end of file
diff --git a/index.php b/index.php
new file mode 100755
index 0000000..c07c582
--- /dev/null
+++ b/index.php
@@ -0,0 +1,65 @@
+
+
+authentification($_POST['username'],$_POST['password']);
+}
+
+if(Authentification::checkUser(0)){
+ header("Location: http://".$_SERVER['HTTP_HOST']."/Dashboard.php");
+ die();
+};
+?>
+
+
+
+ Tests php
+
+
+
+
+
+
+
+
+
+
+
+ ";
+
+ /* AFFICHAGE D'ERREURS */
+ if( $postVariablesAreSet ){ // si formulaire soumis
+ if( !$postVariablesNEmpty )
+ echo 'Certains champs requis sont vides.';
+ elseif( !$usernameCheck )
+ echo 'Nom d\'utilisateur incorrect. (3 car. min)';
+ elseif( !$mailCheck )
+ echo 'Adresse mail incorrecte.';
+ elseif( !$passwordCheck )
+ echo 'Mot de passe incorrect. (8 car. min)';
+ elseif( connected($user) )
+ echo 'Vous êtes connectés.';
+ }
+
+ echo "";
+ echo "";
+ echo "";
+ echo "";
+
+ ?>
+
+
+
+
\ No newline at end of file
diff --git a/src/Authentification.php b/src/Authentification.php
new file mode 100755
index 0000000..a81fd19
--- /dev/null
+++ b/src/Authentification.php
@@ -0,0 +1,87 @@
+users = json_decode(file_get_contents($GLOBALS['managers_dir'].DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'users.json'),true);
+ }
+
+ /**
+ * méthode d'authentification, utilise param['identifiant'] et param['mdp'] et les comparent à
+ * nos utilisateurs enregistrés puis créer une session securisée par token
+ * @param array $param contiens les infomations de connection
+ * @return json json contenant le résultat de l'authentification (true si authentification correcte, sinon non)
+ */
+ public function authentification($user,$mdp){
+ foreach($this->users as $utilisateur=>$infos){
+ if($utilisateur == $user and $infos['password'] == $mdp){
+ $this->createSecureSession($user,$infos['role']);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * déconnecte l'utilisateur en détruisant la session et le cookie
+ * @return json renvoie true, il n'y aucune raison que ça foire
+ */
+ public function deconnection(){
+ $this->destroySecureSession();
+ Response::quickResponse(200,json_encode(['result' => true]));
+ }
+
+ /**
+ * créer une session sécurisé , protégé du vol de session par identification de l'utilisateur par navigateur/ip/cookie
+ * @param String $user nom d'utilisateur
+ * @param String $role role de l'utilisateur (0=administrateur, 1= prof, 2=scolarité,3=élève)
+ * @return void
+ */
+ private function createSecureSession($user,$role){
+ $id = uniqid();
+ $_SESSION['id'] = $id;
+ $_SESSION['token'] = sha1($_SERVER['HTTP_USER_AGENT'].$_SERVER['REMOTE_ADDR'].$id);
+ setcookie('UserId',$id,time()+10*60,'/');
+
+ $_SESSION['user'] = $user;
+ $_SESSION['role'] = $role;
+
+ }
+
+ /**
+ * Détruit une session
+ * @return void
+ */
+ private function destroySecureSession(){
+ session_destroy();
+ setcookie('token',time()-1);
+ }
+
+ /**
+ * Vérifie qu'un utilisateur donné a les droits demandés (passés en paramètres)
+ * @param int $role role minimum
+ * @param boolean $strict si strict vaut true, seul les utilisateurs avec le role précis seront acceptés, sinon tout les utilisateurs
+ * avec un role superieur le seront
+ * @return boolean
+ */
+ public static function checkUser($role, $strict=false){
+ if(isset($_SESSION['token'])){
+ foreach($_SESSION['role'] as $roleUser){
+ if(($strict and $roleUser == $role) or (!$strict and $roleUser<= $role)){
+ if($_SESSION['token'] == sha1($_SERVER['HTTP_USER_AGENT'].$_SERVER['REMOTE_ADDR'].$_SESSION['id'])){
+ setcookie('UserId',$_COOKIE['UserId'],time()+10*60,'/');
+ return true;
+ };
+ }
+ }
+ }
+ return false;
+ }
+
+ public static function getCurrentUser(){
+ return $_SESSION['user'];
+ }
+}
+?>
diff --git a/src/Response.php b/src/Response.php
new file mode 100644
index 0000000..23e3971
--- /dev/null
+++ b/src/Response.php
@@ -0,0 +1,202 @@
+ '100 Continue',
+ 101 => '101 Switching Protocols',
+ //Successful 2xx
+ 200 => '200 OK',
+ 201 => '201 Created',
+ 202 => '202 Accepted',
+ 203 => '203 Non-Authoritative Information',
+ 204 => '204 No Content',
+ 205 => '205 Reset Content',
+ 206 => '206 Partial Content',
+ 226 => '226 IM Used',
+ //Redirection 3xx
+ 300 => '300 Multiple Choices',
+ 301 => '301 Moved Permanently',
+ 302 => '302 Found',
+ 303 => '303 See Other',
+ 304 => '304 Not Modified',
+ 305 => '305 Use Proxy',
+ 306 => '306 (Unused)',
+ 307 => '307 Temporary Redirect',
+ //Client Error 4xx
+ 400 => '400 Bad Request',
+ 401 => '401 Unauthorized',
+ 402 => '402 Payment Required',
+ 403 => '403 Forbidden',
+ 404 => '404 Not Found',
+ 405 => '405 Method Not Allowed',
+ 406 => '406 Not Acceptable',
+ 407 => '407 Proxy Authentication Required',
+ 408 => '408 Request Timeout',
+ 409 => '409 Conflict',
+ 410 => '410 Gone',
+ 411 => '411 Length Required',
+ 412 => '412 Precondition Failed',
+ 413 => '413 Request Entity Too Large',
+ 414 => '414 Request-URI Too Long',
+ 415 => '415 Unsupported Media Type',
+ 416 => '416 Requested Range Not Satisfiable',
+ 417 => '417 Expectation Failed',
+ 418 => '418 I\'m a teapot',
+ 422 => '422 Unprocessable Entity',
+ 423 => '423 Locked',
+ 426 => '426 Upgrade Required',
+ 428 => '428 Precondition Required',
+ 429 => '429 Too Many Requests',
+ 431 => '431 Request Header Fields Too Large',
+ //Server Error 5xx
+ 500 => '500 Internal Server Error',
+ 501 => '501 Not Implemented',
+ 502 => '502 Bad Gateway',
+ 503 => '503 Service Unavailable',
+ 504 => '504 Gateway Timeout',
+ 505 => '505 HTTP Version Not Supported',
+ 506 => '506 Variant Also Negotiates',
+ 510 => '510 Not Extended',
+ 511 => '511 Network Authentication Required'
+ );
+
+ /**
+ * Constructeur de la Response
+ * @param int $status status HTTP de la réponse (404,200,500, etc)
+ * @param bool|false $stream Si la réponse est un stream (avtive/désactive les méthodes send/stream()
+ * @param string $type type HTTP des données de retour
+ * @param bool|true $clearBuffer si activé, vide le buffer avant chaque envoi de donnée (a pour effet de ne pas afficher les echo/printf)
+ */
+ public function __construct($status = 200,$stream = false,$type = 'application/json', $clearBuffer = false)
+ {
+ $this->status = $status;
+ array_push($this->headers,['Content-Type',$type]);
+
+ $this->config['clearBuffer'] = $clearBuffer;
+ $this->config['stream'] = $stream;
+ }
+
+ /** Ajoute du contenu a la réponse qui sera envoyé (par stream() ou par send() )
+ * @param $content contenu a ajouter a la réponse
+ */
+ public function write($content){
+ $this->response .= $content;
+ }
+
+ /** Envoie une partie de réponse au client (doit être récupéré en ajax, aucun intéret sinon), chaque bloc de donéne envoyé est séparé par
+ * un délimiteur ("//Block//" par défaut).ATTENTION: stream() vide la réponse (si on write() puis stream(), la réponse qu'il restera dans l'objet sera vide)
+ * @param string $content contenu a envoyer (optionnel car on peut utiliser la méthode write pour le faire)
+ * @throws Exception si la réponse n'est pas un stream
+ */
+ public function stream($content="",$delimiter = "//Block//"){
+ //vérification que la réponse est un stream
+ if(!$this->config['stream']){
+ throw new Exception("Stream d'une réponse synchrone");
+ }
+ //si les headers ne sont pas encore envoyés, on le fait
+ if(!headers_sent()){
+ $this->sendHeader();
+ }
+ //si demandé, on clear le buffer avant d'envoyer
+ if($this->config['clearBuffer']){
+ ob_end_clean();
+ if($GLOBALS['compression']){
+ ob_start("ob_gzhandler");
+ }else{
+ ob_start();
+ }
+ }
+ //on envoi le contenu de response et la variable content
+ if($this->response!=""){
+ echo $delimiter.$this->response;
+ }if($content != ""){
+ echo $delimiter.$content;
+ }
+ ob_flush();flush();
+ $this->response = '';
+ }
+
+ /**
+ * Envoi les headers de la réponse (status et ceux potentiellement défnini par l'utilisateur)
+ */
+ public function sendHeader(){
+ //envoie le status de la requete (petit trick suivant l'architecture de PHP)
+ if (strpos(PHP_SAPI, 'cgi') === 0) {
+ header(sprintf('Status: %s', $this->Messages[$this->status]));
+ } else {
+ header(sprintf('HTTP/1.1 %s', $this->Messages[$this->status]));
+ }
+ //les autres headers
+ foreach($this->headers as $header){
+ header(sprintf('%s: %s',$header[0],$header[1]));
+ }
+ }
+
+ /**
+ * Défini un header qui sera envoyé
+ * @param $header Nom du header
+ * @param $value Valeur du header
+ */
+ public function setHeader($header,$value){
+ array_push($this->headers,[$header,$value]);
+ }
+
+ /** Envoi la réponse et ferme la communication
+ * @throws Exception si la réponse est un stream
+ */
+ public function send(){
+ //vérification que la réponse n'est pas un stream
+ if($this->config['stream']){
+ throw new Exception("Envoi synchrone d'une réponse stream");
+ }
+ //si les headers ne sont pas encore envoyés, on le fait
+ if(!headers_sent()){
+ $this->sendHeader();
+ }
+ //si demandé, on clear le buffer avant d'envoyer
+ if($this->config['clearBuffer']){
+ ob_end_clean();
+ if($GLOBALS['compression']){
+ ob_start("ob_gzhandler");
+ }else{
+ ob_start();
+ }
+ }
+ //envoi de la réponse
+ echo $this->response;
+ //fermeture de la communication
+ header('Connection: close');
+ header('Content-Length: '.ob_get_length());
+ ob_end_flush();
+ ob_flush();
+ flush();
+ //permet au reste du script de s'executer même si la réponse a été envoyé et que l'utilisateur interromp le script (changement de page, etc...)
+ ignore_user_abort(true);
+ }
+
+ /**
+ * @param int $status status HTTP de la réponse (404,200,500, etc)
+ * @param $content
+ * @param string $type
+ */
+ public static function quickResponse($status,$content,$type = 'application/json'){
+ $response = new Response($status,false,$type);
+ $response->write($content);
+ $response->send();
+ }
+}
diff --git a/src/config/users.json b/src/config/users.json
new file mode 100755
index 0000000..310a83a
--- /dev/null
+++ b/src/config/users.json
@@ -0,0 +1,6 @@
+{
+ "secretaire": {
+ "password":"thecakeisalie",
+ "role":[0]
+ }
+}
diff --git a/src/consultation.svg b/src/consultation.svg
new file mode 100755
index 0000000..a45e261
--- /dev/null
+++ b/src/consultation.svg
@@ -0,0 +1,84 @@
+
+
+
+
diff --git a/src/dashboard.svg b/src/dashboard.svg
new file mode 100755
index 0000000..9b750e3
--- /dev/null
+++ b/src/dashboard.svg
@@ -0,0 +1,146 @@
+
+
+
+
diff --git a/src/home.svg b/src/home.svg
new file mode 100755
index 0000000..fa67b05
--- /dev/null
+++ b/src/home.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/right-arrow.svg b/src/right-arrow.svg
new file mode 100755
index 0000000..04e77dd
--- /dev/null
+++ b/src/right-arrow.svg
@@ -0,0 +1,71 @@
+
+
+
+