summaryrefslogtreecommitdiff
path: root/controller
diff options
context:
space:
mode:
authorpolo <ordipolo@gmx.fr>2022-02-17 18:13:00 +0100
committerpolo <ordipolo@gmx.fr>2022-02-17 18:13:00 +0100
commit787d03e48471ba62cd830379428f04d996f0b74b (patch)
treee9f98c7b9288c4530b50985688dd82622106ba2d /controller
parent29df6f1362745eabf4fbcaedf309eb63795152fa (diff)
downloadmelaine-787d03e48471ba62cd830379428f04d996f0b74b.zip
model update
Diffstat (limited to 'controller')
-rw-r--r--controller/Security.php2
-rw-r--r--controller/admin.php372
-rw-r--r--controller/backup.php158
-rw-r--r--controller/ckeditor.php290
-rw-r--r--controller/installation.php190
-rw-r--r--controller/media.php424
-rw-r--r--controller/visitor.php275
7 files changed, 897 insertions, 814 deletions
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 @@
4// sécurité faille XSS avec htmLawed 4// sécurité faille XSS avec htmLawed
5require('lib/htmlawed/htmLawed.php'); 5require('lib/htmlawed/htmLawed.php');
6 6
7class Security // toute statique, inutile de l'instancier 7class Security
8{ 8{
9 private static $configHtmLawed = array( 9 private static $configHtmLawed = array(
10 'safe'=>1, // protection contre les élements et attributs dangereux 10 '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 @@
1<?php 1<?php
2// controller/admin.php 2// controller/admin.php
3// 3//
4// utilisation du site en écriture (admin uniquement) 4// utilisation du site en écriture (admin uniquement)
5// l'éditeur ouvert ou demande de suppression d'un élément 5// éditeur ouvert ou suppression d'un élément
6 6
7function melaineEdit($numArticle, $suppression) 7function melaineEdit($fileCode, $suppression)
8{ 8{
9 $page_actuelle = "melaine"; 9 $page_actuelle = "melaine";
10 10
11 // modèle 11 // infos sur les fichiers
12 $Article = new Page($page_actuelle); 12 $Articles = new Article($page_actuelle);
13 13
14 // nouvel article 14 // nouvel article
15 if($numArticle == 0) 15 if($fileCode == '')
16 { 16 {
17 $title = "Ajouter un article"; 17 $title = "Ajouter un article";
18 $texte = ''; 18 $texte = '';
19 } 19 }
20 else 20 else
21 { 21 {
22 // nom de l'article ciblé (objet et session) 22 // nom de l'article ciblé (objet et session)
23 $Article->findFileName($numArticle); 23 $Articles->fileCode = $fileCode;
24 $_SESSION['target'] = $Article->fileName; 24 $_SESSION['target'] = $Articles->fileCode;
25 25
26 // suppression 26 // suppression
27 if($suppression) 27 if($suppression)
28 { 28 {
29 $Article->delete(); 29 $Articles->delete();
30 header('Location: index.php?page=' . $page_actuelle); 30
31 exit(); 31 // redirection immédiate avant affichage
32 } 32 header('Location: index.php?page=' . $page_actuelle);
33 // modification 33 exit();
34 else 34 }
35 { 35 // modification
36 $title = "Modifier un article"; 36 else
37 $texte = $Article->readOne(); // entrée de l'éditeur 37 {
38 } 38 $title = "Modifier un article";
39 } 39 $texte = $Articles->readOne(); // entrée de l'éditeur
40 40 }
41 // pour l'affichage des articles 41 }
42 $articles = array_reverse($Article->readAll()); // lourd 42
43 43 // ajout des données dans $Articles->fileList['content']
44 // sécurisation du contenu pré-existant inséré dans l'éditeur 44 if(!empty($Articles->fileList))
45 if($numArticle > 0 && !$suppression) 45 {
46 { 46 $Articles->readAll();
47 require('controller/ckeditor.php'); 47 $Articles->fileList = array_reverse($Articles->fileList);
48 $texte = preparationCKeditor($texte); 48 }
49 } 49
50 50 // sécurisation du contenu pré-existant inséré dans l'éditeur
51 // NB: penser à ajouter au template la fonctionnalité "autosave" 51 if(!empty($fileCode) && !$suppression)
52 // https://ckeditor.com/docs/ckeditor5/latest/builds/guides/integration/saving-data.html 52 {
53 53 $fileCodeArgument = '&article=' . $fileCode;
54 // morceaux en HTML à assembler 54 require('controller/ckeditor.php');
55 // variable $editeurHTML, contient $texte 55 $texte = preparationCKeditor($texte);
56 require('view/template-formulaires.php'); 56 }
57 // variables $css, $js, $header et $content, 57 else
58 // $content contient $articles et $editeurHTML 58 {
59 require('view/melaine.php'); 59 $fileCodeArgument = '';
60 // fin de l'assemblage 60 }
61 require('view/template.php'); 61
62} 62
63 63 // NB: penser à ajouter au template la fonctionnalité "autosave"
64function discoEdit($albumCode, $suppression) 64 // https://ckeditor.com/docs/ckeditor5/latest/builds/guides/integration/saving-data.html
65{ 65
66 $page_actuelle = "discographie"; 66 // morceaux en HTML à assembler
67 $title = "Discographie"; 67 // variable $editeurHTML, contient $texte
68 68 require('view/template-formulaires.php');
69 // modèle 69 // variables $css, $js, $header et $content,
70 $Albums = new Album($page_actuelle); 70 // $content contient $articles et $editeurHTML
71 $Albums->makeFileList(); 71 require('view/melaine.php');
72 72 // fin de l'assemblage
73 // nouvel album 73 require('view/template.php');
74 if($albumCode == '') 74}
75 { 75
76 unset($_SESSION['target']); 76function discoEdit($fileCode, $suppression)
77 $title = "Ajouter un album"; 77{
78 78 $page_actuelle = "discographie";
79 // formulaires vides 79 $title = "Discographie";
80 $vignette = ['', '', '']; 80
81 $texte = ''; 81 // modèle
82 } 82 $Albums = new Album($page_actuelle);
83 else 83 $Albums->makeFileList();
84 { 84 //var_dump($Albums);
85 // album ciblé 85 // contenu: JSON, HTML, noms et chemins des fichiers
86 $Albums->albumCode = $albumCode; 86 $Albums->readAll();
87 87 $Albums->fileList = array_reverse($Albums->fileList);
88 // suppression 88 //var_dump($Albums);
89 if($suppression) 89 //var_dump($Albums->fileList);
90 { 90
91 $Albums->delete(); 91 // nouvel album
92 header('Location: index.php?page=' . $page_actuelle); 92 if($fileCode == '')
93 exit(); 93 {
94 } 94 //echo($_SESSION['target'] . "<br/>");
95 // modification 95 //unset($_SESSION['target']);
96 else 96 $title = "Ajouter un album";
97 { 97
98 $_SESSION['target'] = $Albums->albumCode; 98 // formulaires vides
99 $title = "Modifier un album"; 99 $vignette = ['', '', ''];
100 $texte = $Albums->readOneHTML($albumCode); 100 $texte = '';
101 $vignette = $Albums->getVignetteJSON(); 101 }
102 } 102 else
103 } 103 {
104 104 // album ciblé
105 // traitements PHP pour l'éditeur 105 $Albums->fileCode = $fileCode;
106 // sécurisation du contenu pré-existant inséré dans l'éditeur 106
107 if(!empty($albumCode) && !$suppression && !empty($texte)) 107 // suppression
108 { 108 if($suppression)
109 require('controller/ckeditor.php'); 109 {
110 $texte = preparationCKeditor($texte); 110 $Albums->delete();
111 } 111 header('Location: index.php?page=' . $page_actuelle);
112 112 exit();
113 // préremplir le champ <input type="file" > 113 }
114 // c'est normallement impossible 114 // modification
115 115 else
116 // contenu de tous les fichiers JSON (= tableau de chaines) 116 {
117 $albumsJSON = $Albums->readAll(); 117 $_SESSION['target'] = $fileCode;
118 // noms des fichiers JSON 118 $title = "Modifier un album";
119 $albumNamesJSON = $Albums->fileList; 119
120 120 for($i = 0; $i < $Albums->fileListCount; $i++)
121 $annees = []; 121 {
122 for($i = 0; $i < count($albumsJSON); $i++) 122 if($fileCode == $Albums->fileList[$i]['fileCode'])
123 { 123 {
124 // une case supplémentaire contient le "albumCode" 124 // json
125 $albumsJSON[$i][3] = pathinfo($albumNamesJSON[$i])['filename']; 125 $vignette[0] = $Albums->fileList[$i]['titre'];
126 126 $vignette[1] = $Albums->fileList[$i]['annee'];
127 $annees[$i] = $albumsJSON[$i][1]; 127 $vignette[2] = $Albums->fileList[$i]['pochette'];
128 } 128 // html
129 129 $texte = $Albums->fileList[$i]['HTMLcontent'];
130 // tri d'un tableau multidimensionnel 130
131 array_multisort($annees, $albumsJSON); 131 // image affichée à côté des formulaires
132 132 $imageFormulaire = 'data/' . $page_actuelle . '/images/' . $vignette[2];
133 // lien vers le HTML ou ancre? 133 }
134 $avecLien = []; 134 }
135 $linkDiscoChrono = []; 135 }
136 for($i = 0; $i < count($albumsJSON); $i++) 136 }
137 { 137
138 // cas particulier où le dossier "html" est vide 138 // traitements PHP pour l'éditeur
139 if(!empty($Albums->fileList)) 139 // sécurisation du contenu pré-existant inséré dans l'éditeur
140 { 140 if(!empty($fileCode) && !$suppression && !empty($texte))
141 if(file_exists('data/discographie/html/' . $albumsJSON[$i][3] . '.html')) 141 {
142 { 142 // dans l'adresse dans la balise <form>
143 $lienAlbum[$i] = 'page=album&album_name=' . $albumsJSON[$i][0] . '&album_code=' . $albumsJSON[$i][3]; 143 $fileCodeArgument = '&article=' . $fileCode;
144 $avecLien[$i] = true; 144
145 $linkDiscoChrono[$i] = 'linkChrono'; // css 145 require('controller/ckeditor.php');
146 } 146 $texte = preparationCKeditor($texte);
147 else 147 }
148 { 148 else
149 $lienAlbum[$i] = 'page=discographie#' . $albumsJSON[$i][0]; 149 {
150 $avecLien[$i] = false; 150 $fileCodeArgument = '';
151 $linkDiscoChrono[$i] = 'noLinkChrono'; // css 151 }
152 } 152
153 $lienBoutonModif[$i] = 'page=discographie&action=edition&album_code=' . $albumsJSON[$i][3]; 153 // préremplir le champ <input type="file" >
154 } 154 // c'est normallement impossible
155 } 155
156 156
157 // morceaux en HTML à assembler 157 // tri des albums avec l'année dans le .json
158 // variable $editeurHTML, contient $texte 158
159 require('view/template-formulaires.php'); 159 // noms des fichiers JSON
160 // variables $css, $js, $header et $content, 160 //$albumNamesJSON = $Albums->fileList;
161 // $content contient ???? et $editeurHTML 161 //$annees = [];
162 require('view/discographie.php'); 162 for($i = 0; $i < $Albums->fileListCount; $i++)
163 // fin de l'assemblage 163 {
164 require('view/template.php'); 164 // une case supplémentaire contient le "fileCode"
165} 165 //$albumsJSON[$i][3] = pathinfo($albumNamesJSON[$i])['filename'];
166 //$albumsJSON[$i][3] = pathinfo($Albums->fileList[$i]['fileCode'])['filename'];
167
168 //$annees[$i] = $albumsJSON[$i][1];
169 }
170 //var_dump($annee); die();
171
172 // tri d'un tableau multidimensionnel
173 //array_multisort($annees, $albumsJSON);
174
175
176
177 // liens dans la page et le menu chronologie
178 // ce dernier comporte une ancre lorsque le html n'existe pas
179 /*$lienAlbum = [];
180 $avecLien = [];
181 $linkDiscoChrono = [];*/
182 for($i = 0; $i < $Albums->fileListCount; $i++)
183 {
184 if(file_exists('data/discographie/html/' . $Albums->fileList[$i]['fileCode'] . '.html'))
185 {
186 $lienAlbum[$i] = 'page=album&album_name=' . $Albums->fileList[$i]['titre'] . '&file_code=' . $Albums->fileList[$i]['fileCode'];
187 $avecLien[$i] = true;
188 $linkDiscoChrono[$i] = 'linkChrono'; // css
189 }
190 else
191 {
192 $lienAlbum[$i] = 'page=discographie#' . $Albums->fileList[$i]['titre'];
193 $avecLien[$i] = false;
194 $linkDiscoChrono[$i] = 'noLinkChrono'; // css
195 }
196 $lienBoutonModif[$i] = 'page=discographie&action=edition&file_code=' . $Albums->fileList[$i]['fileCode'];
197 }
198
199 // morceaux en HTML à assembler
200 // variable $editeurHTML, contient $texte
201 require('view/template-formulaires.php');
202 // variables $css, $js, $header et $content,
203 // $content contient ???? et $editeurHTML
204 require('view/discographie.php');
205 // fin de l'assemblage
206 require('view/template.php');
207}
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 @@
1<?php 1<?php
2// controller/backup.php 2// controller/backup.php
3 3
4function extraction($from) 4function extraction($from)
5{ 5{
6 $chemin = "data/"; 6 $chemin = "data/";
7 $nomFichier = "sauvegarde_site_melaine.zip"; 7 $nomFichier = "sauvegarde_site_melaine.zip";
8 8
9 // création ou remplacement d'une archive zip 9 // création ou remplacement d'une archive zip
10 // une erreur est jetée si l'extension zip n'est pas activée 10 // une erreur est jetée si l'extension zip n'est pas activée
11 try 11 try
12 { 12 {
13 $zip = new ZipArchive(); 13 $zip = new ZipArchive();
14 } 14 }
15 catch (Throwable $e) 15 catch (Throwable $e)
16 { 16 {
17 echo('Erreur: la classe ZipArchive est introuvable, la sauvegarde est impossible. L\'extension ZIP de PHP est-elle activée dans le fichier php.ini?<br/> 17 echo('Erreur: la classe ZipArchive est introuvable, la sauvegarde est impossible. L\'extension ZIP de PHP est-elle activée dans le fichier php.ini?<br/>
18 Veuillez prévenir l\'administrateur.<br/> 18 Veuillez prévenir l\'administrateur.<br/>
19 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".<br/><br/> 19 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".<br/><br/>
20 <a href="index.php" >Retour au site</a>'); 20 <a href="index.php" >Retour au site</a>');
21 die(); 21 die();
22 } 22 }
23 23
24 // création du fichier zip vide 24 // création du fichier zip vide
25 // j'ai utilisé l'option ZipArchive::OVERWRITE, 25 // j'ai utilisé l'option ZipArchive::OVERWRITE,
26 // ZipArchive::FL_OVERWRITE n'apparaît qu'avec PHP 8 26 // ZipArchive::FL_OVERWRITE n'apparaît qu'avec PHP 8
27 if ($zip->open($chemin . $nomFichier, ZipArchive::CREATE | ZipArchive::OVERWRITE)!==TRUE) { 27 if ($zip->open($chemin . $nomFichier, ZipArchive::CREATE | ZipArchive::OVERWRITE)!==TRUE) {
28 exit("Impossible d'ouvrir le fichier <i>" . $chemin . $nomFichier . "</i>.\n"); 28 exit("Impossible d'ouvrir le fichier <i>" . $chemin . $nomFichier . "</i>.\n");
29 } 29 }
30 30
31 // ajout des fichiers 31 // ajout des fichiers
32 // chemin complet = data/"pages"/"html ou images"/"tous les fichiers" 32 // chemin complet = data/"pages"/"html ou images"/"tous les fichiers"
33 $zip->addGlob($chemin . '*/*/*', 0, array('')); 33 $zip->addGlob($chemin . '*/*/*', 0, array(''));
34 $zip->close(); 34 $zip->close();
35 35
36 // pour pouvoir manipuler le fichier depuis filezilla ou ssh 36 // pour pouvoir manipuler le fichier depuis filezilla ou ssh
37 chmod($chemin . $nomFichier, 0666); // écriture 4 chiffres 37 chmod($chemin . $nomFichier, 0666); // écriture 4 chiffres
38 38
39?> 39?>
40<head> 40<head>
41 <meta charset="utf-8" /> 41 <meta charset="utf-8" />
42 <title>extraction des données</title> 42 <title>extraction des données</title>
43 <link rel="stylesheet" type="text/css" href="public/accueil.css" /> 43 <link rel="stylesheet" type="text/css" href="public/accueil.css" />
44</head> 44</head>
45<body> 45<body>
46 <div id="bloc_page" style="padding: 5px;"> 46 <div id="bloc_page" style="padding: 5px;">
47 Toutes les données du sites ont été rassemblées dans un gros fichier que vous pouvez garder par exemple sur votre ordinateur.<br/> 47 Toutes les données du sites ont été rassemblées dans un gros fichier que vous pouvez garder par exemple sur votre ordinateur.<br/>
48 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.<br/> 48 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.<br/>
49 Ce fichier se nomme <i>sauvegarde_site_melaine.zip</i>.<br/><br/> 49 Ce fichier se nomme <i>sauvegarde_site_melaine.zip</i>.<br/><br/>
50 <a href="data/sauvegarde_site_melaine.zip" style="border: 2px black ridge;" >Cliquez ici pour télécharger</a><br/><br/> 50 <a href="data/sauvegarde_site_melaine.zip" style="border: 2px black ridge;" >Cliquez ici pour télécharger</a><br/><br/>
51 <a href="index.php?page=<?= $from ?>" >Retour au site</a> 51 <a href="index.php?page=<?= $from ?>" >Retour au site</a>
52 </div> 52 </div>
53</body> 53</body>
54<?php 54<?php
55} 55}
56 56
57function insertion($from) 57function insertion($from)
58{ 58{
59?> 59?>
60<head> 60<head>
61 <meta charset="utf-8" /> 61 <meta charset="utf-8" />
62 <title>Restauration des données avec un backup</title> 62 <title>Restauration des données avec un backup</title>
63 <link rel="stylesheet" type="text/css" href="public/accueil.css" /> 63 <link rel="stylesheet" type="text/css" href="public/accueil.css" />
64</head> 64</head>
65<body> 65<body>
66 <div id="bloc_page" style="padding: 5px;"> 66 <div id="bloc_page" style="padding: 5px;">
67 Restauration des données à partir d'une sauvegarde.<br/><br/> 67 Restauration des données à partir d'une sauvegarde.<br/><br/>
68 Vous devez avoir créé un fichier nommé <i>sauvegarde_site_melaine.zip</i><br/> 68 Vous devez avoir créé un fichier nommé <i>sauvegarde_site_melaine.zip</i><br/>
69 en cliquant sur <i>Extraire les données</i>.<br/><br/> 69 en cliquant sur <i>Extraire les données</i>.<br/><br/>
70 70
71 <form action="index.php?from=<?= $from ?>&action=insertion" method="post" > 71 <form action="index.php?from=<?= $from ?>&action=insertion" method="post" >
72 <input type="file" accept=".zip" ><br/> 72 <input type="file" accept=".zip" ><br/>
73 <!-- ajouter une demande de confirmation en JS au submit --> 73 <!-- ajouter une demande de confirmation en JS au submit -->
74 <input type="submit" ><br/><br/> 74 <input type="submit" ><br/><br/>
75 <a href="index.php?page=<?= $from ?>" >Retour au site</a> 75 <a href="index.php?page=<?= $from ?>" >Retour au site</a>
76 </form> 76 </form>
77 </div> 77 </div>
78</body> 78</body>
79<?php 79<?php
80} \ No newline at end of file 80} \ No newline at end of file
diff --git a/controller/ckeditor.php b/controller/ckeditor.php
index 661e0e3..7102f33 100644
--- a/controller/ckeditor.php
+++ b/controller/ckeditor.php
@@ -1,132 +1,158 @@
1<?php 1<?php
2// controller/ckeditor.php 2// controller/ckeditor.php
3// 3//
4// c'est la partie PHP du ckeditor 4// c'est la partie PHP du ckeditor
5// l'autre partie est le fichier view/template-ckeditor.php 5// l'autre partie est le fichier view/template-ckeditor.php
6// qui est inséré par la vue de la page correspondante 6// qui est inséré par la vue de la page correspondante
7// il y a aussi un fichier CSS parce que le HTML créé par l'éditeur ne suffit pas à lui-même 7// il y a aussi un fichier CSS parce que le HTML créé par l'éditeur ne suffit pas à lui-même
8 8
9// avant de placer l'éditeur 9// avant de placer l'éditeur
10function preparationCKeditor($html) 10function preparationCKeditor($html)
11{ 11{
12 // texte initial inséré avec setData() dans l'éditeur 12 // texte initial inséré avec setData() dans l'éditeur
13 // danger! 13 // danger!
14 // setData() n'insère pas le texte si il ne respecte pas certains critères, l'utilisateur risque de perdre des données en validant un nouveau contenu sans avoir pu modifier l'ancien 14 // setData() n'insère pas le texte si il ne respecte pas certains critères, l'utilisateur risque de perdre des données en validant un nouveau contenu sans avoir pu modifier l'ancien
15 15
16 if(empty($html)) 16 if(empty($html))
17 { 17 {
18 header('Location: index.php?erreur=empty_input'); 18 header('Location: index.php?erreur=empty_input');
19 } 19 }
20 20
21 // supprimer espaces, tabulations et sauts de ligne en début et fin de chaine 21 // supprimer espaces, tabulations et sauts de ligne en début et fin de chaine
22 $html = trim($html); 22 $html = trim($html);
23 23
24 // supprimer les sauts de ligne 24 // supprimer les sauts de ligne
25 $sautsDeLigne = array("\n", "\r", "\r\n"); 25 $sautsDeLigne = array("\n", "\r", "\r\n");
26 $html = str_replace($sautsDeLigne, '', $html); 26 $html = str_replace($sautsDeLigne, '', $html);
27 27
28 // échapper tous les ', ", \ et caractère NULL 28 // échapper tous les ', ", \ et caractère NULL
29 $html = addslashes($html); 29 $html = addslashes($html);
30 30
31 return($html); 31 return($html);
32} 32}
33 33
34// réception du HTML créé par l'éditeur 34// réception du HTML créé par l'éditeur
35// le nom du fichier est celui dans $_SESSION['nomFichier'] 35function submitCKeditor()
36function submitCKeditor($target) 36{
37{ 37 $page = $_GET['page'];
38 $page = $_GET['page']; 38
39 39 // déjà fait mais on ne sait jamais
40 // déjà fait mais on ne sait jamais 40 if(!isset($_SESSION['admin']) || $_SESSION['admin'] != 1)
41 if(!isset($_SESSION['admin']) || $_SESSION['admin'] != 1) 41 {
42 { 42 header('Location: index.php?page=' . $page . '&erreur=connexion');
43 header('Location: index.php?page=' . $page . '&erreur=connexion'); 43 exit();
44 exit(); 44 }
45 } 45
46 46 // POST de l'éditeur
47 // de l'éditeur 47 if(isset($_POST['contenu'])) // optionnel pour discographie
48 if(isset($_POST['contenu'])) // optionnel pour discographie 48 {
49 { 49 $contenu = Security::secureString($_POST['contenu']);
50 $contenu = Security::secureString($_POST['contenu']); 50
51 51 // récupérer les liens multimedia
52 // récupérer les liens multimedia 52 //require("media.php");
53 //require("media.php"); 53 //$contenu = mediaSubmit($contenu);
54 //$contenu = mediaSubmit($contenu); 54
55 55 // ne pas continuer si la variable est vide (javascript mal supporté ou utilisation de IE, bug?, erreur de l'utilisateur), risque perte de contenu !!
56 // ne pas continuer si la variable est vide (javascript mal supporté ou utilisation de IE, bug?, erreur de l'utilisateur), risque perte de contenu !! 56 if($page != 'discographie' && $contenu == '')
57 if($page != 'discographie' && $contenu == '') 57 {
58 { 58 header('Location: index.php?page=' . $page . '&erreur=contenu_vide');
59 header('Location: index.php?page=' . $page . '&erreur=contenu_vide'); 59 exit();
60 exit(); 60 }
61 } 61 }
62 } 62
63 63 // pages avec des articles simples (melaine...)
64 if($page == 'discographie') 64 if($page != 'discographie')
65 { 65 {
66 $titre = Security::secureString($_POST['titre']); 66 $Article = new Article($page);
67 $annee = Security::secureString($_POST['annee']); 67
68 $pochette = $_FILES['upload']['name']; 68 if(!isset($_SESSION['target']) || $_SESSION['target'] == '')
69 69 {
70 // on instancie avec l'enfant de OneArticle 70 $Article->create($contenu);
71 $Album = new Album($page); 71 }
72 72 else
73 // enregistrement 73 {
74 if($target == '') 74 $Article->fileCode = $_SESSION['target']; // erreur ici?
75 { 75 $Article->update($contenu);
76 // page disco 76 }
77 $_SESSION['erreur'] = $Album->createVignette($titre, $annee, $pochette); 77 }
78 78 // page discographie
79 // page de l'album 79 else if($page == 'discographie')
80 if(!empty($_POST['contenu'])) 80 {
81 { 81 $Album = new Album($page);
82 $Album->create($contenu); 82
83 } 83 // on retrouve les données si nécessaire
84 } 84 if(isset($_SESSION['target']) && $_SESSION['target'] != '')
85 else 85 {
86 { 86 $Album->fileCode = $_SESSION['target'];
87 $Album->albumCode = $target; 87 $Album->readOne();
88 88 }
89 // page disco 89
90 $_SESSION['erreur'] = $Album->updateVignetteJSON($titre, $annee, $pochette); 90 $nouveauTitre = Security::secureString($_POST['titre']);
91 91 $nouvelleAnnee = Security::secureString($_POST['annee']);
92 // page de l'album 92 $nouvellePochette = $_FILES['upload']['name'];
93 if(isset($_POST['contenu'])) 93
94 { 94 // enregistrement nouvel album
95 $Album->format = 'html'; 95 if(!isset($_SESSION['target']) || $_SESSION['target'] == '')
96 $Album->setFileName(); 96 {
97 if(!empty($Album->fileName)) 97 // page disco
98 { 98 $Album->createVignette($nouveauTitre, $nouvelleAnnee, $nouvellePochette);
99 $Album->update($_POST['contenu']); 99
100 } 100 // page de l'album
101 } 101 if(!empty($_POST['contenu']))
102 } 102 {
103 } 103 $Album->format = 'html';
104 // autres pages 104 $Album->create($contenu);
105 else 105 }
106 { 106 }
107 $Article = new Page($page); 107 // modification
108 108 else
109 if($target == '') 109 {
110 { 110 $Album->albumCode = $_SESSION['target'];
111 $Article->create($contenu); 111
112 } 112 // page disco
113 else 113 $Album->format = 'json';
114 { 114
115 $Article->fileName = $target; 115 // garder l'image si aucune n'est sélectionnée
116 $Article->update($contenu); 116 // (on ne peut pas préremplir un <input type="file">)
117 } 117 if($nouvellePochette == '' && $Album->oneAlbum['pochette'] != '')
118 } 118 {
119} 119 $nouvellePochette = $Album->oneAlbum['pochette'];
120 120 }
121// lien sans http:// 121
122// 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 122 $Album->updateVignetteJSON($nouveauTitre, $nouvelleAnnee, $nouvellePochette);
123// il est possible de cliquer sur ce lien, ce qui ouvre un onglet avec le site demandé 123
124// 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 124 // page de l'album
125// tomber ainsi sur une page d'erreur est déroutant: 125 if(isset($_POST['contenu']))
126// "ai-je perdu le texte que j'étais en train de taper?"" 126 {
127// solution 1 (mauvaise): activer la redirection en cas d'erreur 404 dans le .htaccess 127 //var_dump($Album->oneAlbum); die();
128// solution 2 (façon pop-up): fermer ce nouvel onglet avec echo '<SCRIPT>javascript:window.close()</SCRIPT>'; 128 $Album->format = 'html';
129// pour faire passer par le .htaccess l'info comme quoi la page précédente comportait un éditeur ouvert... 129 //$Album->setFileName();
130 130 if(!empty($Album->oneAlbum['HTMLfileName']))
131function cleanHTML($contenu) 131 {
132{} 132 $Album->update($_POST['contenu']);
133 }
134 }
135 }
136 }
137
138 // nettoyage
139 unset($_SESSION['target']);
140 unset($_GET['action']);
141 unset($_POST['contenu']);
142 header('Location: index.php?page=' . $_GET['page']);
143 exit();
144}
145
146
147// lien sans http://
148// 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
149// il est possible de cliquer sur ce lien, ce qui ouvre un onglet avec le site demandé
150// 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
151// tomber ainsi sur une page d'erreur est déroutant:
152// "ai-je perdu le texte que j'étais en train de taper?""
153// solution 1 (mauvaise): activer la redirection en cas d'erreur 404 dans le .htaccess
154// solution 2 (façon pop-up): fermer ce nouvel onglet avec echo '<SCRIPT>javascript:window.close()</SCRIPT>';
155// pour faire passer par le .htaccess l'info comme quoi la page précédente comportait un éditeur ouvert...
156
157function cleanHTML($contenu)
158{}
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 @@
1<?php 1<?php
2// premier démarrage du site 2// premier démarrage du site
3function installation() 3function installation()
4{ 4{
5 // les chemins dans le .htaccess seront des chemins relatifs, 5 // les chemins dans le .htaccess seront des chemins relatifs,
6 // la racine dépendant du serveur, donc de l'hébergeur, 6 // la racine dépendant du serveur, donc de l'hébergeur,
7 // par défaut c'est /var/www/ pour debian, etc 7 // par défaut c'est /var/www/ pour debian, etc
8 // c'est /var/www/nom_de_domaine/ avec des hôtes virtuels 8 // c'est /var/www/nom_de_domaine/ avec des hôtes virtuels
9 // on utilisera donc des chemins adaptés à des hôtes virtuels 9 // on utilisera donc des chemins adaptés à des hôtes virtuels
10 10
11 // le nom du serveur sera le nom de domaine tout court 11 // le nom du serveur sera le nom de domaine tout court
12 // la racine sera /var/www/nom_de_domaine 12 // la racine sera /var/www/nom_de_domaine
13 13
14 //echo('document root: ' . $_SERVER['DOCUMENT_ROOT'] . '<br />'); 14 //echo('document root: ' . $_SERVER['DOCUMENT_ROOT'] . '<br />');
15 //echo('server name: ' . $_SERVER['SERVER_NAME'] . '<br /'); 15 //echo('server name: ' . $_SERVER['SERVER_NAME'] . '<br /');
16 // echo('getcwd: ' . getcwd() . '<br />'); 16 // echo('getcwd: ' . getcwd() . '<br />');
17 // echo('dirname: ' . dirname(__FILE__) . '<br />'); 17 // echo('dirname: ' . dirname(__FILE__) . '<br />');
18 // echo('file: ' . __FILE__ . '<br />'); 18 // echo('file: ' . __FILE__ . '<br />');
19 // echo('dir: ' . __DIR__. '<br />'); 19 // echo('dir: ' . __DIR__. '<br />');
20 20
21 //$lien_htaccess = $_SERVER['SERVER_NAME'] . "/.htaccess"; 21 //$lien_htaccess = $_SERVER['SERVER_NAME'] . "/.htaccess";
22 //$nomDuSite = "melaine"; 22 //$nomDuSite = "melaine";
23 23
24 // créer le .htaccess 24 // créer le .htaccess
25 if(!file_exists(".htaccess")) 25 if(!file_exists(".htaccess"))
26 { 26 {
27 echo('<p style="color: red;" >Le .htaccess semble absent ce qui rend le site vulnérable aux attaques, veuillez contacter l\'administrateur.</p>'); 27 echo('<p style="color: red;" >Le .htaccess semble absent ce qui rend le site vulnérable aux attaques, veuillez contacter l\'administrateur.</p>');
28 //$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"; 28 //$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";
29 // $fichier = fopen('.htaccess', 'w'); 29 // $fichier = fopen('.htaccess', 'w');
30 // fputs($fichier, $contenu); 30 // fputs($fichier, $contenu);
31 // fclose($fichier); 31 // fclose($fichier);
32 // chmod('.htaccess', 0666); // mettre 0644 en production 32 // chmod('.htaccess', 0666); // mettre 0644 en production
33 } 33 }
34 34
35 // droits en lecture et écriture dans le cas d'une migration 35 // droits en lecture et écriture dans le cas d'une migration
36 // tester si le site est "vide" et prévoir un formulaire permettant d'upload le fichier .zip 36 // tester si le site est "vide" et prévoir un formulaire permettant d'upload le fichier .zip
37 // contenant toutes les données qu'il est possible de créer depuis le mode admin 37 // contenant toutes les données qu'il est possible de créer depuis le mode admin
38 // cette méthode a deux intérêts: 38 // cette méthode a deux intérêts:
39 // - facilité pour l'utilisateur 39 // - facilité pour l'utilisateur
40 // - toutes les données sont la "possession" du serveur apache, 40 // - toutes les données sont la "possession" du serveur apache,
41 // on prévient ainsi tous les futurs problèmes de droits 41 // on prévient ainsi tous les futurs problèmes de droits
42 42
43 // dans le cas de l'utilisation d'une base de données, le fichiers zip devrait contenir un "dump" 43 // dans le cas de l'utilisation d'une base de données, le fichiers zip devrait contenir un "dump"
44 // (un fichier .sql), à voir si php est capable d'obtenir ou redonner ce fichier à la BDD 44 // (un fichier .sql), à voir si php est capable d'obtenir ou redonner ce fichier à la BDD
45 45
46 // créer les dossiers (fait également à l'extraction du zip de données) 46 // créer les dossiers (fait également à l'extraction du zip de données)
47 // attention: ne fonctionne pas sans une manipulation préalable 47 // attention: ne fonctionne pas sans une manipulation préalable
48 // - modifier soit-même les droits du dossier data (777), quoique 111 serait pas mal non plus 48 // - modifier soit-même les droits du dossier data (777), quoique 111 serait pas mal non plus
49 // - 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 49 // - 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
50 50
51 // le 0 devant signifie que le nombre est en octal 51 // le 0 devant signifie que le nombre est en octal
52 $droitsDossiers = 0777; // mettre 0700 à la fin 52 $droitsDossiers = 0777; // mettre 0700 à la fin
53 53
54 $listePages = array('melaine', 'discographie', 'concerts', 'presse', 'ateliers', 'liens', 'peinture', 'archives'); 54 $listePages = array('melaine', 'discographie', 'concerts', 'presse', 'ateliers', 'liens', 'peinture', 'archives');
55 foreach ($listePages as $page) 55 foreach ($listePages as $page)
56 { 56 {
57 if(!file_exists('data/' . $page)) 57 if(!file_exists('data/' . $page))
58 { 58 {
59 mkdir('data/' . $page); 59 mkdir('data/' . $page);
60 chmod('data/' . $page, $droitsDossiers); 60 chmod('data/' . $page, $droitsDossiers);
61 } 61 }
62 if(!file_exists('data/' . $page . '/html')) 62 if(!file_exists('data/' . $page . '/html'))
63 { 63 {
64 mkdir('data/' . $page . '/html'); 64 mkdir('data/' . $page . '/html');
65 chmod('data/' . $page . '/html', $droitsDossiers); 65 chmod('data/' . $page . '/html', $droitsDossiers);
66 } 66 }
67 if(!file_exists('data/' . $page . '/images')) 67 if(!file_exists('data/' . $page . '/images'))
68 { 68 {
69 mkdir('data/' . $page . '/images'); 69 mkdir('data/' . $page . '/images');
70 chmod('data/' . $page . '/images', $droitsDossiers); 70 chmod('data/' . $page . '/images', $droitsDossiers);
71 } 71 }
72 // if(!file_exists('data/' . $page . '/multimedia')) 72 // if(!file_exists('data/' . $page . '/multimedia'))
73 // { 73 // {
74 // mkdir('data/' . $page . '/multimedia'); 74 // mkdir('data/' . $page . '/multimedia');
75 // chmod('data/' . $page . '/multimedia', 0777); 75 // chmod('data/' . $page . '/multimedia', 0777);
76 // } 76 // }
77 } 77 }
78 // dossier supplémentaire dans discographie 78 // dossier supplémentaire dans discographie
79 if(!file_exists('data/discographie/json')) 79 if(!file_exists('data/discographie/json'))
80 { 80 {
81 mkdir('data/discographie/json'); 81 mkdir('data/discographie/json');
82 chmod('data/discographie/json', $droitsDossiers); 82 chmod('data/discographie/json', $droitsDossiers);
83 } 83 }
84 // fichier password.txt 84 // fichier password.txt
85 if(!file_exists('data/password.txt')) 85 if(!file_exists('data/password.txt'))
86 { 86 {
87 touch('data/password.txt'); 87 touch('data/password.txt');
88 chmod('data/password.txt', 0600); 88 chmod('data/password.txt', 0600);
89 } 89 }
90 90
91 // le modèle donnera les droits 0666 (octal) aux nouveaux fichiers à l'intérieur des dossiers 91 // le modèle donnera les droits 0666 (octal) aux nouveaux fichiers à l'intérieur des dossiers
92 92
93 // création d'un mot de passe si password.txt est vide 93 // création d'un mot de passe si password.txt est vide
94 createPassword(); 94 createPassword();
95} 95}
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 @@
1<?php 1<?php
2 2
3// traitement avant enregistrement dans le fichier submit.php 3// traitement avant enregistrement dans le fichier submit.php
4// cette fonction extrait les liens pointant vers des medias embarqués 4// cette fonction extrait les liens pointant vers des medias embarqués
5// (liste de sites) et les restituent nus, sans les balises 5// (liste de sites) et les restituent nus, sans les balises
6function mediaSubmit($chaine) 6function mediaSubmit($chaine)
7{ 7{
8 // liste de sites concernés par les fonctions de ce fichiers 8 // liste de sites concernés par les fonctions de ce fichiers
9 $listeMedia = "youtube.com|vimeo.com|dailymotion.com|spotify.com|soundcloud.com|instagram.com|twitter.com|flickr.com|facebook.com|fb.watch|deezer.com|openstreetmap.org|goo.gl/maps|google.com/maps|itunes.apple.com|wordpress.com"; 9 $listeMedia = "youtube.com|vimeo.com|dailymotion.com|spotify.com|soundcloud.com|instagram.com|twitter.com|flickr.com|facebook.com|fb.watch|deezer.com|openstreetmap.org|goo.gl/maps|google.com/maps|itunes.apple.com|wordpress.com";
10 10
11 // sites gérés manuellement (l'éditeur semble ne pas les connaître) 11 // sites gérés manuellement (l'éditeur semble ne pas les connaître)
12 $regexListeNonGeree = 'https://open.spotify.com/embed/\w+/\w+'; 12 $regexListeNonGeree = 'https://open.spotify.com/embed/\w+/\w+';
13 13
14 // à faire plus tard 14 // à faire plus tard
15 //https://www.openstreetmap.org.*layer=mapnik 15 //https://www.openstreetmap.org.*layer=mapnik
16 16
17 //global $listeMedia; // avec global, au lieu de créer une variable locale, on crée une référence vers celle à l'extérieur 17 //global $listeMedia; // avec global, au lieu de créer une variable locale, on crée une référence vers celle à l'extérieur
18 //global $regexListeNonGeree; 18 //global $regexListeNonGeree;
19 19
20 //echo($chaine . "\n"); 20 //echo($chaine . "\n");
21 21
22 // pour embarquer spotify, l'url doit ressembler à https://open.spotify.com/embed/... 22 // pour embarquer spotify, l'url doit ressembler à https://open.spotify.com/embed/...
23 // on ajoute "/embed" si necessaire 23 // on ajoute "/embed" si necessaire
24 $chaine = preg_replace('#spotify.com(?!/embed)#', '$0/embed', $chaine); 24 $chaine = preg_replace('#spotify.com(?!/embed)#', '$0/embed', $chaine);
25 25
26 // adaptation pour les sites non gérés par l'éditeur 26 // adaptation pour les sites non gérés par l'éditeur
27 // on gère deux cas: celui ou l'éditeur ne fait rien (lien nu) et celui où l'utilisateur a créé un lien <a> 27 // on gère deux cas: celui ou l'éditeur ne fait rien (lien nu) et celui où l'utilisateur a créé un lien <a>
28 28
29 // on vire les balises <a> et ce qu'il y a entre les deux pour ne garder que les liens 29 // on vire les balises <a> et ce qu'il y a entre les deux pour ne garder que les liens
30 // on pourra ensuite traiter ensemble les url avec et sans balises <a> 30 // on pourra ensuite traiter ensemble les url avec et sans balises <a>
31 // (?:) permet de matcher sans capturer, donc de retirer des choses 31 // (?:) permet de matcher sans capturer, donc de retirer des choses
32 // pour la variable $tolere, on met: 32 // pour la variable $tolere, on met:
33 // \w = [a-zA-Z0-9_], espace ' ', tabulation \t, CR et LF \r\n, 33 // \w = [a-zA-Z0-9_], espace ' ', tabulation \t, CR et LF \r\n,
34 // /, @, %, deux-points ';', virgule ',' et point-virgule ; 34 // /, @, %, deux-points ';', virgule ',' et point-virgule ;
35 // et devant être échappés: . # ( ) ] { } ? ! | et le tiret qui est placé au début ou la fin 35 // et devant être échappés: . # ( ) ] { } ? ! | et le tiret qui est placé au début ou la fin
36 $tolere = '\w\s\t\n\r/,;:éèàçù€\#@%\.\(\)[\]\{\}\?\!\|-'; 36 $tolere = '\w\s\t\n\r/,;:éèàçù€\#@%\.\(\)[\]\{\}\?\!\|-';
37 $pattern = '#(?:<a href=")([' . $tolere . ']{1,})?(' . $regexListeNonGeree . ')([' . $tolere . ']{1,})?(?:">[' . $tolere . ']+</a>)#'; 37 $pattern = '#(?:<a href=")([' . $tolere . ']{1,})?(' . $regexListeNonGeree . ')([' . $tolere . ']{1,})?(?:">[' . $tolere . ']+</a>)#';
38 $chaine = preg_replace($pattern, '$2', $chaine); 38 $chaine = preg_replace($pattern, '$2', $chaine);
39 //echo($chaine . "\n"); 39 //echo($chaine . "\n");
40 40
41 // on met les balises <span> 41 // on met les balises <span>
42 $pattern = '#' . $regexListeNonGeree . '#'; 42 $pattern = '#' . $regexListeNonGeree . '#';
43 $remplacement = '<span class="media_embed">$0</span>'; 43 $remplacement = '<span class="media_embed">$0</span>';
44 $chaine = preg_replace($pattern, $remplacement, $chaine); 44 $chaine = preg_replace($pattern, $remplacement, $chaine);
45 45
46 // c'est quoi cette merde? 46 // c'est quoi cette merde?
47 // l'API DOM de PHP bien sur!! pour manipuler le "document object model" 47 // l'API DOM de PHP bien sur!! pour manipuler le "document object model"
48 // c'est du complètement calqué sur le javascript, avec une syntaxe PHP 48 // c'est du complètement calqué sur le javascript, avec une syntaxe PHP
49 // et en plus elle est super vieille, elle ne connaît pas les balises HTML5 ! 49 // et en plus elle est super vieille, elle ne connaît pas les balises HTML5 !
50 // mais une balise c'est une balise donc ça marche quand même 50 // mais une balise c'est une balise donc ça marche quand même
51 // la doc de PHP est comme toujours plutôt bonne, elle indique les types de données manipulées 51 // la doc de PHP est comme toujours plutôt bonne, elle indique les types de données manipulées
52 // https://www.php.net/manual/fr/book.dom.php 52 // https://www.php.net/manual/fr/book.dom.php
53 $dom = new DOMDocument; 53 $dom = new DOMDocument;
54 54
55 // pour ne pas s'arrêter sur les erreurs à cause des "nouvelles" balises 55 // pour ne pas s'arrêter sur les erreurs à cause des "nouvelles" balises
56 libxml_use_internal_errors(true); 56 libxml_use_internal_errors(true);
57 57
58 if($dom->loadHTML($chaine)) // et non load() tout court qui sert à charger du XML 58 if($dom->loadHTML($chaine)) // et non load() tout court qui sert à charger du XML
59 { 59 {
60 // <figure> 60 // <figure>
61 // détecter <figure class="media"><oembed url="http://..."> 61 // détecter <figure class="media"><oembed url="http://...">
62 // puis extraire le lien et supprimer les balises autour 62 // puis extraire le lien et supprimer les balises autour
63 if(preg_match("#<figure class=\"media\"><oembed url=\".+\"></oembed></figure>#", $chaine)) 63 if(preg_match("#<figure class=\"media\"><oembed url=\".+\"></oembed></figure>#", $chaine))
64 { 64 {
65 $nbFigures = $dom->getElementsByTagName('figure')->length; 65 $nbFigures = $dom->getElementsByTagName('figure')->length;
66 66
67 $j = 0; 67 $j = 0;
68 for($i = 0; $i < $nbFigures ; $i++) // boucle foreach impossible, une <figure> disparaît à chaque tour 68 for($i = 0; $i < $nbFigures ; $i++) // boucle foreach impossible, une <figure> disparaît à chaque tour
69 { 69 {
70 $balisesFigure = $dom->getElementsByTagName('figure'); 70 $balisesFigure = $dom->getElementsByTagName('figure');
71 $figure = $balisesFigure->item($j); // l'item 1 devient 0 au deuxième passage, etc 71 $figure = $balisesFigure->item($j); // l'item 1 devient 0 au deuxième passage, etc
72 $parent = $figure->parentNode; 72 $parent = $figure->parentNode;
73 73
74 if($figure->getAttribute("class") == 'media') 74 if($figure->getAttribute("class") == 'media')
75 { 75 {
76 $oembed = $figure->getElementsByTagName('oembed'); // tableau d'une seule case 76 $oembed = $figure->getElementsByTagName('oembed'); // tableau d'une seule case
77 $div = $figure->getElementsByTagName('div'); // tableau d'une seule case 77 $div = $figure->getElementsByTagName('div'); // tableau d'une seule case
78 if($oembed->length > 0) // si taille = 0, c'est que la balise figure contient autre chose qu'une oembed 78 if($oembed->length > 0) // si taille = 0, c'est que la balise figure contient autre chose qu'une oembed
79 { 79 {
80 $lien = $oembed->item(0)->getAttribute('url') . ' '; // un espace pour ne pas coller deux adresses 80 $lien = $oembed->item(0)->getAttribute('url') . ' '; // un espace pour ne pas coller deux adresses
81 $span = $dom->createElement('span', $lien); 81 $span = $dom->createElement('span', $lien);
82 $class = $dom->createAttribute('class'); 82 $class = $dom->createAttribute('class');
83 $class->value = 'media_embed'; 83 $class->value = 'media_embed';
84 $span->appendChild($class); 84 $span->appendChild($class);
85 $parent->replaceChild($span, $figure); 85 $parent->replaceChild($span, $figure);
86 } 86 }
87 elseif($div->length > 0) // cette div créée par le ckeditor contient notre lien, plus bas se trouve une iframe 87 elseif($div->length > 0) // cette div créée par le ckeditor contient notre lien, plus bas se trouve une iframe
88 { 88 {
89 $lien = $div->item(0)->getAttribute('data-oembed-url') . ' '; 89 $lien = $div->item(0)->getAttribute('data-oembed-url') . ' ';
90 $span = $dom->createElement('span', $lien); 90 $span = $dom->createElement('span', $lien);
91 $class = $dom->createAttribute('class'); 91 $class = $dom->createAttribute('class');
92 $class->value = 'media_embed'; 92 $class->value = 'media_embed';
93 $span->appendChild($class); 93 $span->appendChild($class);
94 $parent->replaceChild($span, $figure); 94 $parent->replaceChild($span, $figure);
95 } 95 }
96 else 96 else
97 { 97 {
98 $j++; // la balise <figure> n'est pas supprimée, on incrémente l'indice du tableau pour ne pas boucler à l'infini 98 $j++; // la balise <figure> n'est pas supprimée, on incrémente l'indice du tableau pour ne pas boucler à l'infini
99 } 99 }
100 } 100 }
101 } 101 }
102 } 102 }
103 103
104 // <iframe> 104 // <iframe>
105 // détecter <iframe src="http://..." et remplacer par le lien nu, comme au dessus 105 // détecter <iframe src="http://..." et remplacer par le lien nu, comme au dessus
106 // site sans oembed? 106 // site sans oembed?
107 if(preg_match("#<iframe src=\".+\"></iframe>#", $chaine)) 107 if(preg_match("#<iframe src=\".+\"></iframe>#", $chaine))
108 { 108 {
109 $nbIframes = $dom->getElementsByTagName('iframe')->length; 109 $nbIframes = $dom->getElementsByTagName('iframe')->length;
110 110
111 for($i = 0; $i < $nbIframes ; $i++) 111 for($i = 0; $i < $nbIframes ; $i++)
112 { 112 {
113 $balisesIframe = $dom->getElementsByTagName('iframe'); 113 $balisesIframe = $dom->getElementsByTagName('iframe');
114 $iframe = $balisesIframe->item(0); 114 $iframe = $balisesIframe->item(0);
115 $parent = $iframe->parentNode; 115 $parent = $iframe->parentNode;
116 116
117 $lien = $iframe->getAttribute('src') . ' '; 117 $lien = $iframe->getAttribute('src') . ' ';
118 $span = $dom->createElement('span', $lien); 118 $span = $dom->createElement('span', $lien);
119 $class = $dom->createAttribute('class'); 119 $class = $dom->createAttribute('class');
120 $class->value = 'media_embed'; 120 $class->value = 'media_embed';
121 $span->appendChild($class); 121 $span->appendChild($class);
122 $parent->replaceChild($span, $$iframe); 122 $parent->replaceChild($span, $$iframe);
123 } 123 }
124 } 124 }
125 125
126 // <a> 126 // <a>
127 // pour tout les sites multimedia, remplacer les balises <a> par les liens nus 127 // pour tout les sites multimedia, remplacer les balises <a> par les liens nus
128 // en effet, en revenant dans l'éditeur les liens ne déclenchent pas automatiquement "l'embarquement" 128 // en effet, en revenant dans l'éditeur les liens ne déclenchent pas automatiquement "l'embarquement"
129 // cliquer à la fin d'un lien et passer à la ligne a pour effet de créer des balises <a> 129 // cliquer à la fin d'un lien et passer à la ligne a pour effet de créer des balises <a>
130 // ça pose un problème parce que la bibliothèque "embera" ne gère pas les liens dans des balises 130 // ça pose un problème parce que la bibliothèque "embera" ne gère pas les liens dans des balises
131 if(preg_match("#<a href=\".+\">.*</a>#", $chaine)) 131 if(preg_match("#<a href=\".+\">.*</a>#", $chaine))
132 { 132 {
133 $nbA = $dom->getElementsByTagName('a')->length; 133 $nbA = $dom->getElementsByTagName('a')->length;
134 134
135 $j = 0; 135 $j = 0;
136 for($i = 0; $i < $nbA ; $i++) 136 for($i = 0; $i < $nbA ; $i++)
137 { 137 {
138 $balisesA = $dom->getElementsByTagName('a'); 138 $balisesA = $dom->getElementsByTagName('a');
139 $a = $balisesA->item($j); 139 $a = $balisesA->item($j);
140 $parent = $a->parentNode; 140 $parent = $a->parentNode;
141 141
142 $lien = $a->getAttribute('href') . ' '; 142 $lien = $a->getAttribute('href') . ' ';
143 143
144 // seules les liens pointant vers une des adresses de la liste sont concernés 144 // seules les liens pointant vers une des adresses de la liste sont concernés
145 if(preg_match("#" . $listeMedia . "#", $lien)) 145 if(preg_match("#" . $listeMedia . "#", $lien))
146 { 146 {
147 $span = $dom->createElement('span', $lien); 147 $span = $dom->createElement('span', $lien);
148 $class = $dom->createAttribute('class'); 148 $class = $dom->createAttribute('class');
149 $class->value = 'media_embed'; 149 $class->value = 'media_embed';
150 $span->appendChild($class); 150 $span->appendChild($class);
151 $parent->replaceChild($span, $a); 151 $parent->replaceChild($span, $a);
152 } 152 }
153 else 153 else
154 { 154 {
155 $j++; // la balise <a> n'est pas supprimée, on incrémente l'indice du tableau pour ne pas boucler à l'infini 155 $j++; // la balise <a> n'est pas supprimée, on incrémente l'indice du tableau pour ne pas boucler à l'infini
156 } 156 }
157 } 157 }
158 } 158 }
159 159
160 // pour nettoyer tous les warnings qu'on vient de produire et purifier nos fichiers log 160 // pour nettoyer tous les warnings qu'on vient de produire et purifier nos fichiers log
161 libxml_clear_errors(); 161 libxml_clear_errors();
162 // pour au contraire pouvoir les regarder, remplacer la ligne au dessus par celles en dessous 162 // pour au contraire pouvoir les regarder, remplacer la ligne au dessus par celles en dessous
163 //~ $errors = libxml_get_errors(); 163 //~ $errors = libxml_get_errors();
164 //~ var_dump($errors); 164 //~ var_dump($errors);
165 165
166 // mettre à jour le DOM et enlever le DOCTYPE et les balises <html> et <body> 166 // mettre à jour le DOM et enlever le DOCTYPE et les balises <html> et <body>
167 $chaine = $dom->saveHTML($dom); 167 $chaine = $dom->saveHTML($dom);
168 $pattern = array ('#<!DOCTYPE.*>#', '#<html><body>#', '#</html></body>#'); 168 $pattern = array ('#<!DOCTYPE.*>#', '#<html><body>#', '#</html></body>#');
169 $remplacement = array ('', '', ''); 169 $remplacement = array ('', '', '');
170 $chaine = preg_replace($pattern, $remplacement, $chaine); 170 $chaine = preg_replace($pattern, $remplacement, $chaine);
171 } 171 }
172 else 172 else
173 { 173 {
174 echo "Impossible de charger le HTML"; 174 echo "Impossible de charger le HTML";
175 } 175 }
176 176
177 177
178 178
179 // détecter soundcloud 179 // détecter soundcloud
180 // normallement il n'y a rien à faire ici mais on sait jamais (une mise à jour du ckeditor?) 180 // normallement il n'y a rien à faire ici mais on sait jamais (une mise à jour du ckeditor?)
181 if(preg_match("#soundcloud.com#", $chaine)) 181 if(preg_match("#soundcloud.com#", $chaine))
182 {} 182 {}
183 183
184 // détecter facebook (éventuellement fb.watch) 184 // détecter facebook (éventuellement fb.watch)
185 // je crois que ça va être compliqué ici 185 // je crois que ça va être compliqué ici
186 if(preg_match("#facebook.com|fb.watch#", $chaine)) 186 if(preg_match("#facebook.com|fb.watch#", $chaine))
187 {} 187 {}
188 188
189 return($chaine); // = $contenu 189 return($chaine); // = $contenu
190} 190}
191 191
192 192
193// embarquement !! 193// embarquement !!
194function mediaEmbed($chaine) 194function mediaEmbed($chaine)
195{ 195{
196 //require("../Embera/src/Autoloader.php"); 196 //require("../Embera/src/Autoloader.php");
197 //$embera = new Embera\Embera(); 197 //$embera = new Embera\Embera();
198 //$chaine = $embera->autoEmbed($chaine); 198 //$chaine = $embera->autoEmbed($chaine);
199 199
200 $pattern = '#<span class="media_embed">(.+)</span>#'; 200 $pattern = '#<span class="media_embed">(.+)</span>#';
201 $remplacement = '<iframe src="$1" frameborder="0" allowtransparency="true"></iframe>'; 201 $remplacement = '<iframe src="$1" frameborder="0" allowtransparency="true"></iframe>';
202 $chaine = preg_replace($pattern, $remplacement, $chaine); 202 $chaine = preg_replace($pattern, $remplacement, $chaine);
203 203
204 // requête oembed 204 // requête oembed
205 //~ echo('<br/><br/>'); 205 //~ echo('<br/><br/>');
206 //~ print_r($embera->getUrlData([ 206 //~ print_r($embera->getUrlData([
207 //~ 'https://vimeo.com/374131624', 207 //~ 'https://vimeo.com/374131624',
208 //~ 'https://www.flickr.com/photos/bees/8597283706/in/photostream', 208 //~ 'https://www.flickr.com/photos/bees/8597283706/in/photostream',
209 //~ ])); 209 //~ ]));
210 210
211 return($chaine); // = $contenu 211 return($chaine); // = $contenu
212} 212}
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 @@
1<?php 1<?php
2// controller/visitor.php 2// controller/visitor.php
3// 3//
4// affichage du site en lecture seul (visiteur ou admin) 4// affichage du site en lecture seul (visiteur ou admin)
5 5
6// pages du sites 6// pages du sites
7function accueil() 7function accueil()
8{ 8{
9 $title = "Bienvenue sur le site de Melaine Favennec"; 9 $title = "Bienvenue sur le site de Melaine Favennec";
10 $page_actuelle = "accueil"; 10 $page_actuelle = "accueil";
11 $content = ''; 11 $content = '';
12 12
13 // variables $js et $header 13 // variables $js et $header
14 require('view/accueil.php'); 14 require('view/accueil.php');
15 // HTML 15 // HTML
16 require('view/template.php'); 16 require('view/template.php');
17} 17}
18 18
19function menu() 19function menu()
20{ 20{
21 $title = "Melaine Favennec - menu BD"; 21 $title = "Melaine Favennec - menu BD";
22 $page_actuelle = "menu"; 22 $page_actuelle = "menu";
23 23
24 // variables $css, $js, $header et $content 24 // variables $css, $js, $header et $content
25 require('view/menu.php'); 25 require('view/menu.php');
26 // fin de l'assemblage 26 // fin de l'assemblage
27 require('view/template.php'); 27 require('view/template.php');
28} 28}
29 29
30function melaineVisitor() 30function melaineVisitor()
31{ 31{
32 $page_actuelle = "melaine"; 32 $page_actuelle = "melaine";
33 $title = "Mais qui est Melaine Favennec?"; 33 $title = "Mais qui est Melaine Favennec?";
34 34
35 // modèle 35 // infos sur les fichiers
36 $Articles = new Page($page_actuelle, 'html'); 36 $Articles = new Article($page_actuelle);
37 37
38 // récupération de toute la page dans $articles 38 // données des dates
39 $articles = array_reverse($Articles->readAll()); // lourd 39 //print_r($Articles->fileList[$i]['date']);
40 40 //getdate($Albums->fileList[$i]['fileCode']);
41 // variables $css, $js, $header et $content 41
42 require('view/melaine.php'); 42 // ajout des données dans $Articles->fileList['content']
43 // HTML 43 if(!empty($Articles->fileList))
44 require('view/template.php'); 44 {
45} 45 $Articles->readAll();
46 46 $Articles->fileList = array_reverse($Articles->fileList);
47function discoVisitor() 47 }
48{ 48
49 $page_actuelle = "discographie"; 49 // variables $css, $js, $header et $content
50 $title = "Discographie"; 50 require('view/melaine.php');
51 51 // HTML
52 // modèle 52 require('view/template.php');
53 $Albums = new Album($page_actuelle); 53}
54 $Albums->makeFileList(); 54
55 55function discoVisitor()
56 // contenu de tous les fichiers JSON (= tableau de chaines) 56{
57 $albumsJSON = $Albums->readAll(); 57 $page_actuelle = "discographie";
58 // noms des fichiers JSON 58 $title = "Discographie";
59 $albumNamesJSON = $Albums->fileList; 59
60 60 // modèle
61 $annees = []; 61 $Albums = new Album($page_actuelle);
62 for($i = 0; $i < count($albumsJSON); $i++) 62 $Albums->makeFileList();
63 { 63
64 // une case supplémentaire contient le "albumCode" 64 // on récupère tout: JSON, HTML, noms et chemins des fichiers
65 $albumsJSON[$i][3] = pathinfo($albumNamesJSON[$i])['filename']; 65 $Albums->readAll();
66 66 $Albums->fileList = array_reverse($Albums->fileList);
67 $annees[$i] = $albumsJSON[$i][1]; 67 //var_dump($Albums->fileList); die();
68 } 68
69 69
70 // tri d'un tableau multidimensionnel 70
71 array_multisort($annees, $albumsJSON); 71 // tri des albums avec l'année dans le .json
72 72
73 // lien vers le HTML ou ancre? 73 // noms des fichiers JSON
74 $lienAlbum = []; 74 //$albumNamesJSON = $Albums->fileList;
75 $avecLien = []; 75
76 $linkDiscoChrono = []; 76 //$annees = [];
77 for($i = 0; $i < count($albumsJSON); $i++) 77 for($i = 0; $i < $Albums->fileListCount; $i++)
78 { 78 {
79 // cas particulier où le dossier "html" est vide 79 // une case supplémentaire contient le "fileCode"
80 if(!empty($Albums->fileList)) 80 //$albumsJSON[$i][3] = pathinfo($albumNamesJSON[$i])['filename'];
81 { 81 //$albumsJSON[$i][3] = pathinfo($Albums->fileList[$i]['fileCode'])['filename'];
82 if(file_exists('data/discographie/html/' . $albumsJSON[$i][3] . '.html')) 82
83 { 83 //$annees[$i] = $albumsJSON[$i][1];
84 $lienAlbum[$i] = 'page=album&album_name=' . $albumsJSON[$i][0] . '&album_code=' . $albumsJSON[$i][3]; 84 }
85 $avecLien[$i] = true; 85 //var_dump($annee); die();
86 $linkDiscoChrono[$i] = 'linkChrono'; // css 86
87 } 87 // tri d'un tableau multidimensionnel
88 else 88 //array_multisort($annees, $albumsJSON);
89 { 89
90 $lienAlbum[$i] = 'page=discographie#' . $albumsJSON[$i][0]; 90
91 $avecLien[$i] = false; 91
92 $linkDiscoChrono[$i] = 'noLinkChrono'; // css 92 // lien vers le HTML ou ancre?
93 } 93 /*$lienAlbum = [];
94 $lienBoutonModif[$i] = 'page=discographie&action=edition&album_code=' . $albumsJSON[$i][3]; 94 $avecLien = [];
95 } 95 $linkDiscoChrono = [];*/
96 } 96 for($i = 0; $i < $Albums->fileListCount; $i++)
97 97 {
98 // variables $css, $js et $content 98 if(file_exists('data/discographie/html/' . $Albums->fileList[$i]['fileCode'] . '.html'))
99 require('view/discographie.php'); 99 {
100 // fin de l'assemblage 100 $lienAlbum[$i] = 'page=album&album_name=' . $Albums->fileList[$i]['titre'] . '&file_code=' . $Albums->fileList[$i]['fileCode'];
101 require('view/template.php'); 101 $avecLien[$i] = true;
102} 102 $linkDiscoChrono[$i] = 'linkChrono'; // css
103 103 }
104// page d'un album 104 else
105function album($albumCode, $albumName) 105 {
106{ 106 $lienAlbum[$i] = 'page=discographie#' . $Albums->fileList[$i]['titre'];
107 $page_actuelle = 'discographie'; 107 $avecLien[$i] = false;
108 $title = $albumName; 108 $linkDiscoChrono[$i] = 'noLinkChrono'; // css
109 109 }
110 $album = Album::readOneHTML($albumCode); // simple, efficace 110 $lienBoutonModif[$i] = 'page=discographie&action=edition&file_code=' . $Albums->fileList[$i]['fileCode'];
111 111 }
112 // variables $css, $header et $content 112
113 require('view/album.php'); 113 // variables $css, $js et $content
114 // HTML 114 require('view/discographie.php');
115 require('view/template.php'); 115 // fin de l'assemblage
116} 116 require('view/template.php');
117 117}
118function presse() 118
119{} 119// page d'un album
120 120function album($fileCode, $albumName)
121function ateliers() 121{
122{} 122 $page_actuelle = 'discographie';
123 123 $title = $albumName;
124function liens() 124
125{} 125 $album = Album::readOneHTML($fileCode); // simple, efficace
126 126
127function peinture() 127 // variables $css, $header et $content
128{} 128 require('view/album.php');
129 129 // HTML
130function archives() 130 require('view/template.php');
131}
132
133function presse()
134{}
135
136function ateliers()
137{}
138
139function liens()
140{}
141
142function peinture()
143{}
144
145function archives()
131{} \ No newline at end of file 146{} \ No newline at end of file