summaryrefslogtreecommitdiff
path: root/src/model
diff options
context:
space:
mode:
Diffstat (limited to 'src/model')
-rw-r--r--src/model/Menu.php53
-rw-r--r--src/model/Path.php84
-rw-r--r--src/model/doctrine-bootstrap.php31
-rw-r--r--src/model/entities/Article.php77
-rw-r--r--src/model/entities/Image.php91
-rw-r--r--src/model/entities/Node.php168
-rw-r--r--src/model/entities/NodeData.php62
-rw-r--r--src/model/entities/Page.php97
-rw-r--r--src/model/entities/User.php47
9 files changed, 710 insertions, 0 deletions
diff --git a/src/model/Menu.php b/src/model/Menu.php
new file mode 100644
index 0000000..624a0fc
--- /dev/null
+++ b/src/model/Menu.php
@@ -0,0 +1,53 @@
1<?php
2// src/controller/Menu.php
3
4declare(strict_types=1);
5
6use Doctrine\ORM\EntityManager;
7use App\Entity\Page;
8use Doctrine\Common\Collections\ArrayCollection;
9
10class Menu extends Page
11{
12 private EntityManager $entityManager;
13 private array $other_pages = []; // pages n'apparaissant pas dans le menu
14
15 public function __construct(EntityManager $entityManager){
16 $this->children = new ArrayCollection();
17
18 $bulk_data = $entityManager
19 ->createQuery('SELECT n FROM App\Entity\Page n WHERE n.parent IS null') // :Doctrine\ORM\Query
20 ->getResult(); // :array de Page
21
22 if(count($bulk_data) === 0){
23 makeStartPage($entityManager);
24 }
25
26 foreach($bulk_data as $first_level_entries){
27 // génération du menu
28 if($first_level_entries->getInMenu()){
29 $this->addChild($first_level_entries);
30 }
31 // autres pages
32 else{
33 // attention, seul le premier élément du chemin est pris en compte
34 $this->other_pages[] = $first_level_entries;
35 }
36 }
37
38 foreach($this->getChildren() as $page){
39 $page->fillChildrenPagePath();
40 }
41
42 /*for($i = 0; $i < count($this->getChildren()[1]->getChildren()); $i++){
43 echo $this->getChildren()[1]->getChildren()[$i]->getEndOfPath() . ' - ';
44 echo $this->getChildren()[1]->getChildren()[$i]->getPageName() . '<br>';
45 }*/
46 //die;
47 }
48
49 public function getOtherPages(): array
50 {
51 return $this->other_pages;
52 }
53} \ No newline at end of file
diff --git a/src/model/Path.php b/src/model/Path.php
new file mode 100644
index 0000000..6faadfd
--- /dev/null
+++ b/src/model/Path.php
@@ -0,0 +1,84 @@
1<?php
2// src/controller/Path.php
3
4declare(strict_types=1);
5
6use Doctrine\ORM\EntityManager;
7use App\Entity\Page;
8
9class Path extends Page
10{
11 private array $current_page = []; // tableau d'objets Page
12
13 public function __construct()
14 {
15 $path_array = explode('/', CURRENT_PAGE);
16 try{
17 $this->findPage(Director::$menu_data, $path_array); // remplit $this->current_page
18 }
19 catch(Exception $e){}
20 /*echo "nb d'autres pages: " . count(Director::$menu_data->getOtherPages()) . '<br>';
21 echo 'longueur du chemin: ' . count($this->current_page) . '<br>';
22 foreach($this->current_page as $current){
23 echo $current->getEndOfPath() . ' ';
24 }
25 die;*/
26 }
27
28 // produit un tableau de Page en comparant le chemin demandé avec les données dans Menu
29 // succès => une exception est lancée pour sortir des fonctions imbriquées
30 // echec => redirection vers la page erreur 404
31 private function findPage(Page|Menu $menu, array $path_array)
32 {
33 // recherche dans les autres pages
34 if($menu instanceof Menu){
35 foreach($menu->getOtherPages() as $page)
36 {
37 if($path_array[0] === $page->getEndOfPath())
38 {
39 $this->current_page[] = $page;
40 throw new Exception();
41 }
42 }
43 }
44 // recherche dans le menu
45 foreach($menu->getChildren() as $page)
46 {
47 if($path_array[0] === $page->getEndOfPath())
48 {
49 $this->current_page[] = $page;
50 if(count($path_array) > 1)
51 {
52 array_shift($path_array); // $this->path_array n'est pas modifié, un tableau PHP est passé à une fonction par copie
53 $this->findPage($page, $path_array);
54 }
55 else{
56 throw new Exception(); // sortir de tous les findPage() en même temps
57 }
58 }
59 }
60 // rien trouvé
61 URL::setPath('erreur404.html');
62 header('Location: '. new URL);
63 die;
64 }
65
66 public function getString(): string
67 {
68 $path_string = "";
69 foreach($this->current_page as $one_page){
70 $path_string .= $one_page->getEndOfPath() . '/';
71 }
72 return rtrim($path_string, '/');
73 }
74 public function getArray(): array
75 {
76 return $this->current_page;
77 }
78
79 // c'est là qu'on est quoi
80 public function getLast(): Page
81 {
82 return $this->current_page[count($this->current_page) - 1];
83 }
84} \ No newline at end of file
diff --git a/src/model/doctrine-bootstrap.php b/src/model/doctrine-bootstrap.php
new file mode 100644
index 0000000..139f410
--- /dev/null
+++ b/src/model/doctrine-bootstrap.php
@@ -0,0 +1,31 @@
1<?php
2// src/model/doctrine-bootstrap.php
3
4use Doctrine\ORM\ORMSetup;
5use Doctrine\DBAL\DriverManager;
6use Doctrine\ORM\EntityManager;
7
8require_once "../vendor/autoload.php";
9
10// Create a simple "default" Doctrine ORM configuration for Attributes
11$config = ORMSetup::createAttributeMetadataConfiguration(
12 //paths: array(__DIR__.'/entities'),
13 paths: array('../src/model/entities'),
14 isDevMode: true,
15 // true: cache en mémoire vive
16 // false: utilisation de APCu ou redis ou memcache
17);
18
19// configuring the database connection
20$connection = DriverManager::getConnection([
21 'driver' => Config::$db_driver,
22 'user' => Config::$user,
23 'password' => Config::$password,
24 'host' => Config::$db_host,
25 'dbname' => Config::$database,
26], $config);
27
28// obtaining the entity manager
29$entityManager = new EntityManager($connection, $config);
30
31foreach($entityManager->getMetadataFactory()->getAllMetadata() as $class){} \ No newline at end of file
diff --git a/src/model/entities/Article.php b/src/model/entities/Article.php
new file mode 100644
index 0000000..3b846da
--- /dev/null
+++ b/src/model/entities/Article.php
@@ -0,0 +1,77 @@
1<?php
2// src/model/entities/Article.php
3
4declare(strict_types=1);
5
6namespace App\Entity;
7
8use Doctrine\ORM\Mapping as ORM;
9use Doctrine\Common\Collections\ArrayCollection;
10use Doctrine\Common\Collections\Collection;
11
12#[ORM\Entity]
13#[ORM\Table(name: TABLE_PREFIX . "article")]
14class Article
15{
16 #[ORM\Id]
17 #[ORM\GeneratedValue]
18 #[ORM\Column(type: "integer")]
19 private int $id_article;
20
21 // datetime_immutable permet à la base de toujours gérer cette clé primaire correctement
22 #[ORM\Column(type: 'datetime', options: ['default' => 'CURRENT_TIMESTAMP'], unique: true)]
23 private \DateTime $date_time; // le type datetime de doctrine convertit en type \DateTime de PHP
24
25 #[ORM\Column(type: "string")]
26 private string $title;
27
28 #[ORM\Column(type: "text")]
29 private string $preview; // une simple textarea
30
31 #[ORM\Column(type: "text")]
32 private string $content; // de l'éditeur html
33
34 // liaison avec table intermédiaire
35 #[ORM\ManyToMany(targetEntity: Image::class, inversedBy: "article")]
36 #[ORM\JoinTable(
37 name: "nb_article_image",
38 joinColumns: [new ORM\JoinColumn(name: "article_id", referencedColumnName: "id_article", onDelete: "CASCADE")],
39 inverseJoinColumns: [new ORM\JoinColumn(name: "image_id", referencedColumnName: "id_image", onDelete: "CASCADE")]
40 )]
41 private Collection $images;
42
43 public function __construct()
44 {
45 $this->images = new ArrayCollection(); // initialisation nécessaire
46 }
47
48 public function getDateTime(): \DateTime
49 {
50 return $this->date_time;
51 }
52 public function getTimestamp(): int
53 {
54 return $this->date_time->getTimestamp();
55 }
56 public function getTitle(): string
57 {
58 return $this->title;
59 }
60 public function getPreview(): string
61 {
62 return $this->preview;
63 }
64 public function getContent(): string
65 {
66 return $this->content;
67 }
68 public function setContent(string $data): void
69 {
70 $this->content = $data;
71 }
72
73 public function getImages(): Collection
74 {
75 return $this->images;
76 }
77}
diff --git a/src/model/entities/Image.php b/src/model/entities/Image.php
new file mode 100644
index 0000000..181c137
--- /dev/null
+++ b/src/model/entities/Image.php
@@ -0,0 +1,91 @@
1<?php
2// src/model/entities/Image.php
3
4declare(strict_types=1);
5
6namespace App\Entity;
7
8use Doctrine\ORM\Mapping as ORM;
9
10#[ORM\Entity]
11#[ORM\Table(name: TABLE_PREFIX . "image")]
12class Image
13{
14 #[ORM\Id]
15 #[ORM\GeneratedValue]
16 #[ORM\Column(type: "integer")]
17 private int $id_image;
18
19 #[ORM\Column(type: "string", length: 255, unique: true)] // nom d'image UNIQUE
20 private string $file_name;
21
22 // choisir un répertoire du genre /var/www/html/uploads/ de préférence hors de /src
23 #[ORM\Column(type: "string", length: 255, unique: true, nullable: true)]
24 private ?string $file_path;
25
26 #[ORM\Column(type: "string", length: 255, unique: true, nullable: true)]
27 private ?string $file_path_mini;
28
29 #[ORM\Column(type: "string", length: 255, nullable: true)]
30 private string $mime_type; // image/jpeg, image/png, etc
31
32 #[ORM\Column(type: "string", length: 255, nullable: true)]
33 private string $alt; // texte alternatif
34
35 // autre champs optionnels: file_size, date (default current timestamp)
36
37 /* étapes au téléchargement:
38 => Validation du type de fichier : On vérifie que le fichier est bien une image en utilisant le type MIME. On peut aussi vérifier la taille du fichier.
39 => Création d'un répertoire structuré : On génère un chemin dynamique basé sur la date (uploads/2024/12/24/) pour organiser les images.
40 => Génération d'un nom de fichier unique : On utilise uniqid() pour générer un nom unique et éviter les conflits de nom.
41 => Déplacement du fichier sur le serveur : Le fichier est déplacé depuis son emplacement temporaire vers le répertoire uploads/.
42 => Enregistrement dans la base de données : On enregistre les informations de l'image dans la base de données. */
43
44 #[ORM\ManyToMany(targetEntity: NodeData::class, mappedBy: "images")]
45 private $node_data;
46
47 #[ORM\ManyToMany(targetEntity: Article::class, mappedBy: "images")]
48 private $article;
49
50 public function __construct(string $name, ?string $path, ?string $path_mini, string $mime_type, string $alt)
51 {
52 $this->file_name = $name;
53 $this->file_path = $path;
54 $this->file_path_mini = $path_mini;
55 $this->mime_type = $mime_type;
56 $this->alt = $alt;
57 }
58
59 public function getFileName(): string
60 {
61 return $this->file_name;
62 }
63 public function getFilePath(): string
64 {
65 return $this->file_path;
66 }
67 public function getFilePathMini(): string
68 {
69 return $this->file_path_mini;
70 }
71 public function getAlt(): string
72 {
73 return $this->alt;
74 }
75
76
77 // pour ViewBuilder?
78 /*public function displayImage($imageId): void
79 {
80 //$imageId = 1; // Exemple d'ID d'image
81 $stmt = $pdo->prepare("SELECT file_path FROM images WHERE id = ?");
82 $stmt->execute([$imageId]);
83 $image = $stmt->fetch();
84
85 if ($image) {
86 echo "<img src='" . $image['file_path'] . "' alt='Image'>";
87 } else {
88 echo "Image non trouvée.";
89 }
90 }*/
91}
diff --git a/src/model/entities/Node.php b/src/model/entities/Node.php
new file mode 100644
index 0000000..49e16ba
--- /dev/null
+++ b/src/model/entities/Node.php
@@ -0,0 +1,168 @@
1<?php
2// src/model/entities/Node.php
3
4declare(strict_types=1);
5
6namespace App\Entity;
7
8use Config;
9use Doctrine\ORM\Mapping as ORM;
10
11#[ORM\Entity]
12#[ORM\Table(name: TABLE_PREFIX . "node")]
13class Node
14{
15 #[ORM\Id]
16 #[ORM\GeneratedValue]
17 #[ORM\Column(type: "integer")]
18 private int $id_node;
19
20 #[ORM\Column(type: "string", length: 255)]
21 private string $name_node;
22
23 #[ORM\Column(type: "string", length: 255, unique: true, nullable: true)]
24 private ?string $article_timestamp;
25
26 #[ORM\Column(type: "json", nullable: true)] // type: "json" crée un longtext avec mariadb
27 private ?array $attributes = null;
28
29 #[ORM\Column(type: "integer")]
30 private int $position;
31
32 #[ORM\ManyToOne(targetEntity: self::class)]
33 //#[ORM\ManyToOne(targetEntity: self::class, fetch: 'EAGER')] // À TESTER
34 #[ORM\JoinColumn(name: "parent_id", referencedColumnName: "id_node", onDelete: "SET NULL", nullable: true)]
35 private ?self $parent = null;
36
37 #[ORM\ManyToOne(targetEntity: Page::class)]
38 #[ORM\JoinColumn(name: "page_id", referencedColumnName: "id_page", onDelete: "SET DEFAULT", nullable: true)]
39 private ?Page $page;
40
41 #[ORM\ManyToOne(targetEntity: Article::class, cascade: ['persist'])]
42 #[ORM\JoinColumn(name: "article_id", referencedColumnName: "id_article", onDelete: "SET NULL", nullable: true)]
43 private ?Article $article = null;
44
45 // propriété non mappée dans la table "node", la jointure est décrite dans NodeData
46 // elle sert à persister ou supprimer des données par cascade
47 // "mappedBy" permet de cibler $node dans l'autre classe, qui elle possède un "inversedBy"
48 #[ORM\OneToOne(targetEntity: NodeData::class, mappedBy: "node", cascade: ['persist', 'remove'])]
49 private ?NodeData $node_data = null;
50
51
52 // -- fin des attributs destinés à doctrine, début du code utilisateur --
53
54 private array $children = []; // tableau de Node
55 private ?self $temp_child = null; // = "new" est l'enfant de "main" lorsque la page est "article"
56
57 public function __construct(string $name = '', ?string $article_timestamp = null, array $attributes = [], int $position = 0, ?self $parent = null, ?Page $page = null, ?Article $article = null)
58 {
59 $this->name_node = $name;
60 $this->article_timestamp = $article_timestamp;
61 $this->attributes = $attributes;
62 $this->position = $position;
63 $this->parent = $parent;
64 $this->page = $page;
65 $this->article = $article;
66 }
67
68 public function addChild(self $child): void
69 {
70 $this->children[] = $child;
71 $this->sortChildren();
72 }
73
74 // utiliser $position pour afficher les éléments dans l'ordre
75 private function sortChildren(): void
76 {
77 $iteration = count($this->children);
78 while($iteration > 1)
79 {
80 for($i = 0; $i < $iteration - 1; $i++)
81 {
82 //echo '<br>' . $this->children[$i]->getPosition() . ' - ' . $this->children[$i + 1]->getPosition();
83 if($this->children[$i]->getPosition() > $this->children[$i + 1]->getPosition())
84 {
85 $tmp = $this->children[$i];
86 $this->children[$i] = $this->children[$i + 1];
87 $this->children[$i + 1] = $tmp;
88 }
89 }
90 $iteration--;
91 }
92 }
93
94 // pfff...
95 public function getId(): int
96 {
97 return $this->id_node;
98 }
99 public function getName(): string
100 {
101 return $this->name_node;
102 }
103 /*public function setName(string $name): void
104 {
105 $this->name_node = $name;
106 }*/
107 public function getArticleTimestamp(): string
108 {
109 return $this->article_timestamp;
110 }
111 public function getAttributes(): array
112 {
113 return $this->attributes;
114 }
115 /*public function setAttributes(array $attributes): void
116 {
117 $this->attributes = $attributes;
118 }*/
119 public function getParent(): ?self
120 {
121 return $this->parent;
122 }
123 /*public function setParent(?self $parent): void
124 {
125 $this->parent = $parent;
126 }*/
127 public function getPosition(): int
128 {
129 return $this->position;
130 }
131 /*public function setPosition(int $position): void
132 {
133 $this->position = $position;
134 }*/
135 public function getPage(): Page
136 {
137 return $this->page;
138 }
139 /*public function setPage(Page $page): void
140 {
141 $this->page = $page;
142 }*/
143 public function getArticle(): Article
144 {
145 return $this->article;
146 }
147 /*public function setArticle(Article $article): void
148 {
149 $this->article = $article;
150 }*/
151 public function getNodeData(): ?NodeData
152 {
153 return $this->node_data;
154 }
155 public function getChildren(): array
156 {
157 return $this->children;
158 }
159
160 public function getTempChild(): ?self // peut renvoyer null
161 {
162 return $this->temp_child;
163 }
164 public function setTempChild(self $child): void
165 {
166 $this->temp_child = $child;
167 }
168}
diff --git a/src/model/entities/NodeData.php b/src/model/entities/NodeData.php
new file mode 100644
index 0000000..ddf6083
--- /dev/null
+++ b/src/model/entities/NodeData.php
@@ -0,0 +1,62 @@
1<?php
2// src/model/entities/NodeData.php
3
4declare(strict_types=1);
5
6namespace App\Entity;
7
8use Doctrine\ORM\Mapping as ORM;
9use Doctrine\Common\Collections\ArrayCollection; // classe
10use Doctrine\Common\Collections\Collection; // interface
11
12#[ORM\Entity]
13#[ORM\Table(name: TABLE_PREFIX . "node_data")]
14class NodeData
15{
16 #[ORM\Id]
17 #[ORM\GeneratedValue]
18 #[ORM\Column(type: "integer")]
19 private int $id_node_data;
20
21 // onDelete: "CASCADE" supprime les données si le noeud est supprimé
22 // inverseBy fait le lien avec $node_data dans Node (qui a "mappedBy")
23 #[ORM\OneToOne(targetEntity: Node::class, inversedBy: "node_data")]
24 #[ORM\JoinColumn(name: "node_id", referencedColumnName: "id_node", onDelete: "CASCADE")]
25 private Node $node;
26
27 #[ORM\Column(type: "json")]
28 private array $data;
29
30 // liaison avec table intermédiaire
31 #[ORM\ManyToMany(targetEntity: Image::class, inversedBy: "id_image")]
32 #[ORM\JoinTable(
33 name: "nb_node_image",
34 joinColumns: [new ORM\JoinColumn(name: "node_data_id", referencedColumnName: "id_node_data", onDelete: "CASCADE")],
35 inverseJoinColumns: [new ORM\JoinColumn(name: "image_id", referencedColumnName: "id_image", onDelete: "CASCADE")]
36 )]
37 private Collection $images;
38
39 public function __construct(array $data, Node $node, Collection $images = new ArrayCollection)
40 {
41 $this->data = $data;
42 $this->node = $node;
43 $this->images = $images;
44 }
45
46 public function getData(): array
47 {
48 return $this->data;
49 }
50 /*public function setData(array $data): void
51 {
52 $this->data = $data;
53 }
54 public function setNode(Node $node): void
55 {
56 $this->node = $node;
57 }*/
58 public function getImages(): Collection
59 {
60 return $this->images;
61 }
62}
diff --git a/src/model/entities/Page.php b/src/model/entities/Page.php
new file mode 100644
index 0000000..d7d8098
--- /dev/null
+++ b/src/model/entities/Page.php
@@ -0,0 +1,97 @@
1<?php
2// src/model/entities/Page.php
3
4declare(strict_types=1);
5
6namespace App\Entity;
7
8use Doctrine\ORM\Mapping as ORM;
9use Doctrine\Common\Collections\Collection;
10use Doctrine\Common\Collections\ArrayCollection;
11
12#[ORM\Entity]
13#[ORM\Table(name: TABLE_PREFIX . "page")]
14class Page
15{
16 #[ORM\Id]
17 #[ORM\GeneratedValue]
18 #[ORM\Column(type: "integer")]
19 private int $id_page;
20
21 #[ORM\Column(type: "string", length: 255)]
22 private string $name_page;
23
24 #[ORM\Column(type: "string", length: 255)]
25 private string $end_of_path; // morceau d'URL plus exactement
26
27 private string $page_path;
28
29 #[ORM\Column(type: "boolean")]
30 private bool $reachable;
31
32 #[ORM\Column(type: "boolean")]
33 private bool $in_menu;
34
35 #[ORM\ManyToOne(targetEntity: self::class)]
36 #[ORM\JoinColumn(name: "parent_id", referencedColumnName: "id_page", onDelete: "SET NULL", nullable: true)]
37 private ?self $parent = null;
38
39 #[ORM\OneToMany(targetEntity: self::class, mappedBy: 'parent')]
40 protected Collection $children;
41
42 /*#[ORM\Column(type: "json", nullable: true)]
43 private ?array $metadata = null;*/
44
45 public function __construct(string $name, string $eop, bool $reachable, bool $in_menu, ?Page $parent)
46 {
47 $this->name_page = $name;
48 $this->end_of_path = $eop;
49 $this->reachable = $reachable;
50 $this->in_menu = $in_menu;
51 $this->parent = $parent;
52 $this->children = new ArrayCollection();
53 }
54
55 // getters
56 /*public function getId(): int
57 {
58 return $this->id_page;
59 }*/
60 public function getPageName(): string
61 {
62 return $this->name_page;
63 }
64 public function getPagePath(): string
65 {
66 return $this->page_path;
67 }
68 public function getEndOfPath(): string
69 {
70 return $this->end_of_path;
71 }
72 public function getInMenu(): bool
73 {
74 return $this->in_menu;
75 }
76 public function getParent(): ?Page
77 {
78 return $this->parent;
79 }
80 public function getChildren(): Collection
81 {
82 return $this->children;
83 }
84
85 public function fillChildrenPagePath(string $parent_path = ''): void
86 {
87 $this->page_path = $parent_path != '' ? $parent_path . '/' . $this->end_of_path : $this->end_of_path;
88 foreach($this->getChildren() as $page){
89 $page->fillChildrenPagePath($this->page_path);
90 }
91 }
92
93 public function addChild(self $child): void
94 {
95 $this->children[] = $child;
96 }
97}
diff --git a/src/model/entities/User.php b/src/model/entities/User.php
new file mode 100644
index 0000000..4b1dcb8
--- /dev/null
+++ b/src/model/entities/User.php
@@ -0,0 +1,47 @@
1<?php
2// src/model/entities/User.php
3
4declare(strict_types=1);
5
6namespace App\Entity;
7
8use Doctrine\ORM\Mapping as ORM;
9
10#[ORM\Entity]
11#[ORM\Table(name: TABLE_PREFIX . "user")]
12class User
13{
14 #[ORM\Id]
15 #[ORM\GeneratedValue]
16 #[ORM\Column(type: "integer")]
17 private int $id_user;
18
19 /*#[ORM\Column(type: "string", length: 255)]
20 private string $name;*/
21
22 #[ORM\Column(type: "string", length: 255, unique: true)] // risque de modifier son mot de passe sans s'apercevoir qu'il fonctionne encore sur un autre compte
23 private string $login;
24
25 #[ORM\Column(type: "string", length: 255)]
26 private string $password;
27
28 public function __construct(string $login, string $password)
29 {
30 $this->login = $login;
31 $this->password = $password;
32 }
33
34 public function getLogin(): string
35 {
36 return $this->login;
37 }
38 public function getPassword(): string
39 {
40 return $this->password;
41 }
42
43 public function setPassword(string $password): void
44 {
45 $this->password = $password;
46 }
47} \ No newline at end of file