diff --git a/TP6/controller/ControleurObjet.php b/TP6/controller/ControleurObjet.php index 4f71ed4ba970788a2b70e747916930f72c8d0097..a44387bb888653202f5616c34926aef600a3c5e3 100644 --- a/TP6/controller/ControleurObjet.php +++ b/TP6/controller/ControleurObjet.php @@ -1,10 +1,5 @@ <?php -/** - * Désolé mais le TP5 est une mauvaise idée de bout en bout. - * Je me suis arrêté à l'ex 2 car je ne vois pas comment on pourrait aisément rassembler tous les contrôleurs ici - * étant donné que le contenu diffère légèrement selon les modèles. - */ class ControleurObjet { public static function lireObjets() : string @@ -15,9 +10,28 @@ class ControleurObjet public static function creerObjet() : string { - return view('formulaire-creation-auteur', [ - 'pageTitle' => 'Créer un auteur', - 'insertMessage' => $insertMessage + $createdObject = []; + // Si reçoie une requête POST pour créer un objet et qu'on a plus d'une entrée + if(!empty($_POST["objectName"]) && count($_POST) > 1){ + $columns = []; + foreach ($_POST as $index => $value){ + if(!in_array($index, ["action", "objectName"])){ + $columns[$index] = $value; + } + } + + $createdObject = Objet::addObject($_POST["objectName"], $columns); + if($createdObject["status"] === "fail"){ + $createdObject["status"] = "danger"; // Pour le style Bootstrap + } + } + if(!empty($_GET["describeTable"])){ + return json_encode(Objet::describeObject($_GET["describeTable"])); + } + + return view('formulaire-creation-objet', [ + 'pageTitle' => 'Créer un objet', + 'insertMessage' => $createdObject ]); } } \ No newline at end of file diff --git a/TP6/index.php b/TP6/index.php index 1463542eafae2e4be24bda999b48b85b957f4e04..b67a879a97d4d3f0aed164e39ef40c0517e9d72f 100644 --- a/TP6/index.php +++ b/TP6/index.php @@ -15,32 +15,19 @@ require_once("controller/ControleurLivre.php"); Database::connect(); -if (empty($_GET["action"])) { +if (empty($_REQUEST["action"])) { echo ControleurAuteur::lireAuteurs(); } else { - // Test TP 5 - if ($_GET["action"] === "lireObjets" && !empty($_GET["objet"])) { - switch ($_GET["objet"]){ - case 'Auteur': - echo ControleurAuteur::lireObjets(); - break; - default: - echo ControleurAuteur::lireObjets(); - break; - } - } - // Fin test TP5 - // C'est plus long que get_class_methods mais c'est moins sujet à problèmes. - switch ($_GET["action"]){ + switch ($_REQUEST["action"]){ case "lireAuteur": echo ControleurAuteur::lireAuteur(); break; case "lireAuteurs": echo ControleurAuteur::lireAuteurs(); break; - case "creerAuteur": - echo ControleurAuteur::creerAuteur(); + case "creerObjet": + echo ControleurObjet::creerObjet(); break; case "lireAdherent": echo ControleurAdherent::lireAdherent(); diff --git a/TP6/models/Auteur.php b/TP6/models/Auteur.php index a45a0403844c3defb156fbac47c1f54666444bd3..da14485a82ed2d45d2461cb9b2c81c4c9d66bede 100644 --- a/TP6/models/Auteur.php +++ b/TP6/models/Auteur.php @@ -62,19 +62,5 @@ class Auteur extends Objet { return "<p>auteur $this->prenom $this->nom, né(e) en $this->anneeNaissance </p>"; } - - public static function addAuteur($nom, $prenom, $anneeNaissance){ - $query = Database::pdo()->prepare("INSERT INTO Auteur(nom, prenom, anneeNaissance) VALUES (:nom, :prenom, :anneeNaissance)"); - try{ - $query->execute([ - "nom" => $nom, - "prenom" => $prenom, - "anneeNaissance" => $anneeNaissance - ]); - return "success"; - } catch (PDOException $e){ - return $e; - } - } } diff --git a/TP6/models/Objet.php b/TP6/models/Objet.php index 24a0740a7a7d4e4bf243b67492285e036147a157..f770e2b8cf6d77b2b1f9b6d8e944f4de73272a27 100644 --- a/TP6/models/Objet.php +++ b/TP6/models/Objet.php @@ -39,10 +39,10 @@ class Objet * @param array $columns * @return array|string[] */ - public static function insertInDatabase(String $tableName, array $columns) : array + public static function addObject(String $tableName, array $columns) : array { - $result["status"] = "sucess"; - $result["message"] = "Insertion réussie."; + $result["status"] = "success"; + $result["message"] = "Insertion réussie"; // On va vérifier que $tableName est bien en format alphanumérique if(!isAlphaNumeric($tableName)){ @@ -92,4 +92,36 @@ class Objet return $result; } + + /** + * Permet de décrire une table représentant un objet. + * @param $tableName + * @return array + */ + public static function describeObject($tableName) : array + { + if(!isAlphaNumeric($tableName)){ + return [ + "status" => "fail", + "message" => "Le format du nom de la table est incorrect.", + "columns" => [] + ]; + }else{ + try{ + $query = Database::pdo()->query("DESCRIBE {$tableName}"); + $columns = $query->fetchAll(PDO::FETCH_ASSOC); + } catch (PDOException $e) { + return [ + "status" => "fail", + "message" => $e->getMessage(), + "columns" => [] + ]; + } + + return [ + "status" => "success", + "columns" => $columns + ]; + } + } } \ No newline at end of file diff --git a/TP6/resources/views/components/navbar.php b/TP6/resources/views/components/navbar.php index e37a42bf412e9a1b404a035e3d446183a9030c77..33f52ea807b338ae6671a415d46888c868f7f378 100644 --- a/TP6/resources/views/components/navbar.php +++ b/TP6/resources/views/components/navbar.php @@ -18,7 +18,7 @@ <a class="nav-link" href="?action=lireLivres">Liste des livres</a> </li> <li class="nav-item"> - <a class="nav-link" href="?action=creerAuteur">Créer un auteur</a> + <a class="nav-link" href="?action=creerObjet">Créer un objet</a> </li> </ul> </div> diff --git a/TP6/resources/views/formulaire-creation-objet.php b/TP6/resources/views/formulaire-creation-objet.php index a2cfbc69d93074e81ae312b11f25fe5c28981051..60bc025d1762ff3892c0279f942b4384825f33e9 100644 --- a/TP6/resources/views/formulaire-creation-objet.php +++ b/TP6/resources/views/formulaire-creation-objet.php @@ -4,26 +4,123 @@ @section('content') <div class="container mt-3"> + <noscript> + <div class="alert alert-danger">L'activation de Javascript est nécessaire sur la page.</div> + </noscript> @if(!empty($insertMessage)) - <div class="alert alert-{{ $insertMessage["type"] }}" role="alert">{{ $insertMessage["text"] }}</div> + <div class="alert alert-{{ $insertMessage["status"] }}" role="alert"> + @if(!empty($insertMessage["pdoError"])) + <strong>{{ $insertMessage["message"] }}</strong> + <br>{{ $insertMessage["pdoError"] }} + @else + {{ $insertMessage["message"] }} + @endif + </div> @endif <h1>{{ $pageTitle }}</h1> - <form action="index.php" method="get" class="col-6"> - <input hidden name="action" value="creerAuteur"> - <div class="mb-3"> - <label class="form-label" for="nom">Nom</label> - <input class="form-control" type="text" name="nom" placeholder="nom" required> - </div> - <div class="mb-3"> - <label class="form-label" for="nom">Prénom</label> - <input class="form-control" type="text" name="prenom" placeholder="prenom" required> - </div> - <div class="mb-3"> - <label class="form-label" for="anneeNaissance">Année de naissance</label> - <input class="form-control" type="number" name="anneeNaissance" placeholder="Année de naissance" required> - </div> - <button type="submit" class="btn btn-primary">Créer</button> + + + <div class="col-6 border rounded bg-light p-2"> + <h5>Type d'objet à créer</h5> + <select id="objectType" class="form-select form-select-sm" aria-label=".form-select-sm example"> + <option value="dontchooseme" selected>Choisissez un objet dans la liste</option> + <option value="Auteur">Auteur (oui c'est triste mais on les considère comme tel dans le code :c)</option> + <option value="Adherent">Adhérent (est-ce surprenant du coup?)</option> + <option value="Livre">Livre</option> + </select> + </div> + <form action="index.php" method="post" class="col-6 mt-2" id="objectForm"> </form> </div> + +<script type="text/javascript"> + const objectForm = document.getElementById("objectForm"); + const selectObjectType = document.getElementById("objectType"); + selectObjectType.addEventListener('change', function (){ + if(selectObjectType.value !== 'dontchooseme') { + loadObjectTypeForm(selectObjectType.value); + } + }) + const typesList = { + "int" : "number", + "varchar" : "text", + "date" : "date" + }; + + async function loadObjectTypeForm(objectType){ + objectForm.innerHTML = ""; + + await fetch('?action=creerObjet&describeTable=' + objectType) + .then(res => res.json()) + .then((out) => { + console.log('Output: ', out); + + let objectName = document.createElement("input"); + objectName.name = "objectName"; + objectName.setAttribute("value", objectType); + objectName.hidden = true; + objectForm.appendChild(objectName); + + if(out.status === "success"){ + for(let i = 0; i < out.columns.length; i++){ + // On évite de proposer les clés primaires auto incrémentables + if(out.columns[i].Extra !== "auto_increment"){ + let columnType = out.columns[i].Type; + let match = columnType.match(/([a-z]*)/); + objectForm.appendChild( + createInputDiv( + typesList[match[1]], + out.columns[i].Field + ) + ); + } + } + }else{ + let errorAlert = document.createElement("div"); + errorAlert.classList.add("alert"); + errorAlert.classList.add("alert-danger"); + errorAlert.innerHTML = "<b>Erreur lors de la récupération des spécifications de l'objet " + objectType + "</b><br>" + out.message; + objectForm.appendChild(errorAlert); + } + }).catch(err => console.error(err)); + + let actionInput = document.createElement("input"); + actionInput.name = "action"; + actionInput.value = "creerObjet"; + actionInput.hidden = true; + + objectForm.appendChild(actionInput); + + let submitButton = document.createElement("button"); + submitButton.type = "submit"; + submitButton.classList.add("btn"); + submitButton.classList.add("btn-primary"); + submitButton.innerText = "Créer"; + + objectForm.appendChild(submitButton); + } + + function createInputDiv(type, name){ + let mainContainer = document.createElement("div"); + mainContainer.classList.add("mb-3"); + + let label = document.createElement("label"); + label.classList.add("form-label"); + label.setAttribute("for", name); + label.innerText = name; + + mainContainer.appendChild(label); + + let input = document.createElement("input"); + input.classList.add("form-control"); + input.type = type; + input.name = name; + input.required = true; + + mainContainer.appendChild(input); + + return mainContainer; + } +</script> @endsection \ No newline at end of file