From 959527bb712fcd05351d8b4b52ff17786baad454 Mon Sep 17 00:00:00 2001 From: polo Date: Sun, 26 Oct 2025 22:48:49 +0100 Subject: =?UTF-8?q?modification=20du=20nom=20et=20plus=20seulement=20de=20?= =?UTF-8?q?l'URL=20des=20entr=C3=A9es=20"URL"=20du=20menu,=20header/footer?= =?UTF-8?q?:=20renommage=20de=20classes=20et=20input=20absents=20du=20HTML?= =?UTF-8?q?=20sans=20=C3=AAtre=20admin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/css/head.css | 22 ++----- public/css/menu.css | 12 ++-- public/js/Input.js | 96 +++++++++++++++++++++++++++++++ public/js/InputFile.js | 62 -------------------- public/js/InputText.js | 48 ---------------- public/js/menu.js | 78 ++++--------------------- src/controller/MenuAndPathsController.php | 19 ++++-- src/model/Model.php | 3 + src/router.php | 4 +- src/view/FooterBuilder.php | 20 ++++--- src/view/HeadBuilder.php | 3 +- src/view/HeaderBuilder.php | 33 ++++++----- src/view/MenuBuilder.php | 26 ++++----- src/view/templates/footer.php | 20 +++---- src/view/templates/header.php | 30 +++++----- 15 files changed, 200 insertions(+), 276 deletions(-) create mode 100644 public/js/Input.js delete mode 100644 public/js/InputFile.js delete mode 100644 public/js/InputText.js diff --git a/public/css/head.css b/public/css/head.css index 4206044..dab81a8 100644 --- a/public/css/head.css +++ b/public/css/head.css @@ -49,7 +49,7 @@ header } } -.site_title +.header_center_col { background-color: #ffffff7f; border-radius: 10px; @@ -81,25 +81,15 @@ header a color: unset; /* ne plus hériter */ text-decoration: none; } -.editing_zone > div -{ - /*display: inline;*/ /* à l'ancienne */ -} /*.header_right_col {}*/ -.social -{ - /*align-self: end;*/ - /*padding: 4px;*/ -} -.social a img +#header_social img { - width: 25px; - background-color: #ffffffb3; + width: 28px; + background-color: rgba(255, 255, 255, 0.7); border-radius: 50%; } - -.social img:hover +#header_social img:hover { background-color: yellow; -} +} \ No newline at end of file diff --git a/public/css/menu.css b/public/css/menu.css index ac77d50..0dfb840 100644 --- a/public/css/menu.css +++ b/public/css/menu.css @@ -58,7 +58,7 @@ .menu button { - margin: 5px; + margin: 4px 0; } .menu_entry_checkbox { @@ -109,15 +109,11 @@ flex-wrap: wrap; align-items: center; } -.menu .url -{ - text-wrap: nowrap; -} -.menu .url input[type=url] +.menu .url_content input { width: 50%; } -@media screen and (min-width: 80rem) { +/*@media screen and (min-width: 80rem) { i{} -} \ No newline at end of file +}*/ \ No newline at end of file diff --git a/public/js/Input.js b/public/js/Input.js new file mode 100644 index 0000000..0b6912b --- /dev/null +++ b/public/js/Input.js @@ -0,0 +1,96 @@ +class Input{ + constructor(name){ + this.name = name; + /*const name_array = name.split('_'); + this.node = name_array[0]; + this.what = name_array[1];*/ + this.parent = document.getElementById(name); + } + open(){ + this.parent.querySelector('#' + this.name + '_content').classList.add('hidden'); + this.parent.querySelector('#' + this.name + '_input').classList.remove('hidden'); + this.parent.querySelector('#' + this.name + '_open').classList.add('hidden'); + this.parent.querySelector('#' + this.name + '_submit').classList.remove('hidden'); + this.parent.querySelector('#' + this.name + '_cancel').classList.remove('hidden'); + } + close(){ + this.parent.querySelector('#' + this.name + '_content').classList.remove('hidden'); + this.parent.querySelector('#' + this.name + '_input').classList.add('hidden'); + this.parent.querySelector('#' + this.name + '_open').classList.remove('hidden'); + this.parent.querySelector('#' + this.name + '_submit').classList.add('hidden'); + this.parent.querySelector('#' + this.name + '_cancel').classList.add('hidden'); + } + cancel(){ + this.close(); + } +} + +class InputFile extends Input{ + submit(){ + const file = this.parent.querySelector('#' + this.name + '_input').files[0]; + if(!file){ + console.error("Erreur: aucun fichier sélectionné."); + toastNotify("Erreur: aucun fichier sélectionné."); + return; + } + const form_data = new FormData(); + form_data.append('file', file); + + fetch('index.php?head_foot_image=' + this.name, { + method: 'POST', // apparemment il faudrait utiliser PUT + body: form_data + }) + .then(response => response.json()) + .then(data => { + if(data.success){ + // cas particuliers + if(this.name === 'head_favicon'){ + const link = document.querySelector('link[rel="icon"]'); + link.type = data.mime_type; + link.href = data.location; + } + else if(this.name === 'header_background'){ + document.querySelector('header').style.backgroundImage = "url('" + data.location + "')"; + } + + this.parent.querySelector('#' + this.name + '_content').src = data.location; + this.close(); + } + else{ + console.error("Erreur: le serveur n'a pas enregistré l'image'."); + } + }) + .catch(error => { + console.error('Erreur:', error); + }); + } +} + +class InputText extends Input{ + submit(){ + const new_text = this.parent.querySelector('#' + this.name + '_input').value; + + fetch('index.php?head_foot_text=' + this.name, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({new_text: new_text}) + }) + .then(response => response.json()) + .then(data => { + if(data.success){ + this.parent.querySelector('#' + this.name + '_content').innerHTML = new_text; + this.close(); + } + else{ + console.error("Erreur: le serveur n'a pas enregistré le nouveau texte."); + } + }) + .catch(error => { + console.error('Erreur:', error); + }); + } + cancel(){ // surcharge + this.parent.querySelector('#' + this.name + '_input').value = this.parent.querySelector('#' + this.name + '_content').innerHTML; + this.close(); + } +} \ No newline at end of file diff --git a/public/js/InputFile.js b/public/js/InputFile.js deleted file mode 100644 index e676037..0000000 --- a/public/js/InputFile.js +++ /dev/null @@ -1,62 +0,0 @@ -// étendre une classe parente avec InputFile? -class InputFile{ - constructor(name){ - this.name = name; - this.parent = document.getElementById(name); - } - open(){ - this.parent.querySelector('#' + this.name + '_img').classList.add('hidden'); - this.parent.querySelector('#' + this.name + '_input').classList.remove('hidden'); - this.parent.querySelector('#' + this.name + '_open').classList.add('hidden'); - this.parent.querySelector('#' + this.name + '_submit').classList.remove('hidden'); - this.parent.querySelector('#' + this.name + '_cancel').classList.remove('hidden'); - } - close(){ - this.parent.querySelector('#' + this.name + '_img').classList.remove('hidden'); - this.parent.querySelector('#' + this.name + '_input').classList.add('hidden'); - this.parent.querySelector('#' + this.name + '_open').classList.remove('hidden'); - this.parent.querySelector('#' + this.name + '_submit').classList.add('hidden'); - this.parent.querySelector('#' + this.name + '_cancel').classList.add('hidden'); - } - submit(){ - const file = this.parent.querySelector('#' + this.name + '_input').files[0]; - if(!file){ - console.error("Erreur: aucun fichier sélectionné."); - return; - } - const form_data = new FormData(); - form_data.append('file', file); - - fetch('index.php?head_foot_image=' + this.name, { - method: 'POST', // apparemment il faudrait utiliser PUT - body: form_data - }) - .then(response => response.json()) - .then(data => { - if(data.success){ - this.parent.querySelector('#' + this.name + '_img').src = data.location; - - // cas particulier - if(this.name === 'head_favicon'){ - const link = document.querySelector('link[rel="icon"]'); - link.type = data.mime_type; - link.href = data.location; - } - else if(this.name === 'header_background'){ - document.querySelector('header').style.backgroundImage = "url('" + data.location + "')"; - } - - this.close(); - } - else{ - console.error("Erreur: le serveur n'a pas enregistré l'image'."); - } - }) - .catch(error => { - console.error('Erreur:', error); - }); - } - cancel(){ - this.close(); - } -} \ No newline at end of file diff --git a/public/js/InputText.js b/public/js/InputText.js deleted file mode 100644 index 79f0398..0000000 --- a/public/js/InputText.js +++ /dev/null @@ -1,48 +0,0 @@ -// s'en servir dans menu et chemin -// étendre un classe parente avec InputText? -class InputText{ - constructor(name){ - this.name = name; - this.parent = document.getElementById(name); - } - open(){ - this.parent.querySelector('#' + this.name + '_span').classList.add('hidden'); - this.parent.querySelector('#' + this.name + '_input').classList.remove('hidden'); - this.parent.querySelector('#' + this.name + '_open').classList.add('hidden'); - this.parent.querySelector('#' + this.name + '_submit').classList.remove('hidden'); - this.parent.querySelector('#' + this.name + '_cancel').classList.remove('hidden'); - } - close(){ - this.parent.querySelector('#' + this.name + '_span').classList.remove('hidden'); - this.parent.querySelector('#' + this.name + '_input').classList.add('hidden'); - this.parent.querySelector('#' + this.name + '_open').classList.remove('hidden'); - this.parent.querySelector('#' + this.name + '_submit').classList.add('hidden'); - this.parent.querySelector('#' + this.name + '_cancel').classList.add('hidden'); - } - submit(){ - const new_text = this.parent.querySelector('#' + this.name + '_input').value; - - fetch('index.php?head_foot_text=' + this.name, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({new_text: new_text}) - }) - .then(response => response.json()) - .then(data => { - if(data.success){ - this.parent.querySelector('#' + this.name + '_span').innerHTML = new_text; - this.close(); - } - else{ - console.error("Erreur: le serveur n'a pas enregistré le nouveau texte."); - } - }) - .catch(error => { - console.error('Erreur:', error); - }); - } - cancel(){ - this.parent.querySelector('#' + this.name + '_input').value = this.parent.querySelector('#' + this.name + '_span').innerHTML; - this.close(); - } -} \ No newline at end of file diff --git a/public/js/menu.js b/public/js/menu.js index ef58c42..5e02387 100644 --- a/public/js/menu.js +++ b/public/js/menu.js @@ -147,22 +147,27 @@ 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){ +function editUrl(page_id, selector){ const parent_div = document.getElementById(page_id); - const url_input = parent_div.querySelector('.url').querySelector('input').value; + const input_data = parent_div.querySelector('.' + selector).querySelector('input').value; - fetch('index.php?menu_edit=edit_url_entry', { + fetch('index.php?menu_edit=url_edit', { method: 'POST', headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ id: page_id, url_input: url_input }) + body: JSON.stringify({ id: page_id, field: selector, input_data: input_data }) }) .then(response => response.json()) .then(data => { if(data.success){ - findParentByTagName(document.getElementById('m_' + page_id), 'a').href = data.url_input; // MAJ menu + // MAJ menu + if(selector === 'url_name'){ + document.getElementById('m_' + page_id).innerHTML = data.url_data; + } + else if(selector === 'url_content'){ + findParentByTagName(document.getElementById('m_' + page_id), 'a').href = data.url_data; + } toastNotify("Nouvelle adresse enregistrée avec succès") } else{ @@ -173,63 +178,4 @@ function editUrlEntry(page_id){ .catch(error => { console.error('Erreur:', error); }); -} - - - -// 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 a32b210..6bb098f 100644 --- a/src/controller/MenuAndPathsController.php +++ b/src/controller/MenuAndPathsController.php @@ -42,21 +42,30 @@ class MenuAndPathsController die; } - static public function editUrlEntry(EntityManager $entityManager, array $json): void + // on pourrait utiliser FormValidation ici + static public function editUrl(EntityManager $entityManager, array $json): void { - $url_input = trim($json['url_input']); // faire htmlspecialchars à l'affichage + $url_data = trim($json['input_data']); // garder htmlspecialchars pour 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')){ + elseif(!in_array($json['field'], ['url_name', 'url_content'])){ + echo json_encode(['success' => false, 'message' => "champ invalide"]); + } + elseif($json['field'] === 'url_content' && (!filter_var($url_data, FILTER_VALIDATE_URL) || !str_starts_with($url_data, 'http'))){ echo json_encode(['success' => false, 'message' => "la chaîne envoyée n'est pas une URL valide"]); } else{ - $page->setEndOfPath($url_input); + if($json['field'] === 'url_name'){ + $page->setPageName($url_data); + } + elseif($json['field'] === 'url_content'){ + $page->setEndOfPath($url_data); + } $entityManager->flush(); - echo json_encode(['success' => true, 'url_input' => $url_input]); + echo json_encode(['success' => true, 'url_data' => $url_data]); } die; } diff --git a/src/model/Model.php b/src/model/Model.php index 68c4c08..eeba8b2 100644 --- a/src/model/Model.php +++ b/src/model/Model.php @@ -1,5 +1,8 @@ getMethod() === 'POST'){ 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); + elseif($_GET['menu_edit'] === 'url_edit' && isset($json['id']) && isset($json['field']) && isset($json['input_data'])){ + MenuAndPathsController::editUrl($entityManager, $json); } } diff --git a/src/view/FooterBuilder.php b/src/view/FooterBuilder.php index fcb78e0..277de4b 100644 --- a/src/view/FooterBuilder.php +++ b/src/view/FooterBuilder.php @@ -30,17 +30,21 @@ class FooterBuilder extends AbstractBuilder if($_SESSION['admin']) { // données du footer - $buttons_footer_name = ' + $admin_footer_name = ' + '; - $buttons_footer_address = ' + $admin_footer_address = ' + '; - $buttons_footer_email = ' + $admin_footer_email = ' + '; - $buttons_footer_logo = ' + $admin_footer_logo = ' + '; @@ -81,10 +85,10 @@ class FooterBuilder extends AbstractBuilder } $zone_admin = ''; - $buttons_footer_name = ''; - $buttons_footer_address = ''; - $buttons_footer_email = ''; - $buttons_footer_logo = ''; + $admin_footer_name = ''; + $admin_footer_address = ''; + $admin_footer_email = ''; + $admin_footer_logo = ''; } ob_start(); diff --git a/src/view/HeadBuilder.php b/src/view/HeadBuilder.php index fd7f751..3eba9a2 100644 --- a/src/view/HeadBuilder.php +++ b/src/view/HeadBuilder.php @@ -36,8 +36,7 @@ class HeadBuilder extends AbstractBuilder if($_SESSION['admin']){ // édition éléments sur toutes les pages (header, footer et favicon) - $js .= '' . "\n"; - $js .= '' . "\n"; + $js .= '' . "\n"; // tinymce, nécéssite un script de copie dans composer.json $css .= '' . "\n"; diff --git a/src/view/HeaderBuilder.php b/src/view/HeaderBuilder.php index 1c82368..ae9a888 100644 --- a/src/view/HeaderBuilder.php +++ b/src/view/HeaderBuilder.php @@ -57,37 +57,42 @@ class HeaderBuilder extends AbstractBuilder if($_SESSION['admin']){ // assets dans classe editing_zone $editing_zone_margin = '5px'; - $buttons_favicon = ' - + $admin_favicon = ' + + '; - $buttons_background = ' + $admin_background = ' + '; // asset dans classe header_content - $buttons_header_logo = ' + $admin_header_logo = ' + '; // texte dans classe header_content - $buttons_header_title = ' + $admin_header_title = ' + '; - $buttons_header_description = ' + $admin_header_description = ' + '; - //$buttons_social_networks = ''; - $buttons_social_networks = ''; + // icônes réseaux sociaux + $admin_social_networks = ''; } else{ $editing_zone_margin = '0'; - $buttons_favicon = ''; - $buttons_background = ''; - $buttons_header_logo = ''; - $buttons_header_title = ''; - $buttons_header_description = ''; - $buttons_social_networks = ''; + $admin_favicon = ''; + $admin_background = ''; + $admin_header_logo = ''; + $admin_header_title = ''; + $admin_header_description = ''; + $admin_social_networks = ''; } ob_start(); diff --git a/src/view/MenuBuilder.php b/src/view/MenuBuilder.php index 12298cf..8e8b9a9 100644 --- a/src/view/MenuBuilder.php +++ b/src/view/MenuBuilder.php @@ -55,32 +55,26 @@ class MenuBuilder extends AbstractBuilder - - '; + '; - // seul la modification des URL est possible pour l'instant, les noms des entrées de menu attendront + // entrées URL: bouton poubelle + nom du lien + adresse if(str_starts_with($entry->getEndOfPath(), 'http')){ $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() . ''; + $this->html .= ' + ' . $entry->getPagePath() . ''; } if(count($entry->getChildren()) > 0){ diff --git a/src/view/templates/footer.php b/src/view/templates/footer.php index 4db38ae..dc1c6cb 100644 --- a/src/view/templates/footer.php +++ b/src/view/templates/footer.php @@ -4,25 +4,21 @@
\ No newline at end of file -- cgit v1.2.3