$status, 'message' => $message, 'data' => $data ]); exit; } if ($_SERVER['REQUEST_METHOD'] !== 'POST') { json_response('error', 'Invalid request method.'); } if (!isset($_FILES['document']) || $_FILES['document']['error'] == UPLOAD_ERR_NO_FILE) { json_response('error', 'No file was uploaded.'); } $file = $_FILES['document']; // Check for upload errors if ($file['error'] !== UPLOAD_ERR_OK) { $upload_errors = [ UPLOAD_ERR_INI_SIZE => 'The uploaded file exceeds the upload_max_filesize directive in php.ini.', UPLOAD_ERR_FORM_SIZE => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.', UPLOAD_ERR_PARTIAL => 'The uploaded file was only partially uploaded.', UPLOAD_ERR_NO_FILE => 'No file was uploaded.', UPLOAD_ERR_NO_TMP_DIR => 'Missing a temporary folder.', UPLOAD_ERR_CANT_WRITE => 'Failed to write file to disk.', UPLOAD_ERR_EXTENSION => 'A PHP extension stopped the file upload.', ]; $error_message = $upload_errors[$file['error']] ?? 'Unknown upload error.'; json_response('error', $error_message); } $upload_dir = __DIR__ . '/uploads/'; if (!is_dir($upload_dir)) { if (!mkdir($upload_dir, 0775, true)) { json_response('error', 'Failed to create upload directory.'); } } $file_name = basename($file['name']); $target_path = $upload_dir . $file_name; // Move the file to the uploads directory if (move_uploaded_file($file['tmp_name'], $target_path)) { // AI Translation Step try { require_once __DIR__ . '/ai/LocalAIApi.php'; $source_lang = $_POST['source_lang'] ?? 'auto-detect'; $target_lang = $_POST['target_lang'] ?? 'English'; $file_path_for_ai = 'uploads/' . $file_name; // Read the file content and base64 encode it $file_content = file_get_contents($target_path); $base64_image = base64_encode($file_content); // Check if mime_content_type function exists if (function_exists('mime_content_type')) { $mime_type = mime_content_type($target_path); } else { // Fallback to a generic MIME type if the function doesn't exist $mime_type = 'application/octet-stream'; } $resp = LocalAIApi::createResponse([ 'input' => [ [ 'role' => 'user', 'content' => [ [ 'type' => 'text', 'text' => "You are an expert document translator. Please perform the following tasks:\n" \ . "1. **OCR Extraction:** Extract all visible text from the attached image.\n" \ . "2. **Translation:** Translate the extracted text from `{$source_lang}` to `{$target_lang}`.\n" \ . "3. **Output:** Return ONLY the translated text as a single block of plain text. Do not include any explanations, apologies, or introductory phrases. Just the translation." ], [ 'type' => 'image', 'source' => [ 'type' => 'base64', 'media_type' => $mime_type, 'data' => $base64_image, ], ], ], ], ], ]); if (!empty($resp['success'])) { $translated_text = LocalAIApi::extractText($resp); if ($translated_text === '') { // Handle cases where the AI returns a non-text response or empty text $decoded = LocalAIApi::decodeJsonFromResponse($resp); $error_details = $decoded ? json_encode($decoded, JSON_PRETTY_PRINT) : 'AI returned an empty or invalid response.'; json_response('error', 'AI processing failed. Details: ' . $error_details); } else { json_response('success', 'File translated successfully.', [ 'filePath' => $file_path_for_ai, 'translatedText' => $translated_text ]); } } else { $error_message = $resp['error'] ?? 'Unknown AI error.'; json_response('error', 'Failed to get response from AI service: ' . $error_message); } } catch (Exception $e) { json_response('error', 'An exception occurred during AI processing: ' . $e->getMessage()); } } else { json_response('error', 'Failed to move uploaded file.'); } ?>