39074-vm/register.php
Flatlogic Bot 7e5d56a6cf 3
2026-03-10 06:04:58 +00:00

296 lines
13 KiB
PHP

<?php
session_start();
require_once 'db/config.php';
require_once 'mail/MailService.php';
header('Content-Type: application/json');
function normalize_email_address($email) {
return strtolower(trim((string) $email));
}
function has_valid_email_dns($domain) {
if ($domain === '') {
return false;
}
return checkdnsrr($domain, 'MX') || checkdnsrr($domain, 'A') || checkdnsrr($domain, 'AAAA');
}
function is_disposable_email_domain($domain) {
static $blocked_domains = [
'10minutemail.com',
'dispostable.com',
'emailondeck.com',
'fakeinbox.com',
'guerrillamail.com',
'maildrop.cc',
'mailinator.com',
'mailnesia.com',
'mintemail.com',
'sharklasers.com',
'tempmail.com',
'temp-mail.org',
'trashmail.com',
'yopmail.com',
'example.com',
'example.net',
'example.org',
];
return in_array($domain, $blocked_domains, true);
}
function validate_registration_email($email) {
$email = normalize_email_address($email);
if ($email === '' || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
return 'Please enter a valid email address.';
}
if (strlen($email) > 190) {
return 'Please enter a shorter email address.';
}
$parts = explode('@', $email);
if (count($parts) !== 2) {
return 'Please enter a valid email address.';
}
[$local, $domain] = $parts;
if ($local === '' || $domain === '') {
return 'Please enter a valid email address.';
}
if (is_disposable_email_domain($domain)) {
return 'Please use your real email address. Temporary or disposable inboxes are not allowed.';
}
if (!has_valid_email_dns($domain)) {
return 'Please use an email with a real mail domain.';
}
return null;
}
// --- Helper function to fetch webinar details ---
function get_webinar_details($id) {
if (empty($id)) return null;
try {
$stmt = db()->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;
}
}
// --- Only allow POST requests ---
if ($_SERVER["REQUEST_METHOD"] !== "POST") {
echo json_encode(['success' => false, 'error' => 'Invalid request method.']);
exit;
}
$webinar_id = filter_input(INPUT_POST, 'webinar_id', FILTER_VALIDATE_INT) ?: 1;
$webinar = get_webinar_details($webinar_id);
if (!$webinar) {
http_response_code(404);
echo json_encode(['success' => false, 'error' => 'Webinar not found.']);
exit;
}
// --- DATA CAPTURE ---
$email_input = (string) filter_input(INPUT_POST, 'email', FILTER_UNSAFE_RAW);
$email = normalize_email_address($email_input);
$email_error = validate_registration_email($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 = trim((string) filter_input(INPUT_POST, 'how_did_you_hear', FILTER_UNSAFE_RAW));
$timezone = filter_input(INPUT_POST, 'timezone', FILTER_SANITIZE_STRING);
$allowed_sources = [
'Social Media',
'LinkedIn',
'Reddit',
'Threads',
'Advertisement',
'ChatGPT',
'Flatlogic Community Discord',
'Other',
];
// --- VALIDATION ---
if (!$first_name || !$last_name || $email === '' || $how_did_you_hear === '') {
echo json_encode(['success' => false, 'error' => 'Please fill out all required fields.']);
exit;
}
if ($email_error !== null) {
echo json_encode(['success' => false, 'error' => $email_error]);
exit;
}
if (!in_array($how_did_you_hear, $allowed_sources, true)) {
echo json_encode(['success' => false, 'error' => 'Please choose how you heard about this webinar from the list.']);
exit;
}
try {
// --- CHECK IF ALREADY REGISTERED OR SOFT-DELETED -- -
$stmt = db()->prepare("SELECT id, deleted_at FROM attendees WHERE webinar_id = ? AND email = ?");
$stmt->execute([$webinar_id, $email]);
$existing_user = $stmt->fetch(PDO::FETCH_ASSOC);
$send_email = false;
if ($existing_user) {
if ($existing_user['deleted_at'] !== null) {
// --- USER IS SOFT-DELETED, SO REACTIVATE AND UPDATE ---
$sql = "UPDATE attendees SET first_name = ?, last_name = ?, company = ?, how_did_you_hear = ?, timezone = ?, deleted_at = NULL, consented = 1 WHERE id = ?";
$stmt = db()->prepare($sql);
$stmt->execute([$first_name, $last_name, $company, $how_did_you_hear, $timezone, $existing_user['id']]);
$send_email = true;
} else {
// --- USER IS ACTIVE, SO REJECT ---
echo json_encode(['success' => false, 'error' => 'You are already registered for this webinar.']);
exit;
}
} else {
// --- REGISTER NEW USER ---
$password_hash = password_hash($email . time(), PASSWORD_DEFAULT);
$sql = "INSERT INTO attendees (webinar_id, first_name, last_name, email, company, how_did_you_hear, password, timezone)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
$stmt = db()->prepare($sql);
$stmt->execute([$webinar_id, $first_name, $last_name, $email, $company, $how_did_you_hear, $password_hash, $timezone]);
$send_email = true;
}
if ($send_email) {
// --- SEND CONFIRMATION EMAIL ---
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'];
$logo_url = $protocol . '://' . $host . '/assets/pasted-20251030-095744-1b7c02ab.png';
$subject = "Confirmation: You're Registered for Building Scalable Apps with AppWizzy";
$webinar_date_obj = new DateTime('2026-03-25 18:00:00', new DateTimeZone('Europe/Berlin'));
// --- PREPARE CALENDAR LINK ---
$event_title_cal = 'Building Scalable Apps with AppWizzy';
$event_description_cal = 'Professional Vibe-Coding Webinar. Join us on March 25th at 6PM CET | 12PM EDT | 9AM PDT to learn the fastest way to go from an idea to a working app you own.';
// Use the same webinar date as in the email body
$webinar_date_for_cal = new DateTime('2026-03-25 18:00:00', new DateTimeZone('Europe/Berlin'));
// Convert to UTC for Google Calendar
$webinar_date_for_cal->setTimezone(new DateTimeZone('UTC'));
$start_time_utc_cal = $webinar_date_for_cal->format('Ymd\THis\Z');
// Add 1 hour for the end time
$webinar_date_for_cal->add(new DateInterval('PT1H'));
$end_time_utc_cal = $webinar_date_for_cal->format('Ymd\THis\Z');
$google_link = 'https://www.google.com/calendar/render?action=TEMPLATE' .
'&text=' . urlencode($event_title_cal) .
'&dates=' . $start_time_utc_cal . '/' . $end_time_utc_cal .
'&details=' . urlencode($event_description_cal) .
'&location=' . urlencode('Online') .
'&ctz=UTC';
$body_html = <<<HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Webinar Registration Confirmation</title>
</head>
<body style="font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; background-color: #f4f4f4; color: #333; margin: 0; padding: 0;">
<table width="100%" border="0" cellspacing="0" cellpadding="0" style="background-color: #f4f4f4;">
<tr>
<td align="center">
<table width="600" border="0" cellspacing="0" cellpadding="0" style="background-color: #ffffff; margin: 20px auto; border-radius: 10px; box-shadow: 0 4px 8px rgba(0,0,0,0.1);">
<!-- Header -->
<tr>
<td align="center" style="padding: 40px 20px; background: linear-gradient(135deg, #1a237e 0%, #673ab7 100%); border-radius: 10px 10px 0 0;">
<img src="{$logo_url}" alt="AppWizzy Logo" style="height: 60px; margin-bottom: 20px;">
<h1 style="color: #ffffff; font-size: 28px; margin: 0; line-height: 1.2;">You're Registered!</h1>
</td>
</tr>
<!-- Body -->
<tr>
<td style="padding: 40px 30px;">
<h2 style="font-size: 22px; color: #1a237e;">Hello {$first_name},</h2>
<p style="font-size: 16px; line-height: 1.6;">Thank you for registering for the <strong>Building Scalable Apps with AppWizzy</strong> webinar.</p>
<p style="font-size: 16px; line-height: 1.6;">We're excited to have you join us for this professional vibe-coding session.</p>
<div style="background-color: #f9f9f9; border-left: 4px solid #673ab7; padding: 15px 20px; margin: 20px 0;">
<p style="margin: 0; font-size: 16px;"><strong>Webinar Details:</strong></p>
<p style="margin: 10px 0 0; font-size: 16px;">{$webinar_date_obj->format('l, F j, Y')} | <strong>6PM CET</strong> | 12PM EDT | 9AM PDT</p>
</div>
<p style="font-size: 16px; line-height: 1.6;">You'll learn the fastest way to go from an idea to a working app you own, running on your server, with your database, using real frameworks.</p>
<p style="font-size: 16px; line-height: 1.6;"><strong>Your personal webinar access link will be emailed to you 1 day before the event.</strong></p>
<p style="text-align: center; margin-top: 30px;">
<a href="{$google_link}" style="background: linear-gradient(135deg, #3f51b5 0%, #9c27b0 100%); color: #ffffff; padding: 12px 25px; text-decoration: none; border-radius: 8px; font-weight: bold;">Add to Calendar</a>
</p>
</td>
</tr>
<!-- Footer -->
<tr>
<td align="center" style="padding: 20px; background-color: #f4f4f4; border-top: 1px solid #dddddd;">
<p style="margin: 0; color: #777;">&copy; 2025 AppWizzy. All rights reserved.</p>
<p style="margin: 5px 0 0; color: #777;">You can <a href="{$protocol}://{$host}/" style="color: #3f51b5;">visit our website</a> for more information.</p>
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>
HTML;
MailService::sendMail($email, $subject, $body_html);
}
// --- PREPARE SUCCESS RESPONSE ---
$webinar_date = new DateTime('2026-03-25 18:00:00', new DateTimeZone('Europe/Berlin'));
$webinar_date->setTimezone(new DateTimeZone('UTC'));
$start_time_utc = $webinar_date->format('Ymd\THis\Z');
$webinar_date->add(new DateInterval('PT1H')); // Assume 1 hour duration
$end_time_utc = $webinar_date->format('Ymd\THis\Z');
$event_title = 'Building Scalable Apps with AppWizzy at 6PM CET';
$event_description = 'Professional Vibe-Coding Webinar\n\nJoin us for this webinar on March 25th at 6PM CET | 12PM EDT | 9AM PDT. The fastest way to go from an idea to a working app you own, running on your server, with your database, using real frameworks.';
$google_link = 'https://www.google.com/calendar/render?action=TEMPLATE&text=' . urlencode($event_title) . '&dates=' . $start_time_utc . '/' . $end_time_utc . '&details=' . urlencode($event_description) . '&location=' . urlencode('Online') . '&ctz=UTC';
$ics_content = implode("\r\n", [
'BEGIN:VCALENDAR',
'VERSION:2.0',
'PRODID:-//Flatlogic//Building Scalable Apps with AppWizzy//EN',
'BEGIN:VEVENT',
'URL:' . 'http://' . $_SERVER['HTTP_HOST'],
'DTSTART:' . $start_time_utc,
'DTEND:' . $end_time_utc,
'SUMMARY:' . $event_title,
'DESCRIPTION:' . str_replace("\n", "\\n", $event_description),
'LOCATION:Online',
'END:VEVENT',
'END:VCALENDAR'
]);
$outlook_link = 'data:text/calendar;charset=utf-8,' . rawurlencode($ics_content);
echo json_encode([
'success' => true,
'webinar_title' => 'Building Scalable Apps with AppWizzy<br><small><strong>Professional Vibe-Coding Webinar</strong></small>',
'google_link' => $google_link,
'outlook_link' => $outlook_link
]);
}
catch (Exception $e) {
http_response_code(500);
echo json_encode(['success' => false, 'error' => 'An unexpected server error occurred. Please try again.']);
}