aboutsummaryrefslogtreecommitdiff
path: root/src/service/router.php
diff options
context:
space:
mode:
authorpolo <ordipolo@gmx.fr>2026-03-24 22:39:29 +0100
committerpolo <ordipolo@gmx.fr>2026-03-24 22:40:33 +0100
commit3b369122645b07b290f7fcc7bccb4787745cd5ea (patch)
tree3f9c2d1fbd5fe8b26162202e9b1e6cd5c8a940f6 /src/service/router.php
parenta70dee9b5021a137ae07041c38921553442b0c11 (diff)
downloadcms-3b369122645b07b290f7fcc7bccb4787745cd5ea.tar.gz
cms-3b369122645b07b290f7fcc7bccb4787745cd5ea.tar.bz2
cms-3b369122645b07b290f7fcc7bccb4787745cd5ea.zip
mode maintenance, optimisation moins de contrôles en mode run, dossier service et déplacement fichiers, sessions et entité User préparées à l'implémentation hypothétique des rôles, entité AppMetadata, meilleure sécurité de fillStartingDatabase
Diffstat (limited to 'src/service/router.php')
-rw-r--r--src/service/router.php384
1 files changed, 384 insertions, 0 deletions
diff --git a/src/service/router.php b/src/service/router.php
new file mode 100644
index 0000000..fc6b028
--- /dev/null
+++ b/src/service/router.php
@@ -0,0 +1,384 @@
1<?php
2// src/service/router.php
3//
4/* fonctionnement:
5=> 1er test, méthode http: GET, POST ou autre chose
6=> 2ème test, type de contenu (méthode POST uniquement):
7"application/x-www-form-urlencoded" = formulaire
8"application/json" = requête AJAX avec fetch()
9"multipart/form-data" = upload d'image par tinymce
10$_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest' requête AJAX xhs, non utilisée
11=> 3ème test, comme le 2ème test mais uniquement si IS_ADMIN est vrai
12*/
13
14declare(strict_types=1);
15
16if($request->getMethod() === 'GET'){
17 // table "user" vide
18 if(!UserController::existUsers($entityManager)){
19 require AbstractBuilder::VIEWS_PATH . 'user_create.php';
20 die;
21 }
22
23 // bouton déconnexion (méthode GET parce que l'utilisateur ne modifie plus de données à partir de là)
24 if($request->query->has('action') && $request->query->get('action') === 'deconnection'){
25 UserController::disconnect($entityManager);
26 }
27
28 // articles suivants
29 if($request->query->has('fetch') && $request->query->get('fetch') === 'next_articles'){
30 ArticleController::fetch($entityManager, $request);
31 }
32
33 // données du calendrier
34 // création du calendrier et changement de dates affichées (boutons flèches mais pas changement de vue)
35 if($request->query->has('action') && $request->query->get('action') === 'get_events'
36 && $request->query->has('start') && $request->query->has('end') && empty($request->getPayload()->all())) // getPayload ne récupère pas que des POST
37 {
38 CalendarController::getData($entityManager);
39 }
40
41 // pages interdites
42 if(!IS_ADMIN && in_array(CURRENT_PAGE, ['menu_paths', 'new_page', 'user_edit', 'emails'])){
43 header('Location: ' . new URL);
44 die;
45 }
46
47 if(IS_ADMIN === true){
48 // ...
49 }
50
51 // construction d'une page
52 $response = (new ViewController)->buildView($entityManager, $request); // utilise Model
53 // parenthèses nécéssaires autour de l'instanciation pour PHP < 8.4
54}
55
56
57elseif($request->getMethod() === 'POST'){
58 /* -- contrôleurs appellables par tout le monde -- */
59
60 // table "user" vide
61 if(!UserController::existUsers($entityManager)){
62 UserController::createAdminUser($entityManager);
63 }
64
65 // requêtes JSON avec fetch()
66 if($_SERVER['CONTENT_TYPE'] === 'application/json')
67 {
68 $json = json_decode($request->getContent(), true); // = json_decode(file_get_contents('php://input'), true);
69
70 if(isset($_GET['action']))
71 {
72 // formulaire de contact
73 if($_GET['action'] === 'send_email'){
74 ContactFormController::sendVisitorEmail($entityManager, $json);
75 }
76 }
77 }
78
79 // envoi formulaire HTML
80 elseif($_SERVER['CONTENT_TYPE'] === 'application/x-www-form-urlencoded'){
81 // tentative de connexion
82 if($request->query->has('action') && $request->query->get('action') === 'connection'){
83 //$response =
84 UserController::connect($entityManager);
85 }
86 }
87
88
89 if(IS_ADMIN === true)
90 {
91 /* -- requêtes AJAX -- */
92
93 // requêtes JSON avec fetch()
94 if($_SERVER['CONTENT_TYPE'] === 'application/json')
95 {
96 $json = json_decode($request->getContent(), true); // = json_decode(file_get_contents('php://input'), true);
97
98 if($request->query->has('action'))
99 {
100 /* -- manipulation des articles -- */
101 if($_GET['action'] === 'editor_submit' && isset($json['id']) && isset($json['content'])){
102 ArticleController::editorSubmit($entityManager, $json);
103 }
104 elseif($_GET['action'] === 'delete_article' && isset($json['id'])){
105 $response = ArticleController::deleteArticle($entityManager, $json); // version AJAX
106 }
107 elseif($_GET['action'] === 'switch_positions' && isset($json['id1']) && isset($json['id2'])){
108 ArticleController::switchPositions($entityManager, $json);
109 }
110 elseif($_GET['action'] === 'date_submit' && isset($json['id']) && isset($json['date'])){
111 ArticleController::dateSubmit($entityManager, $json);
112 }
113
114 /* -- bloc Formulaire -- */
115 elseif($_GET['action'] === 'keep_emails'){
116 ContactFormController::keepEmails($entityManager, $json);
117 }
118 elseif($_GET['action'] === 'set_retention_period'){
119 ContactFormController::setEmailsRetentionPeriod($entityManager, $json);
120 }
121 elseif($_GET['action'] === 'set_email_param'){
122 ContactFormController::setEmailParam($entityManager, $json);
123 }
124 elseif($_GET['action'] === 'test_email'){
125 ContactFormController::sendTestEmail($entityManager, $json);
126 }
127
128 /* -- page emails -- */
129 elseif($_GET['action'] === 'delete_email'){
130 ContactFormController::deleteEmail($entityManager, $json);
131 }
132 elseif($_GET['action'] === 'toggle_sensitive_email'){
133 ContactFormController::toggleSensitiveEmail($entityManager, $json);
134 }
135
136 /* -- upload d'image dans tinymce par copier-coller -- */
137 // collage de HTML contenant une ou plusieurs balises <img>
138 elseif($request->query->get('action') === 'upload_image_url'){
139 ImageUploadController::uploadImageHtml();
140 }
141 // collage d'une image (code base64 dans le presse-papier) non encapsulée dans du HTML
142 elseif($request->query->get('action') === 'upload_image_base64'){
143 ImageUploadController::uploadImageBase64();
144 }
145
146
147 /* -- requêtes spécifiques au calendrier -- */
148 elseif($request->query->get('action') === 'new_event'){
149 CalendarController::newEvent($json, $entityManager);
150 }
151 elseif($request->query->get('action') === 'update_event'){
152 CalendarController::updateEvent($json, $entityManager);
153 }
154 elseif($request->query->get('action') === 'remove_event'){
155 CalendarController::removeEvent($json, $entityManager);
156 }
157 else{
158 echo json_encode(['success' => false]);
159 die;
160 }
161 }
162
163 /* -- site entier (header, footer, favicon) -- */
164 elseif($request->query->has('head_foot_text')){
165 HeadFootController::setTextData($entityManager, $request->query->get('head_foot_text'), $json);
166 }
167 elseif($request->query->has('head_foot_social_check')){
168 HeadFootController::displaySocialNetwork($entityManager, $request->query->get('head_foot_social_check'), $json);
169 }
170
171 /* -- page Menu et chemins -- */
172 elseif(isset($_GET['menu_edit']))
173 {
174 // ne suit pas la règle, faire ça dans un contrôleur?
175 Model::$menu = new Menu($entityManager); // récupération des données
176
177 // flèche gauche <=: position = position du parent + 1, parent = grand-parent, recalculer les positions
178 if($_GET['menu_edit'] === 'move_one_level_up' && isset($json['id'])){
179 MenuAndPathsController::MoveOneLevelUp($entityManager, $json);
180 }
181 // flèche droite =>: position = nombre d'éléments de la fraterie + 1, l'élément précédent devient le parent
182 elseif($_GET['menu_edit'] === 'move_one_level_down' && isset($json['id'])){
183 MenuAndPathsController::MoveOneLevelDown($entityManager, $json);
184 }
185 elseif($_GET['menu_edit'] === 'switch_positions' && isset($json['id1']) && isset($json['id2'])){
186 MenuAndPathsController::switchPositions($entityManager, $json);
187 }
188 elseif($_GET['menu_edit'] === 'display_in_menu' && isset($json['id']) && isset($json['checked'])){
189 MenuAndPathsController::displayInMenu($entityManager, $json);
190 }
191 elseif($_GET['menu_edit'] === 'url_edit' && isset($json['id']) && isset($json['field']) && isset($json['input_data'])){
192 MenuAndPathsController::editUrl($entityManager, $json);
193 }
194 }
195
196 /* -- mode Modification d'une page -- */
197 // partie "page"
198 elseif(isset($_GET['page_edit']))
199 {
200 // titre de la page
201 if($_GET['page_edit'] === 'page_title'){
202 PageManagementController::setPageTitle($entityManager, $json);
203 }
204 // description dans les métadonnées
205 elseif($_GET['page_edit'] === 'page_description'){
206 PageManagementController::setPageDescription($entityManager, $json);
207 }
208 }
209
210 // partie "blocs"
211 elseif($request->query->has('bloc_edit'))
212 {
213 if($request->query->get('bloc_edit') === 'rename_page_bloc'){
214 PageManagementController::renameBloc($entityManager, $json);
215 }
216 elseif($request->query->get('bloc_edit') === 'switch_blocs_positions'){
217 PageManagementController::SwitchBlocsPositions($entityManager, $json);
218 }
219 elseif($request->query->get('bloc_edit') === 'change_articles_order'){
220 PageManagementController::changeArticlesOrder($entityManager, $json);
221 }
222 elseif($request->query->get('bloc_edit') === 'change_presentation'){
223 PageManagementController::changePresentation($entityManager, $json);
224 }
225 elseif($request->query->get('bloc_edit') === 'change_cols_min_width'){
226 PageManagementController::changeColsMinWidth($entityManager, $json);
227 }
228 elseif($request->query->get('bloc_edit') === 'change_pagination_limit'){
229 PageManagementController::changePaginationLimit($entityManager, $json);
230 }
231 }
232 }
233
234 // upload avec FormData
235 elseif(strpos($_SERVER['CONTENT_TYPE'], 'multipart/form-data') !== false)
236 {
237 // dans tinymce avec le plugin (bouton "insérer une image" de l'éditeur ou glisser-déposer)
238 if($request->query->has('action') && $request->query->get('action') === 'upload_image_tinymce'){
239 ImageUploadController::imageUploadTinyMce();
240 }
241 // dans tinymce, des quatre méthodes: bouton "link", drag & drop, html, base64
242 elseif($request->query->has('action') && $request->query->get('action') === 'upload_file_tinymce'){
243 FileUploadController::fileUploadTinyMce();
244 }
245 elseif($request->query->has('head_foot_image')){
246 HeadFootController::uploadAsset($entityManager, $request->query->get('head_foot_image'));
247 }
248 }
249
250 // requêtes XMLHttpRequest
251 elseif(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest')
252 {
253 //echo "requête XMLHttpRequest reçue par le serveur";
254 echo json_encode(['success' => false]); // noyer le poisson en laissant penser que le site gère les requêtes XHR
255 die;
256 }
257
258 /* -- envoi formulaire HTML -- */
259 elseif($_SERVER['CONTENT_TYPE'] === 'application/x-www-form-urlencoded')
260 {
261 if($request->query->has('action') && $request->query->get('action') === 'delete_article' && isset($_GET['id'])){
262 $response = ArticleController::deleteArticle($entityManager, $_GET); // version formulaire
263 }
264
265 /* -- nouvelle page -- */
266 elseif(isset($_POST['page_name']) && $_POST['page_name'] !== null
267 && isset($_POST['page_name_path']) && $_POST['page_name_path'] !== null
268 && isset($_POST['page_location']) && $_POST['page_location'] !== null
269 && isset($_POST['page_description']) && $_POST['page_description'] !== null
270 && isset($_POST['new_page_hidden']) && $_POST['new_page_hidden'] === '')
271 {
272 PageManagementController::newPage($entityManager, $_POST);
273 }
274
275 /* -- suppression d'une page -- */
276 elseif(isset($_POST['page_id']) && $_POST['page_id'] !== null
277 && isset($_POST['submit_hidden']) && $_POST['submit_hidden'] === '')
278 {
279 PageManagementController::deletePage($entityManager);
280 }
281
282
283 /* -- mode Modification d'une page -- */
284
285 // modification du chemins en snake_case
286 elseif(isset($_POST['page_menu_path']) && $_POST['page_menu_path'] !== null
287 && isset($_POST['page_id']) && $_POST['page_id'] !== null
288 && isset($_POST['page_name_path_hidden']) && $_POST['page_name_path_hidden'] === '')
289 {
290 PageManagementController::updatePageMenuPath($entityManager);
291 }
292 // ajout d'un bloc dans une page
293 elseif(isset($_POST['bloc_title']) && $_POST['bloc_title'] !== null
294 && isset($_POST['bloc_select']) && $_POST['bloc_select'] !== null
295 && isset($_POST['bloc_title_hidden']) && $_POST['bloc_title_hidden'] === '') // contrôle anti-robot avec input hidden
296 {
297 PageManagementController::addBloc($entityManager);
298 }
299 // suppression d'un bloc de page
300 elseif(isset($_POST['delete_bloc_id']) && $_POST['delete_bloc_id'] !== null
301 && isset($_POST['delete_bloc_hidden']) && $_POST['delete_bloc_hidden'] === '') // contrôle anti-robot avec input hidden
302 {
303 PageManagementController::deleteBloc($entityManager);
304 }
305
306
307 /* -- page Menu et chemins -- */
308
309 // création d'une entrée de menu avec une URL
310 elseif(isset($_POST["label_input"]) && isset($_POST["url_input"]) && isset($_POST["location"])){
311 MenuAndPathsController::newUrlMenuEntry($entityManager);
312 }
313 // suppression d'une entrée de menu avec une URL
314 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
315 MenuAndPathsController::deleteUrlMenuEntry($entityManager);
316 }
317
318
319 /* -- page Mon compte -- */
320 elseif($request->query->has('action') && $request->query->get('action') === 'update_username')
321 {
322 UserController::updateUsername($entityManager);
323 }
324 elseif($request->query->has('action') && $request->query->get('action') === 'update_password')
325 {
326 UserController::updatePassword($entityManager);
327 }
328
329 // redirection page d'accueil
330 else{
331 header("Location: " . new URL(['error' => 'paramètres inconnus']));
332 die;
333 }
334 }
335 // POST admin ne matchant pas
336 else{
337 echo json_encode(['success' => false]);
338 die;
339 }
340 }
341 // POST non admin ne matchant pas
342 else{
343 echo json_encode(['success' => false]);
344 die;
345 }
346}
347
348// méthode inconnue
349else{
350 header("Location: " . new URL(['error' => 'tu fais quoi là mec?']));
351 die;
352}
353
354
355
356/* -- utilisation de la réponse -- */
357if(isset($response)){
358 // 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
359 if($request->isMethod('GET') && $response->getStatusCode() == 302){ // 302 redirection temporaire
360 header('Location: ' . new URL(['page' => $_GET['from'] ?? '']));
361 }
362 // redirection après traitement de formulaires HTTP
363 elseif($request->getMethod() === 'POST' && $_SERVER['CONTENT_TYPE'] === 'application/x-www-form-urlencoded'){
364 $response_data = json_decode(($response)->getContent(), true);
365 $url = new URL(['page' => $_GET['from'] ?? '']);
366 $url->addParams(['success' => $response_data['success'], 'message' => $response_data['message']]);
367 header('Location: ' . $url);
368 }
369 // affichage d'une page OU requête AJAX
370 else{
371 $response->send();
372 }
373}
374// pas utilisation de RESPONSE (cas destiné à disparaître)
375else{
376 if($request->getMethod() === 'POST' && $_SERVER['CONTENT_TYPE'] === 'application/x-www-form-urlencoded'){
377 header("Location: " . new URL(['error' => 'erreur côté serveur']));
378 }
379 else{
380 http_response_code(500);
381 echo "erreur côté serveur";
382 }
383}
384//die; // inutile \ No newline at end of file