diff options
Diffstat (limited to 'public/index.php')
-rw-r--r-- | public/index.php | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/public/index.php b/public/index.php new file mode 100644 index 0000000..69f335c --- /dev/null +++ b/public/index.php | |||
@@ -0,0 +1,178 @@ | |||
1 | <?php | ||
2 | if(isset($_GET['action']) && $_GET['action'] == 'editor_submit'){ | ||
3 | // récupération des données | ||
4 | $data = file_get_contents('php://input'); | ||
5 | $json = json_decode($data, true); | ||
6 | |||
7 | // Vérifier du décodage du JSON | ||
8 | if(json_last_error() === JSON_ERROR_NONE) { | ||
9 | // Traitement les données... | ||
10 | $articleId = $json['id']; | ||
11 | $content = $json['content']; | ||
12 | |||
13 | // retour au client | ||
14 | echo json_encode(['success' => true]); | ||
15 | } | ||
16 | else{ | ||
17 | echo json_encode(['success' => false, 'message' => 'Erreur de décodage JSON']); | ||
18 | } | ||
19 | die; | ||
20 | } | ||
21 | elseif(isset($_GET['action']) && $_GET['action'] == 'upload_image'){ | ||
22 | echo "hello"; | ||
23 | die; | ||
24 | } | ||
25 | ?> | ||
26 | <!DOCTYPE html> | ||
27 | <html lang="fr"> | ||
28 | <head> | ||
29 | <meta charset="UTF-8"> | ||
30 | <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
31 | <title>Éditeur d'Article</title> | ||
32 | <style> | ||
33 | .tox-promotion{ | ||
34 | display: none; | ||
35 | } | ||
36 | .hidden{ | ||
37 | display: none; | ||
38 | } | ||
39 | </style> | ||
40 | <script src="../node_modules/tinymce/tinymce.min.js"></script> | ||
41 | <!-- peut-être qu'on devra utiliser un lien symbolique vers ce fichier dans /public --> | ||
42 | <script> | ||
43 | let editors = {}; | ||
44 | |||
45 | function openEditor(articleId) { | ||
46 | // Récupérer et sauvegarder le contenu d'origine de l'article | ||
47 | const articleContent = document.getElementById(articleId).innerHTML; | ||
48 | document.getElementById(articleId).setAttribute('data-original-content', articleContent); | ||
49 | |||
50 | tinymce.init({ | ||
51 | selector: `#${articleId}`, | ||
52 | language: 'fr_FR', // télécharger le paquet correspondant ici: https://www.tiny.cloud/get-tiny/language-packages/ | ||
53 | license_key: 'gpl', | ||
54 | branding: false, | ||
55 | plugins: 'image code', // Activer le plugin d'image | ||
56 | toolbar: 'undo redo | styles | bold italic | alignleft aligncenter alignright alignjustify | outdent indent | image code', | ||
57 | setup: function (editor) { | ||
58 | editor.on('init', function () { | ||
59 | editors[articleId] = editor; | ||
60 | |||
61 | // Masquer le bouton "Modifier" et afficher les boutons "Annuler" et "Soumettre" | ||
62 | document.querySelector(`#edit-${articleId}`).classList.add('hidden'); | ||
63 | document.querySelector(`#cancel-${articleId}`).classList.remove('hidden'); | ||
64 | document.querySelector(`#submit-${articleId}`).classList.remove('hidden'); | ||
65 | }); | ||
66 | }, | ||
67 | // upload d'image | ||
68 | images_upload_handler: function (blobInfo, success, failure) { | ||
69 | const xhr = new XMLHttpRequest(); | ||
70 | xhr.withCredentials = false; | ||
71 | xhr.open('POST', 'index.php?action=upload_image'); | ||
72 | |||
73 | xhr.onload = function() { | ||
74 | const json = JSON.parse(xhr.responseText); | ||
75 | |||
76 | if (xhr.status < 200 || xhr.status >= 300) { | ||
77 | failure('HTTP Error: ' + xhr.status); | ||
78 | return; | ||
79 | } | ||
80 | |||
81 | success(json.location); | ||
82 | }; | ||
83 | |||
84 | const formData = new FormData(); | ||
85 | formData.append('file', blobInfo.blob(), blobInfo.filename()); | ||
86 | xhr.send(formData); | ||
87 | } | ||
88 | }); | ||
89 | |||
90 | // Remplacer le contenu de l'article par l'éditeur | ||
91 | document.getElementById(articleId).innerHTML = articleContent; | ||
92 | } | ||
93 | |||
94 | function closeEditor(articleId) { | ||
95 | // Récupérer le contenu d'origine de l'article | ||
96 | const originalContent = document.getElementById(articleId).getAttribute('data-original-content'); | ||
97 | |||
98 | // Fermer l'éditeur | ||
99 | tinymce.remove(`#${articleId}`); | ||
100 | delete editors[articleId]; | ||
101 | |||
102 | // Restaurer le contenu d'origine de l'article | ||
103 | document.getElementById(articleId).innerHTML = originalContent; | ||
104 | |||
105 | // Afficher le bouton "Modifier" et masquer les boutons "Annuler" et "Soumettre" | ||
106 | document.querySelector(`#edit-${articleId}`).classList.remove('hidden'); | ||
107 | document.querySelector(`#cancel-${articleId}`).classList.add('hidden'); | ||
108 | document.querySelector(`#submit-${articleId}`).classList.add('hidden'); | ||
109 | } | ||
110 | |||
111 | function submitArticle(articleId) { | ||
112 | // Récupérer l'éditeur correspondant à l'article | ||
113 | const editor = editors[articleId]; | ||
114 | if (!editor) { | ||
115 | console.error('Éditeur non trouvé pour l\'article:', articleId); | ||
116 | return; | ||
117 | } | ||
118 | |||
119 | // Récupérer le contenu de l'éditeur | ||
120 | const newContent = editor.getContent(); | ||
121 | |||
122 | // test sans envoi au serveur | ||
123 | //~ closeEditor(articleId); | ||
124 | //~ document.getElementById(articleId).innerHTML = newContent; | ||
125 | //~ console.log(newContent); | ||
126 | |||
127 | |||
128 | // Envoyer le contenu au serveur via AJAX | ||
129 | //fetch('/save-article', { | ||
130 | fetch('index.php?action=editor_submit', { | ||
131 | method: 'POST', | ||
132 | headers: { | ||
133 | 'Content-Type': 'application/json' | ||
134 | }, | ||
135 | body: JSON.stringify({ id: articleId, content: newContent }) | ||
136 | }) | ||
137 | .then(response => response.json()) | ||
138 | .then(data => { | ||
139 | // Fermer l'éditeur et mettre à jour le contenu de l'article | ||
140 | closeEditor(articleId); | ||
141 | document.getElementById(articleId).innerHTML = newContent; | ||
142 | console.log(newContent); | ||
143 | if (data.success) { | ||
144 | // Fermer l'éditeur et mettre à jour le contenu de l'article | ||
145 | tinymce.remove(`#${articleId}`); | ||
146 | document.getElementById(articleId).innerHTML = newContent; | ||
147 | } else { | ||
148 | alert('Erreur lors de la sauvegarde de l\'article.'); | ||
149 | } | ||
150 | }) | ||
151 | .catch(error => { | ||
152 | console.error('Erreur:', error); | ||
153 | }); | ||
154 | } | ||
155 | </script> | ||
156 | </head> | ||
157 | <body> | ||
158 | <div> | ||
159 | <h2>Article 1</h2> | ||
160 | <div id="article-1"> | ||
161 | <p>Contenu de l'article 1.</p> | ||
162 | </div> | ||
163 | <button id="edit-article-1" onclick="openEditor('article-1')">Modifier</button> | ||
164 | <button id="cancel-article-1" class="hidden" onclick="closeEditor('article-1')">Annuler</button> | ||
165 | <button id="submit-article-1" class="hidden" onclick="submitArticle('article-1')">Soumettre</button> | ||
166 | </div> | ||
167 | |||
168 | <div> | ||
169 | <h2>Article 2</h2> | ||
170 | <div id="article-2"> | ||
171 | <p>Contenu de l'article 2.</p> | ||
172 | </div> | ||
173 | <button id="edit-article-2" onclick="openEditor('article-2')">Modifier</button> | ||
174 | <button id="cancel-article-2" class="hidden" onclick="closeEditor('article-2')">Annuler</button> | ||
175 | <button id="submit-article-2" class="hidden" onclick="submitArticle('article-2')">Soumettre</button> | ||
176 | </div> | ||
177 | </body> | ||
178 | </html> | ||