From 85fc5278527c564c67c626c61f6dfa2f55db0abd Mon Sep 17 00:00:00 2001 From: vautrin33u <vautrin33u@etu.univ-lorraine.fr> Date: Wed, 22 Dec 2021 23:31:12 +0100 Subject: [PATCH] =?UTF-8?q?nouveaut=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Requete.php | 83 +++++++++++++++------------ Service.php | 85 ++++++++++++++++++++++++++-- connexion.php | 4 +- inscription.php | 8 +-- panier.js | 7 ++- panier.php | 5 +- recettes.css | 110 ++++++++++++++++++++++++++++++------ recettes.js | 6 +- suggestion.js | 146 +++++++++++++++++++++++++++++++++++++++++++----- 9 files changed, 372 insertions(+), 82 deletions(-) diff --git a/Requete.php b/Requete.php index 60de5ba..178f884 100644 --- a/Requete.php +++ b/Requete.php @@ -42,44 +42,55 @@ ?> - <div id='authentification'> - <form method="POST" id='authentification'> - <?php - if (isset($_SESSION['pseudo'])){ - $pseudonyme = ucfirst(strtolower($_SESSION['pseudo'])); - echo "<p id='bienvenue'> Bienvenue ".$pseudonyme."</p>"; - echo "<input type='submit' name='deconnecter' value='Déconnexion'/>"; - }else{ - echo "<input type='submit' name='connexion' value='Connexion'/>"; - echo "<input type='submit' name='inscription' value='Inscription'/>"; - } - echo "<input type='submit' name='panier' id='panier' value='Votre panier'/>"; - - ?> - </form> + <div id='header'> + <form method="POST" id='authentification'> + <?php + if (isset($_SESSION['pseudo'])){ + $pseudonyme = ucfirst(strtolower($_SESSION['pseudo'])); + echo "<p id='bienvenue'> Bienvenue ".$pseudonyme."</p>"; + echo "<input type='submit' name='deconnecter' value='Déconnexion'/>"; + }else{ + echo "<input type='submit' name='connexion' value='Connexion'/>"; + echo "<input type='submit' name='inscription' value='Inscription'/>"; + } + echo "<input type='submit' name='panier' id='panier' value='Votre panier'/>"; + + ?> + </form> + + <div id='recherche'> + <form method="post" id="form"> + <div id='fil'> + Entrez votre recherche : + <input list='listeNoms' type="text" id="requete" onkeyup="afficherSuggestions()"/> + </br> + <input type='button' id='pour' name='pour' value='Avec' onclick='inclureIngredient()'/> + <input type='button' id='contre' name='contre' value='Sans' onclick='exclureIngredient()'/> + <input type='button' id='filtre' value='Recherche via filtres' onclick='rechercheFiltres()' disabled/> + <div id='tags'> + <ul id='tagIn'></ul> + <ul id='tagOut'></ul> + </div> + </div> + + + + <div id='cat'> + Sélectionner : + <label for='categorie'></label><select name='categorie' id='categorie' onchange="optionsCategorie()" > + <option value='Aliment'></option> + <option value='Aliment'>Aliment</option> + </select> + + <button type="button" onclick="remettreAZero()">Remise à zéro</button> + </div> + <br/> + <div id="infos"></div> + </form> + </div> </div> - <form method="post" id="form"> - <fieldset id="fieldset"> - - Entrez votre recherche : - <input list='listeNoms' type="text" id="requete" onkeyup="afficherSuggestionsRecettes()"/> - - Sélectionner : - - <label for='categorie'></label><select name='categorie' id='categorie' onchange="optionsCategorie()" > - <option value='Aliment'></option> - <option value='Aliment'>Aliment</option> - </select> - - <button type="button" onclick="remettreAZero()">Remise à zéro</button> - - <br/> - </fieldset> - </form> - <div id="infos"> - - </div> + <div id="recettes"></div> diff --git a/Service.php b/Service.php index 5162e9b..8f1b435 100644 --- a/Service.php +++ b/Service.php @@ -9,8 +9,11 @@ session_start(); function queryDBB(string $str){ $mysqli= connect_to_db(); $res = $mysqli->query($str); - - $recettes = $res->fetch_all(MYSQLI_ASSOC); + if ($res != false){ + $recettes = $res->fetch_all(MYSQLI_ASSOC); + }else{ + $recettes = false; + } $mysqli->close(); return json_encode($recettes); } @@ -28,7 +31,9 @@ function realiseInscription ($json){ $pseudo = mysqli_real_escape_string ($mysqli, $json['pseudo']); $password = mysqli_real_escape_string ($mysqli, $json['password']); - $res = $mysqli->query("INSERT INTO utilisateurs(nom, prenom, sexe, email, pseudo, password) VALUES ('{$nom}', '{$prenom}', '{$sexe}', '{$email}', '{$pseudo}', '{$password}')"); + $res = $mysqli->query("INSERT INTO utilisateurs(nom, prenom, sexe, email, pseudo, password) + VALUES ('{$nom}', '{$prenom}', '{$sexe}', '{$email}', '{$pseudo}', '{$password}')"); + if ($res == true){ // si l'inscription fonctionne, préparation des éléments de sessions $_SESSION['pseudo'] = $json['pseudo']; $resultat = $mysqli->query("SELECT * FROM utilisateurs WHERE pseudo LIKE '{$pseudo}' AND password = '{$password}'"); @@ -52,8 +57,10 @@ function realiseConnexion ($json){ $_SESSION['pseudo'] = $json['pseudo']; $resultat = $mysqli->query("SELECT * FROM utilisateurs WHERE pseudo LIKE '{$pseudo}' AND password = '{$password}'"); + $resultat = $resultat->fetch_assoc(); $_SESSION['id'] = $resultat['user_id']; + $_SESSION['mdp'] = $resultat['password']; $favs = $mysqli->query("SELECT p.recette_id FROM utilisateurs u, panier p WHERE u.user_id = p.user_id AND u.user_id = {$resultat['user_id']}"); @@ -72,7 +79,19 @@ function realiseConnexion ($json){ function chercheTitres (string $nom){ - $requete = "SELECT titre FROM recettes WHERE titre LIKE '{$nom}%'"; + $requete = "SELECT sous_nom FROM hierarchie WHERE super_nom LIKE '{$nom}%'"; + $requete = "with recursive cte (sous_nom, super_nom) as ( + SELECT sous_nom, super_nom + FROM hierarchie + WHERE super_nom LIKE '{$nom}%' + union all + SELECT h.sous_nom, h.super_nom + FROM hierarchie h + INNER JOIN cte + on h.super_nom = cte.sous_nom + ) + select distinct sous_nom from cte;"; + echo queryDBB($requete); } @@ -87,7 +106,7 @@ function getCategorie (string $req){ /* function getCategorie (string $req){ - //$requete = "SELECT sous_nom FROM hierarchie WHERE super_nom = '{$req}'"; + $requete = "SELECT sous_nom FROM hierarchie WHERE super_nom = '{$req}'"; $requete = "with recursive cte (sous_nom, super_nom) as ( @@ -121,7 +140,7 @@ function grabRecettes (string $req){ INNER JOIN cte on h.super_nom = cte.sous_nom ) SELECT DISTINCT r.id, r.titre, r.ingredients, r.preparation, r.photo FROM cte c, recettes r, ingredientsderecettes ing - WHERE c.sous_nom = ing.nomIngredient AND ing.idBoisson = r.id ;"; + WHERE (c.sous_nom = ing.nomIngredient OR c.super_nom = ing.nomIngredient) AND ing.idBoisson = r.id ;"; echo queryDBB($requete); } @@ -197,6 +216,55 @@ function removeFromCart ($req){ $_SESSION['panier'] = $temp; } +function searchFilters ($inclure, $exclure){ + // recherche de la recette + + // Création de la requête avec les ingrédients à inclure + + $count = count($inclure); + $inc = ''; + $i = 0; + foreach ($inclure as $item){ + if ($i < $count -1){ + $inc .= "super_nom LIKE '".$item."%' OR "; + }else{ + $inc .= "super_nom LIKE '".$item."%' "; + } + $i ++; + } + + // ajoute les ingrédients à retirer de la recherche + $count = count($exclure); + if ($count > 0){ + $exc = 'AND '; + $i = 0; + foreach ($exclure as $item){ + if ($i < $count -1){ + $exc .= "super_nom NOT LIKE '".$item."%' OR "; + }else{ + $exc .= "super_nom NOT LIKE '".$item."%' "; + } + $i ++; + } + $inc .= $exc; + } + + // Corps de la requête récursive cherchant des recettes ayant certains ingrédients, en ignorant des recettes ayant d'autres ingrédients + $requete = "with recursive cte (sous_nom, super_nom) as ( + SELECT sous_nom, super_nom + FROM hierarchie + WHERE ".$inc." + union all + SELECT h.sous_nom, h.super_nom + FROM hierarchie h + INNER JOIN cte on h.super_nom = cte.sous_nom + ) + SELECT DISTINCT r.id, r.titre, r.ingredients, r.preparation, r.photo FROM cte c, recettes r, ingredientsderecettes ing + WHERE (c.sous_nom = ing.nomIngredient OR c.super_nom = ing.nomIngredient) AND ing.idBoisson = r.id ;"; + + echo queryDBB($requete); + +} // Gestion des requetes json @@ -248,6 +316,11 @@ if (isset($decoded['panier'])){ } } +if (isset($decoded['filtre'])){ + searchFilters ($decoded['avec'], $decoded['sans']); +} + + ?> \ No newline at end of file diff --git a/connexion.php b/connexion.php index 6b9f593..182d57d 100644 --- a/connexion.php +++ b/connexion.php @@ -1,5 +1,7 @@ <?php // Gestion de l'inscription session_start(); // début session + include "configuration.php"; + ?> @@ -16,7 +18,7 @@ <body> <?php // Gestion de l'inscription - $mysqli=mysqli_connect('127.0.0.1', 'root', '') or die("Erreur de connexion"); + $mysqli=install_bd(); if (!$mysqli) { die("Connection failed: " . mysqli_connect_error()); } diff --git a/inscription.php b/inscription.php index 01e3486..59d7bbc 100644 --- a/inscription.php +++ b/inscription.php @@ -1,5 +1,7 @@ <?php // Gestion de l'inscription session_start(); // début session + include "configuration.php"; + ?> @@ -15,10 +17,8 @@ <body> <?php // Gestion de l'inscription - $mysqli=mysqli_connect('127.0.0.1', 'root', '') or die("Erreur de connexion"); - if (!$mysqli) { - die("Connection failed: " . mysqli_connect_error()); - } + $mysqli=install_bd(); + $describe = $mysqli->query('describe Boissons.utilisateurs;'); if ($describe->num_rows > 0) { $form = '<h1> Inscription </h1>'; diff --git a/panier.js b/panier.js index d5dcd29..02ea043 100644 --- a/panier.js +++ b/panier.js @@ -2,6 +2,8 @@ function ajoutFormulaire(conteneur, parent, recette){ let formRec = document.createElement('form'); let field = document.createElement('fieldset'); + field.classList.add('favoris'); + var cancel = document.createElement('button'); @@ -52,7 +54,8 @@ function afficheRecettes(recette){ // parcours de toutes les recettes contenu dans l'objet for (var i = 0; i<recette.length; i++){ // Création des éléments titre / paragraphe / liste - let conteneur = document.createElement('span'); // Contient les éléments html d'une recette + let conteneur = document.createElement('div'); // Contient les éléments html d'une recette + conteneur.classList.add('recetteSolo'); let image = document.createElement('img'); // image let titre = document.createElement('h2'); // titre de niveau 2 let paragraph = document.createElement('p'); // paragraphe contenant la liste et description @@ -63,6 +66,8 @@ function afficheRecettes(recette){ // Récupération du contenu titre.textContent = recette[i].titre; paragraph.textContent = recette[i].preparation; + paragraph.classList.add('preparation'); + let ingredients = recette[i].ingredients.split("|"); for (var j = 0; j<ingredients.length; j++){ liste.innerHTML += "<li>"+ingredients[j]+"</li>"; diff --git a/panier.php b/panier.php index 444a5c9..81a1c15 100644 --- a/panier.php +++ b/panier.php @@ -1,6 +1,6 @@ <?php session_start(); - + /* echo '<pre>'; var_dump($_SESSION['panier']); $temp = $_SESSION['panier']; @@ -19,6 +19,7 @@ } echo $requete; echo '</pre>'; + */ ?> @@ -29,7 +30,7 @@ <title>Votre panier</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script type="text/javascript" src="panier.js"> </script> - + <link href="recettes.css" rel="stylesheet"> </head> diff --git a/recettes.css b/recettes.css index 6422deb..ef8c7e3 100644 --- a/recettes.css +++ b/recettes.css @@ -1,6 +1,46 @@ +#recherche{ + display: flex; + justify-content: space-evenly; + width: 50%; + min-width: none; + min-height: 30px; +} + +#panier{ + top: 0; + right :0; + position: fixed; +} + +#header{ + display: flex; + position: fixed; + top:0px; + width: 100%; + min-width: 600px; + height: 100px; + background-color: #c483a6; + +} + +#recettes{ + padding-top: 5%; + width : 90%; + min-width: 400px; + margin: auto; + +} + +img { + max-width: 400px; + height: auto; + width: auto\9; +} + body{ background-color: #c483a6; color: white; + } h2{ @@ -13,47 +53,85 @@ img{ display:block; margin-left:auto; margin-right:auto; -border: 2px solid #a9d5e3; +border: 2px solid #5e3657; } ul{ text-align: center; } -span{ -border: 2px solid #a9d5e3; +@keyframes recette { + from {background-color: #c483a6;} + to {background-color: #743d5a;} + from {color: #c483a6;} + to {color: #ffffff;} +} + + +.recetteSolo { + background-color: #743d5a; + animation-name: recette; + animation-duration: 0.4s; + border: 2px solid #422852; +} + +/* Correspont au texte + liste de chaque recette */ +.preparation{ + padding: 50px; +} + +button { + background-color:white; + border-radius:12px; + border: 2px solid black; + transition-duration:0.4s; } input{ background-color:white; -font-size:20px; +font-size:16px; border-radius:12px; border: 2px solid black; transition-duration:0.4s; -width:150px; } #requete{ -width:400px; +width: 20%; +min-width:200px; + } -input:hover{ +input:hover, button:enabled:hover{ background-color:black; color:white; } input + input{ -margin-left:10px; +margin-right: 2%; +margin-left: 2%; + } -#panier{ -position: fixed; -margin-right:2em; -right:0; +.with { + padding-left: 2px; + padding-right: 2px; + + margin-left: 2px; + margin-right : 2px; + background-color: darkgreen; + border-radius:12px; + border: 2px solid black; + transition-duration:0.4s; } -#panier{ - position: fixed; - margin-right:2em; - right:0; +.without { + padding-left: 2px; + padding-right: 2px; + margin-left: 2px; + margin-right : 2px; + background-color: darkred; + border-radius:12px; + border: 2px solid black; } + + diff --git a/recettes.js b/recettes.js index e135542..fef45b0 100644 --- a/recettes.js +++ b/recettes.js @@ -3,6 +3,7 @@ function ajoutFormulaire(parent, recette){ let formRec = document.createElement('form'); let field = document.createElement('fieldset'); + field.classList.add('favoris'); var add = document.createElement('button'); var cancel = document.createElement('button'); @@ -95,7 +96,8 @@ function afficheRecettes(recette){ // Création des éléments titre / paragraphe / liste - let conteneur = document.createElement('span'); // Contient les éléments html d'une recette + let conteneur = document.createElement('div'); // Contient les éléments html d'une recette + conteneur.classList.add('recetteSolo'); conteneur.id = recette[i].id; let titre = document.createElement('h2'); // titre de niveau 2 let paragraph = document.createElement('p'); // paragraphe contenant la liste et description @@ -106,6 +108,8 @@ function afficheRecettes(recette){ // Récupération du contenu titre.textContent = recette[i].titre; paragraph.textContent = recette[i].preparation; + paragraph.classList.add('preparation'); + let ingredients = recette[i].ingredients.split("|"); for (var j = 0; j<ingredients.length; j++){ liste.innerHTML += "<li>"+ingredients[j]+"</li>"; diff --git a/suggestion.js b/suggestion.js index af004c0..820a2eb 100644 --- a/suggestion.js +++ b/suggestion.js @@ -1,3 +1,14 @@ +var recherche = { + filtre : 'filtre', + avec: [], + sans: [] +}; + + +/** + * affiche les suggestions de complétions d'ingrédients + * @param {} res + */ function genereSuggestions(res){ // Création dataliste var list = document.createElement('datalist'); @@ -8,37 +19,36 @@ function genereSuggestions(res){ console.log(list); // remplissage de la liste - for (const nom of res){ - var opt = document.createElement("option"); - temp = JSON.stringify(nom["titre"]) - opt.value = temp.replaceAll('"', ''); - list.appendChild(opt); - console.log(opt); + if (res.length > 0){ + for (const objet of res){ + var opt = document.createElement("option"); + opt.textContent = objet.sous_nom; + opt.value = objet.sous_nom; + list.appendChild(opt); + } + // Ajout de la liste à la textbox + textbox.appendChild(list); } - // Ajout de la liste à la textbox - textbox.appendChild(list); } /** - * Affiche une liste de cocktails + * Affiche une liste d'ingrédients */ - function afficherSuggestionsRecettes(){ + function afficherSuggestions(){ // Empeche le rechargement de la page quand on valide document.getElementById("form").addEventListener("submit", function (e) { e.preventDefault(); return false; }); - // Récupère la position à laquelle on veut afficher des informations - var zone = document.getElementById("infos"); - zone.innerHTML = ""; // Création d'un objet contenant la requêtes var input = { requete: document.getElementById("requete").value }; - + console.log(input); + // Demande au serveur php (donc à la db) les noms de const xhr = new XMLHttpRequest(); xhr.open("POST", "Service.php", true); @@ -50,10 +60,116 @@ function genereSuggestions(res){ // Si le retour n'est pas vide, on affiche les titres if (this.response != null){ var resultat = JSON.parse(xhr.response); - //console.log(resultat); + console.log(resultat); genereSuggestions(resultat); } } } xhr.send(JSON.stringify(input)); } + +/** + * Inclure des ingrédients dans la recherche + */ +function inclureIngredient(){ + var barre = document.getElementById('requete'); + var filtre = document.getElementById('filtre'); + + + if (!recherche.avec.includes(barre.value) && barre.value != ''){ + recherche.avec.push(barre.value); + + if (recherche.avec.includes(barre.value)){ + let i = recherche.sans.indexOf(barre.value); + recherche.sans = recherche.avec.splice(0, i); + } + } + filtre.disabled = !(recherche.avec.length > 0 || recherche.sans.length > 0); + updateTags(); + +} + +/** + * Exclure des ingrédients de la recherche + */ +function exclureIngredient(){ + var barre = document.getElementById('requete'); + var filtre = document.getElementById('filtre'); + + if (!recherche.sans.includes(barre.value) && barre.value != ''){ + recherche.sans.push(barre.value); + + if (recherche.avec.includes(barre.value)){ + let i = recherche.avec.indexOf(barre.value); + recherche.avec = recherche.avec.splice(0, i); + } + } + filtre.disabled = !(recherche.avec.length > 0 || recherche.sans.length > 0); + updateTags(); + +} + + +function updateTags(){ + // Ajout des tags de recherches + // Ajout des tags de recherches + let tags = document.getElementById('tagIn'); + tags.innerHTML = ''; + if (recherche.avec.length > 0){ + let tag = document.createElement('ul'); + tags.append(tag); + let cmpt = 1; + recherche.avec.forEach(element => { + let puce = document.createElement('il'); + puce.classList.add('with'); + puce.textContent = element; + tag.append(puce); + puce.addEventListener('click', () =>{ + recherche.avec = recherche.avec.splice(1, cmpt); + puce.parentNode.removeChild(puce); + }) + cmpt++; + }); + } + let tagOut = document.getElementById('tagOut'); + tagOut.innerHTML = ''; + if (recherche.sans.length > 0){ + let tag = document.createElement('ul'); + tagOut.append(tag); + let cmpt = 1; + recherche.sans.forEach(element => { + let puce = document.createElement('il'); + puce.classList.add('without'); + puce.textContent = element; + tag.append(puce); + puce.addEventListener('click', () =>{ + recherche.sans = recherche.sans.splice(1, cmpt); + puce.parentNode.removeChild(puce); + }) + cmpt++; + }); + } +} + +/** + * Effectue recherche a partir des filtres + */ +function rechercheFiltres(){ + const xhr = new XMLHttpRequest(); + xhr.open("POST", "Service.php", true); + xhr.setRequestHeader("Content-Type", "application/json ; charset=UTF-8"); + console.log(recherche); + + // Vérification des résultats + xhr.onreadystatechange = function(){ + if (xhr.readyState === 4 && xhr.status === 200){ + // Si le retour n'est pas vide, on affiche les titres + if (this.response != null){ + var resultat = JSON.parse(xhr.response); + console.log(resultat); + } + } + } + xhr.send(JSON.stringify(recherche)); + +} \ No newline at end of file -- GitLab