From 10954c386cacb270e4ae16837483120ca3406259 Mon Sep 17 00:00:00 2001
From: polo
Date: Wed, 1 Sep 2021 23:35:42 +0200
Subject: albums
---
controller/admin.php | 86 ++++++++++++++++----
controller/ckeditor.php | 124 ++++++++++++++++-------------
controller/installation.php | 5 +-
controller/visitor.php | 65 ++++++++++++---
index.php | 6 +-
model/Classes.php | 190 +++++++++++++++++++++++++-------------------
public/discographie.css | 14 +++-
view/discographie.php | 51 ++++++++++--
view/melaine.php | 4 +-
view/template.php | 2 +-
10 files changed, 362 insertions(+), 185 deletions(-)
diff --git a/controller/admin.php b/controller/admin.php
index 0abdb1c..2588d36 100644
--- a/controller/admin.php
+++ b/controller/admin.php
@@ -8,11 +8,9 @@ function melaineEdit($numArticle, $suppression)
{
$page_actuelle = "melaine";
- $Articles = new ArticlesManager;
-
- // contenu de la page
- $Articles->setPage($page_actuelle);
- $Articles->getFiles();
+ // modèle
+ $Article = new OneArticle($page_actuelle);
+ $Article->makeFileList();
// nouvel article
if($numArticle == 0)
@@ -23,13 +21,13 @@ function melaineEdit($numArticle, $suppression)
else
{
// nom de l'article ciblé (objet et session)
- $Articles->findFileName($numArticle);
- $_SESSION['nomFichier'] = $Articles->getFileName();
+ $Article->findFileName($numArticle);
+ $_SESSION['nomFichier'] = $Article->getFileName();
// suppression
if($suppression)
{
- $Articles->delete();
+ $Article->delete();
header('Location: index.php?page=' . $page_actuelle);
exit();
}
@@ -37,15 +35,12 @@ function melaineEdit($numArticle, $suppression)
else
{
$title = "Modifier un article";
-
- // contenu envoyé à l'éditeur
- $texte = $Articles->getOne();
+ $texte = $Article->readOne(); // entrée de l'éditeur
}
}
// pour l'affichage des articles
- $Articles->reverseFilesArray();
- $articles = $Articles->getAll();
+ $articles = array_reverse($Article->readAll()); // lourd
// sécurisation du contenu pré-existant inséré dans l'éditeur
if($numArticle >= 0 && !$suppression)
@@ -73,13 +68,70 @@ function discoEdit($numArticle, $suppression)
$title = "Discographie";
// modèle
- $Albums = new AlbumsManager;
- $texte = '';
+ $Album = new OneArticle($page_actuelle);
+ $Album->makeFileList();
+
+ // nouvel album
+ if($numArticle == 0)
+ {
+ $title = "Ajouter un album";
+ $texte = '';
+ }
+ else
+ {
+ // nom de l'article ciblé (objet et session)
+ $Album->findFileName($numArticle);
+ $_SESSION['nomFichier'] = $Album->getFileName();
+
+ // suppression
+ if($suppression)
+ {
+ $Album->delete();
+ header('Location: index.php?page=' . $page_actuelle);
+ exit();
+ }
+ // modification
+ else
+ {
+ $title = "Modifier un album";
+ $texte = $Album->readOne(); // entrée de l'éditeur
+ }
+ }
+
+ $albums = array_reverse($Album->readAll()); // lourd
+
+ // $albums contient un tableau de chaines JSON,
+ // on extrait de chacune 3 variables: titre, année, pochette
// traitements PHP pour l'éditeur
- require('controller/ckeditor.php');
// sécurisation du contenu pré-existant inséré dans l'éditeur
- $texte = preparationCKeditor($numArticle, $texte);
+ if($numArticle >= 0 && !$suppression)
+ {
+ require('controller/ckeditor.php');
+ $texte = preparationCKeditor($numArticle, $texte);
+ }
+
+ // changer les chaines JSON en tableaux
+ $i = 0;
+ foreach($albums as $oneAlbum)
+ {
+ $albums[$i] = json_decode($oneAlbum, true);
+ $i++;
+ }
+
+ // pour chaque album, détecter le fichier html
+ // si il y en a un, proposer un lien
+ // si non, ne fournir qu'un lien d'ancre pour la liste d'album
+ $titreAlbum = 'discographie';
+ if(false)
+ {
+ $lienAlbum = $titreAlbum;
+ }
+ else
+ {
+ $lienAlbum = 'discographie#' . $titreAlbum;
+ }
+ //echo($lienAlbum);
// morceaux en HTML à assembler
// variable $editeurHTML, contient $texte
diff --git a/controller/ckeditor.php b/controller/ckeditor.php
index d25e5ac..2e72be2 100644
--- a/controller/ckeditor.php
+++ b/controller/ckeditor.php
@@ -44,35 +44,51 @@ function preparationCKeditor($numArticle, $texte)
function submitCKeditor($nomFichier)
{
$page = $_GET['page'];
- $contenu = $_POST['contenu'];
// déjà fait mais on ne sait jamais
if(!isset($_SESSION['admin']) || $_SESSION['admin'] != 1)
{
header('Location: index.php?page=' . $page . '&erreur=connexion');
+ exit();
}
- else
+
+ // sécurité faille XSS avec htmLawed
+ $configHtmLawed = array(
+ 'safe'=>1, // protection contre les élements et attributs dangereux
+ 'elements'=>'h2, h3, h4, p, br, span, i, strong, u, mark, blockquote, li, ol, ul, a, figure, hr, img, figcaption, table, tbody, tr, td', // paramètre optionnel: les balises non indiquées sont supprimées
+ 'deny_attribute'=>'id', // gêner le JS hostile
+ // on garde 'class' et 'style' utilisés par le ckediteur
+ );
+ $specHtmLawed = ''; // optionnel: faire qu'un certain élément puisse n'avoir que certains attributs
+
+ // de l'éditeur
+ if(isset($_POST['contenu'])) // optionnel pour discographie
{
+ $contenu = $_POST['contenu'];
+
// récupérer les liens multimedia
//require("media.php");
//$contenu = mediaSubmit($contenu);
- // sécurité faille XSS
- $configHtmLawed = array(
- 'safe'=>1, // protection contre les élements et attributs dangereux
- 'elements'=>'h2, h3, h4, p, br, span, i, strong, u, mark, blockquote, li, ol, ul, a, figure, hr, img, figcaption, table, tbody, tr, td', // paramètre optionnel: les balises non indiquées sont supprimées
- 'deny_attribute'=>'id', // gêner le JS hostile
- // on garde 'class' et 'style' utilisés par le ckediteur
- );
- $specHtmLawed = ''; // optionnel: faire qu'un certain élément puisse n'avoir que certains attributs
+ $contenu = htmLawed($contenu, $configHtmLawed, $specHtmLawed);
+ // supprimer espaces, tabulations et sauts de ligne en début et fin de chaine (pour l'entrée de l'éditeur)
+ $contenu = trim($contenu);
+
+ // ne pas continuer si la variable est vide (javascript mal supporté ou utilisation de IE, bug?, erreur de l'utilisateur), risque perte de contenu !!
+ if($page != 'discographie' && $contenu == '')
+ {
+ header('Location: index.php?page=' . $page . '&erreur=contenu_vide');
+ exit();
+ }
}
+
if($page == 'discographie')
{
$titre = $_POST['titre'];
$annee = $_POST['annee'];
$pochette = $_POST['pochette']; // une image
-
+
// des formulaires simples
$titre = htmLawed($titre, $configHtmLawed, $specHtmLawed);
$titre = trim($titre);
@@ -83,25 +99,6 @@ function submitCKeditor($nomFichier)
// Album->imageUpload();
// test formats jpg, jpeg, png, gif, tiff
// enregistrement du fichier
-
- // du ckeditor
- $contenu = htmLawed($contenu, $configHtmLawed, $specHtmLawed);
- $contenu = trim($contenu);
- }
- else // pages comme "melaine"
- {
- // ne pas continuer si la variable est vide (javascript mal supporté ou utilisation de IE, bug?, erreur de l'utilisateur), risque perte de contenu !!
- if($contenu == '')
- {
- header('Location: index.php?page=' . $page . '&erreur=contenu_vide');
- }
- else
- {
- // failles XSS
- $contenu = htmLawed($contenu, $configHtmLawed, $specHtmLawed);
- // supprimer espaces, tabulations et sauts de ligne en début et fin de chaine (pour l'entrée de l'éditeur)
- $contenu = trim($contenu);
- }
}
// lien sans http://
@@ -114,42 +111,61 @@ function submitCKeditor($nomFichier)
// solution 2 (façon pop-up): fermer ce nouvel onglet avec echo '';
// pour faire passer par le .htaccess l'info comme quoi la page précédente comportait un éditeur ouvert...
- //var_dump($titre, $annee, $pochette, $contenu);
- //die();
-
- // modèle
- $Article = new ArticlesManager;
- $Article->setPage($page);
// enregistrement
- if($_GET['article'] == 0)
- {
- $Article->create($contenu);
- }
- else
- {
- $Article->setFileName($nomFichier);
- $Article->update($contenu);
- }
+ // var_dump($titre, $annee, $pochette, $contenu);
+ // die();
+ // modèle
if($page == 'discographie')
{
- $Album = new AlbumsManager;
+ // on instancie avec l'enfant de OneArticle
+ $Album = new Album($page);
- var_dump($_POST);
- echo('
');
//var_dump($_GET['article']);
-
+ //var_dump($_POST);
+ //exit();
+
// enregistrement
if($_GET['article'] == 0)
{
- // ERREUR, il faut le même nombre de paramètre pour une méthode du même nom
- $Album->create($titre, $annee, $pochette);
+ // page disco
+ $Album->createVignette($titre, $annee, $pochette);
+
+ // page détail de l'album
+ if(!empty($_POST['contenu']))
+ {
+ $Album->create($contenu);
+ }
+ }
+ else
+ {
+ // page disco
+ $Album->updateVignette($titre, $annee, $pochette);
+
+ // page détail de l'album
+ if(isset($_POST['contenu']))
+ {
+ $Album->update($content);
+ }
+ }
+ }
+ // autres pages
+ else
+ {
+ $Article = new OneArticle($page);
+
+ if($_GET['article'] == 0)
+ {
+ $Article->create($contenu);
}
else
{
- $Album->update($titre, $annee, $pochette);
+ $Article->setFileName($nomFichier);
+ $Article->update($contenu);
}
- die();
}
-}
\ No newline at end of file
+}
+
+function cleanHTML($contenu)
+{}
diff --git a/controller/installation.php b/controller/installation.php
index 42212f5..fc8c900 100644
--- a/controller/installation.php
+++ b/controller/installation.php
@@ -25,7 +25,7 @@ function installation()
if(!file_exists(".htaccess"))
{
echo('Le .htaccess semble absent ce qui rend le site vulnérable aux attaques, veuillez contacter l\'administrateur.
');
- // $contenu = "# redirection en cas d'erreur 404\nErrorDocument 404 http://" . $_SERVER['SERVER_NAME'] . "/" . $nomDuSite . "/erreur404.php\n# Interdire exploration du répertoire\nOptions All -Indexes";
+ //$contenu = "# redirection en cas d'erreur 404\nErrorDocument 404 http://" . $_SERVER['SERVER_NAME'] . "/" . $nomDuSite . "/erreur404.php\n# Interdire exploration du répertoire\nOptions All -Indexes";
// $fichier = fopen('.htaccess', 'w');
// fputs($fichier, $contenu);
// fclose($fichier);
@@ -49,8 +49,7 @@ function installation()
// - modifier ceux du dossier parent (nom du site) avec son client FTP à la mise en ligne chez l'hébergeur et ensuite remettre tout comme avant
// le 0 devant signifie que le nombre est en octal
- // changer cette valeur à la mise en production du site si le script d'upload des données est bon
- $droitsDossiers = 0777;
+ $droitsDossiers = 0777; // mettre 0700 à la fin
$listePages = array('melaine', 'discographie', 'concerts', 'presse', 'ateliers', 'liens', 'peinture', 'archives');
foreach ($listePages as $page)
diff --git a/controller/visitor.php b/controller/visitor.php
index 4f51dda..936eb35 100644
--- a/controller/visitor.php
+++ b/controller/visitor.php
@@ -33,18 +33,9 @@ function melaineVisitor()
$title = "Mais qui est Melaine Favennec?";
// modèle
- $Articles = new ArticlesManager;
- $Articles->setPage($page_actuelle);
- $Articles->getFiles();
- $Articles->reverseFilesArray();
- $articles = $Articles->getAll(); // lourd
-
- // vérification pour protéger les visiteurs
- // normalement déjà faite dans submit.php, au cas où la base a été trafiquée
- foreach ($Articles as $oneArticle)
- {
- $oneArticle = htmLawed($oneArticle);
- }
+ $Articles = new AllArticles($page_actuelle);
+ $Articles->makeFileList();
+ $articles = array_reverse($Articles->readAll()); // lourd
// variables $css, $js, $header et $content
require('view/melaine.php');
@@ -58,7 +49,55 @@ function discoVisitor()
$title = "Discographie";
// modèle
- $Albums = new AlbumsManager;
+ $Albums = new Album($page_actuelle);
+ $Albums->makeFileList();
+ $albumsJSON = array_reverse($Albums->readAll()); // lourd
+
+ // $albums est un tableau de chaines JSON,
+ // chacune renferme 3 variables: titre, année, pochette
+
+ // changer les chaines JSON en tableaux
+ $i = 0;
+ foreach($albumsJSON as $oneAlbum)
+ {
+ $albumsJSON[$i] = json_decode($oneAlbum, true);
+ $i++;
+ }
+
+ // on passe maintenant au contenu HTML
+ $albumNamesJSON = array_reverse($Albums->getFileNames());
+ $Albums->setFormat('html');
+ $Albums->makeFileList();
+ $albumNamesHTML = array_reverse($Albums->getFileNames());
+
+ // pour chaque album, détecter le fichier html
+ // si il y en a un, proposer un lien
+ // si non, ne fournir qu'un lien d'ancre pour la liste d'album
+ $i = 0;
+ //print_r($albumNamesJSON); exit();
+
+ foreach($albumNamesJSON as $oneAlbum)
+ {
+ $chemin = pathinfo($oneAlbum);
+ $nomJSONsansExt = $chemin['filename'];
+ $chemin = pathinfo($albumNamesHTML[0]);
+ $nomHTMLsansExt = $chemin['filename'];
+
+ // détecter un fichier du même nom
+ if(isset($nomJSONsansExt . '.html')) // c'est pas ça!!
+ {
+ //$lienAlbum[$i] = $titreAlbum;
+ }
+ else
+ {
+ //$lienAlbum[$i] = 'discographie#' . $oneAlbum[0];
+ }
+ $i++;
+ }
+ //exit();
+
+
+ //echo($lienAlbum);
// variables $css, $js et $content
require('view/discographie.php');
diff --git a/index.php b/index.php
index dc5f3ba..b9989fd 100644
--- a/index.php
+++ b/index.php
@@ -54,12 +54,13 @@ require('controller/password.php');
installation();
-
// traitement des POST du ckeditor
// 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']) && $_POST['contenu'] != '')
+ // trois possibilités: on a un contenu HTML ou JSON ou les deux
+ && ((isset($_POST['contenu']) && $_POST['contenu'] != '')
+ || (isset($_POST['titre']) && isset($_POST['annee']) && isset($_POST['pochette']))))
{
require('controller/ckeditor.php'); // traitement du POST
require('lib/htmlawed/htmLawed.php'); // failles XSS
@@ -119,7 +120,6 @@ else
}
-
// page du site demandée
if(isset($_GET['page']))
{
diff --git a/model/Classes.php b/model/Classes.php
index e574eeb..1349cd7 100644
--- a/model/Classes.php
+++ b/model/Classes.php
@@ -1,127 +1,137 @@
page = $page;
+ $this->time = time();
+ if($this->page == 'discographie')
+ {
+ $this->format = 'json';
+ }
}
- public function findFileName($numArticle)
+ // GET
+ public function getPage()
{
- $this->fileName = $this->files[$numArticle - 1];
+ return($this->page);
}
- public function setFileName($nomFichier)
+ public function getNbArticles()
{
- $this->fileName = $nomFichier;
+ return($this->nbArticles);
}
-
- // GET
- public function getPage()
+ public function getFileNames()
{
- return($this->page);
+ return($this->files);
}
- public function getFileName()
+ // SET
+ public function setFormat($format)
{
- return($this->fileName);
+ $this->format = $format;
}
-
- public function nbArticles()
+
+ // tableaux des noms des fichiers
+ public function makeFileList()
{
- return($this->nbArticles);
+ $this->files = glob('data/' . $this->page . '/' . $this->format . '/*.' . $this->format);
+ //$this->files = glob('*.' . $this->format);
}
+ /*public function makeFilePath()
+ {}*/
+ // fonctions CRUD (create - read - update - delete)
+
+ // create
- // tableau des noms des articles
- public function getFiles()
+ // read
+ public function readAll()
{
- if($this->page == '')
+ $i = 0;
+ $articles = array();
+ foreach ($this->files as $oneFile)
{
- die("debug: la méthode setPage() doit être appelée avant getFiles().");
+ $articles[$i] = file_get_contents($oneFile);
+ $i++;
}
+ //print_r($articles);
+ return $articles;
+ }
+
+ // update
+
+ // delete
+}
+
+// article créé ou ciblé pour modification/suppression
+class OneArticle extends AllArticles
+{
+ private $fileName; // correspond à $_SESSION['nomFichier']
- $this->files = glob('data/' . $this->page . '/html/*.html');
+ // GET
+ public function getFileName()
+ {
+ return($this->fileName);
}
- // ordre du tableau des noms de fichiers
- public function reverseFilesArray()
+ // SET
+ public function setFileName($nomFichier) // modification
{
- $this->files = array_reverse($this->files);
+ $this->fileName = $nomFichier;
}
+ public function findFileName($numArticle) // nouvel article
+ {
+ $this->fileName = $this->files[$numArticle - 1];
+ }
// fonctions CRUD (create - read - update - delete)
- // ce sont les 4 opérations de base qu'un programme doit permettre pour être complet
-
+
// create
public function create($content)
{
- if($this->page == '')
- {
- die("debug: la méthode setPage() doit être appelée avant toute autre.");
- }
-
- // nommer les fichiers avec le timestamp
- // - trie par ordre chronologique
+ $format = 'html';
+
+ // nommer les fichiers avec le timestamp pour:
+ // - les trier par ordre chronologique
// - rendre quasi impossible d'avoir deux fois le même nom (à la condition de gérer la "concurrence")
- $nom_fichier = 'data/' . $this->page . '/html/' . time() . '.html';
+ $nom_fichier = 'data/' . $this->page . '/' . $format . '/' . $this->time . '.' . $format;
- $fichier = fopen($nom_fichier, 'w'); // w peut créer un fichier, si il existe déjà, il est effacé par le nouveau contenu
+ $fichier = fopen($nom_fichier, 'w'); // w pour créer ou écraser
fputs($fichier, $content);
fclose($fichier);
chmod($nom_fichier, 0666);
}
// read
- public function getNumber()
- {
- return $this->nbArticles;
- }
-
- public function getOne()
+ public function readOne()
{
return(file_get_contents($this->fileName));
}
- public function getAll()
- {
- //$this->getFiles();
-
- $i = 0;
- $articles = array();
- foreach ($this->files as $file)
- {
- $articles[$i] = file_get_contents($file);
- $i++;
- }
-
- //print_r($articles);
- return $articles;
- }
-
- public function getDate($fileNumber)
+ // pour afficher des dates
+ /*public function getDate($fileNumber)
{
// le 2è paramètre exclut le suffixe .html
$timestamp = basename($this->files[$fileNumber], '.html');
return getdate($timestamp);
- }
+ }*/
// update
public function update($content)
{
- $file = fopen($this->fileName, 'w');
- // w peut créer un fichier, si il existe déjà, il est effacé par le nouveau contenu
+ $file = fopen($this->fileName, 'w'); // crée ou écrase
fputs($file, $content);
fclose($file);
//chown($this->fileName, 'http');
@@ -135,39 +145,55 @@ class ArticlesManager
}
}
-// note: les pros font de l'hydration
-// le code du modèle est orienté objet et "refactorisé" d'une manière précise:
-// on utilise un objet pour une chose (des articles, commentaires, etc),
-// un objet article contiendrait ainsi tout le nécessaire pour lire, écrire ou modifier un article
-// il y a pour ça un programme appelé "doctrine" (inclu dans symphony) qui est capable de lire une base de données et d'en écrire les objets PHP
-class AlbumsManager extends ArticlesManager
+class Album extends OneArticle
{
// variables
-
- // SET
+ //private $fileNameJSON; // même nom en .json
+ //protected $format = 'json';
// GET
+ // SET
+
// fonctions CRUD
// create
- //public function create($titre, $annee, $pochette)
- public function create($content)
- //public function create($content, $titre, $annee, $pochette)
- {}
+ public function createVignette($titre, $annee, $pochette)
+ {
+ if($pochette != '')
+ {
+ // enregistrer le fichier
+ // retourner une erreur en cas d'échec de l'upload
+ }
+
+ $albumJSON = json_encode([$titre, $annee, $pochette]);
+
+ $nom_fichier = 'data/' . $this->page . '/' . $this->format . '/' . $this->time . '.' . $this->format;
+
+ $fichier = fopen($nom_fichier, 'w'); // w pour créer ou écraser
+ fputs($fichier, $albumJSON);
+ fclose($fichier);
+ chmod($nom_fichier, 0666);
+ }
// read
public function read()
{}
// update
- //public function update($titre, $annee, $pochette)
- public function update($content)
- //public function update($content, $titre, $annee, $pochette)
+ public function updateVignette($titre, $annee, $pochette)
{}
// delete
public function delete()
{}
-}
\ No newline at end of file
+}
+
+
+
+// note: les pros font de l'hydration
+// le code du modèle est orienté objet et "refactorisé" d'une manière précise:
+// on utilise un objet pour une chose (des articles, commentaires, etc),
+// un objet article contiendrait ainsi tout le nécessaire pour lire, écrire ou modifier un article
+// il y a pour ça un programme appelé "doctrine" (inclu dans symphony) qui est capable de lire une base de données et d'en écrire les objets PHP
\ No newline at end of file
diff --git a/public/discographie.css b/public/discographie.css
index ff622e9..cb0c9b5 100644
--- a/public/discographie.css
+++ b/public/discographie.css
@@ -90,6 +90,12 @@ input
article
{
margin: 5px 0px;
+ width: 45%;
+}
+
+.vignette
+{
+ width: 100%;
}
figure
@@ -97,6 +103,10 @@ figure
margin: 0px;
display: inline-block;
}
+figure:hover
+{
+ border: 2px blue solid;
+}
figcaption
{
@@ -113,10 +123,10 @@ a
display: inline-block;
}
-article a:hover
+/*article a:hover
{
border: 2px blue solid;
-}
+}*/
a:hover figure figcaption
diff --git a/view/discographie.php b/view/discographie.php
index 4eb8e58..47ee377 100644
--- a/view/discographie.php
+++ b/view/discographie.php
@@ -48,12 +48,19 @@ ob_start();
Chronologie
+
+ = $oneAlbum[0] ?> (= $oneAlbum[1] ?>)
+
+
@@ -64,7 +71,7 @@ if($_SESSION['admin'] == 1)
{
?>
Ajouter un album
-= $editeurHTML ?>
+= $editeurHTML ?>
-
+
+
+
+
+ = $oneAlbum[0] ?>
= $oneAlbum[1] ?>
+
+
+
+
Modifier l'article " . $j . "");
- //echo("Modification d'un article
");
+ //echo("\nModifier l'article " . $j . "
");
+ echo("Modification d'un article
");
echo "\n";
echo($editeurHTML); // injection de template-editor.php
diff --git a/view/template.php b/view/template.php
index dad4e17..a14555d 100644
--- a/view/template.php
+++ b/view/template.php
@@ -71,7 +71,7 @@ if($_SESSION['admin'] == 1)