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