diff --git a/build/api/core/AuthSystem.php b/build/api/core/AuthSystem.php index 67010b1..9efe182 100755 --- a/build/api/core/AuthSystem.php +++ b/build/api/core/AuthSystem.php @@ -16,14 +16,14 @@ interface AuthSystem{ - /* VERIFICATION DES ACCES EN FONCTION DE PERMISSIONS ATTENDUES - * - * @expected Liste des permissions attendues - * - * @return error Erreur associée à la permission (Success/PermissionError/TokenError/etc) - * - */ - public static function permission($expected); + /** VERIFICATION DES ACCES EN FONCTION DE PERMISSIONS ATTENDUES + * + * @param array $expected Liste des permissions attendues + * + * @return Error Erreur associée à la permission (Success/PermissionError/TokenError/etc) + * + */ + public static function permission(array $expected) : Error; } ?> diff --git a/build/api/core/AuthSystemDefault.php b/build/api/core/AuthSystemDefault.php index edce675..21e0540 100644 --- a/build/api/core/AuthSystemDefault.php +++ b/build/api/core/AuthSystemDefault.php @@ -79,22 +79,19 @@ - /* VERIFICATION DES ACCES EN FONCTION DE PERMISSIONS ATTENDUES - * - * @expected Liste des permissions attendues - * - * @return error Erreur associée à la permission (Success/PermissionError/TokenError/etc) - * - */ - public static function permission($expected){ + /** VERIFICATION DES ACCES EN FONCTION DE PERMISSIONS ATTENDUES + * + * @param array $expected Liste des permissions attendues + * + * @return Error Erreur associée à la permission (Success/PermissionError/TokenError/etc) + * + */ + public static function permission(array $expected) : Error{ /* (1) Check format -> if not array of array(s) -> ERROR ---------------------------------------------------------*/ - /* (1) If not array -> ERROR */ - if( !is_array($expected) ) - return new Error(Err::FormatError); - /* (2) If not array of array(s) -> ERROR */ + /* (1) If not array of array(s) -> ERROR */ foreach($expected as $permission_group) if( !is_array($permission_group) ) return new Error(Err::FormatError); diff --git a/build/api/core/Checker.php b/build/api/core/Checker.php index 1c49345..63f338b 100755 --- a/build/api/core/Checker.php +++ b/build/api/core/Checker.php @@ -16,15 +16,15 @@ class Checker{ - /* VERIFICATIONS DES TYPES UTILES GENERIQUES + /** VERIFICATIONS DES TYPES UTILES GENERIQUES * - * @type Type que l'on veut verifier - * @value Valeur a verifier + * @param String $type Type que l'on veut verifier + * @param mixed $value Valeur a verifier * - * @return match Retourne si oui ou non la valeur @value est du bon type @type + * @return Boolean Retourne si oui ou non la valeur @value est du bon type @type * */ - public static function run($type, $value){ + public static function run(String $type, $value) : bool { $checker = true; /* [0] On verifie que $value n'est pas nul @@ -44,6 +44,10 @@ // On recupere le sous-type si défini $flags = isset($match[3]) ? explode(',', substr($match[3], 1)) : null; + // Si numeric -> to String + if( is_numeric($value) ) + $value = (string) $value; + // On effectue la verification de taille $lenCheck = $checker && is_string($value) && strlen($value) <= $max && strlen($value) >= $min; @@ -91,6 +95,11 @@ return $checker && is_numeric($value) && $value <= 2147483647 && $value >= 0; break; + // Entier relatif (neg ou pos) + case 'int': + return $checker && is_int($value); + break; + // String quelconque (peut etre vide) case 'text': return $checker && is_string($value); @@ -143,7 +152,7 @@ break; case "float": - return $checker && is_float($value); + return $checker && ( is_int($value) || is_float($value) ); break; default: diff --git a/build/api/core/Config.php b/build/api/core/Config.php index d452ac3..c3046ff 100644 --- a/build/api/core/Config.php +++ b/build/api/core/Config.php @@ -11,23 +11,34 @@ /* (1) Attributes ---------------------------------------------------------*/ /* (1) Static */ + + /** @var Config? */ private static $inst = null; // singleton instance - private static function config_path(){ return __ROOT__.'/config/modules.json'; } + + private static function config_path() : String { return __ROOT__.'/config/modules.json'; } + + /** @var array[String] */ public static $allowed_http_methods = [ "GET", "POST", "PUT", "DELETE" ]; /* (2) Instance */ + + /** @var array */ private $raw; + + /** @var array */ public $index; + + /** @var Error */ public $error; - /* (2) Private constructor + /** (2) Private constructor * - * @path Configuration path + * @param String|null $path Configuration path * ---------------------------------------------------------*/ - private function __construct($path=null){ + private function __construct(?String $path=null){ // Set default error $this->error = new Error(Err::Success); @@ -116,9 +127,9 @@ - /* (3) Static singleton 'get-or-create' + /** (3) Static singleton 'get-or-create' * - * @return inst Configuration singleton + * @return Config Configuration singleton * ---------------------------------------------------------*/ public static function get() : Config{ diff --git a/build/api/core/ModuleFactory.php b/build/api/core/ModuleFactory.php index 8f3e22d..3eede8e 100755 --- a/build/api/core/ModuleFactory.php +++ b/build/api/core/ModuleFactory.php @@ -15,15 +15,15 @@ class ModuleFactory{ - /* INSTANCIE UN MODULE + /** INSTANCIE UN MODULE * - * @module Nom du module - * @arguments [OPTIONNEL] Arguments à passer au constructeur + * @param String $module Nom du module + * @param array $arguments [OPTIONNEL] Arguments à passer au constructeur * - * @return instance Instance du module en question + * @return object|false Instance du module en question * */ - public static function getModule($module, $arguments=[]){ + public static function getModule(String $module, array $arguments=[]){ /* (1) On gère les arguments */ $arguments = is_array($arguments) ? $arguments : []; diff --git a/build/api/core/Request.php b/build/api/core/Request.php index dce1f28..31d73ff 100755 --- a/build/api/core/Request.php +++ b/build/api/core/Request.php @@ -5,35 +5,50 @@ use \api\core\AuthSystem; use \api\core\ModuleFactory; use \api\core\Config; - use \error\core\Error; +use database\core\Repo; +use \error\core\Error; use \error\core\Err; class Request{ // Constantes + + /** @var array[bool] */ private static $default_options = [ 'download' => false ]; + + /** @var AuthSystem|null */ private static $authsystem = null; // Attributs prives utiles (initialisation) + + /** @var array */ private $id; // chemin extrait de l'URI + + /** @var array */ private $raw_params; // paramètres reçus + + /** @var array */ private $params; // paramètres donnés à la fonction + + /** @var array */ private $options; // options + + /** @var String */ private $http_method; // methode HTTP appelante // Contiendra l'etat de la requete + /** @var Error */ public $error; - /* (0) Constructeur d'une requete de module + /** (0) Constructeur d'une requete de module * - * @uri URI relative de l'appel - * @param Tableau associatif contenant les parametres utiles au traitement - * @forced_method Méthode demandée (optionnel) + * @param String|null $uri URI relative de l'appel + * @param array|null $params Tableau associatif contenant les parametres utiles au traitement + * @param String|null $forced_method Méthode demandée (optionnel) * - * @return instance Instance crée * ---------------------------------------------------------*/ public function __construct($uri=null, $params=null, $forced_method=null){ @@ -44,38 +59,44 @@ - /* (1) Constructeur d'une requete de module (delegation) + /** (1) Constructeur d'une requete de module (delegation) * - * @uri URI relative de l'appel - * @param Tableau associatif contenant les parametres utiles au traitement - * @forced_method Méthode demandée (optionnel) + * @param String|null $uri URI relative de l'appel + * @param array|null $params Tableau associatif contenant les parametres utiles au traitement + * @param String|null $forced_method Méthode demandée (optionnel) * - * @return status Retourne si oui ou non tout s'est bien passe + * @return boolean Retourne si oui ou non tout s'est bien passe * ---------------------------------------------------------*/ - private function buildRequestObject($uri=null, $params=null, $forced_method=null){ + private function buildRequestObject($uri=null, $params=null, $forced_method=null) :bool{ /* (1) Initialisation ---------------------------------------------------------*/ /* (1) Erreur par défaut */ $this->error = new Error(Err::Success); /* (2) Si pas parametre manquant, on quitte */ - if( is_null($uri) ) - return $this->error->set(Err::MissingPath); + if( is_null($uri) ){ + $this->error->set(Err::MissingPath); + return false; + } /* (2) On vérifie la configuration ---------------------------------------------------------*/ /* (1) Dispatch if error */ - if( Config::get()->error->get() != Err::Success ) - return ($this->error = Config::get()->error); + if( Config::get()->error->get() != Err::Success ){ + $this->error = Config::get()->error; + return false; + } /* (3) Verification des types des parametres ---------------------------------------------------------*/ /* (1) Si path est une */ - if( !is_string($uri) ) // Si le type est incorrect - return $this->error->set(Err::WrongPathModule); + if( !is_string($uri) ){ + $this->error->set(Err::WrongPathModule); + return false; + } /* (2) Add slash at the beginning of URI */ if( !preg_match('@^\/@', $uri) ) @@ -85,8 +106,10 @@ $this->raw_params = (is_array($params)) ? $params : []; /* (4) On définit en constante la méthode HTTP */ - if( !isset($_SERVER['REQUEST_METHOD']) && !is_string($forced_method) ) - return $this->error->set(Err::UnknownHttpMethod); + if( !isset($_SERVER['REQUEST_METHOD']) && !is_string($forced_method) ){ + $this->error->set(Err::UnknownHttpMethod); + return false; + } $this->http_method = is_string($forced_method) ? strtoupper($forced_method) : strtoupper($_SERVER['REQUEST_METHOD']); @@ -129,14 +152,14 @@ - /* (2) Definit le systeme d'authentification + /** (2) Definit le systeme d'authentification * - * @instance Instance de type AuthSystem + * @param AuthSystem $instance Instance de type AuthSystem * - * @return success Whether the AuthSystem is valid or not + * @return boolean Whether the AuthSystem is valid or not * ---------------------------------------------------------*/ - public static function setAuthSystem($instance=null){ + public static function setAuthSystem( ?AuthSystem $instance=null) : bool{ /* (1) Check instance type */ if( !($instance instanceof AuthSystem) ) return false; @@ -149,20 +172,22 @@ - /* (3) Verification du format et de la coherence du chemin specifie + /** (3) Verification du format et de la coherence du chemin specifie * - * @URI URI d'appel (commence par /) + * @param String $uri URI d'appel (commence par /) * - * @return validity Retourne si oui ou non l'objet est correct + * @return boolean Retourne si oui ou non l'objet est correct * ---------------------------------------------------------*/ - private function checkURI($uri){ + private function checkURI(String $uri) : bool{ /* (1) Verification format general ---------------------------------------------------------*/ /* (1) If wrong format -> exit */ - if( !preg_match('@^\/[^\/]*(\/[^\/]*)*\/?$@', $uri) ) - return $this->error->set(Err::WrongPathModule); + if( !preg_match('@^\/[^\/]*(\/[^\/]*)*\/?$@', $uri) ){ + $this->error->set(Err::WrongPathModule); + return false; + } /* (2) Add ending '/' if not there */ if( $uri[strlen($uri)-1] != '/' ) @@ -188,8 +213,10 @@ } /* (2) If @path not found -> exit */ - if( is_null($path) ) - return $this->error->set(Err::UnknownModule); + if( is_null($path) ){ + $this->error->set(Err::UnknownModule); + return false; + } /* (3) Extract URI parameters @@ -202,8 +229,10 @@ $uri_end = "/$uri_end"; /* (3) If invalid format, return error */ - if( !preg_match('@^((?:\/[^\/]*)*)\/?$@', $uri_end, $uri_match) ) - return $this->error->set(Err::InvalidURI); + if( !preg_match('@^((?:\/[^\/]*)*)\/?$@', $uri_end, $uri_match) ){ + $this->error->set(Err::InvalidURI); + return false; + } /* (4) Add each URI parameter to the parameter store */ $uri_args = array_slice( explode('/', $uri_match[1]), 1); @@ -219,12 +248,16 @@ $doc_req = $this->http_method == 'OPTIONS'; /* (2) Check if HTTP method is in allowed methods */ - if( !in_array($this->http_method, Config::$allowed_http_methods) && !$doc_req ) - return $this->error->set(Err::UnknownHttpMethod, $this->http_method); + if( !in_array($this->http_method, Config::$allowed_http_methods) && !$doc_req ){ + $this->error->set(Err::UnknownHttpMethod, $this->http_method); + return false; + } /* (3) Check if HTTP method is defined for this @path */ - if( !isset(Config::get()->index[$path][$this->http_method]) && !$doc_req ) - return $this->error->set(Err::UnknownMethod, $this->http_method); + if( !isset(Config::get()->index[$path][$this->http_method]) && !$doc_req ){ + $this->error->set(Err::UnknownMethod, $this->http_method); + return false; + } @@ -241,12 +274,12 @@ - /* (4) Retourne si on a la permission d'executer cette methode + /** (4) Retourne si on a la permission d'executer cette methode * - * @return permission Retourne si on a les droits ou pas pour executer cette methode + * @return bool Retourne si on a les droits ou pas pour executer cette methode * ---------------------------------------------------------*/ - private function checkPermission(){ + private function checkPermission() : bool{ /* (1) On recupere les informations utiles ---------------------------------------------------------*/ @@ -263,8 +296,10 @@ if( !is_object(self::$authsystem) || !self::$authsystem instanceof AuthSystem ){ // try to load default AuthSystem - if( !file_exists(__BUILD__.'/api/core/AuthSystemDefault.php') ) - return $this->error->set(Err::UnreachableResource); + if( !file_exists(__BUILD__.'/api/core/AuthSystemDefault.php') ){ + $this->error->set(Err::UnreachableResource); + return false; + } // load default AuthSystem class $classname = '\\api\\core\\AuthSystemDefault'; @@ -288,25 +323,29 @@ - /* (5) Verification du type des parametres envoyes + /** (5) Verification du type des parametres envoyes * - * @return correct Retourne si oui ou non les parametres ont le bon type + * @return bool Retourne si oui ou non les parametres ont le bon type * ---------------------------------------------------------*/ - private function checkParams(){ + private function checkParams() : bool{ /* (1) On verifie qu'il ne manque aucun parametre ---------------------------------------------------------*/ /* (1) Si @params n'est pas un tableau */ - if( !is_array($this->raw_params) ) - return $this->error->set(Err::MissingParam); + if( !is_array($this->raw_params) ){ + $this->error->set(Err::MissingParam); + return false; + } /* (2) On récupère les données de la méthode */ $method = Config::get()->index[$this->id['path']][$this->id['method']]; /* (3) Si pas 'parameters' dans la config */ - if( !isset($method['par']) || !is_array($method['par']) ) - return $this->error->set(Err::ConfigError); + if( !isset($method['par']) || !is_array($method['par']) ){ + $this->error->set(Err::ConfigError); + return false; + } /* (2) Si le type est defini, pour chaque param, on teste @@ -316,16 +355,22 @@ /* (2.1) Vérification des données ---------------------------------------------------------*/ /* (1) Si @name n'est pas une string */ - if( !is_string($name) ) - return $this->error->set(Err::ConfigError); + if( !is_string($name) ){ + $this->error->set(Err::ConfigError); + return false; + } /* (2) Si @config n'est pas un tableau */ - if( !is_array($config) ) - return $this->error->set(Err::ConfigError); + if( !is_array($config) ){ + $this->error->set(Err::ConfigError); + return false; + } /* (3) So @config['typ] manquant ou incorrect */ - if( !isset($config['typ']) || !is_string($config['typ']) ) - return $this->error->set(Err::ConfigError); + if( !isset($config['typ']) || !is_string($config['typ']) ) { + $this->error->set(Err::ConfigError); + return false; + } /* (2.2) Gestion des spécifications @@ -348,10 +393,12 @@ $default = $config['def']; /* (3.1.2) If FILE and not null -> Check type */ - if( $config['typ'] != 'FILE' || $default != null ) - if( !Checker::run($config['typ'], $default) ) - return $this->error->set(Err::WrongDefaultParam, $rename, $config['typ']); - + if( $config['typ'] != 'FILE' || $default != null ){ + if( !Checker::run($config['typ'], $default) ) { + $this->error->set(Err::WrongDefaultParam, $rename, $config['typ']); + return false; + } + } } /* (4) Si de type 'FILE' + fichier existe => on enregistre la ref. */ @@ -359,8 +406,10 @@ $this->params[$rename] = &$_FILES[$name]; /* (4) Si param obligatoire et manquant -> erreur */ - if( !isset($this->raw_params[$name]) && !$optional ) - return $this->error->set(Err::MissingParam, $rename); + if( !isset($this->raw_params[$name]) && !$optional ) { + $this->error->set(Err::MissingParam, $rename); + return false; + } /* (2.3) Gestion des valeurs @@ -382,8 +431,10 @@ $this->raw_params[$name] = $json_rep['json']; // Si la verification est fausse, on retourne faux - if( !Checker::run($config['typ'], $this->raw_params[$name]) ) - return $this->error->set(Err::WrongParam, $rename, $config['typ']); + if( !Checker::run($config['typ'], $this->raw_params[$name]) ){ + $this->error->set(Err::WrongParam, $rename, $config['typ']); + return false; + } // Sinon, on ajoute aux params qu'on enverra à l'appel else @@ -402,12 +453,12 @@ - /* (6) Ajout des options a partir de la configuration + /** (6) Ajout des options a partir de la configuration * - * @return correct Retourne FAUS en cas d'erreur + * @return bool Retourne FAUS en cas d'erreur * ---------------------------------------------------------*/ - private function buildOptions(){ + private function buildOptions() : bool{ /* (1) On récupère les options de la méthode en cours ---------------------------------------------------------*/ @@ -447,12 +498,12 @@ - /* (7) Execute le traitement associe et remplie la reponse + /** (7) Execute le traitement associe et remplie la reponse * - * @return answer Retourne une reponse de type si tout s'est bien passe + * @return Response Retourne une reponse de type si tout s'est bien passe * ---------------------------------------------------------*/ - public function dispatch(){ + public function dispatch() : Response{ /* (1) Vérifications de niveau 0 ---------------------------------------------------------*/ @@ -503,6 +554,11 @@ /* (3) On ajoute les données */ $response->appendAll($returned); + /* (4) Si le Debug est actif on ajoute le debug des repo */ + if(Repo::isDebugEnabled()){ + $response->append("repoDebug" , Repo::getDebug()); + } + /* (4) On retourne la réponse */ return $response; @@ -510,10 +566,11 @@ - /* (8) Gestion d'un téléchargement HTTP - * - */ - public function download($returned){ + /** (8) Gestion d'un téléchargement HTTP + * + * @return Response + */ + public function download($returned) : Response{ /* (1) Vérification des erreurs et paramètres ---------------------------------------------------------*/ @@ -550,7 +607,7 @@ /* (2) On affiche le contenu */ echo $returned['body']; - return true; + return new Response(); } @@ -599,12 +656,13 @@ - /* (9) Getter générique + /** (9) Getter générique * - * @index Index de l'attribut + * @param String $index Index de l'attribut * + * @return mixed ---------------------------------------------------------*/ - public function get($index=null){ + public function get(?String $index=null){ switch($index){ diff --git a/build/api/core/Response.php b/build/api/core/Response.php index f579a6d..d6e576e 100755 --- a/build/api/core/Response.php +++ b/build/api/core/Response.php @@ -17,31 +17,36 @@ class Response{ // Attributs prives utiles (initialisation) + + /** @var array */ private $data; + + /** @var Error */ public $error; - /* CONSTRUCTEUR D'UNE REPONSE DE MODULE + /** CONSTRUCTEUR D'UNE REPONSE DE MODULE * - * @error Erreur passee par la requete (si existe) + * @param Error $error Erreur passee par la requete (si existe) * */ - public function __construct($error=null){ + public function __construct(?Error $error=null){ if( !( $error instanceof Error ) ) $error = new Error(Err::Success); $this->data = []; $this->error = $error; } - /* AJOUTE UNE DONNEE A LA REPONSE + /** AJOUTE UNE DONNEE A LA REPONSE * - * @key Le nom de la valeur a ajouter - * @value La valeur a ajouter + * @param String $key Le nom de la valeur a ajouter + * @param mixed $value La valeur a ajouter * + * @return Response */ - public function append($key, $value){ + public function append(String $key, $value) : Response{ // Ajoute une entree pour la cle @key et de valeur @value $this->data[$key] = $value; @@ -49,12 +54,13 @@ } - /* AJOUTE TOUTES LES DONNEES A LA REPONSE + /** AJOUTE TOUTES LES DONNEES A LA REPONSE * - * @dataset Le tableau associatif correspondant a la reponse + * @param array $dataset Le tableau associatif correspondant a la reponse * + * @return Response */ - public function appendAll($dataset){ + public function appendAll(array $dataset) : Response{ // Si ce n'est pas un tableau, on ne fais rien if( !is_array($dataset) ) return $this; @@ -72,17 +78,16 @@ return $this; } - /* RECUPERE UNE DONNEE DE LA REPONSE + /** RECUPERE UNE DONNEE DE LA REPONSE * - * @key Le nom de la valeur a recuperer + * @param String $key Le nom de la valeur a recuperer * - * @return value La valeur a cette cle - * @return error Retourne NULL si aucune valeur pour cette cle + * @return mixed|null La valeur a cette cle, NULL si aucune valeur pour cette cle * */ - public function get($key){ + public function get(String $key){ // Si la valeur de cle @key n'existe pas, on retourne NULL if( !isset($this->data[$key]) ) return null; @@ -92,9 +97,9 @@ } - /* RECUPERE TOUTES LES DONNEES DE LA REPONSE + /** RECUPERE TOUTES LES DONNEES DE LA REPONSE * - * @return data Les donnees de la reponse + * @return array Les donnees de la reponse * */ public function getAll(){ @@ -103,12 +108,12 @@ } - /* SERIALISATION A PARTIR DES DONNEES + /** SERIALISATION A PARTIR DES DONNEES * - * @return json Retourne les donnees serialisees + * @return String Retourne les donnees serialisees * */ - public function serialize(){ + public function serialize() : String{ // Code Http $this->error->setHttpCode(); diff --git a/build/api/module/departement/statsController.php b/build/api/module/departement/statsController.php new file mode 100644 index 0000000..54563d6 --- /dev/null +++ b/build/api/module/departement/statsController.php @@ -0,0 +1,25 @@ + $repo->getStats()]; + } +} \ No newline at end of file diff --git a/build/api/module/excelController.php b/build/api/module/excelController.php index e3c4a4d..2e1fb4b 100644 --- a/build/api/module/excelController.php +++ b/build/api/module/excelController.php @@ -63,9 +63,11 @@ class excelController $addEU = function() use (&$UECode,&$allUE,&$UE){ //determine if UE is disabled (if cours+td+tp = 0) $totalVH = 0; - foreach ($UE["groups"] as $groups){ - foreach ($groups as $group){ - $totalVH += $group["VH"]; + if(is_array($UE["groups"]) && count($UE["groups"]) > 0){ + foreach ($UE["groups"] as $groups){ + foreach ($groups as $group){ + $totalVH += $group["VH"]; + } } } @@ -348,6 +350,10 @@ class excelController /** @var tp $tpRepo */ $tpRepo = Repo::getRepo("tp"); + $CoursToLink = []; + $TDToLink = []; + $TPToLink = []; + foreach ($allUE as $codeUE => $UE){ if($UE["defaultFormation"]){ @@ -377,22 +383,25 @@ class excelController switch ($type){ case "Course": - $coursRepo->create( $codeUE, - $allProf[$group["professor"]]["dbId"], - $UE["disabled"] ? $UE["CourseVH"] : $group["VH"], - $formations); + $CoursToLink[] = ["id" => $coursRepo->create( $codeUE, + $allProf[$group["professor"]]["dbId"], + $UE["disabled"] ? $UE["CourseVH"] : $group["VH"], + []), + "form" => $formations]; break; case "TD": - $tdRepo->create($codeUE, - $allProf[$group["professor"]]["dbId"], - $UE["disabled"] ? $UE["TdVH"] : $group["VH"], - $formations); + $TDToLink[] = ["id" => $tdRepo->create($codeUE, + $allProf[$group["professor"]]["dbId"], + $UE["disabled"] ? $UE["TdVH"] : $group["VH"], + []), + "form" => $formations]; break; case "TP": - $tpRepo->create($codeUE, - $allProf[$group["professor"]]["dbId"], - $UE["disabled"] ? $UE["TpVH"] : $group["VH"], - $formations); + $TPToLink[] = ["id" => $tpRepo->create($codeUE, + $allProf[$group["professor"]]["dbId"], + $UE["disabled"] ? $UE["TpVH"] : $group["VH"], + []), + "form" => $formations]; break; } @@ -401,7 +410,28 @@ class excelController } } - return [ 'data' => ["professors" => $allProf, "formations" => $allFormations, "UEs" => $allUE ] ]; + Repo::enableStacking(); + + foreach ($CoursToLink as $cour){ + foreach ($cour["form"] as $formation){ + $coursRepo->linkFormation($formation,$cour["id"]); + } + } + foreach ($TDToLink as $cour){ + foreach ($cour["form"] as $formation){ + $tdRepo->linkFormation($formation,$cour["id"]); + } + } + foreach ($TPToLink as $cour){ + foreach ($cour["form"] as $formation){ + $tpRepo->linkFormation($formation,$cour["id"]); + } + } + + Repo::flushStack(); + + //return [ 'data' => ["professors" => $allProf, "formations" => $allFormations, "UEs" => $allUE ] ]; + return["data" => true]; }catch (Exception $e){ return [ 'error' => new Error(Err::UnknownError) ]; } diff --git a/build/api/module/ueController.php b/build/api/module/ueController.php index 8cb9846..66da246 100644 --- a/build/api/module/ueController.php +++ b/build/api/module/ueController.php @@ -42,4 +42,129 @@ class ueController{ } + /* (2) Creates a new UE + * + * @code The code of the UE + * @label The UE label (name) + * @required If the UE is required + * @volumeCours The UE required volume of COURSES + * @volumeTD The UE required volume of TD + * @volumeTP The UE required volume of TP + * @disabled [OPT] If it is disabled + * @defaultFormation [OPT] If there is a foreign key for a default formation (if only one formation) + * + * @return created_code The created UE code (if no error) + * + ---------------------------------------------------------*/ + public static function post($args){ + $code = ""; + $label = ""; + $required = false; + $volumeCours = 0; + $volumeTD = 0; + $volumeTP = 0; + $disabled = true; + $defaultFormation = -1; + extract($args); + + /* Get the ue repo */ + /** @var ue $ue_repo */ + $ue_repo = Repo::getRepo('ue'); + + /* (1) Check if ue code already exists */ + $exists = $ue_repo->get($code); + + /* (2) If found -> already exists */ + if( count($exists) > 0 ) + return ['error' => new Error(Err::AlreadyExists)]; + + /* (3) Else try to create */ + $repo_rtn = $ue_repo->create( + $code, + $label, + $required, + $volumeCours, + $volumeTD, + $volumeTP, + $disabled, + is_int($defaultFormation) && $defaultFormation < 0 ? null : $defaultFormation + ); + + + /* (4) If repo error -> return it */ + if( is_null($repo_rtn) ) + return ['error' => new Error(Err::RepoError)]; + + + /* (5) Else return UID */ + return ['created_code' => $repo_rtn]; + + } + + + /* (3) Deletes an existing UE + * + * @code The UE code + * + * @return deleted Whether it has been removed + * + ---------------------------------------------------------*/ + public static function delete($args){ + $code = ''; + extract($args); + + /* Get the ue repo */ + /** @var ue $ue_repo */ + $ue_repo = Repo::getRepo('ue'); + + /* (1) Try to delete */ + return ['deleted' => $ue_repo->delete($code)]; + + } + + + /* (4) Edits an existing UE + * + * @code The code of the UE + * @label [OPT] The UE label (name) + * @required [OPT] If the UE is required + * @volumeCours [OPT] The UE required volume of COURSES + * @volumeTD [OPT] The UE required volume of TD + * @volumeTP [OPT] The UE required volume of TP + * @disabled [OPT] If it is disabled + * @defaultFormation [OPT] default formation for this UE (-1 to unset, NULL to ignore) + * + * @return updated Whether it has been updated + * + ---------------------------------------------------------*/ + public static function put($args){ + $code = ""; + $label = ""; + $required = false; + $volumeCours = 0; + $volumeTD = 0; + $volumeTP = 0; + $disabled = true; + $defaultFormation = null; + extract($args); + + /* Get the ue repo */ + /** @var ue $ue_repo */ + $ue_repo = Repo::getRepo('ue'); + + /* (1) Try to update */ + return ['updated' => $ue_repo->update( + $code, + $label, + $required, + $volumeCours, + $volumeTD, + $volumeTP, + $disabled, + $defaultFormation + )]; + + } + + } \ No newline at end of file diff --git a/build/database/core/DatabaseDriver.php b/build/database/core/DatabaseDriver.php index a7553fd..080fd09 100755 --- a/build/database/core/DatabaseDriver.php +++ b/build/database/core/DatabaseDriver.php @@ -11,6 +11,7 @@ **************************/ namespace database\core; + use database\core\PDOWrapper\PDOWrapper; use \error\core\Error; use \error\core\Err; @@ -18,7 +19,7 @@ class DatabaseDriver{ /* STATIC ATTRIBUTES */ - private static function conf(){ + private static function conf() : array{ // YOUR CONFIGURATION BEHIND $path = __CONFIG__.'/database-driver.json'; @@ -36,11 +37,10 @@ return $parsed; } - - private static $path; // Databases configurations files - private static $config; // PDO configurations + /** @var DatabaseDriver[] */ private static $instance = []; // Database driver instance list + /** @var Error */ public $error; /* ATTRIBUTES */ @@ -52,15 +52,16 @@ - /* CONSTRUCTOR OF A DATABASE DRIVER + /** CONSTRUCTOR OF A DATABASE DRIVER * - * @host Database Server's host - * @dbname Database name - * @username Database username - * @password Database password + * @param String $host Database Server's host + * @param String $dbname Database name + * @param String $username Database username + * @param String $password Database password + * @param bool $debug * */ - private function __construct($host, $dbname, $username, $password){ + private function __construct(String $host, String $dbname, String $username, String $password, bool $debug = false){ /* (2) Stores configuration */ $this->host = $host; $this->dbname = $dbname; @@ -69,14 +70,19 @@ try{ - $this->pdo = new \PDO('mysql:host='.$this->host.';dbname='.$this->dbname.';charset=utf8', $this->username, $this->password, [ + $this->pdo = new PDOWrapper('mysql:host='.$this->host.';dbname='.$this->dbname.';charset=utf8', $this->username, $this->password, [ \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC, - \PDO::ATTR_TIMEOUT => 5 + \PDO::ATTR_TIMEOUT => 5, + \PDO::ERRMODE_EXCEPTION => true ]); $this->pdo->setAttribute(\PDO::ATTR_STRINGIFY_FETCHES, false); $this->pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false); + if($debug){ + $this->pdo->enableDebug(); + } + // On signale que tout s'est bien passe $this->error = new Error(Err::Success); @@ -92,22 +98,20 @@ **** Multiton Management (static) **** ************************************************/ - /* ADDS A NEW CONNECTION + /** ADDS A NEW CONNECTION * - * @label [optional] Database Label + * @param String $label [optional] Database Label * - * @return status If added successfully + * @return boolean If added successfully * */ - private static function add($label=null){ + private static function add(String $label='default') : bool{ $conf = self::conf(); /* [1] Default values =========================================================*/ - /* (1) If label isn't given */ - is_null($label) && ($label = 'default'); - /* (2) If label and no path */ + /* (1) If label and no path */ if( $label !== 'default' && !isset($conf[$label]) ) return false; @@ -118,7 +122,11 @@ /* (1) If local -> instanciates with local configuration */ // if( !checkdnsrr($_SERVER['SERVER_NAME'], 'NS') ) - self::$instance[$label] = new DatabaseDriver($conf[$label]['local']['host'], $conf[$label]['local']['dbname'], $conf[$label]['local']['user'], $conf[$label]['local']['password']); + if(!isset($conf[$label]['local']['debug'])){ + $conf[$label]['local']['debug'] = false; + } + + self::$instance[$label] = new DatabaseDriver($conf[$label]['local']['host'], $conf[$label]['local']['dbname'], $conf[$label]['local']['user'], $conf[$label]['local']['password'],$conf[$label]['local']['debug']); /* (2) If Remote -> instanciates with Remote configuration */ // else // self::$instance[$label] = new DatabaseDriver($conf[$label]['remote']['host'], $conf[$label]['remote']['dbname'], $conf[$label]['remote']['user'], $conf[$label]['remote']['password']); @@ -135,22 +143,20 @@ } - /* GET A DATABASE DRIVER INSTANCE + /** GET A DATABASE DRIVER INSTANCE * - * @label [optional] Driver's label - * - * @return driver Multiton + * @param String $label [optional] Driver's label + * @throws \Exception + * @return DatabaseDriver Multiton * */ - public static function get($label=null){ + public static function get(String $label='default') : DatabaseDriver{ $conf = self::conf(); /* [1] Checks arguments =========================================================*/ - /* (1) Label default value */ - is_null($label) && ($label = 'default'); - /* (2) If no label, or unknown label */ + /* (1) If no label, or unknown label */ if( !isset(self::$instance[$label]) ){ /* (2.1) Try to add the configuration if exists */ @@ -171,21 +177,31 @@ /** retourne la connection statique - * @param null $label + * @param String|null $label + * @throws \Exception * @return \PDO */ - public static function getPDO($label=null){ - $instance = self::get($label); + public static function getPDO(?String $label=null) : \PDO{ + if(is_string($label)){ + $instance = self::get($label); + }else{ + $instance = self::get(); + } return $instance->pdo; } - + /** + * @return \PDO + */ public function pdo(){ return $this->pdo; } + /** + * @return array + */ public function getConfig(){ return [ 'host' => $this->host, @@ -194,6 +210,34 @@ ]; } + /** + * enable request stacking + */ + public function enableStacking(){ + $this->pdo->enableStacking(); + } + + /** + * send all the stacked request and flush the stack + */ + public function flushStack(){ + $this->pdo->executeStack(); + } + + /** get all debug data + * @return array + */ + public function getDebug() : array{ + return $this->pdo->getDebug(); + } + + /** + * @return bool + */ + public function isDebugEnabled() : bool { + return $this->pdo->isDebugEnabled(); + } + } diff --git a/build/database/core/PDOWrapper/PDOStatementWrapper.php b/build/database/core/PDOWrapper/PDOStatementWrapper.php new file mode 100644 index 0000000..808c2df --- /dev/null +++ b/build/database/core/PDOWrapper/PDOStatementWrapper.php @@ -0,0 +1,65 @@ +statement = $statement; + $this->connexion = $connexion; + + + } + + /** + * @param array $input_parameters + * @return bool + */ + public function execute($input_parameters = []) : bool + { + $this->parameters = $input_parameters; + $this->connexion->stackStatement($this); + return true; + } + + /** + * @return string + */ + public function getStatement() : String + { + return $this->statement; + } + + /** + * @return array + */ + public function getParameters() : array + { + return $this->parameters; + } + + + +} \ No newline at end of file diff --git a/build/database/core/PDOWrapper/PDOWrapper.php b/build/database/core/PDOWrapper/PDOWrapper.php new file mode 100644 index 0000000..ffd5cb8 --- /dev/null +++ b/build/database/core/PDOWrapper/PDOWrapper.php @@ -0,0 +1,197 @@ +debugEnabled){ + $this->storeDebug(); + } + + if($this->stacking){ + return new PDOStatementWrapper($statement, $this); + }else{ + return parent::prepare($statement, $options); + + } + } + + /** + * @throws \ReflectionException + * + * @return void + */ + private function storeDebug(){ + //get all the debug info about the repo + $prepareStack = debug_backtrace(0,3)[1]; + $stack = debug_backtrace(0,3)[2]; + //create the reflection object + $f = new \ReflectionMethod($stack["class"],$stack["function"]); + //get only the repo name + $className = explode("\\",$stack["class"]); + $className = $className[count($className)-1]; + + $result = []; + + //if we are flushing a stack, just count the number of request stacked + if($stack["function"] == "executeStack"){ + + $result["StackedRequest"] = true; + $result["numberOfStackedRequest"] = substr_count($prepareStack["args"][0],";"); + //if we are not stacking, log the repo call + }else if(!$this->stacking){ + //store results + $result["repoName"] = $className; + $result["methodName"] = $stack["function"]; + $result["args"] = []; + + foreach ($f->getParameters() as $key => $param) { + $result["args"][$param->name] = $stack["args"][$key]; + } + //else we are stacking a request, we should not log it + }else{ + return; + } + + $this->debug[] = $result; + } + + /** + * @return array + */ + public function getDebug() : array{ + return $this->debug; + } + + /** + * Enable request stacking + */ + public function enableStacking(){ + $this->stacking = true; + } + + /** + * @return bool + */ + public function isDebugEnabled() : bool{ + return $this->debugEnabled; + } + + /** + * @param PDOStatementWrapper $st + */ + public function stackStatement(PDOStatementWrapper $st){ + array_push($this->statements,$st); + } + + /** + * Enable repo debug + */ + public function enableDebug(){ + $this->debugEnabled = true; + } + + /** + * disable repo debug + */ + public function disableDebug(){ + $this->debugEnabled = false; + } + + /** Execute the stored request stack + * @return bool + */ + public function executeStack(){ + //init the statements and the generator of number + $finalStatement = ''; + $finalExecute = []; + $i = 0; + + //for each request stacked + foreach ($this->statements as $request){ + $statement = $request->getStatement(); + + // we have to modify the parameters index at the same time that we modify the request, so we use static class attribute + $tempParametes = $request->getParameters(); + + //find the given pattern in the request, then call our function and replace the matched string by the return value of our function + $finalStatement .= rtrim(preg_replace_callback("/(:[a-z_\-0-9]*)/is",function($matches) use (&$i,&$tempParametes){ + //get next number + $i++; + + //delete the ':' at the beginning of the string + $tempKey = ltrim($matches[0],':'); + + //copy the parameter with the modified index + $tempParametes[$tempKey.$i] = $tempParametes[$tempKey]; + + //delete the old index + unset($tempParametes[$tempKey]); + + //return the modified string for replacement + return $matches[0].$i; + },$statement),';').';'; + + $finalExecute = array_merge($finalExecute,$tempParametes); + } + + //disable stacking + $this->stacking = false; + + //enable prepare emulation (native prepare do not accept stacked requests + parent::setAttribute(\PDO::ATTR_EMULATE_PREPARES, true); + + $this->beginTransaction(); + + $req = $this->prepare($finalStatement); + + $success = $req->execute($finalExecute); + //as we execute multiple query that we don't fetch, we have to close the cursor if we want to do other requests later + $req->closeCursor(); + $this->commit(); + + //using beginTransaction/commit disable the autocommit, we re-activate it + $this->setAttribute(\PDO::ATTR_AUTOCOMMIT,1); + parent::setAttribute(\PDO::ATTR_EMULATE_PREPARES, false); + + return $success; + } +} \ No newline at end of file diff --git a/build/database/core/Repo.php b/build/database/core/Repo.php index 6a09828..d5d86f3 100644 --- a/build/database/core/Repo.php +++ b/build/database/core/Repo.php @@ -12,6 +12,7 @@ namespace database\core; + use database\core\PDOWrapper\PDOWrapper; use \error\core\Error; use \error\core\Err; @@ -20,6 +21,9 @@ /* (1) Driver ---------------------------------------------------------*/ + /** + * @var DatabaseDriver + */ private static $driver = null; public static function setDriver(DatabaseDriver $driver){ self::$driver = $driver; } @@ -57,6 +61,22 @@ return $instance; } + public static function enableStacking(){ + static::$driver->enableStacking(); + } + + public static function flushStack(){ + static::$driver->flushStack(); + } + + public static function getDebug() : array{ + return static::$driver->getDebug(); + } + + public static function isDebugEnabled() : bool{ + return static::$driver->isDebugEnabled(); + } + diff --git a/build/database/repo/departement.php b/build/database/repo/departement.php index de9d1e6..946b4fc 100644 --- a/build/database/repo/departement.php +++ b/build/database/repo/departement.php @@ -9,6 +9,7 @@ namespace database\repo; +use database\core\Repo; use database\core\Repo_i; class departement extends Repo_i @@ -88,4 +89,82 @@ class departement extends Repo_i return $results; } + public function getStats() : array{ + + /* (1) Potentiel horaire du département */ + $Potentiel = $this->pdo->prepare("SELECT SUM(hoursToDo) potentiel + FROM Professeur + WHERE Categorie_idCategorie IN (1,2,3) + GROUP BY Categorie_idCategorie IN (1,2,3);"); + + $Potentiel->execute([]); + + $results = $Potentiel->fetch(); + + /* (2) Sous-service (professeurs ayant moins d'heure prévu que d'heure du) */ + /** @var professor $ProfRepo */ + $ProfRepo = Repo::getRepo("professor"); + + $profs = $ProfRepo->getWithVH(null); + + $results["sous_service"] = 0; + $results["heures_comp"] = 0; + $results["heures_vacataire"] = 0; + + foreach ($profs as $prof){ + if(in_array($prof["idCat"],[1,2,3,4]) and $prof["equiTD"] < $prof["hoursToDo"]){ + $results["sous_service"] += $prof["hoursToDo"] - $prof["equiTD"]; + + /* (3) Heures effectués par des vacataires */ + }else if(in_array($prof["idCat"],[5,6])){ + $results["heures_vacataire"] += $prof["equiTD"]; + } + + /* (4) Heures complementaires */ + + if(is_numeric($prof["VHComp"])){ + $results["heures_comp"] += $prof["VHComp"]; + } + + } + + /* (5) Heures effectuées pour des départements exterieurs */ + //je crois que j'ai créé un montre - Lucas - 2018 + $HDepExt = $this->pdo->prepare(" + SELECT U.disabled disabled, + count(U.code) nbrUe, + SUM((IFNULL(T1.VolumeCours,0)*IFNULL(tauxInfoCours,0) + IFNULL(T2.VolumeTD,0)*IFNULL(tauxInfoTD,0) + IFNULL(T3.VolumeTP,0)*IFNULL(tauxInfoTP,0))) totalInfo, + SUM((IFNULL(T1.VolumeCours,0)*(1-IFNULL(tauxInfoCours,0)) + IFNULL(T2.VolumeTD,0)*(1-IFNULL(tauxInfoTD,0)) + IFNULL(T3.VolumeTP,0)*(1-IFNULL(tauxInfoTP,0)))) totalExterieur + FROM UE U + LEFT JOIN (SELECT SUM(F.isInternal)/count(F.idFormation) tauxInfoCours,SUM(C.volume)*1.5 VolumeCours, C.UE_code code_UE + FROM Cours C + JOIN GroupeCours C2 ON C.idCours = C2.Cours_idCours + JOIN Formation F ON C2.Formation_idFormation = F.idFormation + GROUP BY C.UE_code) T1 ON U.code = T1.code_UE + LEFT JOIN (SELECT SUM(F.isInternal)/count(F.idFormation) tauxInfoTD,SUM(T1.volume) VolumeTD, T1.UE_code code_UE + FROM TD T1 + JOIN GroupeTD GT ON T1.idTD = GT.TD_idTD + JOIN Formation F ON GT.Formation_idFormation = F.idFormation + GROUP BY T1.UE_code) T2 ON U.code = T2.code_UE + LEFT JOIN (SELECT SUM(F.isInternal)/count(F.idFormation) tauxInfoTP,SUM(T1.volume) VolumeTP, T1.UE_code code_UE + FROM TP T1 + JOIN GroupeTP TP2 ON T1.idTP = TP2.TP_idTP + JOIN Formation F ON TP2.Formation_idFormation = F.idFormation + GROUP BY T1.UE_code) T3 ON U.code = T3.code_UE + GROUP BY U.disabled"); + + $HDepExt->execute([]); + + $HDepExtData = $HDepExt->fetchAll(); + + $results = array_merge($results,[ + "heures_exterieur" => $HDepExtData[0]["totalExterieur"], + "heures_ue_desactive" => $HDepExtData[1]["totalExterieur"] + $HDepExtData[1]["totalInfo"], + "nbr_ue_desactive" => $HDepExtData[1]["nbrUe"] + ]); + + return $results; + + } + } \ No newline at end of file diff --git a/build/database/repo/professor.php b/build/database/repo/professor.php index 1fcfad0..b161ede 100644 --- a/build/database/repo/professor.php +++ b/build/database/repo/professor.php @@ -64,19 +64,26 @@ class professor extends Repo_i { * @return prof_id The professor's UID (or NULL on error) * ---------------------------------------------------------*/ - public function exists(string $lastName, string $firstName) : ?int{ + public function exists(string $lastName, string $firstName, ?string $casLogin = null) : ?int{ /* (1) Prepare Statement */ $st = $this->pdo->prepare("SELECT idProfesseur FROM Professeur WHERE firstName = :firstName - AND lastName = :lastName"); + AND lastName = :lastName + ".(is_string($casLogin) ? "AND casLogin = :casLogin" : "")); /* (2) Bind params and execute */ - $success = $st->execute([ + $params = [ ':firstName' => $firstName, ':lastName' => $lastName - ]); + ]; + + if(is_string($casLogin)){ + $params[":casLogin"] = $casLogin; + } + + $success = $st->execute(); /* (3) Return NULL on error */ if( !$success ) @@ -214,21 +221,25 @@ class professor extends Repo_i { /* (1) Prepare Statement */ $st = $this->pdo->prepare("SELECT * FROM `Professeur` WHERE `casLogin` = :cas_login"); - /* (2) Bind params and execute statement */ + /* (2) Check if statement error */ + if( is_bool($st) ) + return NULL; + + /* (3) Bind params and execute statement */ $success = $st->execute([ ':cas_login' => $cas_login ]); - /* (3) Manage error */ + /* (4) Manage error */ if( !$success ) return NULL; - /* (4) Get data */ + /* (5) Get data */ $fetched = $st->fetch(); - /* (5) Return NULL on no result */ + /* (6) Return NULL on no result */ if( $fetched === false ) return NULL; - /* (6) Return data */ + /* (7) Return data */ return $fetched; } @@ -319,7 +330,7 @@ class professor extends Repo_i { $prof['VHComp'] = round($prof['equiTD'] - $prof['hoursToDo'], 2); $prof['VHComp'] = ( $prof['VHComp'] < 0 ) ? 0 : $prof['VHComp']; }else{ - $VH["equiTD"] = $prof["VHTd"] + (2/3)*$prof["VHTp"] + 1.5*$prof["VHCours"]; + $prof["equiTD"] = $prof["VHTd"] + (2/3)*$prof["VHTp"] + 1.5*$prof["VHCours"]; if(is_numeric($prof["hoursToDo"]) and $prof["hoursToDo"] > 0){ $prof['VHComp'] = round($prof['equiTD'] - $prof['hoursToDo'], 2); $prof['VHComp'] = ( $prof['VHComp'] < 0 ) ? 0 : $prof['VHComp']; diff --git a/build/database/repo/ue.php b/build/database/repo/ue.php index 2c0f82c..d9e6e0e 100644 --- a/build/database/repo/ue.php +++ b/build/database/repo/ue.php @@ -18,16 +18,17 @@ class ue extends Repo_i { * * @code The code of the UE * @label The UE label (name) + * @required If the UE is required * @volumeCours The UE required volume of COURSES * @volumeTD The UE required volume of TD * @volumeTP The UE required volume of TP - * @disabled If it is disabled - * @defaultFormation If there is a foreign key for a default formation (if only one formation) + * @disabled [OPT] If it is disabled + * @defaultFormation [OPT] If there is a foreign key for a default formation (if only one formation) * * @return created_code Code of the created UE (NULL on error) * ---------------------------------------------------------*/ - public function create(string $code, string $label, bool $required, float $volumeCours, float $volumeTD, float $volumeTP, bool $disabled = false, ?int $defaultFormation = null) : ?int { + public function create(string $code, string $label, bool $required, float $volumeCours, float $volumeTD, float $volumeTP, bool $disabled = false, ?int $defaultFormation = null) : ?string { /* (1) Prepare request */ $st = $this->pdo->prepare("INSERT INTO UE(`code`, `label`, `required`, `volumeCours`, `volumeTD`, `volumeTP`, `disabled`, `Formation_idFormation`) @@ -39,14 +40,14 @@ class ue extends Repo_i { /* (3) Bind params and execute request */ $success = $st->execute([ - "code" => $code, - "label" => $label, - "required" => $required ? 1 : 0, - "volCours" => $volumeCours, - "volTD" => $volumeTD, - "volTP" => $volumeTP, - "disabled" => $disabled ? 1 : 0, - "idFormation" => $defaultFormation + ':code' => $code, + ':label' => $label, + ':required' => $required ? 1 : 0, + ':volCours' => $volumeCours, + ':volTD' => $volumeTD, + ':volTP' => $volumeTP, + ':disabled' => $disabled ? 1 : 0, + ':idFormation' => $defaultFormation ]); /* (4) Manage execution error */ @@ -54,7 +55,7 @@ class ue extends Repo_i { return null; /* (5) Return insert id */ - return $this->pdo->lastInsertId(); + return $code; } @@ -68,7 +69,7 @@ class ue extends Repo_i { * @volumeTD [OPT] The UE's new volume of TD * @volumeTP [OPT] The UE's new volume of TP * @disabled [OPT] Whether the UE is disabled - * @defaultFormation [OPT] The default formation foreign key + * @defaultFormation [OPT] The default formation foreign key (-1 to unset) * * @return updated Whether the update have been successful * @@ -80,15 +81,25 @@ class ue extends Repo_i { $bind_param = [ ':code' => $code ]; if( !is_null($label) ){ $build_rq[] = '`label` = :label'; $bind_param[':label'] = $label; } - if( !is_null($required) ){ $build_rq[] = '`required` = :required'; $bind_param[':required'] = $required; } + if( !is_null($required) ){ $build_rq[] = '`required` = :required'; $bind_param[':required'] = $required?1:0; } if( !is_null($volumeCours) ){ $build_rq[] = '`volumeCours` = :volumeCours'; $bind_param[':volumeCours'] = $volumeCours; } if( !is_null($volumeTD) ){ $build_rq[] = '`volumeTD` = :volumeTD'; $bind_param[':volumeTD'] = $volumeTD; } if( !is_null($volumeTP) ){ $build_rq[] = '`volumeTP` = :volumeTP'; $bind_param[':volumeTP'] = $volumeTP; } - if( !is_null($disabled) ){ $build_rq[] = '`disabled` = :disabled'; $bind_param[':disabled'] = $disabled; } - if( !is_null($defaultFormation) ){ $build_rq[] = '`Formation_idFormation` = :defaultFormation'; $bind_param[':defaultFormation'] = $defaultFormation; } + if( !is_null($disabled) ){ $build_rq[] = '`disabled` = :disabled'; $bind_param[':disabled'] = $disabled?1:0; } + + // not null @defaultFormation -> set it + if( !is_null($defaultFormation) ){ + + // if @defaultFormation is (-1) -> unset + if( $defaultFormation < 0 ){ $build_rq[] = '`Formation_idFormation` = NULL'; } + // else -> set to new value + else{ $build_rq[] = '`Formation_idFormation` = :defaultFormation'; $bind_param[':defaultFormation'] = $defaultFormation; } + + } + /* (2) ERROR if no updated field */ - if( count($build_rq) <= 0 || count($bind_param) <= 1 ) + if( count($build_rq) <= 0 ) return FALSE; /* (3) Build request */ @@ -160,14 +171,19 @@ class ue extends Repo_i { * @return ues The UEs matching code (NULL on error) * ---------------------------------------------------------*/ - public function get(?String $code=null) : ?array{ + public function get(?String $code=null) : array{ /* (1) Manage if no id given */ - $cond = is_null($code) ? '' : ' WHERE `code` = :code'; + $cond = is_null($code) ? '' : 'WHERE `code` = :code'; $parm = is_null($code) ? [] : [':code' => $code]; /* (2) Prepare Statement */ - $st = $this->pdo->prepare("SELECT * FROM `UE`$cond GROUP BY `label` ASC"); + $this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); + $st = $this->pdo->prepare("SELECT ue.code, ue.label, ue.disabled, ue.required, ue.volumeCours, ue.volumeTD, ue.volumeTP, IFNULL(ue.Formation_idFormation, -1) idForm, f.labelFormation labelForm + FROM `UE` ue + LEFT JOIN Formation f ON ue.Formation_idFormation = f.idFormation + $cond + ORDER BY `ue`.`label` ASC"); /* (3) Bind params and execute statement */ if( is_bool($st) ) return []; diff --git a/config/database-driver.json b/config/database-driver.json index fb2da3c..0c99f5d 100755 --- a/config/database-driver.json +++ b/config/database-driver.json @@ -4,7 +4,8 @@ "host" : "mariadb", "dbname" : "vhost", "user" : "php", - "password" : "4JB1dtbrIC8pT935" + "password" : "4JB1dtbrIC8pT935", + "debug" : true }, "remote": { "host" : "db_remote_host", diff --git a/config/modules.json b/config/modules.json index f101b2e..4f744ef 100644 --- a/config/modules.json +++ b/config/modules.json @@ -79,6 +79,14 @@ "par": { } } + }, + "stats":{ + "GET": { + "des": "Get the statistics about the departement", + "per": [], + "par": { + } + } } }, @@ -177,17 +185,17 @@ "des": "Creates a new UE", "per": [], "par": { - "code": { "des": "UE code.", "typ": "varchar(2,30,alphanumeric)" }, - "label": { "des": "UE label", "typ": "varchar(2,30,alphanumeric)" }, - "required": { "des": "If UE is required", "typ": "bool" }, - "volumeCours": { "des": "Number of course hours for UE", "typ": "float" }, - "volumeTD": { "des": "Number of TD hours for UE", "typ": "float" }, - "volumeTP": { "des": "Number of TP hours for UE", "typ": "float" }, - "disabled": { "des": "Whether UE is disabled", "typ": "boolean" }, - "defaultFormation": { "des": "UID for optional default formation", "typ": "id", "opt": true } + "code": { "des": "UE code.", "typ": "varchar(4,20,alphanumeric)" }, + "label": { "des": "UE label", "typ": "varchar(4,30,alphanumeric)" }, + "required": { "des": "If UE is required", "typ": "bool" }, + "volumeCours": { "des": "Number of course hours for UE", "typ": "float" }, + "volumeTD": { "des": "Number of TD hours for UE", "typ": "float" }, + "volumeTP": { "des": "Number of TP hours for UE", "typ": "float" }, + "disabled": { "des": "Whether UE is disabled", "typ": "boolean" }, + "defaultFormation": { "des": "UID for optional default formation (-1 if none)", "typ": "int", "opt": true, "def": -1 } }, "out": { - "created_code": { "des": "Created UE code", "typ": "varchar(2,30,alphanumeric)" } + "created_code": { "des": "Created UE code", "typ": "varchar(4,20,alphanumeric)" } } }, @@ -195,11 +203,41 @@ "des": "Get one or all UE", "per": [], "par": { - "URL0": { "des": "Optional UE code.", "typ": "varchar(2,30,alphanumeric)", "ren": "code", "opt": true } + "URL0": { "des": "Optional UE code.", "typ": "varchar(4,20,alphanumeric)", "ren": "code", "opt": true } }, "out": { "ues": { "des": "UE list", "typ": "array" } } + }, + + + "DELETE": { + "des": "Deletes an existing UE", + "per": [], + "par": { + "URL0": { "des": "UE code.", "typ": "varchar(4,20,alphanumeric)", "ren": "code" } + }, + "out": { + "deleted": { "des": "Whether it has been deleted", "typ": "boolean" } + } + }, + + "PUT": { + "des": "Edits an existing UE", + "per": [], + "par": { + "URL0": { "des": "UE code.", "typ": "varchar(4,20,alphanumeric)", "ren": "code" }, + "label": { "des": "UE label", "typ": "varchar(4,30,alphanumeric)", "opt": true }, + "required": { "des": "If UE is required", "typ": "bool", "opt": true }, + "volumeCours": { "des": "Number of course hours for UE", "typ": "float", "opt": true }, + "volumeTD": { "des": "Number of TD hours for UE", "typ": "float", "opt": true }, + "volumeTP": { "des": "Number of TP hours for UE", "typ": "float", "opt": true }, + "disabled": { "des": "Whether UE is disabled", "typ": "boolean", "opt": true }, + "defaultFormation": { "des": "UID for optional default formation (-1 for none)", "typ": "int", "opt": true } + }, + "out": { + "updated": { "des": "Whether the UE has been updated", "typ": "boolean" } + } } diff --git a/public_html/asset/svg/bell.svg b/public_html/asset/svg/bell.svg new file mode 100644 index 0000000..822f455 --- /dev/null +++ b/public_html/asset/svg/bell.svg @@ -0,0 +1,44 @@ + +image/svg+xml \ No newline at end of file diff --git a/public_html/page/ue.php b/public_html/page/ue.php index 9241273..a6bcd82 100644 --- a/public_html/page/ue.php +++ b/public_html/page/ue.php @@ -7,7 +7,7 @@ - Gestion des enseignants + Gestion des UEs diff --git a/webpack/component/teacher/view.vue b/webpack/component/teacher/view.vue index dae6a93..384a8f6 100644 --- a/webpack/component/teacher/view.vue +++ b/webpack/component/teacher/view.vue @@ -19,7 +19,7 @@
- +
@@ -58,9 +58,9 @@
-
-
-
+
+
+
@@ -73,7 +73,7 @@ -

{{ prof.firstName }} {{ prof.lastName }} ({{ prof.casLogin }})

+

{{ prof.firstName }} {{ prof.lastName }} ({{ prof.casLogin }})

@@ -91,14 +91,14 @@ heures à faire

-
+
{{ prof.equiTD }} heures prévues
-
{{ prof.VHCours + prof.VHTd + prof.VHTp }}h physiques prévues
+
{{ prof.VHCours + prof.VHTd + prof.VHTp }}h réelles prévues
{{ gstore.edit_err }}
@@ -107,9 +107,9 @@ {{ prof.VHCours }}h Cours
- {{ prof.VHTd }}h TD + {{ prof.VHTd }}h TD
- {{ prof.VHTp }}h TP + {{ prof.VHTp }}h TP diff --git a/webpack/component/ue/view.vue b/webpack/component/ue/view.vue index c549486..ba3b27a 100644 --- a/webpack/component/ue/view.vue +++ b/webpack/component/ue/view.vue @@ -1,38 +1,110 @@