diff options
| author | polo <ordipolo@gmx.fr> | 2026-01-01 19:57:21 +0100 |
|---|---|---|
| committer | polo <ordipolo@gmx.fr> | 2026-01-01 19:57:21 +0100 |
| commit | 573e3a46efbf159c68a7e9c169b16135a478ab61 (patch) | |
| tree | 4cc112f36e76044d586a21c066eae8faf17f3e37 | |
| parent | 4fa8395994b478a867afbc9efc0143cb64c7c70b (diff) | |
| download | tinymce-573e3a46efbf159c68a7e9c169b16135a478ab61.tar.gz tinymce-573e3a46efbf159c68a7e9c169b16135a478ab61.tar.bz2 tinymce-573e3a46efbf159c68a7e9c169b16135a478ab61.zip | |
factorisation du code dupliqué pour les trois méthodes d'upload, prise en compte du fait que writeImage convertit de force en fonction de l'extension du fichier, paramètres de compression des images
| -rw-r--r-- | public/index.php | 180 |
1 files changed, 82 insertions, 98 deletions
diff --git a/public/index.php b/public/index.php index d8d26e2..2cd0c78 100644 --- a/public/index.php +++ b/public/index.php | |||
| @@ -1,16 +1,37 @@ | |||
| 1 | <?php | 1 | <?php |
| 2 | function imagickCleanImage(string $image_data, string $local_path, string $format = 'jpeg'): bool // "string" parce que file_get_contents... | 2 | function imagickCleanAndWriteImage(string $image_data, string $local_path): bool // "string" parce que file_get_contents... |
| 3 | { | 3 | { |
| 4 | $format = strtolower(pathinfo($local_path)['extension']); | ||
| 4 | try{ | 5 | try{ |
| 5 | $imagick = new Imagick(); | 6 | $imagick = new Imagick(); |
| 6 | $imagick->readImageBlob($image_data); | 7 | $imagick->readImageBlob($image_data); |
| 7 | $imagick->stripImage(); // nettoyage métadonnées | 8 | $imagick->stripImage(); // nettoyage métadonnées |
| 8 | $imagick->setImageFormat($format); | 9 | //$imagick->setImageFormat($format); // inutile, writeImage force la conversion |
| 9 | if($format === 'jpeg'){ | 10 | |
| 10 | $imagick->setImageCompression(Imagick::COMPRESSION_JPEG); | 11 | // compression |
| 11 | $imagick->setImageCompressionQuality(85); // optionnel | 12 | switch($format){ |
| 13 | case 'jpeg': // particularité du switch, si 'jpeg' le test de 'jpg' est ignoré et on va jusqu'au break | ||
| 14 | case 'jpg': | ||
| 15 | $imagick->setImageCompression(Imagick::COMPRESSION_JPEG); | ||
| 16 | $imagick->setImageCompressionQuality(85); | ||
| 17 | break; | ||
| 18 | case 'webp': | ||
| 19 | $imagick->setImageCompression(Imagick::COMPRESSION_WEBP); | ||
| 20 | $imagick->setImageCompressionQuality(85); | ||
| 21 | break; | ||
| 22 | case 'png': | ||
| 23 | $imagick->setImageCompression(Imagick::COMPRESSION_ZIP); | ||
| 24 | $imagick->setImageCompressionQuality(7); // 9 est sans perte | ||
| 25 | break; | ||
| 26 | case 'tiff': | ||
| 27 | $imagick->setImageCompression(Imagick::COMPRESSION_LZW); // LZW est sans perte | ||
| 28 | break; | ||
| 12 | } | 29 | } |
| 13 | $imagick->writeImage($local_path); // enregistrement | 30 | |
| 31 | // enregistrement | ||
| 32 | // writeImage utilise l'extension du fichier et ignore le format détecté | ||
| 33 | // imagemagick est à l'origine une appli console, elle considère que l'extension montre l'intention de l'utilisateur | ||
| 34 | $imagick->writeImage($local_path); | ||
| 14 | $imagick->clear(); | 35 | $imagick->clear(); |
| 15 | $imagick->destroy(); | 36 | $imagick->destroy(); |
| 16 | return true; | 37 | return true; |
| @@ -20,7 +41,7 @@ function imagickCleanImage(string $image_data, string $local_path, string $forma | |||
| 20 | } | 41 | } |
| 21 | } | 42 | } |
| 22 | 43 | ||
| 23 | function curlDownloadImage(string $url, $maxRetries = 3, $timeout = 10): string|false | 44 | function curlDownloadImage(string $url, int $maxRetries = 3, int $timeout = 10): string|false |
| 24 | { | 45 | { |
| 25 | $attempt = 0; | 46 | $attempt = 0; |
| 26 | $imageData = false; | 47 | $imageData = false; |
| @@ -124,112 +145,75 @@ elseif(isset($_GET['action']) && $_GET['action'] == 'delete_article'){ | |||
| 124 | } | 145 | } |
| 125 | die; | 146 | die; |
| 126 | } | 147 | } |
| 127 | elseif(isset($_GET['action']) && $_GET['action'] == 'upload_image'){ | 148 | |
| 128 | if(isset($_FILES['file'])){ | 149 | |
| 129 | $file = $_FILES['file']; | 150 | elseif(isset($_GET['action']) && in_array($_GET['action'], ['upload_image', 'upload_image_url', 'upload_image_base64'])){ |
| 130 | $dest = 'images/'; | 151 | $dest = 'images/'; |
| 131 | 152 | if(!is_dir($dest)){ | |
| 132 | if(!is_dir($dest)){ | 153 | mkdir($dest, 0755, true); |
| 133 | mkdir($dest, 0755, true); | 154 | } |
| 134 | } | 155 | $allowed_extensions = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'tiff', 'tif']; |
| 135 | 156 | ||
| 136 | $allowed_extensions = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'tiff', 'tif']; | 157 | if($_GET['action'] == 'upload_image'){ |
| 137 | $name = sanitizeFileName(pathinfo($file['name'], PATHINFO_FILENAME)); | 158 | if(!isset($_FILES['file'])){ |
| 138 | $extension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION)); | 159 | http_response_code(400); |
| 139 | if(!in_array($extension, $allowed_extensions) || $extension === 'jpg'){ | 160 | echo json_encode(['message' => 'Erreur 400: Bad Request']); |
| 140 | $extension = 'jpeg'; | 161 | die; |
| 141 | } | ||
| 142 | $file_path = $dest . $name . '_' . uniqid() . '.' . $extension; | ||
| 143 | |||
| 144 | if(!is_uploaded_file($file['tmp_name'])) { | ||
| 145 | http_response_code(500); | ||
| 146 | echo json_encode(['message' => "Le fichier n'a pas été téléchargé correctement."]); | ||
| 147 | } | ||
| 148 | |||
| 149 | if(imagickCleanImage(file_get_contents($file['tmp_name']), $file_path, $extension)){ // recréer l’image pour la nettoyer | ||
| 150 | echo json_encode(['location' => $file_path]); | ||
| 151 | } | 162 | } |
| 152 | else{ | 163 | if(!is_uploaded_file($_FILES['file']['tmp_name'])) { |
| 153 | http_response_code(500); | 164 | http_response_code(500); |
| 154 | echo json_encode(['message' => 'Erreur image non valide']); | 165 | echo json_encode(['message' => "Le fichier n'a pas été téléchargé correctement."]); |
| 166 | die; | ||
| 155 | } | 167 | } |
| 156 | } | ||
| 157 | else{ | ||
| 158 | http_response_code(400); | ||
| 159 | echo json_encode(['message' => 'Erreur 400: Bad Request']); | ||
| 160 | } | ||
| 161 | die; | ||
| 162 | } | ||
| 163 | elseif(isset($_GET['action']) && $_GET['action'] == 'upload_image_url'){ | ||
| 164 | $json = json_decode(file_get_contents('php://input'), true); | ||
| 165 | |||
| 166 | if(isset($json['image_url'])){ | ||
| 167 | $image_data = curlDownloadImage($json['image_url']); // téléchargement de l’image par le serveur avec cURL au lieu de file_get_contents | ||
| 168 | $dest = 'images/'; | ||
| 169 | 168 | ||
| 170 | if(!is_dir($dest)){ | 169 | $name = sanitizeFileName(pathinfo($_FILES['file']['name'], PATHINFO_FILENAME)); |
| 171 | mkdir($dest, 0755, true); | 170 | $extension = strtolower(pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION)); |
| 171 | $image_data = file_get_contents($_FILES['file']['tmp_name']); | ||
| 172 | } | ||
| 173 | elseif($_GET['action'] == 'upload_image_url'){ | ||
| 174 | $json = json_decode(file_get_contents('php://input'), true); | ||
| 175 | if(!isset($json['image_url'])){ | ||
| 176 | http_response_code(400); | ||
| 177 | echo json_encode(['message' => 'Erreur 400: Bad Request']); | ||
| 178 | die; | ||
| 172 | } | 179 | } |
| 173 | 180 | ||
| 181 | $image_data = curlDownloadImage($json['image_url']); // téléchargement de l’image par le serveur avec cURL au lieu de file_get_contents | ||
| 174 | if($image_data === false){ | 182 | if($image_data === false){ |
| 175 | http_response_code(400); | 183 | http_response_code(400); |
| 176 | echo json_encode(['message' => "Erreur, le serveur n'a pas réussi à télécharger l'image."]); | 184 | echo json_encode(['message' => "Erreur, le serveur n'a pas réussi à télécharger l'image."]); |
| 177 | die; | 185 | die; |
| 178 | } | 186 | } |
| 179 | 187 | ||
| 180 | $allowed_extensions = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'tiff', 'tif']; | ||
| 181 | $url_path = parse_url($json['image_url'], PHP_URL_PATH); | 188 | $url_path = parse_url($json['image_url'], PHP_URL_PATH); |
| 182 | $name = sanitizeFileName(pathinfo($url_path, PATHINFO_FILENAME)); | 189 | $name = sanitizeFileName(pathinfo($url_path, PATHINFO_FILENAME)); |
| 183 | $extension = strtolower(pathinfo($url_path, PATHINFO_EXTENSION)); | 190 | $extension = strtolower(pathinfo($url_path, PATHINFO_EXTENSION)); |
| 184 | if(!in_array($extension, $allowed_extensions) || $extension === 'jpg'){ | 191 | } |
| 185 | $extension = 'jpeg'; | 192 | elseif($_GET['action'] == 'upload_image_base64'){ |
| 186 | } | 193 | $json = json_decode(file_get_contents('php://input'), true); |
| 187 | $local_path = $dest . $name . '_' . uniqid() . '.' . $extension; | ||
| 188 | 194 | ||
| 189 | if(imagickCleanImage($image_data, $local_path, $extension)){ // recréer l’image pour la nettoyer | 195 | // détection de data:image/ et de ;base64, et capture du format dans $type |
| 190 | echo json_encode(['location' => $local_path]); | 196 | if(!isset($json['image_base64']) || !preg_match('/^data:image\/(\w+);base64,/', $json['image_base64'], $type)){ // $type est déclaré et passé par référence |
| 191 | } | 197 | http_response_code(400); |
| 192 | else{ | 198 | echo json_encode(['message' => 'Données image base64 manquantes ou invalides']); |
| 193 | http_response_code(500); | 199 | die; |
| 194 | echo json_encode(['message' => 'Erreur image non valide']); | ||
| 195 | } | 200 | } |
| 196 | } | 201 | $extension = strtolower($type[1]); // dans (\w+) |
| 197 | else{ | ||
| 198 | echo json_encode(['message' => 'Erreur 400: Bad Request']); | ||
| 199 | } | ||
| 200 | die; | ||
| 201 | } | ||
| 202 | elseif(isset($_GET['action']) && $_GET['action'] == 'upload_image_base64'){ | ||
| 203 | $json = json_decode(file_get_contents('php://input'), true); | ||
| 204 | $dest = 'images/'; | ||
| 205 | 202 | ||
| 206 | if(!is_dir($dest)){ | 203 | $name = 'pasted_image'; |
| 207 | mkdir($dest, 0755, true); | 204 | $image_data = base64_decode(substr($json['image_base64'], strpos($json['image_base64'], ',') + 1)); // découpe la chaine à la virgule puis convertit en binaire |
| 208 | } | 205 | if($image_data === false){ |
| 209 | 206 | http_response_code(400); | |
| 210 | // détection de data:image/ et de ;base64, et capture du format dans $type | 207 | echo json_encode(['message' => 'Décodage base64 invalide']); |
| 211 | if(!isset($json['image_base64']) || !preg_match('/^data:image\/(\w+);base64,/', $json['image_base64'], $type)){ | 208 | die; |
| 212 | http_response_code(400); | 209 | } |
| 213 | echo json_encode(['message' => 'Données image base64 manquantes ou invalides']); | ||
| 214 | die; | ||
| 215 | } | 210 | } |
| 216 | 211 | ||
| 217 | $allowed_extensions = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'tiff', 'tif']; | 212 | if(!in_array($extension, $allowed_extensions)){ |
| 218 | $extension = strtolower($type[1]); | ||
| 219 | if(!in_array($extension, $allowed_extensions) || $extension === 'jpg'){ | ||
| 220 | $extension = 'jpeg'; | 213 | $extension = 'jpeg'; |
| 221 | } | 214 | } |
| 222 | 215 | $local_path = $dest . $name . '_' . uniqid() . '.' . $extension; | |
| 223 | $image_data = base64_decode(substr($json['image_base64'], strpos($json['image_base64'], ',') + 1)); // découpe la chaine à la virgule puis convertit en binaire | 216 | if(imagickCleanAndWriteImage($image_data, $local_path)){ |
| 224 | if($image_data === false){ | ||
| 225 | http_response_code(400); | ||
| 226 | echo json_encode(['message' => 'Décodage base64 invalide']); | ||
| 227 | die; | ||
| 228 | } | ||
| 229 | |||
| 230 | $local_path = $dest . 'pasted_image_' . uniqid() . '.' . $extension; | ||
| 231 | |||
| 232 | if(imagickCleanImage($image_data, $local_path)){ | ||
| 233 | echo json_encode(['location' => $local_path]); | 217 | echo json_encode(['location' => $local_path]); |
| 234 | } | 218 | } |
| 235 | else{ | 219 | else{ |
| @@ -238,21 +222,21 @@ elseif(isset($_GET['action']) && $_GET['action'] == 'upload_image_base64'){ | |||
| 238 | } | 222 | } |
| 239 | die; | 223 | die; |
| 240 | } | 224 | } |
| 225 | |||
| 226 | |||
| 241 | elseif(isset($_GET['action']) && $_GET['action'] == 'upload_file'){ | 227 | elseif(isset($_GET['action']) && $_GET['action'] == 'upload_file'){ |
| 242 | if(isset($_FILES['file'])){ | 228 | if(isset($_FILES['file'])){ |
| 243 | $file = $_FILES['file']; | ||
| 244 | $dest = 'media/'; | 229 | $dest = 'media/'; |
| 245 | |||
| 246 | if(!is_dir($dest)){ // Vérifier si le répertoire existe, sinon le créer | 230 | if(!is_dir($dest)){ // Vérifier si le répertoire existe, sinon le créer |
| 247 | mkdir($dest, 0755, true); | 231 | mkdir($dest, 0755, true); |
| 248 | } | 232 | } |
| 249 | 233 | ||
| 250 | $name = sanitizeFileName(pathinfo($file['name'], PATHINFO_FILENAME)); // retirer caractères spéciaux et changer espaces en underscores | 234 | $name = sanitizeFileName(pathinfo($_FILES['file']['name'], PATHINFO_FILENAME)); // retirer caractères spéciaux et changer espaces en underscores |
| 251 | $extension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION)); | 235 | $extension = strtolower(pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION)); |
| 252 | $file_path = $dest . $name . '_' . uniqid() . '.' . $extension; // nom unique | 236 | $file_path = $dest . $name . '_' . uniqid() . '.' . $extension; // nom unique |
| 253 | 237 | ||
| 254 | if(checkFileDownload($file)){ | 238 | if(checkFileDownload($_FILES['file'])){ |
| 255 | if(move_uploaded_file($file['tmp_name'], $file_path)){ | 239 | if(move_uploaded_file($_FILES['file']['tmp_name'], $file_path)){ |
| 256 | echo json_encode(['location' => $file_path]); | 240 | echo json_encode(['location' => $file_path]); |
| 257 | } | 241 | } |
| 258 | else{ | 242 | else{ |
