prepare("SELECT id, title, description, scheduled_at, presenter FROM webinars WHERE id = ?"); $stmt->execute([$id]); return $stmt->fetch(PDO::FETCH_ASSOC); } catch (PDOException $e) { error_log("Database error fetching webinar ID $id: " . $e->getMessage()); return null; } } // --- AJAX FORM SUBMISSION (POST REQUEST) --- if ($_SERVER["REQUEST_METHOD"] == "POST") { header('Content-Type: application/json'); $response = []; // --- DATA CAPTURE --- $webinar_id = filter_input(INPUT_POST, 'webinar_id', FILTER_VALIDATE_INT) ?: filter_input(INPUT_GET, 'webinar_id', FILTER_VALIDATE_INT) ?: 1; $webinar = get_webinar_details($webinar_id); $email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL); $first_name = filter_input(INPUT_POST, 'first_name', FILTER_SANITIZE_STRING); $last_name = filter_input(INPUT_POST, 'last_name', FILTER_SANITIZE_STRING); $company = filter_input(INPUT_POST, 'company', FILTER_SANITIZE_STRING); $how_did_you_hear = filter_input(INPUT_POST, 'how_did_you_hear', FILTER_SANITIZE_STRING); $password = filter_input(INPUT_POST, 'password', FILTER_UNSAFE_RAW); $confirm_password = filter_input(INPUT_POST, 'confirm_password', FILTER_UNSAFE_RAW); $timezone = filter_input(INPUT_POST, 'timezone', FILTER_SANITIZE_STRING); // Tracking data $utm_source = filter_input(INPUT_POST, 'utm_source', FILTER_SANITIZE_STRING); $utm_medium = filter_input(INPUT_POST, 'utm_medium', FILTER_SANITIZE_STRING); $utm_campaign = filter_input(INPUT_POST, 'utm_campaign', FILTER_SANITIZE_STRING); $utm_term = filter_input(INPUT_POST, 'utm_term', FILTER_SANITIZE_STRING); $utm_content = filter_input(INPUT_POST, 'utm_content', FILTER_SANITIZE_STRING); $referrer = filter_input(INPUT_POST, 'referrer', FILTER_SANITIZE_STRING); $gclid = filter_input(INPUT_POST, 'gclid', FILTER_SANITIZE_STRING); $fbclid = filter_input(INPUT_POST, 'fbclid', FILTER_SANITIZE_STRING); if (!$webinar) { $response = ['success' => false, 'error' => 'Webinar not found. Tried to find webinar with ID: ' . $webinar_id]; } elseif (!$first_name || !$last_name || !$email) { $response = ['success' => false, 'error' => 'Please fill out all required fields.']; } elseif ($password !== $confirm_password) { $response = ['success' => false, 'error' => 'Passwords do not match.']; } else { try { $stmt = db()->prepare("SELECT id FROM attendees WHERE webinar_id = ? AND email = ?"); $stmt->execute([$webinar_id, $email]); if ($stmt->fetch()) { $response = ['success' => false, 'error' => 'You are already registered for this webinar.']; } else { $password_hash = password_hash($password, PASSWORD_DEFAULT); $sql = "INSERT INTO attendees (webinar_id, first_name, last_name, email, company, how_did_you_hear, password, timezone, utm_source, utm_medium, utm_campaign, utm_term, utm_content, referrer, gclid, fbclid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; $stmt = db()->prepare($sql); $stmt->execute([$webinar_id, $first_name, $last_name, $email, $company, $how_did_you_hear, $password_hash, $timezone, $utm_source, $utm_medium, $utm_campaign, $utm_term, $utm_content, $referrer, $gclid, $fbclid]); $webinar_date_obj = new DateTime($webinar['scheduled_at']); $subject = "Confirmation: You're Registered for " . $webinar['title']; $body_html = "
Thanks for registering for our webinar: {$webinar['title']}.
It will take place on " . $webinar_date_obj->format('l, F j, Y \a\t g:i A T') . ".
You can now log in to your dashboard to see the details.
"; MailService::sendMail($email, $subject, $body_html); // --- PREPARE SUCCESS RESPONSE --- $webinar_date = new DateTime($webinar['scheduled_at'], new DateTimeZone('UTC')); $start_time_utc = $webinar_date->format('Ymd H is Z'); $webinar_date->add(new DateInterval('PT1H')); // Assume 1 hour duration $end_time_utc = $webinar_date->format('Ymd H is Z'); $google_link = 'https://www.google.com/calendar/render?action=TEMPLATE&text=' . urlencode($webinar['title']) . '&dates=' . $start_time_utc . '/' . $end_time_utc . '&details=' . urlencode($webinar['description']) . '&ctz=UTC'; $ics_content = implode("\r\n", [ 'BEGIN:VCALENDAR', 'VERSION:2.0', 'BEGIN:VEVENT', 'URL:' . 'http://' . $_SERVER['HTTP_HOST'], 'DTSTART:' . $start_time_utc, 'DTEND:' . $end_time_utc, 'SUMMARY:' . $webinar['title'], 'DESCRIPTION:' . $webinar['description'], 'END:VEVENT', 'END:VCALENDAR' ]); $outlook_link = 'data:text/calendar;charset=utf-8,' . rawurlencode($ics_content); $response = [ 'success' => true, 'webinar_title' => $webinar['title'], 'google_link' => $google_link, 'outlook_link' => $outlook_link ]; } } catch (Exception $e) { error_log("Registration error: " . $e->getMessage()); $response = ['success' => false, 'error' => 'An unexpected error occurred. Please try again.']; } } echo json_encode($response); exit; } // --- RENDER PAGE (Initial GET Request) --- $webinar_id = filter_input(INPUT_GET, 'webinar_id', FILTER_VALIDATE_INT) ?: 1; $webinar = get_webinar_details($webinar_id); if (!$webinar) { http_response_code(404); echo "Webinar not found."; exit; } ?>= htmlspecialchars($webinar['description']) ?>
Philip Daineka
Alex Rubanau
Alexey Vertel