Penyebab menu pencarian tidak muncul disebabkan oleh dua hal utama pada kode penyederhanaan sebelumnya: 1. Variabel $footer Belum Diinisialisasi (Undefined Variable): Saat bagian Villa dihapus, baris PHP yang bertugas memuat konfigurasi footer ($footer) dari file JSON tidak sengaja ikut terhapus. Hal ini memicu Fatal Error di PHP 8+ atau Warning yang menghentikan proses rendering halaman di tengah jalan. 2. Tirai Loading (Preloader) Tersangkut: Karena PHP mengalami error sebelum halaman selesai dimuat, kode JavaScript di bagian bawah tidak sempat dieksekusi. Akibatnya, elemen tirai hitam (#intro-curtain) terus menutupi layar dan menghalangi visual menu pencarian. Berikut adalah kode yang telah diperbaiki dengan mengembalikan inisialisasi $footer secara aman, serta menambahkan pengaman agar sistem tidak crash jika koneksi database di file config.php mengalami kendala: []]); exit; } $url = "https://api.duffel.com/places/suggestions?query=" . $query; $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_ENCODING, ''); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Accept: application/json", "Duffel-Version: v2", "Authorization: Bearer " . $apiKey ]); $ajaxResponse = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($httpCode === 200) { echo $ajaxResponse; } else { echo json_encode(["data" => []]); } exit; } // ========================================== // Memasukkan konfigurasi database untuk penanganan diskon $pdo = null; if (file_exists('config.php')) { include_once 'config.php'; } // ---------------------------------------------------------------------- // PROTEKSI PENGAMAN: MEMASTIKAN FUNGSI DISKON ADA (Mencegah Halaman Stuck) // ---------------------------------------------------------------------- if (!function_exists('get_active_flight_discounts')) { function get_active_flight_discounts($pdo) { if (!$pdo) { return []; } try { $stmt = $pdo->query("SELECT * FROM flight_discounts WHERE is_active = 1"); $discounts = $stmt->fetchAll(); $discount_map = []; foreach ($discounts as $disc) { $discount_map[$disc['airline_code']] = [ 'type' => $disc['discount_type'], 'value' => floatval($disc['discount_value']) ]; } return $discount_map; } catch (\PDOException $e) { error_log("Tabel flight_discounts belum siap atau bermasalah: " . $e->getMessage()); return []; } } } if (!function_exists('calculate_discounted_price')) { function calculate_discounted_price($original_price, $airline_code, $discount_map) { $applied_discount = 0; if (isset($discount_map[$airline_code])) { $rule = $discount_map[$airline_code]; } elseif (isset($discount_map['ALL'])) { $rule = $discount_map['ALL']; } else { return [ 'final_price' => $original_price, 'discount_amount' => 0, 'has_discount' => false ]; } if ($rule['type'] === 'percentage') { $applied_discount = $original_price * ($rule['value'] / 100); } else { $applied_discount = $rule['value']; } $final_price = max(0, $original_price - $applied_discount); return [ 'final_price' => $final_price, 'discount_amount' => $applied_discount, 'has_discount' => $applied_discount > 0 ]; } } // ---------------------------------------------------------------------- // LOAD / INISIALISASI KONFIGURASI HERO SLIDES (JSON) // ---------------------------------------------------------------------- $slides_file = 'slides_config.json'; $default_slides = [ ["image_url" => "https://images.unsplash.com/photo-1436491865332-7a61a109cc05?auto=format&fit=crop&w=1200&q=80"], ["image_url" => "https://images.unsplash.com/photo-1540555700478-4be289fbecef?auto=format&fit=crop&w=1200&q=80"], ["image_url" => "https://images.unsplash.com/photo-1507525428034-b723cf961d3e?auto=format&fit=crop&w=1200&q=80"], ["image_url" => "https://images.unsplash.com/photo-1476514525535-07fb3b4ae5f1?auto=format&fit=crop&w=1200&q=80"] ]; if (file_exists($slides_file)) { $slides = json_decode(file_get_contents($slides_file), true); if (!$slides) { $slides = $default_slides; } } else { $slides = $default_slides; } // ---------------------------------------------------------------------- // LOAD / INISIALISASI KONFIGURASI LOGO SITUS (JSON) // ---------------------------------------------------------------------- $site_config_file = 'site_config.json'; $default_site_config = [ "site_logo_url" => "", "site_title" => "Go Fly Travelia" ]; if (file_exists($site_config_file)) { $site_config = json_decode(file_get_contents($site_config_file), true); if (!$site_config) { $site_config = $default_site_config; } } else { $site_config = $default_site_config; } // ---------------------------------------------------------------------- // LOAD / SINKRONISASI KONFIGURASI FOOTER (JSON) // ---------------------------------------------------------------------- $footer_config_file = 'footer_config.json'; $default_footer_config = [ "bg_color" => "#090d16", "text_color" => "#94a3b8", "accent_color" => "#d4af37", "bg_video_url" => "", "address" => "Jl. Premium Luxury No. 88, Kuta, Bali", "phone" => "+62 812-3456-7890", "email" => "info@goflytravelia.com", "copyright" => "© 2026 Go Fly Travelia. All rights reserved.", "layout" => ["about", "links", "contact", "custom_html"], "custom_widgets" => [], "columns" => [ "about" => [ "title" => "Tentang Kami", "content" => "Go Fly Travelia adalah penyedia layanan perjalanan udara premium dengan kenyamanan kelas dunia." ], "links" => [ "title" => "Tautan Penting", "items" => [ ["label" => "Cari Penerbangan", "url" => "flights.php"], ["label" => "Tentang Kami", "url" => "about.php"], ["label" => "Kontak Kami", "url" => "contact.php"] ] ], "contact" => [ "title" => "Hubungi Kami" ], "custom_html" => [ "title" => "Aset Widget", "html" => "" ] ] ]; if (file_exists($footer_config_file)) { $footer = json_decode(file_get_contents($footer_config_file), true); if (!$footer) { $footer = $default_footer_config; } } else { $footer = $default_footer_config; } // ---------------------------------------------------------------------- // PERSYARATAN FUNGSI DAN PARAMETER PENCARIAN PENERBANGAN DUFFEL API // ---------------------------------------------------------------------- $journeyType = "return"; $origin = "CGK"; $origin_name = "Soekarno-Hatta International Airport (CGK)"; $destination = "SIN"; $destination_name = "Changi Airport (SIN)"; $departureDate = date('Y-m-d', strtotime('+30 days')); $returnDate = date('Y-m-d', strtotime('+37 days')); $adults = 1; $children = 0; $passengers = 1; $cabinClass = "economy"; $depTakeoffFrom = $_GET['dep_takeoff_from'] ?? "00:00"; $depTakeoffTo = $_GET['dep_takeoff_to'] ?? "23:59"; $depLandingFrom = $_GET['dep_landing_from'] ?? "00:00"; $depLandingTo = $_GET['dep_landing_to'] ?? "23:59"; $retTakeoffFrom = $_GET['ret_takeoff_from'] ?? "00:00"; $retTakeoffTo = $_GET['ret_takeoff_to'] ?? "23:59"; $retLandingFrom = $_GET['ret_landing_from'] ?? "00:00"; $retLandingTo = $_GET['ret_landing_to'] ?? "23:59"; $showResults = false; $offers = []; $httpStatusCode = 200; $responseJson = ""; $errorMessage = ""; if (isset($_GET['search'])) { $journeyType = $_GET['journey_type'] ?? 'one_way'; $origin = strtoupper(trim($_GET['origin'] ?? '')); $origin_name = trim($_GET['origin_name'] ?? ''); $destination = strtoupper(trim($_GET['destination'] ?? '')); $destination_name = trim($_GET['destination_name'] ?? ''); $departureDate = trim($_GET['departure_date'] ?? ''); $returnDate = trim($_GET['return_date'] ?? ''); $adults = (int)($_GET['adults'] ?? 1); $children = (int)($_GET['children'] ?? 0); if (isset($_GET['passengers']) && !isset($_GET['adults'])) { $passengers = (int)$_GET['passengers']; $adults = $passengers; $children = 0; } else { if ($adults < 1) $adults = 1; $passengers = $adults + $children; } $cabinClass = $_GET['cabin_class'] ?? 'economy'; if (!empty($origin) && !empty($destination) && !empty($departureDate)) { $showResults = true; $depSlice = [ "origin" => $origin, "destination" => $destination, "departure_date" => $departureDate ]; if ($depTakeoffFrom !== "00:00" || $depTakeoffTo !== "23:59") { $depSlice["departure_time"] = ["from" => $depTakeoffFrom, "to" => $depTakeoffTo]; } if ($depLandingFrom !== "00:00" || $depLandingTo !== "23:59") { $depSlice["arrival_time"] = ["from" => $depLandingFrom, "to" => $depLandingTo]; } $slices = [$depSlice]; if ($journeyType === 'return' && !empty($returnDate)) { $retSlice = [ "origin" => $destination, "destination" => $origin, "departure_date" => $returnDate ]; if ($retTakeoffFrom !== "00:00" || $retTakeoffTo !== "23:59") { $retSlice["departure_time"] = ["from" => $retTakeoffFrom, "to" => $retTakeoffTo]; } if ($retLandingFrom !== "00:00" || $retLandingTo !== "23:59") { $retSlice["arrival_time"] = ["from" => $retLandingFrom, "to" => $retLandingTo]; } $slices[] = $retSlice; } $passengersPayload = []; for ($i = 0; $i < $adults; $i++) { $passengersPayload[] = ["type" => "adult"]; } for ($i = 0; $i < $children; $i++) { $passengersPayload[] = ["type" => "child"]; } $payload = [ "data" => [ "slices" => $slices, "passengers" => $passengersPayload, "cabin_class" => $cabinClass ] ]; $jsonPayload = json_encode($payload); $url = "https://api.duffel.com/air/offer_requests?return_offers=true"; $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonPayload); curl_setopt($ch, CURLOPT_ENCODING, ''); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Content-Type: application/json", "Accept: application/json", "Duffel-Version: v2", "Authorization: Bearer " . $apiKey ]); $responseJson = curl_exec($ch); $httpStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); if (curl_errno($ch)) { $errorMessage = "Koneksi Error: " . curl_error($ch); } else { $response = json_decode($responseJson, true); $offers = $response['data']['offers'] ?? []; } curl_close($ch); } } $is_searched = $showResults; function formatDuration($isoDuration) { return trim(str_replace(['PT', 'H', 'M'], ['', 'j ', 'm'], $isoDuration)); } function convertToIdr($amount, $fromCurrency) { $fromCurrency = strtoupper($fromCurrency); if ($fromCurrency === 'IDR') return $amount; $fallbackRates = ['USD' => 16300, 'SGD' => 12100, 'EUR' => 17600, 'IDR' => 1]; if (!isset($_SESSION['exchange_rates'])) { $ctx = stream_context_create(['http' => ['timeout' => 2.5]]); $ratesJson = @file_get_contents("https://open.er-api.com/v6/latest/USD", false, $ctx); if ($ratesJson) { $ratesData = json_decode($ratesJson, true); if (isset($ratesData['rates'])) { $_SESSION['exchange_rates'] = $ratesData['rates']; } } } $rates = $_SESSION['exchange_rates'] ?? $fallbackRates; $idrRate = $rates['IDR'] ?? 16300; if ($fromCurrency === 'USD') { return $amount * $idrRate; } $fromRate = $rates[$fromCurrency] ?? null; if ($fromRate) { return ($amount / $fromRate) * $idrRate; } return $amount * ($fallbackRates[$fromCurrency] ?? 1); } ?> Pencarian Tiket Pesawat Premium - <?php echo htmlspecialchars($site_config['site_title']); ?>
Preparing flight search engine
$slide): ?>
$slide): ?>
Cari Tiket Pesawat
Journey type
Take-off
at any time
Landing
at any time
Take-off
at any time
Landing
at any time
= 400): ?>

Terjadi Kendala Pencarian:

$errorMessage

"; } else { $response = json_decode($responseJson, true); if (isset($response['errors'])) { foreach ($response['errors'] as $error) { echo "

" . htmlspecialchars($error['title']) . ": " . htmlspecialchars($error['message']) . "

"; } } } ?>
Hasil Pencarian

Penerbangan dari ke

| Tanggal Pergi: ' . date('d M Y', strtotime($returnDate)) . '' : ''; ?> | Penerbangan Ditemukan

Tidak ada jadwal penerbangan yang tersedia saat ini.

PROMO
Rp
Rp
Rp
harga total ( penumpang)
0): $firstSegment = $segments[0]; $lastSegment = $segments[$segmentCount - 1]; $depTime = isset($firstSegment['departing_at']) ? date('H:i', strtotime($firstSegment['departing_at'])) : '--:--'; $depDate = isset($firstSegment['departing_at']) ? date('d M Y', strtotime($firstSegment['departing_at'])) : ''; $depIata = $firstSegment['origin']['iata_code'] ?? '???'; $arrTime = isset($lastSegment['arriving_at']) ? date('H:i', strtotime($lastSegment['arriving_at'])) : '--:--'; $arrDate = isset($lastSegment['arriving_at']) ? date('d M Y', strtotime($lastSegment['arriving_at'])) : ''; $arrIata = $lastSegment['destination']['iata_code'] ?? '???'; $duration = formatDuration($slice['duration'] ?? ''); $transitStatus = ($segmentCount === 1) ? "Langsung" : ($segmentCount - 1) . " Transit"; $statusClass = ($segmentCount === 1) ? "status-direct" : "status-transit"; if ($sliceIndex === 1) { $firstSliceDepTime = $depTime; $firstSliceArrTime = $arrTime; $firstSliceDuration = $duration; $firstSliceDepDate = $depDate; $firstSliceDepIata = $depIata; $firstSliceArrIata = $arrIata; } elseif ($sliceIndex === 2) { $retSliceDepTime = $depTime; $retSliceArrTime = $arrTime; $retSliceDuration = $duration; $retSliceDepDate = $depDate; $retSliceDepIata = $depIata; $retSliceArrIata = $arrIata; } ?>
0): ?>
Bisa reschedule & refund
$firstSliceDepIata, 'destination' => $firstSliceArrIata, 'dep_date' => $firstSliceDepDate, 'carrier_name' => $airlineName, 'carrier_logo' => $airlineLogoUrl, 'dep_time' => $firstSliceDepTime, 'arr_time' => $firstSliceArrTime, 'duration' => $firstSliceDuration, 'price' => $has_discount ? $finalIdr : $originalIdr, 'currency' => 'IDR', 'cabin' => $cabinClass, 'passengers' => $passengers, 'adults' => $adults, 'children' => $children, 'offer_id' => $offerId ]; if (!empty($retSliceDepIata)) { $bookingParams['ret_origin'] = $retSliceDepIata; $bookingParams['ret_destination'] = $retSliceArrIata; $bookingParams['ret_dep_date'] = $retSliceDepDate; $bookingParams['ret_dep_time'] = $retSliceDepTime; $bookingParams['ret_arr_time'] = $retSliceArrTime; $bookingParams['ret_duration'] = $retSliceDuration; } $bookingUrl = "fare_options.php?" . http_build_query($bookingParams); ?>
Logo <?php echo htmlspecialchars($site_config['site_title']); ?> GO FLY TRAVELIA

Komentar