From 787d03e48471ba62cd830379428f04d996f0b74b Mon Sep 17 00:00:00 2001 From: polo Date: Thu, 17 Feb 2022 18:13:00 +0100 Subject: model update --- controller/Security.php | 2 +- controller/admin.php | 372 +++++++++++++++++++++----------------- controller/backup.php | 158 ++++++++--------- controller/ckeditor.php | 290 ++++++++++++++++-------------- controller/installation.php | 190 ++++++++++---------- controller/media.php | 424 ++++++++++++++++++++++---------------------- controller/visitor.php | 275 ++++++++++++++-------------- 7 files changed, 897 insertions(+), 814 deletions(-) (limited to 'controller') diff --git a/controller/Security.php b/controller/Security.php index 98d2e74..6ea121c 100644 --- a/controller/Security.php +++ b/controller/Security.php @@ -4,7 +4,7 @@ // sécurité faille XSS avec htmLawed require('lib/htmlawed/htmLawed.php'); -class Security // toute statique, inutile de l'instancier +class Security { private static $configHtmLawed = array( 'safe'=>1, // protection contre les élements et attributs dangereux diff --git a/controller/admin.php b/controller/admin.php index e319c80..7f22711 100644 --- a/controller/admin.php +++ b/controller/admin.php @@ -1,165 +1,207 @@ -findFileName($numArticle); - $_SESSION['target'] = $Article->fileName; - - // suppression - if($suppression) - { - $Article->delete(); - header('Location: index.php?page=' . $page_actuelle); - exit(); - } - // modification - else - { - $title = "Modifier un article"; - $texte = $Article->readOne(); // entrée de l'éditeur - } - } - - // pour l'affichage des articles - $articles = array_reverse($Article->readAll()); // lourd - - // sécurisation du contenu pré-existant inséré dans l'éditeur - if($numArticle > 0 && !$suppression) - { - require('controller/ckeditor.php'); - $texte = preparationCKeditor($texte); - } - - // NB: penser à ajouter au template la fonctionnalité "autosave" - // https://ckeditor.com/docs/ckeditor5/latest/builds/guides/integration/saving-data.html - - // morceaux en HTML à assembler - // variable $editeurHTML, contient $texte - require('view/template-formulaires.php'); - // variables $css, $js, $header et $content, - // $content contient $articles et $editeurHTML - require('view/melaine.php'); - // fin de l'assemblage - require('view/template.php'); -} - -function discoEdit($albumCode, $suppression) -{ - $page_actuelle = "discographie"; - $title = "Discographie"; - - // modèle - $Albums = new Album($page_actuelle); - $Albums->makeFileList(); - - // nouvel album - if($albumCode == '') - { - unset($_SESSION['target']); - $title = "Ajouter un album"; - - // formulaires vides - $vignette = ['', '', '']; - $texte = ''; - } - else - { - // album ciblé - $Albums->albumCode = $albumCode; - - // suppression - if($suppression) - { - $Albums->delete(); - header('Location: index.php?page=' . $page_actuelle); - exit(); - } - // modification - else - { - $_SESSION['target'] = $Albums->albumCode; - $title = "Modifier un album"; - $texte = $Albums->readOneHTML($albumCode); - $vignette = $Albums->getVignetteJSON(); - } - } - - // traitements PHP pour l'éditeur - // sécurisation du contenu pré-existant inséré dans l'éditeur - if(!empty($albumCode) && !$suppression && !empty($texte)) - { - require('controller/ckeditor.php'); - $texte = preparationCKeditor($texte); - } - - // préremplir le champ - // c'est normallement impossible - - // contenu de tous les fichiers JSON (= tableau de chaines) - $albumsJSON = $Albums->readAll(); - // noms des fichiers JSON - $albumNamesJSON = $Albums->fileList; - - $annees = []; - for($i = 0; $i < count($albumsJSON); $i++) - { - // une case supplémentaire contient le "albumCode" - $albumsJSON[$i][3] = pathinfo($albumNamesJSON[$i])['filename']; - - $annees[$i] = $albumsJSON[$i][1]; - } - - // tri d'un tableau multidimensionnel - array_multisort($annees, $albumsJSON); - - // lien vers le HTML ou ancre? - $avecLien = []; - $linkDiscoChrono = []; - for($i = 0; $i < count($albumsJSON); $i++) - { - // cas particulier où le dossier "html" est vide - if(!empty($Albums->fileList)) - { - if(file_exists('data/discographie/html/' . $albumsJSON[$i][3] . '.html')) - { - $lienAlbum[$i] = 'page=album&album_name=' . $albumsJSON[$i][0] . '&album_code=' . $albumsJSON[$i][3]; - $avecLien[$i] = true; - $linkDiscoChrono[$i] = 'linkChrono'; // css - } - else - { - $lienAlbum[$i] = 'page=discographie#' . $albumsJSON[$i][0]; - $avecLien[$i] = false; - $linkDiscoChrono[$i] = 'noLinkChrono'; // css - } - $lienBoutonModif[$i] = 'page=discographie&action=edition&album_code=' . $albumsJSON[$i][3]; - } - } - - // morceaux en HTML à assembler - // variable $editeurHTML, contient $texte - require('view/template-formulaires.php'); - // variables $css, $js, $header et $content, - // $content contient ???? et $editeurHTML - require('view/discographie.php'); - // fin de l'assemblage - require('view/template.php'); -} +fileCode = $fileCode; + $_SESSION['target'] = $Articles->fileCode; + + // suppression + if($suppression) + { + $Articles->delete(); + + // redirection immédiate avant affichage + header('Location: index.php?page=' . $page_actuelle); + exit(); + } + // modification + else + { + $title = "Modifier un article"; + $texte = $Articles->readOne(); // entrée de l'éditeur + } + } + + // ajout des données dans $Articles->fileList['content'] + if(!empty($Articles->fileList)) + { + $Articles->readAll(); + $Articles->fileList = array_reverse($Articles->fileList); + } + + // sécurisation du contenu pré-existant inséré dans l'éditeur + if(!empty($fileCode) && !$suppression) + { + $fileCodeArgument = '&article=' . $fileCode; + require('controller/ckeditor.php'); + $texte = preparationCKeditor($texte); + } + else + { + $fileCodeArgument = ''; + } + + + // NB: penser à ajouter au template la fonctionnalité "autosave" + // https://ckeditor.com/docs/ckeditor5/latest/builds/guides/integration/saving-data.html + + // morceaux en HTML à assembler + // variable $editeurHTML, contient $texte + require('view/template-formulaires.php'); + // variables $css, $js, $header et $content, + // $content contient $articles et $editeurHTML + require('view/melaine.php'); + // fin de l'assemblage + require('view/template.php'); +} + +function discoEdit($fileCode, $suppression) +{ + $page_actuelle = "discographie"; + $title = "Discographie"; + + // modèle + $Albums = new Album($page_actuelle); + $Albums->makeFileList(); + //var_dump($Albums); + // contenu: JSON, HTML, noms et chemins des fichiers + $Albums->readAll(); + $Albums->fileList = array_reverse($Albums->fileList); + //var_dump($Albums); + //var_dump($Albums->fileList); + + // nouvel album + if($fileCode == '') + { + //echo($_SESSION['target'] . "
"); + //unset($_SESSION['target']); + $title = "Ajouter un album"; + + // formulaires vides + $vignette = ['', '', '']; + $texte = ''; + } + else + { + // album ciblé + $Albums->fileCode = $fileCode; + + // suppression + if($suppression) + { + $Albums->delete(); + header('Location: index.php?page=' . $page_actuelle); + exit(); + } + // modification + else + { + $_SESSION['target'] = $fileCode; + $title = "Modifier un album"; + + for($i = 0; $i < $Albums->fileListCount; $i++) + { + if($fileCode == $Albums->fileList[$i]['fileCode']) + { + // json + $vignette[0] = $Albums->fileList[$i]['titre']; + $vignette[1] = $Albums->fileList[$i]['annee']; + $vignette[2] = $Albums->fileList[$i]['pochette']; + // html + $texte = $Albums->fileList[$i]['HTMLcontent']; + + // image affichée à côté des formulaires + $imageFormulaire = 'data/' . $page_actuelle . '/images/' . $vignette[2]; + } + } + } + } + + // traitements PHP pour l'éditeur + // sécurisation du contenu pré-existant inséré dans l'éditeur + if(!empty($fileCode) && !$suppression && !empty($texte)) + { + // dans l'adresse dans la balise
+ $fileCodeArgument = '&article=' . $fileCode; + + require('controller/ckeditor.php'); + $texte = preparationCKeditor($texte); + } + else + { + $fileCodeArgument = ''; + } + + // préremplir le champ + // c'est normallement impossible + + + // tri des albums avec l'année dans le .json + + // noms des fichiers JSON + //$albumNamesJSON = $Albums->fileList; + //$annees = []; + for($i = 0; $i < $Albums->fileListCount; $i++) + { + // une case supplémentaire contient le "fileCode" + //$albumsJSON[$i][3] = pathinfo($albumNamesJSON[$i])['filename']; + //$albumsJSON[$i][3] = pathinfo($Albums->fileList[$i]['fileCode'])['filename']; + + //$annees[$i] = $albumsJSON[$i][1]; + } + //var_dump($annee); die(); + + // tri d'un tableau multidimensionnel + //array_multisort($annees, $albumsJSON); + + + + // liens dans la page et le menu chronologie + // ce dernier comporte une ancre lorsque le html n'existe pas + /*$lienAlbum = []; + $avecLien = []; + $linkDiscoChrono = [];*/ + for($i = 0; $i < $Albums->fileListCount; $i++) + { + if(file_exists('data/discographie/html/' . $Albums->fileList[$i]['fileCode'] . '.html')) + { + $lienAlbum[$i] = 'page=album&album_name=' . $Albums->fileList[$i]['titre'] . '&file_code=' . $Albums->fileList[$i]['fileCode']; + $avecLien[$i] = true; + $linkDiscoChrono[$i] = 'linkChrono'; // css + } + else + { + $lienAlbum[$i] = 'page=discographie#' . $Albums->fileList[$i]['titre']; + $avecLien[$i] = false; + $linkDiscoChrono[$i] = 'noLinkChrono'; // css + } + $lienBoutonModif[$i] = 'page=discographie&action=edition&file_code=' . $Albums->fileList[$i]['fileCode']; + } + + // morceaux en HTML à assembler + // variable $editeurHTML, contient $texte + require('view/template-formulaires.php'); + // variables $css, $js, $header et $content, + // $content contient ???? et $editeurHTML + require('view/discographie.php'); + // fin de l'assemblage + require('view/template.php'); +} diff --git a/controller/backup.php b/controller/backup.php index bc84a86..d0060c9 100644 --- a/controller/backup.php +++ b/controller/backup.php @@ -1,80 +1,80 @@ - - Veuillez prévenir l\'administrateur.
- Vous pouvez aussi récupérer manuellement les fichiers en vous connectant au serveur avec un client FTP, il suffit de récupérer tout le dossier "data".

- Retour au site'); - die(); - } - - // création du fichier zip vide - // j'ai utilisé l'option ZipArchive::OVERWRITE, - // ZipArchive::FL_OVERWRITE n'apparaît qu'avec PHP 8 - if ($zip->open($chemin . $nomFichier, ZipArchive::CREATE | ZipArchive::OVERWRITE)!==TRUE) { - exit("Impossible d'ouvrir le fichier " . $chemin . $nomFichier . ".\n"); - } - - // ajout des fichiers - // chemin complet = data/"pages"/"html ou images"/"tous les fichiers" - $zip->addGlob($chemin . '*/*/*', 0, array('')); - $zip->close(); - - // pour pouvoir manipuler le fichier depuis filezilla ou ssh - chmod($chemin . $nomFichier, 0666); // écriture 4 chiffres - -?> - - - extraction des données - - - -
- Toutes les données du sites ont été rassemblées dans un gros fichier que vous pouvez garder par exemple sur votre ordinateur.
- Vous pourrez l'utiliser plus tard pour restaurer le site dans l'état où il se trouve aujourd'hui. Ceci est utile dans le cas d'un changement d'hébergement ou dans le cas d'un problème affectant le serveur.
- Ce fichier se nomme sauvegarde_site_melaine.zip.

- Cliquez ici pour télécharger

- Retour au site -
- - - - - Restauration des données avec un backup - - - -
- Restauration des données à partir d'une sauvegarde.

- Vous devez avoir créé un fichier nommé sauvegarde_site_melaine.zip
- en cliquant sur Extraire les données.

- - -
- -

- Retour au site - -
- - + Veuillez prévenir l\'administrateur.
+ Vous pouvez aussi récupérer manuellement les fichiers en vous connectant au serveur avec un client FTP, il suffit de récupérer tout le dossier "data".

+ Retour au site'); + die(); + } + + // création du fichier zip vide + // j'ai utilisé l'option ZipArchive::OVERWRITE, + // ZipArchive::FL_OVERWRITE n'apparaît qu'avec PHP 8 + if ($zip->open($chemin . $nomFichier, ZipArchive::CREATE | ZipArchive::OVERWRITE)!==TRUE) { + exit("Impossible d'ouvrir le fichier " . $chemin . $nomFichier . ".\n"); + } + + // ajout des fichiers + // chemin complet = data/"pages"/"html ou images"/"tous les fichiers" + $zip->addGlob($chemin . '*/*/*', 0, array('')); + $zip->close(); + + // pour pouvoir manipuler le fichier depuis filezilla ou ssh + chmod($chemin . $nomFichier, 0666); // écriture 4 chiffres + +?> + + + extraction des données + + + +
+ Toutes les données du sites ont été rassemblées dans un gros fichier que vous pouvez garder par exemple sur votre ordinateur.
+ Vous pourrez l'utiliser plus tard pour restaurer le site dans l'état où il se trouve aujourd'hui. Ceci est utile dans le cas d'un changement d'hébergement ou dans le cas d'un problème affectant le serveur.
+ Ce fichier se nomme sauvegarde_site_melaine.zip.

+ Cliquez ici pour télécharger

+ Retour au site +
+ + + + + Restauration des données avec un backup + + + +
+ Restauration des données à partir d'une sauvegarde.

+ Vous devez avoir créé un fichier nommé sauvegarde_site_melaine.zip
+ en cliquant sur Extraire les données.

+ +
+
+ +

+ Retour au site +
+
+ +createVignette($titre, $annee, $pochette); - - // page de l'album - if(!empty($_POST['contenu'])) - { - $Album->create($contenu); - } - } - else - { - $Album->albumCode = $target; - - // page disco - $_SESSION['erreur'] = $Album->updateVignetteJSON($titre, $annee, $pochette); - - // page de l'album - if(isset($_POST['contenu'])) - { - $Album->format = 'html'; - $Album->setFileName(); - if(!empty($Album->fileName)) - { - $Album->update($_POST['contenu']); - } - } - } - } - // autres pages - else - { - $Article = new Page($page); - - if($target == '') - { - $Article->create($contenu); - } - else - { - $Article->fileName = $target; - $Article->update($contenu); - } - } -} - -// lien sans http:// -// un clic sur un lien dans l'éditeur affiche une infobulle montrant l'adresse cible du lien si celle-ci a déjà été précisée -// il est possible de cliquer sur ce lien, ce qui ouvre un onglet avec le site demandé -// toutefois si cette adresse est de type "domaine.fr" (sans http:// devant), le navigateur ne va pas rechercher un site mais un fichier comme si mon adresse était de type file:///fichier -// tomber ainsi sur une page d'erreur est déroutant: -// "ai-je perdu le texte que j'étais en train de taper?"" -// solution 1 (mauvaise): activer la redirection en cas d'erreur 404 dans le .htaccess -// 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... - -function cleanHTML($contenu) -{} +create($contenu); + } + else + { + $Article->fileCode = $_SESSION['target']; // erreur ici? + $Article->update($contenu); + } + } + // page discographie + else if($page == 'discographie') + { + $Album = new Album($page); + + // on retrouve les données si nécessaire + if(isset($_SESSION['target']) && $_SESSION['target'] != '') + { + $Album->fileCode = $_SESSION['target']; + $Album->readOne(); + } + + $nouveauTitre = Security::secureString($_POST['titre']); + $nouvelleAnnee = Security::secureString($_POST['annee']); + $nouvellePochette = $_FILES['upload']['name']; + + // enregistrement nouvel album + if(!isset($_SESSION['target']) || $_SESSION['target'] == '') + { + // page disco + $Album->createVignette($nouveauTitre, $nouvelleAnnee, $nouvellePochette); + + // page de l'album + if(!empty($_POST['contenu'])) + { + $Album->format = 'html'; + $Album->create($contenu); + } + } + // modification + else + { + $Album->albumCode = $_SESSION['target']; + + // page disco + $Album->format = 'json'; + + // garder l'image si aucune n'est sélectionnée + // (on ne peut pas préremplir un ) + if($nouvellePochette == '' && $Album->oneAlbum['pochette'] != '') + { + $nouvellePochette = $Album->oneAlbum['pochette']; + } + + $Album->updateVignetteJSON($nouveauTitre, $nouvelleAnnee, $nouvellePochette); + + // page de l'album + if(isset($_POST['contenu'])) + { + //var_dump($Album->oneAlbum); die(); + $Album->format = 'html'; + //$Album->setFileName(); + if(!empty($Album->oneAlbum['HTMLfileName'])) + { + $Album->update($_POST['contenu']); + } + } + } + } + + // nettoyage + unset($_SESSION['target']); + unset($_GET['action']); + unset($_POST['contenu']); + header('Location: index.php?page=' . $_GET['page']); + exit(); +} + + +// lien sans http:// +// un clic sur un lien dans l'éditeur affiche une infobulle montrant l'adresse cible du lien si celle-ci a déjà été précisée +// il est possible de cliquer sur ce lien, ce qui ouvre un onglet avec le site demandé +// toutefois si cette adresse est de type "domaine.fr" (sans http:// devant), le navigateur ne va pas rechercher un site mais un fichier comme si mon adresse était de type file:///fichier +// tomber ainsi sur une page d'erreur est déroutant: +// "ai-je perdu le texte que j'étais en train de taper?"" +// solution 1 (mauvaise): activer la redirection en cas d'erreur 404 dans le .htaccess +// 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... + +function cleanHTML($contenu) +{} diff --git a/controller/installation.php b/controller/installation.php index fc8c900..91521e2 100644 --- a/controller/installation.php +++ b/controller/installation.php @@ -1,95 +1,95 @@ -'); - //echo('server name: ' . $_SERVER['SERVER_NAME'] . '
'); - // echo('dirname: ' . dirname(__FILE__) . '
'); - // echo('file: ' . __FILE__ . '
'); - // echo('dir: ' . __DIR__. '
'); - - //$lien_htaccess = $_SERVER['SERVER_NAME'] . "/.htaccess"; - //$nomDuSite = "melaine"; - - // créer le .htaccess - 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"; - // $fichier = fopen('.htaccess', 'w'); - // fputs($fichier, $contenu); - // fclose($fichier); - // chmod('.htaccess', 0666); // mettre 0644 en production - } - - // droits en lecture et écriture dans le cas d'une migration - // tester si le site est "vide" et prévoir un formulaire permettant d'upload le fichier .zip - // contenant toutes les données qu'il est possible de créer depuis le mode admin - // cette méthode a deux intérêts: - // - facilité pour l'utilisateur - // - toutes les données sont la "possession" du serveur apache, - // on prévient ainsi tous les futurs problèmes de droits - - // dans le cas de l'utilisation d'une base de données, le fichiers zip devrait contenir un "dump" - // (un fichier .sql), à voir si php est capable d'obtenir ou redonner ce fichier à la BDD - - // créer les dossiers (fait également à l'extraction du zip de données) - // attention: ne fonctionne pas sans une manipulation préalable - // - modifier soit-même les droits du dossier data (777), quoique 111 serait pas mal non plus - // - 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 - $droitsDossiers = 0777; // mettre 0700 à la fin - - $listePages = array('melaine', 'discographie', 'concerts', 'presse', 'ateliers', 'liens', 'peinture', 'archives'); - foreach ($listePages as $page) - { - if(!file_exists('data/' . $page)) - { - mkdir('data/' . $page); - chmod('data/' . $page, $droitsDossiers); - } - if(!file_exists('data/' . $page . '/html')) - { - mkdir('data/' . $page . '/html'); - chmod('data/' . $page . '/html', $droitsDossiers); - } - if(!file_exists('data/' . $page . '/images')) - { - mkdir('data/' . $page . '/images'); - chmod('data/' . $page . '/images', $droitsDossiers); - } - // if(!file_exists('data/' . $page . '/multimedia')) - // { - // mkdir('data/' . $page . '/multimedia'); - // chmod('data/' . $page . '/multimedia', 0777); - // } - } - // dossier supplémentaire dans discographie - if(!file_exists('data/discographie/json')) - { - mkdir('data/discographie/json'); - chmod('data/discographie/json', $droitsDossiers); - } - // fichier password.txt - if(!file_exists('data/password.txt')) - { - touch('data/password.txt'); - chmod('data/password.txt', 0600); - } - - // le modèle donnera les droits 0666 (octal) aux nouveaux fichiers à l'intérieur des dossiers - - // création d'un mot de passe si password.txt est vide - createPassword(); -} +'); + //echo('server name: ' . $_SERVER['SERVER_NAME'] . '
'); + // echo('dirname: ' . dirname(__FILE__) . '
'); + // echo('file: ' . __FILE__ . '
'); + // echo('dir: ' . __DIR__. '
'); + + //$lien_htaccess = $_SERVER['SERVER_NAME'] . "/.htaccess"; + //$nomDuSite = "melaine"; + + // créer le .htaccess + 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"; + // $fichier = fopen('.htaccess', 'w'); + // fputs($fichier, $contenu); + // fclose($fichier); + // chmod('.htaccess', 0666); // mettre 0644 en production + } + + // droits en lecture et écriture dans le cas d'une migration + // tester si le site est "vide" et prévoir un formulaire permettant d'upload le fichier .zip + // contenant toutes les données qu'il est possible de créer depuis le mode admin + // cette méthode a deux intérêts: + // - facilité pour l'utilisateur + // - toutes les données sont la "possession" du serveur apache, + // on prévient ainsi tous les futurs problèmes de droits + + // dans le cas de l'utilisation d'une base de données, le fichiers zip devrait contenir un "dump" + // (un fichier .sql), à voir si php est capable d'obtenir ou redonner ce fichier à la BDD + + // créer les dossiers (fait également à l'extraction du zip de données) + // attention: ne fonctionne pas sans une manipulation préalable + // - modifier soit-même les droits du dossier data (777), quoique 111 serait pas mal non plus + // - 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 + $droitsDossiers = 0777; // mettre 0700 à la fin + + $listePages = array('melaine', 'discographie', 'concerts', 'presse', 'ateliers', 'liens', 'peinture', 'archives'); + foreach ($listePages as $page) + { + if(!file_exists('data/' . $page)) + { + mkdir('data/' . $page); + chmod('data/' . $page, $droitsDossiers); + } + if(!file_exists('data/' . $page . '/html')) + { + mkdir('data/' . $page . '/html'); + chmod('data/' . $page . '/html', $droitsDossiers); + } + if(!file_exists('data/' . $page . '/images')) + { + mkdir('data/' . $page . '/images'); + chmod('data/' . $page . '/images', $droitsDossiers); + } + // if(!file_exists('data/' . $page . '/multimedia')) + // { + // mkdir('data/' . $page . '/multimedia'); + // chmod('data/' . $page . '/multimedia', 0777); + // } + } + // dossier supplémentaire dans discographie + if(!file_exists('data/discographie/json')) + { + mkdir('data/discographie/json'); + chmod('data/discographie/json', $droitsDossiers); + } + // fichier password.txt + if(!file_exists('data/password.txt')) + { + touch('data/password.txt'); + chmod('data/password.txt', 0600); + } + + // le modèle donnera les droits 0666 (octal) aux nouveaux fichiers à l'intérieur des dossiers + + // création d'un mot de passe si password.txt est vide + createPassword(); +} diff --git a/controller/media.php b/controller/media.php index 8105b4d..c6682df 100644 --- a/controller/media.php +++ b/controller/media.php @@ -1,212 +1,212 @@ - - - // on vire les balises et ce qu'il y a entre les deux pour ne garder que les liens - // on pourra ensuite traiter ensemble les url avec et sans balises - // (?:) permet de matcher sans capturer, donc de retirer des choses - // pour la variable $tolere, on met: - // \w = [a-zA-Z0-9_], espace ' ', tabulation \t, CR et LF \r\n, - // /, @, %, deux-points ';', virgule ',' et point-virgule ; - // et devant être échappés: . # ( ) ] { } ? ! | et le tiret qui est placé au début ou la fin - $tolere = '\w\s\t\n\r/,;:éèàçù€\#@%\.\(\)[\]\{\}\?\!\|-'; - $pattern = '#(?:[' . $tolere . ']+)#'; - $chaine = preg_replace($pattern, '$2', $chaine); - //echo($chaine . "\n"); - - // on met les balises - $pattern = '#' . $regexListeNonGeree . '#'; - $remplacement = '$0'; - $chaine = preg_replace($pattern, $remplacement, $chaine); - - // c'est quoi cette merde? - // l'API DOM de PHP bien sur!! pour manipuler le "document object model" - // c'est du complètement calqué sur le javascript, avec une syntaxe PHP - // et en plus elle est super vieille, elle ne connaît pas les balises HTML5 ! - // mais une balise c'est une balise donc ça marche quand même - // la doc de PHP est comme toujours plutôt bonne, elle indique les types de données manipulées - // https://www.php.net/manual/fr/book.dom.php - $dom = new DOMDocument; - - // pour ne pas s'arrêter sur les erreurs à cause des "nouvelles" balises - libxml_use_internal_errors(true); - - if($dom->loadHTML($chaine)) // et non load() tout court qui sert à charger du XML - { - //
- // détecter
- // puis extraire le lien et supprimer les balises autour - if(preg_match("#
#", $chaine)) - { - $nbFigures = $dom->getElementsByTagName('figure')->length; - - $j = 0; - for($i = 0; $i < $nbFigures ; $i++) // boucle foreach impossible, une
disparaît à chaque tour - { - $balisesFigure = $dom->getElementsByTagName('figure'); - $figure = $balisesFigure->item($j); // l'item 1 devient 0 au deuxième passage, etc - $parent = $figure->parentNode; - - if($figure->getAttribute("class") == 'media') - { - $oembed = $figure->getElementsByTagName('oembed'); // tableau d'une seule case - $div = $figure->getElementsByTagName('div'); // tableau d'une seule case - if($oembed->length > 0) // si taille = 0, c'est que la balise figure contient autre chose qu'une oembed - { - $lien = $oembed->item(0)->getAttribute('url') . ' '; // un espace pour ne pas coller deux adresses - $span = $dom->createElement('span', $lien); - $class = $dom->createAttribute('class'); - $class->value = 'media_embed'; - $span->appendChild($class); - $parent->replaceChild($span, $figure); - } - elseif($div->length > 0) // cette div créée par le ckeditor contient notre lien, plus bas se trouve une iframe - { - $lien = $div->item(0)->getAttribute('data-oembed-url') . ' '; - $span = $dom->createElement('span', $lien); - $class = $dom->createAttribute('class'); - $class->value = 'media_embed'; - $span->appendChild($class); - $parent->replaceChild($span, $figure); - } - else - { - $j++; // la balise
n'est pas supprimée, on incrémente l'indice du tableau pour ne pas boucler à l'infini - } - } - } - } - - // #", $chaine)) - { - $nbIframes = $dom->getElementsByTagName('iframe')->length; - - for($i = 0; $i < $nbIframes ; $i++) - { - $balisesIframe = $dom->getElementsByTagName('iframe'); - $iframe = $balisesIframe->item(0); - $parent = $iframe->parentNode; - - $lien = $iframe->getAttribute('src') . ' '; - $span = $dom->createElement('span', $lien); - $class = $dom->createAttribute('class'); - $class->value = 'media_embed'; - $span->appendChild($class); - $parent->replaceChild($span, $$iframe); - } - } - - // - // pour tout les sites multimedia, remplacer les balises par les liens nus - // en effet, en revenant dans l'éditeur les liens ne déclenchent pas automatiquement "l'embarquement" - // cliquer à la fin d'un lien et passer à la ligne a pour effet de créer des balises - // ça pose un problème parce que la bibliothèque "embera" ne gère pas les liens dans des balises - if(preg_match("#.*#", $chaine)) - { - $nbA = $dom->getElementsByTagName('a')->length; - - $j = 0; - for($i = 0; $i < $nbA ; $i++) - { - $balisesA = $dom->getElementsByTagName('a'); - $a = $balisesA->item($j); - $parent = $a->parentNode; - - $lien = $a->getAttribute('href') . ' '; - - // seules les liens pointant vers une des adresses de la liste sont concernés - if(preg_match("#" . $listeMedia . "#", $lien)) - { - $span = $dom->createElement('span', $lien); - $class = $dom->createAttribute('class'); - $class->value = 'media_embed'; - $span->appendChild($class); - $parent->replaceChild($span, $a); - } - else - { - $j++; // la balise n'est pas supprimée, on incrémente l'indice du tableau pour ne pas boucler à l'infini - } - } - } - - // pour nettoyer tous les warnings qu'on vient de produire et purifier nos fichiers log - libxml_clear_errors(); - // pour au contraire pouvoir les regarder, remplacer la ligne au dessus par celles en dessous - //~ $errors = libxml_get_errors(); - //~ var_dump($errors); - - // mettre à jour le DOM et enlever le DOCTYPE et les balises et - $chaine = $dom->saveHTML($dom); - $pattern = array ('##', '##', '##'); - $remplacement = array ('', '', ''); - $chaine = preg_replace($pattern, $remplacement, $chaine); - } - else - { - echo "Impossible de charger le HTML"; - } - - - - // détecter soundcloud - // normallement il n'y a rien à faire ici mais on sait jamais (une mise à jour du ckeditor?) - if(preg_match("#soundcloud.com#", $chaine)) - {} - - // détecter facebook (éventuellement fb.watch) - // je crois que ça va être compliqué ici - if(preg_match("#facebook.com|fb.watch#", $chaine)) - {} - - return($chaine); // = $contenu -} - - -// embarquement !! -function mediaEmbed($chaine) -{ - //require("../Embera/src/Autoloader.php"); - //$embera = new Embera\Embera(); - //$chaine = $embera->autoEmbed($chaine); - - $pattern = '#(.+)#'; - $remplacement = ''; - $chaine = preg_replace($pattern, $remplacement, $chaine); - - // requête oembed - //~ echo('

'); - //~ print_r($embera->getUrlData([ - //~ 'https://vimeo.com/374131624', - //~ 'https://www.flickr.com/photos/bees/8597283706/in/photostream', - //~ ])); - - return($chaine); // = $contenu -} + + + // on vire les balises
et ce qu'il y a entre les deux pour ne garder que les liens + // on pourra ensuite traiter ensemble les url avec et sans balises + // (?:) permet de matcher sans capturer, donc de retirer des choses + // pour la variable $tolere, on met: + // \w = [a-zA-Z0-9_], espace ' ', tabulation \t, CR et LF \r\n, + // /, @, %, deux-points ';', virgule ',' et point-virgule ; + // et devant être échappés: . # ( ) ] { } ? ! | et le tiret qui est placé au début ou la fin + $tolere = '\w\s\t\n\r/,;:éèàçù€\#@%\.\(\)[\]\{\}\?\!\|-'; + $pattern = '#(?:[' . $tolere . ']+)#'; + $chaine = preg_replace($pattern, '$2', $chaine); + //echo($chaine . "\n"); + + // on met les balises + $pattern = '#' . $regexListeNonGeree . '#'; + $remplacement = '$0'; + $chaine = preg_replace($pattern, $remplacement, $chaine); + + // c'est quoi cette merde? + // l'API DOM de PHP bien sur!! pour manipuler le "document object model" + // c'est du complètement calqué sur le javascript, avec une syntaxe PHP + // et en plus elle est super vieille, elle ne connaît pas les balises HTML5 ! + // mais une balise c'est une balise donc ça marche quand même + // la doc de PHP est comme toujours plutôt bonne, elle indique les types de données manipulées + // https://www.php.net/manual/fr/book.dom.php + $dom = new DOMDocument; + + // pour ne pas s'arrêter sur les erreurs à cause des "nouvelles" balises + libxml_use_internal_errors(true); + + if($dom->loadHTML($chaine)) // et non load() tout court qui sert à charger du XML + { + //
+ // détecter
+ // puis extraire le lien et supprimer les balises autour + if(preg_match("#
#", $chaine)) + { + $nbFigures = $dom->getElementsByTagName('figure')->length; + + $j = 0; + for($i = 0; $i < $nbFigures ; $i++) // boucle foreach impossible, une
disparaît à chaque tour + { + $balisesFigure = $dom->getElementsByTagName('figure'); + $figure = $balisesFigure->item($j); // l'item 1 devient 0 au deuxième passage, etc + $parent = $figure->parentNode; + + if($figure->getAttribute("class") == 'media') + { + $oembed = $figure->getElementsByTagName('oembed'); // tableau d'une seule case + $div = $figure->getElementsByTagName('div'); // tableau d'une seule case + if($oembed->length > 0) // si taille = 0, c'est que la balise figure contient autre chose qu'une oembed + { + $lien = $oembed->item(0)->getAttribute('url') . ' '; // un espace pour ne pas coller deux adresses + $span = $dom->createElement('span', $lien); + $class = $dom->createAttribute('class'); + $class->value = 'media_embed'; + $span->appendChild($class); + $parent->replaceChild($span, $figure); + } + elseif($div->length > 0) // cette div créée par le ckeditor contient notre lien, plus bas se trouve une iframe + { + $lien = $div->item(0)->getAttribute('data-oembed-url') . ' '; + $span = $dom->createElement('span', $lien); + $class = $dom->createAttribute('class'); + $class->value = 'media_embed'; + $span->appendChild($class); + $parent->replaceChild($span, $figure); + } + else + { + $j++; // la balise
n'est pas supprimée, on incrémente l'indice du tableau pour ne pas boucler à l'infini + } + } + } + } + + // #", $chaine)) + { + $nbIframes = $dom->getElementsByTagName('iframe')->length; + + for($i = 0; $i < $nbIframes ; $i++) + { + $balisesIframe = $dom->getElementsByTagName('iframe'); + $iframe = $balisesIframe->item(0); + $parent = $iframe->parentNode; + + $lien = $iframe->getAttribute('src') . ' '; + $span = $dom->createElement('span', $lien); + $class = $dom->createAttribute('class'); + $class->value = 'media_embed'; + $span->appendChild($class); + $parent->replaceChild($span, $$iframe); + } + } + + // + // pour tout les sites multimedia, remplacer les balises par les liens nus + // en effet, en revenant dans l'éditeur les liens ne déclenchent pas automatiquement "l'embarquement" + // cliquer à la fin d'un lien et passer à la ligne a pour effet de créer des balises + // ça pose un problème parce que la bibliothèque "embera" ne gère pas les liens dans des balises + if(preg_match("#.*#", $chaine)) + { + $nbA = $dom->getElementsByTagName('a')->length; + + $j = 0; + for($i = 0; $i < $nbA ; $i++) + { + $balisesA = $dom->getElementsByTagName('a'); + $a = $balisesA->item($j); + $parent = $a->parentNode; + + $lien = $a->getAttribute('href') . ' '; + + // seules les liens pointant vers une des adresses de la liste sont concernés + if(preg_match("#" . $listeMedia . "#", $lien)) + { + $span = $dom->createElement('span', $lien); + $class = $dom->createAttribute('class'); + $class->value = 'media_embed'; + $span->appendChild($class); + $parent->replaceChild($span, $a); + } + else + { + $j++; // la balise n'est pas supprimée, on incrémente l'indice du tableau pour ne pas boucler à l'infini + } + } + } + + // pour nettoyer tous les warnings qu'on vient de produire et purifier nos fichiers log + libxml_clear_errors(); + // pour au contraire pouvoir les regarder, remplacer la ligne au dessus par celles en dessous + //~ $errors = libxml_get_errors(); + //~ var_dump($errors); + + // mettre à jour le DOM et enlever le DOCTYPE et les balises et + $chaine = $dom->saveHTML($dom); + $pattern = array ('##', '##', '##'); + $remplacement = array ('', '', ''); + $chaine = preg_replace($pattern, $remplacement, $chaine); + } + else + { + echo "Impossible de charger le HTML"; + } + + + + // détecter soundcloud + // normallement il n'y a rien à faire ici mais on sait jamais (une mise à jour du ckeditor?) + if(preg_match("#soundcloud.com#", $chaine)) + {} + + // détecter facebook (éventuellement fb.watch) + // je crois que ça va être compliqué ici + if(preg_match("#facebook.com|fb.watch#", $chaine)) + {} + + return($chaine); // = $contenu +} + + +// embarquement !! +function mediaEmbed($chaine) +{ + //require("../Embera/src/Autoloader.php"); + //$embera = new Embera\Embera(); + //$chaine = $embera->autoEmbed($chaine); + + $pattern = '#(.+)#'; + $remplacement = ''; + $chaine = preg_replace($pattern, $remplacement, $chaine); + + // requête oembed + //~ echo('

'); + //~ print_r($embera->getUrlData([ + //~ 'https://vimeo.com/374131624', + //~ 'https://www.flickr.com/photos/bees/8597283706/in/photostream', + //~ ])); + + return($chaine); // = $contenu +} diff --git a/controller/visitor.php b/controller/visitor.php index 6c6146b..6044676 100644 --- a/controller/visitor.php +++ b/controller/visitor.php @@ -1,131 +1,146 @@ -readAll()); // lourd - - // variables $css, $js, $header et $content - require('view/melaine.php'); - // HTML - require('view/template.php'); -} - -function discoVisitor() -{ - $page_actuelle = "discographie"; - $title = "Discographie"; - - // modèle - $Albums = new Album($page_actuelle); - $Albums->makeFileList(); - - // contenu de tous les fichiers JSON (= tableau de chaines) - $albumsJSON = $Albums->readAll(); - // noms des fichiers JSON - $albumNamesJSON = $Albums->fileList; - - $annees = []; - for($i = 0; $i < count($albumsJSON); $i++) - { - // une case supplémentaire contient le "albumCode" - $albumsJSON[$i][3] = pathinfo($albumNamesJSON[$i])['filename']; - - $annees[$i] = $albumsJSON[$i][1]; - } - - // tri d'un tableau multidimensionnel - array_multisort($annees, $albumsJSON); - - // lien vers le HTML ou ancre? - $lienAlbum = []; - $avecLien = []; - $linkDiscoChrono = []; - for($i = 0; $i < count($albumsJSON); $i++) - { - // cas particulier où le dossier "html" est vide - if(!empty($Albums->fileList)) - { - if(file_exists('data/discographie/html/' . $albumsJSON[$i][3] . '.html')) - { - $lienAlbum[$i] = 'page=album&album_name=' . $albumsJSON[$i][0] . '&album_code=' . $albumsJSON[$i][3]; - $avecLien[$i] = true; - $linkDiscoChrono[$i] = 'linkChrono'; // css - } - else - { - $lienAlbum[$i] = 'page=discographie#' . $albumsJSON[$i][0]; - $avecLien[$i] = false; - $linkDiscoChrono[$i] = 'noLinkChrono'; // css - } - $lienBoutonModif[$i] = 'page=discographie&action=edition&album_code=' . $albumsJSON[$i][3]; - } - } - - // variables $css, $js et $content - require('view/discographie.php'); - // fin de l'assemblage - require('view/template.php'); -} - -// page d'un album -function album($albumCode, $albumName) -{ - $page_actuelle = 'discographie'; - $title = $albumName; - - $album = Album::readOneHTML($albumCode); // simple, efficace - - // variables $css, $header et $content - require('view/album.php'); - // HTML - require('view/template.php'); -} - -function presse() -{} - -function ateliers() -{} - -function liens() -{} - -function peinture() -{} - -function archives() +fileList[$i]['date']); + //getdate($Albums->fileList[$i]['fileCode']); + + // ajout des données dans $Articles->fileList['content'] + if(!empty($Articles->fileList)) + { + $Articles->readAll(); + $Articles->fileList = array_reverse($Articles->fileList); + } + + // variables $css, $js, $header et $content + require('view/melaine.php'); + // HTML + require('view/template.php'); +} + +function discoVisitor() +{ + $page_actuelle = "discographie"; + $title = "Discographie"; + + // modèle + $Albums = new Album($page_actuelle); + $Albums->makeFileList(); + + // on récupère tout: JSON, HTML, noms et chemins des fichiers + $Albums->readAll(); + $Albums->fileList = array_reverse($Albums->fileList); + //var_dump($Albums->fileList); die(); + + + + // tri des albums avec l'année dans le .json + + // noms des fichiers JSON + //$albumNamesJSON = $Albums->fileList; + + //$annees = []; + for($i = 0; $i < $Albums->fileListCount; $i++) + { + // une case supplémentaire contient le "fileCode" + //$albumsJSON[$i][3] = pathinfo($albumNamesJSON[$i])['filename']; + //$albumsJSON[$i][3] = pathinfo($Albums->fileList[$i]['fileCode'])['filename']; + + //$annees[$i] = $albumsJSON[$i][1]; + } + //var_dump($annee); die(); + + // tri d'un tableau multidimensionnel + //array_multisort($annees, $albumsJSON); + + + + // lien vers le HTML ou ancre? + /*$lienAlbum = []; + $avecLien = []; + $linkDiscoChrono = [];*/ + for($i = 0; $i < $Albums->fileListCount; $i++) + { + if(file_exists('data/discographie/html/' . $Albums->fileList[$i]['fileCode'] . '.html')) + { + $lienAlbum[$i] = 'page=album&album_name=' . $Albums->fileList[$i]['titre'] . '&file_code=' . $Albums->fileList[$i]['fileCode']; + $avecLien[$i] = true; + $linkDiscoChrono[$i] = 'linkChrono'; // css + } + else + { + $lienAlbum[$i] = 'page=discographie#' . $Albums->fileList[$i]['titre']; + $avecLien[$i] = false; + $linkDiscoChrono[$i] = 'noLinkChrono'; // css + } + $lienBoutonModif[$i] = 'page=discographie&action=edition&file_code=' . $Albums->fileList[$i]['fileCode']; + } + + // variables $css, $js et $content + require('view/discographie.php'); + // fin de l'assemblage + require('view/template.php'); +} + +// page d'un album +function album($fileCode, $albumName) +{ + $page_actuelle = 'discographie'; + $title = $albumName; + + $album = Album::readOneHTML($fileCode); // simple, efficace + + // variables $css, $header et $content + require('view/album.php'); + // HTML + require('view/template.php'); +} + +function presse() +{} + +function ateliers() +{} + +function liens() +{} + +function peinture() +{} + +function archives() {} \ No newline at end of file -- cgit v1.2.3