summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--public/js/tinymce.js50
-rw-r--r--src/controller/ajax.php39
2 files changed, 86 insertions, 3 deletions
diff --git a/public/js/tinymce.js b/public/js/tinymce.js
index f8d78c8..18974af 100644
--- a/public/js/tinymce.js
+++ b/public/js/tinymce.js
@@ -48,6 +48,51 @@ function openEditor(id, page = '') {
48 document.querySelector(`#new-${id}`).classList.add('hidden'); // id = new-new-id_node 48 document.querySelector(`#new-${id}`).classList.add('hidden'); // id = new-new-id_node
49 } 49 }
50 }); 50 });
51 let skipPastePreProcess = false;
52 editor.on('Paste', function (e){ // déclenchement AVANT PastePreProcess et quelque que soit le contenu collé
53 const clipboardData = (e.clipboardData || e.originalEvent.clipboardData);
54 if(!clipboardData){
55 return;
56 }
57 const items = clipboardData.items;
58 let foundImage = false;
59
60 for(let i = 0; i < items.length; i++){
61 let item = items[i];
62
63 if(item.type.indexOf('image') !== -1){ // test type MIME contenant image
64 foundImage = true;
65
66 const file = item.getAsFile(); // presse-papier => fichier lisible
67 const reader = new FileReader();
68
69 reader.onload = function (event){ // fonction exécutée lorsque reader.readAsDataURL(file) est terminée
70 const base64Data = event.target.result; // données de l'image
71
72 fetch('index.php?action=upload_image_base64', {
73 method: 'POST',
74 headers: { 'Content-Type': 'application/json' },
75 body: JSON.stringify({ image_base64: base64Data })
76 })
77 .then(response => response.json())
78 .then(data => {
79 if(data.location){
80 editor.insertContent('<img src="' + data.location + '">');
81 }
82 })
83 .catch(error => {
84 console.error('Erreur lors de l’upload de l’image base64 :', error);
85 });
86 };
87 reader.readAsDataURL(file); // lecture asynchrone du fichier
88 }
89 }
90
91 if(foundImage){
92 e.preventDefault(); // supprime le collage automatiue
93 skipPastePreProcess = true; // désactiver le PastePreProcess pour ce collage
94 }
95 });
51 editor.on('PastePreProcess', function (e){ // déclenchement au collage AVANT insertion dans l'éditeur 96 editor.on('PastePreProcess', function (e){ // déclenchement au collage AVANT insertion dans l'éditeur
52 const parser = new DOMParser(); 97 const parser = new DOMParser();
53 const doc = parser.parseFromString(e.content, 'text/html'); 98 const doc = parser.parseFromString(e.content, 'text/html');
@@ -58,9 +103,8 @@ function openEditor(id, page = '') {
58 images.forEach(img => { 103 images.forEach(img => {
59 if(img.src.startsWith('file://')){ // détection d'images non insérables 104 if(img.src.startsWith('file://')){ // détection d'images non insérables
60 console.warn('Image locale non insérable dans tinymce :', img.src); 105 console.warn('Image locale non insérable dans tinymce :', img.src);
61 img.outerHTML = '<div style="border:1px solid red; padding:10px; margin:5px 0; background-color:#ffe6e6; color:#a94442; font-size:14px;">' + 106 img.outerHTML = `<div style="border:1px solid red; padding:10px; margin:5px 0; background-color:#ffe6e6; color:#a94442; font-size:14px;">
62"Image locale non insérée (vient-elle de LibreOffice ?). Effacez cet encadré et copiez-collez l'image seule. Ensuite cliquez sur le bouton Insérer une image puis dans la nouvelle fenêtre sur Enregistrer." + 107 "Image locale non insérée (vient-elle d'un document LibreOffice ?). Effacez ce message rouge et copiez-collez l'image seule.</div>`;
63'</div>';
64 } 108 }
65 else if(img.src.startsWith('http')){ // détection d'images web 109 else if(img.src.startsWith('http')){ // détection d'images web
66 const promise = fetch('index.php?action=upload_image_url', { // promesse d'un fichier téléchargeable sur le serveur 110 const promise = fetch('index.php?action=upload_image_url', { // promesse d'un fichier téléchargeable sur le serveur
diff --git a/src/controller/ajax.php b/src/controller/ajax.php
index 6813d45..a462921 100644
--- a/src/controller/ajax.php
+++ b/src/controller/ajax.php
@@ -142,7 +142,46 @@ elseif(isset($_GET['action']) && $_GET['action'] == 'upload_image_url'){
142 } 142 }
143 die; 143 die;
144} 144}
145// cas du collage d'une image (code base64) non encapsulée dans du HTML
146elseif(isset($_GET['action']) && $_GET['action'] == 'upload_image_base64'){
147 $json = json_decode(file_get_contents('php://input'), true);
148 $dest = 'images/';
149
150 if(!is_dir('images')){
151 mkdir('images', 0777, true);
152 }
145 153
154 // détection de data:image/ et de ;base64, et capture du format dans $type
155 if(!isset($json['image_base64']) || !preg_match('/^data:image\/(\w+);base64,/', $json['image_base64'], $type)){
156 http_response_code(400);
157 echo json_encode(['message' => 'Données image base64 manquantes ou invalides']);
158 die;
159 }
160
161 $allowed_extensions = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'tiff', 'tif'];
162 $extension = strtolower($type[1]);
163 if(!in_array($extension, $allowed_extensions) || $extension === 'jpg'){
164 $extension = 'jpeg';
165 }
166
167 $image_data = base64_decode(substr($json['image_base64'], strpos($json['image_base64'], ',') + 1)); // découpe la chaine à la virgule puis convertit en binaire
168 if($image_data === false){
169 http_response_code(400);
170 echo json_encode(['message' => 'Décodage base64 invalide']);
171 die;
172 }
173
174 $local_path = $dest . 'pasted_image_' . uniqid() . '.' . $extension;
175
176 if(imagickCleanImage($image_data, $local_path)){
177 echo json_encode(['location' => $local_path]);
178 }
179 else{
180 http_response_code(500);
181 echo json_encode(['message' => 'Erreur image non valide']);
182 }
183 die;
184}
146 185
147// détection des requêtes de type XHR, y en a pas à priori 186// détection des requêtes de type XHR, y en a pas à priori
148/*elseif(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'){ 187/*elseif(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'){