From 86c2a611e55c9e35384febecf34964e214c0296e Mon Sep 17 00:00:00 2001 From: polo Date: Thu, 22 Jul 2021 03:49:28 +0200 Subject: patch modifs --- controller/admin.php | 31 ++--------------------- controller/ckeditor.php | 12 ++++----- controller/visitor.php | 4 +-- index.php | 62 +++++++++++++++++++++++++++++++++++----------- model/Article.php | 11 ++++---- model/melaine-read.php | 46 +++++++++++++++++++++------------- model/melaine-write.php | 24 ++++++++++++------ view/melaine.php | 56 +++++++++++++++++++---------------------- view/template-ckeditor.php | 2 +- 9 files changed, 133 insertions(+), 115 deletions(-) diff --git a/controller/admin.php b/controller/admin.php index 77ab34e..a35f28a 100644 --- a/controller/admin.php +++ b/controller/admin.php @@ -9,7 +9,6 @@ function melaineEdit($numArticle) $page_actuelle = "melaine"; // tableau $articles[] - require('model/melaine-read.php'); $croissant = False; $articles = lireArticles($page_actuelle, $croissant); @@ -17,46 +16,20 @@ function melaineEdit($numArticle) { $title = "Ajouter un article"; $texte = ''; - //$numArticle = count($articles) + 1; } else { $title = "Modifier un article"; - // faire correspondre le numéro de l'article du GET et le tableau des articles qui est inversé - $texte = $articles[count($articles) - $numArticle]; + $texte = lireUnArticle($_SESSION['nomFichier']); } // traitements PHP pour l'éditeur require('controller/ckeditor.php'); // sécurisation du contenu pré-existant inséré dans l'éditeur - $initial = preparationCKeditor($numArticle, $texte); + $texte = preparationCKeditor($numArticle, $texte); // NB: penser à ajouter au template la fonctionnalité "autosave" // https://ckeditor.com/docs/ckeditor5/latest/builds/guides/integration/saving-data.html - - // if($numArticle > $nombreDarticles || $numArticle < 0) // erreur nombre trop grand (bug?) - // { - // header('Location: index.php?page=melaine'); - // } - // elseif($numArticle == 0) // nouvel article - // { - // $texte = ''; - // $numArticle = $nombreDarticles + 1; - // } - // else // modification d'un article - // { - // $texte = $articles[$numArticle - 1]; - // } - - - // if($initial == '') - // { - // $article = "nouveau"; - // } - // else - // { - // $article = "modif"; - // } // variable $editeurHTML, $initial est inséré dedans require('view/template-ckeditor.php'); diff --git a/controller/ckeditor.php b/controller/ckeditor.php index 013d6b5..ea90726 100644 --- a/controller/ckeditor.php +++ b/controller/ckeditor.php @@ -33,7 +33,8 @@ function preparationCKeditor($numArticle, $texte) } // réception du HTML créé par l'éditeur -function submitCKeditor($page, $article, $contenuPOST) +// le nom du fichier est celui dans $_SESSION['nomFichier'] +function submitCKeditor($page, $nomFichier, $contenu) { // déjà fait mais on ne sait jamais if(!isset($_SESSION['admin']) || $_SESSION['admin'] != 1) @@ -44,14 +45,12 @@ function submitCKeditor($page, $article, $contenuPOST) { // ne pas continuer si la variable est vide (javascript mal supporté ou utilisation de IE, bug?, erreur de l'utilisateur) // on évitera de perdre un article existant par erreur !! - if($contenuPOST == '') + if($contenu == '') { header('Location: index.php?page=' . $page . '&erreur=contenu_vide'); } else { - $contenu = $_POST["contenu"]; - // récupérer les liens multimedia //require("media.php"); //$contenu = mediaSubmit($contenu); @@ -89,14 +88,13 @@ function submitCKeditor($page, $article, $contenuPOST) // enregistrement require('model/melaine-write.php'); - if($article == 0) + if($_GET['article'] == 0) { nouvelArticle($page, $contenu); } else { - // $article est le nom du fichier - modifArticle($page, $article, $contenu); + modifArticle($page, $nomFichier, $contenu); } // debuggage diff --git a/controller/visitor.php b/controller/visitor.php index 9bd3461..a08ea95 100644 --- a/controller/visitor.php +++ b/controller/visitor.php @@ -33,13 +33,11 @@ function melaineVisitor() $title = "Mais qui est Melaine Favennec?"; // tableau $articles - require('model/melaine-read.php'); $croissant = False; $articles = lireArticles($page_actuelle, $croissant); // vérification pour protéger les visiteurs - // normalement déjà faite dans submit.php, - // c'est au cas où les données aient été trafiquées + // normalement déjà faite dans submit.php, au cas où la base a été trafiquée //$article = htmLawed($article); // variables $css, $js et $content diff --git a/index.php b/index.php index 2d3bcd6..ccce82a 100644 --- a/index.php +++ b/index.php @@ -51,9 +51,9 @@ installation(); // à propos des sessions, penser aux attaques CSRF (cross-site request forgery): // ça consite à faire qu'un utilisateur connecté avec une session envoie malgré lui une requête GET ou POST qu'un hacker aura cachée par exemple dans une fausse image clicable -// - solution: faire qu'un GET seul dans une session ne suffise pas à effectuer une action (les GET ne doivent servir qu'à afficher la bonne page), une attaque sur un POST nécessite d'injecter du javascript +// - solution: faire qu'un GET seul dans une session ne suffise pas à effectuer une action (les GET ne doivent servir qu'à afficher la bonne page), une attaque sur un POST est possible aussi mais plus difficile et nécessite d'injecter du javascript // - on peut demander à l'utilisateur une vérification supplémentaire avant chaque action, mais c'est plutôt chiant -// - la méthode des jetons, "nonces" et horodatage +// - il y a la méthode des jetons, "nonces" et horodatage // - vérifier le "référent", c'est à dire l'URL de la page d'où vient normallement la requête // infos: https://fr.wikipedia.org/wiki/Cross-site_request_forgery session_start(); @@ -62,20 +62,27 @@ session_start(); require('lib/htmlawed/htmLawed.php'); // traitement des POST du ckeditor -// NOTER que le fichier "habituel" controller/admin.php n'est pas utilisé -// la fonction submitCKeditor n'affiche rien puis redirige sans GET +// la fonction submitCKeditor n'affiche rien (controller/admin.php n'est pas utilisé) puis redirige sans GET if(isset($_SESSION['admin']) && $_SESSION['admin'] == 1 && isset($_GET['action']) && $_GET['action'] == 'submit' - && isset($_POST['contenu'])) + && isset($_POST['contenu']) && $_POST['contenu'] != '') { require('controller/ckeditor.php'); - submitCKeditor($_GET['page'], $_GET['article'], $_POST['contenu']); - - // nettoyage (je ne sais pas si ça sert à quelque chose, mais c'est pas grave) - unlink($_GET['action']); - unlink($_POST['contenu']); + // modification + if(isset($_SESSION['nomFichier'])) + { + submitCKeditor($_GET['page'], $_SESSION['nomFichier'], $_POST['contenu']); + } + // nouvel article + else + { + submitCKeditor($_GET['page'], '', $_POST['contenu']); + } - // rechargement "nettoyage" à la fin du traitement + // nettoyage + unset($_SESSION['nomFichier']); + unset($_GET['action']); + unset($_POST['contenu']); header('Location: index.php?page=' . $_GET['page']); } @@ -90,13 +97,20 @@ if(isset($_GET['action'])) } // le site comporte deux modes: -// le mode normal en "lecture seule" utilisant le contrôleur visitor.php +// le mode visiteur en "lecture seule" utilisant le contrôleur visitor.php // le mode admin avec droits en "écriture" utilisant le contrôleur admin.php -// appelé tout le temps parce que certaines pages (accueil, menu) n'ont pas de version "admin" -// une optimisation serait bienvenue +// contrôleur des pages en mode visiteur +// appelé tout le temps parce que certaines pages (accueil, menu) n'ont pas de version "admin" => à améliorer require('controller/visitor.php'); +// utile pour presque toutes les pages +if(isset($_GET['page']) && $_GET['page'] != 'menu') +{ + require('model/melaine-read.php'); +} + +// contrôleur des pages en mode admin if(isset($_SESSION['admin']) && $_SESSION['admin'] == 1) { require('controller/admin.php'); @@ -122,17 +136,35 @@ if(isset($_GET['page'])) // page melaine elseif($_GET['page'] == 'melaine') { - // ouverture de l'éditeur + // ouverture de l'éditeur pour modification + // le lien utilisé pour ouvrir l'éditeur contient un GET avec le numéro de l'article, mais pas le nom du fichier que le visiteur ne doit pas voir + // GET, POST, cookies => navigation (utiles au visiteur) + // sessions => action + // c'est ici qu'on passe des GET aux sessions + // on associe maintenant le numéro de l'article et le nom du fichier, l'article déjà existant inséré dans l'éditeur DOIT être celui qui sera modifié + // if($_SESSION['admin'] == 1 && isset($_GET['action']) && $_GET['action'] == 'editor') { // modification + // A MODIFIER! on a aussi besoin du nom du fichier, + // infos à mettre dans la session! + if(isset($_GET['article']) && is_numeric($_GET['article']) && $_GET['article'] > 0) { + // obtenir le nom du fichier à l'aide du modèle + $_SESSION['nomFichier'] = getFileName($_GET['page'], $_GET['article']); + melaineEdit($_GET['article']); } // nouvel article else { + // prévenir une hypothétique perte de donnée + if(isset($_SESSION['nomFichier'])) + { + unset($_SESSION['nomFichier']); + } + melaineEdit(0); } } diff --git a/model/Article.php b/model/Article.php index afcb1ca..aee4f5d 100644 --- a/model/Article.php +++ b/model/Article.php @@ -6,8 +6,9 @@ class Article private $page = ''; // page et donc dossier concerné private $croissant = True; // ordre des éléments du tableau $files private $files; // noms des fichiers d'un dossier - private $nbArticles; // peut servir - private $articles; // contenu de ces mêmes fichiers + private $oneFile; // correspond à $_SESSION['nomFichier'] + private $nbArticles; // un fichier = un article + private $articles; // contenu des fichiers private function getFiles() { @@ -45,7 +46,7 @@ class Article } // read - public function getNb() + public function getNumber() { return $this->nbArticles; } @@ -55,11 +56,11 @@ class Article public function getAll($croissant) { - $this->croissant = $croissant; - + $this->croissant = $croissant; // inversion de $files? getFiles(); $i = 0; + $articles = array(); foreach ($this->files as $file) { $articles[$i] = file_get_contents($file); diff --git a/model/melaine-read.php b/model/melaine-read.php index 801cd3c..7105acd 100644 --- a/model/melaine-read.php +++ b/model/melaine-read.php @@ -3,16 +3,33 @@ // // accès en lecture seule -function lireArticles($page_actuelle, $croissant) +// obtenir le nom du fichier de l'article qu'on modifie +function getFileName($page, $numArticle) +{ + $files = lireNomsFichiers($page); + $fileName = $files[$numArticle - 1]; + + return($fileName); +} + +function lireNomsFichiers($page) { // créer un tableau avec le nom des fichiers html - $files = glob('data/' . $page_actuelle . '/html/*.html'); + $files = glob('data/' . $page . '/html/*.html'); - // nombre de fichiers (= taille du tableau $files) - //$nombreDarticles = count($files); + return $files; +} - // tableau contenant tous les articles au format html - //$articles = [$nombreDarticles]; +function lireUnArticle($nomFichier) +// ce nom est le chemin complet, donc la page y figure +{ + return(file_get_contents($nomFichier)); +} + +function lireArticles($page, $croissant) +{ + // créer un tableau avec le nom des fichiers html + $files = lireNomsFichiers($page); // inverse l'ordre du tableau retourné if($croissant == False) @@ -20,23 +37,18 @@ function lireArticles($page_actuelle, $croissant) $files = array_reverse($files); } - // for ($i = 0 ; $i < $nombreDarticles ; $i++) - // { - // // les noms de fichiers commencent par 1 - // // les articles dans le tableau[] commencent par 0 - // $numero = $i + 1; - // $articles[$i] = file_get_contents('data/' . $page_actuelle . '/html/article' . $numero . '.html'); - // } $i = 0; - foreach ($files as $files) + $articles = array(); + foreach ($files as $oneFile) { - $articles[$i] = file_get_contents($files); + $articles[$i] = file_get_contents($oneFile); $i++; } + // nombre de fichiers (= taille du tableau $files) + //$nombreDarticles = count($files); //print_r($articles); - //var_dump($articles); - + return($articles); } diff --git a/model/melaine-write.php b/model/melaine-write.php index 642bf05..462d59e 100644 --- a/model/melaine-write.php +++ b/model/melaine-write.php @@ -3,22 +3,30 @@ // // accès en écriture pour créer ou modifier des articles + + function nouvelArticle($page, $contenuHTML) { - // manipulation du fichier - //$nom_fichier = 'article' . $article . '.html'; - $nom_fichier = time() . '.html'; - $fichier = fopen('data/' . $page . '/html/' . $nom_fichier, 'w'); // w peut créer un fichier, si il existe déjà, il est effacé par le nouveau contenu + // nommer les fichiers avec le timestamp + // pour les trier par ordre chronologique + // rendre impossible d'avoir deux fois le même nom (à la condition de gérer la "concurrence") + $nom_fichier = 'data/' . $_GET['page'] . '/html/' . time() . '.html'; + + $fichier = fopen($nom_fichier, 'w'); // w peut créer un fichier, si il existe déjà, il est effacé par le nouveau contenu fputs($fichier, $contenuHTML); fclose($fichier); - chmod('data/' . $page . '/html/' . $nom_fichier, 0666); + chmod($nom_fichier, 0666); } -function modifArticle($page, $nom_fichier, $contenuHTML) +function modifArticle($page, $nomFichier, $contenuHTML) { // manipulation du fichier - $fichier = fopen('data/' . $page . '/html/' . $nom_fichier, 'w'); // w peut créer un fichier, si il existe déjà, il est effacé par le nouveau contenu + //$fichier = fopen('data/' . $page . '/html/' . $nom_fichier, 'w'); + $fichier = fopen($nomFichier, 'w'); + // w peut créer un fichier, si il existe déjà, il est effacé par le nouveau contenu fputs($fichier, $contenuHTML); fclose($fichier); - chmod('data/' . $page . '/html/' . $nom_fichier, 0666); + //chmod('data/' . $page . '/html/' . $nom_fichier, 0666); + chown($nomFichier, 'http'); + chmod($nomFichier, 0666); } \ No newline at end of file diff --git a/view/melaine.php b/view/melaine.php index acf4962..debd4e3 100644 --- a/view/melaine.php +++ b/view/melaine.php @@ -67,48 +67,44 @@ if($_SESSION['admin'] == 1) // on pourrait paginer avec des onglets contenant 5 ou 10 articles chacun // tableau articles[] du dernier au premier (1 case = 1 article) -//for ($i=$nombreDarticles - 1; $i >= 0 ; $i--) - -//$j = 0; $j = count($articles); foreach ($articles as $article) -{ - //$j = $i + 1; - +{ // la div invisible sert à la compensation des liens d'ancre # ?>
Modifier l'article " . $j . "

"); - //echo("

Modification d'un article

"); - echo "\n"; - - echo($editeurHTML); // injection de template-editor.php -} + // remplacer un article par l'éditeur + if($_SESSION['admin'] == 1 && isset($_GET['action']) && $_GET['action'] == 'editor' && isset($_GET['article']) && $_GET['article'] == $j) + { + // on pourrait utiliser le timedate, ou encore le nom de l'article + echo("\n

Modifier l'article " . $j . "

"); + //echo("

Modification d'un article

"); + echo "\n"; -// placer un article -else -{ - // c'était pas compliqué - echo($article . "\n"); + echo($editeurHTML); // injection de template-editor.php + } - // bouton - if($_SESSION['admin'] == 1) + // placer un article + else { - ?> -

- - Modifier cet article - -

- +

+ + Modifier cet article + +

+
diff --git a/view/template-ckeditor.php b/view/template-ckeditor.php index f95344a..12e1430 100644 --- a/view/template-ckeditor.php +++ b/view/template-ckeditor.php @@ -174,7 +174,7 @@ ob_start(); // obtenir la liste des plugins disponibles: //alert(ClassicEditor.builtinPlugins.map( plugin => plugin.pluginName )); - var initial = ''; + var initial = ''; editor.setData(initial); } ) .catch( error => { -- cgit v1.2.3