summaryrefslogtreecommitdiff
path: root/controller
diff options
context:
space:
mode:
authorpolo <ordipolo@gmx.fr>2021-04-20 21:46:33 +0200
committerpolo <ordipolo@gmx.fr>2021-04-20 21:46:33 +0200
commit87798e5554eb0330cd2de255e5034f0472d410a4 (patch)
treeacd9e26a7d912c7575cb6dd1c7b42cc3e9f52993 /controller
downloadmelaine-87798e5554eb0330cd2de255e5034f0472d410a4.zip
mot de passe
Diffstat (limited to 'controller')
-rw-r--r--controller/admin.php76
-rw-r--r--controller/backup.php80
-rw-r--r--controller/ckeditor.php92
-rw-r--r--controller/installation.php75
-rw-r--r--controller/media.php212
-rw-r--r--controller/visitor.php110
6 files changed, 645 insertions, 0 deletions
diff --git a/controller/admin.php b/controller/admin.php
new file mode 100644
index 0000000..2b3583f
--- /dev/null
+++ b/controller/admin.php
@@ -0,0 +1,76 @@
1<?php
2// controller/admin.php
3//
4// utilisation du site en écriture
5
6// pages du site en version admin
7function melaineAdmin($numArticle)
8{
9 $title = "Ajouter ou modifier un article";
10 $page_actuelle = "melaine";
11
12 // variables $nombreDarticles et tableau $articles[]
13 require('model/melaine-read.php');
14
15 // traitements PHP pour l'éditeur
16 require('controller/ckeditor.php');
17
18 // NB: penser à ajouter au template la fonctionnalité "autosave"
19 // https://ckeditor.com/docs/ckeditor5/latest/builds/guides/integration/saving-data.html
20
21 // récupération des données du modèle
22 if($numArticle > $nombreDarticles || $numArticle < 0) // erreur nombre trop grand (bug?)
23 {
24 header('Location: index.php?page=melaine');
25 }
26 elseif($numArticle == 0) // nouvel article
27 {
28 $texte = '';
29 $numArticle = $nombreDarticles + 1;
30 }
31 else // modification d'un article
32 {
33 $texte = $articles[$numArticle - 1];
34 }
35
36 // traitement du contenu pré-existant
37 $initial = preparationCKeditor($page_actuelle, $numArticle, $texte);
38
39 // variable $editeurHTML, $initial est inséré dedans
40 require('view/template-ckeditor.php');
41
42 // création des morceaux en HTML avant assemblage, c'est-à-dire;
43 // les variables $css, $js, $header et $content
44 require('view/melaine.php');
45 // le tableau de données ($articles) et l'éditeur ($editeurHTML)
46 // font partie de $content
47
48 // assemblage de la page!
49 require('view/template.php');
50}
51
52function changerMotDePasse($secret, $from)
53{
54 // vérification supplémentaire
55 if($_SESSION['admin'] !== 1)
56 {
57 $_SESSION['admin'] = 0;
58 header('Location: index.php?page=' . $_GET['from']);
59 }
60
61 $title = "nouveau mot de passe";
62 // Ajouter une sécurité par cpatcha avec un "input" supplémentaire
63 // Et créer une variable de session pour la réponse au CAPTCHA
64
65 $title = "nouveau mot de passe";
66 $subHeading = "Veuillez saisir votre actuel mot de passe suivi du nouveau.";
67
68 // cette page utilise la même vue que la fonction connexion() dans controller/visiteur.php
69 require('view/connexion.php');
70
71 echo($header);
72
73 // traitements: vérification ancien mot de passe et choix du nouveau
74
75 echo($footer);
76}
diff --git a/controller/backup.php b/controller/backup.php
new file mode 100644
index 0000000..bc84a86
--- /dev/null
+++ b/controller/backup.php
@@ -0,0 +1,80 @@
1<?php
2// controller/backup.php
3
4function extraction($from)
5{
6 $chemin = "data/";
7 $nomFichier = "sauvegarde_site_melaine.zip";
8
9 // création ou remplacement d'une archive zip
10 // une erreur est jetée si l'extension zip n'est pas activée
11 try
12 {
13 $zip = new ZipArchive();
14 }
15 catch (Throwable $e)
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/>
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/>
20 <a href="index.php" >Retour au site</a>');
21 die();
22 }
23
24 // création du fichier zip vide
25 // j'ai utilisé l'option ZipArchive::OVERWRITE,
26 // ZipArchive::FL_OVERWRITE n'apparaît qu'avec PHP 8
27 if ($zip->open($chemin . $nomFichier, ZipArchive::CREATE | ZipArchive::OVERWRITE)!==TRUE) {
28 exit("Impossible d'ouvrir le fichier <i>" . $chemin . $nomFichier . "</i>.\n");
29 }
30
31 // ajout des fichiers
32 // chemin complet = data/"pages"/"html ou images"/"tous les fichiers"
33 $zip->addGlob($chemin . '*/*/*', 0, array(''));
34 $zip->close();
35
36 // pour pouvoir manipuler le fichier depuis filezilla ou ssh
37 chmod($chemin . $nomFichier, 0666); // écriture 4 chiffres
38
39?>
40<head>
41 <meta charset="utf-8" />
42 <title>extraction des données</title>
43 <link rel="stylesheet" type="text/css" href="public/accueil.css" />
44</head>
45<body>
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/>
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/>
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>
52 </div>
53</body>
54<?php
55}
56
57function insertion($from)
58{
59?>
60<head>
61 <meta charset="utf-8" />
62 <title>Restauration des données avec un backup</title>
63 <link rel="stylesheet" type="text/css" href="public/accueil.css" />
64</head>
65<body>
66 <div id="bloc_page" style="padding: 5px;">
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/>
69 en cliquant sur <i>Extraire les données</i>.<br/><br/>
70
71 <form action="index.php?from=<?= $from ?>&action=insertion" method="post" >
72 <input type="file" accept=".zip" ><br/>
73 <!-- ajouter une demande de confirmation en JS au submit -->
74 <input type="submit" ><br/><br/>
75 <a href="index.php?page=<?= $from ?>" >Retour au site</a>
76 </form>
77 </div>
78</body>
79<?php
80} \ No newline at end of file
diff --git a/controller/ckeditor.php b/controller/ckeditor.php
new file mode 100644
index 0000000..1d085a7
--- /dev/null
+++ b/controller/ckeditor.php
@@ -0,0 +1,92 @@
1<?php
2// controller/ckeditor.php
3//
4// c'est la partie PHP du ckeditor
5// l'autre partie est le fichier view/template-ckeditor.php
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
8
9// avant de placer l'éditeur
10function preparationCKeditor($page, $numArticle, $texte)
11{
12 // $page sert à lire et écrire du contenu dans le bon dossier
13 // $article sert à placer l'éditeur sur la page et à lire et écrire dans le bon dossier
14
15 // texte initial pour setData() à modifier avec l'éditeur
16 if ($numArticle > 0)
17 {
18 // supprimer espaces, tabulations et sauts de ligne en début et fin de chaine
19 $texte = trim($texte);
20
21 // supprimer les sauts de ligne
22 $sautsDeLigne = array("\n", "\r", "\r\n");
23 $texte = str_replace($sautsDeLigne, '', $texte);
24
25 // échapper tous les ', ", \ et caractère NULL
26 $texte = addslashes($texte);
27 }
28 else
29 {
30 $texte = ''; // nouveau contenu
31 }
32
33 return($texte);
34}
35
36// réception du HTML créé par l'éditeur
37function submitCKeditor($page, $article, $contenuPOST)
38{
39 // déjà fait mais on ne sait jamais
40 if(!isset($_SESSION['admin']) || $_SESSION['admin'] != 1)
41 {
42 header('Location: index.php?page=' . $page . '&erreur=connexion');
43 }
44 else
45 {
46 // ne pas continuer si la variable est vide (javascript mal supporté ou utilisation de IE, bug?, erreur de l'utilisateur)
47 // on évitera de perdre un article existant par erreur !!
48 if($contenuPOST == '')
49 {
50 header('Location: index.php?page=' . $page . '&erreur=contenu_vide');
51 }
52 else
53 {
54 $contenu = $_POST["contenu"];
55
56 // récupérer les liens multimedia
57 //require("media.php");
58 //$contenu = mediaSubmit($contenu);
59
60 // sécurité faille XSS
61 $configHtmLawed = array(
62 'safe'=>1, // protection contre les élements et attributs dangereux
63 'elements'=>'h2, h3, h4, p, br, span, i, strong, u, mark, blockquote, li, ol, ul, a, figure, hr, img, figcaption, table, tbody, tr, td', // paramètre optionnel: les balises non indiquées sont supprimées
64 // paramètre optionnel: les balises non indiquées sont supprimées
65 'deny_attribute'=>'id', // gêner le JS hostile
66 // on garde 'class' et 'style' utilisés par l'ckediteur
67 );
68 $specHtmLawed = ''; // optionnel: faire qu'un certain élément puisse n'avoir que certains attributs
69 $contenu = htmLawed($contenu, $configHtmLawed, $specHtmLawed);
70
71 // supprimer espaces, tabulations et sauts de ligne en début et fin de chaine
72 $contenu = trim($contenu);
73 }
74 }
75
76 // lien sans http://
77 // 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
78 // il est possible de cliquer sur ce lien, ce qui ouvre un onglet avec le site demandé
79 // 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
80 // tomber ainsi sur une page d'erreur est déroutant:
81 // "ai-je perdu le texte que j'étais en train de taper?""
82 // solution 1 (mauvaise): activer la redirection en cas d'erreur 404 dans le .htaccess
83 // solution 2 (façon pop-up): fermer ce nouvel onglet avec echo '<SCRIPT>javascript:window.close()</SCRIPT>';
84 // pour faire passer par le .htaccess l'info comme quoi la page précédente comportait un éditeur ouvert...
85
86 // enregistrement
87 require('model/melaine-write.php');
88 nouvelArticle($page, $article, $contenu);
89
90 // debuggage
91 //exit();
92} \ No newline at end of file
diff --git a/controller/installation.php b/controller/installation.php
new file mode 100644
index 0000000..f7d42fc
--- /dev/null
+++ b/controller/installation.php
@@ -0,0 +1,75 @@
1<?php
2// premier démarrage du site
3function installation()
4{
5 // les chemins dans le .htaccess seront des chemins relatifs,
6 // la racine dépendant du serveur, donc de l'hébergeur,
7 // par défaut c'est /var/www/ pour debian, etc
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
10
11 // le nom du serveur sera le nom de domaine tout court
12 // la racine sera /var/www/nom_de_domaine
13
14 //echo('document root: ' . $_SERVER['DOCUMENT_ROOT'] . '<br />');
15 //echo('server name: ' . $_SERVER['SERVER_NAME'] . '<br /');
16 // echo('getcwd: ' . getcwd() . '<br />');
17 // echo('dirname: ' . dirname(__FILE__) . '<br />');
18 // echo('file: ' . __FILE__ . '<br />');
19 // echo('dir: ' . __DIR__. '<br />');
20
21 // créer le .htaccess
22 //$lien_htaccess = $_SERVER['SERVER_NAME'] . "/.htaccess";
23 //$nomDuSite = "melaine";
24 if(!file_exists(".htaccess"))
25 {
26 echo('<p style="color: red;" >Le .htaccess semble absent ce qui rend le site vulnérable aux attaques, veuillez contacter l\'administrateur.</p>');
27 // $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 // $fichier = fopen('.htaccess', 'w');
29 // fputs($fichier, $contenu);
30 // fclose($fichier);
31 // chmod('.htaccess', 0666); // mettre 0644 en production
32 }
33
34 // droits en lecture et écriture dans le cas d'une migration
35 // tester si le site est "vide" et prévoir un formulaire permettant d'upload le fichier .zip
36 // contenant toutes les données qu'il est possible de créer depuis le mode admin
37 // cette méthode a deux intérêts:
38 // - facilité pour l'utilisateur
39 // - toutes les données sont la "possession" du serveur apache,
40 // on prévient ainsi tous les futurs problèmes de droits
41
42 // dans le cas de l'utilisation d'une base de données, le fichiers zip devrait contenir un "dump"
43 // (un fichier .sql), à voir si php est capable d'obtenir ou redonner ce fichier à la BDD
44
45 // créer les dossiers (fait également à l'extraction du zip de données)
46 // attention: ne fonctionne pas sans une manipulation préalable
47 // - modifier soit-même les droits du dossier data (777), quoique 111 serait pas mal non plus
48 // - 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
50 $listePages = array('melaine');
51 foreach ($listePages as $page)
52 {
53 if(!file_exists('data/' . $page))
54 {
55 mkdir('data/' . $page);
56 chmod('data/' . $page, 0777);
57 }
58 if(!file_exists('data/' . $page . '/html'))
59 {
60 mkdir('data/' . $page . '/html');
61 chmod('data/' . $page . '/html', 0777);
62 }
63 if(!file_exists('data/' . $page . '/images'))
64 {
65 mkdir('data/' . $page . '/images');
66 chmod('data/' . $page . '/images', 0777);
67 }
68 // if(!file_exists('data/' . $page . '/multimedia'))
69 // {
70 // mkdir('data/' . $page . '/multimedia');
71 // chmod('data/' . $page . '/multimedia', 0777);
72 // }
73 }
74 // donner les droits 666 aux fichiers à l'intérieur
75}
diff --git a/controller/media.php b/controller/media.php
new file mode 100644
index 0000000..8105b4d
--- /dev/null
+++ b/controller/media.php
@@ -0,0 +1,212 @@
1<?php
2
3// traitement avant enregistrement dans le fichier submit.php
4// cette fonction extrait les liens pointant vers des medias embarqués
5// (liste de sites) et les restituent nus, sans les balises
6function mediaSubmit($chaine)
7{
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";
10
11 // sites gérés manuellement (l'éditeur semble ne pas les connaître)
12 $regexListeNonGeree = 'https://open.spotify.com/embed/\w+/\w+';
13
14 // à faire plus tard
15 //https://www.openstreetmap.org.*layer=mapnik
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
18 //global $regexListeNonGeree;
19
20 //echo($chaine . "\n");
21
22 // pour embarquer spotify, l'url doit ressembler à https://open.spotify.com/embed/...
23 // on ajoute "/embed" si necessaire
24 $chaine = preg_replace('#spotify.com(?!/embed)#', '$0/embed', $chaine);
25
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>
28
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>
31 // (?:) permet de matcher sans capturer, donc de retirer des choses
32 // pour la variable $tolere, on met:
33 // \w = [a-zA-Z0-9_], espace ' ', tabulation \t, CR et LF \r\n,
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
36 $tolere = '\w\s\t\n\r/,;:éèàçù€\#@%\.\(\)[\]\{\}\?\!\|-';
37 $pattern = '#(?:<a href=")([' . $tolere . ']{1,})?(' . $regexListeNonGeree . ')([' . $tolere . ']{1,})?(?:">[' . $tolere . ']+</a>)#';
38 $chaine = preg_replace($pattern, '$2', $chaine);
39 //echo($chaine . "\n");
40
41 // on met les balises <span>
42 $pattern = '#' . $regexListeNonGeree . '#';
43 $remplacement = '<span class="media_embed">$0</span>';
44 $chaine = preg_replace($pattern, $remplacement, $chaine);
45
46 // c'est quoi cette merde?
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
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
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
53 $dom = new DOMDocument;
54
55 // pour ne pas s'arrêter sur les erreurs à cause des "nouvelles" balises
56 libxml_use_internal_errors(true);
57
58 if($dom->loadHTML($chaine)) // et non load() tout court qui sert à charger du XML
59 {
60 // <figure>
61 // détecter <figure class="media"><oembed url="http://...">
62 // puis extraire le lien et supprimer les balises autour
63 if(preg_match("#<figure class=\"media\"><oembed url=\".+\"></oembed></figure>#", $chaine))
64 {
65 $nbFigures = $dom->getElementsByTagName('figure')->length;
66
67 $j = 0;
68 for($i = 0; $i < $nbFigures ; $i++) // boucle foreach impossible, une <figure> disparaît à chaque tour
69 {
70 $balisesFigure = $dom->getElementsByTagName('figure');
71 $figure = $balisesFigure->item($j); // l'item 1 devient 0 au deuxième passage, etc
72 $parent = $figure->parentNode;
73
74 if($figure->getAttribute("class") == 'media')
75 {
76 $oembed = $figure->getElementsByTagName('oembed'); // 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
79 {
80 $lien = $oembed->item(0)->getAttribute('url') . ' '; // un espace pour ne pas coller deux adresses
81 $span = $dom->createElement('span', $lien);
82 $class = $dom->createAttribute('class');
83 $class->value = 'media_embed';
84 $span->appendChild($class);
85 $parent->replaceChild($span, $figure);
86 }
87 elseif($div->length > 0) // cette div créée par le ckeditor contient notre lien, plus bas se trouve une iframe
88 {
89 $lien = $div->item(0)->getAttribute('data-oembed-url') . ' ';
90 $span = $dom->createElement('span', $lien);
91 $class = $dom->createAttribute('class');
92 $class->value = 'media_embed';
93 $span->appendChild($class);
94 $parent->replaceChild($span, $figure);
95 }
96 else
97 {
98 $j++; // la balise <figure> n'est pas supprimée, on incrémente l'indice du tableau pour ne pas boucler à l'infini
99 }
100 }
101 }
102 }
103
104 // <iframe>
105 // détecter <iframe src="http://..." et remplacer par le lien nu, comme au dessus
106 // site sans oembed?
107 if(preg_match("#<iframe src=\".+\"></iframe>#", $chaine))
108 {
109 $nbIframes = $dom->getElementsByTagName('iframe')->length;
110
111 for($i = 0; $i < $nbIframes ; $i++)
112 {
113 $balisesIframe = $dom->getElementsByTagName('iframe');
114 $iframe = $balisesIframe->item(0);
115 $parent = $iframe->parentNode;
116
117 $lien = $iframe->getAttribute('src') . ' ';
118 $span = $dom->createElement('span', $lien);
119 $class = $dom->createAttribute('class');
120 $class->value = 'media_embed';
121 $span->appendChild($class);
122 $parent->replaceChild($span, $$iframe);
123 }
124 }
125
126 // <a>
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"
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
131 if(preg_match("#<a href=\".+\">.*</a>#", $chaine))
132 {
133 $nbA = $dom->getElementsByTagName('a')->length;
134
135 $j = 0;
136 for($i = 0; $i < $nbA ; $i++)
137 {
138 $balisesA = $dom->getElementsByTagName('a');
139 $a = $balisesA->item($j);
140 $parent = $a->parentNode;
141
142 $lien = $a->getAttribute('href') . ' ';
143
144 // seules les liens pointant vers une des adresses de la liste sont concernés
145 if(preg_match("#" . $listeMedia . "#", $lien))
146 {
147 $span = $dom->createElement('span', $lien);
148 $class = $dom->createAttribute('class');
149 $class->value = 'media_embed';
150 $span->appendChild($class);
151 $parent->replaceChild($span, $a);
152 }
153 else
154 {
155 $j++; // la balise <a> n'est pas supprimée, on incrémente l'indice du tableau pour ne pas boucler à l'infini
156 }
157 }
158 }
159
160 // pour nettoyer tous les warnings qu'on vient de produire et purifier nos fichiers log
161 libxml_clear_errors();
162 // pour au contraire pouvoir les regarder, remplacer la ligne au dessus par celles en dessous
163 //~ $errors = libxml_get_errors();
164 //~ var_dump($errors);
165
166 // mettre à jour le DOM et enlever le DOCTYPE et les balises <html> et <body>
167 $chaine = $dom->saveHTML($dom);
168 $pattern = array ('#<!DOCTYPE.*>#', '#<html><body>#', '#</html></body>#');
169 $remplacement = array ('', '', '');
170 $chaine = preg_replace($pattern, $remplacement, $chaine);
171 }
172 else
173 {
174 echo "Impossible de charger le HTML";
175 }
176
177
178
179 // détecter soundcloud
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))
182 {}
183
184 // détecter facebook (éventuellement fb.watch)
185 // je crois que ça va être compliqué ici
186 if(preg_match("#facebook.com|fb.watch#", $chaine))
187 {}
188
189 return($chaine); // = $contenu
190}
191
192
193// embarquement !!
194function mediaEmbed($chaine)
195{
196 //require("../Embera/src/Autoloader.php");
197 //$embera = new Embera\Embera();
198 //$chaine = $embera->autoEmbed($chaine);
199
200 $pattern = '#<span class="media_embed">(.+)</span>#';
201 $remplacement = '<iframe src="$1" frameborder="0" allowtransparency="true"></iframe>';
202 $chaine = preg_replace($pattern, $remplacement, $chaine);
203
204 // requête oembed
205 //~ echo('<br/><br/>');
206 //~ print_r($embera->getUrlData([
207 //~ 'https://vimeo.com/374131624',
208 //~ 'https://www.flickr.com/photos/bees/8597283706/in/photostream',
209 //~ ]));
210
211 return($chaine); // = $contenu
212}
diff --git a/controller/visitor.php b/controller/visitor.php
new file mode 100644
index 0000000..98d7a45
--- /dev/null
+++ b/controller/visitor.php
@@ -0,0 +1,110 @@
1<?php
2// controller/visitor.php
3//
4// simple affichage du site au visiteur
5
6// pages du sites
7function accueil()
8{
9 $title = "Bienvenue sur le site de Melaine Favennec";
10 $page_actuelle = "accueil";
11 $content = '';
12
13 // variables $js et $header
14 require('view/accueil.php');
15 // HTML
16 require('view/template.php');
17}
18
19function menu()
20{
21 $title = "Melaine Favennec - menu BD";
22 $page_actuelle = "menu";
23
24 // variables $css, $js et $content
25 require('view/menu.php');
26 // HTML
27 require('view/template.php');
28}
29
30function melaineVisitor()
31{
32 $page_actuelle = "melaine";
33 $title = "Mais qui est Melaine Favennec?";
34
35 // variables $nombreDarticles et tableau $articles
36 require('model/melaine-read.php');
37
38 // vérification pour protéger les visiteurs
39 // normalement déjà faite dans submit.php,
40 // c'est au cas où les données aient été trafiquées
41 //$article = htmLawed($article);
42
43 // variables $css, $js et $content
44 require('view/melaine.php');
45 // HTML
46 require('view/template.php');
47}
48
49function discographie()
50{}
51
52function presse()
53{}
54
55function ateliers()
56{}
57
58function liens()
59{}
60
61function peinture()
62{}
63
64function archives()
65{}
66
67function connexion($secret)
68{
69 // déjà en mode admin
70 if($_SESSION['admin'] == 1)
71 {
72 header('Location: index.php?page=' . $_GET['from']);
73 }
74
75 // Ajouter une sécurité par cpatcha avec un "input" supplémentaire
76 // Et créer une variable de session pour la réponse au CAPTCHA
77
78 $title = "connexion";
79 $subHeading = "Veuillez saisir votre mot de passe pour pouvoir apporter des modifications au site.";
80
81 // cette page utilise la même vue que la fonction changerMotDePasse() dans controller/admin.php
82 require('view/connexion.php');
83
84 echo($header);
85
86 // bon mot de passe
87 if(isset ($_POST["motdepasse"]) AND $_POST["motdepasse"] == $secret)
88 {
89 $_SESSION['admin'] = 1;
90 header('Location: index.php?page=' . $_GET['from']);
91 exit ();
92 }
93
94 // mauvaise mot de passe
95 elseif(isset ($_POST["motdepasse"]) AND $_POST["motdepasse"] != $secret)
96 {
97 // défense aux attaques par force brute
98 // pas parfait, ne marche pas si l'attaquant multiplie les connexions au site
99 sleep(1);
100 echo($formulaireConnexion);
101 }
102
103 // première arrivée sur la page
104 else
105 {
106 echo($formulaireConnexion);
107 }
108
109 echo($footer);
110} \ No newline at end of file