setClientId($client_id); $client->setClientSecret($client_secret); $client->refreshToken($refresh_token); $service = new Google\Service\Calendar($client); // Fetch known internal event IDs and creators $stmt = $pdo_sys->query("SELECT google_event_id, meet_link, created_by FROM meet_requests WHERE google_event_id IS NOT NULL"); $internal_events = []; $internal_links = []; $internal_creators = []; while ($row = $stmt->fetch()) { $internal_events[] = $row['google_event_id']; $internal_links[$row['google_event_id']] = $row['meet_link']; $internal_creators[$row['google_event_id']] = $row['created_by']; } $optParams = array( 'singleEvents' => true, 'orderBy' => 'startTime' ); if ($start) $optParams['timeMin'] = date('c', strtotime($start)); if ($end) $optParams['timeMax'] = date('c', strtotime($end)); $results = $service->events->listEvents('primary', $optParams); foreach ($results->getItems() as $event) { $eventId = $event->getId(); // Determine if internal or external $is_internal = in_array($eventId, $internal_events); // Format start and end $eventStart = $event->start->dateTime; if (empty($eventStart)) $eventStart = $event->start->date; $eventEnd = $event->end->dateTime; if (empty($eventEnd)) $eventEnd = $event->end->date; // Meet link $meet_link = ''; if ($is_internal && isset($internal_links[$eventId])) { $meet_link = $internal_links[$eventId]; } else { if ($event->getConferenceData()) { $entryPoints = $event->getConferenceData()->getEntryPoints(); if ($entryPoints) { foreach ($entryPoints as $ep) { if ($ep->getEntryPointType() === 'video') { $meet_link = $ep->getUri(); break; } } } } else if ($event->getHangoutLink()) { $meet_link = $event->getHangoutLink(); } } $events[] = [ 'id' => $eventId, 'title' => $event->getSummary() ?: '(ไม่มีชื่อหัวข้อ)', 'start' => $eventStart, 'end' => $eventEnd, 'color' => $is_internal ? '#0d6efd' : '#fd7e14', // Blue for internal, Orange for external 'extendedProps' => [ 'source' => $is_internal ? 'internal' : 'external', 'meet_link' => $meet_link, 'creator' => ($is_internal && isset($internal_creators[$eventId])) ? $internal_creators[$eventId] : $event->creator->email ] ]; } // Fetch Thai Public Holidays from Thailand Formats API try { $year = $start ? date('Y', strtotime($start)) : date('Y'); $apiUrl = "https://thailandformats.com/api/v1/holidays/" . $year; // Set timeout for file_get_contents to prevent hanging $ctx = stream_context_create(array('http' => array('timeout' => 5))); $holidayJson = @file_get_contents($apiUrl, false, $ctx); if ($holidayJson) { $holidayData = json_decode($holidayJson, true); if (isset($holidayData['holidays'])) { $thai_holidays = [ 'new-years-day' => ['title' => 'วันขึ้นปีใหม่', 'details' => 'เฉลิมฉลองวันเริ่มต้นปีใหม่'], 'special-public-holiday' => ['title' => 'วันหยุดพิเศษ', 'details' => 'วันหยุดพิเศษที่ประกาศเพิ่มเติมโดยคณะรัฐมนตรี'], 'makha-bucha-day' => ['title' => 'วันมาฆบูชา', 'details' => 'วันสำคัญทางพระพุทธศาสนา รำลึกถึงพระพุทธโอวาทปาติโมกข์'], 'substitution-for-makha-bucha-day' => ['title' => 'วันหยุดชดเชยวันมาฆบูชา', 'details' => 'วันหยุดชดเชยวันมาฆบูชา'], 'chakri-memorial-day' => ['title' => 'วันจักรี', 'details' => 'รำลึกถึงพระบาทสมเด็จพระพุทธยอดฟ้าจุฬาโลกมหาราช และวันที่ระลึกมหาจักรีบรมราชวงศ์'], 'substitution-for-chakri-memorial-day' => ['title' => 'วันหยุดชดเชยวันจักรี', 'details' => 'วันหยุดชดเชยวันจักรี'], 'songkran-festival' => ['title' => 'วันสงกรานต์', 'details' => 'ประเพณีวันขึ้นปีใหม่ไทย'], 'national-labour-day' => ['title' => 'วันแรงงานแห่งชาติ', 'details' => 'วันแรงงานแห่งชาติ'], 'substitution-for-national-labour-day' => ['title' => 'วันหยุดชดเชยวันแรงงานแห่งชาติ', 'details' => 'วันหยุดชดเชยวันแรงงานแห่งชาติ'], 'coronation-day' => ['title' => 'วันฉัตรมงคล', 'details' => 'รำลึกถึงพระราชพิธีบรมราชาภิเษก พระบาทสมเด็จพระวชิรเกล้าเจ้าอยู่หัว'], 'substitution-for-coronation-day' => ['title' => 'วันหยุดชดเชยวันฉัตรมงคล', 'details' => 'วันหยุดชดเชยวันฉัตรมงคล'], 'visakha-bucha-day' => ['title' => 'วันวิสาขบูชา', 'details' => 'วันสำคัญทางพระพุทธศาสนา ประสูติ ตรัสรู้ และปรินิพพาน'], 'substitution-for-visakha-bucha-day' => ['title' => 'วันหยุดชดเชยวันวิสาขบูชา', 'details' => 'วันหยุดชดเชยวันวิสาขบูชา'], 'hm-queen-suthidas-birthday' => ['title' => 'วันเฉลิมฯ สมเด็จพระนางเจ้าสุทิดาฯ', 'details' => 'วันเฉลิมพระชนมพรรษา สมเด็จพระนางเจ้าสุทิดา พัชรสุธาพิมลลักษณ พระบรมราชินี'], 'substitution-for-hm-queen-suthidas-birthday' => ['title' => 'วันหยุดชดเชยวันเฉลิมฯ พระบรมราชินี', 'details' => 'วันหยุดชดเชยวันเฉลิมพระชนมพรรษา สมเด็จพระนางเจ้าสุทิดาฯ พระบรมราชินี'], 'asanha-bucha-day' => ['title' => 'วันอาสาฬหบูชา', 'details' => 'วันสำคัญทางพระพุทธศาสนา รำลึกถึงการแสดงปฐมเทศนา'], 'buddhist-lent-day' => ['title' => 'วันเข้าพรรษา', 'details' => 'วันเริ่มต้นเทศกาลเข้าพรรษา'], 'substitution-for-buddhist-lent-day' => ['title' => 'วันหยุดชดเชยวันเข้าพรรษา', 'details' => 'วันหยุดชดเชยวันเข้าพรรษา'], 'hm-king-maha-vajiralongkorns-birthday' => ['title' => 'วันเฉลิมฯ รัชกาลที่ 10', 'details' => 'วันเฉลิมพระชนมพรรษา พระบาทสมเด็จพระวชิรเกล้าเจ้าอยู่หัว รัชกาลที่ 10'], 'substitution-for-hm-king-maha-vajiralongkorns-birthday' => ['title' => 'วันหยุดชดเชยวันเฉลิมฯ รัชกาลที่ 10', 'details' => 'วันหยุดชดเชยวันเฉลิมพระชนมพรรษา พระบาทสมเด็จพระวชิรเกล้าเจ้าอยู่หัว'], 'hm-queen-sirikit-the-queen-mothers-birthday-mothers-day' => ['title' => 'วันแม่แห่งชาติ', 'details' => 'วันเฉลิมพระชนมพรรษา สมเด็จพระนางเจ้าสิริกิติ์ พระบรมราชินีนาถ พระบรมราชชนนีพันปีหลวง และวันแม่แห่งชาติ'], 'substitution-for-hm-queen-sirikit-the-queen-mothers-birthday-mothers-day' => ['title' => 'วันหยุดชดเชยวันแม่แห่งชาติ', 'details' => 'วันหยุดชดเชยวันแม่แห่งชาติ'], 'hm-king-bhumibol-adulyadej-the-great-memorial-day' => ['title' => 'วันนวมินทรมหาราช', 'details' => 'วันคล้ายวันสวรรคต พระบาทสมเด็จพระบรมชนกาธิเบศร มหาภูมิพลอดุลยเดชมหาราช บรมนาถบพิตร รัชกาลที่ 9'], 'substitution-for-hm-king-bhumibol-adulyadej-the-great-memorial-day' => ['title' => 'วันหยุดชดเชยวันนวมินทรมหาราช', 'details' => 'วันหยุดชดเชยวันนวมินทรมหาราช'], 'chulalongkorn-memorial-day' => ['title' => 'วันปิยมหาราช', 'details' => 'วันคล้ายวันสวรรคต พระบาทสมเด็จพระจุลจอมเกล้าเจ้าอยู่หัว รัชกาลที่ 5'], 'substitution-for-chulalongkorn-memorial-day' => ['title' => 'วันหยุดชดเชยวันปิยมหาราช', 'details' => 'วันหยุดชดเชยวันปิยมหาราช'], 'hm-king-bhumibol-adulyadejs-birthday-national-day-fathers-day' => ['title' => 'วันพ่อแห่งชาติ', 'details' => 'วันคล้ายวันพระบรมราชสมภพ พระบาทสมเด็จพระบรมชนกาธิเบศร มหาภูมิพลอดุลยเดชมหาราช บรมนาถบพิตร วันชาติ และวันพ่อแห่งชาติ'], 'substitution-for-hm-king-bhumibol-adulyadejs-birthday' => ['title' => 'วันหยุดชดเชยวันพ่อแห่งชาติ', 'details' => 'วันหยุดชดเชยวันพ่อแห่งชาติ'], 'constitution-day' => ['title' => 'วันรัฐธรรมนูญ', 'details' => 'ระลึกถึงการพระราชทานรัฐธรรมนูญแห่งราชอาณาจักรไทย'], 'substitution-for-constitution-day' => ['title' => 'วันหยุดชดเชยวันรัฐธรรมนูญ', 'details' => 'วันหยุดชดเชยวันรัฐธรรมนูญ'], 'new-years-eve' => ['title' => 'วันสิ้นปี', 'details' => 'วันสุดท้ายของปี'], 'substitution-for-new-years-eve' => ['title' => 'วันหยุดชดเชยวันสิ้นปี', 'details' => 'วันหยุดชดเชยวันสิ้นปี'] ]; foreach ($holidayData['holidays'] as $h) { $titleTh = isset($thai_holidays[$h['slug']]) ? $thai_holidays[$h['slug']]['title'] : $h['title']; $detailsTh = isset($thai_holidays[$h['slug']]) ? $thai_holidays[$h['slug']]['details'] : $h['details']; // FullCalendar requires end date to be exclusive for all-day block events $endDate = date('Y-m-d', strtotime($h['end_date'] . ' +1 day')); $events[] = [ 'id' => 'hol_' . $h['slug'], 'title' => $titleTh, 'start' => $h['start_date'], 'end' => $endDate, 'color' => '#dc3545', 'display' => 'block', 'allDay' => true, 'extendedProps' => [ 'source' => 'holiday', 'creator' => 'ประกาศวันหยุดราชการ', 'meet_link' => '', 'details' => $detailsTh ] ]; } } } } catch (Exception $e) { error_log("Thailand Formats API Fetch Error: " . $e->getMessage()); } $api_success = true; } catch (Exception $e) { error_log("Google API Calendar Fetch Error: " . $e->getMessage()); $api_success = false; } } // Fallback to local DB if API fails or not connected if (!$api_success) { try { $sql = "SELECT * FROM meet_requests"; if ($start && $end) { $sql .= " WHERE meet_date BETWEEN :start AND :end"; $stmt = $pdo_sys->prepare($sql); $stmt->execute(['start' => date('Y-m-d', strtotime($start)), 'end' => date('Y-m-d', strtotime($end))]); } else { $stmt = $pdo_sys->query($sql); } while ($row = $stmt->fetch()) { $events[] = [ 'id' => $row['id'], 'title' => $row['topic'], 'start' => $row['meet_date'] . 'T' . $row['start_time'], 'end' => $row['meet_date'] . 'T' . $row['end_time'], 'color' => '#0d6efd', 'extendedProps' => [ 'source' => 'internal', 'meet_link' => $row['meet_link'], 'creator' => $row['created_by'] ] ]; } } catch (PDOException $e) { // error } } echo json_encode($events); ?>