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 = `
+
`
@@ -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 @@
+