summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--public/css/main.css215
-rw-r--r--public/css/menu.css4
-rw-r--r--public/js/main.js81
-rw-r--r--src/controller/ajax.php744
-rw-r--r--src/controller/installation.php39
-rw-r--r--src/controller/post.php30
-rw-r--r--src/model/entities/NodeData.php10
-rw-r--r--src/model/entities/Page.php8
-rw-r--r--src/view/BreadcrumbBuilder.php4
-rw-r--r--src/view/GridBuilder.php4
-rw-r--r--src/view/HeadBuilder.php8
-rw-r--r--src/view/MainBuilder.php47
-rw-r--r--src/view/NavBuilder.php4
-rw-r--r--src/view/ViewBuilder.php2
14 files changed, 499 insertions, 701 deletions
diff --git a/public/css/main.css b/public/css/main.css
deleted file mode 100644
index 870082a..0000000
--- a/public/css/main.css
+++ /dev/null
@@ -1,215 +0,0 @@
1main
2{
3 margin: auto;
4 /*max-width: 1200px;*/
5 background-color: #E3F3FF;
6 padding: 15px 0;
7}
8section > h3
9{
10 padding: 15px;
11 margin: 0;
12 text-align: center;
13}
14.grid_columns
15{
16 display: grid;
17 grid-template-columns: repeat(3, 1fr);
18}
19@media screen and (max-width: 800px)
20{
21 .grid_columns
22 {
23 grid-template-columns: repeat(2, 1fr);
24 }
25}
26@media screen and (max-width: 550px)
27{
28 .grid_columns
29 {
30 display: block;
31 }
32}
33.galery_photos
34{
35 display: flex;
36 flex-wrap: wrap;
37 justify-content: space-evenly;
38}
39.galery_photos .html_from_editor img
40{
41 max-width: 300px;
42 max-height: 200px;
43}
44article
45{
46 /*display: flex;*/
47 background-color: white;
48 margin: 15px;
49 padding: 0 15px;
50 /*min-height: 150px;*/
51}
52article .logo2
53{
54 vertical-align: middle;
55 max-width: 200px;
56 max-height: 200px;
57 margin-right: 15px;
58}
59.new_content, .article_content
60{
61 width: 100%;
62}
63.new_content
64{
65 /*max-height: 400;*/
66 overflow: hidden;
67}
68article img
69{
70 width: 100%;
71 height: auto;
72}
73
74.action_icon
75{
76 width: 24px;
77 vertical-align: bottom;
78 border: white 2px solid; /* invisible */
79}
80button .action_icon
81{
82 border: none;
83}
84.action_icon:hover
85{
86 background-color: #ffff00;
87 border-radius: 4px;
88 border: lightgrey 2px outset;
89 cursor: pointer;
90}
91button .action_icon:hover
92{
93 border: none;
94}
95
96.button_zone
97{
98 display: flex;
99}
100
101.share
102{
103 float: right;
104}
105.article_title_zone
106{
107 padding: 10px;
108}
109.under_an_article
110{
111 display: flex;
112 justify-content: space-between;
113 font-size: small;
114}
115.under_an_article img
116{
117 width: 24px;
118 margin-right: 5px;
119 vertical-align: middle;
120}
121.article_admin_zone
122{
123 display: flex;
124 justify-content: end;
125}
126main button
127{
128 color: #ff1d04;
129 font-size: medium;
130 border-radius: 4px;
131 background-color: white;
132 border: lightgrey 2px outset; /* rend identiques les boutons firefox et chromium */
133}
134main button:hover
135{
136 background-color: #ffff00;
137 border-radius: 4px;
138 cursor: pointer;
139}
140
141article a:hover
142{
143 cursor: pointer;
144}
145
146
147
148/* -- mode modification d'une page -- */
149/*.modif_page_explanations
150{
151 background-color: white;
152 padding: 10px;
153 margin: 10px 20px;
154}
155.modif_page_explanations div
156{
157 display: flex;
158 flex-wrap: wrap;
159 font-size: smaller;
160}*/
161.edit_bloc_zone
162{
163 background-color: white;
164 padding: 10px;
165 margin: 10px 15px;
166 display: flex;
167 justify-content: space-evenly;
168 flex-wrap: wrap;
169}
170.edit_bloc_zone p
171{
172 margin: 5px;
173}
174.new_bloc, .modify_bloc
175{
176 /*background-color: white;
177 padding: 10px;
178 margin: 10px 20px;*/
179}
180.new_bloc p
181{
182 /*margin: 5px;*/
183}
184.new_bloc #bloc_title
185{
186 width: 70%;
187 max-width: 300px;
188}
189.new_bloc form select, .new_bloc form input[type=submit], .modify_bloc form input[type=submit]
190{
191 color: #ff1d04;
192 font-size: medium;
193 border-radius: 4px;
194 background-color: white;
195 border: lightgrey 2px outset;
196}
197select:hover
198{
199 cursor: pointer;
200}
201.new_bloc form input[type=submit]:hover, .modify_bloc form input[type=submit]:hover
202{
203 background-color: #ffff00;
204 border-radius: 4px;
205 cursor: pointer;
206}
207.modify_bloc > div
208{
209 display: flex;
210 align-items: baseline;
211}
212.modify_bloc img
213{
214 vertical-align: middle;
215} \ No newline at end of file
diff --git a/public/css/menu.css b/public/css/menu.css
index 61e8a01..68e2b2a 100644
--- a/public/css/menu.css
+++ b/public/css/menu.css
@@ -1,4 +1,4 @@
1/* page "Menu et chemins" uniquement */ 1/*-- page "Menu et chemins" uniquement --*/
2 2
3.menu 3.menu
4{ 4{
@@ -68,7 +68,7 @@
68{ 68{
69 width: 20px; 69 width: 20px;
70 vertical-align: middle; 70 vertical-align: middle;
71 border: 2px #e3f3ff solid; 71 border: 2px transparent solid;
72} 72}
73.menu #location:hover, .menu input[type=submit]:hover, .move_entry_icon:hover 73.menu #location:hover, .menu input[type=submit]:hover, .move_entry_icon:hover
74{ 74{
diff --git a/public/js/main.js b/public/js/main.js
index 7dacb7a..071a1db 100644
--- a/public/js/main.js
+++ b/public/js/main.js
@@ -36,6 +36,7 @@ function toastNotify(message) {
36 setTimeout(function(){ toast.className = toast.className.replace('show', ''); }, 3000); 36 setTimeout(function(){ toast.className = toast.className.replace('show', ''); }, 3000);
37} 37}
38 38
39
39// complète les fonctions dans tinymce.js 40// complète les fonctions dans tinymce.js
40function switchPositions(article_id, direction) 41function switchPositions(article_id, direction)
41{ 42{
@@ -202,84 +203,4 @@ function findParent(element, tag_name){
202 element = element.parentElement; 203 element = element.parentElement;
203 } 204 }
204 return null; 205 return null;
205}
206
207
208/* -- mode Modification d'une page -- */
209function renamePageBloc(bloc_id){
210 const input = document.getElementById("bloc_rename_" + bloc_id);
211 const title = document.getElementById(bloc_id).querySelector("h3");
212
213 fetch('index.php?bloc_edit=rename_page_bloc', {
214 method: 'POST',
215 headers: {
216 'Content-Type': 'application/json'
217 },
218 body: JSON.stringify({bloc_title: input.value, bloc_id: bloc_id})
219 })
220 .then(response => response.json())
221 .then(data => {
222 if(data.success){
223 title.innerHTML = data.title;
224 console.log(data.title);
225 toastNotify('Le bloc a été renommé: ' + data.title);
226 }
227 else{
228 console.error('Erreur au renommage du titre.');
229 }
230 })
231 .catch(error => {
232 console.error('Erreur:', error);
233 });
234}
235
236function switchBlocsPositions(bloc_id, direction, current_page) {
237 const current_bloc = document.getElementById(bloc_id);
238 const current_bloc_edit_zone = document.getElementById("bloc_edit_" + bloc_id);
239 var other_bloc;
240
241 if(direction == 'down'){
242 other_bloc = current_bloc.nextElementSibling;
243 }
244 else if(direction == 'up'){
245 other_bloc = current_bloc.previousElementSibling;
246 }
247
248 if(other_bloc == null || other_bloc.tagName !== 'SECTION')
249 {
250 console.log('Inversion impossible');
251 return;
252 }
253 const other_bloc_edit_zone = document.getElementById("bloc_edit_" + other_bloc.id);
254
255 fetch('index.php?page=' + current_page + '&bloc_edit=switch_blocs_positions', {
256 method: 'POST',
257 headers: {
258 'Content-Type': 'application/json'
259 },
260 body: JSON.stringify({ id1: bloc_id, id2: parseInt(other_bloc.id) })
261 })
262 .then(response => response.json())
263 .then(data => {
264 if(data.success)
265 {
266 if(direction == 'down'){
267 current_bloc.parentElement.insertBefore(other_bloc, current_bloc);
268 current_bloc_edit_zone.parentElement.insertBefore(other_bloc_edit_zone, current_bloc_edit_zone);
269 console.log('Inversion réussie');
270 }
271 else if(direction == 'up'){
272 other_bloc.parentElement.insertBefore(current_bloc, other_bloc);
273 other_bloc_edit_zone.parentElement.insertBefore(current_bloc_edit_zone, other_bloc_edit_zone);
274 console.log('Inversion réussie');
275 }
276 }
277 else {
278
279 console.error('Échec de l\'inversion');
280 }
281 })
282 .catch(error => {
283 console.error('Erreur:', error);
284 });
285} \ No newline at end of file 206} \ No newline at end of file
diff --git a/src/controller/ajax.php b/src/controller/ajax.php
index a64c39b..a820136 100644
--- a/src/controller/ajax.php
+++ b/src/controller/ajax.php
@@ -3,172 +3,9 @@
3 3
4declare(strict_types=1); 4declare(strict_types=1);
5 5
6use App\Entity\Article; 6use App\Entity\Page;
7use App\Entity\Node; 7use App\Entity\Node;
8 8use App\Entity\Article;
9// détection des requêtes de tinymce ou touchant aux articles
10if($_SERVER['CONTENT_TYPE'] === 'application/json' && isset($_GET['action']))
11{
12 // récupération des données
13 $data = file_get_contents('php://input');
14 $json = json_decode($data, true);
15
16 if($_GET['action'] === 'editor_submit' && isset($json['id']) && isset($json['content']))
17 {
18 if(json_last_error() === JSON_ERROR_NONE)
19 {
20 $id = $json['id'];
21 $director = new Director($entityManager);
22
23 // cas d'une nouvelle "news"
24 if(is_array($json['content'])){
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']);
32 }
33
34 // nouvel article
35 if($id[0] === 'n')
36 {
37 $section_id = (int)substr($id, 1); // id du bloc <section>
38 $director->findNodeById($section_id);
39 $director->makeSectionNode();
40 $node = $director->getNode(); // = <section>
41
42 if(is_array($content)){
43 $date = new \DateTime($content['d']);
44 $article = new Article($content['i'], $date, $content['t'], $content['p']);
45 $article_node = new Node('new', 'i' . (string)$date->getTimestamp(), [], count($node->getChildren()) + 1, $node, $node->getPage(), $article);
46
47 // id_node tout juste généré
48 //$article_node->getId();
49 }
50 else{
51 $timestamp = time();
52 $date = new \DateTime;
53 $date->setTimestamp($timestamp);
54
55 $article = new Article($content, $date); // le "current" timestamp est obtenu par la BDD
56 $article_node = new Node('article', 'i' . (string)$timestamp, [], count($node->getChildren()) + 1, $node, $node->getPage(), $article);
57 }
58
59 $entityManager->persist($article_node);
60 $entityManager->flush();
61
62 echo json_encode(['success' => true, 'article_id' => $article_node->getArticleTimestamp()]);
63 die;
64 }
65 // modification article
66 else{
67 $id[0] = 'i'; // id de l'article node
68 }
69
70 if($director->makeArticleNode($id)) // une entrée est trouvée
71 {
72 $node = $director->getArticleNode(); // article
73 switch($json['id'][0]){
74 case 'i':
75 $node->getArticle()->setContent($content);
76 break;
77 case 'p':
78 $node->getArticle()->setPreview($content); // html de l'éditeur
79 break;
80 case 't':
81 $node->getArticle()->setTitle($content); // html de l'éditeur
82 break;
83 case 'd':
84 echo json_encode(['success' => false, 'message' => 'l\'action editor_submit ne supporte pas les dates, utiliser date_submit.']);
85 die;
86 default:
87 echo json_encode(['success' => false, 'message' => 'identifiant non utilisable']);
88 die;
89 }
90 $entityManager->flush();
91 echo json_encode(['success' => true]);
92 }
93 else
94 {
95 echo json_encode(['success' => false, 'message' => 'article non identifié']);
96 }
97 }
98 else{
99 echo json_encode(['success' => false, 'message' => 'Erreur de décodage JSON']);
100 }
101 die;
102 }
103 elseif($_GET['action'] === 'delete_article' && isset($json['id']))
104 {
105 $director = new Director($entityManager);
106 $director->makeArticleNode($json['id'], true);
107 $article = $director->getArticleNode();
108 $section = $director->getNode();
109
110 $entityManager->remove($article);
111 $section->removeChild($article);
112 $section->sortChildren(true); // régénère les positions
113 $entityManager->flush();
114
115 // test avec une nouvelle requête qui ne devrait rien trouver
116 if(!$director->makeArticleNode($json['id']))
117 {
118 echo json_encode(['success' => true]);
119
120 // on pourrait afficher une notification "toast"
121 }
122 else{
123 http_response_code(500);
124 echo json_encode(['success' => false, 'message' => 'Erreur lors de la suppression de l\'article.']);
125 }
126 die;
127 }
128 // inversion de la position de deux noeuds
129 elseif($_GET['action'] === 'switch_positions' && isset($json['id1']) && isset($json['id2']))
130 {
131 $director = new Director($entityManager);
132 $director->makeArticleNode($json['id1'], true);
133 $article1 = $director->getArticleNode();
134 $section = $director->getNode();
135
136 $section->sortChildren(true); // régénère les positions avant inversion
137
138 $article2;
139 foreach($section->getChildren() as $child){
140 if($child->getArticleTimestamp() === $json['id2']) // type string
141 {
142 $article2 = $child;
143 break;
144 }
145 }
146
147 // inversion
148 $tmp = $article1->getPosition();
149 $article1->setPosition($article2->getPosition());
150 $article2->setPosition($tmp);
151 $entityManager->flush();
152
153 echo json_encode(['success' => true]);
154 die;
155 }
156 elseif($_GET['action'] === 'date_submit' && isset($json['id']) && isset($json['date']))
157 {
158 $id = $json['id'];
159 $id[0] = 'i';
160 $date = new DateTime($json['date']);
161
162 $director = new Director($entityManager);
163 $director->makeArticleNode($id);
164 $node = $director->getArticleNode();
165 $node->getArticle()->setDateTime($date);
166 $entityManager->flush();
167
168 echo json_encode(['success' => true]);
169 die;
170 }
171}
172 9
173// détection des requêtes d'upload d'image de tinymce 10// détection des requêtes d'upload d'image de tinymce
174if(strpos($_SERVER['CONTENT_TYPE'], 'multipart/form-data') !== false && isset($_GET['action']) && $_GET['action'] === 'upload_image') 11if(strpos($_SERVER['CONTENT_TYPE'], 'multipart/form-data') !== false && isset($_GET['action']) && $_GET['action'] === 'upload_image')
@@ -207,221 +44,414 @@ if(strpos($_SERVER['CONTENT_TYPE'], 'multipart/form-data') !== false && isset($_
207} 44}
208 45
209 46
210/* -- page Menu et chemins -- */ 47// détection des requêtes de type XHR, y en a pas à priori
211if($_SERVER['CONTENT_TYPE'] === 'application/json' && isset($_GET['menu_edit'])) 48/*elseif(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'){
212{ 49 echo "requête XHR reçue par le serveur";
213 // récupération des données 50 die;
51}*/
52
53
54// détection des requêtes envoyées avec fetch (application/json) et récupération du JSON
55if($_SERVER['CONTENT_TYPE'] === 'application/json'){
214 $data = file_get_contents('php://input'); 56 $data = file_get_contents('php://input');
215 $json = json_decode($data, true); 57 $json = json_decode($data, true);
216 Director::$menu_data = new Menu($entityManager);
217
218 // flèche gauche <=: position = position du parent + 1, parent = grand-parent, recalculer les positions
219 if($_GET['menu_edit'] === 'move_one_level_up' && isset($json['id'])){
220 $id = $json['id'];
221 $page = Director::$menu_data->findPageById((int)$id);
222
223 $parent = $page->getParent(); // peut être null
224 if($parent === null){
225 // 1er niveau: ne rien faire
226 echo json_encode(['success' => false]);
227 die;
228 }
229 // BDD
230 else{
231 $page->setPosition($parent->getPosition() + 1); // nouvelle position
232
233 // 2ème niveau: le parent devient $menu_data, puis null après tri
234 if($parent->getParent() === null){
235 // connexion dans les deux sens
236 $page->setParent(Director::$menu_data); // => pour la persistance
237
238 //Director::$menu_data->addChild($page); // => pour sortChildren
239 $page->getParent()->addChild($page); // => pour sortChildren
240 //Director::$menu_data->sortChildren(true); // positions décaléees des nouveaux petits frères
241 $page->getParent()->sortChildren(true); // positions décaléees des nouveaux petits frères
242 $page->setParent(null);
243
244 // affichage
245 $page->setPagePath($page->getEndOfPath());
246 $page->fillChildrenPagePath();
247 }
248 // 3ème niveau et plus
249 else{
250 $page->setParent($parent->getParent()); // nouveau parent
251 $page->getParent()->addChild($page); // => pour sortChildren
252 $page->getParent()->sortChildren(true); // positions décaléees des nouveaux petits frères
253 $page->fillChildrenPagePath($page->getParent()->getPagePath());
254 }
255 //$parent->sortChildren(true); // positions des enfants restants, inutile si la fonction est récursive?
256 $entityManager->flush();
257
258 // affichage
259 $parent->removeChild($page);
260 $nav_builder = new NavBuilder();
261 $menu_builder = new MenuBuilder(null, false);
262 echo json_encode(['success' => true, 'nav' => $nav_builder->render(), 'menu_buttons' => $menu_builder->render()]);
263 die;
264 }
265 }
266 58
267 // flèche droite =>: position = nombre d'éléments de la fraterie + 1, l'élément précédent devient le parent 59 // requêtes de tinymce ou touchant aux articles
268 if($_GET['menu_edit'] === 'move_one_level_down' && isset($json['id'])){ 60 if(isset($_GET['action']))
269 $id = $json['id']; 61 {
270 $page = Director::$menu_data->findPageById((int)$id); 62 if($_GET['action'] === 'editor_submit' && isset($json['id']) && isset($json['content']))
63 {
64 if(json_last_error() === JSON_ERROR_NONE)
65 {
66 $id = $json['id'];
67 $director = new Director($entityManager);
68
69 // cas d'une nouvelle "news"
70 if(is_array($json['content'])){
71 foreach($json['content'] as $one_input){
72 $one_input = Security::secureString($one_input);
73 }
74 $content = $json['content'];
75 }
76 else{
77 $content = Security::secureString($json['content']);
78 }
79
80 // nouvel article
81 if($id[0] === 'n')
82 {
83 $section_id = (int)substr($id, 1); // id du bloc <section>
84 $director->findNodeById($section_id);
85 $director->makeSectionNode();
86 $node = $director->getNode(); // = <section>
87
88 if(is_array($content)){
89 $date = new \DateTime($content['d']);
90 $article = new Article($content['i'], $date, $content['t'], $content['p']);
91 $article_node = new Node('new', 'i' . (string)$date->getTimestamp(), [], count($node->getChildren()) + 1, $node, $node->getPage(), $article);
92
93 // id_node tout juste généré
94 //$article_node->getId();
95 }
96 else{
97 $timestamp = time();
98 $date = new \DateTime;
99 $date->setTimestamp($timestamp);
100
101 $article = new Article($content, $date); // le "current" timestamp est obtenu par la BDD
102 $article_node = new Node('article', 'i' . (string)$timestamp, [], count($node->getChildren()) + 1, $node, $node->getPage(), $article);
103 }
104
105 $entityManager->persist($article_node);
106 $entityManager->flush();
107
108 echo json_encode(['success' => true, 'article_id' => $article_node->getArticleTimestamp()]);
109 die;
110 }
111 // modification article
112 else{
113 $id[0] = 'i'; // id de l'article node
114 }
115
116 if($director->makeArticleNode($id)) // une entrée est trouvée
117 {
118 $node = $director->getArticleNode(); // article
119 switch($json['id'][0]){
120 case 'i':
121 $node->getArticle()->setContent($content);
122 break;
123 case 'p':
124 $node->getArticle()->setPreview($content); // html de l'éditeur
125 break;
126 case 't':
127 $node->getArticle()->setTitle($content); // html de l'éditeur
128 break;
129 case 'd':
130 echo json_encode(['success' => false, 'message' => 'l\'action editor_submit ne supporte pas les dates, utiliser date_submit.']);
131 die;
132 default:
133 echo json_encode(['success' => false, 'message' => 'identifiant non utilisable']);
134 die;
135 }
136 $entityManager->flush();
137 echo json_encode(['success' => true]);
138 }
139 else
140 {
141 echo json_encode(['success' => false, 'message' => 'article non identifié']);
142 }
143 }
144 else{
145 echo json_encode(['success' => false, 'message' => 'Erreur de décodage JSON']);
146 }
147 die;
148 }
149 elseif($_GET['action'] === 'delete_article' && isset($json['id']))
150 {
151 $director = new Director($entityManager);
152 $director->makeArticleNode($json['id'], true);
153 $article = $director->getArticleNode();
154 $section = $director->getNode();
155
156 $entityManager->remove($article);
157 $section->removeChild($article);
158 $section->sortChildren(true); // régénère les positions
159 $entityManager->flush();
271 160
272 $parent = $page->getParent(); // peut être null 161 // test avec une nouvelle requête qui ne devrait rien trouver
273 if($parent == null){ 162 if(!$director->makeArticleNode($json['id']))
274 $parent = Director::$menu_data; 163 {
275 } 164 echo json_encode(['success' => true]);
276 165
277 // BDD 166 // on pourrait afficher une notification "toast"
278 $parent->sortChildren(true); // trie et réindexe par sécurité: 1, 2, 3... 167 }
279 if($page->getPosition() > 1){ 168 else{
280 foreach($parent->getChildren() as $child){ 169 http_response_code(500);
281 //echo $child->getPageName(); 170 echo json_encode(['success' => false, 'message' => 'Erreur lors de la suppression de l\'article.']);
282 if($child->getPosition() === $page->getPosition() - 1){ 171 }
283 $page->setParent($child); 172 die;
284 break; 173 }
285 } 174 // inversion de la position de deux noeuds
286 } 175 elseif($_GET['action'] === 'switch_positions' && isset($json['id1']) && isset($json['id2']))
287 $page->setPosition(count($page->getParent()->getChildren()) + 1); 176 {
288 } 177 $director = new Director($entityManager);
289 $entityManager->flush(); 178 $director->makeArticleNode($json['id1'], true);
179 $article1 = $director->getArticleNode();
180 $section = $director->getNode();
181
182 $section->sortChildren(true); // régénère les positions avant inversion
183
184 $article2;
185 foreach($section->getChildren() as $child){
186 if($child->getArticleTimestamp() === $json['id2']) // type string
187 {
188 $article2 = $child;
189 break;
190 }
191 }
290 192
291 // affichage 193 // inversion
292 $parent->removeChild($page); 194 $tmp = $article1->getPosition();
293 $page->getParent()->addChild($page); 195 $article1->setPosition($article2->getPosition());
294 $page->fillChildrenPagePath($page->getParent()->getPagePath()); // variable non mappée $page_path 196 $article2->setPosition($tmp);
295 $nav_builder = new NavBuilder(); 197 $entityManager->flush();
296 $menu_builder = new MenuBuilder(null, false);
297 198
298 echo json_encode(['success' => true, 'nav' => $nav_builder->render(), 'menu_buttons' => $menu_builder->render()]); 199 echo json_encode(['success' => true]);
299 die; 200 die;
201 }
202 elseif($_GET['action'] === 'date_submit' && isset($json['id']) && isset($json['date']))
203 {
204 $id = $json['id'];
205 $id[0] = 'i';
206 $date = new DateTime($json['date']);
207
208 $director = new Director($entityManager);
209 $director->makeArticleNode($id);
210 $node = $director->getArticleNode();
211 $node->getArticle()->setDateTime($date);
212 $entityManager->flush();
213
214 echo json_encode(['success' => true]);
215 die;
216 }
300 } 217 }
301 218
302 if($_GET['menu_edit'] === 'switch_positions' && isset($json['id1']) && isset($json['id2'])) 219
220 /* -- page Menu et chemins -- */
221 elseif(isset($_GET['menu_edit']))
303 { 222 {
304 $id1 = $json['id1']; 223 // récupération des données
305 $id2 = $json['id2']; 224 $data = file_get_contents('php://input');
306 225 $json = json_decode($data, true);
307 // vérifier qu'ils ont le même parent 226 Director::$menu_data = new Menu($entityManager);
308 $page1 = Director::$menu_data->findPageById((int)$id1); 227
309 $page2 = Director::$menu_data->findPageById((int)$id2); 228 // flèche gauche <=: position = position du parent + 1, parent = grand-parent, recalculer les positions
310 229 if($_GET['menu_edit'] === 'move_one_level_up' && isset($json['id'])){
311 // double le contrôle fait en JS 230 $id = $json['id'];
312 if($page1->getParent() === $page2->getParent()) // comparaison stricte d'objet (même instance du parent?) 231 $page = Director::$menu_data->findPageById((int)$id);
313 { 232
314 // inversion 233 $parent = $page->getParent(); // peut être null
315 $tmp = $page1->getPosition(); 234 if($parent === null){
316 $page1->setPosition($page2->getPosition()); 235 // 1er niveau: ne rien faire
317 $page2->setPosition($tmp); 236 echo json_encode(['success' => false]);
318 Director::$menu_data->sortChildren(true); // modifie tableau children 237 die;
238 }
239 // BDD
240 else{
241 $page->setPosition($parent->getPosition() + 1); // nouvelle position
242
243 // 2ème niveau: le parent devient $menu_data, puis null après tri
244 if($parent->getParent() === null){
245 // connexion dans les deux sens
246 $page->setParent(Director::$menu_data); // => pour la persistance
247
248 //Director::$menu_data->addChild($page); // => pour sortChildren
249 $page->getParent()->addChild($page); // => pour sortChildren
250 //Director::$menu_data->sortChildren(true); // positions décaléees des nouveaux petits frères
251 $page->getParent()->sortChildren(true); // positions décaléees des nouveaux petits frères
252 $page->setParent(null);
253
254 // affichage
255 $page->setPagePath($page->getEndOfPath());
256 $page->fillChildrenPagePath();
257 }
258 // 3ème niveau et plus
259 else{
260 $page->setParent($parent->getParent()); // nouveau parent
261 $page->getParent()->addChild($page); // => pour sortChildren
262 $page->getParent()->sortChildren(true); // positions décaléees des nouveaux petits frères
263 $page->fillChildrenPagePath($page->getParent()->getPagePath());
264 }
265 //$parent->sortChildren(true); // positions des enfants restants, inutile si la fonction est récursive?
266 $entityManager->flush();
267
268 // affichage
269 $parent->removeChild($page);
270 $nav_builder = new NavBuilder();
271 $menu_builder = new MenuBuilder(null, false);
272 echo json_encode(['success' => true, 'nav' => $nav_builder->render(), 'menu_buttons' => $menu_builder->render()]);
273 die;
274 }
275 }
276
277 // flèche droite =>: position = nombre d'éléments de la fraterie + 1, l'élément précédent devient le parent
278 if($_GET['menu_edit'] === 'move_one_level_down' && isset($json['id'])){
279 $id = $json['id'];
280 $page = Director::$menu_data->findPageById((int)$id);
281
282 $parent = $page->getParent(); // peut être null
283 if($parent == null){
284 $parent = Director::$menu_data;
285 }
286
287 // BDD
288 $parent->sortChildren(true); // trie et réindexe par sécurité: 1, 2, 3...
289 if($page->getPosition() > 1){
290 foreach($parent->getChildren() as $child){
291 if($child->getPosition() === $page->getPosition() - 1){
292 $page->setParent($child);
293 break;
294 }
295 }
296 $page->setPosition(count($page->getParent()->getChildren()) + 1);
297 }
319 $entityManager->flush(); 298 $entityManager->flush();
320 299
321 // nouveau menu 300 // affichage
301 $parent->removeChild($page);
302 $page->getParent()->addChild($page);
303 $page->fillChildrenPagePath($page->getParent()->getPagePath()); // variable non mappée $page_path
322 $nav_builder = new NavBuilder(); 304 $nav_builder = new NavBuilder();
323 echo json_encode(['success' => true, 'nav' => $nav_builder->render()]); 305 $menu_builder = new MenuBuilder(null, false);
324 }
325 else{
326 echo json_encode(['success' => false]);
327 }
328
329 die;
330 }
331 306
332 if($_GET['menu_edit'] === 'displayInMenu' && isset($json['id']) && isset($json['checked'])) 307 echo json_encode(['success' => true, 'nav' => $nav_builder->render(), 'menu_buttons' => $menu_builder->render()]);
333 { 308 die;
334 $id = $json['id']; 309 }
335 $checked = $json['checked'];
336 310
337 $page = Director::$menu_data->findPageById((int)$id); 311 if($_GET['menu_edit'] === 'switch_positions' && isset($json['id1']) && isset($json['id2']))
338 if($page->isHidden() === $checked){ 312 {
339 $page->setHidden(!$checked); 313 $id1 = $json['id1'];
340 $entityManager->flush(); 314 $id2 = $json['id2'];
341 315
342 // nouveau menu 316 // vérifier qu'ils ont le même parent
343 $nav_builder = new NavBuilder(); 317 $page1 = Director::$menu_data->findPageById((int)$id1);
344 echo json_encode(['success' => true, 'nav' => $nav_builder->render()]); 318 $page2 = Director::$menu_data->findPageById((int)$id2);
319
320 // double le contrôle fait en JS
321 if($page1->getParent() === $page2->getParent()) // comparaison stricte d'objet (même instance du parent?)
322 {
323 // inversion
324 $tmp = $page1->getPosition();
325 $page1->setPosition($page2->getPosition());
326 $page2->setPosition($tmp);
327 Director::$menu_data->sortChildren(true); // modifie tableau children
328 $entityManager->flush();
329
330 // nouveau menu
331 $nav_builder = new NavBuilder();
332 echo json_encode(['success' => true, 'nav' => $nav_builder->render()]);
333 }
334 else{
335 echo json_encode(['success' => false]);
336 }
337
338 die;
345 } 339 }
346 else{ 340
347 echo json_encode(['success' => false]); 341 if($_GET['menu_edit'] === 'displayInMenu' && isset($json['id']) && isset($json['checked']))
342 {
343 $id = $json['id'];
344 $checked = $json['checked'];
345
346 $page = Director::$menu_data->findPageById((int)$id);
347 if($page->isHidden() === $checked){
348 $page->setHidden(!$checked);
349 $entityManager->flush();
350
351 // nouveau menu
352 $nav_builder = new NavBuilder();
353 echo json_encode(['success' => true, 'nav' => $nav_builder->render()]);
354 }
355 else{
356 echo json_encode(['success' => false]);
357 }
358 die;
348 } 359 }
349 die;
350 } 360 }
351}
352 361
353 362
354/* -- mode Modification d'une page -- */ 363 /* -- mode Modification d'une page -- */
355if($_SERVER['CONTENT_TYPE'] === 'application/json' && isset($_GET['bloc_edit']))
356{
357 // récupération des données
358 $data = file_get_contents('php://input');
359 $json = json_decode($data, true);
360 364
361 // renommage d'un bloc 365 // partie "page"
362 if($_GET['bloc_edit'] === 'rename_page_bloc') 366 elseif(isset($_GET['page_edit']))
363 { 367 {
364 if(isset($json['bloc_title']) && $json['bloc_title'] !== null && isset($json['bloc_id']) && is_int($json['bloc_id'])){ 368 // récupération des données
365 $director = new Director($entityManager); 369 $data = file_get_contents('php://input');
366 $director->findNodeById($json['bloc_id']); 370 $json = json_decode($data, true);
367 371
368 // le titre (du JSON en BDD) est récupéré sous forme de tableau, modifié et renvoyé 372 // tite de la page
369 $data = $director->getNode()->getNodeData()->getData(); 373 if($_GET['page_edit'] === 'page_title'){
370 $data['title'] = htmlspecialchars($json['bloc_title']); 374 $page = $entityManager->find('App\Entity\Page', $json['page_id']);
371 $director->getNode()->getNodeData()->setData($data); 375 $page->setPageName(htmlspecialchars($json['title']));
372 376 $entityManager->flush();
373 $entityManager->flush(); 377 echo json_encode(['success' => true, 'title' => $page->getPageName()]);
374 echo json_encode(['success' => true, 'title' => $data['title']]);
375 }
376 else{
377 echo json_encode(['success' => false]);
378 } 378 }
379 die; 379 // titre en snake_case pour le menu
380 } 380 /*elseif($_GET['page_edit'] === 'page_menu_path'){
381 // inversion des positions de deux blocs 381 $page = $entityManager->find('App\Entity\Page', $json['page_id']);
382 elseif($_GET['bloc_edit'] === 'switch_blocs_positions') 382 $page->setEndOfPath(htmlspecialchars($json['page_menu_path']));
383 { 383 $entityManager->flush();
384 if(isset($json['id1']) && is_int($json['id1']) && isset($json['id2']) && is_int($json['id2']) && isset($_GET['page'])){ 384 echo json_encode(['success' => true, 'page_name_path' => $page->getEndOfPath()]);
385 $director = new Director($entityManager, true); 385 }*/
386 $director->findUniqueNodeByName('main'); 386 // description dans les métadonnées
387 $director->findItsChildren(); 387 elseif($_GET['page_edit'] === 'page_description'){
388 $main = $director->getNode(); 388 $node_data = $entityManager->find('App\Entity\NodeData', $json['node_data_id']);
389 $main->sortChildren(true); // régénère les positions avant inversion 389 $node_data->updateData('description', htmlspecialchars($json['description']));
390 390 $entityManager->flush();
391 $bloc1; $bloc2; 391 echo json_encode(['success' => true, 'description' => $node_data->getData()['description']]);
392 foreach($main->getChildren() as $child){
393 if($child->getId() === $json['id1']){
394 $bloc1 = $child;
395 break;
396 }
397 }
398 foreach($main->getChildren() as $child){
399 if($child->getId() === $json['id2']){
400 $bloc2 = $child;
401 break;
402 }
403 }
404
405 // inversion
406 $tmp = $bloc1->getPosition();
407 $bloc1->setPosition($bloc2->getPosition());
408 $bloc2->setPosition($tmp);
409
410 $entityManager->flush();
411 echo json_encode(['success' => true]);
412 }
413 else{
414 echo json_encode(['success' => false]);
415 } 392 }
416 die; 393 die;
417 } 394 }
418}
419
420
421// détection des requêtes de type XHR?, pas d'utilité à priori
422/*elseif(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'){
423 echo "requête XHR reçue par le serveur";
424 die;
425}*/
426
427 395
396 // partie "blocs"
397 elseif(isset($_GET['bloc_edit']))
398 {
399 // renommage d'un bloc
400 if($_GET['bloc_edit'] === 'rename_page_bloc')
401 {
402 if(isset($json['bloc_title']) && $json['bloc_title'] !== null && isset($json['bloc_id']) && is_int($json['bloc_id'])){
403 $director = new Director($entityManager);
404 $director->findNodeById($json['bloc_id']);
405
406 // le titre (du JSON en BDD) est récupéré sous forme de tableau, modifié et renvoyé
407 $data = $director->getNode()->getNodeData()->getData();
408 $data['title'] = htmlspecialchars($json['bloc_title']);
409 $director->getNode()->getNodeData()->updateData('title', htmlspecialchars($json['bloc_title']));
410
411 $entityManager->flush();
412 echo json_encode(['success' => true, 'title' => $data['title']]);
413 }
414 else{
415 echo json_encode(['success' => false]);
416 }
417 die;
418 }
419 // inversion des positions de deux blocs
420 elseif($_GET['bloc_edit'] === 'switch_blocs_positions')
421 {
422 if(isset($json['id1']) && is_int($json['id1']) && isset($json['id2']) && is_int($json['id2']) && isset($_GET['page'])){
423 $director = new Director($entityManager, true);
424 $director->findUniqueNodeByName('main');
425 $director->findItsChildren();
426 $main = $director->getNode();
427 $main->sortChildren(true); // régénère les positions avant inversion
428
429 $bloc1; $bloc2;
430 foreach($main->getChildren() as $child){
431 if($child->getId() === $json['id1']){
432 $bloc1 = $child;
433 break;
434 }
435 }
436 foreach($main->getChildren() as $child){
437 if($child->getId() === $json['id2']){
438 $bloc2 = $child;
439 break;
440 }
441 }
442
443 // inversion
444 $tmp = $bloc1->getPosition();
445 $bloc1->setPosition($bloc2->getPosition());
446 $bloc2->setPosition($tmp);
447
448 $entityManager->flush();
449 echo json_encode(['success' => true]);
450 }
451 else{
452 echo json_encode(['success' => false]);
453 }
454 die;
455 }
456 }
457} \ No newline at end of file
diff --git a/src/controller/installation.php b/src/controller/installation.php
index 4aaa4e0..64ed94e 100644
--- a/src/controller/installation.php
+++ b/src/controller/installation.php
@@ -76,27 +76,29 @@ HTACCESS;
76// les informations ici ne sont pas demandées à l'utilisateur pour l'instant (on verra ça plus tard) 76// les informations ici ne sont pas demandées à l'utilisateur pour l'instant (on verra ça plus tard)
77function makeStartPage(EntityManager $entityManager){ 77function makeStartPage(EntityManager $entityManager){
78 /* -- table page -- */ 78 /* -- table page -- */
79 // paramètres: name_page, end_of_path, reachable, in_menu, position, parent 79 // paramètres: name_page, end_of_path, reachable, in_menu, hidden, position, parent
80 $accueil = new Page('Accueil', 'accueil', true, true, false, 1, NULL); 80 $accueil = new Page('Accueil', 'accueil', true, true, false, 1, NULL);
81 $connection = new Page('Connexion', 'connexion', true, false, false, NULL, NULL);
82 $article = new Page('Article', 'article', true, false, false, NULL, NULL); 81 $article = new Page('Article', 'article', true, false, false, NULL, NULL);
82 $connection = new Page('Connexion', 'connexion', true, false, false, NULL, NULL);
83 $menu_paths = new Page("Menu et chemins", 'menu_chemins', true, false, false, NULL, NULL); 83 $menu_paths = new Page("Menu et chemins", 'menu_chemins', true, false, false, NULL, NULL);
84 $edit_page = new Page("Modification d'une page", 'modif_page', true, false, false, NULL, NULL); 84 //$edit_page = new Page("Modification d'une page", 'modif_page', true, false, false, NULL, NULL); // pas de page "Modification de la page"
85 $new_page = new Page('Nouvelle page', 'nouvelle_page', true, false, false, NULL, NULL); 85 $new_page = new Page('Nouvelle page', 'nouvelle_page', true, false, false, NULL, NULL);
86 86
87 /* -- table node -- */ 87 /* -- table node -- */
88 // paramètres: name_node, article_timestamp, attributes, position, parent, page, article 88 // paramètres: name_node, article_timestamp, attributes, position, parent, page, article
89 $head_accueil = new Node('head', NULL, ['css_array' => ['body', 'head', 'nav', 'main', 'foot'], 'js_array' => ['main']], 1, NULL, $accueil, NULL); 89 $head_accueil = new Node('head', NULL, ['css_array' => ['body', 'head', 'nav', 'foot'], 'js_array' => ['main']], 1, NULL, $accueil, NULL);
90 $head_article = new Node('head', NULL, ['css_array' => ['body', 'head', 'nav', 'foot'], 'js_array' => ['main']], 1, NULL, $article, NULL);
90 $header = new Node('header', NULL, [], 2, NULL, NULL, NULL); 91 $header = new Node('header', NULL, [], 2, NULL, NULL, NULL);
91 $nav = new Node('nav', NULL, [], 1, $header, NULL, NULL); 92 $nav = new Node('nav', NULL, [], 1, $header, NULL, NULL);
92 $main = new Node('main', NULL, [], 3, NULL, NULL, NULL); 93 $main = new Node('main', NULL, [], 3, NULL, NULL, NULL);
93 $footer = new Node('footer', NULL, [], 4, NULL, NULL, NULL); 94 $footer = new Node('footer', NULL, [], 4, NULL, NULL, NULL);
94 $breadcrumb = new Node('breadcrumb', NULL, [], 2, $header, NULL, NULL); 95 $breadcrumb = new Node('breadcrumb', NULL, [], 2, $header, NULL, NULL);
95 $head_login = new Node('head', NULL, ["stop" => true, 'css_array' => ['body', 'head', 'nav', 'main'], 'js_array' => ['main']], 1, NULL, $connection, NULL); 96 $head_login = new Node('head', NULL, ["stop" => true, 'css_array' => ['body', 'head', 'nav'], 'js_array' => ['main']], 1, NULL, $connection, NULL);
96 $login = new Node('login', NULL, [], 1, $main, $connection, NULL); 97 $login = new Node('login', NULL, [], 1, $main, $connection, NULL);
97 $head_article = new Node('head', NULL, ['css_array' => ['body', 'head', 'nav', 'main', 'foot'], 'js_array' => ['main']], 1, NULL, $article, NULL); 98 $head_edit_menu = new Node('head', NULL, ['css_array' => ['body', 'head', 'nav', 'menu'], 'js_array' => ['main', 'menu']], 1, NULL, $menu_paths, NULL);
98 $head_edit_menu = new Node('head', NULL, ['css_array' => ['body', 'head', 'nav', 'main', 'menu'], 'js_array' => ['main', 'menu']], 1, NULL, $menu_paths, NULL); 99 $bloc_edit_menu = new Node('menu', NULL, [], 1, $main, $menu_paths, NULL);
99 $edit_menu = new Node('menu', NULL, [], 1, $main, $menu_paths, NULL); 100 $head_new_page = new Node('head', NULL, ['css_array' => ['body', 'head', 'nav', 'new_page'], 'js_array' => ['main', 'new_page']], 1, NULL, $new_page, NULL);
101 $bloc_new_page = new Node('new_page', NULL, [], 1, $main, $new_page, NULL);
100 102
101 /* -- table image -- */ 103 /* -- table image -- */
102 // paramètres: file_name, file_path, file_path_mini, mime_type, alt 104 // paramètres: file_name, file_path, file_path_mini, mime_type, alt
@@ -107,20 +109,24 @@ function makeStartPage(EntityManager $entityManager){
107 $fond_piscine = new Image("fond-piscine.jpg", "assets/fond-piscine.jpg", NULL, "images/jpg", "fond-piscine"); 109 $fond_piscine = new Image("fond-piscine.jpg", "assets/fond-piscine.jpg", NULL, "images/jpg", "fond-piscine");
108 110
109 /* -- table node_data -- */ 111 /* -- table node_data -- */
110 // paramètres: data, node 112 // paramètres: data, node, images
111 $head_accueil_data = new NodeData(["description" => "Club, École de natation et Perfectionnement", "title" => "Les Nageurs Bigoudens"], $head_accueil, new ArrayCollection([$favicon])); 113 $head_accueil_data = new NodeData(["description" => "Club, École de natation et Perfectionnement", "title" => "Les Nageurs Bigoudens"], $head_accueil, new ArrayCollection([$favicon]));
112 $header_data = new NodeData(["description" => "Club, École de natation et Perfectionnement", "title" => "Les Nageurs Bigoudens", "facebook_link" => "https://www.facebook.com/nageursbigoudens29120", "instagram_link" => "https://www.instagram.com/nageursbigoudens/"], $header, new ArrayCollection([$logo, $facebook, $instagram, $fond_piscine])); 114 $header_data = new NodeData(["description" => "Club, École de natation et Perfectionnement", "title" => "Les Nageurs Bigoudens", "facebook_link" => "https://www.facebook.com/nageursbigoudens29120", "instagram_link" => "https://www.instagram.com/nageursbigoudens/"], $header, new ArrayCollection([$logo, $facebook, $instagram, $fond_piscine]));
113 $footer_data = new NodeData(["adresse" => "17, rue Raymonde Folgoas Guillou, 29120 Pont-l’Abbé", "contact_nom" => "Les Nageurs Bigoudens", "e_mail" => "nb.secretariat@orange.fr", "logo_footer" => "assets/logo-nb-et-ffn.png"], $footer); 115 $footer_data = new NodeData(["adresse" => "17, rue Raymonde Folgoas Guillou, 29120 Pont-l’Abbé", "contact_nom" => "Les Nageurs Bigoudens", "e_mail" => "nb.secretariat@orange.fr", "logo_footer" => "assets/logo-nb-et-ffn.png"], $footer);
114 $head_login_data = new NodeData(["description" => "Connexion", "title" => "Connexion"], $head_login, new ArrayCollection([$favicon])); 116 $head_login_data = new NodeData(["description" => "Connexion", "title" => "Connexion"], $head_login, new ArrayCollection([$favicon]));
115 $head_article_data = new NodeData(["description" => "", "title" => ""], $head_article, new ArrayCollection([$favicon])); 117 $head_article_data = new NodeData(["description" => "", "title" => ""], $head_article, new ArrayCollection([$favicon]));
116 $head_edit_menu_data = new NodeData(["description" => "Menu et chemins", "title" => "Menu et chemins"], $head_edit_menu, new ArrayCollection([$favicon])); 118 $head_edit_menu_data = new NodeData(["description" => "Menu et chemins", "title" => "Menu et chemins"], $head_edit_menu, new ArrayCollection([$favicon]));
119 $head_new_page_data = new NodeData(["description" => "Nouvelle page", "title" => "Nouvelle page"], $head_new_page, new ArrayCollection([$favicon]));
117 120
121 /* -- table page -- */
118 $entityManager->persist($accueil); 122 $entityManager->persist($accueil);
119 $entityManager->persist($connection);
120 $entityManager->persist($article); 123 $entityManager->persist($article);
124 $entityManager->persist($connection);
121 $entityManager->persist($menu_paths); 125 $entityManager->persist($menu_paths);
122 $entityManager->persist($edit_page); 126 //$entityManager->persist($edit_page); // pas de page "Modification de la page"
123 $entityManager->persist($new_page); 127 $entityManager->persist($new_page);
128
129 /* -- table node -- */
124 $entityManager->persist($head_accueil); 130 $entityManager->persist($head_accueil);
125 $entityManager->persist($header); 131 $entityManager->persist($header);
126 $entityManager->persist($nav); 132 $entityManager->persist($nav);
@@ -131,20 +137,27 @@ function makeStartPage(EntityManager $entityManager){
131 $entityManager->persist($login); 137 $entityManager->persist($login);
132 $entityManager->persist($head_article); 138 $entityManager->persist($head_article);
133 $entityManager->persist($head_edit_menu); 139 $entityManager->persist($head_edit_menu);
134 $entityManager->persist($edit_menu); 140 $entityManager->persist($bloc_edit_menu);
141 $entityManager->persist($head_new_page);
142 $entityManager->persist($bloc_new_page);
143
144 /* -- table image -- */
135 $entityManager->persist($favicon); 145 $entityManager->persist($favicon);
136 $entityManager->persist($logo); 146 $entityManager->persist($logo);
137 $entityManager->persist($facebook); 147 $entityManager->persist($facebook);
138 $entityManager->persist($instagram); 148 $entityManager->persist($instagram);
139 $entityManager->persist($fond_piscine); 149 $entityManager->persist($fond_piscine);
150
151 /* -- table node_data -- */
140 $entityManager->persist($head_accueil_data); 152 $entityManager->persist($head_accueil_data);
141 $entityManager->persist($header_data); 153 $entityManager->persist($header_data);
142 $entityManager->persist($footer_data); 154 $entityManager->persist($footer_data);
143 $entityManager->persist($head_login_data); 155 $entityManager->persist($head_login_data);
144 $entityManager->persist($head_article_data); 156 $entityManager->persist($head_article_data);
145 $entityManager->persist($head_edit_menu_data); 157 $entityManager->persist($head_edit_menu_data);
146 $entityManager->flush(); 158 $entityManager->persist($head_new_page_data);
147 159
160 $entityManager->flush();
148 header('Location: ' . new URL); 161 header('Location: ' . new URL);
149 die; 162 die;
150} \ No newline at end of file 163} \ No newline at end of file
diff --git a/src/controller/post.php b/src/controller/post.php
index d437423..631c4ad 100644
--- a/src/controller/post.php
+++ b/src/controller/post.php
@@ -13,9 +13,30 @@ if($_SERVER['REQUEST_METHOD'] === 'POST' && $_SESSION['admin'] === true)
13 if($_SERVER['CONTENT_TYPE'] === 'application/x-www-form-urlencoded') 13 if($_SERVER['CONTENT_TYPE'] === 'application/x-www-form-urlencoded')
14 { 14 {
15 /* -- mode Modification d'une page -- */ 15 /* -- mode Modification d'une page -- */
16 if(isset($_POST['page_menu_path']) && $_POST['page_menu_path'] !== null
17 && isset($_POST['page_id']) && $_POST['page_id'] !== null
18 && isset($_POST['page_name_path_hidden']) && $_POST['page_name_path_hidden'] === '')
19 {
20 $director = new Director($entityManager, true);
21 $page = Director::$page_path->getLast();
22 //$page = $entityManager->find('App\Entity\Page', $_POST['page_id']);
23 $path = htmlspecialchars($_POST['page_menu_path']);
16 24
25 // mise en snake_case: filtre caractères non-alphanumériques, minuscule, doublons d'underscore, trim des underscores
26 $path = trim(preg_replace('/_+/', '_', strtolower(preg_replace('/[^a-zA-Z0-9]/', '_', $path))), '_');
27 $page->setEndOfPath($path);
28 foreach(Director::$menu_data->getChildren() as $child){
29 if($child->getEndOfPath() === Director::$page_path->getArray()[0]->getEndOfPath()){
30 $child->fillChildrenPagePath(); // MAJ de $page_path
31 }
32 }
33 $entityManager->flush();
34 header("Location: " . new URL(['page' => $page->getPagePath(), 'action' => 'modif_page']));
35 die;
36 }
17 // ajout d'un bloc dans une page 37 // ajout d'un bloc dans une page
18 if(isset($_POST['bloc_title']) && $_POST['bloc_title'] !== null && isset($_POST['bloc_select']) && $_POST['bloc_select'] !== null 38 elseif(isset($_POST['bloc_title']) && $_POST['bloc_title'] !== null
39 && isset($_POST['bloc_select']) && $_POST['bloc_select'] !== null
19 && isset($_POST['bloc_title_hidden']) && $_POST['bloc_title_hidden'] === '') // contrôle anti-robot avec input hidden 40 && isset($_POST['bloc_title_hidden']) && $_POST['bloc_title_hidden'] === '') // contrôle anti-robot avec input hidden
20 { 41 {
21 $director = new Director($entityManager, true); // on a besoin de page_path qui dépend de menu_data 42 $director = new Director($entityManager, true); // on a besoin de page_path qui dépend de menu_data
@@ -39,6 +60,7 @@ if($_SERVER['REQUEST_METHOD'] === 'POST' && $_SESSION['admin'] === true)
39 $entityManager->persist($data); 60 $entityManager->persist($data);
40 $entityManager->flush(); 61 $entityManager->flush();
41 header("Location: " . new URL(['page' => $_GET['page'], 'action' => 'modif_page'])); 62 header("Location: " . new URL(['page' => $_GET['page'], 'action' => 'modif_page']));
63 die;
42 } 64 }
43 // suppression d'un bloc de page 65 // suppression d'un bloc de page
44 elseif(isset($_POST['delete_bloc_id']) && $_POST['delete_bloc_id'] !== null 66 elseif(isset($_POST['delete_bloc_id']) && $_POST['delete_bloc_id'] !== null
@@ -62,8 +84,9 @@ if($_SERVER['REQUEST_METHOD'] === 'POST' && $_SESSION['admin'] === true)
62 $entityManager->remove($bloc); // suppression en BDD 84 $entityManager->remove($bloc); // suppression en BDD
63 $entityManager->flush(); 85 $entityManager->flush();
64 header("Location: " . new URL(['page' => $_GET['page'], 'action' => 'modif_page'])); 86 header("Location: " . new URL(['page' => $_GET['page'], 'action' => 'modif_page']));
87 die;
65 } 88 }
66 89
67 90
68 /* -- page Menu et chemins -- */ 91 /* -- page Menu et chemins -- */
69 92
@@ -91,6 +114,7 @@ if($_SERVER['REQUEST_METHOD'] === 'POST' && $_SESSION['admin'] === true)
91 $entityManager->persist($page); 114 $entityManager->persist($page);
92 $entityManager->flush(); 115 $entityManager->flush();
93 header("Location: " . new URL(['page' => $_GET['from']])); 116 header("Location: " . new URL(['page' => $_GET['from']]));
117 die;
94 } 118 }
95 // suppression d'une entrée de menu avec une URL 119 // suppression d'une entrée de menu avec une URL
96 elseif(isset($_POST['delete']) && isset($_POST['x']) && isset($_POST['y'])){ // 2 params x et y sont là parce qu'on a cliqué sur une image 120 elseif(isset($_POST['delete']) && isset($_POST['x']) && isset($_POST['y'])){ // 2 params x et y sont là parce qu'on a cliqué sur une image
@@ -107,9 +131,11 @@ if($_SERVER['REQUEST_METHOD'] === 'POST' && $_SESSION['admin'] === true)
107 $entityManager->remove($page); // suppression en BDD 131 $entityManager->remove($page); // suppression en BDD
108 $entityManager->flush(); 132 $entityManager->flush();
109 header("Location: " . new URL(['page' => $_GET['from']])); 133 header("Location: " . new URL(['page' => $_GET['from']]));
134 die;
110 } 135 }
111 else{ 136 else{
112 header("Location: " . new URL(['error' => 'paramètres inconnus'])); 137 header("Location: " . new URL(['error' => 'paramètres inconnus']));
138 die;
113 } 139 }
114 } 140 }
115 141
diff --git a/src/model/entities/NodeData.php b/src/model/entities/NodeData.php
index aaffb6a..8f0f511 100644
--- a/src/model/entities/NodeData.php
+++ b/src/model/entities/NodeData.php
@@ -43,13 +43,21 @@ class NodeData
43 $this->images = $images; 43 $this->images = $images;
44 } 44 }
45 45
46 public function getId(): int
47 {
48 return $this->id_node_data;
49 }
46 public function getData(): array 50 public function getData(): array
47 { 51 {
48 return $this->data; 52 return $this->data;
49 } 53 }
50 public function setData(array $data): void 54 /*public function setData(array $data): void
51 { 55 {
52 $this->data = $data; 56 $this->data = $data;
57 }*/
58 public function updateData(string $key, string $value): void
59 {
60 $this->data[$key] = $value;
53 } 61 }
54 /*public function setNode(Node $node): void 62 /*public function setNode(Node $node): void
55 { 63 {
diff --git a/src/model/entities/Page.php b/src/model/entities/Page.php
index 9564342..1ad9ddb 100644
--- a/src/model/entities/Page.php
+++ b/src/model/entities/Page.php
@@ -71,6 +71,10 @@ class Page
71 { 71 {
72 return $this->name_page; 72 return $this->name_page;
73 } 73 }
74 public function setPageName(string $name): void
75 {
76 $this->name_page = $name;
77 }
74 public function getPagePath(): string 78 public function getPagePath(): string
75 { 79 {
76 return $this->page_path; 80 return $this->page_path;
@@ -83,6 +87,10 @@ class Page
83 { 87 {
84 return $this->end_of_path; 88 return $this->end_of_path;
85 } 89 }
90 public function setEndOfPath(string $end_of_path):void
91 {
92 $this->end_of_path = $end_of_path;
93 }
86 public function isReachable(): bool 94 public function isReachable(): bool
87 { 95 {
88 return $this->reachable; 96 return $this->reachable;
diff --git a/src/view/BreadcrumbBuilder.php b/src/view/BreadcrumbBuilder.php
index fcdcd41..c042fa9 100644
--- a/src/view/BreadcrumbBuilder.php
+++ b/src/view/BreadcrumbBuilder.php
@@ -41,8 +41,8 @@ class BreadcrumbBuilder extends AbstractBuilder
41 $html .= '<span class="arrow"> →</span>' . "\n"; 41 $html .= '<span class="arrow"> →</span>' . "\n";
42 } 42 }
43 43
44 // fin du chemin 44 // fin du chemin (=> Thésée)
45 $html .= '<span aria-current="page">' . $breadcrumb_array[$nb_of_entries - 1]->getPageName() . "</span>\n"; 45 $html .= '<span id="thesee" aria-current="page">' . $breadcrumb_array[$nb_of_entries - 1]->getPageName() . "</span>\n";
46 $html .= "</nav>\n"; 46 $html .= "</nav>\n";
47 } 47 }
48 return $html; 48 return $html;
diff --git a/src/view/GridBuilder.php b/src/view/GridBuilder.php
index 6845c49..30a9040 100644
--- a/src/view/GridBuilder.php
+++ b/src/view/GridBuilder.php
@@ -69,8 +69,8 @@ class GridBuilder extends AbstractBuilder
69 $content = $this->html; 69 $content = $this->html;
70 70
71 ob_start(); 71 ob_start();
72 require $viewFile; 72 require $viewFile; // utilise $content
73 $this->html = ob_get_clean(); // pas de concaténation ici, on écrase 73 $this->html = ob_get_clean(); // nouveau contenu
74 } 74 }
75 } 75 }
76} \ No newline at end of file 76} \ No newline at end of file
diff --git a/src/view/HeadBuilder.php b/src/view/HeadBuilder.php
index 2cca757..4b913b9 100644
--- a/src/view/HeadBuilder.php
+++ b/src/view/HeadBuilder.php
@@ -28,12 +28,18 @@ class HeadBuilder extends AbstractBuilder
28 { 28 {
29 $css .= '<link rel="stylesheet" href="css/' . $name . '.css">' . "\n"; 29 $css .= '<link rel="stylesheet" href="css/' . $name . '.css">' . "\n";
30 } 30 }
31 $js = ''; 31
32 $js = '';
32 foreach($js_array as $name) 33 foreach($js_array as $name)
33 { 34 {
34 $js .= '<script src="js/' . $name . '.js"></script>' . "\n"; 35 $js .= '<script src="js/' . $name . '.js"></script>' . "\n";
35 } 36 }
36 37
38 if(MainBuilder::$modif_mode){
39 $css .= '<link rel="stylesheet" href="css/modif_page.css">' . "\n";
40 $js .= '<script src="js/modif_page.js"></script>' . "\n";
41 }
42
37 // tinymce, nécéssite un script de copie dans composer.json 43 // tinymce, nécéssite un script de copie dans composer.json
38 if($_SESSION['admin']){ 44 if($_SESSION['admin']){
39 $css .= '<link rel="stylesheet" href="css/tinymce.css">' . "\n"; 45 $css .= '<link rel="stylesheet" href="css/tinymce.css">' . "\n";
diff --git a/src/view/MainBuilder.php b/src/view/MainBuilder.php
index 5096134..11f5c4b 100644
--- a/src/view/MainBuilder.php
+++ b/src/view/MainBuilder.php
@@ -14,7 +14,7 @@ class MainBuilder extends AbstractBuilder
14 { 14 {
15 $this->html .= "<main>\n"; 15 $this->html .= "<main>\n";
16 16
17 // cas particulier de la page article où l'article est greffé sur main 17 // page article: cas particulier où l'article est greffé sur main
18 if(Director::$page_path->getLast()->getEndOfPath() === 'article'){ 18 if(Director::$page_path->getLast()->getEndOfPath() === 'article'){
19 // pas censé arriver 19 // pas censé arriver
20 if(!isset($_GET['id'])){ 20 if(!isset($_GET['id'])){
@@ -42,14 +42,18 @@ class MainBuilder extends AbstractBuilder
42 $this->viewEditBlocks($node); 42 $this->viewEditBlocks($node);
43 } 43 }
44 44
45 // cas normal
45 $this->useChildrenBuilder($node); 46 $this->useChildrenBuilder($node);
46 } 47 }
47 48
48 $this->html .= "</main>\n"; 49 $this->html .= "</main>\n";
49 } 50 }
50 51
52 // mode modification de page uniquement
51 private function viewEditBlocks($node): void 53 private function viewEditBlocks($node): void
52 { 54 {
55 $viewFile = self::VIEWS_PATH . $node->getName() . '.php'; // mode modification uniquement
56
53 // blocs disponibles 57 // blocs disponibles
54 $blocs = ['Blog', 'Grille', 'Calendrier', 'Galerie']; // générer ça dynamiquement! 58 $blocs = ['Blog', 'Grille', 'Calendrier', 'Galerie']; // générer ça dynamiquement!
55 $blocs_true_names = ['blog', 'grid', 'calendar', 'galery']; 59 $blocs_true_names = ['blog', 'grid', 'calendar', 'galery'];
@@ -68,41 +72,36 @@ class MainBuilder extends AbstractBuilder
68 </div> 72 </div>
69 </aside>' . "\n";*/ 73 </aside>' . "\n";*/
70 74
71 // création d'un bloc 75 //$page_id = Director::$page_path->getLast()->getId();
72 $this->html .= '<div class="edit_bloc_zone"> 76 $head_node = null;
73 <div class="new_bloc"> 77 foreach(ViewBuilder::$root_node->getChildren() as $first_level_node){
74 <p>Ajouter un bloc de page</p> 78 if($first_level_node->getName() === 'head'){
75 <form method="post" action="' . new URL(['page' => CURRENT_PAGE]) . '"> 79 $head_node = $first_level_node; // normallement c'est le 1er enfant
76 <p><label for="bloc_title">Titre</label> 80 break;
77 <input type="text" id="bloc_title" name="bloc_title" required></p> 81 }
78 <p><label for="bloc_select">Type</label> 82 }
79 <select id="bloc_select" name="bloc_select" required>' 83
80 . $options . 84 $bloc_edit = '';
81 '</select>
82 <input type="hidden" name="bloc_title_hidden">
83 <input type="submit" value="Valider"></p>
84 </form>
85 </div>' . "\n";
86 $this->html .= '<div class="modify_bloc">
87 <p>Modifier un bloc</p>';
88 foreach($node->getChildren() as $child_node){ 85 foreach($node->getChildren() as $child_node){
89 // renommage d'un bloc 86 // renommage d'un bloc
90 $this->html .= '<div id="bloc_edit_' . $child_node->getId() . '"> 87 $bloc_edit .= '<div id="bloc_edit_' . $child_node->getId() . '">
91 <p><label for="bloc_rename_' . $child_node->getId() . '">Titre</label> 88 <p><label for="bloc_rename_' . $child_node->getId() . '">Titre</label>
92 <input type="text" id="bloc_rename_' . $child_node->getId() . '" name="bloc_rename_title" value="' . $child_node->getNodeData()->getdata()['title'] . '" required> 89 <input type="text" id="bloc_rename_' . $child_node->getId() . '" name="bloc_rename_title" value="' . $child_node->getNodeData()->getdata()['title'] . '" required>
93 <button onclick="renamePageBloc(' . $child_node->getId() . ')">Renommer</button>'. "\n"; 90 <button onclick="renamePageBloc(' . $child_node->getId() . ')">Renommer</button>'. "\n";
94 // déplacement d'un bloc 91 // déplacement d'un bloc
95 $this->html .= '<img class="action_icon" onclick="switchBlocsPositions(' . $child_node->getId() . ', \'up\', \'' . CURRENT_PAGE . '\')" src="assets/arrow-up.svg"> 92 $bloc_edit .= '<img class="action_icon" onclick="switchBlocsPositions(' . $child_node->getId() . ', \'up\', \'' . CURRENT_PAGE . '\')" src="assets/arrow-up.svg">
96 <img class="action_icon" onclick="switchBlocsPositions(' . $child_node->getId() . ', \'down\', \'' . CURRENT_PAGE . '\')" src="assets/arrow-down.svg">' . "\n"; 93 <img class="action_icon" onclick="switchBlocsPositions(' . $child_node->getId() . ', \'down\', \'' . CURRENT_PAGE . '\')" src="assets/arrow-down.svg">' . "\n";
97 // suppression d'un bloc 94 // suppression d'un bloc
98 $this->html .= '<form method="post" action="' . new URL(['page' => CURRENT_PAGE]) . '"> 95 $bloc_edit .= '<form method="post" action="' . new URL(['page' => CURRENT_PAGE]) . '">
99 <input type="hidden" name="delete_bloc_id" value="' . $child_node->getId() . '"> 96 <input type="hidden" name="delete_bloc_id" value="' . $child_node->getId() . '">
100 <input type="hidden" name="delete_bloc_hidden"> 97 <input type="hidden" name="delete_bloc_hidden">
101 <input type="submit" value="Supprimer"></p> 98 <input type="submit" value="Supprimer"></p>
102 </form> 99 </form>
103 </div>'. "\n"; 100 </div>'. "\n";
104 } 101 }
105 $this->html .= "</div> 102
106 </div>\n"; 103 ob_start();
104 require $viewFile;
105 $this->html .= ob_get_clean();
107 } 106 }
108} 107} \ No newline at end of file
diff --git a/src/view/NavBuilder.php b/src/view/NavBuilder.php
index f4fb651..fd5f867 100644
--- a/src/view/NavBuilder.php
+++ b/src/view/NavBuilder.php
@@ -53,7 +53,7 @@ class NavBuilder extends AbstractBuilder
53 { 53 {
54 $li_class .= $data->getParent() == null ? 'drop-down' : 'drop-right'; 54 $li_class .= $data->getParent() == null ? 'drop-down' : 'drop-right';
55 55
56 $nav_html .= '<li class="'. $li_class . '">' . $link . '<p>' . $data->getPageName() . '</p></a><ul class="sub-menu">' . "\n"; 56 $nav_html .= '<li class="'. $li_class . '">' . $link . '<p id="m_' . $data->getId() . '">' . $data->getPageName() . '</p></a><ul class="sub-menu">' . "\n";
57 $level++; 57 $level++;
58 $nav_html .= $this->navMainHTML($data, $current); 58 $nav_html .= $this->navMainHTML($data, $current);
59 $level--; 59 $level--;
@@ -61,7 +61,7 @@ class NavBuilder extends AbstractBuilder
61 } 61 }
62 else 62 else
63 { 63 {
64 $nav_html .= '<li class="'. $li_class . '">' . $link . '<p>' . $data->getPageName() . '</p></a></li>' . "\n"; 64 $nav_html .= '<li class="'. $li_class . '">' . $link . '<p id="m_' . $data->getId() . '">' . $data->getPageName() . '</p></a></li>' . "\n";
65 } 65 }
66 } 66 }
67 67
diff --git a/src/view/ViewBuilder.php b/src/view/ViewBuilder.php
index acac972..2e2fea6 100644
--- a/src/view/ViewBuilder.php
+++ b/src/view/ViewBuilder.php
@@ -9,8 +9,10 @@ use App\Entity\Node;
9 9
10class ViewBuilder extends AbstractBuilder 10class ViewBuilder extends AbstractBuilder
11{ 11{
12 static public Node $root_node;
12 public function __construct(Node $root_node) 13 public function __construct(Node $root_node)
13 { 14 {
15 self::$root_node = $root_node;
14 $this->useChildrenBuilder($root_node); 16 $this->useChildrenBuilder($root_node);
15 } 17 }
16} 18}