summaryrefslogtreecommitdiff
path: root/view
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 /view
downloadmelaine-87798e5554eb0330cd2de255e5034f0472d410a4.zip
mot de passe
Diffstat (limited to 'view')
-rw-r--r--view/accueil.php24
-rw-r--r--view/connexion.php62
-rw-r--r--view/courriel.php10
-rw-r--r--view/melaine.php113
-rw-r--r--view/menu.php74
-rw-r--r--view/nav.php13
-rw-r--r--view/template-ckeditor.php189
-rw-r--r--view/template.php90
8 files changed, 575 insertions, 0 deletions
diff --git a/view/accueil.php b/view/accueil.php
new file mode 100644
index 0000000..3d852d7
--- /dev/null
+++ b/view/accueil.php
@@ -0,0 +1,24 @@
1<?php
2// view/accueil.php
3
4// variable $js
5ob_start();
6?>
7 <script type="text/javascript" src="public/main.js" ></script>
8 <script type="text/javascript" >accueil_vers_menu();</script>
9<?php
10$js = ob_get_clean();
11
12// variable $header
13ob_start();
14echo "\n\n";
15?>
16 <header>
17 <a class="no_underline" href="index.php?page=menu" >
18 <div id="bienvenue" >
19 <span class="police_titre" >Bienvenue sur le site de</span>
20 </div>
21 </a>
22 </header>
23<?php
24$header = ob_get_clean(); \ No newline at end of file
diff --git a/view/connexion.php b/view/connexion.php
new file mode 100644
index 0000000..2187ecf
--- /dev/null
+++ b/view/connexion.php
@@ -0,0 +1,62 @@
1<?php
2// view/connexion.php
3//
4// ce fichier contient le HTML de deux pages du site:
5// - connexion au mode admin
6// - changement de mot de passe
7
8// formulaire connexion
9ob_start();
10?>
11 <form class="connexionFormulaire" method="post" action="index.php?page=connexion&from=<?= $_GET['from'] ?>" >
12 <label for="motdepasse" >Mot de passe:</label>
13 <input type="password" name="motdepasse" autofocus required >
14 <input type="submit" value="Valider" >
15 </form>
16<?php
17$formulaireConnexion = ob_get_clean();
18
19// formulaire changement de mot de passe
20// vérification de l'ancien et choix du nouveau à taper deux fois dont une à l'aveugle
21ob_start();
22?>
23
24<?php
25$formulaireNouveauMDP = ob_get_clean();
26
27// en-tête
28ob_start();
29?>
30<!DOCTYPE html>
31
32<html lang="fr" >
33 <head>
34 <meta charset="utf-8" />
35 <title><?= $title ?></title>
36
37 <!-- <link rel="shortcut icon" type="image/x-icon" href="favicon.ico" /> -->
38 <link rel="icon" type="image/png" href="public/mouette-logo.png" >
39 <link rel="stylesheet" type="text/css" href="public/normalize.css">
40 <link rel="stylesheet" type="text/css" href="public/accueil.css" />
41 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
42 </head>
43
44 <body>
45 <div id="bloc_page" >
46 <h2 class="connexionTitre" ><?= $title ?></h2>
47 <p class="connexionTitre" ><?= $subHeading ?></p>
48<?php
49$header = ob_get_clean();
50
51// pied de page
52ob_start();
53?>
54 <p class="connexionFooter" >
55 <i>N'oubliez de cliquer sur "déconnexion" quand vous aurez fini.</i><br />
56 <a href="index.php?page=<?= $_GET['from'] ?>" >Retour à la page précédente</a>
57 </p>
58 </div>
59 </body>
60</html>
61<?php
62$footer = ob_get_clean(); \ No newline at end of file
diff --git a/view/courriel.php b/view/courriel.php
new file mode 100644
index 0000000..ed5fe79
--- /dev/null
+++ b/view/courriel.php
@@ -0,0 +1,10 @@
1 <div id="courriel" >
2 <div>
3 <img src="public/timbre.png" alt="" ><br />Envoyez-moi un courriel à: <img src="public/courriel.png" >
4 </div>
5
6 <div id="courrielJS" >
7 <button onclick="clientCourriel();" >Avec mon logiciel<br />de messagerie</button>
8 <button onclick="copierAdresse();" >Copier l'adresse dans<br />le presse-papier</button>
9 </div>
10 </div> \ No newline at end of file
diff --git a/view/melaine.php b/view/melaine.php
new file mode 100644
index 0000000..9fb8482
--- /dev/null
+++ b/view/melaine.php
@@ -0,0 +1,113 @@
1<?php
2// view/melaine.php
3//
4// variable $css
5ob_start();
6?>
7 <link rel="stylesheet" type="text/css" href="public/<?= $page_actuelle ?>.css" />
8 <link rel="stylesheet" type="text/css" href="public/donnees_hors_editeur.css" />
9<?php
10$css = ob_get_clean();
11
12
13//variable $js
14ob_start();
15?>
16 <script type="text/javascript" src="public/main.js" ></script>
17<?php
18if(isset($_GET['action']) && $_GET['action'] == 'editor')
19{
20
21 // bibliothèques JS ckeditor et ckfinder
22?>
23 <script src="lib/ckeditor5/build/ckeditor.js"></script>
24<?php
25}
26$js = ob_get_clean();
27
28
29// variable $header
30ob_start();
31echo "\n";
32?>
33 <header>
34 <div id="titre" >
35 <span class="police_titre" >Melaine Favennec</span>
36 </div>
37 <div id="photo" ></div>
38 </header>
39 <?php
40$header = ob_get_clean();
41
42
43// variable $content
44ob_start();
45if($_SESSION['admin'] == 1)
46{
47 // éditeur
48 if(isset($_GET['action']) && $_GET['action'] == 'editor' && !isset($_GET['article']))
49 {
50 echo("<p>Rédiger un nouvel article</p>");
51 echo($editeurHTML); // injection de template-editor.php
52 }
53
54 // bouton
55 else
56 {
57?>
58 <p class="boutonArticle" >
59 <a href="index.php?page=melaine&action=editor" >
60 Nouvel article
61 </a>
62 </p>
63<?php
64 }
65}
66
67// on pourrait paginer avec des onglets contenant 5 ou 10 articles chacun
68
69// tableau articles[] du dernier au premier (1 case = 1 article)
70for ($i=$nombreDarticles - 1; $i >= 0 ; $i--)
71{
72 $j = $i + 1;
73
74 // la div invisible sert à la compensation des liens d'ancre #
75?>
76 <div class="zoneVideNav" ></div>
77 <article id="article<?= $j ?>" >
78<?php
79
80// remplacer un article par l'éditeur
81if($_SESSION['admin'] == 1 && isset($_GET['action']) && $_GET['action'] == 'editor' && isset($_GET['article']) && $_GET['article'] == $j)
82{
83 echo("\n<p>Modifier l'article " . $j . "</p>");
84 //echo("<p>Modification d'un article</p>");
85 echo "\n";
86
87 echo($editeurHTML); // injection de template-editor.php
88}
89
90// placer un article
91else
92{
93 // c'était pas compliqué
94 echo($articles[$i] . "\n");
95
96 // bouton
97 if($_SESSION['admin'] == 1)
98 {
99 ?>
100 <p class="boutonArticle" >
101 <a href="index.php?page=melaine&action=editor&article=<?= $j ?>#article<?= $j ?>" >
102 Modifier cet article
103 </a>
104 </p>
105 <?php
106 }
107}
108
109?>
110 </article>
111<?php
112}
113$content = ob_get_clean();
diff --git a/view/menu.php b/view/menu.php
new file mode 100644
index 0000000..51476b4
--- /dev/null
+++ b/view/menu.php
@@ -0,0 +1,74 @@
1<?php
2// view/menu.php
3
4// variable $css
5ob_start();
6?>
7 <link rel="stylesheet" type="text/css" href="public/<?= $page_actuelle ?>.css" />
8<?php
9$css = ob_get_clean();
10
11//variable $js
12ob_start();
13?>
14 <script type="text/javascript" src="public/main.js" ></script>
15<?php
16$js = ob_get_clean();
17
18// variable $header
19ob_start();
20echo "\n\n";
21?>
22 <header>
23 <div id="titre" >
24 <span class="police_titre" >Choisissez une rubrique</span>
25 </div>
26 </header>
27 <?php
28$header = ob_get_clean();
29
30// variable $content
31ob_start();
32echo "\n";
33?>
34 <div id="contenu" >
35 <div id="colonne1" >
36 <a href="index.php?page=liens" >
37 <div id="canoe" ></div>
38 </a>
39
40 <a href="index.php?page=presse" >
41 <div id="fille_qui_tombe" ></div>
42 </a>
43
44 <a href="index.php?page=melaine" >
45 <div id="pochette" ></div>
46 </a>
47
48 <a href="index.php?page=ateliers" >
49 <div id="cavalier" ></div>
50 </a>
51
52 <a href="index.php" >
53 <div id="pommes" ></div>
54 </a>
55 </div>
56
57 <div id="colonne2" >
58 <a href="index.php?page=concerts" >
59 <div id="sirene" ></div>
60 </a>
61
62 <a href="index.php?page=peinture" >
63 <div id="mouette_ocean" ></div>
64 </a>
65
66 <a href="index.php?page=archives" >
67 <div id="blonde"></div>
68 </a>
69
70 <a id="hey_ho" href="index.php?page=discographie" ></a>
71 </div>
72 </div>
73<?php
74$content = ob_get_clean(); \ No newline at end of file
diff --git a/view/nav.php b/view/nav.php
new file mode 100644
index 0000000..f7cb299
--- /dev/null
+++ b/view/nav.php
@@ -0,0 +1,13 @@
1 <nav>
2 <ul>
3 <li><a href="index.php?page=menu" <?php if($page_actuelle == "menu") {echo('id="actuelle" ');} ?>>Menu</a></li>
4 <li><a href="index.php?page=melaine" <?php if($page_actuelle == "melaine") {echo('id="actuelle" ');} ?>>Melaine</a></li>
5 <li><a href="index.php?page=discographie" <?php if($page_actuelle == "discographie") {echo('id="actuelle" ');} ?>>Discographie</a></li>
6 <li><a href="index.php?page=concerts" <?php if($page_actuelle == "concerts") {echo('id="actuelle" ');} ?>>Concerts</a></li>
7 <li><a href="index.php?page=presse" <?php if($page_actuelle == "presse") {echo('id="actuelle" ');} ?>>La Presse</a></li>
8 <li><a href="index.php?page=ateliers" <?php if($page_actuelle == "ateliers ") {echo('id="actuelle" ');} ?>>Ateliers</a></li>
9 <li><a href="index.php?page=liens" <?php if($page_actuelle == "liens") {echo('id="actuelle" ');} ?>>Liens</a></li>
10 <li><a href="index.php?page=peinture" <?php if($page_actuelle == "peinture") {echo('id="actuelle" ');} ?>>Peinture</a></li>
11 <li><a href="index.php?page=archives" <?php if($page_actuelle == "archives") {echo('id="actuelle" ');} ?>>Archives</a></li>
12 </ul>
13 </nav> \ No newline at end of file
diff --git a/view/template-ckeditor.php b/view/template-ckeditor.php
new file mode 100644
index 0000000..48b673a
--- /dev/null
+++ b/view/template-ckeditor.php
@@ -0,0 +1,189 @@
1<?php
2// view/template-ckeditor.php
3
4// voici la partie HTML et javascript du ckeditor,
5// elle permette d'insérer l'éditeur dans la page avec un formulaire qui comporte 4 éléments:
6// barre d'outils, zone de saisie, formulaire caché, bouton "valider"
7
8// le formulaire est presque classique, en effet on utilise le ckeditor 5 dans sa version "Document" (ou DecoupledEditor):
9// - avantage: plus de possibilité dans la barre d'outils (se rapproche d'un traitement de texte)
10// - inconvénient: on ne peut utiliser la balise <textarea> qu'on remplace par une <div>
11
12// pour pouvoir envoyer le contenu dans le POST, on a deux possibilité:
13// - savoir coder en javascript ! et donc faire de l'AJAX, dans ce cas on n'a même plus besoin de formulaire, le contenu est envoyé au serveur au fur et à mesure! ce sera l'objet d'une future amélioration
14// - utiliser l'astuce du formulaire caché !
15
16// le javascript place les données dans le formulaire caché
17// avec la fonction envoiDonnees(), les données se retrouvent dans une <input> et sont donc envoyées avec par la POST (haha)
18
19// l'envoi d'image en revanche utilise nécessairement de l'AJAX et
20// la bibliothèque "ckfinder" (en JS + PHP) me permet de ne pas coder moi-même un "upload adapter", ce sera l'objet d'une autre amélioration, et en plus certaines fonctionnalités sont payantes
21// https://ckeditor.com/docs/ckeditor5/latest/framework/guides/deep-dive/upload-adapter.html
22// le ckfinder communique avec le serveur au moyen de requêtes AJAX,
23// le fichier est ainsi téléchargé sur le serveur avant même d'apparaître dans l'éditeur
24// attention, le ckfinder nécessite php7.3, les extensions GD et FileInfo et le support du type MIME JSON sur le serveur (retenir php7.3 et GD)
25// https://ckeditor.com/ckfinder/download/
26
27// variable $editeurHTML
28ob_start();
29?>
30
31 <div class="conteneur_article" >
32 <form action="index.php?page=<?= $page_actuelle ?>&article=<?= $numArticle ?>&action=submit" method="post" >
33 <textarea id="editor" name="contenu" ></textarea>
34
35<?php
36// falsification de requête inter-site
37// on ajoute un formulaire caché avec une valeur aléatoire cryptée utilisable une seule fois (=jeton)
38
39// "Vous pouvez rendre chaque jeton utilisable une seule fois et ainsi éviter de rejouer plusieurs fois la même requête.
40// Les jetons sont stockés dans le back-office.
41// Une rotation des jetons est effectuée quand le nombre maximum a été atteint, les plus vieux en premier.
42// Chaque jeton peut être lié à une URL spécifique.
43// Si un jeton est intercepté, il ne peut pas être utilisé dans un autre contexte.
44// Si besoin, les jetons peuvent être attachés à une adresse IP spécifique.
45// Depuis la version v2.1, les jetons peuvent être réutilisés (par exemple pour les requêtes AJAX).
46// Si vous n’utilisez pas un framework qui gère la protection CSRF pour vous, jetez un oeil à Anti-CSRF."
47
48// une bibli qui fait ça: https://github.com/paragonie/anti-csrf
49?>
50
51 <input class="boutonSubmitEditeur" type="submit" value="Valider" onclick="envoiDonnees();" />
52
53 <script>
54 let editor; // variable utilisable depuis une fonction
55
56 // code exécuté à la validation du formulaire
57 function envoiDonnees()
58 {
59 // supprimer le positionnement absolu de l'iframe
60 //~ let balisesIframe = document.getElementsByTagName("iframe");
61 //~ for(var i = 0; i < balisesIframe.length; i++)
62 //~ {
63 //~ alert(balisesIframe[i].getAttribute("style")); // affiche le CSS
64 //~ balisesIframe[i].removeAttribute("style");
65 //~ alert(balisesIframe[i].getAttribute("style")); // affiche null
66 //~ }
67 }
68
69 // ATTENTION: si l'éditeur ne fonctionne pas, empêcher qu'on puisse cliquer sur Valider!
70 // Il y a aussi des paramètres dans le fichier de config: ckeditor/webpack.config.js
71 ClassicEditor
72 .create( document.querySelector( '#editor' ),{
73 language: 'fr',
74
75 // barre d'outils à adapter au build
76 toolbar: {
77 items: [ 'undo', 'redo', 'selectAll', '|', 'heading', '|', 'alignment', 'bulletedList', 'numberedList', 'todoList', 'blockQuote', 'horizontalLine', '-', 'bold', 'italic', 'underline',
78 //'strikethrough',
79 '|',
80 //'fontFamily',
81 'fontColor', 'fontSize', 'highlight', '|', 'imageInsert', 'link',
82 //'htmlEmbed',
83 //'mediaEmbed',
84 'insertTable'
85 //'|', 'textPartLanguage'
86 ],
87 // multiligne automatique (le '-' dans la liste permet de choisir l'endroit où couper)
88 shouldNotGroupWhenFull: true
89
90 // noter que 'fontFamily' ne comporte que des polices microsoft => problèmes de droits?
91 // de plus, il faut que le navigateur connaisse toutes les polices
92 },
93
94 // barre d'outils dans une image
95 image: {
96 toolbar: [
97 'imageTextAlternative',
98 'imageStyle:full',
99 'imageStyle:side',
100 'linkImage'
101 ]
102 },
103
104 // barre d'outils dans un tableau
105 table: {
106 contentToolbar: [
107 'tableColumn',
108 'tableRow',
109 'mergeTableCells',
110 //'tableCellProperties',
111 'tableProperties'
112 ]
113 },
114
115 // plugin code HTML
116 // pour coller le code HTML "embed" proposé par certains sites
117 //
118
119 // media embarqué (audio, vidéo, carte)
120 mediaEmbed: {
121 //previewsInData: true,
122 // vaut "false" par defaut, on crée la balise non standard <oembed url="" > // https://oembed.com/
123 // qui nécessite un traitement (en JS ou côté serveur) en utilisant le lien à l'intérieur
124 // avec "true", on crée la balise <iframe> qui sert à insérer une page HTML dans une autre,
125 // notre "embarquement de média" devrit donc réussir quelque soit le site
126 // c'est plus simple, il ne reste plus qu'à ajuster le contenu avec du CSS (important)
127 // on doit supprimer le positionnement absolu qui fait que l'iframe se place par dessus le reste et adapter la taille de l'élément
128
129 // en outre, le plugin mediaEmbed (dans l'éditeur), tout comme la balise "iframe" (hors éditeur),
130 // permettent d'afficher un aperçu (preview): une image avec un bouton lecture dessus
131 // cette image est envoyée imédiatement par le serveur, et le contenu après un clic dessus
132 //
133 },
134
135 // images
136 // https://ckeditor.com/docs/ckeditor5/latest/features/image-upload/simple-upload-adapter.html
137 // le plugin "image upload" s'occupe est la partie graphique, il crée un objet "createLoader",
138 // le plugin "simple upload adapter" est la classe qui communique avec le serveur au moyen de requêtes AJAX
139 // il attend du serveur une réponse au format .json contenant l'adresse où est stockée l'image:
140 //{
141 // "url": "https://example.com/images/foo.jpg"
142 //}
143 // cette url sert à deux choses:
144 // - à télécharger l'image avant de la placer dans l'éditeur
145 // - écrire le HTML qu'on enregistrera ensuite
146 // en effet, le fichier est téléchargé sur le serveur avant de revenir dans l'éditeur comme un téléchargement classique
147
148 simpleUpload: {
149 uploadUrl: 'imageAJAX.php?page=<?= $page_actuelle ?>',
150 // noter qu'il est possible (parce que souhaitable je ne pense pas) d'envoyer une requête AJAX
151 // en indiquant une adresse "statique" du type: fichier.txt ou .xml, jpg, png, etc
152
153 // Headers supplémentaires envoyés avec la requête
154 // c'est ici qu'on installe les mécanismes de sécurités comme l'authentification et la protection au CSRF
155 headers: {
156 'X-CSRF-TOKEN': 'CSRF-Token',
157 Authorization: 'Bearer <JSON Web Token>'
158 }
159 },
160 // formats acceptés par défaut: jpeg, png, gif, bmp, webp, tiff
161 // le svg n'est pas dans la liste, pour raison de sécurité il me semble, apparemment on peut mettre du javascript à l'intérieur
162
163 // ce plugin a l'intérêt de ne pas imposer l'utilisation de l'extension GD de PHP,
164 // Reste qu'il sera quand même intéressant de l'ajouter pour le redimensionnement des images trop lourdes,
165 // quoi que le système d'onglets (limiter l'affichge à 5 ou 10 articles par page) règle aussi le problème d'une autre manière
166
167
168 // plugin autosave
169 } )
170
171 .then( newEditor => {
172 editor = newEditor;
173
174 // obtenir la liste des éléments disponibles pour la barre d'outils
175 //alert(Array.from( editor.ui.componentFactory.names() ));
176 // obtenir la liste des plugins disponibles:
177 //alert(ClassicEditor.builtinPlugins.map( plugin => plugin.pluginName ));
178
179 var initial = '<?= $initial ?>';
180 editor.setData(initial);
181 } )
182 .catch( error => {
183 console.error( error );
184 } );
185 </script>
186 </form>
187 </div>
188<?php
189$editeurHTML = ob_get_clean(); \ No newline at end of file
diff --git a/view/template.php b/view/template.php
new file mode 100644
index 0000000..772b0b1
--- /dev/null
+++ b/view/template.php
@@ -0,0 +1,90 @@
1<!DOCTYPE html>
2
3<html lang="fr" >
4 <head>
5 <meta charset="utf-8" />
6 <title><?= $title ?></title>
7
8 <!-- partie que Melaine doit écrire -->
9 <meta name="description" content="" />
10
11 <!-- <link rel="shortcut icon" type="image/x-icon" href="favicon.ico" /> -->
12 <link rel="icon" type="image/png" href="public/mouette-logo.png" >
13 <link rel="stylesheet" type="text/css" href="public/normalize.css">
14 <link rel="stylesheet" type="text/css" href="public/accueil.css" />
15<?php
16if(isset($css)) // fichiers CSS supplémentaires
17{
18 echo($css);
19}
20
21if(isset($js)) // fonctions dans main.js puis appel des fonctions
22{
23 echo($js);
24}
25?>
26 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
27 </head>
28
29 <body>
30 <div id="bloc_page" >
31<?php
32echo "\n";
33require("view/nav.php");
34echo "\n";
35
36// variables obtenues avec le buffer
37echo($header);
38?>
39
40 <div id="contenu" >
41<?php
42echo($content);
43?>
44 </div>
45<?php
46
47// section courriel sur toutes les pages sauf accueil
48if($page_actuelle != "accueil")
49{
50 echo "\n";
51 require("view/courriel.php");
52 echo "\n\n";
53}
54
55// lien vers le mode admin
56if($_SESSION['admin'] == 0)
57{
58?>
59 <div id="lienModeAdmin" >
60 <p><a href="index.php?page=connexion&from=<?= $page_actuelle ?>" >Mode Administrateur</a></p>
61 </div>
62<?php
63}
64
65// actions en mode admin
66if($_SESSION['admin'] == 1)
67{
68?>
69 <!-- zone superposée par les commande du mode admin -->
70 <div class="zoneVideAdmin" ></div>
71
72 <div id="modeAdmin" >
73 <p>Vous êtes en mode administrateur.
74 <a href="index.php?action=deconnexion" >Déconnexion</a></p>
75 <div>
76 <p><a href="index.php?from=<?= $page_actuelle ?>&action=nouveau_mdp" >
77 Changer le mot de passe de connexion.</a></p>
78 <p><a href="melainePHP.zip" >
79 Télécharger le code PHP pour migration.</a></p>
80 <p><a href="index.php?from=<?= $page_actuelle ?>&action=extraction" >
81 Extraire les données de tout le site.</a></p>
82 <p><a href="index.php?from=<?= $page_actuelle ?>&action=insertion" >Restauration des données avec une sauvegarde.</a></p>
83 </div>
84 </div>
85<?php
86}
87?>
88 </div>
89 </body>
90</html> \ No newline at end of file