From 8a173ed2c723dfa904797a91b4245bc6e4faa308 Mon Sep 17 00:00:00 2001
From: Benjamin
Date: Thu, 2 Apr 2026 18:10:47 +0200
Subject: [PATCH 1/2] =?UTF-8?q?Base=20de=20ingr=C3=A9dient=20termin=C3=A9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
config/database.php | 4 +-
src/Domain/Ingredients/Ingredient.php | 5 ++
.../Ingredients/IngredientRepository.php | 80 ++++++++++++++++++-
.../Ingredients/UseIngredientsInterface.php | 19 +++++
src/Domain/LinkableInterface.php | 13 +++
src/Domain/Model.php | 5 ++
src/Domain/Recettes/Recette.php | 12 +++
src/Domain/Recettes/RecetteRepository.php | 29 ++++++-
src/Domain/Repository.php | 74 ++++++++++++++++-
views/home.php | 18 ++++-
10 files changed, 246 insertions(+), 13 deletions(-)
create mode 100644 src/Domain/Ingredients/UseIngredientsInterface.php
create mode 100644 src/Domain/LinkableInterface.php
diff --git a/config/database.php b/config/database.php
index 334dc3f..05bbd80 100644
--- a/config/database.php
+++ b/config/database.php
@@ -3,7 +3,7 @@
return [
'host' => 'localhost',
'port' => 3306,
- 'user' => 'benjamin',
- 'pass' => '011235813',
+ 'user' => 'root',
+ 'pass' => '',
'name' => 'siterecette'
];
\ No newline at end of file
diff --git a/src/Domain/Ingredients/Ingredient.php b/src/Domain/Ingredients/Ingredient.php
index bfab46f..9fb655e 100644
--- a/src/Domain/Ingredients/Ingredient.php
+++ b/src/Domain/Ingredients/Ingredient.php
@@ -9,5 +9,10 @@ class Ingredient extends Model {
public int $num_ingredient;
public string $nom_ingredient;
+ public function getID(): int
+ {
+ return $this->num_ingredient;
+ }
+
}
\ No newline at end of file
diff --git a/src/Domain/Ingredients/IngredientRepository.php b/src/Domain/Ingredients/IngredientRepository.php
index 63efb45..b0f2376 100644
--- a/src/Domain/Ingredients/IngredientRepository.php
+++ b/src/Domain/Ingredients/IngredientRepository.php
@@ -2,10 +2,13 @@
namespace App\Domain\Ingredients;
+use App\Domain\LinkableInterface;
+use App\Domain\Recettes\Recette;
use App\Domain\Repository;
use App\Domain\Model;
+use App\Kernel;
-class IngredientRepository extends Repository {
+class IngredientRepository extends Repository implements LinkableInterface {
public static function getEntity(): string
{
@@ -18,12 +21,83 @@ class IngredientRepository extends Repository {
'table' => 'Ingredient',
'columns' => [
'num_ingredient', 'nom_ingredient'
- ]
+ ],
+ 'link_recettes' => 'Listeingredient'
];
}
- public function add( Model $ingredient ): bool {
+ /**
+ * Permet d'obtenir un ingrédient spécifique par son ID.
+ *
+ * @param int $id
+ *
+ * @return Ingredient|null
+ */
+ public function getByID( int $id ): ?Ingredient {
+ $sqlQuery = "SELECT * FROM {$this->tableName} WHERE num_ingredient = {$id}";
+ $results = $this->selectGetAll($sqlQuery);
+ if( $results === null || count( $results ) > 1 )
+ return null;
+ return $results[0];
+ }
+
+ /**
+ * Permet d'obtenir, sous forme de liste, toutes les entrées qui lient des ingrédients.
+ *
+ * @param string $linkedTo La table qui permet de faire la liaison des ingrédients avec une autre entité.
+ * @param string $linkingField Le champ qui permet de faire la liaison des ingrédients avec une autre entité.
+ * @param Model $linkedEntity L'autre entité.
+ *
+ * @return array|null
+ */
+ public function getIdLinkedTo( string $linkedTo, string $linkingField, Model $linkedEntity ): ?array {
+
+ $linkName = 'link_' . $linkedTo;
+ if( !isset( $this->globalStructure[$linkName]))
+ return null;
+
+ $sqlQuery = "SELECT * FROM {$this->globalStructure[$linkName]} WHERE {$linkingField} = {$linkedEntity->getId()};";
+ $results = $this->selectGetAll($sqlQuery, true);
+ if( $results === null )
+ return null;
+ return $results;
+ }
+
+ public function addLinkBetween( string $linkedTo, string $linkingField, Model $linkedEntity, Model $ingredientEntity ): bool {
+
+ $linkName = 'link_' . $linkedTo;
+ if( !isset( $this->globalStructure[$linkName]))
+ return false;
+
+ $query = "INSERT INTO {$this->globalStructure[$linkName]} ({$linkingField},num_ingredient) VALUES ({$linkedEntity->getId()}, {$ingredientEntity->getID()});";
+ $statement = Kernel::$DB->pdo->prepare( $query );
+
+ return $statement->execute();
}
+
+ public function removeLinkBetween(string $linkedTo, string $linkingField, Model $linkedEntity, Model $ingredientEntity ): bool
+ {
+ $linkName = 'link_' . $linkedTo;
+ if( !isset( $this->globalStructure[$linkName]))
+ return false;
+
+ $query = "DELETE FROM {$this->globalStructure[$linkName]} WHERE {$linkingField} = {$linkedEntity->getId()} AND num_ingredient = {$ingredientEntity->getId()};";
+ $statement = Kernel::$DB->pdo->prepare( $query );
+ return $statement->execute();
+ }
+
+ public function add( Model $ingredient ): bool {
+ return $this->addEntity( $ingredient );
+ }
+
+ public function update( Model $ingredient ): bool {
+ return $this->updateEntity( $ingredient, 'num_ingredient' );
+ }
+
+ public function delete( Model $ingredient ): bool {
+ return $this->deleteEntity( $ingredient, 'num_ingredient' );
+ }
+
}
\ No newline at end of file
diff --git a/src/Domain/Ingredients/UseIngredientsInterface.php b/src/Domain/Ingredients/UseIngredientsInterface.php
new file mode 100644
index 0000000..d0163d6
--- /dev/null
+++ b/src/Domain/Ingredients/UseIngredientsInterface.php
@@ -0,0 +1,19 @@
+num_recette;
+ }
+
public function getHTMLDescription(): string {
return Markdown::convertToHTML( $this->description_recette );
}
+ public function getAllLinkedIngredients(): ?array
+ {
+ return new RecetteRepository()->getAllLinkedIngredients( $this );
+ }
+
}
\ No newline at end of file
diff --git a/src/Domain/Recettes/RecetteRepository.php b/src/Domain/Recettes/RecetteRepository.php
index 53bc4a2..10692ba 100644
--- a/src/Domain/Recettes/RecetteRepository.php
+++ b/src/Domain/Recettes/RecetteRepository.php
@@ -2,10 +2,13 @@
namespace App\Domain\Recettes;
+use App\Domain\Ingredients\Ingredient;
+use App\Domain\Ingredients\IngredientRepository;
+use App\Domain\Ingredients\UseIngredientsInterface;
use App\Domain\Model;
use App\Domain\Repository;
-class RecetteRepository extends Repository {
+class RecetteRepository extends Repository implements UseIngredientsInterface {
public static function getEntity(): string
{
@@ -63,4 +66,28 @@ class RecetteRepository extends Repository {
return $this->deleteEntity( $recette, 'num_recette' );
}
+
+
+ public function getAllLinkedIngredients(Model $entity): ?array
+ {
+ $ingredientRepo = new IngredientRepository();
+ $response = $ingredientRepo->getIdLinkedTo( 'recettes', 'num_recette', $entity );
+
+ return array_map( function($arr) use($ingredientRepo) {
+ return $ingredientRepo->getByID( $arr['num_ingredient'] );
+ }, $response );
+ }
+
+ public function addAnIngredient(Ingredient $ingredient, Model $entity): bool
+ {
+ $ingredientRepo = new IngredientRepository();
+ return $ingredientRepo->addLinkBetween( 'recettes', 'num_recette', $ingredient, $entity );
+ }
+
+ public function removeAnIngredient(Ingredient $ingredient, Model $entity): bool
+ {
+ $ingredientRepo = new IngredientRepository();
+ return $ingredientRepo->removeLinkBetween( 'recettes', 'num_recette', $ingredient, $entity );
+ }
+
}
\ No newline at end of file
diff --git a/src/Domain/Repository.php b/src/Domain/Repository.php
index b1933c3..2de7a9a 100644
--- a/src/Domain/Repository.php
+++ b/src/Domain/Repository.php
@@ -21,34 +21,63 @@ abstract class Repository {
*/
abstract public static function getStructure(): array;
+ /**
+ * Contient le nom de la table principale du repo.
+ * @var string|mixed
+ */
final public string $tableName;
+
+ /**
+ * Contient le nom des colonnes de la table du repo.
+ * @var array|mixed
+ */
final public array $tableColumns;
+ /**
+ * Contient les mêmes données que getStructure().
+ * @var array
+ */
+ public private(set) array $globalStructure;
+
+ /**
+ * Constructeur.
+ * Reprend les informations de getStructure et les met dans des attributs.
+ */
public function __construct(){
$structure = static::getStructure();
$this->tableName = $structure['table'];
$this->tableColumns = $structure['columns'];
+ $this->globalStructure = $structure;
}
-
/**
* Permet d'avoir tous les éléments correspondant à la requête passée en paramètre.
*
* @param string $sqlQuery
+ * @param bool $asArray Permet de savoir si on veut que le retour soit une array ou bien un tableau de Model.
* @return array|null
*/
- public function selectGetAll( string $sqlQuery ): ?array {
+ public function selectGetAll( string $sqlQuery, bool $asArray = false ): ?array {
$statement = Kernel::$DB->pdo->prepare( $sqlQuery );
if( !$statement->execute() )
return null;
- $results = $statement->fetchAll( PDO::FETCH_CLASS, static::getEntity() );
+ if( $asArray )
+ $results = $statement->fetchAll( PDO::FETCH_ASSOC );
+ else
+ $results = $statement->fetchAll( PDO::FETCH_CLASS, static::getEntity() );
if( empty( $results ) )
return null;
return $results;
}
+ /**
+ * Permet d'ajouter une entité à la base de données.
+ *
+ * @param Model $entity
+ * @return bool
+ */
public function addEntity( Model $entity ): bool {
$query = "INSERT INTO {$this->tableName} (";
@@ -69,6 +98,14 @@ abstract class Repository {
return $statement->execute();
}
+ /**
+ * Permet de mettre à jour les informations de l'entité dans la base de données.
+ *
+ * @param Model $entity
+ * @param string $identifier
+ *
+ * @return bool
+ */
public function updateEntity( Model $entity, string $identifier ): bool {
$query = "UPDATE {$this->tableName} SET ";
foreach( $this->tableColumns as $column ) {
@@ -84,6 +121,14 @@ abstract class Repository {
return $statement->execute();
}
+ /**
+ * Permet de supprimer une entrée d'entité dans la base de données.
+ *
+ * @param Model $entity
+ * @param string $identifier
+ *
+ * @return bool
+ */
public function deleteEntity( Model $entity, string $identifier ): bool {
$query = "DELETE FROM {$this->tableName} WHERE {$identifier} = :{$identifier};";
$statement = Kernel::$DB->pdo->prepare( $query );
@@ -91,8 +136,31 @@ abstract class Repository {
return $statement->execute();
}
+ /**
+ * Fonction raccourcie pour préparer les champs nécessaires pour addEntity.
+ *
+ * @param Model $entity
+ *
+ * @return bool
+ */
abstract public function add( Model $entity ): bool;
+
+ /**
+ * Fonction raccourcie pour préparer les champs nécessaires pour updateEntity
+ *
+ * @param Model $entity
+ *
+ * @return bool
+ */
abstract public function update( Model $entity ): bool;
+
+ /**
+ * Fonction raccourcie pour préparer les champs nécessaires pour deleteEntity
+ *
+ * @param Model $entity
+ *
+ * @return bool
+ */
abstract public function delete( Model $entity ): bool;
diff --git a/views/home.php b/views/home.php
index c0c0f44..325bbea 100644
--- a/views/home.php
+++ b/views/home.php
@@ -1,9 +1,19 @@
Coucou
$md
"; ?>
-getByID( 4 );
-$rec->temps_de_preparation = 7;
-$rec->titre_recette = "Tutu";
+num_ingredient = 0;
+ $ing->nom_ingredient = "coucou";
+ new \App\Domain\Ingredients\IngredientRepository()->add($ing);
+*/
-new \App\Domain\Recettes\RecetteRepository()->delete( $rec );
+ $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() );
?>
--
2.39.5
From 69a5a99e15591d97885897500ece13e35d1450f4 Mon Sep 17 00:00:00 2001
From: Benjamin
Date: Thu, 2 Apr 2026 19:07:08 +0200
Subject: [PATCH 2/2] =?UTF-8?q?Finish=20tag=20et=20commencer=20=C3=A0=20aj?=
=?UTF-8?q?outer=20les=20template.s?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
public/assets/css/style.css | 65 ++++++-
src/Domain/Controller.php | 3 +
src/Domain/Ingredients/Ingredient.php | 17 +-
.../Ingredients/IngredientRepository.php | 72 ++++++++
.../Ingredients/UseIngredientsInterface.php | 19 ++
src/Domain/LinkableInterface.php | 38 ++++
src/Domain/Model.php | 3 +
src/Domain/Pages/PagesController.php | 9 +-
src/Domain/Recettes/Recette.php | 18 ++
src/Domain/Recettes/RecetteRepository.php | 75 +++++++-
src/Domain/Recettes/RecettesController.php | 14 +-
src/Domain/Repository.php | 3 +
src/Domain/Tags/Tag.php | 33 ++++
src/Domain/Tags/TagRepository.php | 174 ++++++++++++++++++
src/Domain/Tags/UseTagsInterface.php | 38 ++++
src/Http/Router.php | 4 +-
views/partials/header.php | 5 +-
views/partials/tag-sidebar.php | 39 ++++
views/recettes/index.php | 25 ++-
19 files changed, 620 insertions(+), 34 deletions(-)
create mode 100644 src/Domain/Tags/Tag.php
create mode 100644 src/Domain/Tags/TagRepository.php
create mode 100644 src/Domain/Tags/UseTagsInterface.php
create mode 100644 views/partials/tag-sidebar.php
diff --git a/public/assets/css/style.css b/public/assets/css/style.css
index 898ca90..2156e6d 100644
--- a/public/assets/css/style.css
+++ b/public/assets/css/style.css
@@ -157,6 +157,7 @@ nav {
border: 1px solid black;
border-radius: 10px;
width: 95%;
+ max-width: calc(128px*0.95);
box-shadow: 1px 1px 1px black;
}
@@ -170,7 +171,7 @@ nav {
.tag-unselected {
background-color: white;
-
+
}
.tag-unselected:hover {
background-color: #ffa04d;
@@ -306,25 +307,51 @@ ul {
.recette-div-info {
display: flex;
flex-direction: row;
+ padding: 20px;
}
.recette-div-liste-info{
- padding: 50px;
+ padding: 30px;
margin: 10px;
+ width: 100%;
+ flex:1;
+}
+
+.recette-list-buttons {
+ display: flex;
+ flex-direction: row-reverse;
+}
+
+.recette-button {
+ border: 1px solid black;
+ border-radius: 10px;
+ padding : 10px;
+ box-shadow: 1px 1px 1px black;
+ background-color: blanchedalmond;
+}
+
+.recette-button:hover{
+ background-color: rgb(243, 215, 174);
}
.recette-liste-info-elem {
text-align: left;
+ padding: 4px;
+ padding-top: 6px;
+ padding-bottom: 6px;
+ color: #535353bd;
+ border-right: 1px solid #535353bd;
+ border-left: 1px solid #535353bd;
}
.recette-liste-info {
display: flex;
- flex-direction: column;
+ flex-direction: row;
}
.recette-liste-tag {
display: flex;
- flex-direction: row;
+ flex-wrap: wrap; /*trouvé à l'aide de ChatGPT car je n'arrivais pas à trouver*/
}
@@ -373,8 +400,8 @@ ul {
.formcont form .form-group input {
width: 95%;
box-sizing: border-box;
- font-size:3vmin;
- padding:1vmin;
+ font-size:3vmin;
+ padding:1vmin;
}
@@ -386,7 +413,7 @@ ul {
margin: 0 auto;
background: #ffa04d;
color: black;
- font-size: 5vmin;
+ font-size: 4vmin;
border-radius: 7px;
box-shadow: 2px 2px 0px #000000;
}
@@ -400,6 +427,30 @@ ul {
box-shadow: 3px 4px 5px #8c8c8c;
}
+.recette-form-div-desc {
+ height: 90%;
+}
+
+.recette-form {
+ height: 100%;
+ width: 100%;
+ margin: 10px;
+ padding: 10px;
+}
+
+.recette-form-group {
+ display: flex;
+ flex-direction: column;
+}
+
+#recette-form-div-desc {
+ height: 400px;
+}
+
+#recette-form-description {
+ height: 95%;
+}
+
/*Footer et son contenue*/
footer{
padding: 25px;
diff --git a/src/Domain/Controller.php b/src/Domain/Controller.php
index 4311c0b..0be0ade 100644
--- a/src/Domain/Controller.php
+++ b/src/Domain/Controller.php
@@ -4,6 +4,9 @@ namespace App\Domain;
use App\Http\Route;
+/**
+ * Classe abstraite des controllers qui vont pouvoir permettre de gérer les routes et leur retour.
+ */
abstract class Controller {
/**
diff --git a/src/Domain/Ingredients/Ingredient.php b/src/Domain/Ingredients/Ingredient.php
index 9fb655e..8a965db 100644
--- a/src/Domain/Ingredients/Ingredient.php
+++ b/src/Domain/Ingredients/Ingredient.php
@@ -4,15 +4,30 @@ namespace App\Domain\Ingredients;
use App\Domain\Model;
+/**
+ * Classe qui va gérer les ingrédients.
+ */
class Ingredient extends Model {
+ /**
+ * Le numéro de l'ingrédient.
+ * @var int
+ */
public int $num_ingredient;
+
+ /**
+ * Le nom de l'ingrédient
+ * @var string
+ */
public string $nom_ingredient;
+ /**
+ * Retourne le numéro de l'ingrédient.
+ * @return int
+ */
public function getID(): int
{
return $this->num_ingredient;
}
-
}
\ No newline at end of file
diff --git a/src/Domain/Ingredients/IngredientRepository.php b/src/Domain/Ingredients/IngredientRepository.php
index b0f2376..daca14c 100644
--- a/src/Domain/Ingredients/IngredientRepository.php
+++ b/src/Domain/Ingredients/IngredientRepository.php
@@ -6,15 +6,30 @@ use App\Domain\LinkableInterface;
use App\Domain\Recettes\Recette;
use App\Domain\Repository;
use App\Domain\Model;
+use App\Domain\Tags\Tag;
use App\Kernel;
+/**
+ * Classe qui va permettre de gérer les requêtes BDD en lien avec les ingrédients.
+ * Les ingrédients sont liables à d'autres entités comme les Recettes.
+ */
class IngredientRepository extends Repository implements LinkableInterface {
+ /**
+ * Permet d'avoir le nom de l'entité dont dépend ce repo.
+ * @return string
+ */
public static function getEntity(): string
{
return Ingredient::class;
}
+ /**
+ * La structure de notre table dans la BDD.
+ * Un champ link_recettes a été ajouté pour donner le nom de la table de lien entre nos recettes.
+ *
+ * @return array
+ */
public static function getStructure(): array
{
return [
@@ -27,6 +42,19 @@ class IngredientRepository extends Repository implements LinkableInterface {
}
+ /**
+ * Permet d'obtenir une liste de tous les ingrédients objet Ingreident.
+ *
+ * @return Ingredient[]|null
+ */
+ public function getAll(): ?array {
+ $sqlQuery = "SELECT * FROM {$this->tableName};";
+ $results = $this->selectGetAll($sqlQuery);
+ if( $results === null )
+ return null;
+ return $results;
+ }
+
/**
* Permet d'obtenir un ingrédient spécifique par son ID.
*
@@ -49,6 +77,7 @@ class IngredientRepository extends Repository implements LinkableInterface {
* @param string $linkingField Le champ qui permet de faire la liaison des ingrédients avec une autre entité.
* @param Model $linkedEntity L'autre entité.
*
+ * @see LinkableInterface
* @return array|null
*/
public function getIdLinkedTo( string $linkedTo, string $linkingField, Model $linkedEntity ): ?array {
@@ -64,6 +93,17 @@ class IngredientRepository extends Repository implements LinkableInterface {
return $results;
}
+ /**
+ * Permet d'ajouter un lien entre un ingrédient et une autre entité comme Recette.
+ *
+ * @param string $linkedTo
+ * @param string $linkingField
+ * @param Model $linkedEntity
+ * @param Model $ingredientEntity
+ *
+ * @see LinkableInterface
+ * @return bool
+ */
public function addLinkBetween( string $linkedTo, string $linkingField, Model $linkedEntity, Model $ingredientEntity ): bool {
$linkName = 'link_' . $linkedTo;
@@ -77,6 +117,17 @@ class IngredientRepository extends Repository implements LinkableInterface {
}
+ /**
+ * Retire un lien dans la BDD entre un ingrédient et une autre entité.
+ *
+ * @param string $linkedTo
+ * @param string $linkingField
+ * @param Model $linkedEntity
+ * @param Model $ingredientEntity
+ *
+ * @see LinkableInterface
+ * @return bool
+ */
public function removeLinkBetween(string $linkedTo, string $linkingField, Model $linkedEntity, Model $ingredientEntity ): bool
{
$linkName = 'link_' . $linkedTo;
@@ -88,14 +139,35 @@ class IngredientRepository extends Repository implements LinkableInterface {
return $statement->execute();
}
+ /**
+ * Ajouter un ingrédient dans la BDD.
+ *
+ * @param Model $ingredient
+ *
+ * @return bool
+ */
public function add( Model $ingredient ): bool {
return $this->addEntity( $ingredient );
}
+ /**
+ * Met à jour un ingrédient dans la BDD.
+ *
+ * @param Model $ingredient
+ *
+ * @return bool
+ */
public function update( Model $ingredient ): bool {
return $this->updateEntity( $ingredient, 'num_ingredient' );
}
+ /**
+ * Supprime un ingrédient de la BDD.
+ *
+ * @param Model $ingredient
+ *
+ * @return bool
+ */
public function delete( Model $ingredient ): bool {
return $this->deleteEntity( $ingredient, 'num_ingredient' );
}
diff --git a/src/Domain/Ingredients/UseIngredientsInterface.php b/src/Domain/Ingredients/UseIngredientsInterface.php
index d0163d6..9019473 100644
--- a/src/Domain/Ingredients/UseIngredientsInterface.php
+++ b/src/Domain/Ingredients/UseIngredientsInterface.php
@@ -4,6 +4,9 @@ namespace App\Domain\Ingredients;
use App\Domain\Model;
+/**
+ * Interface utilisée par tous les repository qui sont en lien avec les ingrédients.
+ */
interface UseIngredientsInterface {
/**
@@ -12,8 +15,24 @@ interface UseIngredientsInterface {
*/
public function getAllLinkedIngredients( Model $entity ): ?array;
+ /**
+ * Permet d'ajouter un ingrédient en lien avec notre autre entité.
+ *
+ * @param Ingredient $ingredient
+ * @param Model $entity
+ *
+ * @return bool
+ */
public function addAnIngredient( Ingredient $ingredient, Model $entity ): bool;
+ /**
+ * Permet de retirer un lien entre un ingrédient et une autre entité.
+ *
+ * @param Ingredient $ingredient
+ * @param Model $entity
+ *
+ * @return bool
+ */
public function removeAnIngredient( Ingredient $ingredient, Model $entity ): bool;
}
\ No newline at end of file
diff --git a/src/Domain/LinkableInterface.php b/src/Domain/LinkableInterface.php
index 79d9399..7ba5af9 100644
--- a/src/Domain/LinkableInterface.php
+++ b/src/Domain/LinkableInterface.php
@@ -2,12 +2,50 @@
namespace App\Domain;
+/**
+ * Interface pour dire qu'un objet peut avoir un lien avec un autre objet par une table.
+ * Il s'agit d'une interface qui s'utilise sur des repositories de meta-données (Tag, Ingrédients)
+ *
+ * Les champs de toutes les méthodes se présentent de la même façon.
+ * $linkedTo : Champ qui va désigner le nom de la table de liens que vous avez dans getStructure().
+ * $linkingField : Champ dans la BDD qui va permettre de lier l'élément courant et l'étranger.
+ * $linkedEntity : Une instance de l'entité étrangère que l'on veut lier.
+ */
interface LinkableInterface {
+ /**
+ * Permet de récupérer tous les liens entre notre entité implémentée et notre entité étrangère.
+ *
+ * @param string $linkedTo
+ * @param string $linkingField
+ * @param Model $linkedEntity
+ *
+ * @return array|null
+ */
public function getIdLinkedTo( string $linkedTo, string $linkingField, Model $linkedEntity ): ?array;
+ /**
+ * Permet d'ajouter un lien entre notre entité implémentée et notre entité étrangère.
+ *
+ * @param string $linkedTo
+ * @param string $linkingField
+ * @param Model $linkedEntity
+ * @param Model $entity
+ *
+ * @return bool
+ */
public function addLinkBetween( string $linkedTo, string $linkingField, Model $linkedEntity, Model $entity ): bool;
+ /**
+ * Permet de retirer un lien entre notre entité implémentée et notre entité étrangère.
+ *
+ * @param string $linkedTo
+ * @param string $linkingField
+ * @param Model $linkedEntity
+ * @param Model $entity
+ *
+ * @return bool
+ */
public function removeLinkBetween( string $linkedTo, string $linkingField, Model $linkedEntity, Model $entity ): bool;
}
\ No newline at end of file
diff --git a/src/Domain/Model.php b/src/Domain/Model.php
index fc59f5b..e9caa90 100644
--- a/src/Domain/Model.php
+++ b/src/Domain/Model.php
@@ -2,6 +2,9 @@
namespace App\Domain;
+/**
+ * Classe abstraite pour gérer l'implémentation des entités de données.
+ */
abstract class Model {
/**
diff --git a/src/Domain/Pages/PagesController.php b/src/Domain/Pages/PagesController.php
index 3d8612b..9982a09 100644
--- a/src/Domain/Pages/PagesController.php
+++ b/src/Domain/Pages/PagesController.php
@@ -11,11 +11,14 @@ use App\Infrastructure\View;
*/
class PagesController extends Controller {
+ /**
+ * Définit les routes globales d'acceuil.
+ * @return array|\App\Http\Route[]
+ */
public static function defineRoutes(): array
{
return [
self::Route( routeUrl: '/', routeName: 'home', routeAction: 'index', pageHeadTitle: "Home Page" ),
- self::Route( routeUrl: '/test/{int}/', routeName: 'test', routeAction: 'test' ),
];
}
@@ -28,8 +31,4 @@ class PagesController extends Controller {
return new View( 'home', [ 'ok' => 'bla' ] );
}
- public function test( string $id ): void {
- echo "Coucou" . $id;
- }
-
}
\ No newline at end of file
diff --git a/src/Domain/Recettes/Recette.php b/src/Domain/Recettes/Recette.php
index c7f44c2..6073250 100644
--- a/src/Domain/Recettes/Recette.php
+++ b/src/Domain/Recettes/Recette.php
@@ -2,11 +2,15 @@
namespace App\Domain\Recettes;
+use App\Domain\Ingredients\Ingredient;
use App\Domain\Ingredients\IngredientRepository;
use App\Domain\Ingredients\UseIngredientsInterface;
use App\Domain\Model;
use App\Helpers\Markdown;
+/**
+ * Classe qui va permettre de gérer tous les objets recette.
+ */
class Recette extends Model {
public int $num_recette;
@@ -22,13 +26,27 @@ class Recette extends Model {
return $this->num_recette;
}
+ /**
+ * Convertit la description de Markdown à HTML.
+ * @return string
+ */
public function getHTMLDescription(): string {
return Markdown::convertToHTML( $this->description_recette );
}
+ /**
+ * Récupère une liste de tous les ingrédients liés à la recette.
+ * @return Ingredient[]|null
+ */
public function getAllLinkedIngredients(): ?array
{
return new RecetteRepository()->getAllLinkedIngredients( $this );
}
+ public function getNumberOfIngredients(): int {
+
+ $response = $this->getAllLinkedIngredients();
+ return $response !== null ? count( $response ) : 0;
+ }
+
}
\ No newline at end of file
diff --git a/src/Domain/Recettes/RecetteRepository.php b/src/Domain/Recettes/RecetteRepository.php
index 10692ba..5806f8b 100644
--- a/src/Domain/Recettes/RecetteRepository.php
+++ b/src/Domain/Recettes/RecetteRepository.php
@@ -7,8 +7,15 @@ use App\Domain\Ingredients\IngredientRepository;
use App\Domain\Ingredients\UseIngredientsInterface;
use App\Domain\Model;
use App\Domain\Repository;
+use App\Domain\Tags\Tag;
+use App\Domain\Tags\TagRepository;
+use App\Domain\Tags\UseTagsInterface;
-class RecetteRepository extends Repository implements UseIngredientsInterface {
+/**
+ * Classe qui permet de faire le lien entre la BDD et le site pour les recettes.
+ * Les recettes sont en lien avec les ingrédients.
+ */
+class RecetteRepository extends Repository implements UseIngredientsInterface, UseTagsInterface {
public static function getEntity(): string
{
@@ -26,6 +33,42 @@ class RecetteRepository extends Repository implements UseIngredientsInterface {
}
+ /**
+ * Permet d'obtenir une liste de toutes les recettes objet Recette.
+ *
+ * @return Recette[]|null
+ */
+ public function getAll(): ?array {
+ $sqlQuery = "SELECT * FROM {$this->tableName};";
+ $results = $this->selectGetAll($sqlQuery);
+ if( $results === null )
+ return null;
+ return $results;
+ }
+
+ /**
+ * Permet d'obtenir toutes les recettes paginées.
+ * Mise par défaut dans l'ordre croissant du titre et avec une pagination de 15 éléments.
+ *
+ * @param int $page
+ * @param int $pagination
+ *
+ * @return array|null
+ */
+ public function getAllRecettesBrowse( int $page = 1, int $pagination = 15 ){
+
+ if( $page <= 0 )
+ $page = 1;
+
+ $offset = ( $page - 1 ) * $pagination;
+
+ $sqlQuery = "SELECT * FROM {$this->tableName} ORDER BY titre_recette ASC LIMIT {$pagination} OFFSET {$offset};";
+ $results = $this->selectGetAll($sqlQuery);
+ if( $results === null )
+ return null;
+ return $results;
+ }
+
/**
* Permet d'avoir une recette par un ID.
*
@@ -72,6 +115,8 @@ class RecetteRepository extends Repository implements UseIngredientsInterface {
{
$ingredientRepo = new IngredientRepository();
$response = $ingredientRepo->getIdLinkedTo( 'recettes', 'num_recette', $entity );
+ if( $response === null )
+ return null;
return array_map( function($arr) use($ingredientRepo) {
return $ingredientRepo->getByID( $arr['num_ingredient'] );
@@ -81,13 +126,37 @@ class RecetteRepository extends Repository implements UseIngredientsInterface {
public function addAnIngredient(Ingredient $ingredient, Model $entity): bool
{
$ingredientRepo = new IngredientRepository();
- return $ingredientRepo->addLinkBetween( 'recettes', 'num_recette', $ingredient, $entity );
+ return $ingredientRepo->addLinkBetween( 'recettes', 'num_recette', $entity, $ingredient );
}
public function removeAnIngredient(Ingredient $ingredient, Model $entity): bool
{
$ingredientRepo = new IngredientRepository();
- return $ingredientRepo->removeLinkBetween( 'recettes', 'num_recette', $ingredient, $entity );
+ return $ingredientRepo->removeLinkBetween( 'recettes', 'num_recette', $entity, $ingredient );
+ }
+
+ public function getAllLinkedTags(Model $entity): ?array
+ {
+ $tagRepo = new TagRepository();
+ $response = $tagRepo->getIdLinkedTo( 'recettes', 'num_recette', $entity );
+ if( $response === null )
+ return null;
+
+ return array_map( function($arr) use($tagRepo) {
+ return $tagRepo->getByID( $arr['num_tag'] );
+ }, $response );
+ }
+
+ public function addATag(Tag $tag, Model $entity): bool
+ {
+ $tagRepo = new TagRepository();
+ return $tagRepo->addLinkBetween( 'recettes', 'num_recette', $entity, $tag );
+ }
+
+ public function removeATag(Tag $tag, Model $entity): bool
+ {
+ $tagRepo = new TagRepository();
+ return $tagRepo->removeLinkBetween( 'recettes', 'num_recette', $entity, $tag );
}
}
\ No newline at end of file
diff --git a/src/Domain/Recettes/RecettesController.php b/src/Domain/Recettes/RecettesController.php
index 1ed1dc8..6264eb0 100644
--- a/src/Domain/Recettes/RecettesController.php
+++ b/src/Domain/Recettes/RecettesController.php
@@ -3,7 +3,10 @@
namespace App\Domain\Recettes;
use App\Domain\Controller;
+use App\Domain\Ingredients\IngredientRepository;
+use App\Domain\Tags\TagRepository;
use App\Http\JSONResponse;
+use App\Http\Request;
use App\Infrastructure\View;
class RecettesController extends Controller {
@@ -18,7 +21,16 @@ class RecettesController extends Controller {
}
public function index(): View {
- return new View( 'recettes/index', [] );
+
+ $page = Request::get( 'page' );
+ if( $page == null )
+ $page = 1;
+
+ return new View( 'recettes/index', [
+ 'tagsList' => new TagRepository()->getAll(),
+ 'ingredientsList' => new IngredientRepository()->getAll(),
+ 'recettesList' => new RecetteRepository()->getAllRecettesBrowse( $page ),
+ ] );
}
}
\ No newline at end of file
diff --git a/src/Domain/Repository.php b/src/Domain/Repository.php
index 2de7a9a..c6fb738 100644
--- a/src/Domain/Repository.php
+++ b/src/Domain/Repository.php
@@ -6,6 +6,9 @@ use App\Domain\Recettes\Recette;
use App\Kernel;
use PDO;
+/**
+ * Classe abstraite avec des méthodes pour pouvoir gérer les liens entre le site et la base de données.
+ */
abstract class Repository {
/**
diff --git a/src/Domain/Tags/Tag.php b/src/Domain/Tags/Tag.php
new file mode 100644
index 0000000..56f1102
--- /dev/null
+++ b/src/Domain/Tags/Tag.php
@@ -0,0 +1,33 @@
+num_tag;
+ }
+
+}
\ No newline at end of file
diff --git a/src/Domain/Tags/TagRepository.php b/src/Domain/Tags/TagRepository.php
new file mode 100644
index 0000000..e42e1f3
--- /dev/null
+++ b/src/Domain/Tags/TagRepository.php
@@ -0,0 +1,174 @@
+ 'Tag',
+ 'columns' => [
+ 'num_tag', 'nom_tag'
+ ],
+ 'link_recettes' => 'Referencetag'
+ ];
+
+ }
+
+ /**
+ * Permet d'obtenir une liste de tous les tags objet Tag.
+ *
+ * @return Tag[]|null
+ */
+ public function getAll(): ?array {
+ $sqlQuery = "SELECT * FROM {$this->tableName};";
+ $results = $this->selectGetAll($sqlQuery);
+ if( $results === null )
+ return null;
+ return $results;
+ }
+
+ /**
+ * Permet d'obtenir un tag spécifique par son ID.
+ *
+ * @param int $id
+ *
+ * @return Tag|null
+ */
+ public function getByID( int $id ): ?Tag {
+ $sqlQuery = "SELECT * FROM {$this->tableName} WHERE num_tag = {$id}";
+ $results = $this->selectGetAll($sqlQuery);
+ if( $results === null || count( $results ) > 1 )
+ return null;
+ return $results[0];
+ }
+
+ /**
+ * Permet d'obtenir, sous forme de liste, toutes les entrées qui lient des tags.
+ *
+ * @param string $linkedTo La table qui permet de faire la liaison des tags avec une autre entité.
+ * @param string $linkingField Le champ qui permet de faire la liaison des tags avec une autre entité.
+ * @param Model $linkedEntity L'autre entité.
+ *
+ * @see LinkableInterface
+ * @return array|null
+ */
+ public function getIdLinkedTo( string $linkedTo, string $linkingField, Model $linkedEntity ): ?array {
+
+ $linkName = 'link_' . $linkedTo;
+ if( !isset( $this->globalStructure[$linkName]))
+ return null;
+
+ $sqlQuery = "SELECT * FROM {$this->globalStructure[$linkName]} WHERE {$linkingField} = {$linkedEntity->getId()};";
+ $results = $this->selectGetAll($sqlQuery, true);
+ if( $results === null )
+ return null;
+ return $results;
+ }
+
+ /**
+ * Permet d'ajouter un lien entre un tag et une autre entité comme Recette.
+ *
+ * @param string $linkedTo
+ * @param string $linkingField
+ * @param Model $linkedEntity
+ * @param Model $tagEntity
+ *
+ * @see LinkableInterface
+ * @return bool
+ */
+ public function addLinkBetween( string $linkedTo, string $linkingField, Model $linkedEntity, Model $tagEntity ): bool {
+
+ $linkName = 'link_' . $linkedTo;
+ if( !isset( $this->globalStructure[$linkName]))
+ return false;
+
+ $query = "INSERT INTO {$this->globalStructure[$linkName]} ({$linkingField},num_tag) VALUES ({$linkedEntity->getId()}, {$tagEntity->getID()});";
+ $statement = Kernel::$DB->pdo->prepare( $query );
+
+ return $statement->execute();
+
+ }
+
+ /**
+ * Retire un lien dans la BDD entre un tag et une autre entité.
+ *
+ * @param string $linkedTo
+ * @param string $linkingField
+ * @param Model $linkedEntity
+ * @param Model $tagEntity
+ *
+ * @see LinkableInterface
+ * @return bool
+ */
+ public function removeLinkBetween(string $linkedTo, string $linkingField, Model $linkedEntity, Model $tagEntity ): bool
+ {
+ $linkName = 'link_' . $linkedTo;
+ if( !isset( $this->globalStructure[$linkName]))
+ return false;
+
+ $query = "DELETE FROM {$this->globalStructure[$linkName]} WHERE {$linkingField} = {$linkedEntity->getId()} AND num_tag = {$tagEntity->getId()};";
+ $statement = Kernel::$DB->pdo->prepare( $query );
+ return $statement->execute();
+ }
+
+ /**
+ * Ajouter un tag dans la BDD.
+ *
+ * @param Model $ingredient
+ *
+ * @return bool
+ */
+ public function add( Model $tag ): bool {
+ return $this->addEntity( $tag );
+ }
+
+ /**
+ * Met à jour un tag dans la BDD.
+ *
+ * @param Model $tag
+ *
+ * @return bool
+ */
+ public function update( Model $tag ): bool {
+ return $this->updateEntity( $tag, 'num_tag' );
+ }
+
+ /**
+ * Supprime un tag de la BDD.
+ *
+ * @param Model $tag
+ *
+ * @return bool
+ */
+ public function delete( Model $tag ): bool {
+ return $this->deleteEntity( $tag, 'num_tag' );
+ }
+
+}
\ No newline at end of file
diff --git a/src/Domain/Tags/UseTagsInterface.php b/src/Domain/Tags/UseTagsInterface.php
new file mode 100644
index 0000000..90a6fa2
--- /dev/null
+++ b/src/Domain/Tags/UseTagsInterface.php
@@ -0,0 +1,38 @@
+routeUrl);
- return rtrim( Kernel::$configs['general']['website_url'] . $routeUrl, '/' );
+ return rtrim( rtrim( Kernel::$configs['general']['website_url'], '/' ) . $routeUrl, '/' );
}
}
diff --git a/views/partials/header.php b/views/partials/header.php
index 2848cdd..292c5c5 100644
--- a/views/partials/header.php
+++ b/views/partials/header.php
@@ -16,10 +16,11 @@