aboutsummaryrefslogtreecommitdiff
path: root/src/Controller/MenuAndPathsController.php
diff options
context:
space:
mode:
Diffstat (limited to 'src/Controller/MenuAndPathsController.php')
-rw-r--r--src/Controller/MenuAndPathsController.php226
1 files changed, 226 insertions, 0 deletions
diff --git a/src/Controller/MenuAndPathsController.php b/src/Controller/MenuAndPathsController.php
new file mode 100644
index 0000000..1916f06
--- /dev/null
+++ b/src/Controller/MenuAndPathsController.php
@@ -0,0 +1,226 @@
1<?php
2// src/Controller/MenuAndPathsController.php
3
4declare(strict_types=1);
5
6namespace App\Controller;
7
8use Doctrine\ORM\EntityManager;
9use Symfony\Component\HttpFoundation\JsonResponse;
10use Symfony\Component\HttpFoundation\RedirectResponse;
11use App\Entity\Page;
12use App\Model\Menu;
13use App\Model\Model;
14use App\Service\URL;
15use App\View\NavBuilder;
16use App\View\MenuBuilder;
17
18class MenuAndPathsController
19{
20 static public function newUrlMenuEntry(EntityManager $entityManager): RedirectResponse
21 {
22 Model::$menu = new Menu($entityManager);
23 $previous_page = Model::$menu->findPageById((int)$_POST["location"]); // (int) à cause de declare(strict_types=1);
24 $parent = $previous_page->getParent();
25
26 $url_input = trim($_POST["url_input"]); // faire htmlspecialchars à l'affichage
27 if(!filter_var($url_input, FILTER_VALIDATE_URL) || !str_starts_with($url_input, 'http')){
28 // utiliser une flash error
29 return new RedirectResponse((string)new URL(['page' => $_GET['from'], 'error' => 'invalide_url']));
30 }
31
32 $page = new Page(
33 trim(htmlspecialchars($_POST["label_input"])),
34 $url_input, '',
35 true, true, false,
36 $previous_page->getPosition(),
37 $parent); // peut et DOIT être null si on est au 1er niveau
38
39 // on a donné à la nouvelle entrée la même position qu'à la précédente,
40 // addChild l'ajoute à la fin du tableau "children" puis on trie
41 // exemple avec 2 comme position demandée: 1 2 3 4 2 devient 1 2 3 4 5 et la nouvelle entrée sera en 3è position
42 if(!$parent){
43 $parent = Model::$menu;
44 }
45 $parent->addChild($page); // true pour réindexer les positions en BDD
46 $parent->reindexPositions();
47
48 $entityManager->persist($page);
49 $entityManager->flush();
50 return new RedirectResponse((string)new URL(['page' => $_GET['from']]));
51 }
52
53 // on pourrait utiliser FormValidation ici
54 static public function editUrl(EntityManager $entityManager, array $json): JsonResponse
55 {
56 $url_data = trim($json['input_data']); // garder htmlspecialchars pour l'affichage
57 $page = $entityManager->find('App\Entity\Page', $json['id']);
58
59 if(!$page){
60 return new JsonResponse(['success' => false, 'message' => "id invalide"]);
61 }
62 elseif(!in_array($json['field'], ['url_name', 'url_content'])){
63 return new JsonResponse(['success' => false, 'message' => "champ invalide"]);
64 }
65 elseif($json['field'] === 'url_content' && (!filter_var($url_data, FILTER_VALIDATE_URL) || !str_starts_with($url_data, 'http'))){
66 return new JsonResponse(['success' => false, 'message' => "la chaîne envoyée n'est pas une URL valide"]);
67 }
68 else{
69 if($json['field'] === 'url_name'){
70 $page->setPageName($url_data);
71 }
72 elseif($json['field'] === 'url_content'){
73 $page->setEndOfPath($url_data);
74 }
75 $entityManager->flush();
76 return new JsonResponse(['success' => true, 'url_data' => $url_data]);
77 }
78 }
79
80 static public function deleteUrlMenuEntry(EntityManager $entityManager): RedirectResponse
81 {
82 Model::$menu = new Menu($entityManager);
83 $page = Model::$menu->findPageById((int)$_POST["delete"]);
84 $parent = $page->getParent();
85 if($parent == null){
86 $parent = Model::$menu;
87 }
88
89 $parent->removeChild($page); // suppression de $children avant de trier
90 $parent->reindexPositions();
91
92 $entityManager->remove($page); // suppression en BDD
93 $entityManager->flush();
94 return new RedirectResponse((string)new URL(['page' => $_GET['from']]));
95 }
96
97 static public function MoveOneLevelUp(EntityManager $entityManager, array $json): JsonResponse
98 {
99 $id = $json['id'];
100 $page = Model::$menu->findPageById((int)$id);
101
102 $parent = $page->getParent(); // peut être null
103 if($parent === null){
104 // 1er niveau: ne rien faire
105 return new JsonResponse(['success' => false, 'message' => 'nothing to do']);
106 }
107 // BDD
108 else{
109 $page->setPosition($parent->getPosition() + 1); // nouvelle position
110
111 // 2ème niveau: le parent devient $menu, puis null après tri
112 if($parent->getParent() === null){
113 // connexion dans les deux sens
114 $page->setParent(Model::$menu); // => pour la persistance
115
116 //Model::$menu->addChild($page); // => pour sortChildren
117 $page->getParent()->addChild($page); // => pour sortChildren
118 $page->getParent()->sortChildren(true); // positions décaléees des nouveaux petits frères
119 $page->setParent(null);
120
121 // affichage
122 $page->setPagePath($page->getEndOfPath());
123 $page->fillChildrenPagePath();
124 }
125 // 3ème niveau et plus
126 else{
127 $page->setParent($parent->getParent()); // nouveau parent
128 $page->getParent()->addChild($page); // => pour sortChildren
129 $page->getParent()->sortChildren(true); // positions décaléees des nouveaux petits frères
130 $page->fillChildrenPagePath($page->getParent()->getPagePath());
131 }
132 $entityManager->flush();
133
134 // affichage
135 $parent->removeChild($page);
136 $nav_builder = new NavBuilder();
137 $menu_builder = new MenuBuilder(null, false);
138 return new JsonResponse(['success' => true, 'nav' => $nav_builder->render(), 'menu_buttons' => $menu_builder->render()]);
139 }
140 }
141
142 static public function MoveOneLevelDown(EntityManager $entityManager, array $json): JsonResponse
143 {
144 $id = $json['id'];
145 $page = Model::$menu->findPageById((int)$id);
146
147 $parent = $page->getParent(); // peut être null
148 if($parent === null){
149 $parent = Model::$menu;
150 }
151
152 // BDD
153 $parent->sortChildren(true); // trie et réindexe par sécurité: 1, 2, 3...
154 if($page->getPosition() > 1){
155 foreach($parent->getChildren() as $child){
156 if($child->getPosition() === $page->getPosition() - 1){
157 // refus si $parent est une adresse, ça va casser le lien, exemple: index.php?page=chemin/http://un_site_web.fr/vers/ici
158 if(str_starts_with($child->getEndOfPath(), 'http')){
159 return new JsonResponse(['success' => false, 'error' => 'new_parent_is_a_link']);
160 }
161
162 $page->setParent($child);
163 break;
164 }
165 }
166 $page->setPosition(count($page->getParent()->getChildren()) + 1);
167 }
168 $entityManager->flush();
169
170 // affichage
171 $parent->removeChild($page);
172 $page->getParent()->addChild($page);
173 $page->fillChildrenPagePath($page->getParent()->getPagePath()); // variable non mappée $page_path
174 $nav_builder = new NavBuilder();
175 $menu_builder = new MenuBuilder(null, false);
176
177 return new JsonResponse(['success' => true, 'nav' => $nav_builder->render(), 'menu_buttons' => $menu_builder->render()]);
178 }
179
180 static public function SwitchPositions(EntityManager $entityManager, array $json): JsonResponse
181 {
182 $id1 = $json['id1'];
183 $id2 = $json['id2'];
184
185 // vérifier qu'ils ont le même parent
186 $page1 = Model::$menu->findPageById((int)$id1);
187 $page2 = Model::$menu->findPageById((int)$id2);
188
189 // double le contrôle fait en JS
190 if($page1->getParent() === $page2->getParent()) // comparaison stricte d'objet (même instance du parent?)
191 {
192 // inversion
193 $tmp = $page1->getPosition();
194 $page1->setPosition($page2->getPosition());
195 $page2->setPosition($tmp);
196 Model::$menu->sortChildren(true); // modifie tableau children
197 $entityManager->flush();
198
199 // nouveau menu
200 $nav_builder = new NavBuilder();
201 return new JsonResponse(['success' => true, 'nav' => $nav_builder->render()]);
202 }
203 else{
204 return new JsonResponse(['success' => false]);
205 }
206 }
207
208 static public function displayInMenu(EntityManager $entityManager, array $json): JsonResponse
209 {
210 $id = $json['id'];
211 $checked = $json['checked'];
212
213 $page = Model::$menu->findPageById((int)$id);
214 if($page->isHidden() === $checked){
215 $page->setHidden(!$checked);
216 $entityManager->flush();
217
218 // nouveau menu
219 $nav_builder = new NavBuilder();
220 return new JsonResponse(['success' => true, 'nav' => $nav_builder->render()]);
221 }
222 else{
223 return new JsonResponse(['success' => false]);
224 }
225 }
226} \ No newline at end of file