'php_running', 'gd' => function_exists('getimagesize'), 'fileinfo' => function_exists('mime_content_type')]); exit; } $max_bytes = 20 * 1024 * 1024; // 20 Mt header('Content-Type: application/json'); if ($_SERVER['REQUEST_METHOD'] !== 'POST') { ob_clean(); http_response_code(405); echo json_encode(['error' => 'Method not allowed']); exit; } if (empty($_FILES['file'])) { ob_clean(); http_response_code(400); echo json_encode(['error' => 'No file']); exit; } $f = $_FILES['file']; if ($f['error'] !== UPLOAD_ERR_OK) { $codes = [1=>'Tiedosto ylittää php.ini upload_max_filesize',2=>'Tiedosto ylittää MAX_FILE_SIZE',3=>'Tiedosto tuli vain osittain',6=>'Ei temp-kansiota',7=>'Levylle kirjoitus epäonnistui']; ob_clean(); http_response_code(400); echo json_encode(['error' => 'Lähetysvirhe: ' . ($codes[$f['error']] ?? 'koodi '.$f['error'])]); exit; } if ($f['size'] > $max_bytes) { ob_clean(); http_response_code(413); echo json_encode(['error' => 'Tiedosto liian suuri (max 20 Mt)']); exit; } // getimagesize() on osa GD-kirjastoa (ei vaadi fileinfo-laajennusta) $imginfo = @getimagesize($f['tmp_name']); $type_map = [IMAGETYPE_JPEG => 'image/jpeg', IMAGETYPE_PNG => 'image/png', IMAGETYPE_GIF => 'image/gif', IMAGETYPE_WEBP => 'image/webp']; $mime = $imginfo ? ($type_map[$imginfo[2]] ?? null) : null; if (!$mime) { ob_clean(); http_response_code(415); echo json_encode(['error' => 'Vain kuvat (jpeg/png/gif/webp) hyväksytään']); exit; } $ext_map = ['image/jpeg' => '.jpg', 'image/png' => '.png', 'image/gif' => '.gif', 'image/webp' => '.webp']; $ext = $ext_map[$mime] ?? '.jpg'; $dir = __DIR__ . '/images/'; if (!is_dir($dir)) { mkdir($dir, 0755, true); } $fname = round(microtime(true) * 1000) . $ext; $dest = $dir . $fname; if (!move_uploaded_file($f['tmp_name'], $dest)) { ob_clean(); http_response_code(500); $writable = is_writable($dir) ? 'kirjoitusoikeus ok' : 'EI kirjoitusoikeutta'; echo json_encode(['error' => "Tiedoston tallennus epäonnistui. Kansio images/: $writable"]); exit; } ob_clean(); echo json_encode(['url' => 'images/' . $fname]);