'ok']); } // Только POST if ($_SERVER['REQUEST_METHOD'] !== 'POST') { json_response(['success' => false, 'error' => 'Method not allowed'], 405); } log_message('=== START API REQUEST ==='); // Получаем входные данные $input = file_get_contents('php://input'); log_message('Raw input: ' . substr($input, 0, 500)); $input = ltrim($input, "\xEF\xBB\xBF\x00\x09\x0A\x0D\x20"); $data = json_decode($input, true); if (json_last_error() !== JSON_ERROR_NONE) { log_message('❌ JSON Error: ' . json_last_error_msg()); json_response([ 'success' => false, 'error' => 'Invalid JSON: ' . json_last_error_msg() ], 400); } // Поддерживаем как массив, так и одиночный объект $documents_array = is_array($data) && isset($data[0]) ? $data : [$data]; log_message('Processing ' . count($documents_array) . ' document(s)'); // Обрабатываем каждый документ $processed_documents = []; $S3_HOST = 'https://s3.twcstorage.ru'; foreach ($documents_array as $idx => $doc) { $contact_id = $doc['contact_id'] ?? null; $project_id = $doc['project_id'] ?? null; $ticket_id = $doc['ticket_id'] ?? null; // Поддерживаем оба формата: file и file_url $file_path = $doc['file'] ?? $doc['file_url'] ?? null; if (!$file_path) { log_message("❌ Document #{$idx}: missing 'file' or 'file_url'"); continue; } // Строим полный S3 URL if (strpos($file_path, 'http') === 0) { $file_url = $file_path; } elseif (strpos($file_path, '/') === 0) { $file_url = $S3_HOST . $file_path; } else { $file_url = $S3_HOST . '/' . $file_path; } // Поддерживаем оба формата: filename и file_name $file_name = $doc['filename'] ?? $doc['file_name'] ?? null; if (!$file_name) { log_message("❌ Document #{$idx}: missing 'filename' or 'file_name'"); continue; } $file_type = $doc['file_type'] ?? 'Документ'; // Валидация обязательных полей if (!$contact_id || !$project_id) { log_message("❌ Document #{$idx}: missing contact_id or project_id"); continue; } log_message(" [{$idx}] {$file_name} (type: {$file_type})"); log_message(" Contact: {$contact_id}, Project: {$project_id}, Ticket: " . ($ticket_id ?: 'N/A')); log_message(" File URL: {$file_url}"); $processed_documents[] = [ 'url' => $file_url, 'file_name' => $file_name, 'description' => $file_type, 'projectid' => (int)$project_id, 'ticket_id' => $ticket_id ? (int)$ticket_id : null, 'contactid' => (int)$contact_id, 'pages' => 1 ]; } if (empty($processed_documents)) { log_message('❌ No valid documents to process'); json_response([ 'success' => false, 'error' => 'No valid documents to process' ], 400); } log_message('📤 Sending ' . count($processed_documents) . ' documents to upload_documents_to_crm.php'); // Формируем запрос к upload_documents_to_crm.php $upload_url = 'https://crm.clientright.ru/upload_documents_to_crm.php'; // Берем общие параметры из первого документа $first_doc = $processed_documents[0]; $payload = json_encode([ 'documents' => $processed_documents, 'projectid' => $first_doc['projectid'], 'ticket_id' => $first_doc['ticket_id'], 'user_id' => 1 ], JSON_UNESCAPED_UNICODE); log_message('Payload: ' . substr($payload, 0, 500)); // Отправляем запрос $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $upload_url); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $payload); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 60); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json', 'Content-Length: ' . strlen($payload) ]); $response = curl_exec($ch); $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($response === false) { log_message('❌ CURL error: ' . curl_error($ch)); json_response([ 'success' => false, 'error' => 'Internal error: ' . curl_error($ch) ], 500); } log_message("Response HTTP code: {$http_code}"); log_message("Response: " . substr($response, 0, 500)); // Парсим ответ $result = json_decode($response, true); if (json_last_error() !== JSON_ERROR_NONE) { log_message('❌ Failed to parse response JSON: ' . json_last_error_msg()); json_response([ 'success' => false, 'error' => 'Invalid response from upload service' ], 500); } // Проверяем успешность if ($result && $result['success'] && isset($result['results'])) { $results_array = $result['results']; // Формируем ответ $processed_results = []; $errors = []; foreach ($results_array as $idx => $res) { if ($res['status'] === 'success') { $crm_result = $res['crm_result'] ?? []; $processed_results[] = [ 'document_id' => $crm_result['document_id'] ?? null, 'document_numeric_id' => $crm_result['document_numeric_id'] ?? null, 'attached_to' => isset($res['ticket_id']) && $res['ticket_id'] ? 'ticket' : 'project', 'attached_to_id' => $res['ticket_id'] ?? $res['projectid'] ?? null, 'file_name' => $res['file_name'] ?? null, 'file_type' => $res['description'] ?? null, 's3_bucket' => $crm_result['s3_bucket'] ?? null, 's3_key' => $crm_result['s3_key'] ?? null, 'file_size' => $crm_result['file_size'] ?? null, 'message' => $crm_result['message'] ?? null ]; log_message(" ✅ [{$idx}] {$res['file_name']} → {$crm_result['document_id']}"); } else { $error_msg = $res['crm_result']['message'] ?? 'Unknown error'; $errors[] = [ 'file_name' => $res['file_name'] ?? 'Unknown', 'error' => $error_msg ]; log_message(" ❌ [{$idx}] {$res['file_name']}: {$error_msg}"); } } log_message('✅ Success: ' . count($processed_results) . ' documents attached'); json_response([ 'success' => true, 'total_processed' => count($results_array), 'successful' => count($processed_results), 'failed' => count($errors), 'results' => $processed_results, 'errors' => !empty($errors) ? $errors : null ]); } else { log_message('❌ Upload failed: ' . ($result['error']['message'] ?? 'Unknown error')); json_response([ 'success' => false, 'error' => $result['error']['message'] ?? 'Upload failed' ], 500); }