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 /public/index.php | |
| 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
Diffstat (limited to 'public/index.php')
| -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{ |
