summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpolo <ordipolo@gmx.fr>2025-04-06 12:18:49 +0200
committerpolo <ordipolo@gmx.fr>2025-04-06 12:18:49 +0200
commit68b6058e2a27fc251c117c4efeb141392a0c9736 (patch)
tree5c029b2c147bd14f777765d41bc623582c81daa2
parente4a325c9d5c07f09bc18b7e366ffb82b82c43502 (diff)
downloadcms-68b6058e2a27fc251c117c4efeb141392a0c9736.zip
nouvel article, boutons dans les builders, makeArticleNode, JS MAJ page, tri quand déplacement ou suppression
-rw-r--r--public/css/main.css14
-rw-r--r--public/css/trombinoscope.css6
-rw-r--r--public/images/SAR_Constructions.jpgbin0 -> 571935 bytes
-rw-r--r--public/images/Ysoline Rabin.jpgbin0 -> 4993 bytes
-rw-r--r--public/images/beatrice_carre.jpgbin0 -> 4475 bytes
-rw-r--r--public/images/eaulibre.jpgbin0 -> 53251 bytes
-rw-r--r--public/images/frank_pouliquen.jpgbin0 -> 27842 bytes
-rw-r--r--public/images/leclerc_bigouden.pngbin0 -> 82228 bytes
-rw-r--r--public/images/silhouette nageur.jpgbin0 -> 11805 bytes
-rw-r--r--public/images/silhouette nageuse.jpgbin0 -> 18499 bytes
-rw-r--r--public/images/yves_pouliquen.jpgbin0 -> 37276 bytes
-rw-r--r--public/index.php4
-rw-r--r--public/js/main.js30
-rw-r--r--public/js/tinymce.js151
-rw-r--r--src/controller/Director.php93
-rw-r--r--src/controller/Security.php2
-rw-r--r--src/controller/ajax.php88
-rw-r--r--src/model/entities/Article.php8
-rw-r--r--src/model/entities/Node.php71
-rw-r--r--src/view/AbstractBuilder.php6
-rw-r--r--src/view/ArticleBuilder.php14
-rw-r--r--src/view/BlogBuilder.php41
-rw-r--r--src/view/GaleryBuilder.php41
-rw-r--r--src/view/GridBuilder.php47
-rw-r--r--src/view/templates/article.php1
-rw-r--r--src/view/templates/blog.php8
-rw-r--r--src/view/templates/galery.php7
-rw-r--r--src/view/templates/grid.php6
28 files changed, 479 insertions, 159 deletions
diff --git a/public/css/main.css b/public/css/main.css
index 50c2173..cb44e16 100644
--- a/public/css/main.css
+++ b/public/css/main.css
@@ -28,8 +28,8 @@ section > p /* boutons spéciaux mode admin */
28} 28}
29.galery_photos .html_from_editor img 29.galery_photos .html_from_editor img
30{ 30{
31 max-width: 400px; 31 max-width: 300px;
32 max-height: 250px; 32 max-height: 200px;
33} 33}
34article 34article
35{ 35{
@@ -50,6 +50,11 @@ article .logo2
50{ 50{
51 width: 100%; 51 width: 100%;
52} 52}
53article img
54{
55 max-width: 100%;
56 height: auto;
57}
53.new_content_text 58.new_content_text
54{ 59{
55 max-height: 250px; 60 max-height: 250px;
@@ -120,4 +125,9 @@ main button:hover
120 cursor: pointer; /* curseur qui pointe du doigt */ 125 cursor: pointer; /* curseur qui pointe du doigt */
121 background-color: #ffff00; 126 background-color: #ffff00;
122 border-radius: 4px; 127 border-radius: 4px;
128}
129
130article a:hover
131{
132 cursor: pointer;
123} \ No newline at end of file 133} \ No newline at end of file
diff --git a/public/css/trombinoscope.css b/public/css/trombinoscope.css
index f42dad8..357e6b0 100644
--- a/public/css/trombinoscope.css
+++ b/public/css/trombinoscope.css
@@ -1,4 +1,10 @@
1article img 1article img
2{ 2{
3 border-radius: 50%; 3 border-radius: 50%;
4}
5
6.grid_columns
7{
8 /* écrase les 3 colonnes par défaut */
9 grid-template-columns: repeat(4, 1fr);
4} \ No newline at end of file 10} \ No newline at end of file
diff --git a/public/images/SAR_Constructions.jpg b/public/images/SAR_Constructions.jpg
new file mode 100644
index 0000000..1b9cb81
--- /dev/null
+++ b/public/images/SAR_Constructions.jpg
Binary files differ
diff --git a/public/images/Ysoline Rabin.jpg b/public/images/Ysoline Rabin.jpg
new file mode 100644
index 0000000..2ecfcc4
--- /dev/null
+++ b/public/images/Ysoline Rabin.jpg
Binary files differ
diff --git a/public/images/beatrice_carre.jpg b/public/images/beatrice_carre.jpg
new file mode 100644
index 0000000..8db4036
--- /dev/null
+++ b/public/images/beatrice_carre.jpg
Binary files differ
diff --git a/public/images/eaulibre.jpg b/public/images/eaulibre.jpg
new file mode 100644
index 0000000..02b1917
--- /dev/null
+++ b/public/images/eaulibre.jpg
Binary files differ
diff --git a/public/images/frank_pouliquen.jpg b/public/images/frank_pouliquen.jpg
new file mode 100644
index 0000000..7bb3ead
--- /dev/null
+++ b/public/images/frank_pouliquen.jpg
Binary files differ
diff --git a/public/images/leclerc_bigouden.png b/public/images/leclerc_bigouden.png
new file mode 100644
index 0000000..596ead7
--- /dev/null
+++ b/public/images/leclerc_bigouden.png
Binary files differ
diff --git a/public/images/silhouette nageur.jpg b/public/images/silhouette nageur.jpg
new file mode 100644
index 0000000..526cc0f
--- /dev/null
+++ b/public/images/silhouette nageur.jpg
Binary files differ
diff --git a/public/images/silhouette nageuse.jpg b/public/images/silhouette nageuse.jpg
new file mode 100644
index 0000000..e4f7307
--- /dev/null
+++ b/public/images/silhouette nageuse.jpg
Binary files differ
diff --git a/public/images/yves_pouliquen.jpg b/public/images/yves_pouliquen.jpg
new file mode 100644
index 0000000..435c69e
--- /dev/null
+++ b/public/images/yves_pouliquen.jpg
Binary files differ
diff --git a/public/index.php b/public/index.php
index 3c6f261..2512d6d 100644
--- a/public/index.php
+++ b/public/index.php
@@ -69,9 +69,9 @@ elseif(isset($_GET['action']) && $_GET['action'] === 'modif_mdp')
69} 69}
70 70
71// -- contrôleurs -- 71// -- contrôleurs --
72$director = new Director($entityManager); 72$director = new Director($entityManager, true);
73$director->makeRootNode($id); 73$director->makeRootNode($id);
74$node = $director->getRootNode(); 74$node = $director->getNode();
75 75
76// -- vues -- 76// -- vues --
77$view_builder = new ViewBuilder($node); 77$view_builder = new ViewBuilder($node);
diff --git a/public/js/main.js b/public/js/main.js
index 1351fea..c05eb2f 100644
--- a/public/js/main.js
+++ b/public/js/main.js
@@ -30,10 +30,10 @@ function copyInClipBoard(link){
30} 30}
31 31
32// complète les fonctions dans tinymce.js 32// complète les fonctions dans tinymce.js
33function switchPositions(articleId, direction) 33function switchPositions(article_id, direction)
34{ 34{
35 const current_article = document.getElementById(articleId).parentElement.parentElement; 35 const current_article = findParent(document.getElementById(article_id), 'article');
36 var other_article = current_article; 36 var other_article;
37 37
38 if(direction == 'down'){ 38 if(direction == 'down'){
39 other_article = current_article.nextElementSibling; 39 other_article = current_article.nextElementSibling;
@@ -41,14 +41,23 @@ function switchPositions(articleId, direction)
41 else if(direction == 'up'){ 41 else if(direction == 'up'){
42 other_article = current_article.previousElementSibling; 42 other_article = current_article.previousElementSibling;
43 } 43 }
44 const other_article_id = other_article.querySelector('div[id]').id; 44
45 var other_article_id;
46 try{
47 other_article_id = other_article.querySelector('div[id]').id;
48 other_article_id = 'i' + other_article_id.slice(1); // peut mieux faire
49 }
50 catch(error){
51 console.log('Inversion impossible');
52 return;
53 }
45 54
46 fetch('index.php?action=switch_positions', { 55 fetch('index.php?action=switch_positions', {
47 method: 'POST', 56 method: 'POST',
48 headers: { 57 headers: {
49 'Content-Type': 'application/json' 58 'Content-Type': 'application/json'
50 }, 59 },
51 body: JSON.stringify({ id1: articleId, id2: other_article_id }) 60 body: JSON.stringify({ id1: article_id, id2: other_article_id })
52 }) 61 })
53 .then(response => response.json()) 62 .then(response => response.json())
54 .then(data => { 63 .then(data => {
@@ -155,4 +164,15 @@ function submitDate(id_date)
155 .catch(error => { 164 .catch(error => {
156 console.error('Erreur:', error); 165 console.error('Erreur:', error);
157 }); 166 });
167}
168
169function findParent(element, tag_name) {
170 while (element !== null) {
171 if (element.tagName === tag_name.toUpperCase()) // tagName est en majuscules
172 {
173 return element;
174 }
175 element = element.parentElement;
176 }
177 return null;
158} \ No newline at end of file 178} \ No newline at end of file
diff --git a/public/js/tinymce.js b/public/js/tinymce.js
index d3c9739..cb1938a 100644
--- a/public/js/tinymce.js
+++ b/public/js/tinymce.js
@@ -1,15 +1,26 @@
1let editors = {}; 1let editors = {};
2 2
3function openEditor(id, page = '') { 3function openEditor(id, page = '') {
4 const real_id = 'i' + id.slice(1); 4 var creation_mode;
5 var real_id;
6 var article;
5 7
6 // Récupérer et sauvegarder le contenu d'origine de l'article 8 // création ou modification d'un article?
7 const articleContent = document.getElementById(id).innerHTML; 9 if(id[0] === 'n'){
8 document.getElementById(id).setAttribute('data-original-content', articleContent); 10 creation_mode = true;
11 article = document.getElementById(id);
12 }
13 else{
14 creation_mode = false;
15 // Récupérer et sauvegarder le contenu d'origine de l'article
16 real_id = 'i' + id.slice(1);
17 article = document.getElementById(id);
18 document.getElementById(id).setAttribute('data-original-content', article.innerHTML);
19 }
9 20
10 tinymce.init({ 21 tinymce.init({
11 selector: `#${id}`, 22 selector: `#${id}`,
12 language: 'fr_FR', // télécharger des paquets de langue ici: https://www.tiny.cloud/get-tiny/language-packages/ 23 language: 'fr_FR', // téléchargement ici: https://www.tiny.cloud/get-tiny/language-packages/
13 language_url: 'js/tinymce-langs/fr_FR.js', // ou installer tweeb/tinymce-i18n avec composer 24 language_url: 'js/tinymce-langs/fr_FR.js', // ou installer tweeb/tinymce-i18n avec composer
14 license_key: 'gpl', 25 license_key: 'gpl',
15 branding: false, 26 branding: false,
@@ -23,14 +34,18 @@ function openEditor(id, page = '') {
23 editors[id] = editor; 34 editors[id] = editor;
24 35
25 // boutons "Modifier", "Supprimer", "déplacer vers le haut", "déplacer vers le bas", "Annuler" et "Soumettre" 36 // boutons "Modifier", "Supprimer", "déplacer vers le haut", "déplacer vers le bas", "Annuler" et "Soumettre"
26 document.querySelector(`#edit-${id}`).classList.add('hidden');
27 document.querySelector(`#cancel-${id}`).classList.remove('hidden'); 37 document.querySelector(`#cancel-${id}`).classList.remove('hidden');
28 document.querySelector(`#submit-${id}`).classList.remove('hidden'); 38 document.querySelector(`#submit-${id}`).classList.remove('hidden');
29 document.querySelector(`#delete-${real_id}`).classList.add('hidden'); 39 if(creation_mode === false){
30 // boutons absents page article 40 document.querySelector(`#edit-${id}`).classList.add('hidden');
31 if(page != 'article'){ 41 document.querySelector(`#delete-${real_id}`).classList.add('hidden');
32 document.querySelector(`#position_up-${id}`).classList.add('hidden'); 42 if(page != 'article'){
33 document.querySelector(`#position_down-${id}`).classList.add('hidden'); 43 document.querySelector(`#position_up-${id}`).classList.add('hidden');
44 document.querySelector(`#position_down-${id}`).classList.add('hidden');
45 }
46 }
47 else{
48 document.querySelector(`#new-${id}`).classList.add('hidden'); // id = new-new-id_node
34 } 49 }
35 }); 50 });
36 }, 51 },
@@ -60,7 +75,9 @@ function openEditor(id, page = '') {
60 }); 75 });
61 76
62 // Remplacer le contenu de l'article par l'éditeur 77 // Remplacer le contenu de l'article par l'éditeur
63 document.getElementById(id).innerHTML = articleContent; 78 if(creation_mode === false){
79 document.getElementById(id).innerHTML = article.innerHTML;
80 }
64} 81}
65 82
66function deleteArticle(id, page = '') { 83function deleteArticle(id, page = '') {
@@ -100,33 +117,78 @@ function deleteArticle(id, page = '') {
100 } 117 }
101} 118}
102 119
103function closeEditor(id, page = '', display_old = true) 120function closeEditor(id, page = '', restore_old = true)
104{ 121{
105 const real_id = 'i' + id.slice(1); 122 var creation_mode;
123 var real_id;
124 var article;
125 var parent;
126
127 // création ou modification d'un article?
128 if(id[0] === 'n'){
129 creation_mode = true;
130 }
131 else{
132 creation_mode = false;
133 }
106 134
107 // Fermer l'éditeur 135 // Fermer l'éditeur
108 tinymce.remove(`#${id}`); 136 tinymce.remove(`#${id}`);
109 delete editors[id]; 137 delete editors[id];
110 138
139 if(creation_mode){
140 article = document.getElementById(id);
141 parent = findParent(article, 'section');
142 }
143 else{
144 real_id = 'i' + id.slice(1);
145 }
146
111 // Restaurer le contenu d'origine de l'article 147 // Restaurer le contenu d'origine de l'article
112 if(display_old){ 148 if(restore_old){
113 const originalContent = document.getElementById(id).getAttribute('data-original-content'); 149 const originalContent = document.getElementById(id).getAttribute('data-original-content');
114 document.getElementById(id).innerHTML = originalContent; 150 document.getElementById(id).innerHTML = originalContent;
115 } 151 }
116 152
117 // boutons "Modifier", "Supprimer", "déplacer vers le haut", "déplacer vers le bas", "Annuler" et "Soumettre" 153 // boutons: "Nouvel article", Modifier", "Supprimer", "déplacer vers le haut", "déplacer vers le bas", "Annuler" et "Valider"
118 document.querySelector(`#edit-${id}`).classList.remove('hidden');
119 document.querySelector(`#cancel-${id}`).classList.add('hidden'); 154 document.querySelector(`#cancel-${id}`).classList.add('hidden');
120 document.querySelector(`#submit-${id}`).classList.add('hidden'); 155 document.querySelector(`#submit-${id}`).classList.add('hidden');
121 document.querySelector(`#delete-${real_id}`).classList.remove('hidden'); 156 if(creation_mode){
122 // boutons absents page article 157 document.querySelector(`#new-${id}`).classList.remove('hidden'); // id = new-new-id_node
158 }
159 else{
160 document.querySelector(`#edit-${id}`).classList.remove('hidden');
161 if(page != 'article'){
162 document.querySelector(`#position_up-${id}`).classList.remove('hidden');
163 document.querySelector(`#position_down-${id}`).classList.remove('hidden');
164 document.querySelector(`#delete-${id}`).classList.remove('hidden');
165 }
166 }
123 if(page != 'article'){ 167 if(page != 'article'){
124 document.querySelector(`#position_up-${id}`).classList.remove('hidden'); 168 /*document.querySelector(`#position_up-${id}`).classList.remove('hidden');
125 document.querySelector(`#position_down-${id}`).classList.remove('hidden'); 169 document.querySelector(`#position_down-${id}`).classList.remove('hidden');
126 } 170 document.querySelector(`#delete-${id}`).classList.remove('hidden');*/
171 }
172 else{
173 //document.querySelector(`#delete-${real_id}`).classList.remove('hidden');
174 }
175
127} 176}
128 177
129function submitArticle(id, page = '') { 178function submitArticle(id, page = '', clone = null) {
179 //var creation_mode;
180 if(id[0] === 'n'){
181 //creation_mode = true;
182
183 // sécurité
184 if(clone == null){
185 return;
186 }
187 }
188 else{
189 //creation_mode = false;
190 }
191
130 // Récupérer l'éditeur correspondant à l'article 192 // Récupérer l'éditeur correspondant à l'article
131 const editor = editors[id]; 193 const editor = editors[id];
132 if(!editor) { 194 if(!editor) {
@@ -150,7 +212,50 @@ function submitArticle(id, page = '') {
150 if (data.success) { 212 if (data.success) {
151 // Fermer l'éditeur et mettre à jour le contenu de l'article 213 // Fermer l'éditeur et mettre à jour le contenu de l'article
152 closeEditor(id, page, false); 214 closeEditor(id, page, false);
153 document.getElementById(id).innerHTML = html; 215 if(id[0] === 'n'){
216 var share_btn = document.querySelector(`.share.hidden`); // combinaison de deux classes
217 var new_btn = document.querySelector(`#new-${id}`);
218 var edit_btn = document.querySelector(`#edit-${id}`);
219 var pos_up_btn = document.querySelector(`#position_up-${id}`);
220 var pos_down_btn = document.querySelector(`#position_down-${id}`);
221 var delete_btn = document.querySelector(`#delete-${id}`);
222 var cancel_btn = document.querySelector(`#cancel-${id}`);
223 var submit_btn = document.querySelector(`#submit-${id}`);
224
225 share_btn.classList.remove('hidden')
226 new_btn.classList.add('hidden');
227 edit_btn.classList.remove('hidden');
228 pos_up_btn.classList.remove('hidden');
229 pos_down_btn.classList.remove('hidden');
230 delete_btn.classList.remove('hidden');
231 //cancel_btn.classList.add('hidden');
232 //submit_btn.classList.add('hidden');
233
234 var article = document.getElementById(id);
235 var parent = findParent(article, 'article');
236 //share_btn.setAttribute('href', '#' + data.article_id);
237 share_btn.setAttribute('onclick', "copyInClipBoard('" + window.location.href + data.article_id + "')"); // # de l'ancre ajouté au clic sur le lien ouvrant l'éditeur
238 article.id = data.article_id;
239 edit_btn.id = 'edit-' + data.article_id;
240 edit_btn.querySelector('.action_icon').setAttribute('onclick', "openEditor('" + data.article_id + "')");
241 pos_up_btn.id = 'position_up-' + data.article_id;
242 pos_up_btn.querySelector('.action_icon').setAttribute('onclick', "switchPositions('" + data.article_id + "', 'up')");
243 pos_down_btn.id = 'position_down-' + data.article_id;
244 pos_down_btn.querySelector('.action_icon').setAttribute('onclick', "switchPositions('" + data.article_id + "', 'down')");
245 delete_btn.id = 'delete-' + data.article_id;
246 delete_btn.querySelector('.action_icon').setAttribute('onclick', "deleteArticle('" + data.article_id + "')");
247 cancel_btn.id = 'cancel-' + data.article_id;
248 cancel_btn.querySelector('button').setAttribute('onclick', "closeEditor('" + data.article_id + "')");
249 submit_btn.id = 'submit-' + data.article_id;
250 submit_btn.querySelector('button').setAttribute('onclick', "submitArticle('" + data.article_id + "')");
251
252 var next_div = parent.nextElementSibling.nextElementSibling;
253 parent.parentNode.replaceChild(clone, parent);
254 next_div.appendChild(parent);
255 }
256 else{
257 //document.getElementById(id).innerHTML = html;
258 }
154 } 259 }
155 else { 260 else {
156 alert('Erreur lors de la sauvegarde de l\'article.'); 261 alert('Erreur lors de la sauvegarde de l\'article.');
diff --git a/src/controller/Director.php b/src/controller/Director.php
index 5ff8f47..db84661 100644
--- a/src/controller/Director.php
+++ b/src/controller/Director.php
@@ -13,17 +13,29 @@ class Director
13 static public Menu $menu_data; // pour NavBuilder 13 static public Menu $menu_data; // pour NavBuilder
14 static public Path $page_path; // pour BreadcrumbBuilder 14 static public Path $page_path; // pour BreadcrumbBuilder
15 private Page $page; 15 private Page $page;
16 private Node $root_node; 16 private Node $node;
17 private Node $article;
17 18
18 public function __construct(EntityManager $entityManager) 19 public function __construct(EntityManager $entityManager, bool $for_display = false)
19 { 20 {
20 $this->entityManager = $entityManager; 21 $this->entityManager = $entityManager;
21 self::$menu_data = new Menu($entityManager); // Menu est un modèle mais pas une entité 22 if($for_display){
22 self::$page_path = new Path(); 23 self::$menu_data = new Menu($entityManager); // Menu est un modèle mais pas une entité
23 $this->page = self::$page_path->getLast(); 24 self::$page_path = new Path();
24 $this->root_node = new Node; // instance mère "vide" ne possédant rien d'autre que des enfants 25 $this->page = self::$page_path->getLast();
26 }
27 $this->node = new Node; // instance mère "vide" ne possédant rien d'autre que des enfants
25 } 28 }
26 29
30 public function getNode(): Node
31 {
32 return $this->node;
33 }
34 public function getArticleNode(): Node
35 {
36 return $this->article;
37 }
38
27 public function makeRootNode(string $id = ''): void 39 public function makeRootNode(string $id = ''): void
28 { 40 {
29 // on récupère toutes les entrées 41 // on récupère toutes les entrées
@@ -44,25 +56,10 @@ class Director
44 ->setParameter('id', $id) 56 ->setParameter('id', $id)
45 ->getResult(); 57 ->getResult();
46 } 58 }
47 $this->feedObjects($bulk_data); 59 $this->feedRootNodeObjects($bulk_data);
48 }
49
50 public function makeArticleNode(string $id = ''): bool
51 {
52 $bulk_data = $this->entityManager
53 ->createQuery('SELECT n FROM App\Entity\Node n WHERE n.article_timestamp = :id')
54 ->setParameter('id', $id)
55 ->getResult();
56
57 if(count($bulk_data) === 0){
58 return false;
59 }
60
61 $this->root_node = $bulk_data[0];
62 return true;
63 } 60 }
64 61
65 private function feedObjects(array $bulk_data): void // $bulk_data = tableau de Node 62 private function feedRootNodeObjects(array $bulk_data): void // $bulk_data = tableau de Node
66 { 63 {
67 // puis on les range 64 // puis on les range
68 // (attention, risque de disfonctionnement si les noeuds de 1er niveau ne sont pas récupérés en 1er dans la BDD) 65 // (attention, risque de disfonctionnement si les noeuds de 1er niveau ne sont pas récupérés en 1er dans la BDD)
@@ -71,7 +68,7 @@ class Director
71 // premier niveau 68 // premier niveau
72 if($node->getParent() == null) 69 if($node->getParent() == null)
73 { 70 {
74 $this->root_node->addChild($node); 71 $this->node->addChild($node);
75 72
76 // spécifique page article 73 // spécifique page article
77 if($node->getName() === 'main' && $this->page->getEndOfPath() == 'article'){ 74 if($node->getName() === 'main' && $this->page->getEndOfPath() == 'article'){
@@ -94,8 +91,50 @@ class Director
94 } 91 }
95 } 92 }
96 93
97 public function getRootNode(): Node 94 // récupération d'un article pour modification
98 { 95 public function makeArticleNode(string $id = '', bool $get_section = false): bool
99 return $this->root_node; 96 {
97 if($get_section){
98 $dql = 'SELECT n, p FROM App\Entity\Node n LEFT JOIN n.parent p WHERE n.article_timestamp = :id';
99 }
100 else{
101 $dql = 'SELECT n FROM App\Entity\Node n WHERE n.article_timestamp = :id';
102 }
103 // n est l'article et p son $parent
104 $bulk_data = $this->entityManager
105 ->createQuery($dql)
106 ->setParameter('id', $id)
107 ->getResult();
108
109 if(count($bulk_data) === 0){
110 return false;
111 }
112
113 if($get_section){
114 $this->article = $bulk_data[0];
115 $this->makeSectionNode($bulk_data[0]->getParent()->getId());
116 }
117 else{
118 $this->article = $bulk_data[0];
119 }
120
121 return true;
122 }
123
124 // récupération des articles d'un bloc <section> à la création d'un article
125 public function makeSectionNode(int $section_id): bool
126 {
127 $section = $this->entityManager->find('App\Entity\Node', (string)$section_id);
128
129 $bulk_data = $this->entityManager
130 ->createQuery('SELECT n FROM App\Entity\Node n WHERE n.parent = :parent')
131 ->setParameter('parent', $section)
132 ->getResult();
133
134 foreach($bulk_data as $article){
135 $section->addChild($article); // pas de flush, on ne va pas écrire dans la BDD à chaque nouvelle page
136 }
137 $this->node = $section;
138 return true;
100 } 139 }
101} 140}
diff --git a/src/controller/Security.php b/src/controller/Security.php
index 818a2bd..f9092e2 100644
--- a/src/controller/Security.php
+++ b/src/controller/Security.php
@@ -9,7 +9,7 @@ class Security
9 'safe'=>1, // protection contre les élements et attributs dangereux 9 'safe'=>1, // protection contre les élements et attributs dangereux
10 10
11 // liste blanche d'éléments HTML 11 // liste blanche d'éléments HTML
12 'elements'=> 'h1, h2, h3, h4, h5, h6, p, s, em, span, strong, a, ul, ol, li, sup, sub, code, blockquote, div, pre, table, caption, colgroup, col, tbody, tr, th, td, figure, img, figcaption, iframe, small', 12 'elements'=> 'h1, h2, h3, h4, h5, h6, p, br, s, em, span, strong, a, ul, ol, li, sup, sub, code, blockquote, div, pre, table, caption, colgroup, col, tbody, tr, th, td, figure, img, figcaption, iframe, small',
13 13
14 // liste noire d'attributs HTML 14 // liste noire d'attributs HTML
15 'deny_attribute'=> 'id, class' // on garde 'style' 15 'deny_attribute'=> 'id, class' // on garde 'style'
diff --git a/src/controller/ajax.php b/src/controller/ajax.php
index 86acd39..b5c2e51 100644
--- a/src/controller/ajax.php
+++ b/src/controller/ajax.php
@@ -3,6 +3,9 @@
3 3
4declare(strict_types=1); 4declare(strict_types=1);
5 5
6use App\Entity\Article;
7use App\Entity\Node;
8
6// détection des requêtes de tinymce 9// détection des requêtes de tinymce
7if($_SERVER['CONTENT_TYPE'] === 'application/json' && isset($_GET['action'])) 10if($_SERVER['CONTENT_TYPE'] === 'application/json' && isset($_GET['action']))
8{ 11{
@@ -15,13 +18,44 @@ if($_SERVER['CONTENT_TYPE'] === 'application/json' && isset($_GET['action']))
15 if(json_last_error() === JSON_ERROR_NONE) 18 if(json_last_error() === JSON_ERROR_NONE)
16 { 19 {
17 $id = $json['id']; 20 $id = $json['id'];
18 $id[0] = 'i';
19 $content = Security::secureString($json['content']); 21 $content = Security::secureString($json['content']);
20
21 $director = new Director($entityManager); 22 $director = new Director($entityManager);
23
24 // nouvel article
25 if($id[0] === 'n')
26 {
27 if($content === ''){
28 echo json_encode(['success' => false, 'message' => 'pas de données à sauvegarder']);
29 die;
30 }
31 $section_id = (int)substr($id, 1); // id du bloc <section>
32 $director->makeSectionNode($section_id);
33 $node = $director->getNode(); // = <section>
34
35 $timestamp = time();
36 $date = new \DateTime;
37 $date->setTimestamp($timestamp);
38
39 $article = new Article($content, $date); // le "current" timestamp est obtenu par la BDD
40 $article_node = new Node('article', 'i' . (string)$timestamp, [], count($node->getChildren()) + 1, $node, $node->getPage(), $article);
41
42 $entityManager->persist($article_node);
43 $entityManager->flush();
44
45 // id_node tout juste généré
46 //$article_node->getId();
47
48 echo json_encode(['success' => true, 'article_id' => $article_node->getArticleTimestamp()]);
49 die;
50 }
51 // modification article
52 else{
53 $id[0] = 'i'; // id de l'article node
54 }
55
22 if($director->makeArticleNode($id)) // une entrée est trouvée 56 if($director->makeArticleNode($id)) // une entrée est trouvée
23 { 57 {
24 $node = $director->getRootNode(); 58 $node = $director->getArticleNode(); // article
25 switch($json['id'][0]){ 59 switch($json['id'][0]){
26 case 'i': 60 case 'i':
27 $node->getArticle()->setContent($content); 61 $node->getArticle()->setContent($content);
@@ -42,8 +76,9 @@ if($_SERVER['CONTENT_TYPE'] === 'application/json' && isset($_GET['action']))
42 $entityManager->flush(); 76 $entityManager->flush();
43 echo json_encode(['success' => true]); 77 echo json_encode(['success' => true]);
44 } 78 }
45 else{ 79 else
46 echo json_encode(['success' => false, 'message' => 'Aucune entrée trouvée en BDD']); 80 {
81 echo json_encode(['success' => false, 'message' => 'article non identifié']);
47 } 82 }
48 } 83 }
49 else{ 84 else{
@@ -53,16 +88,18 @@ if($_SERVER['CONTENT_TYPE'] === 'application/json' && isset($_GET['action']))
53 } 88 }
54 elseif($_GET['action'] === 'delete_article' && isset($json['id'])) 89 elseif($_GET['action'] === 'delete_article' && isset($json['id']))
55 { 90 {
56 $id = $json['id'];
57
58 $director = new Director($entityManager); 91 $director = new Director($entityManager);
59 $director->makeArticleNode($id); 92 $director->makeArticleNode($json['id'], true);
60 $node = $director->getRootNode(); 93 $article = $director->getArticleNode();
61 $entityManager->remove($node); 94 $section = $director->getNode();
95
96 $entityManager->remove($article);
97 $section->removeChild($article);
98 $section->sortChildren(true); // régénère les positions
62 $entityManager->flush(); 99 $entityManager->flush();
63 100
64 // test avec une nouvelle requête qui ne devrait rien trouver 101 // test avec une nouvelle requête qui ne devrait rien trouver
65 if(!$director->makeArticleNode($id)) 102 if(!$director->makeArticleNode($json['id']))
66 { 103 {
67 echo json_encode(['success' => true]); 104 echo json_encode(['success' => true]);
68 105
@@ -78,14 +115,25 @@ if($_SERVER['CONTENT_TYPE'] === 'application/json' && isset($_GET['action']))
78 elseif($_GET['action'] === 'switch_positions' && isset($json['id1']) && isset($json['id2'])) 115 elseif($_GET['action'] === 'switch_positions' && isset($json['id1']) && isset($json['id2']))
79 { 116 {
80 $director = new Director($entityManager); 117 $director = new Director($entityManager);
81 $director->makeArticleNode($json['id1']); 118 $director->makeArticleNode($json['id1'], true);
82 $node1 = $director->getRootNode(); 119 $article1 = $director->getArticleNode();
83 $director->makeArticleNode($json['id2']); 120 $section = $director->getNode();
84 $node2 = $director->getRootNode(); 121
85 122 $section->sortChildren(true); // régénère les positions avant inversion
86 $tmp = $node1->getPosition(); 123
87 $node1->setPosition($node2->getPosition()); 124 $article2;
88 $node2->setPosition($tmp); 125 foreach($section->getChildren() as $child){
126 if($child->getArticleTimestamp() === $json['id2']) // type string
127 {
128 $article2 = $child;
129 break;
130 }
131 }
132
133 // inversion
134 $tmp = $article1->getPosition();
135 $article1->setPosition($article2->getPosition());
136 $article2->setPosition($tmp);
89 $entityManager->flush(); 137 $entityManager->flush();
90 138
91 echo json_encode(['success' => true]); 139 echo json_encode(['success' => true]);
@@ -99,7 +147,7 @@ if($_SERVER['CONTENT_TYPE'] === 'application/json' && isset($_GET['action']))
99 147
100 $director = new Director($entityManager); 148 $director = new Director($entityManager);
101 $director->makeArticleNode($id); 149 $director->makeArticleNode($id);
102 $node = $director->getRootNode(); 150 $node = $director->getArticleNode();
103 $node->getArticle()->setDateTime($date); 151 $node->getArticle()->setDateTime($date);
104 $entityManager->flush(); 152 $entityManager->flush();
105 153
diff --git a/src/model/entities/Article.php b/src/model/entities/Article.php
index 601e573..dc2d78b 100644
--- a/src/model/entities/Article.php
+++ b/src/model/entities/Article.php
@@ -20,7 +20,7 @@ class Article
20 20
21 // datetime_immutable permet à la base de toujours gérer cette clé primaire correctement 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)] 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 23 private ?\DateTime $date_time; // le type datetime de doctrine convertit en type \DateTime de PHP
24 24
25 #[ORM\Column(type: "string")] 25 #[ORM\Column(type: "string")]
26 private string $title; 26 private string $title;
@@ -40,8 +40,12 @@ class Article
40 )] 40 )]
41 private Collection $images; 41 private Collection $images;
42 42
43 public function __construct() 43 public function __construct(string $content, \DateTime $date_time = null, string $title = '', string $preview = '')
44 { 44 {
45 $this->date_time = $date_time;
46 $this->title = $title;
47 $this->preview = $preview;
48 $this->content = $content;
45 $this->images = new ArrayCollection(); // initialisation nécessaire 49 $this->images = new ArrayCollection(); // initialisation nécessaire
46 } 50 }
47 51
diff --git a/src/model/entities/Node.php b/src/model/entities/Node.php
index 9240413..c9b310a 100644
--- a/src/model/entities/Node.php
+++ b/src/model/entities/Node.php
@@ -65,32 +65,6 @@ class Node
65 $this->article = $article; 65 $this->article = $article;
66 } 66 }
67 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... 68 // pfff...
95 public function getId(): int 69 public function getId(): int
96 { 70 {
@@ -156,6 +130,51 @@ class Node
156 { 130 {
157 return $this->children; 131 return $this->children;
158 } 132 }
133 public function addChild(self $child): void
134 {
135 $this->children[] = $child;
136 $this->sortChildren(false);
137 }
138 // utiliser $position pour afficher les éléments dans l'ordre
139 public function sortChildren(bool $reposition = false): void
140 {
141 // ordre du tableau des enfants
142 // inefficace quand des noeuds ont la même position
143
144 // tri par insertion
145 for($i = 1; $i < count($this->children); $i++)
146 {
147 $tmp = $this->children[$i];
148 $j = $i - 1;
149
150 // Déplacez les éléments du tableau qui sont plus grands que la clé
151 // à une position devant leur position actuelle
152 while ($j >= 0 && $this->children[$j]->getPosition() > $tmp->getPosition()) {
153 $this->children[$j + 1] = $this->children[$j];
154 $j = $j - 1;
155 }
156 $this->children[$j + 1] = $tmp;
157 }
158
159 // nouvelles positions
160 if($reposition){
161 $i = 1;
162 foreach($this->children as $child){
163 $child->setPosition($i);
164 $i++;
165 }
166 }
167 }
168 public function removeChild(self $child): void
169 {
170 foreach($this->children as $key => $object){
171 if($object->getId() === $child->getId()){
172 unset($this->children[$key]);
173 }
174 break;
175 }
176 $this->children = array_values($this->children); // réindexer pour supprimer la case vide
177 }
159 178
160 public function getTempChild(): ?self // peut renvoyer null 179 public function getTempChild(): ?self // peut renvoyer null
161 { 180 {
diff --git a/src/view/AbstractBuilder.php b/src/view/AbstractBuilder.php
index cd2b361..285ebc3 100644
--- a/src/view/AbstractBuilder.php
+++ b/src/view/AbstractBuilder.php
@@ -7,6 +7,12 @@ abstract class AbstractBuilder
7{ 7{
8 protected const VIEWS_PATH = '../src/view/templates/'; 8 protected const VIEWS_PATH = '../src/view/templates/';
9 protected string $html = ''; 9 protected string $html = '';
10 protected int $id_node;
11
12 protected function __construct(Node $node)
13 {
14 $this->id_node = $node->getId();
15 }
10 16
11 protected function useChildrenBuilder(Node $node): void 17 protected function useChildrenBuilder(Node $node): void
12 { 18 {
diff --git a/src/view/ArticleBuilder.php b/src/view/ArticleBuilder.php
index f86f9bd..1f5dbb8 100644
--- a/src/view/ArticleBuilder.php
+++ b/src/view/ArticleBuilder.php
@@ -25,29 +25,29 @@ class ArticleBuilder extends AbstractBuilder
25 // partage 25 // partage
26 $share_link = new URL(['page' => CURRENT_PAGE], $id); 26 $share_link = new URL(['page' => CURRENT_PAGE], $id);
27 $share_js = 'onclick="copyInClipBoard(\'' . $share_link . '\')"'; 27 $share_js = 'onclick="copyInClipBoard(\'' . $share_link . '\')"';
28 $share_button = '<a class="share" href="' . $share_link . '" ' . $share_js . '><img class="action_icon" src="assets/share.svg"></a>' . "\n"; 28 $share_button = '<p class="share" ' . $share_js . '><img class="action_icon" src="assets/share.svg"></p>' . "\n";
29 29
30 // modifier un article 30 // modifier un article
31 $admin_buttons = ''; 31 $admin_buttons = '';
32 if($_SESSION['admin']) 32 if($_SESSION['admin'])
33 { 33 {
34 $modify_js = 'onclick="openEditor(\'' . $id . '\')"'; 34 $modify_js = 'onclick="openEditor(\'' . $id . '\')"';
35 $modify_article = '<p id="edit-' . $id . '"><a href="#"><img class="action_icon" src="assets/edit.svg" ' . $modify_js . '></a></p>' . "\n"; 35 $modify_article = '<p id="edit-' . $id . '"><img class="action_icon" src="assets/edit.svg" ' . $modify_js . '></p>' . "\n";
36 36
37 $up_js = 'onclick="switchPositions(\'' . $id . '\', \'up\')"'; 37 $up_js = 'onclick="switchPositions(\'' . $id . '\', \'up\')"';
38 $up_button = '<p id="position_up-' . $id . '"><a href="#"><img class="action_icon" src="assets/arrow-up.svg" ' . $up_js . '></a></p>' . "\n"; 38 $up_button = '<p id="position_up-' . $id . '"><img class="action_icon" src="assets/arrow-up.svg" ' . $up_js . '></p>' . "\n";
39 39
40 $down_js = 'onclick="switchPositions(\'' . $id . '\', \'down\')"'; 40 $down_js = 'onclick="switchPositions(\'' . $id . '\', \'down\')"';
41 $down_button = '<p id="position_down-' . $id . '"><a href="#"><img class="action_icon" src="assets/arrow-down.svg" ' . $down_js . '></a></p>' . "\n"; 41 $down_button = '<p id="position_down-' . $id . '"><img class="action_icon" src="assets/arrow-down.svg" ' . $down_js . '></p>' . "\n";
42 42
43 $delete_js = 'onclick="deleteArticle(\'' . $id . '\')"'; 43 $delete_js = 'onclick="deleteArticle(\'' . $id . '\')"';
44 $delete_article = '<p id="delete-' . $id . '"><a href="#"><img class="action_icon" src="assets/delete-bin.svg" ' . $delete_js . '></a></p>' . "\n"; 44 $delete_article = '<p id="delete-' . $id . '"><img class="action_icon" src="assets/delete-bin.svg" ' . $delete_js . '></p>' . "\n";
45 45
46 $close_js = 'onclick="closeEditor(\'' . $id . '\')"'; 46 $close_js = 'onclick="closeEditor(\'' . $id . '\')"';
47 $close_editor = '<p id="cancel-' . $id . '" class="hidden"><a href="#"><button ' . $close_js . '>Annuler</button></a></p>'; 47 $close_editor = '<p id="cancel-' . $id . '" class="hidden"><button ' . $close_js . '>Annuler</button></p>';
48 48
49 $submit_js = 'onclick="submitArticle(\'' . $id . '\')"'; 49 $submit_js = 'onclick="submitArticle(\'' . $id . '\')"';
50 $submit_article = '<p id="submit-' . $id . '" class="hidden"><a href="#"><button ' . $submit_js . '>Valider</button></a></p>'; 50 $submit_article = '<p id="submit-' . $id . '" class="hidden"><button ' . $submit_js . '>Valider</button></p>';
51 51
52 $admin_buttons = $modify_article . $up_button . $down_button . $delete_article . $close_editor . $submit_article; 52 $admin_buttons = $modify_article . $up_button . $down_button . $delete_article . $close_editor . $submit_article;
53 } 53 }
diff --git a/src/view/BlogBuilder.php b/src/view/BlogBuilder.php
index 8c2125f..ca020b2 100644
--- a/src/view/BlogBuilder.php
+++ b/src/view/BlogBuilder.php
@@ -7,6 +7,7 @@ class BlogBuilder extends AbstractBuilder
7{ 7{
8 public function __construct(Node $node) 8 public function __construct(Node $node)
9 { 9 {
10 parent::__construct($node);
10 $viewFile = self::VIEWS_PATH . $node->getName() . '.php'; 11 $viewFile = self::VIEWS_PATH . $node->getName() . '.php';
11 12
12 if(file_exists($viewFile)) 13 if(file_exists($viewFile))
@@ -18,26 +19,44 @@ class BlogBuilder extends AbstractBuilder
18 19
19 // ajouter un article 20 // ajouter un article
20 $new_article = ''; 21 $new_article = '';
21 $new_article_admin_buttons = '';
22 if($_SESSION['admin']) 22 if($_SESSION['admin'])
23 { 23 {
24 $id = 'new'; 24 $id = 'n' . $this->id_node;
25
26 //$link = new URL(['page' => CURRENT_PAGE, 'action' => 'open_editor']);
27 $js = 'onclick="openEditor(\'' . $id . '\')"'; 25 $js = 'onclick="openEditor(\'' . $id . '\')"';
28 //$new_article = '<article><a href="' . $link . '"><button>Nouvel article</button></a></article>'; 26
29 $new_article = '<article><p id="new"></p>' . "\n" . 27 $share_button = '<p class="share hidden"><img class="action_icon" src="assets/share.svg"></p>';
30 '<p id="new-' . $id . '"><a href="#"><button ' . $js . '><img class="action_icon" src="assets/edit.svg">Nouvel article</button></a></p>'; 28 $html = '';
29
30 $new_button = '<p id="new-' . $id . '">' . "\n" .
31 '<button ' . $js . '><img class="action_icon" src="assets/edit.svg">Nouvel article</button></p>';
32
33 $modify_js = 'onclick="openEditor(\'' . $id . '\')"';
34 $modify_article = '<p id="edit-' . $id . '" class="hidden"><img class="action_icon" src="assets/edit.svg" ' . $modify_js . '></p>' . "\n";
35
36 $up_js = 'onclick="switchPositions(\'' . $id . '\', \'up\')"';
37 $up_button = '<p id="position_up-' . $id . '" class="hidden"><img class="action_icon" src="assets/arrow-up.svg" ' . $up_js . '></p>' . "\n";
38
39 $down_js = 'onclick="switchPositions(\'' . $id . '\', \'down\')"';
40 $down_button = '<p id="position_down-' . $id . '" class="hidden"><img class="action_icon" src="assets/arrow-down.svg" ' . $down_js . '></p>' . "\n";
41
42 $delete_js = 'onclick="deleteArticle(\'' . $id . '\')"';
43 $delete_article = '<p id="delete-' . $id . '" class="hidden"><img class="action_icon" src="assets/delete-bin.svg" ' . $delete_js . '></p>' . "\n";
31 44
32 $close_js = 'onclick="closeEditor(\'' . $id . '\')"'; 45 $close_js = 'onclick="closeEditor(\'' . $id . '\')"';
33 $close_editor = '<div class="article_admin_zone"><p id="cancel-' . $id . '" class="hidden"><a href="#"><button ' . $close_js . '>Annuler</button></a></p>'; 46 $close_editor = '<p id="cancel-' . $id . '" class="hidden"><button ' . $close_js . '>Annuler</button></p>';
34 47
35 $submit_js = 'onclick="submitArticle(\'' . $id . '\')"'; 48 $submit_js = 'onclick="submitArticle(\'' . $id . '\', \'\', clone' . $this->id_node . ')"';
36 $submit_article = '<p id="submit-' . $id . '" class="hidden"><a href="#"><button ' . $submit_js . '>Valider</button></a></p></div></article>'; 49 $submit_article = '<p id="submit-' . $id . '" class="hidden"><button ' . $submit_js . '>Valider</button></p>';
37 50
38 $new_article_admin_buttons = $close_editor . $submit_article; 51 $admin_buttons = $new_button . $modify_article . $up_button . $down_button . $delete_article . $close_editor . $submit_article;
52
53 // squelette d'un nouvel article
54 ob_start();
55 require self::VIEWS_PATH . 'article.php';
56 $new_article = ob_get_clean();
39 } 57 }
40 58
59 // articles existants
41 $this->useChildrenBuilder($node); 60 $this->useChildrenBuilder($node);
42 $content = $this->html; 61 $content = $this->html;
43 62
diff --git a/src/view/GaleryBuilder.php b/src/view/GaleryBuilder.php
index 89be2b1..a895d70 100644
--- a/src/view/GaleryBuilder.php
+++ b/src/view/GaleryBuilder.php
@@ -7,6 +7,7 @@ class GaleryBuilder extends AbstractBuilder
7{ 7{
8 public function __construct(Node $node) 8 public function __construct(Node $node)
9 { 9 {
10 parent::__construct($node);
10 $viewFile = self::VIEWS_PATH . $node->getName() . '.php'; 11 $viewFile = self::VIEWS_PATH . $node->getName() . '.php';
11 12
12 if(file_exists($viewFile)) 13 if(file_exists($viewFile))
@@ -18,26 +19,44 @@ class GaleryBuilder extends AbstractBuilder
18 19
19 // ajouter un article 20 // ajouter un article
20 $new_article = ''; 21 $new_article = '';
21 $new_article_admin_buttons = '';
22 if($_SESSION['admin']) 22 if($_SESSION['admin'])
23 { 23 {
24 $id = 'new'; 24 $id = 'n' . $this->id_node;
25
26 //$link = new URL(['page' => CURRENT_PAGE, 'action' => 'open_editor']);
27 $js = 'onclick="openEditor(\'' . $id . '\')"'; 25 $js = 'onclick="openEditor(\'' . $id . '\')"';
28 //$new_article = '<article><a href="' . $link . '"><button>Nouvel article</button></a></article>'; 26
29 $new_article = '<article><p id="new"></p>' . "\n" . 27 $share_button = '<p class="share hidden"><img class="action_icon" src="assets/share.svg"></p>';
30 '<p id="new-' . $id . '"><a href="#"><button ' . $js . '><img class="action_icon" src="assets/edit.svg">Nouvel article</button></a></p>'; 28 $html = '';
29
30 $new_button = '<p id="new-' . $id . '">' . "\n" .
31 '<button ' . $js . '><img class="action_icon" src="assets/edit.svg">Nouvel article</button></p>';
32
33 $modify_js = 'onclick="openEditor(\'' . $id . '\')"';
34 $modify_article = '<p id="edit-' . $id . '" class="hidden"><img class="action_icon" src="assets/edit.svg" ' . $modify_js . '></p>' . "\n";
35
36 $up_js = 'onclick="switchPositions(\'' . $id . '\', \'up\')"';
37 $up_button = '<p id="position_up-' . $id . '" class="hidden"><img class="action_icon" src="assets/arrow-up.svg" ' . $up_js . '></p>' . "\n";
38
39 $down_js = 'onclick="switchPositions(\'' . $id . '\', \'down\')"';
40 $down_button = '<p id="position_down-' . $id . '" class="hidden"><img class="action_icon" src="assets/arrow-down.svg" ' . $down_js . '></p>' . "\n";
41
42 $delete_js = 'onclick="deleteArticle(\'' . $id . '\')"';
43 $delete_article = '<p id="delete-' . $id . '" class="hidden"><img class="action_icon" src="assets/delete-bin.svg" ' . $delete_js . '></p>' . "\n";
31 44
32 $close_js = 'onclick="closeEditor(\'' . $id . '\')"'; 45 $close_js = 'onclick="closeEditor(\'' . $id . '\')"';
33 $close_editor = '<div class="article_admin_zone"><p id="cancel-' . $id . '" class="hidden"><a href="#"><button ' . $close_js . '>Annuler</button></a></p>'; 46 $close_editor = '<p id="cancel-' . $id . '" class="hidden"><button ' . $close_js . '>Annuler</button></p>';
34 47
35 $submit_js = 'onclick="submitArticle(\'' . $id . '\')"'; 48 $submit_js = 'onclick="submitArticle(\'' . $id . '\', \'\', clone' . $this->id_node . ')"';
36 $submit_article = '<p id="submit-' . $id . '" class="hidden"><a href="#"><button ' . $submit_js . '>Valider</button></a></p></div></article>'; 49 $submit_article = '<p id="submit-' . $id . '" class="hidden"><button ' . $submit_js . '>Valider</button></p>';
37 50
38 $new_article_admin_buttons = $close_editor . $submit_article; 51 $admin_buttons = $new_button . $modify_article . $up_button . $down_button . $delete_article . $close_editor . $submit_article;
52
53 // squelette d'un nouvel article
54 ob_start();
55 require self::VIEWS_PATH . 'article.php';
56 $new_article = ob_get_clean();
39 } 57 }
40 58
59 // articles existants
41 $this->useChildrenBuilder($node); 60 $this->useChildrenBuilder($node);
42 $content = $this->html; 61 $content = $this->html;
43 62
diff --git a/src/view/GridBuilder.php b/src/view/GridBuilder.php
index 6e16d46..e183e6f 100644
--- a/src/view/GridBuilder.php
+++ b/src/view/GridBuilder.php
@@ -7,6 +7,7 @@ class GridBuilder extends AbstractBuilder
7{ 7{
8 public function __construct(Node $node) 8 public function __construct(Node $node)
9 { 9 {
10 parent::__construct($node);
10 $viewFile = self::VIEWS_PATH . $node->getName() . '.php'; 11 $viewFile = self::VIEWS_PATH . $node->getName() . '.php';
11 12
12 if(file_exists($viewFile)) 13 if(file_exists($viewFile))
@@ -18,32 +19,50 @@ class GridBuilder extends AbstractBuilder
18 19
19 // ajouter un article 20 // ajouter un article
20 $new_article = ''; 21 $new_article = '';
21 $new_article_admin_buttons = '';
22 if($_SESSION['admin']) 22 if($_SESSION['admin'])
23 { 23 {
24 $id = 'new'; 24 $id = 'n' . $this->id_node;
25 $js = 'onclick="openEditor(\'' . $id . '\')"'; 25 $js = 'onclick="openEditor(\'' . $id . '\')"';
26 26
27 if(Director::$page_path->getLast()->getEndOfPath() === 'accueil') 27 $share_button = '<p class="share hidden"><img class="action_icon" src="assets/share.svg"></p>';
28 { 28 $html = '';
29 $new_article = '<article><p id="new"></p>' . "\n" . 29
30 '<p><a href="' . new URL(['page' => 'article']) . '"><button><img class="action_icon" src="assets/edit.svg">Nouvel article</button></a></p>'; 30 if(CURRENT_PAGE === 'accueil'){
31 $new_button = '<p><a class="link_to_article" href="' . new URL(['page' => 'article', 'id' => $id]) . '">
32 <button><img class="action_icon" src="assets/book-open.svg">Nouvel article</button></a></p>';
31 } 33 }
32 else 34 else{
33 { 35 $new_button = '<p id="new-' . $id . '">' . "\n" .
34 $new_article = '<article><p id="new"></p>' . "\n" . 36 '<button ' . $js . '><img class="action_icon" src="assets/edit.svg">Nouvel article</button></p>';
35 '<p id="new-' . $id . '"><a href="#"><button ' . $js . '><img class="action_icon" src="assets/edit.svg">Nouvel article</button></a></p>';
36 } 37 }
38
39 $modify_js = 'onclick="openEditor(\'' . $id . '\')"';
40 $modify_article = '<p id="edit-' . $id . '" class="hidden"><img class="action_icon" src="assets/edit.svg" ' . $modify_js . '></p>' . "\n";
41
42 $up_js = 'onclick="switchPositions(\'' . $id . '\', \'up\')"';
43 $up_button = '<p id="position_up-' . $id . '" class="hidden"><img class="action_icon" src="assets/arrow-up.svg" ' . $up_js . '></p>' . "\n";
37 44
45 $down_js = 'onclick="switchPositions(\'' . $id . '\', \'down\')"';
46 $down_button = '<p id="position_down-' . $id . '" class="hidden"><img class="action_icon" src="assets/arrow-down.svg" ' . $down_js . '></p>' . "\n";
47
48 $delete_js = 'onclick="deleteArticle(\'' . $id . '\')"';
49 $delete_article = '<p id="delete-' . $id . '" class="hidden"><img class="action_icon" src="assets/delete-bin.svg" ' . $delete_js . '></p>' . "\n";
50
38 $close_js = 'onclick="closeEditor(\'' . $id . '\')"'; 51 $close_js = 'onclick="closeEditor(\'' . $id . '\')"';
39 $close_editor = '<div class="article_admin_zone"><p id="cancel-' . $id . '" class="hidden"><a href="#"><button ' . $close_js . '>Annuler</button></a></p>'; 52 $close_editor = '<p id="cancel-' . $id . '" class="hidden"><button ' . $close_js . '>Annuler</button></p>';
40 53
41 $submit_js = 'onclick="submitArticle(\'' . $id . '\')"'; 54 $submit_js = 'onclick="submitArticle(\'' . $id . '\', \'\', clone' . $this->id_node . ')"';
42 $submit_article = '<p id="submit-' . $id . '" class="hidden"><a href="#"><button ' . $submit_js . '>Valider</button></a></p></div></article>'; 55 $submit_article = '<p id="submit-' . $id . '" class="hidden"><button ' . $submit_js . '>Valider</button></p>';
43 56
44 $new_article_admin_buttons = $close_editor . $submit_article; 57 $admin_buttons = $new_button . $modify_article . $up_button . $down_button . $delete_article . $close_editor . $submit_article;
58
59 // squelette d'un nouvel article
60 ob_start();
61 require self::VIEWS_PATH . 'article.php';
62 $new_article = ob_get_clean();
45 } 63 }
46 64
65 // articles existants
47 $this->useChildrenBuilder($node); 66 $this->useChildrenBuilder($node);
48 $content = $this->html; 67 $content = $this->html;
49 68
diff --git a/src/view/templates/article.php b/src/view/templates/article.php
index f3ab32f..c57c1cb 100644
--- a/src/view/templates/article.php
+++ b/src/view/templates/article.php
@@ -10,5 +10,4 @@
10 <?= $admin_buttons ?> 10 <?= $admin_buttons ?>
11 </div> 11 </div>
12 </div> 12 </div>
13
14</article> \ No newline at end of file 13</article> \ No newline at end of file
diff --git a/src/view/templates/blog.php b/src/view/templates/blog.php
index 35cac8b..e2066c8 100644
--- a/src/view/templates/blog.php
+++ b/src/view/templates/blog.php
@@ -1,6 +1,10 @@
1<section class="blog"> 1<section class="blog" id="<?= $this->id_node ?>">
2 <h3><?= $title ?></h3> 2 <h3><?= $title ?></h3>
3<?= $new_article ?> 3<?= $new_article ?>
4<?= $new_article_admin_buttons ?> 4 <script>
5 var clone<?= $this->id_node ?> = document.currentScript.previousElementSibling.cloneNode(true);
6 </script>
7 <div>
5<?= $content ?> 8<?= $content ?>
9 </div>
6</section> \ No newline at end of file 10</section> \ No newline at end of file
diff --git a/src/view/templates/galery.php b/src/view/templates/galery.php
index 306526f..246c4dd 100644
--- a/src/view/templates/galery.php
+++ b/src/view/templates/galery.php
@@ -1,9 +1,10 @@
1<section class="galery"> 1<section class="galery" id="<?= $this->id_node ?>">
2 <h3><?= $title ?></h3> 2 <h3><?= $title ?></h3>
3<?= $new_article ?> 3<?= $new_article ?>
4<?= $new_article_admin_buttons ?> 4 <script>
5 var clone<?= $this->id_node ?> = document.currentScript.previousElementSibling.cloneNode(true);
6 </script>
5 <div class="galery_photos"> 7 <div class="galery_photos">
6 <a><p></p></a>
7<?= $content ?> 8<?= $content ?>
8 </div> 9 </div>
9 <script>enableGaleryScroller();</script> 10 <script>enableGaleryScroller();</script>
diff --git a/src/view/templates/grid.php b/src/view/templates/grid.php
index a09ed40..f9e441d 100644
--- a/src/view/templates/grid.php
+++ b/src/view/templates/grid.php
@@ -1,7 +1,9 @@
1<section class="grid"> 1<section class="grid" id="<?= $this->id_node ?>">
2 <h3><?= $title ?></h3> 2 <h3><?= $title ?></h3>
3<?= $new_article ?> 3<?= $new_article ?>
4<?= $new_article_admin_buttons ?> 4 <script>
5 var clone<?= $this->id_node ?> = document.currentScript.previousElementSibling.cloneNode(true);
6 </script>
5 <div class="grid_columns"> 7 <div class="grid_columns">
6<?= $content ?> 8<?= $content ?>
7 </div> 9 </div>