From f2397b6d312eedf8e1c3b1de97b5c0a25b06e15c Mon Sep 17 00:00:00 2001 From: Benjamin Date: Fri, 3 Apr 2026 10:43:55 +0200 Subject: [PATCH 1/2] 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 @@
    -
    +
    From ae3164483166596a28dd6a4e4bacb899a7022749 Mon Sep 17 00:00:00 2001 From: Benjamin Date: Fri, 3 Apr 2026 12:55:05 +0200 Subject: [PATCH 2/2] Fix logins and add routes. --- public/assets/css/style.css | 0 public/assets/images/Logo.jpg | Bin public/assets/js/advanced-search.js | 11 +- public/assets/js/login.js | 0 public/index.php | 0 public/uploads/.gitignore | 0 src/Domain/Ingredients/Ingredient.php | 6 + .../Ingredients/IngredientRepository.php | 2 +- .../Ingredients/IngredientsAPIController.php | 70 +++++ src/Domain/Recettes/Recette.php | 11 + src/Domain/Recettes/RecetteRepository.php | 2 +- src/Domain/Recettes/RecettesAPIController.php | 253 +++++++++++++++++- src/Domain/Tags/TagsAPIController.php | 72 +++++ src/Helpers/UploadFiles.php | 51 ++++ views/partials/header.php | 2 +- 15 files changed, 470 insertions(+), 10 deletions(-) mode change 100644 => 100755 public/assets/css/style.css mode change 100644 => 100755 public/assets/images/Logo.jpg mode change 100644 => 100755 public/assets/js/advanced-search.js mode change 100644 => 100755 public/assets/js/login.js mode change 100644 => 100755 public/index.php create mode 100644 public/uploads/.gitignore create mode 100644 src/Domain/Ingredients/IngredientsAPIController.php create mode 100644 src/Domain/Tags/TagsAPIController.php create mode 100644 src/Helpers/UploadFiles.php diff --git a/public/assets/css/style.css b/public/assets/css/style.css old mode 100644 new mode 100755 diff --git a/public/assets/images/Logo.jpg b/public/assets/images/Logo.jpg old mode 100644 new mode 100755 diff --git a/public/assets/js/advanced-search.js b/public/assets/js/advanced-search.js old mode 100644 new mode 100755 index 519619b..bc433f2 --- a/public/assets/js/advanced-search.js +++ b/public/assets/js/advanced-search.js @@ -12,13 +12,13 @@ document.addEventListener('DOMContentLoaded', function(){ document.getElementById( "recetteList" ).innerHTML = ''; for( const [key, recette] of Object.entries( data ) ) { - let HTML_CONTENT = ` - + let HTML_CONTENT = ` +

    ${recette.titre_recette}

    • Temps de préparation : ${recette.temps_de_preparation}
    • -
    • Nombre d'ingrédients : data.nb_ing
    • +
    • Nombre d'ingrédients : ${recette.nb_ingredients}
    ` @@ -95,10 +95,9 @@ document.addEventListener('DOMContentLoaded', function(){ } const SEARCHBAR = document.getElementById( 'searchForm' ); - searchInput = new URLSearchParams(document.location.search).get("s"); - console.log( searchInput ); + searchInput = new URLSearchParams(document.location.search).get("s") || searchInput; - if( searchInput !== "" ) { + if( searchInput !== undefined && searchInput != "" ) { advancedSearch(); } diff --git a/public/assets/js/login.js b/public/assets/js/login.js old mode 100644 new mode 100755 diff --git a/public/index.php b/public/index.php old mode 100644 new mode 100755 diff --git a/public/uploads/.gitignore b/public/uploads/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/src/Domain/Ingredients/Ingredient.php b/src/Domain/Ingredients/Ingredient.php index 8a965db..3469a6f 100644 --- a/src/Domain/Ingredients/Ingredient.php +++ b/src/Domain/Ingredients/Ingredient.php @@ -21,6 +21,12 @@ class Ingredient extends Model { */ public string $nom_ingredient; + /** + * L'URL vers l'image de l'ingrédient. + * @var string + */ + public string $photo_ingredient; + /** * Retourne le numéro de l'ingrédient. * @return int diff --git a/src/Domain/Ingredients/IngredientRepository.php b/src/Domain/Ingredients/IngredientRepository.php index daca14c..234732d 100644 --- a/src/Domain/Ingredients/IngredientRepository.php +++ b/src/Domain/Ingredients/IngredientRepository.php @@ -35,7 +35,7 @@ class IngredientRepository extends Repository implements LinkableInterface { return [ 'table' => 'Ingredient', 'columns' => [ - 'num_ingredient', 'nom_ingredient' + 'num_ingredient', 'nom_ingredient', 'photo_ingredient', ], 'link_recettes' => 'Listeingredient' ]; diff --git a/src/Domain/Ingredients/IngredientsAPIController.php b/src/Domain/Ingredients/IngredientsAPIController.php new file mode 100644 index 0000000..1e3b59d --- /dev/null +++ b/src/Domain/Ingredients/IngredientsAPIController.php @@ -0,0 +1,70 @@ +ingredients->create', routeAction: 'create', routeMethods: ['POST'] ), + self::Route( routeUrl: '/api/ingredients/edit', routeName: 'api->ingredients->edit', routeAction: 'edit', routeMethods: ['POST'] ), + ]; + + } + + public function create(){ + + $name = Request::post( 'name' ); + $fileNameField = "image"; + if( !$name || $name == "" ) + JSONResponse::sendError( [ 'error' => 'Name not defined' ] ); + + $urlOrError = UploadFiles::uploadFile( $fileNameField ); + if( is_int( $urlOrError ) ){ + JSONResponse::sendError( [ 'error' => $urlOrError ] ); + } + + $ingredient = new Ingredient(); + + $ingredient->num_ingredient = 0; + $ingredient->nom_ingredient = $name; + $ingredient->photo_ingredient = $urlOrError; + + if( !new IngredientRepository()->add( $ingredient ) ) + JSONResponse::sendError( [ 'error' => 'An error occured while adding ingredient' ] ); + + JSONResponse::sendSuccess( [ 'image_url' => $urlOrError ] ); + + } + + public function edit(){ + + $id = Request::post( 'id' ) ?? 0; + $ingredient = new IngredientRepository()->getByID( $id ); + if( !$ingredient ) + JSONResponse::sendError( [ 'error' => 'Ingredient not found' ] ); + + $name = Request::post( 'name' ); + $fileNameField = "image"; + + if( $name ) { + $ingredient->nom_ingredient = $name; + } + + $urlOrError = UploadFiles::uploadFile( $fileNameField ); + if( !is_int( $urlOrError ) ){ + $ingredient->photo_ingredient = $urlOrError; + } + + if( !new IngredientRepository()->update( $ingredient ) ) + JSONResponse::sendError( [ 'error' => 'An error occured while updating ingredient' ] ); + + JSONResponse::sendSuccess( [] ); + } +} \ No newline at end of file diff --git a/src/Domain/Recettes/Recette.php b/src/Domain/Recettes/Recette.php index 6073250..3f16eac 100644 --- a/src/Domain/Recettes/Recette.php +++ b/src/Domain/Recettes/Recette.php @@ -6,11 +6,13 @@ use App\Domain\Ingredients\Ingredient; use App\Domain\Ingredients\IngredientRepository; use App\Domain\Ingredients\UseIngredientsInterface; use App\Domain\Model; +use App\Domain\Tags\Tag; use App\Helpers\Markdown; /** * Classe qui va permettre de gérer tous les objets recette. */ +#[\AllowDynamicProperties] class Recette extends Model { public int $num_recette; @@ -43,6 +45,15 @@ class Recette extends Model { return new RecetteRepository()->getAllLinkedIngredients( $this ); } + /** + * Récupère une liste de tous les tags liés à la recette. + * @return Tag[]|null + */ + public function getAllLinkedTags(): ?array + { + return new RecetteRepository()->getAllLinkedTags( $this ); + } + public function getNumberOfIngredients(): int { $response = $this->getAllLinkedIngredients(); diff --git a/src/Domain/Recettes/RecetteRepository.php b/src/Domain/Recettes/RecetteRepository.php index 0075f6a..552f16a 100644 --- a/src/Domain/Recettes/RecetteRepository.php +++ b/src/Domain/Recettes/RecetteRepository.php @@ -90,7 +90,7 @@ class RecetteRepository extends Repository implements UseIngredientsInterface, U * @return Recette|null */ public function getBySlug( string $slug ): ?Recette { - $sqlQuery = "SELECT * FROM {$this->tableName} WHERE slug = {$slug}"; + $sqlQuery = "SELECT * FROM {$this->tableName} WHERE slug = '{$slug}'"; $results = $this->selectGetAll($sqlQuery); if( $results === null || count( $results ) > 1 ) return null; diff --git a/src/Domain/Recettes/RecettesAPIController.php b/src/Domain/Recettes/RecettesAPIController.php index a2e3440..7811cf2 100644 --- a/src/Domain/Recettes/RecettesAPIController.php +++ b/src/Domain/Recettes/RecettesAPIController.php @@ -3,8 +3,12 @@ namespace App\Domain\Recettes; use App\Domain\Controller; +use App\Domain\Ingredients\IngredientRepository; +use App\Domain\Tags\TagRepository; +use App\Helpers\UploadFiles; use App\Http\JSONResponse; use App\Http\Request; +use App\Http\Router; class RecettesAPIController extends Controller { @@ -12,6 +16,9 @@ class RecettesAPIController extends Controller { { return [ self::Route( routeUrl: '/api/recettes/list', routeName: 'api->recettes->list', routeAction: 'list', routeMethods: ['POST'] ), + self::Route( routeUrl: '/api/recettes/create', routeName: 'api->recettes->create', routeAction: 'create', routeMethods: ['POST'] ), + self::Route( routeUrl: '/api/recettes/edit', routeName: 'api->recettes->edit', routeAction: 'edit', routeMethods: ['POST'] ), + self::Route( routeUrl: '/api/recettes/delete', routeName: 'api->recettes->delete', routeAction: 'delete', routeMethods: ['POST'] ), ]; } @@ -35,9 +42,253 @@ class RecettesAPIController extends Controller { $resp = $recetteRepo->advancedRecetteSearch( $title, $tagsId, $ingredientsId ); $resp = array_map( function($recette) use ($recetteRepo){ - return $recetteRepo->getByID( $recette['num_recette'] ); + $r = $recetteRepo->getByID( $recette['num_recette'] ); + $r->url = Router::getRouteURL( 'recettes->show', $r->slug ); + $r->nb_ingredients = $r->getNumberOfIngredients(); + return $r; }, $resp ?? [] ); JSONResponse::sendSuccess( [ 'data' => $resp ] ); } + + public function create(){ + + // Récupération des champs. + $name = Request::post( 'nom' ) ?? ""; + $temps = Request::post( 'temps' ) ?? ""; + $fileField = "image"; + + $tagsId = explode( ",", Request::post( 'tag' ) ) ?? []; + $ingredientsId = explode( ",", Request::post( 'ingr' ) ) ?? []; + + if( $tagsId == [ "" ] ) + $tagsId = []; + if( $ingredientsId == [ "" ] ) + $ingredientsId = []; + + $tagsId = array_map( 'intval', $tagsId ); + $ingredientsId = array_map( 'intval', $ingredientsId ); + + $description = Request::post( 'description' ); + + // Vérification. + if( $name == "" || $temps == "" || $ingredientsId == [] || $description == "" ) + JSONResponse::sendError( [ 'error' => "One required fields is missing" ] ); + + // Upload & Vérification de l'image. + $urlOrError = UploadFiles::uploadFile( $fileField ); + if( is_int( $urlOrError ) ){ + JSONResponse::sendError( [ 'error' => $urlOrError ] ); + } + + // Vérification d'une entrée qui existerait déjà. + $slug = strtolower( $name ); + $slug = str_replace( ' ', '-', $slug ); + + $recetteRepo = new RecetteRepository(); + + if( $recetteRepo->getBySlug( $slug ) ){ + JSONResponse::sendError( [ 'error' => "Recette already exists" ] ); + } + + // Création de la recette. + $recette = new Recette(); + + $recette->num_recette = 0; + $recette->titre_recette = $name; + $recette->slug = $slug; + + $recette->temps_de_preparation = intval( $temps ); + $recette->photo = $urlOrError; + $recette->description_recette = $description; + $recette->publication_date = date("Y-m-d"); + + // Importation de la recette. + if( !$recetteRepo->add( $recette ) ){ + JSONResponse::sendError( [ 'error' => "Error adding recette" ] ); + } + + // Pour actualiser l'ID. + $recette = $recetteRepo->getBySlug( $slug ); + + // Ajout du lien ingrédients recettes. + foreach( $ingredientsId as $ingredientId ){ + $ingredient = new IngredientRepository()->getByID( $ingredientId ); + if( $ingredient == null ) + continue; + $recetteRepo->addAnIngredient( $ingredient, $recette ); + } + + // Ajout du lien Recettes tags. + if( $tagsId != [] ){ + foreach( $tagsId as $tagId ){ + $tag = new TagRepository()->getByID( $tagId ); + if( $tag == null ) + continue; + $recetteRepo->addATag( $tag, $recette ); + } + } + + JSONResponse::sendSuccess( [ 'recette' => $recette ] ); + } + + public function edit(){ + + // Récupération des champs. + $id = Request::post( 'id' ); + $name = Request::post( 'nom' ) ?? ""; + $temps = Request::post( 'temps' ) ?? ""; + $fileField = "image"; + + $tagsId = explode( ",", Request::post( 'tag' ) ) ?? []; + $ingredientsId = explode( ",", Request::post( 'ingr' ) ) ?? []; + + if( $tagsId == [ "" ] ) + $tagsId = []; + if( $ingredientsId == [ "" ] ) + $ingredientsId = []; + + $tagsId = array_map( 'intval', $tagsId ); + $ingredientsId = array_map( 'intval', $ingredientsId ); + + $description = Request::post( 'description' ); + + // Vérification. + if( $id == "" || $name == "" || $temps == "" || $ingredientsId == [] || $description == "" ) + JSONResponse::sendError( [ 'error' => "One required fields is missing" ] ); + + $recetteRepo = new RecetteRepository(); + $recette = $recetteRepo->getByID( $id ); + if( !$recette ){ + JSONResponse::sendError( [ 'error' => "Recette not found" ] ); + } + + // Upload & Vérification de l'image. + $urlOrError = UploadFiles::uploadFile( $fileField ); + if( is_int( $urlOrError ) ){ + // Ingore image. + } else { + $recette->photo = $urlOrError; + } + + // Vérification d'une entrée qui existerait déjà. + $slug = strtolower( $name ); + $slug = str_replace( ' ', '-', $slug ); + + $recette->titre_recette = $name; + $recette->slug = $slug; + + $recette->temps_de_preparation = intval( $temps ); + $recette->description_recette = $description; + + // Importation de la recette. + if( !$recetteRepo->update( $recette ) ){ + JSONResponse::sendError( [ 'error' => "Error updating recette" ] ); + } + + // Actualisation des ingrédients. + $ingrObjArray = $recette->getAllLinkedIngredients(); + if( !$ingrObjArray || $ingrObjArray === [] ){ // Si il n'y a pas déjà d'autres ingrédients, on ajoute tous ceux présents ici. + + foreach( $ingredientsId as $ingredientId ){ + $ingredient = new IngredientRepository()->getByID( $ingredientId ); + if( $ingredient == null ) + continue; + $recetteRepo->addAnIngredient( $ingredient, $recette ); + } + + } else { + + $ingrIntArray = array_map( function($ingr){ + return intval( $ingr->getID() ); + }, $ingrObjArray ); + + foreach( $ingrIntArray as $ingrId ){ + // Si un ingrédient n'est pas dans la nouvelle liste d'ingrédients, il faut retirer le lien. + if( !in_array( $ingrId, $ingredientsId ) ){ + $ingredient = new IngredientRepository()->getByID( $ingrId ); + if( $ingredient == null ) + continue; + $recetteRepo->removeAnIngredient( $ingredient, $recette ); + } + } + + foreach( $ingredientsId as $ingrId ){ + // Si un ingrédient n'est pas dans l'ancienne liste, il faut ajouter un lien. + if( !in_array( $ingrId, $ingrIntArray ) ){ + $ingredient = new IngredientRepository()->getByID( $ingrId ); + if( $ingredient == null ) + continue; + $recetteRepo->addAnIngredient( $ingredient, $recette ); + } + } + + } + + // Actualisation des tags. + if( $tagsId != [] ) { + $tagObjArray = $recette->getAllLinkedTags(); + if (!$tagObjArray || $tagObjArray === []) { // Si il n'y a pas déjà d'autres tags, on ajoute tous ceux présents ici. + + foreach ($tagsId as $tagId) { + $tag = new TagRepository()->getByID($tagId); + if ($tag == null) + continue; + $recetteRepo->addATag($tag, $recette); + } + + } else { + + $tagIntArray = array_map(function ($ingr) { + return intval( $ingr->getID() ); + }, $tagObjArray); + + foreach ($tagIntArray as $tagId) { + // Si un ingrédient n'est pas dans la nouvelle liste d'ingrédients, il faut retirer le lien. + if (!in_array($tagId, $tagsId)) { + $tag = new TagRepository()->getByID($tagId); + if ($tag == null) + continue; + $recetteRepo->removeATag($tag, $recette); + } + } + + foreach ($tagsId as $tagId) { + // Si un ingrédient n'est pas dans l'ancienne liste, il faut ajouter un lien. + if (!in_array($tagId, $tagIntArray)) { + $tag = new TagRepository()->getByID($tagId); + if ($tag == null) + continue; + $recetteRepo->addATag($tag, $recette); + } + } + + } + } + + JSONResponse::sendSuccess( [ 'recette' => $recette ] ); + } + + public function delete(){ + $id = Request::post( 'id' ); + $recette = new RecetteRepository()->getByID( $id ); + if( !$recette ) + JSONResponse::sendError( [ 'error' => 'Recette not found' ] ); + + $recetteRepo = new RecetteRepository(); + + // Retirer tous les liens Ingrédients/Tags. + foreach( ( $recette->getAllLinkedIngredients() ?? [] ) as $ingr ){ + $recetteRepo->removeAnIngredient( $ingr, $recette ); + } + foreach( ( $recette->getAllLinkedTags() ?? [] ) as $tag ){ + $recetteRepo->removeATag( $tag, $recette ); + } + + if( !$recetteRepo->delete( $recette ) ) + JSONResponse::sendError( [ 'error' => 'An error occured while deleting recette' ] ); + + JSONResponse::sendSuccess(); + + } } \ No newline at end of file diff --git a/src/Domain/Tags/TagsAPIController.php b/src/Domain/Tags/TagsAPIController.php new file mode 100644 index 0000000..95f5402 --- /dev/null +++ b/src/Domain/Tags/TagsAPIController.php @@ -0,0 +1,72 @@ +tags->create', routeAction: 'create', routeMethods: ['POST'] ), + self::Route( routeUrl: '/api/tags/edit', routeName: 'api->tags->edit', routeAction: 'edit', routeMethods: ['POST'] ), + self::Route( routeUrl: '/api/tags/delete', routeName: 'api->tags->delete', routeAction: 'delete', routeMethods: ['POST'] ), + ]; + + } + + public function create(){ + + $name = Request::post( 'name' ); + if( !$name || $name == "" ) + JSONResponse::sendError( [ 'error' => 'Name not defined' ] ); + + $tag = new Tag(); + $tag->num_tag = 0; + $tag->nom_tag = $name; + + if( !new TagRepository()->add( $tag ) ) + JSONResponse::sendError( [ 'error' => 'An error occured while adding tag' ] ); + + JSONResponse::sendSuccess(); + + } + + public function edit(){ + + $id = Request::post( 'id' ) ?? 0; + $tag = new TagRepository()->getByID( $id ); + if( !$tag ) + JSONResponse::sendError( [ 'error' => 'Tag not found' ] ); + + $name = Request::post( 'name' ); + if( !$name || $name == "" ) + JSONResponse::sendError( [ 'error' => 'Name not defined' ] ); + + $tag->nom_tag = $name; + + if( !new TagRepository()->update( $tag ) ) + JSONResponse::sendError( [ 'error' => 'An error occured while updating tag' ] ); + + JSONResponse::sendSuccess(); + + } + + public function delete(){ + + $id = Request::post( 'id' ) ?? 0; + $tag = new TagRepository()->getByID( $id ); + if( !$tag ) + JSONResponse::sendError( [ 'error' => 'Tag not found' ] ); + + if( !new TagRepository()->delete( $tag ) ) + JSONResponse::sendError( [ 'error' => 'An error occured while deleting tag' ] ); + + JSONResponse::sendSuccess(); + + } +} \ No newline at end of file diff --git a/src/Helpers/UploadFiles.php b/src/Helpers/UploadFiles.php new file mode 100644 index 0000000..658fe48 --- /dev/null +++ b/src/Helpers/UploadFiles.php @@ -0,0 +1,51 @@ +
    - +