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