aboutsummaryrefslogtreecommitdiff
path: root/src/Model/Entity/Node.php
diff options
context:
space:
mode:
Diffstat (limited to 'src/Model/Entity/Node.php')
-rw-r--r--src/Model/Entity/Node.php167
1 files changed, 167 insertions, 0 deletions
diff --git a/src/Model/Entity/Node.php b/src/Model/Entity/Node.php
new file mode 100644
index 0000000..07666c3
--- /dev/null
+++ b/src/Model/Entity/Node.php
@@ -0,0 +1,167 @@
1<?php
2// src/Model/Entity/Node.php
3
4declare(strict_types=1);
5
6namespace App\Entity;
7
8use Doctrine\ORM\Mapping as ORM;
9use App\Model\Position;
10
11#[ORM\Entity]
12#[ORM\Table(name: TABLE_PREFIX . "node")]
13class Node
14{
15 use Position;
16
17 #[ORM\Id]
18 #[ORM\GeneratedValue]
19 #[ORM\Column(type: "integer")]
20 private ?int $id_node = null;
21
22 #[ORM\Column(type: "string", length: 255)]
23 private string $name_node;
24
25 #[ORM\Column(type: "integer")]
26 private int $position;
27
28 #[ORM\ManyToOne(targetEntity: self::class)]
29 //#[ORM\ManyToOne(targetEntity: self::class, fetch: 'EAGER')] // fetch: 'eager' désactive le mode fainéant de doctrine
30 #[ORM\JoinColumn(name: "parent_id", referencedColumnName: "id_node", onDelete: "SET NULL", nullable: true)]
31 private ?self $parent = null;
32
33 // un onDelete: "CASCADE" serait logique ici mais dangereux, on pourrait aussi faire en sorte que les noeuds soient récupérables si la page est brutalement supprimée
34 #[ORM\ManyToOne(targetEntity: Page::class)]
35 #[ORM\JoinColumn(name: "page_id", referencedColumnName: "id_page", nullable: true)]
36 private ?Page $page;
37
38 #[ORM\ManyToOne(targetEntity: Article::class, cascade: ['persist'])]
39 #[ORM\JoinColumn(name: "article_id", referencedColumnName: "id_article", onDelete: "CASCADE", nullable: true)] // supprimer le contenu d'un article supprime les noeuds associés, faux dans l'autre sens
40 private ?Article $article = null;
41
42 // propriété non mappée dans la table "node", la jointure est décrite dans NodeData
43 // elle sert à persister ou supprimer des données par cascade
44 // "mappedBy" permet de cibler $node dans l'autre classe, qui elle possède un "inversedBy"
45 #[ORM\OneToOne(targetEntity: NodeData::class, mappedBy: "node", cascade: ['persist', 'remove'])]
46 private ?NodeData $node_data = null;
47
48 #[ORM\OneToOne(targetEntity: EmailForm::class, mappedBy: "node", cascade: ['persist'])] // pas de remove, les e-mails sont associés au EmailForm
49 private ?EmailForm $email_form = null;
50
51 #[ORM\OneToOne(targetEntity: Presentation::class, mappedBy: "node", cascade: ['persist', 'remove'])]
52 private ?Presentation $presentation = null;
53
54 // attributs non destinés à doctrine
55 private array $children = []; // tableau de Node
56 private ?self $adopted = null; // = "new" est un enfant de "main" lorsque la page est "article"
57
58 public function __construct(string $name = '', int $position = 0, ?self $parent = null, ?Page $page = null, ?Article $article = null){
59 $this->name_node = $name;
60 $this->position = $position;
61 $this->parent = $parent;
62 $this->page = $page;
63 $this->article = $article;
64 }
65
66 // pfff...
67 public function getId(): ?int
68 {
69 return $this->id_node;
70 }
71 public function getName(): string
72 {
73 return $this->name_node;
74 }
75 /*public function setName(string $name): void
76 {
77 $this->name_node = $name;
78 }*/
79
80 public function getParent(): ?self
81 {
82 return $this->parent;
83 }
84 /*public function setParent(?self $parent): void
85 {
86 $this->parent = $parent;
87 }*/
88 public function getPosition(): int
89 {
90 return $this->position;
91 }
92 public function setPosition(int $position): void
93 {
94 $this->position = $position;
95 }
96 public function getPage(): Page
97 {
98 return $this->page;
99 }
100 /*public function setPage(Page $page): void
101 {
102 $this->page = $page;
103 }*/
104
105 // utiliser l'interface de NodeData et EmailForm
106 public function getArticle(): Article
107 {
108 return $this->article;
109 }
110 /*public function setArticle(Article $article): void
111 {
112 $this->article = $article;
113 }*/
114
115 // une interface serait cool!
116 // OU possible un "héritage doctrine", faire en sorte que Node soit la mère de NodeData, EmailForm, Article...
117 // une seule instance est matérialisée par plusieurs tables en même temps
118 public function getNodeData(): NodeData|EmailForm|Presentation|null
119 {
120 // pour du polymorphisme (une unique variable $node_data): opter pour l'héritage
121 return match($this->name_node){
122 'form' => $this->email_form,
123 'post_block', 'news_block' => $this->presentation,
124 default => $this->node_data, // inclut 'calendar'
125 };
126 }
127 public function getChildren(): array
128 {
129 return $this->children;
130 }
131 public function getNodeByName(string $name): ?Node
132 {
133 foreach($this->children as $child){
134 if($child->getName() === $name){
135 return $child;
136 }
137 }
138 return null;
139 }
140 public function addChild(self $child): void
141 {
142 $this->children[] = $child;
143
144 if(!Presentation::hasPresentation($this->getName())){ // post_block et news_block ont leurs enfants ordonnés avec ORDER BY
145 $this->sortChildren(false);
146 }
147 }
148 public function removeChild(self $child): void
149 {
150 foreach($this->children as $key => $object){
151 if($object->getId() === $child->getId()){
152 unset($this->children[$key]);
153 }
154 break;
155 }
156 $this->children = array_values($this->children); // réindexer pour supprimer la case vide
157 }
158
159 public function getAdoptedChild(): ?self // peut renvoyer null
160 {
161 return $this->adopted;
162 }
163 public function setAdoptedChild(self $child): void
164 {
165 $this->adopted = $child;
166 }
167}