From 1b0a52ded629189468805505a2207044c6d7cd80 Mon Sep 17 00:00:00 2001 From: Unknown Date: Tue, 20 Feb 2018 20:20:23 +0100 Subject: [PATCH 1/2] Add formations to output JSON --- build/api/module/Excel.php | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/build/api/module/Excel.php b/build/api/module/Excel.php index 3c011f0..8a66436 100644 --- a/build/api/module/Excel.php +++ b/build/api/module/Excel.php @@ -22,6 +22,7 @@ class Excel public function post($args){ if(isset($_FILES["file"]["tmp_name"])){ + //put everything in a try so we catch all PhpExcel exceptions and return a clean API Response try{ $reader = new \PhpOffice\PhpSpreadsheet\Reader\Xls(); $reader->setReadDataOnly(true); @@ -42,6 +43,8 @@ class Excel $UE = []; //array containing all the UEs $allUE = []; + //array containing all the formations + $allFormations = []; /* * declare the lambda that will add finalized UE to the array @@ -65,7 +68,7 @@ class Excel /* * declaring the lambda tha twill extract the list of formation involved in the group */ - $getFormations = function(?string $group) use (&$formation) : array{ + $getFormations = function(?string $group) use (&$formation,&$allFormations) : array{ if(!$group) return [$formation]; //replace the generic "INFO" keyword by the actual formation @@ -78,7 +81,18 @@ class Excel $groups = array_map('trim', $groups); //delete empty strings - return array_filter($groups); + $groups = array_filter($groups); + + foreach ($groups as $group){ + if(!isset($allFormations[$group])){ + $allFormations[$group] = [ + "name" => $group, + "internal" => strpos(strtolower($group),"info") !== false ? true : false + ]; + } + } + + return $groups; }; /* @@ -146,8 +160,8 @@ class Excel if ($UESpreadsheet->getCellByColumnAndRow(5,$row->getRowIndex())->getCalculatedValue()){ $UE["groups"]["Course"][] = [ "VH" => $UESpreadsheet->getCellByColumnAndRow(5,$row->getRowIndex())->getCalculatedValue(), - "internalStudentPart" => $getInternalStudentPart($UESpreadsheet->getCellByColumnAndRow(6,$row->getRowIndex())->getValue()), - "formations" => $getFormations($UESpreadsheet->getCellByColumnAndRow(6,$row->getRowIndex())->getValue()), + "internalStudentPart" => $getInternalStudentPart($UESpreadsheet->getCellByColumnAndRow(6,$row->getRowIndex())->getCalculatedValue()), + "formations" => $getFormations($UESpreadsheet->getCellByColumnAndRow(6,$row->getRowIndex())->getCalculatedValue()), "professor" => $UESpreadsheet->getCellByColumnAndRow(7,$row->getRowIndex())->getValue() ?: null ]; } @@ -156,8 +170,8 @@ class Excel if($UESpreadsheet->getCellByColumnAndRow(8,$row->getRowIndex())->getCalculatedValue()){ $UE["groups"]["TD"][] = [ "VH" => $UESpreadsheet->getCellByColumnAndRow(8,$row->getRowIndex())->getCalculatedValue(), - "internalStudentPart" => $getInternalStudentPart($UESpreadsheet->getCellByColumnAndRow(9,$row->getRowIndex())->getValue()), - "formations" => $getFormations($UESpreadsheet->getCellByColumnAndRow(6,$row->getRowIndex())->getValue()), + "internalStudentPart" => $getInternalStudentPart($UESpreadsheet->getCellByColumnAndRow(9,$row->getRowIndex())->getCalculatedValue()), + "formations" => $getFormations($UESpreadsheet->getCellByColumnAndRow(6,$row->getRowIndex())->getCalculatedValue()), "professor" => $UESpreadsheet->getCellByColumnAndRow(10,$row->getRowIndex())->getValue() ?: null ]; } @@ -166,8 +180,8 @@ class Excel if($UESpreadsheet->getCellByColumnAndRow(11,$row->getRowIndex())->getCalculatedValue()){ $UE["groups"]["TP"][] = [ "VH" => $UESpreadsheet->getCellByColumnAndRow(11,$row->getRowIndex())->getCalculatedValue(), - "internalStudentPart" => $getInternalStudentPart($UESpreadsheet->getCellByColumnAndRow(12,$row->getRowIndex())->getValue()), - "formations" => $getFormations($UESpreadsheet->getCellByColumnAndRow(6,$row->getRowIndex())->getValue()), + "internalStudentPart" => $getInternalStudentPart($UESpreadsheet->getCellByColumnAndRow(12,$row->getRowIndex())->getCalculatedValue()), + "formations" => $getFormations($UESpreadsheet->getCellByColumnAndRow(6,$row->getRowIndex())->getCalculatedValue()), "professor" => $UESpreadsheet->getCellByColumnAndRow(13,$row->getRowIndex())->getValue() ?: null ]; } @@ -222,7 +236,7 @@ class Excel - return [ 'data' => ["professors" => $allProf, "UEs" => $allUE ] ]; + return [ 'data' => ["professors" => $allProf, "formations" => $allFormations, "UEs" => $allUE ] ]; }catch (Exception $e){ return [ 'error' => new Error(Err::UnknownError) ]; } From 30e5abede15cab4870c75215fadd7d3ae95be9cc Mon Sep 17 00:00:00 2001 From: Unknown Date: Tue, 27 Feb 2018 14:46:38 +0100 Subject: [PATCH 2/2] Working excel import + added phpstan to composer file --- build/api/module/Excel.php | 144 +++-- build/database/repo/category.php | 34 ++ build/database/repo/cours.php | 87 +++ build/database/repo/formation.php | 45 ++ build/database/repo/professor.php | 89 +++ build/database/repo/td.php | 88 +++ build/database/repo/tp.php | 87 +++ build/database/repo/ue.php | 64 +++ build/database/repo/user.php | 250 --------- composer.json | 3 +- composer.lock | 901 +++++++++++++++++++++++++++++- 11 files changed, 1507 insertions(+), 285 deletions(-) create mode 100644 build/database/repo/category.php create mode 100644 build/database/repo/cours.php create mode 100644 build/database/repo/formation.php create mode 100644 build/database/repo/professor.php create mode 100644 build/database/repo/td.php create mode 100644 build/database/repo/tp.php create mode 100644 build/database/repo/ue.php delete mode 100644 build/database/repo/user.php diff --git a/build/api/module/Excel.php b/build/api/module/Excel.php index 8a66436..7540023 100644 --- a/build/api/module/Excel.php +++ b/build/api/module/Excel.php @@ -9,6 +9,8 @@ namespace api\module; +use database\core\Repo; +use database\core\Repo_i; use error\core\Err; use error\core\Error; use PhpOffice\PhpSpreadsheet\Exception; @@ -21,6 +23,7 @@ class Excel private const startLineProf = 10; public function post($args){ + if(isset($_FILES["file"]["tmp_name"])){ //put everything in a try so we catch all PhpExcel exceptions and return a clean API Response try{ @@ -111,14 +114,18 @@ class Excel } }; + $exitWithNullException = function(){ + exit(json_encode(["error" => true, "message" => "NullCelException"])); + }; + //starting the iteration foreach($UESpreadsheet->getRowIterator() as $row){ //skip the first rows if($row->getRowIndex() < Excel::startLineUE) continue; - $firstCellValue = $UESpreadsheet->getCellByColumnAndRow(1,$row->getRowIndex())->getValue(); - $secondCellValue = $UESpreadsheet->getCellByColumnAndRow(2,$row->getRowIndex())->getValue(); + $firstCellValue = ($UESpreadsheet->getCellByColumnAndRow(1,$row->getRowIndex()) ?? $exitWithNullException())->getValue(); + $secondCellValue = ($UESpreadsheet->getCellByColumnAndRow(2,$row->getRowIndex()) ?? $exitWithNullException())->getValue(); //if the first value is not null and the second is, this means we change formation and rest the UUCode if($secondCellValue == "" and $firstCellValue != "") {$formation = $firstCellValue; $addEU(); $UECode = ""; continue; } @@ -133,18 +140,18 @@ class Excel //if the required field is not set this means we are at the header of the UE if(!isset($UE["required"])){ - $UE["name"] = $UESpreadsheet->getCellByColumnAndRow(2,$row->getRowIndex())->getCalculatedValue(); - $UE["required"] = $UESpreadsheet->getCellByColumnAndRow(3,$row->getRowIndex())->getValue(); - $UE["TotalVH"] = $UESpreadsheet->getCellByColumnAndRow(4,$row->getRowIndex())->getCalculatedValue(); + $UE["name"] = ($UESpreadsheet->getCellByColumnAndRow(2,$row->getRowIndex()) ?? $exitWithNullException())->getCalculatedValue(); + $UE["required"] = ($UESpreadsheet->getCellByColumnAndRow(3,$row->getRowIndex()) ?? $exitWithNullException())->getValue(); + $UE["TotalVH"] = ($UESpreadsheet->getCellByColumnAndRow(4,$row->getRowIndex()) ?? $exitWithNullException())->getCalculatedValue(); - $UE["CourseVH"] = $UESpreadsheet->getCellByColumnAndRow(5,$row->getRowIndex())->getValue() ?: 0.0; - $UE["CourseGroup"] = $UESpreadsheet->getCellByColumnAndRow(6,$row->getRowIndex())->getValue() ?: 0; + $UE["CourseVH"] = ($UESpreadsheet->getCellByColumnAndRow(5,$row->getRowIndex()) ?? $exitWithNullException())->getValue() ?: 0.0; + $UE["CourseGroup"] = ($UESpreadsheet->getCellByColumnAndRow(6,$row->getRowIndex()) ?? $exitWithNullException())->getValue() ?: 0; - $UE["TdVH"] = $UESpreadsheet->getCellByColumnAndRow(8,$row->getRowIndex())->getValue() ?: 0.0; - $UE["TdGroup"] = $UESpreadsheet->getCellByColumnAndRow(9,$row->getRowIndex())->getValue() ?: 0; + $UE["TdVH"] = ($UESpreadsheet->getCellByColumnAndRow(8,$row->getRowIndex()) ?? $exitWithNullException())->getValue() ?: 0.0; + $UE["TdGroup"] = ($UESpreadsheet->getCellByColumnAndRow(9,$row->getRowIndex()) ?? $exitWithNullException())->getValue() ?: 0; - $UE["TpVH"] = $UESpreadsheet->getCellByColumnAndRow(11,$row->getRowIndex())->getValue() ?: 0.0; - $UE["TpGroup"] = $UESpreadsheet->getCellByColumnAndRow(12,$row->getRowIndex())->getValue() ?: 0; + $UE["TpVH"] = ($UESpreadsheet->getCellByColumnAndRow(11,$row->getRowIndex()) ?? $exitWithNullException())->getValue() ?: 0.0; + $UE["TpGroup"] = ($UESpreadsheet->getCellByColumnAndRow(12,$row->getRowIndex()) ?? $exitWithNullException())->getValue() ?: 0; continue; } @@ -157,32 +164,32 @@ class Excel ]; //compute Course - if ($UESpreadsheet->getCellByColumnAndRow(5,$row->getRowIndex())->getCalculatedValue()){ + if (($UESpreadsheet->getCellByColumnAndRow(5,$row->getRowIndex()) ?? $exitWithNullException())->getCalculatedValue()){ $UE["groups"]["Course"][] = [ - "VH" => $UESpreadsheet->getCellByColumnAndRow(5,$row->getRowIndex())->getCalculatedValue(), - "internalStudentPart" => $getInternalStudentPart($UESpreadsheet->getCellByColumnAndRow(6,$row->getRowIndex())->getCalculatedValue()), - "formations" => $getFormations($UESpreadsheet->getCellByColumnAndRow(6,$row->getRowIndex())->getCalculatedValue()), - "professor" => $UESpreadsheet->getCellByColumnAndRow(7,$row->getRowIndex())->getValue() ?: null + "VH" => ($UESpreadsheet->getCellByColumnAndRow(5,$row->getRowIndex()) ?? $exitWithNullException())->getCalculatedValue(), + "internalStudentPart" => $getInternalStudentPart(($UESpreadsheet->getCellByColumnAndRow(6,$row->getRowIndex()) ?? $exitWithNullException())->getCalculatedValue()), + "formations" => $getFormations(($UESpreadsheet->getCellByColumnAndRow(6,$row->getRowIndex()) ?? $exitWithNullException())->getCalculatedValue()), + "professor" => ($UESpreadsheet->getCellByColumnAndRow(7,$row->getRowIndex()) ?? $exitWithNullException())->getValue() ?: null ]; } //compute TDs - if($UESpreadsheet->getCellByColumnAndRow(8,$row->getRowIndex())->getCalculatedValue()){ + if(($UESpreadsheet->getCellByColumnAndRow(8,$row->getRowIndex()) ?? $exitWithNullException())->getCalculatedValue()){ $UE["groups"]["TD"][] = [ - "VH" => $UESpreadsheet->getCellByColumnAndRow(8,$row->getRowIndex())->getCalculatedValue(), - "internalStudentPart" => $getInternalStudentPart($UESpreadsheet->getCellByColumnAndRow(9,$row->getRowIndex())->getCalculatedValue()), - "formations" => $getFormations($UESpreadsheet->getCellByColumnAndRow(6,$row->getRowIndex())->getCalculatedValue()), - "professor" => $UESpreadsheet->getCellByColumnAndRow(10,$row->getRowIndex())->getValue() ?: null + "VH" => ($UESpreadsheet->getCellByColumnAndRow(8,$row->getRowIndex()) ?? $exitWithNullException())->getCalculatedValue(), + "internalStudentPart" => $getInternalStudentPart(($UESpreadsheet->getCellByColumnAndRow(9,$row->getRowIndex()) ?? $exitWithNullException())->getCalculatedValue()), + "formations" => $getFormations(($UESpreadsheet->getCellByColumnAndRow(6,$row->getRowIndex()) ?? $exitWithNullException())->getCalculatedValue()), + "professor" => ($UESpreadsheet->getCellByColumnAndRow(10,$row->getRowIndex()) ?? $exitWithNullException())->getValue() ?: null ]; } //compute TPs - if($UESpreadsheet->getCellByColumnAndRow(11,$row->getRowIndex())->getCalculatedValue()){ + if(($UESpreadsheet->getCellByColumnAndRow(11,$row->getRowIndex()) ?? $exitWithNullException())->getCalculatedValue()){ $UE["groups"]["TP"][] = [ - "VH" => $UESpreadsheet->getCellByColumnAndRow(11,$row->getRowIndex())->getCalculatedValue(), - "internalStudentPart" => $getInternalStudentPart($UESpreadsheet->getCellByColumnAndRow(12,$row->getRowIndex())->getCalculatedValue()), - "formations" => $getFormations($UESpreadsheet->getCellByColumnAndRow(6,$row->getRowIndex())->getCalculatedValue()), - "professor" => $UESpreadsheet->getCellByColumnAndRow(13,$row->getRowIndex())->getValue() ?: null + "VH" => ($UESpreadsheet->getCellByColumnAndRow(11,$row->getRowIndex()) ?? $exitWithNullException())->getCalculatedValue(), + "internalStudentPart" => $getInternalStudentPart(($UESpreadsheet->getCellByColumnAndRow(12,$row->getRowIndex()) ?? $exitWithNullException())->getCalculatedValue()), + "formations" => $getFormations(($UESpreadsheet->getCellByColumnAndRow(6,$row->getRowIndex()) ?? $exitWithNullException())->getCalculatedValue()), + "professor" => ($UESpreadsheet->getCellByColumnAndRow(13,$row->getRowIndex()) ?? $exitWithNullException())->getValue() ?: null ]; } @@ -209,8 +216,8 @@ class Excel //skip the first lines if($row->getRowIndex() < Excel::startLineProf) continue; - $firstCellValue = $ProfSpreadshit->getCellByColumnAndRow(2,$row->getRowIndex())->getValue(); - $secondCellValue = $ProfSpreadshit->getCellByColumnAndRow(3,$row->getRowIndex())->getValue(); + $firstCellValue = ($ProfSpreadshit->getCellByColumnAndRow(2,$row->getRowIndex()) ?? $exitWithNullException())->getValue(); + $secondCellValue = ($ProfSpreadshit->getCellByColumnAndRow(3,$row->getRowIndex()) ?? $exitWithNullException())->getValue(); //skip empty lines if(!$firstCellValue and !$secondCellValue) continue; @@ -222,18 +229,89 @@ class Excel } //if the line is valid - if($ProfSpreadshit->getCellByColumnAndRow(3,$row->getRowIndex())->getValue() and $ProfSpreadshit->getCellByColumnAndRow(4,$row->getRowIndex())->getValue()){ - $allProf[$ProfSpreadshit->getCellByColumnAndRow(3,$row->getRowIndex())->getValue()] = [ + if(($ProfSpreadshit->getCellByColumnAndRow(3,$row->getRowIndex()) ?? $exitWithNullException())->getValue() and ($ProfSpreadshit->getCellByColumnAndRow(4,$row->getRowIndex()) ?? $exitWithNullException())->getValue()){ + $allProf[($ProfSpreadshit->getCellByColumnAndRow(3,$row->getRowIndex()) ?? $exitWithNullException())->getValue()] = [ "categoryLabel" => $currentCategory, "categoryIndex" => $currentCategoryIndex, - "lastName" => explode(" ",$ProfSpreadshit->getCellByColumnAndRow(4,$row->getRowIndex())->getValue(),2)[1], - "firstName" => explode(" ",$ProfSpreadshit->getCellByColumnAndRow(4,$row->getRowIndex())->getValue(),2)[0], - "hoursToDo" => $ProfSpreadshit->getCellByColumnAndRow(5,$row->getRowIndex())->getValue() ?: 0 + "lastName" => explode(" ",($ProfSpreadshit->getCellByColumnAndRow(4,$row->getRowIndex()) ?? $exitWithNullException())->getValue(),2)[1], + "firstName" => explode(" ",($ProfSpreadshit->getCellByColumnAndRow(4,$row->getRowIndex()) ?? $exitWithNullException())->getValue(),2)[0], + "hoursToDo" => ($ProfSpreadshit->getCellByColumnAndRow(5,$row->getRowIndex()) ?? $exitWithNullException())->getValue() ?: 0 ]; } } + /* + * adding data to the database + */ + + //professors + foreach ($allProf as $initials => &$prof){ + //create or update the professor category + Repo::request("category", "createOrUpdate", $prof["categoryIndex"], utf8_decode($prof["categoryLabel"])); + + //create the professor, as some names are missing, we replace them by something else + if(!$prof["lastName"]) $prof["lastName"] = "missingLastName"; + if(!$prof["firstName"]) $prof["firstName"] = "missingFirstName"; + + $prof["dbId"] = Repo::request("professor", "exists", utf8_decode($prof["lastName"]), utf8_decode($prof["firstName"])); + if(!$prof["dbId"]){ + $prof["dbId"] = Repo::request("professor", "create", utf8_decode($prof["lastName"]), utf8_decode($prof["firstName"]), $prof["categoryIndex"], $prof["hoursToDo"], $initials); + } + } + + //formation and retreive the databse IDs + foreach ($allFormations as &$form){ + $form["dbId"] = Repo::request("formation","exists", utf8_decode($form["name"])); + if(!$form["dbId"]){ + $form["dbId"] = Repo::request("formation", "create", utf8_decode($form["name"]), $form["internal"]); + } + } + + //UEs and corresponding groups + foreach ($allUE as $codeUE => $UE){ + Repo::request("ue","create", utf8_decode($codeUE), + utf8_decode($UE["name"]), + $UE["required"] == "OBL", + $UE["CourseVH"], + $UE["TdVH"], + $UE["TpVH"]); + if(isset($UE["groups"])){ + foreach ($UE["groups"] as $type => $groups){ + foreach ($groups as $group){ + $formations = []; + foreach ($group["formations"] as $form){ + if(isset($allFormations[$form]["dbId"])){ + $formations[] = $allFormations[$form]["dbId"]; + } + } + + switch ($type){ + case "Course": + Repo::request("cours","create", utf8_decode($codeUE), + $allProf[$group["professor"]]["dbId"], + $group["VH"], + $formations); + break; + case "TD": + Repo::request("td","create", utf8_decode($codeUE), + $allProf[$group["professor"]]["dbId"], + $group["VH"], + $formations); + break; + case "TP": + Repo::request("tp","create", utf8_decode($codeUE), + $allProf[$group["professor"]]["dbId"], + $group["VH"], + $formations); + break; + } + } + } + + } + } + return [ 'data' => ["professors" => $allProf, "formations" => $allFormations, "UEs" => $allUE ] ]; diff --git a/build/database/repo/category.php b/build/database/repo/category.php new file mode 100644 index 0000000..6dc2210 --- /dev/null +++ b/build/database/repo/category.php @@ -0,0 +1,34 @@ +pdo->prepare("INSERT INTO Categorie (idCategorie, labelCategorie) VALUES (:id, :label) ON DUPLICATE KEY UPDATE labelCategorie = :label;"); + + $st->execute([ + "id" => $id, + "label" => $label + ]); + } + + public function delete(int $id) :bool{ + $st = $this->pdo->prepare("DELETE FROM Categorie WHERE idCategorie = :id"); + + return $st->execute([ + "id" => $id + ]); + } + +} \ No newline at end of file diff --git a/build/database/repo/cours.php b/build/database/repo/cours.php new file mode 100644 index 0000000..c9d6290 --- /dev/null +++ b/build/database/repo/cours.php @@ -0,0 +1,87 @@ +pdo->prepare("INSERT INTO Cours(UE_code, Professeur_idProfesseur, volume) + VALUE(:UE, :idProf, :vol)"); + $st->execute([ + "UE" => $codeUE, + "idProf" => $idProf, + "vol" => $volume + ]); + + $idCours = $this->pdo->lastInsertId(); + + //if there is formations, link them with the group + if(count($formations) > 0){ + $linkSt = $this->pdo->prepare("INSERT INTO GroupeCours(Formation_idFormation, Cours_idCours) + VALUE (:form, :cours)"); + foreach ($formations as $form){ + $linkSt->execute([ + "form" => $form, + "cours" => $idCours + ]); + } + } + + return $idCours; + + } + + public function unlinkFormation(int $idFormation, int $idCours) : bool{ + $st = $this->pdo->prepare("DELETE FROM GroupeCours WHERE Cours_idCours = :cours AND Formation_idFormation = :form"); + + return $st->execute([ + "cours" => $idCours, + "form" => $idFormation + ]); + } + + public function linkFormation(int $idFormation, int $idCours) : bool{ + $st = $this->pdo->prepare("INSERT INTO GroupeCours(Cours_idCours,Formation_idFormation) + VALUE(:cours, :form)"); + + return $st->execute([ + "cours" => $idCours, + "form" => $idFormation + ]); + } + + public function updateProf(?int $prof) : bool { + $st = $this->pdo->prepare("UPDATE Cours SET Professeur_idProfesseur = :prof"); + + return $st->execute([ + "prof" => $prof + ]); + } + + public function updateVolume(float $volume) : bool { + $st = $this->pdo->prepare("UPDATE Cours SET volume = :vol"); + + return $st->execute([ + "vol" => $volume + ]); + } + + public function delete(int $id) :bool { + $st = $this->pdo->prepare("DELETE FROM Cours WHERE idCours = :id"); + + return $st->execute([ + "id" => $id + ]); + } + +} \ No newline at end of file diff --git a/build/database/repo/formation.php b/build/database/repo/formation.php new file mode 100644 index 0000000..8396ef5 --- /dev/null +++ b/build/database/repo/formation.php @@ -0,0 +1,45 @@ +pdo->prepare("INSERT INTO Formation (labelFormation, isInternal) VALUE (:label,:isInternal);"); + + $st->execute([ + "label" => $label, + "isInternal" => $isInternal? 1 : 0 + ]); + + return $this->pdo->lastInsertId(); + } + + public function exists(string $label) : int{ + $st = $this->pdo->prepare("SELECT idFormation FROM Formation WHERE labelFormation = :label"); + + $st->execute([ + "label" => $label + ]); + + return $st->fetch()["idFormation"]?: 0; + } + + public function delete(int $id) : bool{ + $st = $this->pdo->prepare("DELETE FROM Formation WHERE idFormation = :id"); + + return $st->execute([ + "id" => $id + ]); + } + +} \ No newline at end of file diff --git a/build/database/repo/professor.php b/build/database/repo/professor.php new file mode 100644 index 0000000..433d58d --- /dev/null +++ b/build/database/repo/professor.php @@ -0,0 +1,89 @@ +pdo->prepare("INSERT INTO Professeur (casLogin, lastName, firstName, abreviation, admin,hoursToDo, Categorie_idCategorie) + VALUE (:casLogin, :lastName, :firstName, :abrev, :admin, :hoursToDo, :cat); + "); + + $st->execute([ + "casLogin" => $casLogin, + "lastName" => $lastName, + "firstName" => $firstName, + "abrev" => $initials, + "admin" => $isAdmin? 1 : 0, + "hoursToDo" => $hoursToDo, + "cat" => $category + ]); + + return $this->pdo->lastInsertId(); + } + + public function exists(string $lastName, string $firstName) : int{ + $st = $this->pdo->prepare("SELECT idProfesseur FROM Professeur WHERE firstName = :firstName AND lastName = :lastName"); + + $st->execute([ + "firstName" => $firstName, + "lastName" => $lastName + ]); + + return $st->fetch()["idProfesseur"]?: 0; + } + + public function update(int $id, array $data) : bool{ + $updSt = ""; + + foreach ($data as $key => $field){ + $updSt .= "$key = :$key,"; + } + + $updSt = rtrim($updSt,","); + + $st = $this->pdo->prepare("UPDATE Professeur SET $updSt WHERE idProfesseur = :id"); + + return $st->execute(array_merge($data,[ + "id" => $id + ])); + } + + public function isAdmin(int $id) : bool{ + $st = $this->pdo->prepare("SELECT admin FROM Professeur WHERE idProfesseur = :id"); + + $st->execute([ + "id" => $id + ]); + + return $st->fetch()["admin"] == 1; + } + + public function get(int $id) : array{ + $st = $this->pdo->prepare("SELECT * FROM Professeur WHERE idProfesseur = :id"); + + $st->execute([ + "id" => $id + ]); + + return $st->fetch(); + } + + public function delete(int $id) : bool{ + $st = $this->pdo->prepare("DELETE FROM Professeur WHERE idProfesseur = :id"); + + return $st->execute([ + "id" => $id + ]); + } + +} \ No newline at end of file diff --git a/build/database/repo/td.php b/build/database/repo/td.php new file mode 100644 index 0000000..03f70e8 --- /dev/null +++ b/build/database/repo/td.php @@ -0,0 +1,88 @@ +pdo->prepare("INSERT INTO TD(UE_code, Professeur_idProfesseur, volume) + VALUE(:UE, :idProf, :vol)"); + + $st->execute([ + "UE" => $codeUE, + "idProf" => $idProf, + "vol" => $volume + ]); + + $idTD = $this->pdo->lastInsertId(); + + //if there is formations, link them with the group + if(count($formations) > 0){ + $linkSt = $this->pdo->prepare("INSERT INTO GroupeTD(Formation_idFormation, TD_idTD) + VALUE (:form, :TD)"); + foreach ($formations as $form){ + $linkSt->execute([ + "form" => $form, + "TD" => $idTD + ]); + } + } + + return $idTD; + + } + + public function unlinkFormation(int $idFormation, int $idTD) : bool{ + $st = $this->pdo->prepare("DELETE FROM GroupeTD WHERE TD_idTD = :TD AND Formation_idFormation = :form"); + + return $st->execute([ + "TD" => $idTD, + "form" => $idFormation + ]); + } + + public function linkFormation(int $idFormation, int $idTD) : bool{ + $st = $this->pdo->prepare("INSERT INTO GroupeTD(TD_idTD,Formation_idFormation) + VALUE(:TD, :form)"); + + return $st->execute([ + "TD" => $idTD, + "form" => $idFormation + ]); + } + + public function updateProf(?int $prof) : bool { + $st = $this->pdo->prepare("UPDATE TD SET Professeur_idProfesseur = :prof"); + + return $st->execute([ + "prof" => $prof + ]); + } + + public function updateVolume(float $volume) : bool { + $st = $this->pdo->prepare("UPDATE TD SET volume = :vol"); + + return $st->execute([ + "vol" => $volume + ]); + } + + public function delete(int $id) :bool { + $st = $this->pdo->prepare("DELETE FROM TD WHERE idTD = :id"); + + return $st->execute([ + "id" => $id + ]); + } + +} \ No newline at end of file diff --git a/build/database/repo/tp.php b/build/database/repo/tp.php new file mode 100644 index 0000000..0cb1d2c --- /dev/null +++ b/build/database/repo/tp.php @@ -0,0 +1,87 @@ +pdo->prepare("INSERT INTO TP(UE_code, Professeur_idProfesseur, volume) + VALUE(:UE, :idProf, :vol)"); + $st->execute([ + "UE" => $codeUE, + "idProf" => $idProf, + "vol" => $volume + ]); + + $idTP = $this->pdo->lastInsertId(); + + //if there is formations, link them with the group + if(count($formations) > 0){ + $linkSt = $this->pdo->prepare("INSERT INTO GroupeTP(Formation_idFormation, TP_idTP) + VALUE (:form, :TP)"); + foreach ($formations as $form){ + $linkSt->execute([ + "form" => $form, + "TP" => $idTP + ]); + } + } + + return $idTP; + + } + + public function unlinkFormation(int $idFormation, int $idTP) : bool{ + $st = $this->pdo->prepare("DELETE FROM GroupeTP WHERE TP_idTP = :TP AND Formation_idFormation = :form"); + + return $st->execute([ + "TP" => $idTP, + "form" => $idFormation + ]); + } + + public function linkFormation(int $idFormation, int $idTP) : bool{ + $st = $this->pdo->prepare("INSERT INTO GroupeTP(TP_idTP,Formation_idFormation) + VALUE(:TP, :form)"); + + return $st->execute([ + "TP" => $idTP, + "form" => $idFormation + ]); + } + + public function updateProf(?int $prof) : bool { + $st = $this->pdo->prepare("UPDATE TP SET Professeur_idProfesseur = :prof"); + + return $st->execute([ + "prof" => $prof + ]); + } + + public function updateVolume(float $volume) : bool { + $st = $this->pdo->prepare("UPDATE TP SET volume = :vol"); + + return $st->execute([ + "vol" => $volume + ]); + } + + public function delete(int $id) :bool { + $st = $this->pdo->prepare("DELETE FROM TP WHERE idTP = :id"); + + return $st->execute([ + "id" => $id + ]); + } + +} \ No newline at end of file diff --git a/build/database/repo/ue.php b/build/database/repo/ue.php new file mode 100644 index 0000000..4b3407b --- /dev/null +++ b/build/database/repo/ue.php @@ -0,0 +1,64 @@ +pdo->prepare("INSERT INTO UE(code, label, required, volumeCours, volumeTD, volumeTP, disabled) + VALUE(:code, :label, :required, :volCours, :volTD, :volTP, :disabled) "); + + $st->execute([ + "code" => $code, + "label" => $label, + "required" => $required ? 1 : 0, + "volCours" => $volumeCours, + "volTD" => $volumeTD, + "volTP" => $volumeTP, + "disabled" => $disabled ? 1 : 0 + ]); + + return $this->pdo->lastInsertId(); + } + + public function update(string $code, array $data) : bool{ + $updSt = ""; + + foreach ($data as $key => $field){ + $updSt .= "$key = :$key,"; + } + + $updSt = rtrim($updSt,","); + + $st = $this->pdo->prepare("UPDATE UE SET $updSt WHERE code = :code"); + + return $st->execute(array_merge($data,[ + "code" => $code + ])); + } + + public function delete(string $code) : bool { + $st = $this->pdo->prepare("DELETE FROM UE WHERE code = :code"); + + return $st->execute([ + "code" => $code + ]); + } + + public function disable(string $code) : bool { + return $this->update($code, ["disabled" => 1]); + } + + public function enable(string $code) : bool { + return $this->update($code, ["disabled" => 0]); + } +} \ No newline at end of file diff --git a/build/database/repo/user.php b/build/database/repo/user.php deleted file mode 100644 index 5223588..0000000 --- a/build/database/repo/user.php +++ /dev/null @@ -1,250 +0,0 @@ - The user list - * FALSE on error - * - ---------------------------------------------------------*/ - public function getAll(){ - - /* (1) Statement */ - $st = $this->pdo->query("SELECT * FROM `user` ORDER BY `username` ASC"); - - /* (2) Fetched data */ - return $st->fetchAll(); - - } - - - /* (2) Return a user by its `id_user` - * - * @id_user The user UID - * - * @return user The user if found - * FALSE on error - * - ---------------------------------------------------------*/ - public function getById(int $id_user){ - - /* (1) Prepare Statement */ - $pst = $this->pdo->prepare("SELECT * FROM `user` WHERE `id_user` = :id_user LIMIT 1"); - - /* (2) Bind variables */ - $pst->bindParam(':id_user', $id_user, \PDO::PARAM_INT); - - /* (3) Execute */ - if( !$pst->execute() ) return false; // if error -> send FALSE - - /* (4) Fetched data */ - return $pst->fetch(); - - } - - - /* (3) Return a user by its `mail` - * - * @mail The user mail address - * - * @return user The user if found - * FALSE on error - * - ---------------------------------------------------------*/ - public function getByMail(String $mail){ - - /* (1) Prepare Statement */ - $pst = $this->pdo->prepare("SELECT * FROM `user` WHERE `mail` = :mail LIMIT 1"); - - /* (2) Bind variables */ - $pst->bindParam(':mail', $mail, \PDO::PARAM_STR, 50); - - /* (3) Execute */ - if( !$pst->execute() ) return false; // if error -> send FALSE - - /* (4) Fetched data */ - return $pst->fetch(); - - } - - - /* (4) Return a user by its `username` - * - * @username The user username - * - * @return user The user if found - * FALSE on error - * - ---------------------------------------------------------*/ - public function getByUsername(String $username){ - - /* (1) Prepare Statement */ - $pst = $this->pdo->prepare("SELECT * FROM `user` WHERE `username` = :username LIMIT 1"); - - /* (2) Bind variables */ - $pst->bindParam(':username', $username, \PDO::PARAM_STR, 20); - - /* (3) Execute */ - if( !$pst->execute() ) return false; // if error -> send FALSE - - /* (4) Fetched data */ - return $pst->fetch(); - - } - - - /* (5) Return a user by its `token` - * - * @token The user token - * - * @return user The user if found - * FALSE on error - * - ---------------------------------------------------------*/ - public function getByToken(String $token){ - - /* (1) Prepare Statement */ - $pst = $this->pdo->prepare("SELECT * FROM `user` WHERE `token` is not NULL AND `token` = :token LIMIT 1"); - - /* (2) Bind variables */ - $pst->bindParam(':token', $token, \PDO::PARAM_STR, 128); - - /* (3) Execute */ - if( !$pst->execute() ) return false; // if error -> send FALSE - - /* (4) Fetched data */ - return $pst->fetch(); - - } - - - /* (6) Check the password of a user - * - * @id_user The user UID - * @password The password to test - * - * @return valid Whether the password is valid or not - * - ---------------------------------------------------------*/ - public function checkPassword(int $id_user, String $password){ - - /* (1) Hash the password */ - $hash = \secure_hash($password, $id_user, 'user-pass'); - - /* (2) Prepare Statement */ - $pst = $this->pdo->prepare("SELECT * FROM `user` WHERE `id_user` = :id_user AND `pass` = :pass LIMIT 1"); - - /* (3) Bind variables */ - $pst->bindParam(':id_user', $id_user, \PDO::PARAM_INT); - $pst->bindParam(':pass', $hash, \PDO::PARAM_STR, 128); - - /* (4) Execute */ - if( !$pst->execute() ) return false; // if error -> send FALSE - - /* (5) If no data -> means invalid password */ - if( !is_array($pst->fetch()) ) - return false; - - /* (6) If here -> means password is ok */ - return true; - - } - - - /* (6) Set the password for a user - * - * @id_user The user UID - * @password The password to set - * - * @return set Whether the password has been set or not - * - ---------------------------------------------------------*/ - public function setPassword(int $id_user, String $password){ - - /* (1) Hash the password */ - $hash = \secure_hash($password, $id_user, 'user-pass'); - - /* (2) Prepare Statement */ - $pst = $this->pdo->prepare("UPDATE `user` SET `pass` = :pass WHERE `id_user` = :id_user"); - - /* (3) Bind variables */ - $pst->bindParam(':pass', $hash, \PDO::PARAM_STR, 128); - $pst->bindParam(':id_user', $id_user, \PDO::PARAM_INT); - - /* (4) Execute -> dispatch status */ - return $pst->execute(); - - } - - /* (7) Creates a new user - * - * @username The username (must be unique) - * @mail The mail address (must be unique) - * @password The password - * - * @return id_created UID of the created user - * FALSE on error - * - ---------------------------------------------------------*/ - public function create(String $username, String $mail, String $password){ - - - /* (1) Check @username + @mail are unique - ---------------------------------------------------------*/ - /* (1) If @username already exists -> abort */ - if( is_array($this->getByUsername($username)) ) - return false; - - /* (2) If @mail already exists -> abort */ - if( is_array($this->getByMail($mail)) ) - return false; - - - - /* (2) Create the user (without password) - ---------------------------------------------------------*/ - /* (1) Create a random token */ - $token = \secure_hash(uniqid(), 'user-token'); - - /* (2) Prepare Statement */ - $pst = $this->pdo->prepare("INSERT INTO `user`(`id_user`, `username`, `mail`, `pass`, `token`) VALUES(DEFAULT, :username, :mail, NULL, :token)"); - - /* (3) Bind variables */ - $pst->bindParam(':username', $username, \PDO::PARAM_STR, 20); - $pst->bindParam(':mail', $mail, \PDO::PARAM_STR, 50); - $pst->bindParam(':token', $token, \PDO::PARAM_STR, 128); - - /* (4) Execute -> if error return FALSE */ - if( !$pst->execute() ) return false; - - - /* (2) Set the password (needed @id_user) - ---------------------------------------------------------*/ - /* (1) Get last inserted id */ - $fetch_user = $this->getByUsername($username); - - /* (2) If nothing found -> error */ - if( !is_array($fetch_user) || !isset($fetch_user['id_user']) || !is_numeric($fetch_user['id_user']) ) - return false; - - /* (3) Extract @id_user */ - $id_user = intval($fetch_user['id_user']); - - /* (4) Repo self call */ - if( !$this->setPassword($id_user, $password) ) - return false; - - /* (5) Return @id_user */ - return $id_user; - - } - - - - - } \ No newline at end of file diff --git a/composer.json b/composer.json index e26b2de..b11b7ca 100644 --- a/composer.json +++ b/composer.json @@ -25,6 +25,7 @@ "files": ["autoloader.php"] }, "require": { - "phpoffice/phpspreadsheet": "^1.1" + "phpoffice/phpspreadsheet": "^1.1", + "phpstan/phpstan": "^0.9.2" } } diff --git a/composer.lock b/composer.lock index 3ece352..b860bbe 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,623 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "1e36e5a5313eb5645d060a32fb93ac57", + "content-hash": "18a1824304295027ad9aa6050280670b", "packages": [ + { + "name": "jean85/pretty-package-versions", + "version": "1.1", + "source": { + "type": "git", + "url": "https://github.com/Jean85/pretty-package-versions.git", + "reference": "d457344b6a035ef99236bdda4729ad7eeb233f54" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/d457344b6a035ef99236bdda4729ad7eeb233f54", + "reference": "d457344b6a035ef99236bdda4729ad7eeb233f54", + "shasum": "" + }, + "require": { + "ocramius/package-versions": "^1.2.0", + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Jean85\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alessandro Lai", + "email": "alessandro.lai85@gmail.com" + } + ], + "description": "A wrapper for ocramius/pretty-package-versions to get pretty versions strings", + "keywords": [ + "composer", + "package", + "release", + "versions" + ], + "time": "2018-01-21T13:54:22+00:00" + }, + { + "name": "nette/bootstrap", + "version": "v2.4.5", + "source": { + "type": "git", + "url": "https://github.com/nette/bootstrap.git", + "reference": "804925787764d708a7782ea0d9382a310bb21968" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/bootstrap/zipball/804925787764d708a7782ea0d9382a310bb21968", + "reference": "804925787764d708a7782ea0d9382a310bb21968", + "shasum": "" + }, + "require": { + "nette/di": "~2.4.7", + "nette/utils": "~2.4", + "php": ">=5.6.0" + }, + "conflict": { + "nette/nette": "<2.2" + }, + "require-dev": { + "latte/latte": "~2.2", + "nette/application": "~2.3", + "nette/caching": "~2.3", + "nette/database": "~2.3", + "nette/forms": "~2.3", + "nette/http": "~2.4.0", + "nette/mail": "~2.3", + "nette/robot-loader": "^2.4.2 || ^3.0", + "nette/safe-stream": "~2.2", + "nette/security": "~2.3", + "nette/tester": "~2.0", + "tracy/tracy": "^2.4.1" + }, + "suggest": { + "nette/robot-loader": "to use Configurator::createRobotLoader()", + "tracy/tracy": "to use Configurator::enableTracy()" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🅱 Nette Bootstrap: the simple way to configure and bootstrap your Nette application.", + "homepage": "https://nette.org", + "keywords": [ + "bootstrapping", + "configurator", + "nette" + ], + "time": "2017-08-20T17:36:59+00:00" + }, + { + "name": "nette/di", + "version": "v2.4.10", + "source": { + "type": "git", + "url": "https://github.com/nette/di.git", + "reference": "a4b3be935b755f23aebea1ce33d7e3c832cdff98" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/di/zipball/a4b3be935b755f23aebea1ce33d7e3c832cdff98", + "reference": "a4b3be935b755f23aebea1ce33d7e3c832cdff98", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "nette/neon": "^2.3.3 || ~3.0.0", + "nette/php-generator": "^2.6.1 || ~3.0.0", + "nette/utils": "^2.4.3 || ~3.0.0", + "php": ">=5.6.0" + }, + "conflict": { + "nette/bootstrap": "<2.4", + "nette/nette": "<2.2" + }, + "require-dev": { + "nette/tester": "^2.0", + "tracy/tracy": "^2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "💎 Nette Dependency Injection Container: Flexible, compiled and full-featured DIC with perfectly usable autowiring and support for all new PHP 7.1 features.", + "homepage": "https://nette.org", + "keywords": [ + "compiled", + "di", + "dic", + "factory", + "ioc", + "nette", + "static" + ], + "time": "2017-08-31T22:42:00+00:00" + }, + { + "name": "nette/finder", + "version": "v2.4.1", + "source": { + "type": "git", + "url": "https://github.com/nette/finder.git", + "reference": "4d43a66d072c57d585bf08a3ef68d3587f7e9547" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/finder/zipball/4d43a66d072c57d585bf08a3ef68d3587f7e9547", + "reference": "4d43a66d072c57d585bf08a3ef68d3587f7e9547", + "shasum": "" + }, + "require": { + "nette/utils": "^2.4 || ~3.0.0", + "php": ">=5.6.0" + }, + "conflict": { + "nette/nette": "<2.2" + }, + "require-dev": { + "nette/tester": "^2.0", + "tracy/tracy": "^2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "Nette Finder: Files Searching", + "homepage": "https://nette.org", + "time": "2017-07-10T23:47:08+00:00" + }, + { + "name": "nette/neon", + "version": "v2.4.2", + "source": { + "type": "git", + "url": "https://github.com/nette/neon.git", + "reference": "9eacd50553b26b53a3977bfb2fea2166d4331622" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/neon/zipball/9eacd50553b26b53a3977bfb2fea2166d4331622", + "reference": "9eacd50553b26b53a3977bfb2fea2166d4331622", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "ext-json": "*", + "php": ">=5.6.0" + }, + "require-dev": { + "nette/tester": "~2.0", + "tracy/tracy": "^2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "Nette NEON: parser & generator for Nette Object Notation", + "homepage": "http://ne-on.org", + "time": "2017-07-11T18:29:08+00:00" + }, + { + "name": "nette/php-generator", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/nette/php-generator.git", + "reference": "1652635d312a8db4291b16f3ebf87cb1a15a6257" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/php-generator/zipball/1652635d312a8db4291b16f3ebf87cb1a15a6257", + "reference": "1652635d312a8db4291b16f3ebf87cb1a15a6257", + "shasum": "" + }, + "require": { + "nette/utils": "^2.4.2 || ~3.0.0", + "php": ">=7.0" + }, + "conflict": { + "nette/nette": "<2.2" + }, + "require-dev": { + "nette/tester": "^2.0", + "tracy/tracy": "^2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🐘 Nette PHP Generator: generates neat PHP code for you. Supports new PHP 7.2 features.", + "homepage": "https://nette.org", + "keywords": [ + "code", + "nette", + "php", + "scaffolding" + ], + "time": "2017-09-26T11:19:32+00:00" + }, + { + "name": "nette/robot-loader", + "version": "v3.0.3", + "source": { + "type": "git", + "url": "https://github.com/nette/robot-loader.git", + "reference": "92d4b40b49d5e2d9e37fc736bbcebe6da55fa44a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/robot-loader/zipball/92d4b40b49d5e2d9e37fc736bbcebe6da55fa44a", + "reference": "92d4b40b49d5e2d9e37fc736bbcebe6da55fa44a", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "nette/finder": "^2.3 || ^3.0", + "nette/utils": "^2.4 || ^3.0", + "php": ">=5.6.0" + }, + "conflict": { + "nette/nette": "<2.2" + }, + "require-dev": { + "nette/tester": "^2.0", + "tracy/tracy": "^2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🍀 Nette RobotLoader: high performance and comfortable autoloader that will search and autoload classes within your application.", + "homepage": "https://nette.org", + "keywords": [ + "autoload", + "class", + "interface", + "nette", + "trait" + ], + "time": "2017-09-26T13:42:21+00:00" + }, + { + "name": "nette/utils", + "version": "v2.5.1", + "source": { + "type": "git", + "url": "https://github.com/nette/utils.git", + "reference": "8a85ce76298c8a8941f912b8fa3ee93ca17d2ebc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/utils/zipball/8a85ce76298c8a8941f912b8fa3ee93ca17d2ebc", + "reference": "8a85ce76298c8a8941f912b8fa3ee93ca17d2ebc", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "conflict": { + "nette/nette": "<2.2" + }, + "require-dev": { + "nette/tester": "~2.0", + "tracy/tracy": "^2.3" + }, + "suggest": { + "ext-gd": "to use Image", + "ext-iconv": "to use Strings::webalize() and toAscii()", + "ext-intl": "for script transliteration in Strings::webalize() and toAscii()", + "ext-json": "to use Nette\\Utils\\Json", + "ext-mbstring": "to use Strings::lower() etc...", + "ext-xml": "to use Strings::length() etc. when mbstring is not available" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ], + "files": [ + "src/loader.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", + "homepage": "https://nette.org", + "keywords": [ + "array", + "core", + "datetime", + "images", + "json", + "nette", + "paginator", + "password", + "slugify", + "string", + "unicode", + "utf-8", + "utility", + "validation" + ], + "time": "2018-02-19T14:42:42+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v3.1.4", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "e57b3a09784f846411aa7ed664eedb73e3399078" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/e57b3a09784f846411aa7ed664eedb73e3399078", + "reference": "e57b3a09784f846411aa7ed664eedb73e3399078", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "~4.0|~5.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "time": "2018-01-25T21:31:33+00:00" + }, + { + "name": "ocramius/package-versions", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/Ocramius/PackageVersions.git", + "reference": "4489d5002c49d55576fa0ba786f42dbb009be46f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Ocramius/PackageVersions/zipball/4489d5002c49d55576fa0ba786f42dbb009be46f", + "reference": "4489d5002c49d55576fa0ba786f42dbb009be46f", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0.0", + "php": "^7.1.0" + }, + "require-dev": { + "composer/composer": "^1.6.3", + "ext-zip": "*", + "infection/infection": "^0.7.1", + "phpunit/phpunit": "^7.0.0" + }, + "type": "composer-plugin", + "extra": { + "class": "PackageVersions\\Installer", + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "PackageVersions\\": "src/PackageVersions" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", + "time": "2018-02-05T13:05:30+00:00" + }, { "name": "phpoffice/phpspreadsheet", "version": "1.1.0", @@ -94,6 +709,114 @@ ], "time": "2018-01-28T12:37:15+00:00" }, + { + "name": "phpstan/phpdoc-parser", + "version": "0.2", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "02f909f134fe06f0cd4790d8627ee24efbe84d6a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/02f909f134fe06f0cd4790d8627ee24efbe84d6a", + "reference": "02f909f134fe06f0cd4790d8627ee24efbe84d6a", + "shasum": "" + }, + "require": { + "php": "~7.0" + }, + "require-dev": { + "consistence/coding-standard": "^2.0.0", + "jakub-onderka/php-parallel-lint": "^0.9.2", + "phing/phing": "^2.16.0", + "phpstan/phpstan": "^0.9", + "phpunit/phpunit": "^6.3", + "slevomat/coding-standard": "^3.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.1-dev" + } + }, + "autoload": { + "psr-4": { + "PHPStan\\PhpDocParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", + "time": "2018-01-13T18:19:41+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "0.9.2", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "e59541bcc7cac9b35ca54db6365bf377baf4a488" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/e59541bcc7cac9b35ca54db6365bf377baf4a488", + "reference": "e59541bcc7cac9b35ca54db6365bf377baf4a488", + "shasum": "" + }, + "require": { + "jean85/pretty-package-versions": "^1.0.3", + "nette/bootstrap": "^2.4 || ^3.0", + "nette/di": "^2.4.7 || ^3.0", + "nette/robot-loader": "^3.0.1", + "nette/utils": "^2.4.5 || ^3.0", + "nikic/php-parser": "^3.1", + "php": "~7.0", + "phpstan/phpdoc-parser": "^0.2", + "symfony/console": "~3.2 || ~4.0", + "symfony/finder": "~3.2 || ~4.0" + }, + "require-dev": { + "consistence/coding-standard": "2.2.1", + "ext-gd": "*", + "ext-intl": "*", + "ext-mysqli": "*", + "jakub-onderka/php-parallel-lint": "^0.9.2", + "phing/phing": "^2.16.0", + "phpstan/phpstan-php-parser": "^0.9", + "phpstan/phpstan-phpunit": "^0.9.3", + "phpstan/phpstan-strict-rules": "^0.9", + "phpunit/phpunit": "^6.5.4", + "slevomat/coding-standard": "4.0.0" + }, + "bin": [ + "bin/phpstan" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.9-dev" + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": [ + "src/", + "build/PHPStan" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "time": "2018-01-28T13:22:19+00:00" + }, { "name": "psr/simple-cache", "version": "1.0.0", @@ -141,6 +864,182 @@ "simple-cache" ], "time": "2017-01-02T13:31:39+00:00" + }, + { + "name": "symfony/console", + "version": "v4.0.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "36d5b41e7d4e1ccf0370f6babe966c08ef0a1488" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/36d5b41e7d4e1ccf0370f6babe966c08ef0a1488", + "reference": "36d5b41e7d4e1ccf0370f6babe966c08ef0a1488", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/dependency-injection": "<3.4", + "symfony/process": "<3.3" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~3.4|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/event-dispatcher": "~3.4|~4.0", + "symfony/lock": "~3.4|~4.0", + "symfony/process": "~3.4|~4.0" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/lock": "", + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Console Component", + "homepage": "https://symfony.com", + "time": "2018-01-29T09:06:29+00:00" + }, + { + "name": "symfony/finder", + "version": "v4.0.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "8b08180f2b7ccb41062366b9ad91fbc4f1af8601" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/8b08180f2b7ccb41062366b9ad91fbc4f1af8601", + "reference": "8b08180f2b7ccb41062366b9ad91fbc4f1af8601", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Finder Component", + "homepage": "https://symfony.com", + "time": "2018-01-03T07:38:00+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.7.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "78be803ce01e55d3491c1397cf1c64beb9c1b63b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/78be803ce01e55d3491c1397cf1c64beb9c1b63b", + "reference": "78be803ce01e55d3491c1397cf1c64beb9c1b63b", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "time": "2018-01-30T19:27:44+00:00" } ], "packages-dev": [],