diff options
| author | polo <ordipolo@gmx.fr> | 2025-04-07 07:46:27 +0200 |
|---|---|---|
| committer | polo <ordipolo@gmx.fr> | 2025-04-07 07:46:27 +0200 |
| commit | 09bea09c8157ff45279f0d06aa9d313448c0bec5 (patch) | |
| tree | 4f79c47678df12cb508607be040050c8f08455aa | |
| parent | 022d0c36258c874a21a36e207ae89aa8d91e44a1 (diff) | |
| download | cms-09bea09c8157ff45279f0d06aa9d313448c0bec5.tar.gz cms-09bea09c8157ff45279f0d06aa9d313448c0bec5.tar.bz2 cms-09bea09c8157ff45279f0d06aa9d313448c0bec5.zip | |
nouvelle "news"
| -rw-r--r-- | public/assets/logo-fond-bleu.png | bin | 61236 -> 0 bytes | |||
| -rw-r--r-- | public/js/main.js | 96 | ||||
| -rw-r--r-- | public/js/tinymce.js | 166 | ||||
| -rw-r--r-- | src/controller/Director.php | 2 | ||||
| -rw-r--r-- | src/controller/ajax.php | 46 | ||||
| -rw-r--r-- | src/model/Path.php | 6 | ||||
| -rw-r--r-- | src/model/entities/Node.php | 10 | ||||
| -rw-r--r-- | src/view/GridBuilder.php | 4 | ||||
| -rw-r--r-- | src/view/MainBuilder.php | 18 | ||||
| -rw-r--r-- | src/view/NewBuilder.php | 63 |
10 files changed, 257 insertions, 154 deletions
diff --git a/public/assets/logo-fond-bleu.png b/public/assets/logo-fond-bleu.png deleted file mode 100644 index f51ac9c..0000000 --- a/public/assets/logo-fond-bleu.png +++ /dev/null | |||
| Binary files differ | |||
diff --git a/public/js/main.js b/public/js/main.js index c05eb2f..cb76ea8 100644 --- a/public/js/main.js +++ b/public/js/main.js | |||
| @@ -90,13 +90,8 @@ function changeDate(id_date) | |||
| 90 | const real_id = 'i' + id_date.slice(1); | 90 | const real_id = 'i' + id_date.slice(1); |
| 91 | const date_span = document.getElementById(id_date); // = <span> | 91 | const date_span = document.getElementById(id_date); // = <span> |
| 92 | var old_date = date_span.innerHTML; | 92 | var old_date = date_span.innerHTML; |
| 93 | 93 | ||
| 94 | // changer "le 28-12-2024 à 23h14" en "2024-12-28T23:14" | 94 | old_date = dateToISO(old_date); |
| 95 | let values = old_date.split(" à "); // 2 parties: date et heure | ||
| 96 | values[1] = values[1].replace('h', ':'); | ||
| 97 | values[0] = values[0].replace("le ", ""); | ||
| 98 | let date = values[0].split("-"); // tableau jj-mm-aaaa | ||
| 99 | old_date = date[2] + '-' + date[1] + "-" + date[0] + "T" + values[1]; | ||
| 100 | 95 | ||
| 101 | var label = document.createElement('label'); | 96 | var label = document.createElement('label'); |
| 102 | label.textContent = 'Choisir une date: '; | 97 | label.textContent = 'Choisir une date: '; |
| @@ -117,6 +112,15 @@ function changeDate(id_date) | |||
| 117 | document.querySelector(`#submit-${id_date}`).classList.remove('hidden'); | 112 | document.querySelector(`#submit-${id_date}`).classList.remove('hidden'); |
| 118 | } | 113 | } |
| 119 | 114 | ||
| 115 | function dateToISO(date){ | ||
| 116 | // changer "le 28-12-2024 à 23h14" en "2024-12-28T23:14" | ||
| 117 | let values = date.split(" à "); // 2 parties: date et heure | ||
| 118 | values[1] = values[1].replace('h', ':'); | ||
| 119 | values[0] = values[0].replace("le ", ""); | ||
| 120 | let date_array = values[0].split("-"); // tableau jj-mm-aaaa | ||
| 121 | return date_array[2] + '-' + date_array[1] + "-" + date_array[0] + "T" + values[1]; | ||
| 122 | } | ||
| 123 | |||
| 120 | function closeInput(id) | 124 | function closeInput(id) |
| 121 | { | 125 | { |
| 122 | const date_span = document.getElementById(id); | 126 | const date_span = document.getElementById(id); |
| @@ -133,40 +137,56 @@ function closeInput(id) | |||
| 133 | 137 | ||
| 134 | function submitDate(id_date) | 138 | function submitDate(id_date) |
| 135 | { | 139 | { |
| 136 | const date_input = document.getElementById('input-' + id_date); | 140 | var date_input = document.getElementById('input-' + id_date); |
| 141 | |||
| 142 | // cas des nouvelles "news" | ||
| 143 | const params = new URL(document.location).searchParams; // "search" = ? et paramètres, searchParams = objet avec des getters | ||
| 144 | if(params != null && params.get("id")[0] === 'n') | ||
| 145 | { | ||
| 146 | // modifier la date dans le <span> caché | ||
| 147 | date_input = updateDate(id_date, date_input); | ||
| 148 | closeInput(id_date); | ||
| 149 | return; | ||
| 150 | } | ||
| 151 | else{ | ||
| 152 | fetch('index.php?action=date_submit', { | ||
| 153 | method: 'POST', | ||
| 154 | headers: { | ||
| 155 | 'Content-Type': 'application/json' | ||
| 156 | }, | ||
| 157 | body: JSON.stringify({id: id_date, date: date_input.value}) | ||
| 158 | }) | ||
| 159 | .then(response => response.json()) | ||
| 160 | .then(data => { | ||
| 161 | if (data.success) { | ||
| 162 | // modifier la date dans le <span> caché | ||
| 163 | date_input = updateDate(id_date, date_input); | ||
| 164 | closeInput(id_date); | ||
| 165 | } | ||
| 166 | else { | ||
| 167 | console.error('Erreur lors de la sauvegarde de la date.'); | ||
| 168 | } | ||
| 169 | }) | ||
| 170 | .catch(error => { | ||
| 171 | console.error('Erreur:', error); | ||
| 172 | }); | ||
| 173 | } | ||
| 174 | } | ||
| 137 | 175 | ||
| 138 | fetch('index.php?action=date_submit', { | 176 | function updateDate(id_date, date_input){ |
| 139 | method: 'POST', | 177 | var date_span = document.getElementById(id_date); |
| 140 | headers: { | 178 | let date = new Date(date_input.value); |
| 141 | 'Content-Type': 'application/json' | 179 | date_span.innerHTML = |
| 142 | }, | 180 | 'le ' + String(date.getDate()).padStart(2, '0') + '-' + |
| 143 | body: JSON.stringify({id: id_date, date: date_input.value}) | 181 | String(date.getMonth() + 1).padStart(2, '0') + '-' + |
| 144 | }) | 182 | String(date.getFullYear()).padStart(4, '0') + ' à ' + |
| 145 | .then(response => response.json()) | 183 | String(date.getHours()).padStart(2, '0') + 'h' + |
| 146 | .then(data => { | 184 | String(date.getMinutes()).padStart(2, '0'); |
| 147 | if (data.success) { | 185 | |
| 148 | // modifier la date dans le <span> caché | 186 | return date_input; |
| 149 | const date_span = document.getElementById(id_date); | ||
| 150 | let date = new Date(date_input.value); | ||
| 151 | date_span.innerHTML = | ||
| 152 | 'le ' + String(date.getDate()).padStart(2, '0') + '-' + | ||
| 153 | String(date.getMonth() + 1).padStart(2, '0') + '-' + | ||
| 154 | String(date.getFullYear()).padStart(4, '0') + ' à ' + | ||
| 155 | String(date.getHours()).padStart(2, '0') + 'h' + | ||
| 156 | String(date.getMinutes()).padStart(2, '0'); | ||
| 157 | |||
| 158 | closeInput(id_date); | ||
| 159 | } | ||
| 160 | else { | ||
| 161 | console.error('Erreur lors de la sauvegarde de la date.'); | ||
| 162 | } | ||
| 163 | }) | ||
| 164 | .catch(error => { | ||
| 165 | console.error('Erreur:', error); | ||
| 166 | }); | ||
| 167 | } | 187 | } |
| 168 | 188 | ||
| 169 | function findParent(element, tag_name) { | 189 | function findParent(element, tag_name){ |
| 170 | while (element !== null) { | 190 | while (element !== null) { |
| 171 | if (element.tagName === tag_name.toUpperCase()) // tagName est en majuscules | 191 | if (element.tagName === tag_name.toUpperCase()) // tagName est en majuscules |
| 172 | { | 192 | { |
diff --git a/public/js/tinymce.js b/public/js/tinymce.js index 1e40f51..00868ee 100644 --- a/public/js/tinymce.js +++ b/public/js/tinymce.js | |||
| @@ -38,10 +38,10 @@ function openEditor(id, page = '') { | |||
| 38 | document.querySelector(`#submit-${id}`).classList.remove('hidden'); | 38 | document.querySelector(`#submit-${id}`).classList.remove('hidden'); |
| 39 | if(creation_mode === false){ | 39 | if(creation_mode === false){ |
| 40 | document.querySelector(`#edit-${id}`).classList.add('hidden'); | 40 | document.querySelector(`#edit-${id}`).classList.add('hidden'); |
| 41 | document.querySelector(`#delete-${real_id}`).classList.add('hidden'); | ||
| 42 | if(page != 'article'){ | 41 | if(page != 'article'){ |
| 43 | document.querySelector(`#position_up-${id}`).classList.add('hidden'); | 42 | document.querySelector(`#position_up-${id}`).classList.add('hidden'); |
| 44 | document.querySelector(`#position_down-${id}`).classList.add('hidden'); | 43 | document.querySelector(`#position_down-${id}`).classList.add('hidden'); |
| 44 | document.querySelector(`#delete-${real_id}`).classList.add('hidden'); | ||
| 45 | } | 45 | } |
| 46 | } | 46 | } |
| 47 | else{ | 47 | else{ |
| @@ -175,37 +175,75 @@ function closeEditor(id, page = '', restore_old = true) | |||
| 175 | 175 | ||
| 176 | } | 176 | } |
| 177 | 177 | ||
| 178 | function submitArticle(id, page = '', clone = null) { | 178 | function submitArticle(id, page = '', clone = null) |
| 179 | //var creation_mode; | 179 | { |
| 180 | if(id[0] === 'n'){ | 180 | /*if(id[0] === 'n' && clone == null){ |
| 181 | //creation_mode = true; | 181 | return; // sécurité |
| 182 | }*/ | ||
| 183 | var editor; | ||
| 184 | const params = new URL(document.location).searchParams; // "search" = ? et paramètres, searchParams = objet avec des getters | ||
| 182 | 185 | ||
| 183 | // sécurité | 186 | // clic sur "tout enregistrer" |
| 184 | if(clone == null){ | 187 | if(id[0] === 'n' && page === 'article'){ |
| 185 | return; | 188 | const prefixes = ['t', 'p', 'i', 'd']; |
| 186 | } | 189 | const allElemsWithId = document.querySelectorAll('[id]'); |
| 187 | } | 190 | var content = {}; |
| 188 | else{ | ||
| 189 | //creation_mode = false; | ||
| 190 | } | ||
| 191 | 191 | ||
| 192 | // Récupérer l'éditeur correspondant à l'article | 192 | allElemsWithId.forEach(element => { |
| 193 | const editor = editors[id]; | 193 | const first_letter = element.id.charAt(0).toLowerCase(); |
| 194 | if(!editor) { | 194 | if(prefixes.includes(first_letter)){ |
| 195 | console.error('Éditeur non trouvé pour l\'article:', id); | 195 | content[first_letter] = element.innerHTML; |
| 196 | } | ||
| 197 | }) | ||
| 198 | content['d'] = dateToISO(content['d']); | ||
| 199 | |||
| 200 | // Envoi AJAX au serveur | ||
| 201 | fetch('index.php?action=editor_submit', { | ||
| 202 | method: 'POST', | ||
| 203 | headers: { | ||
| 204 | 'Content-Type': 'application/json' | ||
| 205 | }, | ||
| 206 | body: JSON.stringify({id: id, content: content}) | ||
| 207 | }) | ||
| 208 | .then(response => response.json()) | ||
| 209 | .then(data => { | ||
| 210 | if (data.success) { | ||
| 211 | console.log('données envoyées au serveur avec succès.'); | ||
| 212 | |||
| 213 | // remplacer les boutons (Enregistrer => Supprimer) | ||
| 214 | } | ||
| 215 | else { | ||
| 216 | alert('Erreur lors de la sauvegarde de l\'article.'); | ||
| 217 | } | ||
| 218 | }) | ||
| 219 | .catch(error => { | ||
| 220 | console.error('Erreur:', error); | ||
| 221 | }); | ||
| 196 | return; | 222 | return; |
| 197 | } | 223 | } |
| 224 | // champs à remplir des nouvelles "news" | ||
| 225 | else if(page === 'article' && params != null && params.get("id")[0] === 'n'){ | ||
| 226 | closeEditor(id, page, false); | ||
| 227 | //makeNewArticleButtons(id, id, clone); | ||
| 228 | return; | ||
| 229 | } | ||
| 230 | // dans les autres cas, on doit pouvoir récupérer l'éditeur | ||
| 231 | else{ | ||
| 232 | // l'éditeur correspond à l'article OU page "article" à un élément: titre, aperçu, article | ||
| 233 | editor = editors[id]; | ||
| 234 | if(!editor) { | ||
| 235 | console.error('Éditeur non trouvé pour l\'article:', id); | ||
| 236 | return; | ||
| 237 | } | ||
| 238 | } | ||
| 198 | 239 | ||
| 199 | // Récupérer le contenu de l'éditeur | ||
| 200 | const html = editor.getContent(); | ||
| 201 | |||
| 202 | // Envoi AJAX au serveur | 240 | // Envoi AJAX au serveur |
| 203 | fetch('index.php?action=editor_submit', { | 241 | fetch('index.php?action=editor_submit', { |
| 204 | method: 'POST', | 242 | method: 'POST', |
| 205 | headers: { | 243 | headers: { |
| 206 | 'Content-Type': 'application/json' | 244 | 'Content-Type': 'application/json' |
| 207 | }, | 245 | }, |
| 208 | body: JSON.stringify({id: id, content: html}) | 246 | body: JSON.stringify({id: id, content: editor.getContent()}) |
| 209 | }) | 247 | }) |
| 210 | .then(response => response.json()) | 248 | .then(response => response.json()) |
| 211 | .then(data => { | 249 | .then(data => { |
| @@ -213,48 +251,7 @@ function submitArticle(id, page = '', clone = null) { | |||
| 213 | // Fermer l'éditeur et mettre à jour le contenu de l'article | 251 | // Fermer l'éditeur et mettre à jour le contenu de l'article |
| 214 | closeEditor(id, page, false); | 252 | closeEditor(id, page, false); |
| 215 | if(id[0] === 'n'){ | 253 | if(id[0] === 'n'){ |
| 216 | var share_btn = document.querySelector(`.share.hidden`); // combinaison de deux classes | 254 | makeNewArticleButtons(id, data.article_id, clone); |
| 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.cloneNode(true), parent); // clone du squelette pour le garder intact | ||
| 254 | next_div.appendChild(parent); | ||
| 255 | } | ||
| 256 | else{ | ||
| 257 | //document.getElementById(id).innerHTML = html; | ||
| 258 | } | 255 | } |
| 259 | } | 256 | } |
| 260 | else { | 257 | else { |
| @@ -264,4 +261,47 @@ function submitArticle(id, page = '', clone = null) { | |||
| 264 | .catch(error => { | 261 | .catch(error => { |
| 265 | console.error('Erreur:', error); | 262 | console.error('Erreur:', error); |
| 266 | }); | 263 | }); |
| 264 | } | ||
| 265 | |||
| 266 | function makeNewArticleButtons(id, article_id, clone) | ||
| 267 | { | ||
| 268 | var share_btn = document.querySelector(`.share.hidden`); // combinaison de deux classes | ||
| 269 | var new_btn = document.querySelector(`#new-${id}`); | ||
| 270 | var edit_btn = document.querySelector(`#edit-${id}`); | ||
| 271 | var pos_up_btn = document.querySelector(`#position_up-${id}`); | ||
| 272 | var pos_down_btn = document.querySelector(`#position_down-${id}`); | ||
| 273 | var delete_btn = document.querySelector(`#delete-${id}`); | ||
| 274 | var cancel_btn = document.querySelector(`#cancel-${id}`); | ||
| 275 | var submit_btn = document.querySelector(`#submit-${id}`); | ||
| 276 | |||
| 277 | share_btn.classList.remove('hidden') | ||
| 278 | new_btn.classList.add('hidden'); | ||
| 279 | edit_btn.classList.remove('hidden'); | ||
| 280 | pos_up_btn.classList.remove('hidden'); | ||
| 281 | pos_down_btn.classList.remove('hidden'); | ||
| 282 | delete_btn.classList.remove('hidden'); | ||
| 283 | //cancel_btn.classList.add('hidden'); | ||
| 284 | //submit_btn.classList.add('hidden'); | ||
| 285 | |||
| 286 | var article = document.getElementById(id); | ||
| 287 | var parent = findParent(article, 'article'); | ||
| 288 | |||
| 289 | share_btn.setAttribute('onclick', "copyInClipBoard('" + window.location.href + article_id + "')"); // # de l'ancre ajouté au clic sur le lien ouvrant l'éditeur | ||
| 290 | article.id = article_id; | ||
| 291 | edit_btn.id = 'edit-' + article_id; | ||
| 292 | edit_btn.querySelector('.action_icon').setAttribute('onclick', "openEditor('" + article_id + "')"); | ||
| 293 | pos_up_btn.id = 'position_up-' + article_id; | ||
| 294 | pos_up_btn.querySelector('.action_icon').setAttribute('onclick', "switchPositions('" + article_id + "', 'up')"); | ||
| 295 | pos_down_btn.id = 'position_down-' + article_id; | ||
| 296 | pos_down_btn.querySelector('.action_icon').setAttribute('onclick', "switchPositions('" + article_id + "', 'down')"); | ||
| 297 | delete_btn.id = 'delete-' + article_id; | ||
| 298 | delete_btn.querySelector('.action_icon').setAttribute('onclick', "deleteArticle('" + article_id + "')"); | ||
| 299 | cancel_btn.id = 'cancel-' + article_id; | ||
| 300 | cancel_btn.querySelector('button').setAttribute('onclick', "closeEditor('" + article_id + "')"); | ||
| 301 | submit_btn.id = 'submit-' + article_id; | ||
| 302 | submit_btn.querySelector('button').setAttribute('onclick', "submitArticle('" + article_id + "')"); | ||
| 303 | |||
| 304 | var next_div = parent.nextElementSibling.nextElementSibling; | ||
| 305 | parent.parentNode.replaceChild(clone.cloneNode(true), parent); // clone du squelette pour le garder intact | ||
| 306 | next_div.appendChild(parent); | ||
| 267 | } \ No newline at end of file | 307 | } \ No newline at end of file |
diff --git a/src/controller/Director.php b/src/controller/Director.php index db84661..b7be9b8 100644 --- a/src/controller/Director.php +++ b/src/controller/Director.php | |||
| @@ -87,7 +87,7 @@ class Director | |||
| 87 | } | 87 | } |
| 88 | } | 88 | } |
| 89 | if(isset($new)){ | 89 | if(isset($new)){ |
| 90 | $main->setTempChild($new); | 90 | $main->setAdoptedChild($new); |
| 91 | } | 91 | } |
| 92 | } | 92 | } |
| 93 | 93 | ||
diff --git a/src/controller/ajax.php b/src/controller/ajax.php index b5c2e51..4863681 100644 --- a/src/controller/ajax.php +++ b/src/controller/ajax.php | |||
| @@ -18,32 +18,54 @@ if($_SERVER['CONTENT_TYPE'] === 'application/json' && isset($_GET['action'])) | |||
| 18 | if(json_last_error() === JSON_ERROR_NONE) | 18 | if(json_last_error() === JSON_ERROR_NONE) |
| 19 | { | 19 | { |
| 20 | $id = $json['id']; | 20 | $id = $json['id']; |
| 21 | $content = Security::secureString($json['content']); | ||
| 22 | $director = new Director($entityManager); | 21 | $director = new Director($entityManager); |
| 23 | 22 | ||
| 24 | // nouvel article | 23 | // cas d'une nouvelle "news" |
| 25 | if($id[0] === 'n') | 24 | if(is_array($json['content'])){ |
| 26 | { | 25 | foreach($json['content'] as $one_input){ |
| 26 | $one_input = Security::secureString($one_input); | ||
| 27 | } | ||
| 28 | $content = $json['content']; | ||
| 29 | } | ||
| 30 | else{ | ||
| 31 | $content = Security::secureString($json['content']); | ||
| 27 | if($content === ''){ | 32 | if($content === ''){ |
| 28 | echo json_encode(['success' => false, 'message' => 'pas de données à sauvegarder']); | 33 | echo json_encode(['success' => false, 'message' => 'pas de données à sauvegarder']); |
| 29 | die; | 34 | die; |
| 30 | } | 35 | } |
| 36 | } | ||
| 37 | |||
| 38 | // nouvel article | ||
| 39 | if($id[0] === 'n') | ||
| 40 | { | ||
| 31 | $section_id = (int)substr($id, 1); // id du bloc <section> | 41 | $section_id = (int)substr($id, 1); // id du bloc <section> |
| 32 | $director->makeSectionNode($section_id); | 42 | $director->makeSectionNode($section_id); |
| 33 | $node = $director->getNode(); // = <section> | 43 | $node = $director->getNode(); // = <section> |
| 34 | 44 | ||
| 35 | $timestamp = time(); | 45 | if(is_array($content)){ |
| 36 | $date = new \DateTime; | 46 | // |
| 37 | $date->setTimestamp($timestamp); | 47 | //$timestamp = time(); // int |
| 48 | $date = new \DateTime($content['d']); | ||
| 49 | |||
| 50 | //echo substr($content['i'], 1) . ' '; | ||
| 51 | //echo $article_id;die; | ||
| 52 | $article = new Article($content['i'], $date, $content['t'], $content['p']); | ||
| 53 | $article_node = new Node('new', 'i' . (string)$date->getTimestamp(), [], count($node->getChildren()) + 1, $node, $node->getPage(), $article); | ||
| 38 | 54 | ||
| 39 | $article = new Article($content, $date); // le "current" timestamp est obtenu par la BDD | 55 | // id_node tout juste généré |
| 40 | $article_node = new Node('article', 'i' . (string)$timestamp, [], count($node->getChildren()) + 1, $node, $node->getPage(), $article); | 56 | //$article_node->getId(); |
| 57 | } | ||
| 58 | else{ | ||
| 59 | $timestamp = time(); | ||
| 60 | $date = new \DateTime; | ||
| 61 | $date->setTimestamp($timestamp); | ||
| 62 | |||
| 63 | $article = new Article($content, $date); // le "current" timestamp est obtenu par la BDD | ||
| 64 | $article_node = new Node('article', 'i' . (string)$timestamp, [], count($node->getChildren()) + 1, $node, $node->getPage(), $article); | ||
| 65 | } | ||
| 41 | 66 | ||
| 42 | $entityManager->persist($article_node); | 67 | $entityManager->persist($article_node); |
| 43 | $entityManager->flush(); | 68 | $entityManager->flush(); |
| 44 | |||
| 45 | // id_node tout juste généré | ||
| 46 | //$article_node->getId(); | ||
| 47 | 69 | ||
| 48 | echo json_encode(['success' => true, 'article_id' => $article_node->getArticleTimestamp()]); | 70 | echo json_encode(['success' => true, 'article_id' => $article_node->getArticleTimestamp()]); |
| 49 | die; | 71 | die; |
diff --git a/src/model/Path.php b/src/model/Path.php index 6faadfd..11be6fe 100644 --- a/src/model/Path.php +++ b/src/model/Path.php | |||
| @@ -17,12 +17,6 @@ class Path extends Page | |||
| 17 | $this->findPage(Director::$menu_data, $path_array); // remplit $this->current_page | 17 | $this->findPage(Director::$menu_data, $path_array); // remplit $this->current_page |
| 18 | } | 18 | } |
| 19 | catch(Exception $e){} | 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 | } | 20 | } |
| 27 | 21 | ||
| 28 | // produit un tableau de Page en comparant le chemin demandé avec les données dans Menu | 22 | // produit un tableau de Page en comparant le chemin demandé avec les données dans Menu |
diff --git a/src/model/entities/Node.php b/src/model/entities/Node.php index c9b310a..a52a7e6 100644 --- a/src/model/entities/Node.php +++ b/src/model/entities/Node.php | |||
| @@ -52,7 +52,7 @@ class Node | |||
| 52 | // -- fin des attributs destinés à doctrine, début du code utilisateur -- | 52 | // -- fin des attributs destinés à doctrine, début du code utilisateur -- |
| 53 | 53 | ||
| 54 | private array $children = []; // tableau de Node | 54 | private array $children = []; // tableau de Node |
| 55 | private ?self $temp_child = null; // = "new" est l'enfant de "main" lorsque la page est "article" | 55 | private ?self $adopted = null; // = "new" est un enfant de "main" lorsque la page est "article" |
| 56 | 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) | 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 | { | 58 | { |
| @@ -176,12 +176,12 @@ class Node | |||
| 176 | $this->children = array_values($this->children); // réindexer pour supprimer la case vide | 176 | $this->children = array_values($this->children); // réindexer pour supprimer la case vide |
| 177 | } | 177 | } |
| 178 | 178 | ||
| 179 | public function getTempChild(): ?self // peut renvoyer null | 179 | public function getAdoptedChild(): ?self // peut renvoyer null |
| 180 | { | 180 | { |
| 181 | return $this->temp_child; | 181 | return $this->adopted; |
| 182 | } | 182 | } |
| 183 | public function setTempChild(self $child): void | 183 | public function setAdoptedChild(self $child): void |
| 184 | { | 184 | { |
| 185 | $this->temp_child = $child; | 185 | $this->adopted = $child; |
| 186 | } | 186 | } |
| 187 | } | 187 | } |
diff --git a/src/view/GridBuilder.php b/src/view/GridBuilder.php index e183e6f..fdc5426 100644 --- a/src/view/GridBuilder.php +++ b/src/view/GridBuilder.php | |||
| @@ -27,9 +27,9 @@ class GridBuilder extends AbstractBuilder | |||
| 27 | $share_button = '<p class="share hidden"><img class="action_icon" src="assets/share.svg"></p>'; | 27 | $share_button = '<p class="share hidden"><img class="action_icon" src="assets/share.svg"></p>'; |
| 28 | $html = ''; | 28 | $html = ''; |
| 29 | 29 | ||
| 30 | if(CURRENT_PAGE === 'accueil'){ | 30 | if(Director::$page_path->getLast()->getEndOfPath() === 'accueil'){ |
| 31 | $new_button = '<p><a class="link_to_article" href="' . new URL(['page' => 'article', 'id' => $id]) . '"> | 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>'; | 32 | <button><img class="action_icon" src="assets/edit.svg">Nouvel article</button></a></p>'; |
| 33 | } | 33 | } |
| 34 | else{ | 34 | else{ |
| 35 | $new_button = '<p id="new-' . $id . '">' . "\n" . | 35 | $new_button = '<p id="new-' . $id . '">' . "\n" . |
diff --git a/src/view/MainBuilder.php b/src/view/MainBuilder.php index a44570b..ea7b8c3 100644 --- a/src/view/MainBuilder.php +++ b/src/view/MainBuilder.php | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | <?php | 1 | <?php |
| 2 | // src/view/MainBuilder.php | 2 | // src/view/MainBuilder.php |
| 3 | 3 | ||
| 4 | use App\Entity\Article; | ||
| 4 | use App\Entity\Node; | 5 | use App\Entity\Node; |
| 5 | 6 | ||
| 6 | class MainBuilder extends AbstractBuilder | 7 | class MainBuilder extends AbstractBuilder |
| @@ -10,11 +11,22 @@ class MainBuilder extends AbstractBuilder | |||
| 10 | $this->html .= "<main>\n"; | 11 | $this->html .= "<main>\n"; |
| 11 | 12 | ||
| 12 | if(Director::$page_path->getLast()->getEndOfPath() === 'article'){ | 13 | if(Director::$page_path->getLast()->getEndOfPath() === 'article'){ |
| 13 | if($node->getTempChild() == null){ | 14 | // pas censé arriver |
| 14 | $new = new Node; | 15 | if(!isset($_GET['id'])){ |
| 16 | header('Location: ' . new URL); | ||
| 17 | die; | ||
| 18 | } | ||
| 19 | |||
| 20 | if($node->getAdoptedChild() == null){ | ||
| 21 | // on pourrait raccourcir ça | ||
| 22 | $timestamp = time(); // int | ||
| 23 | $date = new \DateTime; | ||
| 24 | $date->setTimestamp($timestamp); // \DateTime | ||
| 25 | $article = new Article('', $date); | ||
| 26 | $new = new Node('new', 'i' . (string)$timestamp, [], 0, null, null, $article); | ||
| 15 | } | 27 | } |
| 16 | else{ | 28 | else{ |
| 17 | $new = $node->getTempChild(); | 29 | $new = $node->getAdoptedChild(); |
| 18 | } | 30 | } |
| 19 | //$builder_name = $this->snakeToPascalCase($new->getName()) . 'Builder'; | 31 | //$builder_name = $this->snakeToPascalCase($new->getName()) . 'Builder'; |
| 20 | $builder_name = 'NewBuilder'; | 32 | $builder_name = 'NewBuilder'; |
diff --git a/src/view/NewBuilder.php b/src/view/NewBuilder.php index acde8b4..a862a08 100644 --- a/src/view/NewBuilder.php +++ b/src/view/NewBuilder.php | |||
| @@ -5,7 +5,7 @@ use App\Entity\Node; | |||
| 5 | 5 | ||
| 6 | class NewBuilder extends AbstractBuilder | 6 | class NewBuilder extends AbstractBuilder |
| 7 | { | 7 | { |
| 8 | public function __construct(Node $node) | 8 | public function __construct(Node $node, ) |
| 9 | { | 9 | { |
| 10 | $viewFile = self::VIEWS_PATH . $node->getName() . '.php'; | 10 | $viewFile = self::VIEWS_PATH . $node->getName() . '.php'; |
| 11 | 11 | ||
| @@ -50,10 +50,15 @@ class NewBuilder extends AbstractBuilder | |||
| 50 | //$date = str_replace(':', 'h', $date_object->format('d-m-Y à H:i')); | 50 | //$date = str_replace(':', 'h', $date_object->format('d-m-Y à H:i')); |
| 51 | 51 | ||
| 52 | // partage | 52 | // partage |
| 53 | $share_link = new URL(['page' => CURRENT_PAGE], $id); | 53 | $share_link = new URL(['page' => 'article', 'id' => $id]); |
| 54 | isset($_GET['id']) ? $share_link->addParams(['id' => $_GET['id']]) : ''; | ||
| 55 | $share_js = 'onclick="copyInClipBoard(\'' . $share_link . '\')"'; | 54 | $share_js = 'onclick="copyInClipBoard(\'' . $share_link . '\')"'; |
| 56 | $share_button = '<a class="share" href="' . $share_link . '" ' . $share_js . '><img class="action_icon" src="assets/share.svg"></a>' . "\n"; | 55 | if(isset($_GET['id']) && $_GET['id'][0] === 'n'){ |
| 56 | $class = 'class="share hidden"'; | ||
| 57 | } | ||
| 58 | else{ | ||
| 59 | $class = 'class="share"'; | ||
| 60 | } | ||
| 61 | $share_button = '<p ' . $class . ' ' . $share_js . '><img class="action_icon" src="assets/share.svg"></p>' . "\n"; | ||
| 57 | 62 | ||
| 58 | // modifier un article | 63 | // modifier un article |
| 59 | $title_buttons = ''; | 64 | $title_buttons = ''; |
| @@ -65,53 +70,64 @@ class NewBuilder extends AbstractBuilder | |||
| 65 | { | 70 | { |
| 66 | if(Director::$page_path->getLast()->getEndOfPath() === 'article'){ | 71 | if(Director::$page_path->getLast()->getEndOfPath() === 'article'){ |
| 67 | $title_js = 'onclick="openEditor(\'' . $id_title . '\', \'article\')"'; | 72 | $title_js = 'onclick="openEditor(\'' . $id_title . '\', \'article\')"'; |
| 68 | $modify_title = '<p id="edit-' . $id_title . '"><a href="#"><button ' . $title_js . '><img class="action_icon" src="assets/edit.svg">Titre</button></a></p>' . "\n"; | 73 | $modify_title = '<p id="edit-' . $id_title . '"><button ' . $title_js . '><img class="action_icon" src="assets/edit.svg">Titre</button></p>' . "\n"; |
| 69 | $close_js_title = 'onclick="closeEditor(\'' . $id_title . '\', \'article\', \'preview\')"'; | 74 | $close_js_title = 'onclick="closeEditor(\'' . $id_title . '\', \'article\', \'preview\')"'; |
| 70 | $close_editor_title = '<p id="cancel-' . $id_title . '" class="hidden"><a href="#"><button ' . $close_js_title . '>Annuler</button></a></p>'; | 75 | $close_editor_title = '<p id="cancel-' . $id_title . '" class="hidden"><button ' . $close_js_title . '>Annuler</button></p>'; |
| 71 | $submit_js_title = 'onclick="submitArticle(\'' . $id_title . '\', \'article\')"'; | 76 | $submit_js_title = 'onclick="submitArticle(\'' . $id_title . '\', \'article\')"'; |
| 72 | $submit_title = '<p id="submit-' . $id_title . '" class="hidden"><a href="#"><button ' . $submit_js_title . '>Valider</button></a></p>'; | 77 | $submit_title = '<p id="submit-' . $id_title . '" class="hidden"><button ' . $submit_js_title . '>Valider</button></p>'; |
| 73 | $title_buttons = '<div class="button_zone">' . $modify_title . $close_editor_title . $submit_title . '</div>'; | 78 | $title_buttons = '<div class="button_zone">' . $modify_title . $close_editor_title . $submit_title . '</div>'; |
| 74 | 79 | ||
| 75 | $preview_js = 'onclick="openEditor(\'' . $id_preview . '\', \'article\')"'; | 80 | $preview_js = 'onclick="openEditor(\'' . $id_preview . '\', \'article\')"'; |
| 76 | $modify_preview = '<p id="edit-' . $id_preview . '"><a href="#"><button ' . $preview_js . '><img class="action_icon" src="assets/edit.svg">Aperçu</button></a></p>' . "\n"; | 81 | $modify_preview = '<p id="edit-' . $id_preview . '"><button ' . $preview_js . '><img class="action_icon" src="assets/edit.svg">Aperçu</button></a></p>' . "\n"; |
| 77 | $close_js_preview = 'onclick="closeEditor(\'' . $id_preview . '\', \'article\', \'preview\')"'; | 82 | $close_js_preview = 'onclick="closeEditor(\'' . $id_preview . '\', \'article\', \'preview\')"'; |
| 78 | $close_editor_preview = '<p id="cancel-' . $id_preview . '" class="hidden"><a href="#"><button ' . $close_js_preview . '>Annuler</button></a></p>'; | 83 | $close_editor_preview = '<p id="cancel-' . $id_preview . '" class="hidden"><button ' . $close_js_preview . '>Annuler</button></p>'; |
| 79 | $submit_js_preview = 'onclick="submitArticle(\'' . $id_preview . '\', \'article\')"'; | 84 | $submit_js_preview = 'onclick="submitArticle(\'' . $id_preview . '\', \'article\')"'; |
| 80 | $submit_preview = '<p id="submit-' . $id_preview . '" class="hidden"><a href="#"><button ' . $submit_js_preview . '>Valider</button></a></p>'; | 85 | $submit_preview = '<p id="submit-' . $id_preview . '" class="hidden"><button ' . $submit_js_preview . '>Valider</button></p>'; |
| 81 | $preview_buttons = '<div class="button_zone">' . $modify_preview . $close_editor_preview . $submit_preview . '</div>'; | 86 | $preview_buttons = '<div class="button_zone">' . $modify_preview . $close_editor_preview . $submit_preview . '</div>'; |
| 82 | 87 | ||
| 83 | $article_js = 'onclick="openEditor(\'' . $id . '\', \'article\')"'; | 88 | $article_js = 'onclick="openEditor(\'' . $id . '\', \'article\')"'; |
| 84 | $modify_article = '<p id="edit-' . $id . '"><a href="#"><button ' . $article_js . '><img class="action_icon" src="assets/edit.svg">Article</button></a></p>' . "\n"; | 89 | $modify_article = '<p id="edit-' . $id . '"><button ' . $article_js . '><img class="action_icon" src="assets/edit.svg">Article</button></p>' . "\n"; |
| 85 | $close_js_article = 'onclick="closeEditor(\'' . $id . '\', \'article\')"'; | 90 | $close_js_article = 'onclick="closeEditor(\'' . $id . '\', \'article\')"'; |
| 86 | $close_editor_article = '<p id="cancel-' . $id . '" class="hidden"><a href="#"><button ' . $close_js_article . '>Annuler</button></a></p>'; | 91 | $close_editor_article = '<p id="cancel-' . $id . '" class="hidden"><button ' . $close_js_article . '>Annuler</button></p>'; |
| 87 | $submit_js_article = 'onclick="submitArticle(\'' . $id . '\', \'article\')"'; | 92 | $submit_js_article = 'onclick="submitArticle(\'' . $id . '\', \'article\')"'; |
| 88 | $submit_article = '<p id="submit-' . $id . '" class="hidden"><a href="#"><button ' . $submit_js_article . '>Valider</button></a></p>'; | 93 | $submit_article = '<p id="submit-' . $id . '" class="hidden"><button ' . $submit_js_article . '>Valider</button></p>'; |
| 89 | $article_buttons = '<div class="button_zone">' . $modify_article . $close_editor_article . $submit_article . '</div>'; | 94 | $article_buttons = '<div class="button_zone">' . $modify_article . $close_editor_article . $submit_article . '</div>'; |
| 90 | 95 | ||
| 91 | $date_js = 'onclick="changeDate(\'' . $id_date . '\', \'article\');'; | 96 | $date_js = 'onclick="changeDate(\'' . $id_date . '\', \'article\');'; |
| 92 | $modify_date = '<p id="edit-' . $id_date . '"><a href="#"><button ' . $date_js . '"><img class="action_icon" src="assets/edit.svg">Date</button></a></p>' . "\n"; | 97 | $modify_date = '<p id="edit-' . $id_date . '"><button ' . $date_js . '"><img class="action_icon" src="assets/edit.svg">Date</button></p>' . "\n"; |
| 93 | $close_js_date = 'onclick="closeInput(\'' . $id_date . '\')"'; | 98 | $close_js_date = 'onclick="closeInput(\'' . $id_date . '\')"'; |
| 94 | $close_editor_date = '<p id="cancel-' . $id_date . '" class="hidden"><a href="#"><button ' . $close_js_date . '>Annuler</button></a></p>'; | 99 | $close_editor_date = '<p id="cancel-' . $id_date . '" class="hidden"><button ' . $close_js_date . '>Annuler</button></p>'; |
| 95 | $submit_js_date = 'onclick="submitDate(\'' . $id_date . '\')"'; | 100 | $submit_js_date = 'onclick="submitDate(\'' . $id_date . '\')"'; |
| 96 | $submit_date = '<p id="submit-' . $id_date . '" class="hidden"><a href="#"><button ' . $submit_js_date . '>Valider</button></a></p>'; | 101 | $submit_date = '<p id="submit-' . $id_date . '" class="hidden"><button ' . $submit_js_date . '>Valider</button></p>'; |
| 97 | $date_buttons = '<div class="button_zone">' . $modify_date . $close_editor_date . $submit_date . '</div>'; | 102 | $date_buttons = '<div class="button_zone">' . $modify_date . $close_editor_date . $submit_date . '</div>'; |
| 98 | 103 | ||
| 99 | $delete_js = 'onclick="deleteArticle(\'' . $id . '\', \'' . CURRENT_PAGE . '\')"'; | 104 | $delete_article = ''; |
| 100 | $delete_article = '<p id="delete-' . $id . '"><a href="#"><button ' . $delete_js . '"><img class="action_icon" src="assets/delete-bin.svg" ' . $delete_js . '>Retirer<br>la publication</button></a></p>' . "\n"; | 105 | $submit_article = ''; |
| 101 | 106 | // modification: bouton "supprimer" | |
| 102 | $admin_buttons = $delete_article; | 107 | if($_GET['id'][0] === 'i'){ |
| 108 | $delete_js = 'onclick="deleteArticle(\'' . $id . '\', \'' . Director::$page_path->getLast()->getEndOfPath() . '\')"'; | ||
| 109 | $delete_article = '<p id="delete-' . $id . '"><button ' . $delete_js . '><img class="action_icon" src="assets/delete-bin.svg" ' . $delete_js . '>Retirer<br>la publication</button></p>' . "\n"; | ||
| 110 | } | ||
| 111 | // nouvel article: bouton pour valider la création d'un nouvel article | ||
| 112 | else{ | ||
| 113 | $submit_js = 'onclick="submitArticle(\'' . $_GET['id'] . '\', \'' . Director::$page_path->getLast()->getEndOfPath() . '\')"'; | ||
| 114 | $submit_article = '<p id="submit-' . $id . '"><button ' . $submit_js . '><img class="action_icon" src="assets/edit.svg">Tout<br>enregistrer</button></p>' . "\n"; | ||
| 115 | } | ||
| 116 | |||
| 117 | $admin_buttons = $delete_article . $submit_article; | ||
| 103 | } | 118 | } |
| 119 | // page d'accueil | ||
| 104 | else{ | 120 | else{ |
| 105 | $modify_article = '<p id="edit-' . $id . '"></p>' . "\n"; | 121 | $modify_article = '<p id="edit-' . $id . '"></p>' . "\n"; |
| 106 | 122 | ||
| 107 | $up_js = 'onclick="switchPositions(\'' . $id . '\', \'up\')"'; | 123 | $up_js = 'onclick="switchPositions(\'' . $id . '\', \'up\')"'; |
| 108 | $up_button = '<p id="position_up-' . $id . '"><a href="#"><img class="action_icon" src="assets/arrow-up.svg" ' . $up_js . '></a></p>' . "\n"; | 124 | $up_button = '<p id="position_up-' . $id . '"><img class="action_icon" src="assets/arrow-up.svg" ' . $up_js . '></p>' . "\n"; |
| 109 | 125 | ||
| 110 | $down_js = 'onclick="switchPositions(\'' . $id . '\', \'down\')"'; | 126 | $down_js = 'onclick="switchPositions(\'' . $id . '\', \'down\')"'; |
| 111 | $down_button = '<p id="position_down-' . $id . '"><a href="#"><img class="action_icon" src="assets/arrow-down.svg" ' . $down_js . '></a></p>' . "\n"; | 127 | $down_button = '<p id="position_down-' . $id . '"><img class="action_icon" src="assets/arrow-down.svg" ' . $down_js . '></p>' . "\n"; |
| 112 | 128 | ||
| 113 | $delete_js = 'onclick="deleteArticle(\'' . $id . '\')"'; | 129 | $delete_js = 'onclick="deleteArticle(\'' . $id . '\')"'; |
| 114 | $delete_article = '<p id="delete-' . $id . '"><a href="#"><img class="action_icon" src="assets/delete-bin.svg" ' . $delete_js . '></a></p>' . "\n"; | 130 | $delete_article = '<p id="delete-' . $id . '"><img class="action_icon" src="assets/delete-bin.svg" ' . $delete_js . '></p>' . "\n"; |
| 115 | 131 | ||
| 116 | $close_editor = '<p id="cancel-' . $id . '" class="hidden"></p>'; | 132 | $close_editor = '<p id="cancel-' . $id . '" class="hidden"></p>'; |
| 117 | $submit_article = '<p id="submit-' . $id . '" class="hidden"></p>'; | 133 | $submit_article = '<p id="submit-' . $id . '" class="hidden"></p>'; |
| @@ -120,7 +136,6 @@ class NewBuilder extends AbstractBuilder | |||
| 120 | 136 | ||
| 121 | $admin_buttons = $modify_article . $up_button . $down_button . $delete_article . $close_editor . $submit_article; | 137 | $admin_buttons = $modify_article . $up_button . $down_button . $delete_article . $close_editor . $submit_article; |
| 122 | } | 138 | } |
| 123 | |||
| 124 | } | 139 | } |
| 125 | 140 | ||
| 126 | ob_start(); | 141 | ob_start(); |
