diff options
Diffstat (limited to 'src/upload.php')
| -rw-r--r-- | src/upload.php | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/src/upload.php b/src/upload.php new file mode 100644 index 0000000..62db139 --- /dev/null +++ b/src/upload.php | |||
| @@ -0,0 +1,66 @@ | |||
| 1 | <?php | ||
| 2 | /* upload.php — handle image uploads */ | ||
| 3 | |||
| 4 | header('Content-Type: application/json'); | ||
| 5 | |||
| 6 | if ($_SERVER['REQUEST_METHOD'] !== 'POST') { | ||
| 7 | http_response_code(405); | ||
| 8 | echo json_encode(['error' => 'Method not allowed']); | ||
| 9 | exit; | ||
| 10 | } | ||
| 11 | |||
| 12 | if (!isset($_FILES['image']) || $_FILES['image']['error'] !== UPLOAD_ERR_OK) { | ||
| 13 | $code = $_FILES['image']['error'] ?? 'unknown'; | ||
| 14 | http_response_code(400); | ||
| 15 | echo json_encode(['error' => "Upload failed (code: $code)"]); | ||
| 16 | exit; | ||
| 17 | } | ||
| 18 | |||
| 19 | $file = $_FILES['image']; | ||
| 20 | $allowed = [ | ||
| 21 | 'image/png', 'image/jpeg', 'image/gif', | ||
| 22 | 'image/webp', 'image/svg+xml', 'image/bmp', | ||
| 23 | ]; | ||
| 24 | |||
| 25 | $finfo = finfo_open(FILEINFO_MIME_TYPE); | ||
| 26 | $mime = finfo_file($finfo, $file['tmp_name']); | ||
| 27 | finfo_close($finfo); | ||
| 28 | |||
| 29 | if (!in_array($mime, $allowed, true)) { | ||
| 30 | http_response_code(400); | ||
| 31 | echo json_encode(['error' => "Invalid file type: $mime"]); | ||
| 32 | exit; | ||
| 33 | } | ||
| 34 | |||
| 35 | $ext = match ($mime) { | ||
| 36 | 'image/png' => 'png', | ||
| 37 | 'image/jpeg' => 'jpg', | ||
| 38 | 'image/gif' => 'gif', | ||
| 39 | 'image/webp' => 'webp', | ||
| 40 | 'image/svg+xml' => 'svg', | ||
| 41 | 'image/bmp' => 'bmp', | ||
| 42 | default => 'bin', | ||
| 43 | }; | ||
| 44 | |||
| 45 | /* generate safe filename */ | ||
| 46 | $basename = pathinfo($file['name'], PATHINFO_FILENAME); | ||
| 47 | $basename = preg_replace('/[^a-zA-Z0-9_-]/', '_', $basename); | ||
| 48 | $basename = substr($basename, 0, 64); | ||
| 49 | $filename = $basename . '_' . bin2hex(random_bytes(4)) . '.' . $ext; | ||
| 50 | |||
| 51 | $uploadDir = __DIR__ . '/uploads'; | ||
| 52 | if (!is_dir($uploadDir)) { | ||
| 53 | mkdir($uploadDir, 0755, true); | ||
| 54 | } | ||
| 55 | |||
| 56 | $dest = $uploadDir . '/' . $filename; | ||
| 57 | if (!move_uploaded_file($file['tmp_name'], $dest)) { | ||
| 58 | http_response_code(500); | ||
| 59 | echo json_encode(['error' => 'Failed to save file']); | ||
| 60 | exit; | ||
| 61 | } | ||
| 62 | |||
| 63 | echo json_encode([ | ||
| 64 | 'filename' => $filename, | ||
| 65 | 'url' => 'uploads/' . $filename, | ||
| 66 | ]); | ||
