aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpolo <ordipolo@gmx.fr>2025-09-18 00:27:20 +0200
committerpolo <ordipolo@gmx.fr>2025-09-18 00:27:20 +0200
commitfa3c582a2bd91433399a5b275616052028a5a011 (patch)
tree64a5c2c0eb54dc033fb5ed78ed69745bd492aa05
parent027af942de75f7c5bc519fabfa5fa11de9bc89ea (diff)
downloadcms-fa3c582a2bd91433399a5b275616052028a5a011.zip
news positionnées en fonction de leur date, suppression de leurs boutons position, améliorations routage page article, bouton share en bas pour les news
-rw-r--r--public/css/body.css12
-rw-r--r--public/js/tinymce.js6
-rw-r--r--src/controller/ArticleController.php11
-rw-r--r--src/controller/ViewController.php25
-rw-r--r--src/model/entities/Node.php26
-rw-r--r--src/router.php5
-rw-r--r--src/view/NewBuilder.php34
-rw-r--r--src/view/NewsBlockBuilder.php8
-rw-r--r--src/view/templates/new.php1
9 files changed, 74 insertions, 54 deletions
diff --git a/public/css/body.css b/public/css/body.css
index d60f28c..f8e4f81 100644
--- a/public/css/body.css
+++ b/public/css/body.css
@@ -7,10 +7,6 @@ body
7 background-color: #0cceec; 7 background-color: #0cceec;
8} 8}
9 9
10.hidden{
11 display: none;
12}
13
14#bloc_page 10#bloc_page
15{} 11{}
16 12
@@ -176,8 +172,7 @@ button .action_icon:hover
176} 172}
177.delete_button 173.delete_button
178{ 174{
179 float: right; 175 margin-right: 2px;
180 margin-left: 2px;
181} 176}
182section button, section input[type=submit] 177section button, section input[type=submit]
183{ 178{
@@ -238,4 +233,9 @@ article a:hover
238 { 233 {
239 grid-template-columns: repeat(2, 1fr); 234 grid-template-columns: repeat(2, 1fr);
240 } 235 }
236}
237
238.article_admin_zone p
239{
240 align-self: center;
241} \ No newline at end of file 241} \ No newline at end of file
diff --git a/public/js/tinymce.js b/public/js/tinymce.js
index d6b0bf8..81ba8ea 100644
--- a/public/js/tinymce.js
+++ b/public/js/tinymce.js
@@ -332,7 +332,11 @@ class Editor
332 content = this.tiny_instance.getContent(); 332 content = this.tiny_instance.getContent();
333 } 333 }
334 334
335 let fetch_params = {id: this.id, content: content}; 335 let fetch_params = {
336 id: this.id,
337 content: content,
338 from: new URLSearchParams(window.location.search).get('from') // le "$_GET" de javascript
339 };
336 if(this.placement){ 340 if(this.placement){
337 fetch_params['placement'] = this.placement; 341 fetch_params['placement'] = this.placement;
338 } 342 }
diff --git a/src/controller/ArticleController.php b/src/controller/ArticleController.php
index cb132cf..411c1dc 100644
--- a/src/controller/ArticleController.php
+++ b/src/controller/ArticleController.php
@@ -36,14 +36,19 @@ class ArticleController
36 if($json['id'][0] === 'n') // ici $id est un bloc 36 if($json['id'][0] === 'n') // ici $id est un bloc
37 { 37 {
38 $section_id = (int)substr($id, 1); // id du bloc <section> 38 $section_id = (int)substr($id, 1); // id du bloc <section>
39 if(!$director->findNodeById($section_id)){ 39 if(!$director->findNodeById($section_id)){ // erreur mauvais id
40 echo json_encode(['success' => false, 'error' => 'article_not_saved']); 40 echo json_encode(['success' => false, 'error' => 'article_not_saved, bad id']);
41 die; 41 die;
42 } 42 }
43 $director->makeSectionNode(); 43 $director->makeSectionNode();
44 $node = $director->getNode(); // = <section> 44 $node = $director->getNode(); // = <section>
45 45
46 if(is_array($content)){ // cas d'une nouvelle "news" 46 if(is_array($content)){ // cas d'une nouvelle "news"
47 if($node->getPage()->getEndOfPath() !== $json['from']){ // erreur mauvais from
48 echo json_encode(['success' => false, 'error' => 'article_not_saved, bad from']);
49 die;
50 }
51
47 $date = new \DateTime($content['d'] . ':' . (new \DateTime)->format('s')); // l'input type="datetime-local" ne donne pas les secondes, on les ajoute: 'hh:mm' . ':ss' 52 $date = new \DateTime($content['d'] . ':' . (new \DateTime)->format('s')); // l'input type="datetime-local" ne donne pas les secondes, on les ajoute: 'hh:mm' . ':ss'
48 $article = new Article($content['i'], $date, $content['t'], $content['p']); 53 $article = new Article($content['i'], $date, $content['t'], $content['p']);
49 $article_node = new Node('new', [], count($node->getChildren()) + 1, $node, $node->getPage(), $article); 54 $article_node = new Node('new', [], count($node->getChildren()) + 1, $node, $node->getPage(), $article);
diff --git a/src/controller/ViewController.php b/src/controller/ViewController.php
index 668fa25..f66baff 100644
--- a/src/controller/ViewController.php
+++ b/src/controller/ViewController.php
@@ -33,17 +33,24 @@ class ViewController extends AbstractBuilder // ViewController est aussi le prem
33 } 33 }
34 34
35 // page article: mode création et erreurs d'id 35 // page article: mode création et erreurs d'id
36 if($_SESSION['admin'] && $request->query->has('page') && $request->query->get('page') === 'article'){ 36 if($request->query->has('page') && $request->query->get('page') === 'article'){
37 if(!$request->query->has('id')){ 37 if($_SESSION['admin']){
38 return new Response($this->html, 302); 38 if(!$request->query->has('id')){
39 }
40 else{
41 if($request->query->get('id')[0] === 'n'){ // mode création d'article (vérification de l'id du bloc dans ArticleController)
42 NewBuilder::$new_article_mode = true;
43 }
44 elseif(self::$root_node->getNodeByName('main')->getAdoptedChild() === null){ // id inconnu
45 return new Response($this->html, 302); 39 return new Response($this->html, 302);
46 } 40 }
41 else{
42 // mode création d'article
43 // l'id du bloc et 'from=' sont vérifiés dans ArticleController::editorSubmit
44 if($request->query->get('id')[0] === 'n' && $request->query->has('from') && !empty($request->query->get('from'))){
45 NewBuilder::$new_article_mode = true;
46 }
47 elseif(self::$root_node->getNodeByName('main')->getAdoptedChild() === null){ // id inconnu
48 return new Response($this->html, 302);
49 }
50 }
51 }
52 elseif($request->query->get('id')[0] === 'n'){ // accès page nouvelle article interdit sans être admin
53 return new Response($this->html, 302);
47 } 54 }
48 } 55 }
49 56
diff --git a/src/model/entities/Node.php b/src/model/entities/Node.php
index eb73116..c5df8d1 100644
--- a/src/model/entities/Node.php
+++ b/src/model/entities/Node.php
@@ -171,7 +171,31 @@ class Node
171 public function addChild(self $child): void 171 public function addChild(self $child): void
172 { 172 {
173 $this->children[] = $child; 173 $this->children[] = $child;
174 $this->sortChildren(false); 174
175 // cas particulier des news: utilise les dates au lieu des positions (les positions existent mais sont ignorées)
176 if($this->getName() === 'news_block'){
177 $this->sortNews($this->getNodeData()->getData()['chrono'] ?? false); // faux = ordre chronologique
178 }
179 else{
180 $this->sortChildren(false);
181 }
182 }
183
184 private function sortNews(bool $chrono = false) // affichage du plus récent au plus ancien par défaut
185 {
186 // tri par insertion similaire à Position::sortChildren
187 for($i = 1; $i < count($this->children); $i++){
188 $tmp = $this->children[$i];
189 $j = $i - 1;
190
191 $compare = $chrono ? fn($a, $b) => $a > $b : fn($a, $b) => $a < $b;
192
193 while($j >= 0 && $compare($this->children[$j]->getArticle()->getDateTime(), $tmp->getArticle()->getDateTime())){
194 $this->children[$j + 1] = $this->children[$j];
195 $j--;
196 }
197 $this->children[$j + 1] = $tmp;
198 }
175 } 199 }
176 200
177 public function removeChild(self $child): void 201 public function removeChild(self $child): void
diff --git a/src/router.php b/src/router.php
index ccab426..8c33d6e 100644
--- a/src/router.php
+++ b/src/router.php
@@ -83,8 +83,7 @@ elseif($_SERVER['REQUEST_METHOD'] === 'POST'){
83 // requêtes JSON avec fetch() 83 // requêtes JSON avec fetch()
84 if($_SERVER['CONTENT_TYPE'] === 'application/json') 84 if($_SERVER['CONTENT_TYPE'] === 'application/json')
85 { 85 {
86 $data = file_get_contents('php://input'); 86 $json = json_decode($request->getContent(), true); // = json_decode(file_get_contents('php://input'), true);
87 $json = json_decode($data, true);
88 87
89 if($request->query->has('action')) 88 if($request->query->has('action'))
90 { 89 {
@@ -309,7 +308,7 @@ else{
309 308
310/* -- utilisation de la réponse -- */ 309/* -- utilisation de la réponse -- */
311if(isset($response)){ 310if(isset($response)){
312 // cas des mauvais id de la page article (d'autres cas à prévoir) 311 // cas gérés (d'autres sont à prévoir): mauvais id de la page article, accès page création d'article sans être admin
313 if($request->isMethod('GET') && $response->getStatusCode() == 302){ // 302 redirection temporaire 312 if($request->isMethod('GET') && $response->getStatusCode() == 302){ // 302 redirection temporaire
314 header('Location: ' . new URL(['page' => !empty($_GET['from']) ? $_GET['from'] : 'accueil'])); 313 header('Location: ' . new URL(['page' => !empty($_GET['from']) ? $_GET['from'] : 'accueil']));
315 } 314 }
diff --git a/src/view/NewBuilder.php b/src/view/NewBuilder.php
index 9965d15..cd5534b 100644
--- a/src/view/NewBuilder.php
+++ b/src/view/NewBuilder.php
@@ -55,7 +55,7 @@ class NewBuilder extends AbstractBuilder
55 // page article unique 55 // page article unique
56 if(Director::$page_path->getLast()->getEndOfPath() === 'article'){ 56 if(Director::$page_path->getLast()->getEndOfPath() === 'article'){
57 $content = $node->getArticle()->getContent(); 57 $content = $node->getArticle()->getContent();
58 $from_to_button = '<p><a class="link_to_article" href="' . new URL(isset($_GET['from']) ? ['page' => $_GET['from']] : []) . '"><button>Page<br>précédente</button></a></p>'; 58 $from_to_button = '<p><a class="link_to_article" href="' . new URL(isset($_GET['from']) ? ['page' => $_GET['from']] : []) . '"><button>Retour</button></a></p>';
59 } 59 }
60 else{ 60 else{
61 $from_to_button = '<p><a class="link_to_article" href="' . new URL(['page' => 'article', 'id' => $id, 'from' => CURRENT_PAGE]) . '"><button><img class="action_icon" src="assets/book-open.svg">Lire la suite</button></a></p>'; 61 $from_to_button = '<p><a class="link_to_article" href="' . new URL(['page' => 'article', 'id' => $id, 'from' => CURRENT_PAGE]) . '"><button><img class="action_icon" src="assets/book-open.svg">Lire la suite</button></a></p>';
@@ -82,8 +82,7 @@ class NewBuilder extends AbstractBuilder
82 $article_buttons = ''; 82 $article_buttons = '';
83 $date_buttons = ''; 83 $date_buttons = '';
84 $admin_buttons = ''; 84 $admin_buttons = '';
85 if($_SESSION['admin']) 85 if($_SESSION['admin']){
86 {
87 if(Director::$page_path->getLast()->getEndOfPath() === 'article'){ 86 if(Director::$page_path->getLast()->getEndOfPath() === 'article'){
88 $title_js = 'onclick="openEditor(\'' . $id_title . '\')"'; 87 $title_js = 'onclick="openEditor(\'' . $id_title . '\')"';
89 $modify_title = '<p id="edit-' . $id_title . '"><button ' . $title_js . '><img class="action_icon" src="assets/edit.svg">Titre</button></p>' . "\n"; 88 $modify_title = '<p id="edit-' . $id_title . '"><button ' . $title_js . '><img class="action_icon" src="assets/edit.svg">Titre</button></p>' . "\n";
@@ -122,45 +121,34 @@ class NewBuilder extends AbstractBuilder
122 $delete_article = ''; 121 $delete_article = '';
123 // valider la création d'un nouvel article 122 // valider la création d'un nouvel article
124 $submit_js = 'onclick="submitArticle(\'' . $_GET['id'] . '\')"'; 123 $submit_js = 'onclick="submitArticle(\'' . $_GET['id'] . '\')"';
125 $submit_article = '<p id="save-' . $id . '"><button ' . $submit_js . '><img class="action_icon" src="assets/edit.svg"><span class="delete_button">Tout<br>enregistrer</span></button></p>' . "\n"; 124 $submit_article = '<p id="save-' . $id . '"><img class="action_icon delete_button" src="assets/save.svg" ' . $submit_js . '></p>' . "\n";
126 } 125 }
127 // mode article existant 126 // mode article existant
128 else{ 127 else{
129 $url = new URL(['action' => 'delete_article', 'id' => $_GET['id'], 'from' => $_GET['from'] ?? '']); 128 $url = new URL(['action' => 'delete_article', 'id' => $_GET['id'], 'from' => $_GET['from'] ?? '']);
130 $delete_article = '<form id="delete-' . $id . '" method="post" onsubmit="return confirm(\'Voulez-vous vraiment supprimer cet article ?\');" action="' . $url . '"> 129 $delete_article = '<form id="delete-' . $id . '" method="post" action="' . $url . '">
131 <p><button type="submit"> 130 <p>
132 <img class="action_icon" src="assets/delete-bin.svg"> 131 <img src="assets/delete-bin.svg" alt="Supprimer l\'article" class="action_icon" style="cursor: pointer;" onclick="if(confirm(\'Voulez-vous vraiment supprimer cet article ?\')) { this.closest(\'form\').submit(); }"
133 <span class="delete_button">Supprimer<br>cet article</span> 132 </p>
134 </button></p> 133 </form>' . "\n"; // this.closest('form').submit() = submit du formulaire avec javascript
135 </form>' . "\n";
136 $submit_article = ''; 134 $submit_article = '';
137 } 135 }
138 136
139 $admin_buttons = $delete_article . $from_to_button . $submit_article; 137 $admin_buttons = $share_button . $delete_article . $submit_article . $from_to_button;
140 } 138 }
141 // autre page 139 // autre page
142 else{ 140 else{
143 $modify_article = '<p id="edit-' . $id . '"></p>' . "\n";
144
145 $up_js = 'onclick="switchPositions(\'' . $id . '\', \'up\')"';
146 $up_button = '<p id="position_up-' . $id . '"><img class="action_icon" src="assets/arrow-up.svg" ' . $up_js . '></p>' . "\n";
147
148 $down_js = 'onclick="switchPositions(\'' . $id . '\', \'down\')"';
149 $down_button = '<p id="position_down-' . $id . '"><img class="action_icon" src="assets/arrow-down.svg" ' . $down_js . '></p>' . "\n";
150
151 $delete_js = 'onclick="deleteArticle(\'' . $id . '\')"'; 141 $delete_js = 'onclick="deleteArticle(\'' . $id . '\')"';
152 $delete_article = '<p id="delete-' . $id . '"><img class="action_icon" src="assets/delete-bin.svg" ' . $delete_js . '></p>' . "\n"; 142 $delete_article = '<p id="delete-' . $id . '"><img class="action_icon" src="assets/delete-bin.svg" ' . $delete_js . '></p>' . "\n";
153 143
154 $close_editor = '<p id="cancel-' . $id . '" class="hidden"></p>'; 144 $close_editor = '<p id="cancel-' . $id . '" class="hidden"></p>';
155 $submit_article = '<p id="submit-' . $id . '" class="hidden"></p>'; 145 $submit_article = '<p id="submit-' . $id . '" class="hidden"></p>';
156 146
157 $submit_article = '<p id="submit-' . $id . '" class="hidden"></p>'; 147 $admin_buttons = $from_to_button . $share_button . $delete_article . $close_editor . $submit_article;
158
159 $admin_buttons = $from_to_button . $modify_article . $up_button . $down_button . $delete_article . $close_editor . $submit_article;
160 } 148 }
161 } 149 }
162 else{ 150 else{
163 $admin_buttons = $from_to_button; 151 $admin_buttons = $share_button . $from_to_button;
164 } 152 }
165 153
166 ob_start(); 154 ob_start();
diff --git a/src/view/NewsBlockBuilder.php b/src/view/NewsBlockBuilder.php
index 76e42c5..e7bbec9 100644
--- a/src/view/NewsBlockBuilder.php
+++ b/src/view/NewsBlockBuilder.php
@@ -41,12 +41,6 @@ class NewsBlockBuilder extends AbstractBuilder
41 41
42 $modify_js = 'onclick="openEditor(\'' . $id . '\')"'; 42 $modify_js = 'onclick="openEditor(\'' . $id . '\')"';
43 $modify_article = '<p id="edit-' . $id . '" class="hidden"><img class="action_icon" src="assets/edit.svg" ' . $modify_js . '></p>' . "\n"; 43 $modify_article = '<p id="edit-' . $id . '" class="hidden"><img class="action_icon" src="assets/edit.svg" ' . $modify_js . '></p>' . "\n";
44
45 $up_js = 'onclick="switchPositions(\'' . $id . '\', \'up\')"';
46 $up_button = '<p id="position_up-' . $id . '" class="hidden"><img class="action_icon" src="assets/arrow-up.svg" ' . $up_js . '></p>' . "\n";
47
48 $down_js = 'onclick="switchPositions(\'' . $id . '\', \'down\')"';
49 $down_button = '<p id="position_down-' . $id . '" class="hidden"><img class="action_icon" src="assets/arrow-down.svg" ' . $down_js . '></p>' . "\n";
50 44
51 $delete_js = 'onclick="deleteArticle(\'' . $id . '\')"'; 45 $delete_js = 'onclick="deleteArticle(\'' . $id . '\')"';
52 $delete_article = '<p id="delete-' . $id . '" class="hidden"><img class="action_icon" src="assets/delete-bin.svg" ' . $delete_js . '></p>' . "\n"; 46 $delete_article = '<p id="delete-' . $id . '" class="hidden"><img class="action_icon" src="assets/delete-bin.svg" ' . $delete_js . '></p>' . "\n";
@@ -58,7 +52,7 @@ class NewsBlockBuilder extends AbstractBuilder
58 $submit_article = '<p id="submit-' . $id . '" class="hidden"><button ' . $submit_js . '>Valider</button></p>'; 52 $submit_article = '<p id="submit-' . $id . '" class="hidden"><button ' . $submit_js . '>Valider</button></p>';
59 53
60 $html = ''; 54 $html = '';
61 $admin_buttons = $new_button . $modify_article . $up_button . $down_button . $delete_article . $close_editor . $submit_article; 55 $admin_buttons = $new_button . $modify_article . $delete_article . $close_editor . $submit_article;
62 56
63 // post vide mis là pour le bouton "Nouvel article" => déplace vers page "article" 57 // post vide mis là pour le bouton "Nouvel article" => déplace vers page "article"
64 ob_start(); 58 ob_start();
diff --git a/src/view/templates/new.php b/src/view/templates/new.php
index fadf1a2..bda7daf 100644
--- a/src/view/templates/new.php
+++ b/src/view/templates/new.php
@@ -2,7 +2,6 @@
2<article> 2<article>
3 <div class="new_content" id="<?= $id ?>"> 3 <div class="new_content" id="<?= $id ?>">
4 <div class="article_title_zone"> 4 <div class="article_title_zone">
5 <?= $share_button ?>
6 <div class="data" id="<?= $id_title ?>"> 5 <div class="data" id="<?= $id_title ?>">
7 <?= $title ?> 6 <?= $title ?>
8 </div> 7 </div>