From efd79d15adef2a27347c25ebb19754e9937f9715 Mon Sep 17 00:00:00 2001 From: polo Date: Wed, 10 Sep 2025 01:02:36 +0200 Subject: =?UTF-8?q?modification=20d'une=20URL=20page=20Menu=20et=20chemin,?= =?UTF-8?q?=20htmlspecialchars=20sur=20les=20URL=20du=20menu=20=C3=A0=20l'?= =?UTF-8?q?affichage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/assets/save-nb.svg | 1 + public/assets/save.svg | 37 ++++++++++++ public/css/menu.css | 11 +++- public/js/menu.js | 94 +++++++++++++++++++++++++++---- src/controller/MenuAndPathsController.php | 30 +++++++++- src/router.php | 5 +- src/view/MenuBuilder.php | 30 ++++++---- src/view/NavBuilder.php | 2 +- src/view/templates/menu.php | 11 ++-- 9 files changed, 188 insertions(+), 33 deletions(-) create mode 100644 public/assets/save-nb.svg create mode 100644 public/assets/save.svg diff --git a/public/assets/save-nb.svg b/public/assets/save-nb.svg new file mode 100644 index 0000000..f7fe755 --- /dev/null +++ b/public/assets/save-nb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/save.svg b/public/assets/save.svg new file mode 100644 index 0000000..f2405a5 --- /dev/null +++ b/public/assets/save.svg @@ -0,0 +1,37 @@ + + + + + + diff --git a/public/css/menu.css b/public/css/menu.css index 62e6623..57d842a 100644 --- a/public/css/menu.css +++ b/public/css/menu.css @@ -70,7 +70,7 @@ vertical-align: middle; border: 2px transparent solid; } -.menu #location:hover, .menu input[type=submit]:hover, .move_entry_icon:hover +.menu #location:hover, .menu input[type=submit]:hover, .menu .move_entry_icon:hover { background-color: yellow; border-radius: 4px; @@ -106,8 +106,17 @@ { margin: 5px; display: flex; + flex-wrap: wrap; align-items: center; } +.menu .url +{ + text-wrap: nowrap; +} +.menu .url input[type=url] +{ + width: 50%; +} @media screen and (min-width: 80rem) { i{} diff --git a/public/js/menu.js b/public/js/menu.js index 8f1f326..ef58c42 100644 --- a/public/js/menu.js +++ b/public/js/menu.js @@ -122,7 +122,7 @@ function checkMenuEntry(page_id){ const checkbox = clicked_menu_entry.querySelector("input"); let color; - fetch('index.php?menu_edit=displayInMenu', { + fetch('index.php?menu_edit=display_in_menu', { method: 'POST', headers: { 'Content-Type': 'application/json' @@ -131,16 +131,14 @@ function checkMenuEntry(page_id){ }) .then(response => response.json()) .then(data => { - if(data.success) - { + if(data.success){ color = checkbox.checked ? "#ff1d04" : "grey"; clicked_menu_entry.querySelector("button").style.color = color; nav_zone.innerHTML = ''; nav_zone.insertAdjacentHTML('afterbegin', data.nav); } - else { - + else{ console.error('Échec de l\'inversion'); } }) @@ -149,13 +147,89 @@ function checkMenuEntry(page_id){ }); } - +// seul la modification des URL est possible pour l'instant, les noms des entrées de menu attendront function editUrlEntry(page_id){ - const selected_div = document.getElementById(page_id); - console.log(selected_div.id); + const parent_div = document.getElementById(page_id); + const url_input = parent_div.querySelector('.url').querySelector('input').value; + + fetch('index.php?menu_edit=edit_url_entry', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ id: page_id, url_input: url_input }) + }) + .then(response => response.json()) + .then(data => { + if(data.success){ + findParentByTagName(document.getElementById('m_' + page_id), 'a').href = data.url_input; // MAJ menu + toastNotify("Nouvelle adresse enregistrée avec succès") + } + else{ + toastNotify("Erreur rencontrée par le serveur, changements non pris en compte"); + console.error("Erreur rencontrée par le serveur, changements non pris en compte"); + } + }) + .catch(error => { + console.error('Erreur:', error); + }); } -function deleteUrlEntry(page_id){ + + +// code à recycler pour pouvoir modifier le nom de l'entrée de menu correspondant aux liens +/*function editUrlEntry(page_id){ + const parent_div = document.getElementById(page_id); + parent_div.querySelector('i').classList.add('hidden'); + parent_div.querySelector('.url').querySelector('input').classList.remove('hidden'); + parent_div.querySelector('#edit-i' + page_id).classList.add('hidden'); + parent_div.querySelector('#delete-i' + page_id).querySelector('input[type=image]').classList.add('hidden'); + parent_div.querySelector('#cancel-i' + page_id).querySelector('button').classList.remove('hidden'); + parent_div.querySelector('#submit-i' + page_id).querySelector('input[type=submit]').classList.remove('hidden'); +} +function cancelUrlEntry(page_id){ + const parent_div = document.getElementById(page_id); + parent_div.querySelector('.url').querySelector('input').value = parent_div.querySelector('i').textContent; // textContent (contrairement à innerHTML) ne transforme pas les & en entités HTML + closeUrlEntry(page_id, parent_div); +} +function submitUrlEntry(page_id){ + const parent_div = document.getElementById(page_id); + const url_input = parent_div.querySelector('.url').querySelector('input').value; + + fetch('index.php?menu_edit=edit_url_entry', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ id: page_id, url_input: url_input }) + }) + .then(response => response.json()) + .then(data => { + if(data.success){ + parent_div.querySelector('i').innerHTML = data.url_input; // MAJ + findParentByTagName(document.getElementById('m_' + page_id), 'a').href = data.url_input; // MAJ menu + closeUrlEntry(page_id, parent_div); + } + else{ + toastNotify("Erreur rencontrée par le serveur, changements non pris en compte"); + console.error("Erreur rencontrée par le serveur, changements non pris en compte"); + } + }) + .catch(error => { + console.error('Erreur:', error); + }); +} +function closeUrlEntry(page_id, parent_div){ + parent_div.querySelector('i').classList.remove('hidden'); + parent_div.querySelector('.url').querySelector('input').classList.add('hidden'); + parent_div.querySelector('#edit-i' + page_id).classList.remove('hidden'); + parent_div.querySelector('#delete-i' + page_id).querySelector('input[type=image]').classList.remove('hidden'); + parent_div.querySelector('#cancel-i' + page_id).querySelector('button').classList.add('hidden'); + parent_div.querySelector('#submit-i' + page_id).querySelector('input[type=submit]').classList.add('hidden'); +}*/ + +/*function deleteUrlEntry(page_id){ const selected_div = document.getElementById(page_id); console.log(selected_div.id); -} \ No newline at end of file +}*/ + diff --git a/src/controller/MenuAndPathsController.php b/src/controller/MenuAndPathsController.php index d429287..5779b39 100644 --- a/src/controller/MenuAndPathsController.php +++ b/src/controller/MenuAndPathsController.php @@ -14,9 +14,15 @@ class MenuAndPathsController $previous_page = Director::$menu_data->findPageById((int)$_POST["location"]); // (int) à cause de declare(strict_types=1); $parent = $previous_page->getParent(); + $url_input = trim($_POST["url_input"]); // faire htmlspecialchars à l'affichage + if(!filter_var($url_input, FILTER_VALIDATE_URL) || !str_starts_with($url_input, 'http')){ + header("Location: " . new URL(['page' => $_GET['from'], 'error' => 'invalide_url'])); + die; + } + $page = new Page( trim(htmlspecialchars($_POST["label_input"])), - filter_var($_POST["url_input"], FILTER_VALIDATE_URL), + $url_input, true, true, false, $previous_page->getPosition(), $parent); // peut et DOIT être null si on est au 1er niveau @@ -24,7 +30,7 @@ class MenuAndPathsController // on a donné à la nouvelle entrée la même position qu'à la précédente, // addChild l'ajoute à la fin du tableau "children" puis on trie // 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 - if($parent == null){ + if(!$parent){ $parent = Director::$menu_data; } $parent->addChild($page); // true pour réindexer les positions en BDD @@ -36,6 +42,25 @@ class MenuAndPathsController die; } + static public function editUrlEntry(EntityManager $entityManager, array $json): void + { + $url_input = trim($json['url_input']); // faire htmlspecialchars à l'affichage + $page = $entityManager->find('App\Entity\Page', $json['id']); + + if(!$page){ + echo json_encode(['success' => false, 'message' => "id invalide"]); + } + elseif(!filter_var($url_input, FILTER_VALIDATE_URL) || !str_starts_with($url_input, 'http')){ + echo json_encode(['success' => false, 'message' => "la chaîne envoyée n'est pas une URL valide"]); + } + else{ + $page->setEndOfPath($url_input); + $entityManager->flush(); + echo json_encode(['success' => true, 'url_input' => $url_input]); + } + die; + } + static public function deleteUrlMenuEntry(EntityManager $entityManager): void { Director::$menu_data = new Menu($entityManager); @@ -163,7 +188,6 @@ class MenuAndPathsController else{ echo json_encode(['success' => false]); } - die; } diff --git a/src/router.php b/src/router.php index 04441a9..3c3c773 100644 --- a/src/router.php +++ b/src/router.php @@ -156,9 +156,12 @@ elseif($_SERVER['REQUEST_METHOD'] === 'POST'){ elseif($_GET['menu_edit'] === 'switch_positions' && isset($json['id1']) && isset($json['id2'])){ MenuAndPathsController::switchPositions($entityManager, $json); } - elseif($_GET['menu_edit'] === 'displayInMenu' && isset($json['id']) && isset($json['checked'])){ + elseif($_GET['menu_edit'] === 'display_in_menu' && isset($json['id']) && isset($json['checked'])){ MenuAndPathsController::displayInMenu($entityManager, $json); } + elseif($_GET['menu_edit'] === 'edit_url_entry' && isset($json['id']) && isset($json['url_input'])){ + MenuAndPathsController::editUrlEntry($entityManager, $json); + } } /* -- mode Modification d'une page -- */ diff --git a/src/view/MenuBuilder.php b/src/view/MenuBuilder.php index 9d4dda1..bc64e30 100644 --- a/src/view/MenuBuilder.php +++ b/src/view/MenuBuilder.php @@ -13,18 +13,13 @@ class MenuBuilder extends AbstractBuilder //private int $margin_left_multiplier = 29; private string $options = ''; - public function __construct(Node $node = null, bool $template = true) + public function __construct(Node $node, bool $template = true) { - //parent::__construct($node); + // impossible de me rappeler pourquoi j'ai écrit ce test sur $node, pourquoi $node serait null? $viewFile = $node === null ? self::VIEWS_PATH . 'menu.php' : self::VIEWS_PATH . $node->getName() . '.php'; if(file_exists($viewFile)) { - /*if(!empty($node->getNodeData()->getData())) - { - extract($node->getNodeData()->getData()); - }*/ - if($_SESSION['admin']){ $this->unfoldMenu(Director::$menu_data); @@ -63,13 +58,26 @@ class MenuBuilder extends AbstractBuilder '; + // seul la modification des URL est possible pour l'instant, les noms des entrées de menu attendront if(str_starts_with($entry->getEndOfPath(), 'http')){ - $this->html .= ' - ' . $entry->getEndOfPath() . ' -
+ $this->html .= ' -
'; + + + + + '; + + // code à recycler pour pouvoir modifier le nom de l'entrée de menu correspondant aux liens + /*$this->html .= ' + + + + + + + ';*/ } else{ $this->html .= '' . $entry->getPagePath() . ''; diff --git a/src/view/NavBuilder.php b/src/view/NavBuilder.php index a9cf49c..2cbdef9 100644 --- a/src/view/NavBuilder.php +++ b/src/view/NavBuilder.php @@ -38,7 +38,7 @@ class NavBuilder extends AbstractBuilder { if(str_starts_with($data->getEndOfPath(), 'http')) // lien vers autre site { - $link .= ''; + $link .= ''; } elseif($data->getEndOfPath() != '') // lien relatif { diff --git a/src/view/templates/menu.php b/src/view/templates/menu.php index 55c9ff9..d78c665 100644 --- a/src/view/templates/menu.php +++ b/src/view/templates/menu.php @@ -2,18 +2,18 @@ \ No newline at end of file -- cgit v1.2.3