From b8d067fd2a75b2c4212b0d2d0262b60d1ce0d5d4 Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Tue, 20 Oct 2015 10:44:40 +0200 Subject: [PATCH] =?UTF-8?q?Commit=20de=20migration=20(re-cr=C3=A9ation)=20?= =?UTF-8?q?du=20GIT?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- API.js | 77 +++++ API.php | 99 ++++++ LICENSE | 0 README.md | 1 - css/container.css | 0 css/global.css | 293 +++++++++++++++++ css/header.css | 10 + css/layout.css | 189 +++++++++++ css/menu.css | 170 ++++++++++ index.php | 78 +++++ js/actionScript.js | 264 ++++++++++++++++ js/pageManager.js | 237 ++++++++++++++ js/shortcut.js | 145 +++++++++ manager/database.php | 18 ++ manager/security.php | 76 +++++ manager/user.php | 135 ++++++++ page/_JS/auth.js | 80 +++++ page/_JS/groups.js | 43 +++ page/auth.php | 42 +++ page/career.php | 1 + page/groups.php | 145 +++++++++ page/home.php | 42 +++ page/marks.php | 1 + page/modules.php | 4 + page/semestre.php | 1 + page/settings.php | 1 + page/ue.php | 1 + src/input_icon/default.svg | 1 + src/input_icon/default_grayscale.svg | 59 ++++ src/input_icon/password.svg | 49 +++ src/input_icon/password_grayscale.svg | 51 +++ src/input_icon/user.svg | 59 ++++ src/input_icon/user_grayscale.svg | 61 ++++ src/menu_icon/auth.svg | 53 ++++ src/menu_icon/auth_grayscale.svg | 53 ++++ src/menu_icon/groups.svg | 51 +++ src/menu_icon/groups_grayscale.svg | 51 +++ src/menu_icon/home.svg | 151 +++++++++ src/menu_icon/home_grayscale.svg | 151 +++++++++ src/menu_icon/marks.svg | 57 ++++ src/menu_icon/marks_grayscale.svg | 58 ++++ src/menu_icon/modules.svg | 71 +++++ src/menu_icon/modules_grayscale.svg | 71 +++++ src/menu_icon/settings.svg | 49 +++ src/menu_icon/settings_grayscale.svg | 49 +++ src/menu_icon/ue.svg | 53 ++++ src/menu_icon/ue_grayscale.svg | 53 ++++ src/userlist.json | 32 ++ xdoc/cdcf_droits | 35 +++ xdoc/droits.svg | 123 ++++++++ xdoc/login-page.png | Bin 0 -> 17523 bytes xdoc/rdv1_tutrice | 1 + xdoc/sid.rules | 258 +++++++++++++++ xdoc/svg/API.png | Bin 0 -> 64217 bytes xdoc/svg/API.svg | 437 ++++++++++++++++++++++++++ xdoc/svg/architecture.png | Bin 0 -> 59674 bytes xdoc/svg/architecture.svg | 341 ++++++++++++++++++++ xdoc/test.php | 6 + xdoc/verifType.php | 34 ++ 59 files changed, 4670 insertions(+), 1 deletion(-) create mode 100755 API.js create mode 100755 API.php mode change 100644 => 100755 LICENSE mode change 100644 => 100755 README.md create mode 100755 css/container.css create mode 100755 css/global.css create mode 100755 css/header.css create mode 100755 css/layout.css create mode 100755 css/menu.css create mode 100755 index.php create mode 100755 js/actionScript.js create mode 100755 js/pageManager.js create mode 100755 js/shortcut.js create mode 100755 manager/database.php create mode 100755 manager/security.php create mode 100755 manager/user.php create mode 100755 page/_JS/auth.js create mode 100755 page/_JS/groups.js create mode 100755 page/auth.php create mode 100755 page/career.php create mode 100755 page/groups.php create mode 100755 page/home.php create mode 100755 page/marks.php create mode 100755 page/modules.php create mode 100755 page/semestre.php create mode 100755 page/settings.php create mode 100755 page/ue.php create mode 100755 src/input_icon/default.svg create mode 100755 src/input_icon/default_grayscale.svg create mode 100755 src/input_icon/password.svg create mode 100755 src/input_icon/password_grayscale.svg create mode 100755 src/input_icon/user.svg create mode 100755 src/input_icon/user_grayscale.svg create mode 100755 src/menu_icon/auth.svg create mode 100755 src/menu_icon/auth_grayscale.svg create mode 100755 src/menu_icon/groups.svg create mode 100755 src/menu_icon/groups_grayscale.svg create mode 100755 src/menu_icon/home.svg create mode 100755 src/menu_icon/home_grayscale.svg create mode 100755 src/menu_icon/marks.svg create mode 100755 src/menu_icon/marks_grayscale.svg create mode 100755 src/menu_icon/modules.svg create mode 100755 src/menu_icon/modules_grayscale.svg create mode 100755 src/menu_icon/settings.svg create mode 100755 src/menu_icon/settings_grayscale.svg create mode 100755 src/menu_icon/ue.svg create mode 100755 src/menu_icon/ue_grayscale.svg create mode 100755 src/userlist.json create mode 100755 xdoc/cdcf_droits create mode 100755 xdoc/droits.svg create mode 100755 xdoc/login-page.png create mode 100755 xdoc/rdv1_tutrice create mode 100755 xdoc/sid.rules create mode 100755 xdoc/svg/API.png create mode 100755 xdoc/svg/API.svg create mode 100755 xdoc/svg/architecture.png create mode 100755 xdoc/svg/architecture.svg create mode 100755 xdoc/test.php create mode 100755 xdoc/verifType.php diff --git a/API.js b/API.js new file mode 100755 index 0000000..d5b8def --- /dev/null +++ b/API.js @@ -0,0 +1,77 @@ +/* classe API */ +function APIClass(){}; + +APIClass.prototype = { + xhr: [], // tableau d'objets pour les requêtes ajax + + + + /* transaction avec le serveur (API.php) + * + * @param pRequest l'objet passé en JSON à API.php + * @param pHandler fonction qui s'éxécutera lors de la réponse (1 argument -> réponse) + * + * @return answer l'objet retourné par API.php via pHandler (1er argument) + * + *************************************************************************************************** + * + * @usecase + * 1. var answerObject = sendRequest( + * 2. { var1: "exemple", var2: 198294 }, + * 3. function(rep){ alert(rep); } + * 4. ); + * @explain + * 1. on appelle la fonction <=> on créé la requête + * 2. on passe l'objet qui sera envoyé + * 3. on passe une fonction qui utilise un argument (sera la réponse de API.php) (sous forme d'objet) + * + */ + send: function(pRequest, pHandler){ + + // on efface les requêtes qui sont terminées (toutes celles de this.xhr) + for( var i = 0 ; i < this.xhr.length ; i++ ){ + if( this.xhr[i].readyState == 4 ) // si terminée + this.xhr = this.xhr.slice(0,i-1).concat(this.xhr.slice(i,this.xhr.length-1)); // suppression entrée + } + + // on créé une nouvelle entrée + this.xhr.push(null); + i = this.xhr.length-1; + + // création de l'objet AJAX + if(window.XMLHttpRequest) // IE7+, Firefox, Chrome, Opera, Safari + this.xhr[i] = new XMLHttpRequest(); + else // IE5, IE6 + this.xhr[i] = new ActiveXObject('Microsoft.XMLHttpRequest'); + + console.log(pRequest); + + var ptrAPI = this; + this.xhr[i].onreadystatechange = function(){ + if( ptrAPI.xhr[i].readyState == 4 ){ // si la requête est terminée + + /* DEBUG : affiche la réponse BRUTE de API.php */ + // console.log('API.php => '+ptrAPI.xhr[i].responseText); + console.log(JSON.parse(ptrAPI.xhr[i].responseText) ); + + /* si success de requête */ + if( [0,200].indexOf(ptrAPI.xhr[i].status) > -1 ){ // si fichier existe et reçu + try{ pHandler( JSON.parse(ptrAPI.xhr[i].responseText) ); } // si on peut parser, on envoie + catch(e){ pHandler({request:'corrupted'}); } // sinon on envoie obj.request = 'corrupted' + } + /* sinon retourne obj.request = 'unreachable' */ + else + pHandler({request: 'unreachable'}); + + } + } + + // on créé un formulaire POST (virtuel) + var form = new FormData(); + form.append('json', JSON.stringify(pRequest) ); // on créé la variable $_POST['json']=>request + + this.xhr[i].open('POST', 'API.php', true); + this.xhr[i].send( form ); + + } +}; diff --git a/API.php b/API.php new file mode 100755 index 0000000..08d527c --- /dev/null +++ b/API.php @@ -0,0 +1,99 @@ +level_0 ){ + + /***************/ + /* UTILISATEUR */ + /***************/ + case 'user': + if( isset($request->level_1) ){ include 'manager/user.php'; user_switch_level_1($request, $answer); } + else { $answer->request = 'missing_level_1'; } + break; + + + /***********/ + /* GROUPES */ + /***********/ + case 'groups': + $answer->type = "group"; + break; + + + /******/ + /* UE */ + /******/ + case 'ues': + break; + + + /**********/ + /* MODULE */ + /**********/ + case 'modules': + break; + + + /************/ + /* CONTRÔLE */ + /************/ + case 'tests': + break; + + + /**************/ + /* PARAMETRES */ + /**************/ + case 'settings': + break; + + + /***********/ + /* DEFAULT */ + /***********/ + default: + $answer->request = 'unknown_level_0'; + break; + } + + + if( $answer == null ) + $answer->request = 'no_level_0'; + + + + }else // si json corrompu (undécodable) + $answer->request = 'jsoncorrupted'; + + }else // $_POST vide [OU] $_POST['json'] pas défini + $answer->request = 'nopost'; + + + // on envoie (affiche) l'objet en JSON + echo json_encode($answer); + + } + +?> \ No newline at end of file diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 index 6ad259f..ae4adf0 --- a/README.md +++ b/README.md @@ -1,2 +1 @@ # SID -Système d'Information du Département diff --git a/css/container.css b/css/container.css new file mode 100755 index 0000000..e69de29 diff --git a/css/global.css b/css/global.css new file mode 100755 index 0000000..af02993 --- /dev/null +++ b/css/global.css @@ -0,0 +1,293 @@ +/* +* +* Gestion des règles globales +* ------------------------------------- +* 1-1. sections +* 1-2. titres des sections +* 2-1. tableaux génériques +* 2-2. tableaux manuels +* 3. formulaires +* 4. paragraphes +* 5. liens +* 6. ... +* +*/ + + + + + +/*********************/ +/*** 1-1. Sections ***/ +/*********************/ +Hgroup + section{ + /* position */ + display: none; /* on cache par défaut si le titre n'est pas actif */ + position: absolute; + top: calc( 5px + 3em + 1px ); /* 1px pour que le border soit au même endroit que celui de Hgroup */ + left: 0; + width: calc( 100% - 2*2em ); + height: auto; + padding: 2em; /* top right/left bottom */ + + /* border */ + border-top: 1px solid #aaa; + + /* z axis */ + z-index: 7; +} + +/* on active le premier par défaut si aucun n'est .active*/ +/*Hgroup:nth-child(1) + section{ + display: block; + z-index: 8; +}*/ + +Hgroup.active + section{ + display: block; + z-index: 9; +} + + +/********************************/ +/*** 1-2. Titres des sections ***/ +/********************************/ +Hgroup{ + /* position */ + display: block; + position: relative; + float: left; + margin-top: 5px; + margin-left: 1em; + height: 3em; + padding: 0 2em; + + /* border */ + border-radius: 3px 3px 0 0; + border: 1px solid transparent; + border-bottom-color: #aaa; + + /* background */ + background-color: inherit; + + /* foreground */ + color: #666; + text-align: center; + line-height: 3em; + + /* Xtra */ + cursor: pointer; + + /* animation */ + transition: .1s ease-in-out; + -moz-transition: .1s ease-in-out; + -webkit-transition: .1s ease-in-out; + -ms-transition: .1s ease-in-out; + -o-transition: .1s ease-in-out; + + /* z axis */ + z-index: 10; +} + + +/*Hgroup:nth-child(1) ~ .active,*/ +Hgroup.active{ + /* border */ + border-color: #aaa; + border-bottom-color: inherit; + + /* foreground */ + color: #000; +} + + + + + + + + + + + + + +/********************************/ +/*** 2-1. Tableaux génériques ***/ +/********************************/ +table { + font-family:Arial, Helvetica, sans-serif; + color:#666; + font-size:12px; + text-shadow: 1px 1px 0px #fff; + background:#eaebec; + margin:20px; + border:#ccc 1px solid; + + border-spacing: 0; + + -moz-border-radius:3px; + -webkit-border-radius:3px; + border-radius:3px; + + -moz-box-shadow: 0 1px 2px #d1d1d1; + -webkit-box-shadow: 0 1px 2px #d1d1d1; + box-shadow: 0 1px 2px #d1d1d1; + + text-align: center; +} + +table th { + padding:21px 25px 22px 25px; + border-top:1px solid #fafafa; + border-bottom:1px solid #e0e0e0; + + background: #ededed; + background: -webkit-gradient(linear, left top, left bottom, from(#ededed), to(#ebebeb)); + background: -moz-linear-gradient(top, #ededed, #ebebeb); +} + +table tr:first-child th:first-child { + -moz-border-radius-topleft:3px; + -webkit-border-top-left-radius:3px; + border-top-left-radius:3px; +} + +table tr:first-child th:last-child { + -moz-border-radius-topright:3px; + -webkit-border-top-right-radius:3px; + border-top-right-radius:3px; +} + +table tr { + padding-left:20px; +} + +table td:first-child { + border-left: 0; +} + +table td { + padding:18px; + border-top: 1px solid #ffffff; + border-bottom:1px solid #e0e0e0; + border-left: 1px solid #e0e0e0; + + background: #fafafa; + background: -webkit-gradient(linear, left top, left bottom, from(#fbfbfb), to(#fafafa)); + background: -moz-linear-gradient(top, #fbfbfb, #fafafa); +} + +table tr.even td { + background: #f6f6f6; + background: -webkit-gradient(linear, left top, left bottom, from(#f8f8f8), to(#f6f6f6)); + background: -moz-linear-gradient(top, #f8f8f8, #f6f6f6); +} + +table tr:last-child td { + border-bottom:0; +} + +table tr:last-child td:first-child { + -moz-border-radius-bottomleft:3px; + -webkit-border-bottom-left-radius:3px; + border-bottom-left-radius:3px; +} + +table tr:last-child td:last-child { + -moz-border-radius-bottomright:3px; + -webkit-border-bottom-right-radius:3px; + border-bottom-right-radius:3px; +} + +table tr:hover td { + background: #f2f2f2; + background: -webkit-gradient(linear, left top, left bottom, from(#f2f2f2), to(#f0f0f0)); + background: -moz-linear-gradient(top, #f2f2f2, #f0f0f0); +} + +/* http://johnsardine.com/example/simple-little-table/ */ + + +/**********************/ +/*** 3. Formulaires ***/ +/**********************/ +/* champs de texte */ +section form input[type=text], +section form input[type=password]{ + /* position */ + display: block; + position: relative; + margin: 2em 0; + padding: .8em; + padding-left: 2.5em; + + /* border */ + border-radius: 3px; + border: 1px solid #aaa; + + /* foreground */ + font-family: inherit; + font-size: 1em; + color: #b1b1b1; + + /* background */ + background: #fff url(../src/input_icon/default_grayscale.svg) center left .35em no-repeat; + background-size: 1.8em 1.8em; + + transition: .2s ease-in-out; + -moz-transition: .2s ease-in-out; + -webkit-transition: .2s ease-in-out; + -ms-transition: .2s ease-in-out; + -o-transition: .2s ease-in-out; +} + +/* boutons */ +section form input[type=button]{ + /* position */ + display: block; + position: relative; + margin: 1em 0; + padding: .8em; + + /* border */ + border-radius: 3px; + border: 0; + box-shadow: 1px 1px 0 #207fa8, 2px 2px 0 #207fa8; + + /* foreground */ + font-family: inherit; + font-size: 1em; + color: #fff; + font-weight: bold; + + /* background */ + background: #29a2d6; + + /* Xtra */ + cursor: pointer; +} + +/* clic sur les boutons */ +section form input[type=button]:focus{ + box-shadow: 0 0 0 transparent; + margin-top: calc( 1em + 2px ); + margin-left: 2px; +} + + +/* quand on selectionne */ +section form input[type=text]:focus, +section form input[type=password]:focus{ + background-image: url(../src/input_icon/default.svg); + color: #000; + border-color: #29a2d6; +} + + +/* GESTION DES ICÔNES SPECIFIQUES */ +section form input[type=password] { background-image: url(../src/input_icon/password_grayscale.svg); } +section form input[type=password]:focus{ background-image: url(../src/input_icon/password.svg); } + +section form input.user { background-image: url(../src/input_icon/user_grayscale.svg); } +section form input.user:focus { background-image: url(../src/input_icon/user.svg); } diff --git a/css/header.css b/css/header.css new file mode 100755 index 0000000..abcdea3 --- /dev/null +++ b/css/header.css @@ -0,0 +1,10 @@ +/* +* +* Gestion complète du HEADER +* ------------------------------------- +* 1. icon +* 2. connection/inscription +* 3. mot de passe perdu +* 4. ... +* +*/ \ No newline at end of file diff --git a/css/layout.css b/css/layout.css new file mode 100755 index 0000000..290f42d --- /dev/null +++ b/css/layout.css @@ -0,0 +1,189 @@ +/* +* +* Positionnement global et mise en page +* ------------------------------------- +* 1. Propriétés globales +* 2. MENU +* 3. CONTAINER +* 4. msgBox +* +*/ + + + + + + + + +/******************************/ +/*** 1. Propriétés globales ***/ +/******************************/ +*{ /* on supprime le margin/padding par défaut */ + margin : 0; + padding: 0; +} + + +/* on initialise le body avec les valeurs par défaut [compatibilité] */ +body{ + /* position */ + display: block; + position: absolute; + top : 0; + left : 0; + width : 100%; + height: 100%; + + /* background */ + background: #fff; + + /* overflow */ + overflow-x: hidden; /* empêche la barre horizontale de scroll [précaution] */ + + /* foreground */ + font: 18px 'Open Sans', 'Helvetica', 'Arial', 'sans-serif'; + font-size: 16px; +} + + + + + + + +/***************/ +/*** 2. MENU ***/ +/***************/ +#MENU{ + /* position */ + display: flex; + position: fixed; + top : 0; + left : 0; + width : 5.5em; + height: 100%; + + /* flex */ + flex-direction : column; + justify-content: flex-start; + flex-wrap: nowrap; /* default, une seule colonne */ + + + /* background */ + /*background: #424c54 url(https://www.iut-tlse3.fr/static/ui/v1/icons/iut/iut.png) bottom .9em center no-repeat;*/ + background: #424c54; + + /* foreground */ + /*font-size: 1.7vh;*/ + + /* z axis */ + z-index: 2; + + /* list */ + list-style-type: none; +} + + + + + +/********************/ +/*** 3. CONTAINER ***/ +/********************/ +#CONTAINER{ + /* position */ + display: block; + position: absolute; + top : 0; + left : 5.5em; + width : calc( 100% - 5.5em ); + min-height: 100%; + + /* background */ + background: #fff; + + /* foreground */ + /*font-size: 1.7vh;*/ + + /* border < inherit < hgroup */ + border-color: #fff; + + /* z axis */ + z-index: 0; +} + + +/*****************/ +/*** 4. MSGBOX ***/ +/*****************/ +#MSGBOX{ + /* position */ + display: block; + position: fixed; + top: calc( 100% - 2*1em - 1em - 1em ); /* 100% - padding - taille - marge */ + left: 30%; + width: 40%; + height: 1em; + padding: 1em; + + /* border */ + border-radius: 3px; + border: 1px solid transparent; + + /* background */ + background-color: #f64b2f; + + /* foreground */ + color: #fff; + text-shadow: 1px 1px 1px #d33e27; + line-height: 1em; + + transition: all 0s ease 0s, top .3s ease-in-out; + -moz-transition: all 0s ease 0s, top .3s ease-in-out; + -webkit-transition: all 0s ease 0s, top .3s ease-in-out; + -ms-transition: all 0s ease 0s, top .3s ease-in-out; + -o-transition: all 0s ease 0s, top .3s ease-in-out; +} + +/* LES DIFFERENTES CLASSES */ + +/* validation ou réussite */ +#MSGBOX.success{ + border-color: #689525; + background-color: #7eb62e; + text-shadow: 1px 1px 1px #689525; +} + +/* information */ +#MSGBOX.info{ + border-color: #278fd0; + background-color: #2fa9f6; + text-shadow: 1px 1px 1px #278fd0; +} + +/* avertissement */ +#MSGBOX.warning{ + border-color: #d87620; + background-color: #f68725; + text-shadow: 1px 1px 1px #d87620; +} + +/* notice */ +#MSGBOX.error{ + border-color: #d33e27; + background-color: #f64b2f; + text-shadow: 1px 1px 1px #d33e27; +} + +/* LORSQUE PAS ACTIVE */ +#MSGBOX:not( [class] ), /* si n'a pas de classe */ +#MSGBOX[class='']{ /* ou qu'elle est vide */ + top: 100%; + + transition: all 0s ease .3s, top .3s ease-in-out; + -moz-transition: all 0s ease .3s, top .3s ease-in-out; + -webkit-transition: all 0s ease .3s, top .3s ease-in-out; + -ms-transition: all 0s ease .3s, top .3s ease-in-out; + -o-transition: all 0s ease .3s, top .3s ease-in-out; +} \ No newline at end of file diff --git a/css/menu.css b/css/menu.css new file mode 100755 index 0000000..1307ee8 --- /dev/null +++ b/css/menu.css @@ -0,0 +1,170 @@ + +* +* Gestion complète du MENU +* ------------------------------------- +* 1. propriétés complémentaires #MENU +* 2. position textes +* 3. icônes +* 4. Labels +* +*/ + + + + +/*******************************************/ +/*** 1. Propriétés complémentaires #MENU ***/ +/*******************************************/ +#MENU{} + + + +/**************************/ +/*** 2. Position textes ***/ +/**************************/ +#MENU li{ + /* position */ + display: block; + position: relative; + margin: .75em; + width: 4em; /* 5.5 - 1.5 */ + height: 4em; + + /* border */ + border-radius: .3em; + + /* background */ + background: center center no-repeat; + background-size: auto 2.2em; + + /* Xtra */ + cursor: pointer; + -webkit-touch-callout: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + + /* animation */ + transition: all 0s, background-color .2s ease-in-out; + -moz-transition: all 0s, background-color .2s ease-in-out; + -webkit-transition: all 0s, background-color .2s ease-in-out; + -ms-transition: all 0s, background-color .2s ease-in-out; + -o-transition: all 0s, background-color .2s ease-in-out; +} + + + +/*****************/ +/*** 3. Icônes ***/ +/*****************/ +/* dernier en bas */ +#MENU li:last-child{ align-self: flex-start; } + +/* icônes de base */ +#MENU li[data-link='home'] { background-image: url(../src/menu_icon/home_grayscale.svg); } +#MENU li[data-link='groups'] { background-image: url(../src/menu_icon/groups_grayscale.svg); } +#MENU li[data-link='ue'] { background-image: url(../src/menu_icon/ue_grayscale.svg); } +#MENU li[data-link='modules'] { background-image: url(../src/menu_icon/modules_grayscale.svg); } +#MENU li[data-link='marks'] { background-image: url(../src/menu_icon/marks_grayscale.svg); } +#MENU li[data-link='settings'] { background-image: url(../src/menu_icon/settings_grayscale.svg); } +#MENU li[data-link='auth'] { background-image: url(../src/menu_icon/auth_grayscale.svg); } + +/* HOVER ou active (page courante) */ +#MENU li:hover, #MENU li.active{ + color: #fff; + background-color: rgba(0,0,0,.3); +} + +/* icône quand HOVER ou .active */ +#MENU li[data-link='home']:hover , #MENU li[data-link='home'].active { background-image: url(../src/menu_icon/home.svg); } +#MENU li[data-link='groups']:hover , #MENU li[data-link='groups'].active { background-image: url(../src/menu_icon/groups.svg); } +#MENU li[data-link='ue']:hover , #MENU li[data-link='ue'].active { background-image: url(../src/menu_icon/ue.svg); } +#MENU li[data-link='modules']:hover , #MENU li[data-link='modules'].active { background-image: url(../src/menu_icon/modules.svg); } +#MENU li[data-link='marks']:hover , #MENU li[data-link='marks'].active { background-image: url(../src/menu_icon/marks.svg); } +#MENU li[data-link='settings']:hover , #MENU li[data-link='settings'].active { background-image: url(../src/menu_icon/settings.svg); } +#MENU li[data-link='auth']:hover , #MENU li[data-link='auth'].active { background-image: url(../src/menu_icon/auth.svg); } + + +/* le séparateur qui remplit l'espace entre le haut et le bas */ +#MENU li.fill{ + flex-grow: 1; + opacity: 0; + cursor: default; +} + + + +/*****************/ +/*** 4. Labels ***/ +/*****************/ +#MENU li[data-text]::before{ /* affichage du texte */ + content: attr(data-text); + + /* position */ + display: block; + position: absolute; + top: .4em; + left: 6em; + width: auto; + width: 0; + height: 3em; + padding: 0 0; + + /* border */ + border-radius: 5px; + + /* background */ + background: #232323; + + /* foreground */ + line-height: 3em; + + /* animation */ + transition: .1s ease-out; + -moz-transition: .1s ease-out; + -webkit-transition: .1s ease-out; + -ms-transition: .1s ease-out; + -o-transition: .1s ease-out; + + /* overflow */ + overflow: hidden; + + /* z axis */ + z-index: -1; +} + + + +#MENU li[data-text]::after{ /* petite flèche */ + content: ''; + + /* position */ + display: none; + position: absolute; + top: 1.16em; + left: 5.7em; + + /* border */ + border-style: solid; + border-width: .8em .8em .8em 0; + border-color: transparent #232323 transparent transparent; + + /* animation */ + transition: .2s ease-in; + -moz-transition: .2s ease-in; + -webkit-transition: .2s ease-in; + -ms-transition: .2s ease-in; + -o-transition: .2s ease-in; + + /* z axis */ + z-index: -1; +} + + + +/* lors du survol */ + +#MENU li[data-text]:hover::before{ width: auto; left: 6em; padding: 0 1em; } /* affichage du texte */ + +#MENU li[data-text]:hover::after{ display: block; } /* affichage de la petite flèche \ No newline at end of file diff --git a/index.php b/index.php new file mode 100755 index 0000000..a25e302 --- /dev/null +++ b/index.php @@ -0,0 +1,78 @@ + + + + + + + Système d'Information du Département + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
Hey! Your password is not the right one.
+ + + + + + + + + + + + + diff --git a/js/actionScript.js b/js/actionScript.js new file mode 100755 index 0000000..723d7b0 --- /dev/null +++ b/js/actionScript.js @@ -0,0 +1,264 @@ + + /*********************************************************** + * * + * SCRIPT POST-HTML - SCRIPT PRINCIPAL * + * * + ************************************************************ + * * + * [0] Variables * + * [1] Gestionnaires de navigation * + * [a] pageManager.js * + * [b] API.js * + * [2] Gestion des liens * + * [a] catégories * + * [b] sous-parties * + * [3] Gestion des formulaires * + * [4] Gestion de la messageBox * + * * + * * + * * + * * + * * + * * + * * + * * + * * + ***********************************************************/ + + +/* [0] VARIABLES +==============================================================*/ +var msgBoxTimeout = null; + +/* pageManager */ +var pageM; +/* API */ +var API; + +/* Structure de la page */ +var DOM = { + menu : document.getElementById('MENU'), + container : document.getElementById('CONTAINER'), + msgBox : document.getElementById('MSGBOX') +}; + + + + + + + +/* [1] GESTIONNAIRES DE NAVIGATION +==============================================================*/ + + + /* [a] pageManager.js + ==============================================================*/ + pageM = new pageManager(); // instance principale + + /* initialisation du gestionnaire */ + pageM.setPage(null, 'page', DOM.container, ['home', 'groups', 'ue', 'modules', 'marks', 'auth', 'settings'] ); + + + /* [b] API.js + ==============================================================*/ + API = new APIClass(); + + + + + + + +/* [2] GESTION DES LIENS +==============================================================*/ + + + /* [a] CATÉGORIES + ==============================================================*/ + /* GESTION DES CATEGORIES (SECTIONS) + * + * @param section l'élément à activer + * + * [1] selectionne l'élément, l'affichage de la page associée est géré par pageManager.js + * [2] déselectionne l'élément précédemment selectioné + * + */ + function selectSection(section){ + + // si @subSection est un de type
  • qui a la propriété "data-link" [ET] section pas déjà active + if( section instanceof Element && section.tagName == 'LI' && section.dataset.hasOwnProperty('link') && section.className != 'active' ){ + + // on charge la page + pageM.setPage( section.dataset.link ); + + // on récupère la section déja selectionnée si elle existe + var last = document.querySelector('#MENU li.active'); + + if( last != null ) // si une section est déjà activée + last.className = ''; // on désactive la courante + + section.className = 'active'; // on active @section + + }else // sinon on affiche l'erreur + console.log("[selectSection_Error] - ("+section+")"); + + } + + /* activation au chargement en fonction de la page courante de pageManager.js */ + lastSection = document.querySelector('[data-link='+pageM.page+']'); + lastSection.className = 'active'; // on l'active + + /* Gestion des liens du menu */ + DOM.menu.addEventListener('click', function(e){ selectSection( e.target ); }, false); + + + /* [b] SOUS-PARTIES + ==============================================================*/ + /* GESTION DES SOUS-PARTIES (SOUS-CATÉGORIES) + * + * @param subSection l'élément à activer + * + * [1] selectionne l'élément, l'affichage de la page associée est géré en CSS3 + * [2] déselectionne l'élément précédemment selectioné + * + */ + function selectSubSection(subSection){ + + // si @subSection est un de type HGROUP [ET] + if( subSection instanceof Element && subSection.tagName == 'HGROUP' ){ + + if( subSection.className != 'active' ){ // si @subSection pas déjà active + + // on récupère la sous-partie selectionnée en cours + var last = document.querySelector('hgroup.active'); + + if( last != null ) // si un sous-partie est déjà selectionnée + last.className = ''; // on la désactive + + subSection.className = 'active'; // on active @subSection + + }else // sinon on affiche l'erreur + console.log("[selectSubSection_Error] - ("+subSection+")"); + + } + + } + + /* gestion du clic sur les sous-parties */ + DOM.container.addEventListener('click', function(e){ selectSubSection(e.target); }, false); + + + + + + + + +/* [3] GESTION DES FORMULAIRES +==============================================================*/ +/* INITIALISE UN FORMULAIRE POUR QU'IL INTERPRETE UN OBJET LORS DE SA SOUMISSIONS +* +* @param pForm le formulaire cible +* @param pHandler fonction exécutée lors de la soumission du formulaire +* +* [1] parcourt les élements du formulaire @pForm et active un évènement lors du "submit" +* [2] retourne l'objet à @pHandler lors du "submit" +* +* +* @example +* +*
    +* +* +* +* +* +* +*
    +* +* @explaination +* +* Lors du clic sur le bouton [VALIDER], la fonction @pHandler s'exécutera avec pour paramètre un objet +* OBJ{ id: nomFormulaire, nomDuChamp1: valeurDuChamp1, nomDuChamp2: valeurDuChamp2 } +* +*/ +function initForm(pForm, pHandler){ + + // vérification des arguments + var isForm = pForm instanceof Element && pForm.tagName == 'FORM'; + var isFunc = pHandler instanceof Function; + + // si les arguments sont corrects + if( pForm instanceof Element && pForm.tagName == 'FORM' ){ + + var submitButton = null; // contiendra le bouton d'envoi du formulaire + + for( var i = 0 ; i < pForm.children.length ; i++ ) + if( pForm.children[i].type == 'button' && pForm.children[i].name == 'submit' ){ + submitButton = pForm.children[i]; // on définit le bouton + break; // on sort du for + } + + + // on définit l'évènement de validation du formulaie + function submitEvent(){ + + var obj = {} // on créé l'objet qui va être envoyé + + for( var i = 0 ; i < pForm.children.length ; i++ ) // on parcourt les enfants + if( pForm.children[i].tagName == 'INPUT' && pForm.children[i].name != 'submit' ) // si c'est un champ et que c'est pas le bouton + obj[pForm.children[i].name] = pForm.children[i].value; // alors on enregistre le champ dans l'objet + + // on exécute la fonction @pHandler en lui envoyant les arguments + pHandler(obj); + + } + + // on définit l'évènement du clic sur le bouton + submitButton.addEventListener('click', function(e){ + submitEvent(e.target.parentNode); // on envoie le formulaire + }, false); + + // on définit l'évènement de l'appui sur la touche [ENTRER] + pForm.addEventListener('keydown', function(e){ + if(e.keyCode==13) submitEvent(e.target); // si c'est la bonne touche, on submit le formulaire + }, false); + + + + }else + console.log('[initForm_Error] - ('+pForm+', '+pHandler+')'); + + +} + + + + + + + +/* [4] GESTION DE LA MESSAGEBOX +==============================================================*/ +function messageBox(message, type){ + + /* on affecte le message */ + DOM.msgBox.innerHTML = message; + + /* on définit le style s'il est correct */ + if( ['success', 'info', 'warning', 'error'].indexOf(type) > -1 ) + DOM.msgBox.className = type; + else + DOM.msgBox.className = 'info'; + + + + if( msgBoxTimeout != null ) // si une autre message box est en cours, on arrête son timeout + clearTimeout(msgBoxTimeout); + + msgBoxTimeout = setTimeout( function(){ + DOM.msgBox.className = ''; + }, 2000); + +} \ No newline at end of file diff --git a/js/pageManager.js b/js/pageManager.js new file mode 100755 index 0000000..44ce627 --- /dev/null +++ b/js/pageManager.js @@ -0,0 +1,237 @@ +function pageManager(){}; + +var ptrPageManager; // pointeur global pour l'utilisation de fonctions de fonctions + +pageManager.prototype = { + depJS: null, // la dépendance javascript + depCSS: null, // la dépendance css + xhr: [], // tableau d'objets pour les requêtes ajax + page: null, // l'indice de la page courante dans pagelist + vars: [], // les variables suivant le nom de la page dans l'URL + path: '', // le chemin du dossier contenant les pages (.php) + pagelist: null, // la liste des pages pouvant être chargées + container: null, // élément DOM qui contiendra le contenu des pages à charger + /* ======================================================================= + Cette fonction effectue une requête Ajax (compatible à partir de IE5) + PARAMETRES: + - pLink le lien à charger + - pHandler une fonction qui s'éxécutera avec la réponse de la requête passée en paramètre (voir exemples dessous pour pHandler) + - pMethod type de méthode, vaut 'POST' ou 'GET' et vaut 'POST' par défaut ou s'il n'est pas renseigné + - pForm formulaire de type FormData() contenant les données à envoyer (uniquement en POST), si pForm vaut GET les données doivent être passées dans l'URL + ========================================================================== */ + ajax: function(pLink, pHandler, pMethod, pForm){ + // on efface les requêtes qui sont terminées et on push une nouvelle + for( var i = 0 ; i < this.xhr.length ; i++ ){ + if( this.xhr[i].readyState == 4 ) // si terminée + this.xhr = this.xhr.slice(0,i-1).concat(this.xhr.slice(i,this.xhr.length-1)); // suppression entrée + } + + this.xhr.push(true); + i = this.xhr.length-1; + + if(window.XMLHttpRequest) // IE7+, Firefox, Chrome, Opera, Safari + this.xhr[i] = new XMLHttpRequest(); + else // IE5, IE6 + this.xhr[i] = new ActiveXObject('Microsoft.XMLHttpRequest'); + + var ptrPageManager = this; + this.xhr[i].onreadystatechange = function(){ + if( ptrPageManager.xhr[i].readyState == 4 ) // si la requête est terminée + if( [0,200].indexOf(ptrPageManager.xhr[i].status) > -1 ) // si fichier existe et reçu + pHandler(ptrPageManager.xhr[i].responseText); + else // si code d'erreur retourne null + pHandler(); + } + + // gestion de la méthode + var method = ( typeof pMethod == 'string' && /^POST|GET$/i.test(pMethod) ) ? pMethod.toUpperCase() : 'POST'; + + // gestion du formulaire si la méthode est POST + var form = ( method == 'POST' && typeof pForm == 'object' && pForm instanceof FormData ) ? pForm : null; + + this.xhr[i].open( method, pLink, true); + this.xhr[i].send( form ); + }, + /***************************************************** [APPLICATION] Ajax() ******************************************************/ + // EXEMPLES DE FONCTIONS POUR pHandler // + // 1. var a = function(param){ alert(param); } // les deux notations 1 et 2 sont équivalents + // 2. function a(param){ alert(param); } // les deux notations 1 et 2 sont équivalents + + // ajax( 'index.php', a ); // utilisation d'une fonction définie + + // ajax( 'index.php', alert ); // utilisation d'une fonction prédéfinie + // ajax( 'index.php', alert, 'GET' ); // utilisation de méthode + + // var fd = new FormData(); // création d'un formulaire + // fd.append('var', 100); // ajout de la variable VAR qui vaut 100 + + // ajax( 'index.php', alert, null, fd ); // saut de paramètre avec null + envoi formulaire + // ajax( 'index.php?var=10', alert, 'GET' ); // envoi formulaire en GET (dans l'url) + // ajax( 'index.php?var=10', alert, 'POST', fd ); // envoi formulaire en GET (dans l'url) + en POST via le formulaire FD + + + /* ======================================================================= + Cette fonction effectue une décomposition de l'URL sur le shéma spécifié dessous + Renvoie pour http://www.exemple.com/dirA/dirB/#/NOMPAGE/VARPAGE + - null si la page n'est pas référencée dans le tableau PAGELIST + - null si le lien ne contient pas /#/NOMPAGE à la fin + - null si NOMPAGE ne contient pas uniquement : lettres, chiffres, underscore + - null si VARPAGE ne contient pas uniquement : lettres, chiffres, underscore + - un objet contenant {page: valeur, var: valeur} + ========================================================================== */ + explodeURL: function(url_data){ + url_data = (arguments.length >= 1) ? url_data : document.URL; + // si pageList est correct et que l'URL correspond à un schéma de page => continue [sinon] return null + if( this.pagelist != null && /^(?:.+)\/#\/([a-z0-9_]+)\/?(?:\/((?:[a-z0-9_]+\/)+)\/?)?$/i.test(url_data) ){ + // si la page récupérée dans l'url est dans la liste => renvoi de l'objet [sinon] null + var vars = RegExp.$2.split('/'); + while( vars[vars.length-1] == '' ) // on supprime les dernières entrées vides + vars.pop(); + + return ( this.pagelist.indexOf(RegExp.$1) > -1 ) ? {page: RegExp.$1, var: vars} : null; + }else + return null; + }, + /* ======================================================================= + Cette fonction ajoute des dépendances (un js et un css) situés dans le répertoire des pages. + pageDir/ + _JS/ + page1.js + page2.js + _CSS/ + page1.css + page2.css + ========================================================================== */ + loadDependencies: function(){ + // si depCSS est un élément du DOM c'est à dire qu'il contient le fichier de la page précédente et qu'il est enfant de , on le détruit + if( typeof this.depCSS == 'object' && this.depCSS instanceof Element && this.depCSS.parentNode == document.head ) + document.head.removeChild( this.depCSS ); + + // si depJS est un élément du DOM c'est à dire qu'il contient le fichier de la page précédente, on le détruit + if( typeof this.depJS == 'object' && this.depJS instanceof Element && this.depJS.parentNode == document.head ) + document.head.removeChild( this.depJS ); + + ptrPageManager = this; + // si le fichier css existe + this.ajax(this.path+'/'+'_CSS'+'/'+this.page+'.css', function(e){ + if( e != null ){ // on charge la dépendance CSS si le fichier existe + ptrPageManager.depCSS = document.createElement('link'); + ptrPageManager.depCSS.rel = 'stylesheet'; + ptrPageManager.depCSS.type = 'text/css'; + ptrPageManager.depCSS.href = ptrPageManager.path+'/'+'_CSS'+'/'+ptrPageManager.page+'.css'; + document.head.appendChild(ptrPageManager.depCSS); + }else + console.log('[loadDependencies_Error] - ('+ptrPageManager.path+'/'+'_CSS'+'/'+ptrPageManager.page+'.css'+')'); + }); + + // si le fichier js existe + this.ajax(this.path+'/'+'_JS'+'/'+this.page+'.js', function(e){ + if( e != null ){ // on charge la dépendance JS si le fichier existe + ptrPageManager.depJS = document.createElement('script'); + ptrPageManager.depJS.type = 'text/javascript'; + ptrPageManager.depJS.src = ptrPageManager.path+'/'+'_JS'+'/'+ptrPageManager.page+'.js'; + document.head.appendChild(ptrPageManager.depJS); + }else + console.log('[loadDependencies_Error] - ('+ptrPageManager.path+'/'+'_JS'+'/'+ptrPageManager.page+'.js'+')'); + }); + }, + + /* ======================================================================= + Cette fonction est celle qui gère les 2 autres et celle que l'utilisateur utilisera + PARAMETRES: + - pName le nom de la page à charger (lettres, chiffres, underscore) (*) + - pPath chemin (relatif ou absolu) du dossier contenant les pages de même nom de fichier que le nom (extension .php) + - pContainer l'élément du DOM qui contiendra la page chargée (**) + - pPageList> tableau contenant la liste des pages sous forme de chaînes de caractères (**) (***) + * Le chemin du dossier sans le '/' final si c'est le dossier actuel le chemin est une chaîne vide + Si le dossier est 'page' et que l'on cherche la page 'accUe1l', la requête sera vers 'page/accUe1l.php' + le nom de la page est sensible à la casse + ** 1. pPageList et pContainer doivent être mis en paramètres uniquement à la première utilisation + et la première utilisation doit se faire au chargement de la page car elle permetra + de mettre l'URL à jour et/ou charger la page de l'URL + *** la première page du tableau est la page par défaut (qui est chargée si l'URL ne contient + pas la page ou si la page de l'URL ne correspond à aucune page de la liste) + ========================================================================== */ + setPage: function(pName, pPath, pContainer, pPageList){ + + // liste de pages si c'est un tableau + var pageList = ( typeof pPageList == 'object' && pPageList instanceof Array ) ? pPageList : null; // si this.pagelist n'est pas overwrite il vaut null + + if( pageList != null ){ // si c'est un tableau + for( var i = 0 ; i < pageList.length ; i++ ){ // on parcourt tout les éléments pour vérifier que chaque élément ne contient que : lettres, chiffres, underscore [non]> pageList = null + pageList = ( typeof pageList[i] == 'string' && /^[a-z0-9_]+$/i.test(pageList[i]) ) ? pageList : null; + if( pageList == null ) break; // si le tableau est null stoppe la boucle + } + } + /* on attribue la variable temporaire pageList à l'attribut de l'objet si la variable pageList temporaire n'est pas nulle */ + this.pagelist = ( pageList != null ) ? pageList : this.pagelist; + // affecte à l'attribut page la page par défaut (premier élément de pagelist) + this.page = this.pagelist[0]; + // affecte pPath à l'attribut path s'il est renseigné + this.path = ( typeof pPath == 'string' ) ? pPath : this.path; + /* on attribue le paramètre pContainer à l'attribut si il est spécifié */ + this.container = ( typeof pContainer == 'object' && pContainer instanceof Element ) ? pContainer : this.container; + + // si this.pagelist && this.container ne sont pas null && + if( this.pagelist != null && this.container != null ){ + // si le pName est renseigné et qu'il est dans pagelist + if( typeof pName == 'string' && this.pagelist.indexOf(pName) > -1 ){ + // affecte pName à l'attribut page + this.page = pName; + + // charge le contenu de la page dans le container + var ptrPageManager = this; + + // formulaire POST + var fd = new FormData(); + for( var i = 0 ; i < this.vars.length ; i++ ) + fd.append(this.vars[i], null); + + this.ajax(this.path+'/'+this.page+'.php', function(e){ + ptrPageManager.container.innerHTML = e; + ptrPageManager.loadDependencies(); + }, 'POST', fd); + + // change l'URL en conséquences(stateObj, titre, url) + if( this.vars.length > 0 ) // si il y a des variables + window.history.pushState(null, this.page, '#/'+this.page+'/'+this.vars.join('/')+'/'); + else // s'il n'y en a pas + window.history.pushState(null, this.page, '#/'+this.page+'/'); + + }else{ // si la page n'est pas spécifiée ou qu'elle n'est pas dans la liste des pages + var urlGet = this.explodeURL(); + + // si on a récupéré le numéro de la page dans l'URL et qu'elle fait partie de la liste des pages + if( urlGet != null ){ + this.page = urlGet.page; + // charge le contenu de la page dans le container + var ptrThis = this; + + // formulaire POST + var fd = new FormData(); + this.vars.length = 0; + + for( var i = 0 ; i < urlGet.var.length ; i++ ){ // replacing object variables with explodeURL variables + this.vars[i] = urlGet.var[i]; + fd.append(this.vars[i], null); + } + + this.ajax(this.path+'/'+this.page+'.php', function(e){ + ptrThis.container.innerHTML = e; + ptrThis.loadDependencies(); + }, 'POST', fd); + + // change l'URL en conséquences(stateObj, titre, url) + if( this.vars.length > 0 ) // si il y a des variables + window.history.pushState(null, this.page, '#/'+this.page+'/'+this.vars.join('/')+'/'); + else // s'il n'y en a pas + window.history.pushState(null, this.page, '#/'+this.page+'/'); + + }else // si l'url ne contient rien, on charge la page par défaut + this.setPage(this.pagelist[0]); + } + }else + console.log('pagelist et container manquant'); + } + +} \ No newline at end of file diff --git a/js/shortcut.js b/js/shortcut.js new file mode 100755 index 0000000..b032b03 --- /dev/null +++ b/js/shortcut.js @@ -0,0 +1,145 @@ +/* Retourne le keyCode correspondant à la chaîne +* +* @param keyStore enchaînement de touches sous forme de string +* @param handler function qui s'éxécute lors du raccourci +* +* return keyCode le code de la touche correspondante +*/ +function strToKeyCode(str){ + // on enregistre le keyCode du premier caractère + var keyCode = str.toUpperCase().charCodeAt(0); + + // s'il s'agit d'un caractère uniquement (entre "a" et "z") + if( str.length == 1 && keyCode >= 65 && keyCode <= 90 ) + return keyCode; // on retourne le keyCode associé + else + switch( str ){ + case 'ctrl': return 17; break; + case 'maj': return 16; break; + case 'alt': return 18; break; + case 'tab': return 9; break; + } + + return null; +} + + + + +var shortcutList = []; // contient les combinaisons de touches +var shortcutStep = []; // contient l'avancée d'un raccourcis + +/* Gestion des raccourcis claviers +* +* @param keyStore enchaînement de touches sous forme de string +* @param handler function qui s'éxécute lors du raccourci +* +*/ +function Shortcut(keyStore, handler){ + + var splittedString = keyStore.toLowerCase().split('+'), // découpe la chaîne (en minuscule) par "+" + splittedKeyCode = new Array(); // contiendra les keyCode de chaque touche + + + // pour chaque touche, on récupère le keyCode + for( var i = 0 ; i < splittedString.length ; i++ ) + splittedKeyCode[i] = strToKeyCode( splittedString[i] ); // on enregistre le keyCode correspondant + + + // on ajout à la liste globale + eventIndex = shortcutList.length; + shortcutList.push( splittedKeyCode ); + + // on initialise l'avancement + shortcutStep[eventIndex] = 0; + + + + // creation de la fonction d'évènement + shortcutList[eventIndex].push( function(k, f, h){ /* k ; f ; h */ + // on cherche l'avancée + var step = shortcutStep[f]; + + // on regarde si la touche est bonne + if( shortcutList[f][step] == k ){ // si c'est la touche suivante + + if( step >= shortcutList[f].length-2 ){ // si c'était la dernière touche + + // on initialise le tableau + for( var i = 0 ; i < shortcutStep[f].length ; i++ ) + shortcutStep[f][i] = 0; + + h(); // EXECUTION DE : handler(); + + }else // sinon on incrémente l'avancée + shortcutStep[f]++; + + }else // si c'est pas la bonne touche, on réinitialise le tableau + shortcutStep[f] = 0; + + }); + + console.log( shortcutList ); + + + // création de l'évènement + window.addEventListener( + 'keydown', + function(e){ e.preventDefault(); shortcutList[eventIndex][shortcutList[eventIndex].length-1](e.keyCode, eventIndex, handler); }, + false + ); + +} + +/* quand on lâche une touche, tout les raccourcis s'effacent */ +window.addEventListener('keyup', function(){ + for( var i = 0 ; i < shortcutStep.length ; i++ ) + shortcutStep[i] = 0; +}, false); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +/*** UTILISATION ***/ + +// Shortcut( +// 'ctrl+s', +// function(){ alert('sauvegardé'); } +// ); \ No newline at end of file diff --git a/manager/database.php b/manager/database.php new file mode 100755 index 0000000..5b4c2cb --- /dev/null +++ b/manager/database.php @@ -0,0 +1,18 @@ +connection = new PDO("mysql:host=$host;dbname=$dbname", $username, $password); + } +} + +?> \ No newline at end of file diff --git a/manager/security.php b/manager/security.php new file mode 100755 index 0000000..6781c74 --- /dev/null +++ b/manager/security.php @@ -0,0 +1,76 @@ + 0; + $permissionsDefinedProperly = isset($_SESSION['permissions']) && !empty($_SESSION['permissions']) && gettype($_SESSION['permissions']) == 'string' && strlen($_SESSION['permissions']) > 0; + + // si les variables sessions ne sont pas toutes les 2 correctes + if( !($usernameDefinedProperly && $permissionsDefinedProperly) ){ + $_SESSION['username'] = null; // on les initialise à NULL + $_SESSION['permissions'] = null; + } + } + + + + + + + +?> \ No newline at end of file diff --git a/manager/user.php b/manager/user.php new file mode 100755 index 0000000..0d37fe9 --- /dev/null +++ b/manager/user.php @@ -0,0 +1,135 @@ +level_1 ){ + + /****************************/ + /* authentification (login) */ + /****************************/ + case 'authentification': + $areSetParam = isset($request->username) && isset($request->password); // les arguments existent + $typeOkParam = $areSetParam && is_string($request->username) && is_string($request->password); // ils sont tous 2 des string + $nEmptyParam = $typeOkParam && strlen($request->username) > 0 && strlen($request->password) > 0; // d'au moins 1 caractère + + if( $areSetParam && $typeOkParam && $nEmptyParam ) + $answer->request = user_authentification($request->username, $request->password); + else{ + if ( !$areSetParam ) $answer->request= 'missing_param'; + elseif( !$typeOkParam ) $answer->request = 'wrong_type'; + else $answer->request = 'empty_param'; + } + break; + + + + /***********/ + /* DEFAULT */ + /***********/ + default: + $answer->request = 'unknown_level_1'; + break; + } + + } + + + + + + + + + + + + + + + + + + + /* [2] AUTHENTIFICATION + ============================================================*/ + + /* [a] userlist */ + function user_getUserList(){ + $userlistFile = file_get_contents("src/userlist.json"); + return json_decode( $userlistFile ); + } + + + /* [b] CONNECTION + ========================================================*/ + /* GESTION DE L'AUTHENTIFICATION D'UN UTILISATEUR + * + * @param username Identifiant de l'utilisateur + * @param password Mot de passe de l'utilisateur + * + * si @username est référencé et que le mot de passe associé vaut @password + * alors @return TRUE sinon FALSE + * + mise ajout à @answer + * + * Les variables sessions suivantes sont définies : + * - $_SESSION['permissions'] + * - $_SESSION['userid'] + * - $_SESSION['username'] + * + * @return Boolean true si l'utilisateur est ok + */ + function user_authentification($username, $password){ + + // [1] On récupère la liste d'utilisateurs (/src/userlist.json) + $userList = user_getUserList(); + + // [2] On check l'existence de l'utilisateur + if( isset($userList->{$username}) ){ + + // [3] On check le mot de passe + if( $userList->{$username}->password == $password ){ + // on définit les variables session + $_SESSION['username'] = $username; + $_SESSION['permissions'] = $userList->{$username}->permissions; + return 'success'; + }else + return 'wrong_password'; + + }else + return 'unknown_user'; + } + + +?> \ No newline at end of file diff --git a/page/_JS/auth.js b/page/_JS/auth.js new file mode 100755 index 0000000..7e95c72 --- /dev/null +++ b/page/_JS/auth.js @@ -0,0 +1,80 @@ + + /*********************************************************** + * * + * SCRIPT LOCAL DE LA PAGE D'AUTHENTIFICATION * + * * + ************************************************************ + * * + * [0] Variables * + * [1] Gestion des formulaires * + * [a] Gestion des réponses * + * [b] Initialisation des formulaires * + * * + * * + * * + * * + * * + * * + * * + * * + * * + ***********************************************************/ + + /* [0] Variables + ==============================================================*/ + var subSections = document.querySelectorAll('hgroup'); + + + /* [1] Gestion des formulaires + ==============================================================*/ + + + /* [a] Gestion des réponses + ==============================================================*/ + /* GESTION DU COMPORTEMENT EN FONCTION DE LA REPONSE POUR LE [LOGIN] + * + * @param response + * + * Gestion de toutes les réponse possibles avec une "messageBox" ou de redirection + * + */ + function manageAuthentificationResponse(response){ + switch( response.request ){ + + case 'success': + messageBox('Vous êtes maintenant connecté', 'success'); // on affiche le message + selectSection( document.querySelector('#MENU li:first-child') ); // on redirige vers la page d'accueil + break; + + // case 'missing_param': messageBox('Un des champs requis n\'est pas présent', 'warning'); break; + // case 'empty_param': messageBox('Un des champs requis est vide', 'warning'); break; + // case 'unknown_user': messageBox('Nom d\'utilisateur inconnu', 'error'); break; + // case 'wrong_password': messageBox('Mot de passe incorrect', 'error'); break; + + + case 'empty_param': case 'missing_param': case 'unknown_user': case 'wrong_password': + messageBox('Identifiants incorrects', 'error'); + break; + + default: + messageBox('Erreur interne', 'error'); + break; + + } + } + + + + + /* [b] Initialisation des formulaires + ==============================================================*/ + initForm( // initialisation du formulaire de connection + document.querySelector('#user'), // formulaire (élément DOM) + function(request){ // handler + // ajout d'informations à la requête + request.level_0 = 'user'; + request.level_1 = 'authentification'; + + API.send(request, function(response){ manageAuthentificationResponse(response); }); + } + ); diff --git a/page/_JS/groups.js b/page/_JS/groups.js new file mode 100755 index 0000000..65848f2 --- /dev/null +++ b/page/_JS/groups.js @@ -0,0 +1,43 @@ +var subSections = document.querySelectorAll('hgroup'); + + + + +// si aucune sous-partie n'est active, on active la première +if( document.querySelector('#CONTAINER hgroup.active') == null ) + selectSubSection( document.querySelector('#CONTAINER hgroup') ); + + + + + + + + + + + + + + + + + +/*************************************************/ +/****************** EXEMPLE API ******************/ +/*************************************************/ + +/* objet envoyé à API.php */ +var request = { + level_0: 'groups', + level_1: 'visualiser', + group : 'ego' +}; + +// console.log( request ); + +// envoi de la requête +// @ on envoie l'objet +// @ quand réception: affichage de l'objet reçu +// +API.send(request, function(){} ); diff --git a/page/auth.php b/page/auth.php new file mode 100755 index 0000000..d0847f8 --- /dev/null +++ b/page/auth.php @@ -0,0 +1,42 @@ + + +
    Connection
    +
    + +
    + + + +
    + +
    + + + + + + +
    Mon Profil
    +
    + + username =
    + droits = + +
    + + + \ No newline at end of file diff --git a/page/career.php b/page/career.php new file mode 100755 index 0000000..12bea97 --- /dev/null +++ b/page/career.php @@ -0,0 +1 @@ +career.php \ No newline at end of file diff --git a/page/groups.php b/page/groups.php new file mode 100755 index 0000000..6420150 --- /dev/null +++ b/page/groups.php @@ -0,0 +1,145 @@ + +
    Mon Groupe
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NomPrénomBlablabla
    001002003
    001002003
    001002003
    001002003
    001002003
    001002003
    001002003
    001002003
    001002003
    001002003
    + +
    + + + + +
    Mes Groupe
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Nom du groupeNombre d'élèvesNombre de modules
    A302
    B283
    D321
    F212
    + +
    + + + + +
    Tout les groupes
    +
    + Tout les groupes
    + bla
    + bla
    +
    + + + + +
    Mon Groupe 2
    +
    + Mon Groupe 2
    + bla
    + bla
    +
    \ No newline at end of file diff --git a/page/home.php b/page/home.php new file mode 100755 index 0000000..7abdfd5 --- /dev/null +++ b/page/home.php @@ -0,0 +1,42 @@ + +
    Présentation
    +
    + +Bienvenue sur la plateforme de gestion des élèves.

    +Seuls les membres du département y possède un accès, c'est à dire:
    +
      +
    • - Elèves
    • +
    • - Enseignants
    • +
    • - Personnel administratif
    • +
    + +Si vous faite partie de cette liste et que vous n'avez pas de compte, veuillez envoyer une requête au chef du département: Monsieur. Max Chevalier. + + +
    + + + + +
    Qui peut avoir accès à la plateforme
    +
    +blabla +
    \ No newline at end of file diff --git a/page/marks.php b/page/marks.php new file mode 100755 index 0000000..58569ea --- /dev/null +++ b/page/marks.php @@ -0,0 +1 @@ +Notes ici !!! \ No newline at end of file diff --git a/page/modules.php b/page/modules.php new file mode 100755 index 0000000..de1673c --- /dev/null +++ b/page/modules.php @@ -0,0 +1,4 @@ + + + +modules.php \ No newline at end of file diff --git a/page/semestre.php b/page/semestre.php new file mode 100755 index 0000000..83d0be7 --- /dev/null +++ b/page/semestre.php @@ -0,0 +1 @@ +semestre.php \ No newline at end of file diff --git a/page/settings.php b/page/settings.php new file mode 100755 index 0000000..3dd1e75 --- /dev/null +++ b/page/settings.php @@ -0,0 +1 @@ +settings.php \ No newline at end of file diff --git a/page/ue.php b/page/ue.php new file mode 100755 index 0000000..49446a4 --- /dev/null +++ b/page/ue.php @@ -0,0 +1 @@ +ue.php \ No newline at end of file diff --git a/src/input_icon/default.svg b/src/input_icon/default.svg new file mode 100755 index 0000000..405ca99 --- /dev/null +++ b/src/input_icon/default.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/input_icon/default_grayscale.svg b/src/input_icon/default_grayscale.svg new file mode 100755 index 0000000..ed397a3 --- /dev/null +++ b/src/input_icon/default_grayscale.svg @@ -0,0 +1,59 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/src/input_icon/password.svg b/src/input_icon/password.svg new file mode 100755 index 0000000..6f078a4 --- /dev/null +++ b/src/input_icon/password.svg @@ -0,0 +1,49 @@ + +image/svg+xml \ No newline at end of file diff --git a/src/input_icon/password_grayscale.svg b/src/input_icon/password_grayscale.svg new file mode 100755 index 0000000..8f2447c --- /dev/null +++ b/src/input_icon/password_grayscale.svg @@ -0,0 +1,51 @@ + +image/svg+xml \ No newline at end of file diff --git a/src/input_icon/user.svg b/src/input_icon/user.svg new file mode 100755 index 0000000..4a35e05 --- /dev/null +++ b/src/input_icon/user.svg @@ -0,0 +1,59 @@ + +image/svg+xml \ No newline at end of file diff --git a/src/input_icon/user_grayscale.svg b/src/input_icon/user_grayscale.svg new file mode 100755 index 0000000..6a1d45f --- /dev/null +++ b/src/input_icon/user_grayscale.svg @@ -0,0 +1,61 @@ + +image/svg+xml \ No newline at end of file diff --git a/src/menu_icon/auth.svg b/src/menu_icon/auth.svg new file mode 100755 index 0000000..b87b166 --- /dev/null +++ b/src/menu_icon/auth.svg @@ -0,0 +1,53 @@ + +image/svg+xml \ No newline at end of file diff --git a/src/menu_icon/auth_grayscale.svg b/src/menu_icon/auth_grayscale.svg new file mode 100755 index 0000000..9f3378c --- /dev/null +++ b/src/menu_icon/auth_grayscale.svg @@ -0,0 +1,53 @@ + +image/svg+xml \ No newline at end of file diff --git a/src/menu_icon/groups.svg b/src/menu_icon/groups.svg new file mode 100755 index 0000000..bf6f121 --- /dev/null +++ b/src/menu_icon/groups.svg @@ -0,0 +1,51 @@ + +image/svg+xml \ No newline at end of file diff --git a/src/menu_icon/groups_grayscale.svg b/src/menu_icon/groups_grayscale.svg new file mode 100755 index 0000000..2eb2cd1 --- /dev/null +++ b/src/menu_icon/groups_grayscale.svg @@ -0,0 +1,51 @@ + +image/svg+xml \ No newline at end of file diff --git a/src/menu_icon/home.svg b/src/menu_icon/home.svg new file mode 100755 index 0000000..5d68207 --- /dev/null +++ b/src/menu_icon/home.svg @@ -0,0 +1,151 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/menu_icon/home_grayscale.svg b/src/menu_icon/home_grayscale.svg new file mode 100755 index 0000000..6a9bc63 --- /dev/null +++ b/src/menu_icon/home_grayscale.svg @@ -0,0 +1,151 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/menu_icon/marks.svg b/src/menu_icon/marks.svg new file mode 100755 index 0000000..894e9ee --- /dev/null +++ b/src/menu_icon/marks.svg @@ -0,0 +1,57 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/src/menu_icon/marks_grayscale.svg b/src/menu_icon/marks_grayscale.svg new file mode 100755 index 0000000..0aafb63 --- /dev/null +++ b/src/menu_icon/marks_grayscale.svg @@ -0,0 +1,58 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/src/menu_icon/modules.svg b/src/menu_icon/modules.svg new file mode 100755 index 0000000..0882a93 --- /dev/null +++ b/src/menu_icon/modules.svg @@ -0,0 +1,71 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/src/menu_icon/modules_grayscale.svg b/src/menu_icon/modules_grayscale.svg new file mode 100755 index 0000000..6b2b773 --- /dev/null +++ b/src/menu_icon/modules_grayscale.svg @@ -0,0 +1,71 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/src/menu_icon/settings.svg b/src/menu_icon/settings.svg new file mode 100755 index 0000000..64f8cf1 --- /dev/null +++ b/src/menu_icon/settings.svg @@ -0,0 +1,49 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/src/menu_icon/settings_grayscale.svg b/src/menu_icon/settings_grayscale.svg new file mode 100755 index 0000000..6c7c89d --- /dev/null +++ b/src/menu_icon/settings_grayscale.svg @@ -0,0 +1,49 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/src/menu_icon/ue.svg b/src/menu_icon/ue.svg new file mode 100755 index 0000000..578cd4d --- /dev/null +++ b/src/menu_icon/ue.svg @@ -0,0 +1,53 @@ + +image/svg+xml \ No newline at end of file diff --git a/src/menu_icon/ue_grayscale.svg b/src/menu_icon/ue_grayscale.svg new file mode 100755 index 0000000..4c14e1e --- /dev/null +++ b/src/menu_icon/ue_grayscale.svg @@ -0,0 +1,53 @@ + +image/svg+xml \ No newline at end of file diff --git a/src/userlist.json b/src/userlist.json new file mode 100755 index 0000000..5b1059e --- /dev/null +++ b/src/userlist.json @@ -0,0 +1,32 @@ +{ + "eleve1": { + "permissions": "student", + "password" : "eleve1password" + }, + + "eleve2": { + "permissions": "student", + "password" : "eleve2password" + }, + + "prof1": { + "permissions": "teacher", + "password" : "prof1password" + }, + + "prof2": { + "permissions": "master", + "password" : "prof2password" + }, + + "admin1": { + "permissions": "admin", + "password" : "admin1password" + }, + + "admin2": { + "permissions": "admin", + "password" : "admin2password" + } + +} \ No newline at end of file diff --git a/xdoc/cdcf_droits b/xdoc/cdcf_droits new file mode 100755 index 0000000..7cab8f2 --- /dev/null +++ b/xdoc/cdcf_droits @@ -0,0 +1,35 @@ +ETUDIANT + Consulter son dossier (suivi des notes par semestre, UE, module) + Consulter ses notes + Consulter la composition de son groupe + Consulter la composition des autres groupes du même semestre + +ENSEIGNANT (sans droits spécifiques) + Consulter la composition des groupes du semestre actuel + +ENSEIGNANT + correcteur du contrôle "X" pour les groupes A, B, et F + Saisie des notes pour le contrôle X des groupes A, B, et F + Consultation et correction des notes du contrôle X des groupes A, B, et F + +ENSEIGNANT + droit d'accès au dossiers des étudiants du groupe D + Consulter le dossier des étudiants du groupe D + +ENSEIGNANT + droit de lecture des données étudiants + Consulter et importer au format Excel + la liste des élèves par groupe (groupes selectionnés) + les notes d'un contrôle (groupes selectionnés) + la liste des notes d'un module (groupes selectionnés) + la liste des notes d'un UE (groupes selectionnés) + la liste des notes d'un semestre (groupes selectionnés) + +ENSEIGNANT + droit de modification des données étudiant + Idem que précédemment + modification + Modification de la composition des groupes + Importation au format Excel de la liste des étudiants + +NOTE: Ces droits sont cummulables et selectionnés par l'administrateur + + +ADMINISTRATEUR: + Tous les droits vus précédemment + Possibilité d'octroyer, retirer des droits aux enseignants \ No newline at end of file diff --git a/xdoc/droits.svg b/xdoc/droits.svg new file mode 100755 index 0000000..6aec575 --- /dev/null +++ b/xdoc/droits.svg @@ -0,0 +1,123 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + étudiant + + + + enseignant + + + + administrateur + + + diff --git a/xdoc/login-page.png b/xdoc/login-page.png new file mode 100755 index 0000000000000000000000000000000000000000..1c76b2e01ab65d219f06430d0ea2085672af8d2e GIT binary patch literal 17523 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 G{67Hv6A#t^ literal 0 HcmV?d00001 diff --git a/xdoc/rdv1_tutrice b/xdoc/rdv1_tutrice new file mode 100755 index 0000000..495540c --- /dev/null +++ b/xdoc/rdv1_tutrice @@ -0,0 +1 @@ +Dater les documents \ No newline at end of file diff --git a/xdoc/sid.rules b/xdoc/sid.rules new file mode 100755 index 0000000..46e7aaf --- /dev/null +++ b/xdoc/sid.rules @@ -0,0 +1,258 @@ +Organisation GIT +---------------- + + master o--------------o-------------------o-------------------o----> + | | | | + dev o----o----o----o----o----o----o----o----o----o----o----o----o----o----o + + perso ..................... + + [DEV] active tout le temps + MERGE des branches perso toutes les semaines (au moins) + MERGE de la branche DEV vers MASTER à chaque réunion des branches perso + + + + + + + +Organisation TRELLO +------------------- + [ A faire ] - tâches qu'il faut réaliser (1 seul language, un seul fichier) + [ En cours ] - Personne attribuée + [ A vérifier ] - Vérifier par qqn d'extérieur + [ A confirmer] - confirmation par client + W3C + [ Fini ] - ... + + + + + + + +Architecture Fichiers +--------------------- +├── index.php +├── API.js +├── API.php +├── css +│   ├── container.css +│   ├── footer.css +│   ├── header.css +│   ├── layout.css +│   ├── menu.css +│   ├── page1.css +│   ├── page2.css +│   └── pagen.css +├── js +├── manager +│   ├── controles.php +│   ├── DATABASE.php +│   ├── etudiant.php +│   ├── excel.php +│   ├── groups.php +│   ├── history.php +│   ├── MCC.php +│   └── users.php +└── src + + + + + +Commentaires d'entête des fonctions +----------------------------------- +/* NOM : Résumé +* +* @param nomParam1 Le nombre de bits.. +* @param nomParam2 Description param2 +* @param nomParam3 [OBLIGATOIRE] +* +* Explication plus précise mais en prenant en compte les params et le return +* @return = @nomParam1 concaté avec la chaîne @nomParam2 +* +* @return nomVar[] +* +*/ + + + +Vérification d'intégrité des paramètres +--------------------------------------- +1) Créer une fonction booléenne qui vérifie le type d'un paramètre +2) Créer un booléen de vérification pour chaque paramèter utilisant "1)" + +Types pris en compte: + number + int + double + float + strings + char + boolean + [] + int + .. + + +@FUNCTION verifType(variable:void, type:string) + +exemples de @type + 'int' - si entier + 'bool' - si booléen + 'int[]' - si tableau d'entier + 'string[10]' - si tableau de string de taille 10 + 'int[][10]' - si matrice de string de taille n*10 + + +function(p1, p2, p3){ + + verifType( + func_get_args(), + [ 'string', 'int', 'int[10]' ], + [ null, null, null ] + ); + + ........ + +} + + + + + + + +Liste des pages +--------------- + + +I. GROUPES + [eleve] Mon groupe + [tous] Tout les groupes + [admin] Modifier les groupes + + ajouter + + supprimer + [admin] Répartition d'élèves + + ajouter (drag&drop) + + retirer (drag&drop) + + déplacer (drag&drop) + +II. SEMESTRE/UE + [eleve ] Mon parcourt + [prof autorisé] Mes élèves + [admin ] Les élèves + +III. MODULE + [eleve ] Mes modules + + par semestre + + par ue + [prof autorisé] Mes modules + + modifier contenu + . créer/modifier section + . upload document + . rédiger paragraphe + [admin ] Les modules + + ajouter + + supprimer + + modifier + . titre + . section (ajouter/supprimer/modifier) + +IV. CONTRÔLE + [eleve ] Mes contrôles + + par semestre + + par ue + + par module + [prof autorisé] Mes contrôles + + saisir notes (par groupe) + + modifier notes (par groupe) + [admin ] Contrôles + + consulter + . par semestre + . par ue + . par module + + modifier + + +V. PARAMÈTRES + ... + + + +Groupes + Mon groupe + visualiser + Tous + visualiser + Administration + modifier la liste d'élèves (drag & drop) (par ordre alpha) + + +Parametres + Profil + visualiser + modifier + password + mail + description + + +VISUALISER LES NOTES CLASSÉES PAR MODULES +{ + 'level_0': 'visualiser', + 'level_1': 'notes', + 'affichage': 'module' +} + +VISUALISER TOUT LES GROUPES +{ + 'level_O': 'visualiser', + 'level_1': 'groupe', + 'affichage': 'tous' +} + +VISUALISER MON GROUPE +{ + 'level_O': 'visualiser', + 'level_1': 'groupe', + 'affichage': 'ego' +} + +MODIFIER UN GROUPE +{ + 'level_O': 'administrer', + 'level_1': 'groupe', + 'groupe': 'A', + 'action': 'supprimer', + 'membres': [123, 567] +} + +SAISIR LES NOTES D'UN PARTIEL +{ + 'level_O': 'saisir', + 'level_1': 'notes', + 'module': 'M3102', + 'groupe': 'A' +} + + + + +Chevalier RDV (2) + + Eleve peut consulter notes (semestre uniquement) + + pas de moyenne (règlement intérieur => uniquement sur relevé de notes) + + + Rôles cummulatifs (admin choice) + + Profs correcteurs n'accèdent + + Historique des notes (1 courant + 1 antécédent uniquement) + + PROF + [x] Visualiser les notes (choix des groupes/modules) + [x] Saisie des notes (choix des groupes/modules) + [x] visualiser parcourt étu (groupes/modules) diff --git a/xdoc/svg/API.png b/xdoc/svg/API.png new file mode 100755 index 0000000000000000000000000000000000000000..ab587f229f00ddafee2ca8a85a31d0ece1737fdf GIT binary patch literal 64217 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 literal 0 HcmV?d00001 diff --git a/xdoc/svg/API.svg b/xdoc/svg/API.svg new file mode 100755 index 0000000..ef65224 --- /dev/null +++ b/xdoc/svg/API.svg @@ -0,0 +1,437 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + API.js + + + + JSON <String> + + + + JSON <String> + + + + + PARSE + + + + UNPARSE + + + + + JSON <Object> + + + + ROUTAGE + + + + + + + MANAGERS:TRAITEMENT + + + + + + + + + + + + + + + JSON <Object> + + + + JSON <Object> + + + API.php physique + + API.php réel + + diff --git a/xdoc/svg/architecture.png b/xdoc/svg/architecture.png new file mode 100755 index 0000000000000000000000000000000000000000..c5fce10f895c9670b48be45acd91c2823e74145f GIT binary patch literal 59674 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
    }EpkaHJ@kF5F zx-eZ2rqR0FCDR{cWmzB>8$E=Na;mawFUQQ@r`Lq=sRR`M%FzUgBI(vrFSy>2={74OIp_XOIR5OhlPdp{L);# zwfO+iQw%HoylOCH+m03T$Zx-GlfFlJvcCQ&F(Dxh=J>#q!@Vf&(cqX7g*{A8;Ii}> zT8S7F047yGuYUeq|6ev8mOzsbBMq`wnaw6aqZTb=l#C2V>9sYFy!Di4F_vTr;?g=b z$8WWTi+B?V)%ig#B@g{n8yV{+8#^E30t8})KVZxlm(dw?h*J0p8N<_ik7;30LSkYt znV%9yL)O$?`il3FCkzPG5e58Z{6OdmaCL|U_0AM*L7%gP027E4vGTK9iHLLpop82KWJy9qxk zxIsI#HCUrmKQM5Q|LgKJcdM;gB{?FSkq696%v= zNgycLM&;un1cm7)0|((0^J=fr;ia8+EDcwwf+_anDS?+FybvDir>~Q^Gxd#)Rh$qM z!7dr*F{Ntm9i_G;W<1-l?tqPfunQnV#yMJREsCioAVF>JO5IeQwC+Wj8tusOygZ#` zc|8@ODApYO}(IQAwx}GFeO=gC%xG&ixwHs z$Q$07-Tr+*{bvSZMu$^8VmtIT?*UG8NnRA-bbN_d&l>*h%Iar|{}Je-;!7M#K*k`T zv=f(3#?abl4%;oJVJ7~t8dWrUbN`3cni{$RVTehj>7G! zN5CXD820|@1~TiT#^qL2C+)V<7cC`yZ_4Kzy)@PorgqYL5%Z3^5kBq&-a>`%J@`=S zfaY@C(ad09xHUh2y^hn|0IMKKOd4dYsNj#!jx`=(<8s@n;tTL>QC>_-Ol<5zTxhBN z%*U80x2ta$N3$b3Gc-*0(Jq@DZGggBC-2z|=C^E?<`F`>b>oRy1W^Iy;!W&S?EZCfq^x*n6gdTS2qdfJl;s(`T6D4 z_`#A5e&?(dY6uUuCqE@#uf7i+Tk3?WHxAypckfmDew_e4o&!bnKw=#^y?gR_GMm{9 zOp?g04$&^={Z)B+c?y+}q1KB%%6`4e(guU}z@kC<)=zx0NH4{CeYo^gcL;GU*Jk5C zNFD@8(4>!rhF#RG+mdzcSO_f}+tj8E)g3r|xZT?pYTyAAC-&i$fpB19jEigL-E zdms7%0SHsfI9h<-#T8f7{_cuTOF?C2KU^c6qwjD5Q6Y7}f%u76RazNY8-t@Ae0r0^ zLAlo8IMW~~(J9PKL3*%Oa_su%oT@u4L2W#m@g zr6hYixuu~K+r5TZ_{ZEJJjE~RRT#aPAwz1#;8S--p^}or%#Vq~5cl~ht-WQGQXhv4 zoC+QT1%{B~Srl5v1USAVwF}uePFS_@Tz2l-A1g+>NC!#0l4U>zraw_`u7)D~G^1r~f)s zq$w#riIo8>fVj1Z_xeMIBwxu4hF`j!o3{XA=Yz<{U4^X9i6x*K3%T!b)l&cYAf|ufMUi?bNy*G_~Z>5TJmqCPSkp#WF1Lo(Mb|ip}i}IHQiluv;fUEHWUQ@ z**eN0>D&?gLR%4`xuD8>y{4N&EEMny-HW-Vp8Qk39kgDwqFUAE;ezF9$z;Ad2e@AN z-x&EldHJ%PiAkC)rQ)$b}p@;4sLgRQ@?bb3R@A*mNi`oyA6lgMa9h*W$%H$g3rv zeHx#5P=wBDIfj75xXGI#uEolgndx>F%ocnamW&$scXh%wR15bn$su&P0TNtaH z>)$YK=}w*g{^Q5(|I+R+{<2vTb-MG@t@CG!S1ib|7*EN1P4TZF&RIq!hBK$7V(zGc zzJJ^}VHPnl`ngruq{_~*&@S#6QkhV`ZI>4)fgi-v)D{Pgizs9WsEs-&S;Te|D&B7p73 zNIqxutA5Qt@bQ-2X!g3lHh$I&sX%+AwHq7vE#G2~Y0{MX<>vqVsc=+VlB4|H|NrU# f_8AnlsC#v-S$3$wuM0cs6yHyqWtC~^x&40t!}_uX literal 0 HcmV?d00001 diff --git a/xdoc/svg/architecture.svg b/xdoc/svg/architecture.svg new file mode 100755 index 0000000..408d21a --- /dev/null +++ b/xdoc/svg/architecture.svg @@ -0,0 +1,341 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + index.php + + + + API.js + + + + API.php + + + + manager/*.php + + + + + + JSON <String> + JSON <String> + + + + + + js + css + + + + + + + + + + + DATABASE.php + + + + + + diff --git a/xdoc/test.php b/xdoc/test.php new file mode 100755 index 0000000..7d08495 --- /dev/null +++ b/xdoc/test.php @@ -0,0 +1,6 @@ + \ No newline at end of file diff --git a/xdoc/verifType.php b/xdoc/verifType.php new file mode 100755 index 0000000..ce5d472 --- /dev/null +++ b/xdoc/verifType.php @@ -0,0 +1,34 @@ + Les variables respectives des paramètres +* @param typeArray< String[] > Les types respectifs des paramètres +* @param defaultArray< *[] > Les valeurs par défaut (respectives) +* +* Vérifie si le type @varArray[n] correspond au type spécifié par le chaîne @typeArray[n] +* si oui, la variable est inchangée +* si non, attribue la valeur @defaultArray[n] +* +*/ +function verifType($valueVar, $typeVar, $defaultVar){ + return ( gettype($valueVar) == $typeVar ) ? $valueVar : $defaultVar; +} + +// implémenter un format pour les types complexes !!! :P + + + + +function test1($arg1, $arg2, $arg3){ + $arg1 = verifType($arg1, 'integer', 0); + $arg2 = verifType($arg2, 'string', 'void'); + $arg3 = verifType($arg3, 'boolean', true); + + echo $arg1.' - '.$arg2.' - '.$arg3; +} + +// test1( Array(), Array(), Array() ); + + + +?> \ No newline at end of file