'Invalid action'], 400); } function importFromUrl() { $input = json_decode(file_get_contents('php://input'), true); $url = trim($input['url'] ?? ''); $projectId = !empty($input['project_id']) ? (int)$input['project_id'] : null; if (empty($url)) { jsonResponse(['error' => 'กรุณาระบุ URL หรือ Link ของ Google Form'], 400); } // Extract Form ID or viewform URL if (!preg_match('/docs\.google\.com\/forms\/d\/e?\/([^\/]+)/i', $url, $matches) && !preg_match('/docs\.google\.com\/forms\/d\/([^\/]+)/i', $url, $matches)) { jsonResponse(['error' => 'รูปแบบ URL ของ Google Form ไม่ถูกต้อง'], 400); } // Attempt to fetch the public viewform HTML $fetchUrl = $url; if (strpos($fetchUrl, '/viewform') === false && strpos($fetchUrl, '/edit') === false) { $fetchUrl = rtrim($fetchUrl, '/') . '/viewform'; } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $fetchUrl); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'); curl_setopt($ch, CURLOPT_TIMEOUT, 15); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); $html = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode !== 200 || empty($html)) { jsonResponse(['error' => 'ไม่สามารถดึงข้อมูลจาก Google Form URL นี้ได้ โปรดตรวจสอบว่าเปิดเป็นสาธารณะ (Public) หรือไม่'], 400); } // Parse FB_PUBLIC_LOAD_DATA_ if (!preg_match('/FB_PUBLIC_LOAD_DATA_\s*=\s*(.+?);<\/script>/s', $html, $dataMatches)) { jsonResponse(['error' => 'ไม่พบโครงสร้างแบบสอบถามใน Google Form นี้'], 400); } $formData = json_decode($dataMatches[1], true); if (!$formData || !isset($formData[1])) { jsonResponse(['error' => 'โครงสร้างข้อมูล Google Form ไม่ถูกต้อง'], 400); } $parsedSurvey = parseGoogleFormData($formData); $surveyId = saveParsedSurveyToDB($parsedSurvey, $projectId); jsonResponse([ 'success' => true, 'message' => 'นำเข้าโครงสร้างแบบสอบถามจาก Google Form เรียบร้อยแล้ว', 'survey_id' => $surveyId, 'title' => $parsedSurvey['title'] ]); } function importFromJson() { $input = json_decode(file_get_contents('php://input'), true); $projectId = !empty($input['project_id']) ? (int)$input['project_id'] : null; $surveyData = $input['survey_data'] ?? null; if (!$surveyData || empty($surveyData['title'])) { jsonResponse(['error' => 'ข้อมูล JSON ไม่ถูกต้อง หรือขาดชื่อแบบสอบถาม'], 400); } $surveyId = saveParsedSurveyToDB($surveyData, $projectId); jsonResponse([ 'success' => true, 'message' => 'นำเข้าแบบสอบถามเรียบร้อยแล้ว', 'survey_id' => $surveyId, 'title' => $surveyData['title'] ]); } /** * Helper: Parse Google Forms FB_PUBLIC_LOAD_DATA_ structure */ function parseGoogleFormData($data) { $title = $data[1][8] ?? $data[1][1] ?? $data[3] ?? 'แบบสอบถามจาก Google Forms'; $description = $data[1][0] ?? ''; $rawItems = $data[1][1] ?? []; $sections = []; $currentSection = [ 'section_number' => 1, 'title' => 'ส่วนที่ 1 ข้อมูลทั่วไป', 'description' => '', 'category' => 'general', 'questions' => [] ]; $sectionCount = 1; foreach ($rawItems as $item) { if (!is_array($item)) continue; $qTitle = $item[1] ?? ''; $qDesc = $item[2] ?? ''; $qTypeNum = $item[3] ?? 0; $qDetails = $item[4][0] ?? []; if (empty($qTitle) && $qTypeNum != 8) continue; // Skip empty items except section breaks // Type 8 = Section Break in Google Forms if ($qTypeNum == 8) { if (!empty($currentSection['questions'])) { $sections[] = $currentSection; } $sectionCount++; $currentSection = [ 'section_number' => $sectionCount, 'title' => $qTitle ?: ('ส่วนที่ ' . $sectionCount), 'description' => $qDesc, 'category' => 'rating', 'questions' => [] ]; continue; } $qType = 'radio'; $options = []; $scaleMin = 1; $scaleMax = 5; // Map Google Forms Item Type numbers: // 0: Short Text, 1: Paragraph // 2: Radio (Multiple Choice), 3: Dropdown, 4: Checkbox // 5: Linear Scale (1-5) // 7: Grid / Matrix switch ($qTypeNum) { case 0: case 1: $qType = 'text'; break; case 2: $qType = 'radio'; if (isset($qDetails[1]) && is_array($qDetails[1])) { foreach ($qDetails[1] as $opt) { if (isset($opt[0])) $options[] = $opt[0]; } } break; case 3: $qType = 'dropdown'; if (isset($qDetails[1]) && is_array($qDetails[1])) { foreach ($qDetails[1] as $opt) { if (isset($opt[0])) $options[] = $opt[0]; } } break; case 4: $qType = 'checkbox'; if (isset($qDetails[1]) && is_array($qDetails[1])) { foreach ($qDetails[1] as $opt) { if (isset($opt[0])) $options[] = $opt[0]; } } break; case 5: $qType = 'radio'; // Rating Scale $scaleMin = 1; $scaleMax = 5; break; default: $qType = 'text'; break; } $isRequired = isset($qDetails[2]) && $qDetails[2] == 1 ? 1 : 0; $questionObj = [ 'question_text' => $qTitle, 'question_type' => $qType, 'is_required' => $isRequired, 'description' => $qDesc, 'options' => count($options) > 0 ? $options : null, 'scale_min' => $scaleMin, 'scale_max' => $scaleMax ]; $currentSection['questions'][] = $questionObj; } if (!empty($currentSection['questions'])) { $sections[] = $currentSection; } if (empty($sections)) { $sections[] = [ 'section_number' => 1, 'title' => 'ส่วนที่ 1 ข้อมูลและข้อคำถาม', 'description' => 'นำเข้าจาก Google Forms', 'category' => 'general', 'questions' => [] ]; } return [ 'title' => $title, 'description' => $description ?: 'แบบสอบถามที่นำเข้าจาก Google Forms', 'sections' => $sections ]; } /** * Save parsed survey structure into database */ function saveParsedSurveyToDB($parsedSurvey, $projectId = null) { $db = getDB(); $uniqueLink = bin2hex(random_bytes(16)); $db->beginTransaction(); try { $stmt = $db->prepare("INSERT INTO surveys (user_id, project_id, title, description, unique_link, status) VALUES (?, ?, ?, ?, ?, 'active')"); $stmt->execute([ $_SESSION['user_id'], $projectId, $parsedSurvey['title'], $parsedSurvey['description'] ?? '', $uniqueLink ]); $surveyId = $db->lastInsertId(); $sections = $parsedSurvey['sections'] ?? []; $secNum = 1; foreach ($sections as $sec) { $stmt = $db->prepare("INSERT INTO survey_sections (survey_id, section_number, title, description, category) VALUES (?, ?, ?, ?, ?)"); $stmt->execute([ $surveyId, $sec['section_number'] ?? $secNum, $sec['title'] ?? ('ส่วนที่ ' . $secNum), $sec['description'] ?? '', $sec['category'] ?? 'rating' ]); $sectionId = $db->lastInsertId(); $orderNum = 1; foreach ($sec['questions'] as $q) { $optionsJson = !empty($q['options']) ? json_encode($q['options'], JSON_UNESCAPED_UNICODE) : null; $stmtQ = $db->prepare("INSERT INTO survey_questions (section_id, question_text, question_type, is_required, order_num, options, scale_min, scale_max, description) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"); $stmtQ->execute([ $sectionId, $q['question_text'], $q['question_type'] ?? 'radio', $q['is_required'] ?? 1, $orderNum++, $optionsJson, $q['scale_min'] ?? 1, $q['scale_max'] ?? 5, $q['description'] ?? null ]); } $secNum++; } $db->commit(); return $surveyId; } catch (Exception $e) { $db->rollBack(); jsonResponse(['error' => 'เกิดข้อผิดพลาดในการบันทึกแบบสอบถาม: ' . $e->getMessage()], 500); } }