From f2397b6d312eedf8e1c3b1de97b5c0a25b06e15c Mon Sep 17 00:00:00 2001 From: Benjamin Date: Fri, 3 Apr 2026 10:43:55 +0200 Subject: [PATCH] Finish Advanced Search --- config/database.php | 4 +- public/assets/js/advanced-search.js | 111 ++++++++++++++++++ src/Domain/Recettes/RecetteRepository.php | 34 ++++++ src/Domain/Recettes/RecettesAPIController.php | 27 +++++ views/home.php | 8 +- views/partials/header.php | 4 +- views/partials/tag-sidebar.php | 15 +-- views/recettes/index.php | 2 +- 8 files changed, 187 insertions(+), 18 deletions(-) create mode 100644 public/assets/js/advanced-search.js diff --git a/config/database.php b/config/database.php index 05bbd80..334dc3f 100644 --- a/config/database.php +++ b/config/database.php @@ -3,7 +3,7 @@ return [ 'host' => 'localhost', 'port' => 3306, - 'user' => 'root', - 'pass' => '', + 'user' => 'benjamin', + 'pass' => '011235813', 'name' => 'siterecette' ]; \ No newline at end of file diff --git a/public/assets/js/advanced-search.js b/public/assets/js/advanced-search.js new file mode 100644 index 0000000..519619b --- /dev/null +++ b/public/assets/js/advanced-search.js @@ -0,0 +1,111 @@ +document.addEventListener('DOMContentLoaded', function(){ + + let searchInput = ""; + let tagsId = []; + let ingredientsId = []; + + function buildCards( data ){ + + if( Array.isArray( data ) ){ + data = Object.assign({}, data ); + } + + document.getElementById( "recetteList" ).innerHTML = ''; + for( const [key, recette] of Object.entries( data ) ) { + let HTML_CONTENT = ` + +
+

${recette.titre_recette}

+
    +
  • Temps de préparation : ${recette.temps_de_preparation}
  • +
  • Nombre d'ingrédients : data.nb_ing
  • +
+
+
` + document.getElementById("recetteList").innerHTML += HTML_CONTENT; + } + } + + function advancedSearch(){ + + let form = new FormData(); + form.append( "title", searchInput ); + form.append( "tagsId", tagsId ); + form.append( "ingredientsId", ingredientsId ); + + const XML = new XMLHttpRequest(); + XML.open( "POST", '/api/recettes/list' ); + XML.onreadystatechange = function ( e ) { + if( XML.status === 200 && XML.readyState === XMLHttpRequest.DONE ) { + try { + console.log( XML.response ); + let response = JSON.parse(XML.response); + console.log( "Reponse parsé" ); + buildCards( response.data ); + } catch( e ) { + console.log( "Ce n'est pas un fichier JSON" ); + } + } + } + XML.send( form ); + } + + const INGREDIENTSLIST = document.getElementById( 'ingredientsList' ); + for( let item of INGREDIENTSLIST.getElementsByTagName( 'li' ) ){ + item.addEventListener( 'click', function(){ + + let ingredientId = Number( item.getAttribute( 'data-ingredient-id' ) ); + let index = ingredientsId.indexOf( ingredientId ); + + if( index > -1 ) { + ingredientsId.splice( index, 1 ); + item.classList.add( 'tag-unselected' ); + item.classList.remove( 'tag-selected' ); + } else { + ingredientsId.push( ingredientId ); + item.classList.add( 'tag-selected' ); + item.classList.remove( 'tag-unselected' ); + } + + advancedSearch(); + + }); + } + + const TAGSLIST = document.getElementById( 'tagsList' ); + for( let item of TAGSLIST.getElementsByTagName( 'li' ) ){ + item.addEventListener( 'click', function(){ + + let tagId = Number( item.getAttribute( 'data-tag-id' ) ); + let index = tagsId.indexOf( tagId ); + + if( index > -1 ) { + tagsId.splice( index, 1 ); + item.classList.add( 'tag-unselected' ); + item.classList.remove( 'tag-selected' ); + } else { + tagsId.push( tagId ); + item.classList.add( 'tag-selected' ); + item.classList.remove( 'tag-unselected' ); + } + + advancedSearch(); + + }); + } + + const SEARCHBAR = document.getElementById( 'searchForm' ); + searchInput = new URLSearchParams(document.location.search).get("s"); + console.log( searchInput ); + + if( searchInput !== "" ) { + advancedSearch(); + } + + SEARCHBAR.onsubmit = function( e ){ + e.preventDefault(); + searchInput = document.getElementById( 'searchFormField' ).value; + advancedSearch(); + } + +}); \ No newline at end of file diff --git a/src/Domain/Recettes/RecetteRepository.php b/src/Domain/Recettes/RecetteRepository.php index 5806f8b..0075f6a 100644 --- a/src/Domain/Recettes/RecetteRepository.php +++ b/src/Domain/Recettes/RecetteRepository.php @@ -97,6 +97,40 @@ class RecetteRepository extends Repository implements UseIngredientsInterface, U return $results[0]; } + public function advancedRecetteSearch( string $title = "", array $tagsId= [], array $ingredientsId= [] ): ?array { + + $tableLinkIngredients = IngredientRepository::getStructure()['link_recettes']; + $tableLinkTags = TagRepository::getStructure()['link_recettes']; + + $sqlQuery = "SELECT ({$this->tableName}.num_recette) FROM {$this->tableName} LEFT JOIN {$tableLinkIngredients} ON {$this->tableName}.num_recette = {$tableLinkIngredients}.num_recette LEFT JOIN {$tableLinkTags} ON {$this->tableName}.num_recette = {$tableLinkTags}.num_recette"; + + if( $title != "" || $tagsId !== [] || $ingredientsId !== [] ) { + $sqlQuery .= " WHERE "; + if ($title != "") + $sqlQuery .= " titre_recette LIKE '%{$title}%' AND"; + if ($tagsId !== []) + $sqlQuery .= " num_tag IN (" . implode(",", $tagsId) . ") AND"; + if ($ingredientsId !== []) + $sqlQuery .= " num_ingredient IN (" . implode(",", $ingredientsId) . ") AND"; + $sqlQuery = substr($sqlQuery, 0, -3); + } + $sqlQuery .= ";"; + + $results = $this->selectGetAll($sqlQuery, true); + if( $results === null ) + return null; + + $alreadyGettedId = []; + for( $i = 0; $i < count( $results ); $i++ ){ + if( in_array( $results[$i]['num_recette'], $alreadyGettedId ) ) + unset( $results[$i] ); + else + $alreadyGettedId[] = $results[$i]['num_recette']; + } + + return $results; + } + public function add( Model $recette ): bool { return $this->addEntity( $recette ); } diff --git a/src/Domain/Recettes/RecettesAPIController.php b/src/Domain/Recettes/RecettesAPIController.php index ec76612..a2e3440 100644 --- a/src/Domain/Recettes/RecettesAPIController.php +++ b/src/Domain/Recettes/RecettesAPIController.php @@ -3,6 +3,8 @@ namespace App\Domain\Recettes; use App\Domain\Controller; +use App\Http\JSONResponse; +use App\Http\Request; class RecettesAPIController extends Controller { @@ -13,4 +15,29 @@ class RecettesAPIController extends Controller { ]; } + + public function list(){ + + $title = Request::post( 'title' ) ?? ""; + $tagsId = explode( ",", Request::post( 'tagsId' ) ) ?? []; + $ingredientsId = explode( ",", Request::post( 'ingredientsId' ) ) ?? []; + + if( $tagsId == [ "" ] ) + $tagsId = []; + if( $ingredientsId == [ "" ] ) + $ingredientsId = []; + + $tagsId = array_map( 'intval', $tagsId ); + $ingredientsId = array_map( 'intval', $ingredientsId ); + + + $recetteRepo = new RecetteRepository(); + $resp = $recetteRepo->advancedRecetteSearch( $title, $tagsId, $ingredientsId ); + + $resp = array_map( function($recette) use ($recetteRepo){ + return $recetteRepo->getByID( $recette['num_recette'] ); + }, $resp ?? [] ); + JSONResponse::sendSuccess( [ 'data' => $resp ] ); + + } } \ No newline at end of file diff --git a/views/home.php b/views/home.php index 325bbea..8698283 100644 --- a/views/home.php +++ b/views/home.php @@ -9,11 +9,5 @@ new \App\Domain\Ingredients\IngredientRepository()->add($ing); */ - $recette = new \App\Domain\Recettes\RecetteRepository()->getByID( 2 ); - $ingredient = new \App\Domain\Ingredients\IngredientRepository()->getByID( 2 ); - // var_dump( $recette ); - // var_dump( $ingredient ); - - // new \App\Domain\Recettes\RecetteRepository()->removeAnIngredient( $ingredient, $recette ); - var_dump( $recette->getAllLinkedIngredients() ); + var_dump( new \App\Domain\Recettes\RecetteRepository()->advancedRecetteSearch( "", [ 4 ], [] ) ); ?> diff --git a/views/partials/header.php b/views/partials/header.php index 292c5c5..9f32e01 100644 --- a/views/partials/header.php +++ b/views/partials/header.php @@ -25,6 +25,8 @@
  • Login
  • - +
    + +
    diff --git a/views/partials/tag-sidebar.php b/views/partials/tag-sidebar.php index 23b25d9..89c70a6 100644 --- a/views/partials/tag-sidebar.php +++ b/views/partials/tag-sidebar.php @@ -1,4 +1,4 @@ - + + \ No newline at end of file diff --git a/views/recettes/index.php b/views/recettes/index.php index 974caff..900f8c8 100644 --- a/views/recettes/index.php +++ b/views/recettes/index.php @@ -2,7 +2,7 @@
    -
    +