diff options
author | polo <ordipolo@gmx.fr> | 2025-04-29 00:27:06 +0200 |
---|---|---|
committer | polo <ordipolo@gmx.fr> | 2025-04-29 00:27:06 +0200 |
commit | 5fc1a655e0271b583f3caa009524ea9d99a8bd3e (patch) | |
tree | 6af87a085a403dbf123907d26dfde7eed1765da4 | |
parent | 962d315ec0c99974df3dc2261bf94c54ca8cdbdd (diff) | |
download | cms-5fc1a655e0271b583f3caa009524ea9d99a8bd3e.zip |
page menu et chemins, partie4
-rw-r--r-- | public/css/foot.css | 15 | ||||
-rw-r--r-- | public/css/menu.css | 64 | ||||
-rw-r--r-- | public/js/menu.js | 11 | ||||
-rw-r--r-- | src/controller/post.php | 84 | ||||
-rw-r--r-- | src/view/FooterBuilder.php | 2 | ||||
-rw-r--r-- | src/view/MenuBuilder.php | 25 | ||||
-rw-r--r-- | src/view/templates/menu.php | 43 |
7 files changed, 138 insertions, 106 deletions
diff --git a/public/css/foot.css b/public/css/foot.css index 91f67ab..038d33b 100644 --- a/public/css/foot.css +++ b/public/css/foot.css | |||
@@ -6,6 +6,7 @@ footer | |||
6 | background-color: #B7E9FE; | 6 | background-color: #B7E9FE; |
7 | /*width: 1200px;*/ | 7 | /*width: 1200px;*/ |
8 | margin: auto; | 8 | margin: auto; |
9 | padding: 0 20px; | ||
9 | 10 | ||
10 | } | 11 | } |
11 | footer > div | 12 | footer > div |
@@ -72,6 +73,20 @@ footer > div | |||
72 | { | 73 | { |
73 | max-width: 288px; | 74 | max-width: 288px; |
74 | } | 75 | } |
76 | @media screen and (max-width: 1000px) | ||
77 | { | ||
78 | .footer .contact | ||
79 | { | ||
80 | width: 70px; | ||
81 | } | ||
82 | } | ||
83 | @media screen and (max-width: 800px) | ||
84 | { | ||
85 | footer > div | ||
86 | { | ||
87 | flex-direction: column; | ||
88 | } | ||
89 | } | ||
75 | 90 | ||
76 | .breadcrumb a | 91 | .breadcrumb a |
77 | { | 92 | { |
diff --git a/public/css/menu.css b/public/css/menu.css index 5016610..a338666 100644 --- a/public/css/menu.css +++ b/public/css/menu.css | |||
@@ -8,32 +8,56 @@ | |||
8 | { | 8 | { |
9 | margin-left: 29px; | 9 | margin-left: 29px; |
10 | } | 10 | } |
11 | .menu .new_page_button | ||
12 | { | ||
13 | background-color: white; | ||
14 | padding: 10px; | ||
15 | } | ||
11 | .menu img | 16 | .menu img |
12 | { | 17 | { |
13 | width: 20px; | 18 | width: 20px; |
14 | vertical-align: middle; | ||
15 | } | 19 | } |
16 | .menu form | 20 | /*.menu form |
17 | { | 21 | { |
18 | display: inline; | 22 | display: inline; |
23 | }*/ | ||
24 | .menu p | ||
25 | { | ||
26 | margin: 5px; | ||
19 | } | 27 | } |
20 | 28 | ||
21 | /* explications pour l'utiisateur */ | 29 | /* explications pour l'utilisateur */ |
22 | .menu aside | 30 | .menu aside |
23 | { | 31 | { |
24 | display: flex; | ||
25 | flex-wrap: wrap; | ||
26 | background-color: white; | 32 | background-color: white; |
27 | padding: 10px; | 33 | padding: 10px; |
34 | margin-top: 10px; | ||
28 | } | 35 | } |
29 | .menu aside p | 36 | .menu aside .controls_explanations |
37 | { | ||
38 | display: flex; | ||
39 | flex-wrap: wrap; | ||
40 | } | ||
41 | .menu aside .controls_explanations p | ||
30 | { | 42 | { |
31 | margin: 5px; | ||
32 | font-size: smaller; | 43 | font-size: smaller; |
33 | } | 44 | } |
45 | .menu aside img | ||
46 | { | ||
47 | vertical-align: bottom; | ||
48 | } | ||
34 | .menu aside input | 49 | .menu aside input |
35 | { | 50 | { |
36 | pointer-events: none; /* case non clicable, sauf action au clavier... */ | 51 | pointer-events: none; /* case non clicable, sauf action au clavier... */ |
52 | vertical-align: bottom; | ||
53 | } | ||
54 | .menu #location, .menu input[type=submit] | ||
55 | { | ||
56 | color: #ff1d04; | ||
57 | font-size: medium; | ||
58 | border-radius: 4px; | ||
59 | background-color: white; | ||
60 | border: lightgrey 2px outset; | ||
37 | } | 61 | } |
38 | 62 | ||
39 | .menu button | 63 | .menu button |
@@ -54,7 +78,7 @@ input | |||
54 | vertical-align: middle; | 78 | vertical-align: middle; |
55 | border: 2px #e3f3ff solid; | 79 | border: 2px #e3f3ff solid; |
56 | } | 80 | } |
57 | .move_entry_icon:hover | 81 | .menu #location:hover, .menu input[type=submit]:hover, .move_entry_icon:hover |
58 | { | 82 | { |
59 | background-color: #ffff00; | 83 | background-color: #ffff00; |
60 | border-radius: 4px; | 84 | border-radius: 4px; |
@@ -62,15 +86,35 @@ input | |||
62 | cursor: pointer; | 86 | cursor: pointer; |
63 | } | 87 | } |
64 | 88 | ||
65 | .menu .new_entry_buttons | 89 | .menu form |
90 | { | ||
91 | padding: 10px; | ||
92 | background-color: #f0f0f0f0; | ||
93 | } | ||
94 | .menu .url_form_zone | ||
66 | { | 95 | { |
67 | background-color: white; | 96 | background-color: white; |
68 | padding: 10px; | 97 | padding: 10px; |
69 | margin-top: 10px; | 98 | margin-top: 10px; |
70 | } | 99 | } |
71 | .menu .new_entry_buttons p | 100 | /*.menu .url_form_zone div |
101 | { | ||
102 | display: flex; | ||
103 | }*/ | ||
104 | .menu .url_form_zone label | ||
105 | { | ||
106 | text-wrap: nowrap; | ||
107 | margin-right: 5px; | ||
108 | } | ||
109 | .menu .url_form_zone #url_input | ||
110 | { | ||
111 | width: 100%; | ||
112 | } | ||
113 | .menu .url_form_zone p | ||
72 | { | 114 | { |
73 | margin: 5px; | 115 | margin: 5px; |
116 | display: flex; | ||
117 | align-items: center; | ||
74 | } | 118 | } |
75 | 119 | ||
76 | @media screen and (min-width: 80rem) { | 120 | @media screen and (min-width: 80rem) { |
diff --git a/public/js/menu.js b/public/js/menu.js index a864597..ac6d35e 100644 --- a/public/js/menu.js +++ b/public/js/menu.js | |||
@@ -237,4 +237,15 @@ function checkMenuEntry(page_id){ | |||
237 | .catch(error => { | 237 | .catch(error => { |
238 | console.error('Erreur:', error); | 238 | console.error('Erreur:', error); |
239 | }); | 239 | }); |
240 | } | ||
241 | |||
242 | |||
243 | function editUrlEntry(page_id){ | ||
244 | const selected_div = document.getElementById(page_id); | ||
245 | console.log(selected_div.id); | ||
246 | } | ||
247 | |||
248 | function deleteUrlEntry(page_id){ | ||
249 | const selected_div = document.getElementById(page_id); | ||
250 | console.log(selected_div.id); | ||
240 | } \ No newline at end of file | 251 | } \ No newline at end of file |
diff --git a/src/controller/post.php b/src/controller/post.php index 8924686..66de5a0 100644 --- a/src/controller/post.php +++ b/src/controller/post.php | |||
@@ -5,89 +5,13 @@ declare(strict_types=1); | |||
5 | 5 | ||
6 | if($_SERVER['REQUEST_METHOD'] === 'POST' && $_SESSION['admin'] === true) | 6 | if($_SERVER['REQUEST_METHOD'] === 'POST' && $_SESSION['admin'] === true) |
7 | { | 7 | { |
8 | /* -- requêtes non AJAX -- */ | 8 | /* -- formulaires HTML -- */ |
9 | // page Menu et chemin | ||
10 | /*if(isset($_POST['menu_edit_post']) && isset($_POST['id'])) | ||
11 | { | ||
12 | // <= flèche gauche: le parent devient le grand-parent position = position du parent + 1, recalculer les positions des enfants restants | ||
13 | if($_POST['menu_edit_post'] == 'move_one_level_up'){ | ||
14 | Director::$menu_data = new Menu($entityManager); | ||
15 | $page = Director::$menu_data->findPageById((int)$_POST['id']); | ||
16 | |||
17 | $parent = $page->getParent(); // peut être null | ||
18 | if($parent === null){ | ||
19 | // 1er niveau: ne rien faire | ||
20 | header('Location: ' . new URL(['page' => 'menu_chemins'])); | ||
21 | die; | ||
22 | } | ||
23 | else{ | ||
24 | $page->setPosition($parent->getPosition() + 1); // nouvelle position | ||
25 | |||
26 | // 2ème niveau: le parent devient $menu_data, puis null après tri | ||
27 | if($parent->getParent() === null){ | ||
28 | // connexion dans les deux sens | ||
29 | $page->setParent(Director::$menu_data); // => pour la persistance | ||
30 | Director::$menu_data->addChild($page); // => pour sortChildren | ||
31 | |||
32 | //Director::$menu_data->sortChildren(true); // positions décaléees des nouveaux petits frères | ||
33 | $page->getParent()->sortChildren(true); // positions décaléees des nouveaux petits frères | ||
34 | |||
35 | $page->setParent(null); | ||
36 | } | ||
37 | // 3ème niveau et plus | ||
38 | else{ | ||
39 | $page->setParent($parent->getParent()); // nouveau parent | ||
40 | $page->getParent()->sortChildren(true); // positions décaléees des nouveaux petits frères | ||
41 | } | ||
42 | //$parent->sortChildren(true); // positions des enfants restants, inutile si la fonction est récursive? | ||
43 | echo $page->getPosition(); | ||
44 | //die; | ||
45 | } | ||
46 | $entityManager->flush(); | ||
47 | |||
48 | header('Location: ' . new URL(['page' => 'menu_chemins'])); | ||
49 | die; | ||
50 | } | ||
51 | // => flèche droite: l'élément précédent devient le parent, position = nombre d'éléments de la fraterie + 1 | ||
52 | elseif($_POST['menu_edit_post'] == 'move_one_level_down') | ||
53 | { | ||
54 | Director::$menu_data = new Menu($entityManager); | ||
55 | $page = Director::$menu_data->findPageById((int)$_POST['id']); | ||
56 | |||
57 | $parent = $page->getParent(); // peut être null | ||
58 | if($parent == null){ | ||
59 | $parent = Director::$menu_data; | ||
60 | } | ||
61 | |||
62 | $parent->sortChildren(true); // trie et réindexe par sécurité: 1, 2, 3... | ||
63 | if($page->getPosition() > 1){ | ||
64 | foreach($parent->getChildren() as $child){ | ||
65 | echo $child->getPageName(); | ||
66 | if($child->getPosition() === $page->getPosition() - 1){ | ||
67 | $page->setParent($child); | ||
68 | break; | ||
69 | } | ||
70 | } | ||
71 | $page->setPosition(count($page->getParent()->getChildren()) + 1); | ||
72 | } | ||
73 | $entityManager->flush(); | ||
74 | |||
75 | header('Location: ' . new URL(['page' => 'menu_chemins'])); | ||
76 | die; | ||
77 | } | ||
78 | else{ | ||
79 | // you talking to me? | ||
80 | die; | ||
81 | } | ||
82 | }*/ | ||
83 | |||
84 | /* -- requêtes AJAX -- */ | ||
85 | require '../src/controller/ajax.php'; | ||
86 | |||
87 | // formulaires HTML | ||
88 | /*if(isset($_POST['from']) // page d'où vient la requête | 9 | /*if(isset($_POST['from']) // page d'où vient la requête |
89 | && isset($_POST)) // données | 10 | && isset($_POST)) // données |
90 | { | 11 | { |
91 | echo "requête envoyée en validant un formulaire"; | 12 | echo "requête envoyée en validant un formulaire"; |
92 | }*/ | 13 | }*/ |
14 | |||
15 | /* -- requêtes AJAX -- */ | ||
16 | require '../src/controller/ajax.php'; | ||
93 | } | 17 | } |
diff --git a/src/view/FooterBuilder.php b/src/view/FooterBuilder.php index 5a7748f..7abdb90 100644 --- a/src/view/FooterBuilder.php +++ b/src/view/FooterBuilder.php | |||
@@ -28,7 +28,7 @@ class FooterBuilder extends AbstractBuilder | |||
28 | $div_admin = 'logged_in'; | 28 | $div_admin = 'logged_in'; |
29 | $empty_admin_zone = 'empty_admin_zone'; | 29 | $empty_admin_zone = 'empty_admin_zone'; |
30 | $link_edit_page = new URL(['page' => CURRENT_PAGE, 'action' => 'modif_page']); | 30 | $link_edit_page = new URL(['page' => CURRENT_PAGE, 'action' => 'modif_page']); |
31 | $link_new_page = new URL(['from' => CURRENT_PAGE, 'page' => 'nouvelle_page']); | 31 | $link_new_page = new URL(['page' => 'nouvelle_page']); |
32 | $link_change_paths = new URL(['page' => 'menu_chemins']); | 32 | $link_change_paths = new URL(['page' => 'menu_chemins']); |
33 | 33 | ||
34 | $link_change_password = new URL(['from' => CURRENT_PAGE, 'action' => 'modif_mdp']); | 34 | $link_change_password = new URL(['from' => CURRENT_PAGE, 'action' => 'modif_mdp']); |
diff --git a/src/view/MenuBuilder.php b/src/view/MenuBuilder.php index 42c9273..5331c08 100644 --- a/src/view/MenuBuilder.php +++ b/src/view/MenuBuilder.php | |||
@@ -9,6 +9,7 @@ use App\Entity\Page; | |||
9 | class MenuBuilder extends AbstractBuilder | 9 | class MenuBuilder extends AbstractBuilder |
10 | { | 10 | { |
11 | //private int $margin_left_multiplier = 29; | 11 | //private int $margin_left_multiplier = 29; |
12 | private string $options = ''; | ||
12 | 13 | ||
13 | public function __construct(Node $node = null, bool $template = true) | 14 | public function __construct(Node $node = null, bool $template = true) |
14 | { | 15 | { |
@@ -23,7 +24,11 @@ class MenuBuilder extends AbstractBuilder | |||
23 | }*/ | 24 | }*/ |
24 | 25 | ||
25 | if($_SESSION['admin']){ | 26 | if($_SESSION['admin']){ |
26 | $this->unfoldMenu(Director::$menu_data/*, 0 - $this->margin_left_multiplier*/); | 27 | $this->unfoldMenu(Director::$menu_data); |
28 | |||
29 | if($template){ | ||
30 | $this->unfoldOptions(Director::$menu_data); | ||
31 | } | ||
27 | } | 32 | } |
28 | else{ | 33 | else{ |
29 | header('Location: ' . new URL); | 34 | header('Location: ' . new URL); |
@@ -39,11 +44,11 @@ class MenuBuilder extends AbstractBuilder | |||
39 | } | 44 | } |
40 | } | 45 | } |
41 | 46 | ||
42 | private function unfoldMenu(Page $menu): void | 47 | private function unfoldMenu(Page $page): void |
43 | { | 48 | { |
44 | $this->html .= '<div class="level">' . "\n"; | 49 | $this->html .= '<div class="level">' . "\n"; |
45 | 50 | ||
46 | foreach($menu->getChildren() as $entry) | 51 | foreach($page->getChildren() as $entry) |
47 | { | 52 | { |
48 | $checked = $entry->isHidden() ? '' : 'checked'; | 53 | $checked = $entry->isHidden() ? '' : 'checked'; |
49 | $this->html .= '<div id="' . $entry->getId() . '" class="menu_edit_entry"> | 54 | $this->html .= '<div id="' . $entry->getId() . '" class="menu_edit_entry"> |
@@ -57,9 +62,9 @@ class MenuBuilder extends AbstractBuilder | |||
57 | <button>' . $entry->getPageName() . '</button>'; | 62 | <button>' . $entry->getPageName() . '</button>'; |
58 | 63 | ||
59 | if(str_starts_with($entry->getEndOfPath(), 'http')){ | 64 | if(str_starts_with($entry->getEndOfPath(), 'http')){ |
60 | $this->html .= '<span id="edit-i..."><img class="move_entry_icon" src="assets/edit.svg" onclick="openEditor(\'i...\')"></span> | 65 | $this->html .= '<span id="edit-i..."><img class="move_entry_icon" src="assets/edit.svg" onclick="editUrlEntry(' . $entry->getId() . ')"></span> |
61 | <i class="url">' . $entry->getEndOfPath() . '</i> | 66 | <i class="url">' . $entry->getEndOfPath() . '</i> |
62 | <span id="delete-i..."><img class="move_entry_icon" src="assets/delete-bin.svg" onclick="delete(\'i...\')"></span>'; | 67 | <span id="delete-i..."><img class="move_entry_icon" src="assets/delete-bin.svg" onclick="deleteUrlEntry(' . $entry->getId() . ')"></span>'; |
63 | } | 68 | } |
64 | else{ | 69 | else{ |
65 | $this->html .= '<i class="path">' . $entry->getPagePath() . '</i>'; | 70 | $this->html .= '<i class="path">' . $entry->getPagePath() . '</i>'; |
@@ -72,4 +77,14 @@ class MenuBuilder extends AbstractBuilder | |||
72 | } | 77 | } |
73 | $this->html .= "</div>\n"; | 78 | $this->html .= "</div>\n"; |
74 | } | 79 | } |
80 | |||
81 | private function unfoldOptions(Page $page): void | ||
82 | { | ||
83 | foreach($page->getChildren() as $entry){ | ||
84 | $this->options .= '<option value="' . $entry->getId() . '">' . $entry->getPageName() . "</options>\n"; | ||
85 | if(count($entry->getChildren()) > 0){ | ||
86 | $this->unfoldOptions($entry); | ||
87 | } | ||
88 | } | ||
89 | } | ||
75 | } \ No newline at end of file | 90 | } \ No newline at end of file |
diff --git a/src/view/templates/menu.php b/src/view/templates/menu.php index 1414ab0..49df4e0 100644 --- a/src/view/templates/menu.php +++ b/src/view/templates/menu.php | |||
@@ -1,18 +1,41 @@ | |||
1 | <section class="menu"> | 1 | <section class="menu"> |
2 | <h3>Menu et chemins</h3> | 2 | <h3>Menu et chemins</h3> |
3 | <div class="new_page_button"> | ||
4 | <p >Créer une <a href="<?= new URL(['page' => 'nouvelle_page']) ?>"><button style="color: #ff1d04;">Nouvelle page</button></a>.</p> | ||
5 | </div> | ||
6 | <div class="url_form_zone"> | ||
7 | <p>Ajouter au menu un lien vers un site web quelconque avec le formulaire ci-dessous:</p> | ||
8 | <form method="post" action="<?= new URL(['from' => 'menu_chemins']) ?>"> | ||
9 | <p> | ||
10 | <label for="url_input">Adresse URL:</label> | ||
11 | <input id="url_input" type="url" name="url_input"> | ||
12 | </p> | ||
13 | <p> | ||
14 | <label for="label_input">Nom:</label> | ||
15 | <input id="label_input" type="text" name="label_input"> | ||
16 | </p> | ||
17 | <p> | ||
18 | <label>Placer le lien juste après cette entrée:</label> | ||
19 | <select id="location" name="location"> | ||
20 | <?= $this->options ?> | ||
21 | </select> | ||
22 | </p> | ||
23 | <input type="submit" onclick="createUrlEntry()" value="Valider"> | ||
24 | </form> | ||
25 | </div> | ||
3 | <aside> | 26 | <aside> |
4 | <p><img src="assets/arrow-left.svg"> remonter dans l'arbre</p> | 27 | <p>Modifier le menu:</p> |
5 | <p><img src="assets/arrow-right.svg"> devenir une branche de l'élément précédent</p> | 28 | <div class="controls_explanations"> |
6 | <p><img src="assets/arrow-up.svg"><img src="assets/arrow-down.svg"> déplacer la branche parmi celles de même niveau</p> | 29 | <p><img src="assets/arrow-left.svg"> remonter dans l'arbre</p> |
7 | <p><input type="checkbox" checked>afficher/cacher</p> | 30 | <p><img src="assets/arrow-right.svg"> devenir une branche de l'élément précédent</p> |
31 | <p><img src="assets/arrow-up.svg"><img src="assets/arrow-down.svg"> déplacer la branche parmi celles de même niveau</p> | ||
32 | <p><input type="checkbox" checked> afficher/cacher</p> | ||
33 | <p><img src="assets/edit.svg"> modifier un lien</p> | ||
34 | <p><img src="assets/delete-bin.svg"> supprimer un lien</p> | ||
35 | </div> | ||
8 | </aside> | 36 | </aside> |
9 | <div id="menu_edit_buttons"> | 37 | <div id="menu_edit_buttons"> |
10 | <?= $this->html ?> | 38 | <?= $this->html ?> |
11 | </div> | 39 | </div> |
12 | <div class="new_entry_buttons"> | 40 | |
13 | <p>Ajouter une nouvelle entrée dans le menu | ||
14 | <button id="new-i..." onclick="openEditor('i...')"><img class="action_icon" src="assets/edit.svg">avec une URL</button> | ||
15 | ?</p> | ||
16 | <p>... ou cliquer sur <span style="color: #ff1d04;">Nouvelle page</span><img src="assets/arrow-down.svg">dans la barre jaune</p> | ||
17 | </div> | ||
18 | </section> \ No newline at end of file | 41 | </section> \ No newline at end of file |