'Missing survey_id'], 400); } $db = getDB(); // Verify access if (!isAdmin()) { $stmt = $db->prepare("SELECT user_id FROM surveys WHERE id = ?"); $stmt->execute([$surveyId]); $s = $stmt->fetch(); if (!$s || $s['user_id'] != $_SESSION['user_id']) { jsonResponse(['error' => 'ไม่มีสิทธิ์เข้าถึงแบบสอบถามนี้'], 403); } } // Check uploaded file if (!isset($_FILES['csv_file']) || $_FILES['csv_file']['error'] !== UPLOAD_ERR_OK) { jsonResponse(['error' => 'กรุณาอัปโหลดไฟล์ CSV คำตอบจาก Google Forms'], 400); } $filePath = $_FILES['csv_file']['tmp_name']; // Read CSV $handle = fopen($filePath, 'r'); if (!$handle) { jsonResponse(['error' => 'ไม่สามารถเปิดไฟล์ CSV ได้'], 500); } // Check UTF-8 BOM or UTF-16 $bom = fread($handle, 3); if ($bom !== "\xEF\xBB\xBF") { rewind($handle); } // Get Headers (Row 1) $headers = fgetcsv($handle, 0, ","); if (!$headers) { fclose($handle); jsonResponse(['error' => 'ไฟล์ CSV ไม่มีข้อมูลหรือรูปแบบไม่ถูกต้อง'], 400); } // Clean headers $cleanHeaders = array_map(function($h) { return trim(preg_replace('/\s+/', ' ', $h)); }, $headers); // Fetch all questions for this survey $stmt = $db->prepare(" SELECT q.id, q.question_text, q.question_type FROM survey_questions q JOIN survey_sections s ON q.section_id = s.id WHERE s.survey_id = ? ORDER BY s.section_number, q.order_num "); $stmt->execute([$surveyId]); $questions = $stmt->fetchAll(); if (empty($questions)) { fclose($handle); jsonResponse(['error' => 'ไม่พบข้อคำถามในแบบสอบถามนี้'], 400); } // Map CSV Column Index -> question_id $colToQuestionMap = []; function normalizeText($str) { $str = mb_strtolower($str, 'UTF-8'); // Remove leading numbers or prefix like "1. ", "ข้อ 1. " $str = preg_replace('/^[\d๑-๙]+[\.\)\s\-:\x{00A0}]*/u', '', $str); return trim($str); } foreach ($cleanHeaders as $colIdx => $headerText) { if (empty($headerText) || strtolower($headerText) === 'timestamp' || strtolower($headerText) === 'ประทับเวลา') { continue; } $normHeader = normalizeText($headerText); // Try exact or normalized matching against survey questions foreach ($questions as $q) { $normQText = normalizeText($q['question_text']); if ($normHeader === $normQText || strpos($normHeader, $normQText) !== false || strpos($normQText, $normHeader) !== false) { $colToQuestionMap[$colIdx] = $q['id']; break; } } } // Fallback: If column mapping count is low, map columns sequentially to questions if (count($colToQuestionMap) === 0) { $qIdx = 0; foreach ($cleanHeaders as $colIdx => $headerText) { if (strtolower($headerText) === 'timestamp' || strtolower($headerText) === 'ประทับเวลา') continue; if (isset($questions[$qIdx])) { $colToQuestionMap[$colIdx] = $questions[$qIdx]['id']; $qIdx++; } } } // Process Rows $importedCount = 0; $db->beginTransaction(); try { while (($row = fgetcsv($handle, 0, ",")) !== false) { if (empty(array_filter($row))) continue; // Skip empty lines // Extract timestamp or use now $submittedAt = date('Y-m-d H:i:s'); if (!empty($row[0])) { $ts = strtotime($row[0]); if ($ts !== false) { $submittedAt = date('Y-m-d H:i:s', $ts); } } // Insert into survey_responses $stmtResp = $db->prepare("INSERT INTO survey_responses (survey_id, respondent_info, submitted_at) VALUES (?, ?, ?)"); $stmtResp->execute([ $surveyId, json_encode(['imported' => true, 'source' => 'google_forms_csv'], JSON_UNESCAPED_UNICODE), $submittedAt ]); $responseId = $db->lastInsertId(); // Insert answers foreach ($colToQuestionMap as $colIdx => $qId) { $val = isset($row[$colIdx]) ? trim($row[$colIdx]) : ''; if ($val !== '') { $stmtAns = $db->prepare("INSERT INTO response_answers (response_id, question_id, answer_value) VALUES (?, ?, ?)"); $stmtAns->execute([$responseId, $qId, $val]); } } $importedCount++; } $db->commit(); fclose($handle); jsonResponse([ 'success' => true, 'message' => "นำเข้าข้อมูลคำตอบสำเร็จจำนวน $importedCount รายการ", 'imported_count' => $importedCount, 'mapped_questions' => count($colToQuestionMap) ]); } catch (Exception $e) { $db->rollBack(); fclose($handle); jsonResponse(['error' => 'เกิดข้อผิดพลาดในการบันทึกคำตอบ: ' . $e->getMessage()], 500); }