diff --git a/admin.php b/admin.php
index 5f8a686..3aa6e76 100644
--- a/admin.php
+++ b/admin.php
@@ -29,7 +29,7 @@ $total_records = $total_stmt->fetchColumn();
$total_pages = ceil($total_records / $records_per_page);
// Get records for the current page
-$stmt = $pdo->prepare("SELECT id, first_name, last_name, email, created_at FROM attendees ORDER BY first_name ASC, last_name ASC LIMIT :limit OFFSET :offset");
+$stmt = $pdo->prepare("SELECT id, first_name, last_name, email, created_at, how_did_you_hear, company FROM attendees ORDER BY first_name ASC, last_name ASC LIMIT :limit OFFSET :offset");
$stmt->bindValue(':limit', $records_per_page, PDO::PARAM_INT);
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
$stmt->execute();
@@ -67,6 +67,8 @@ $attendees = $stmt->fetchAll(PDO::FETCH_ASSOC);
- | No attendees found. |
+ No attendees found. |
@@ -83,6 +85,8 @@ $attendees = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
|
+ |
+ |
|
Edit
diff --git a/describe_table.php b/describe_table.php
deleted file mode 100644
index 477ef4a..0000000
--- a/describe_table.php
+++ /dev/null
@@ -1,8 +0,0 @@
-query('DESCRIBE attendees');
- print_r($stmt->fetchAll(PDO::FETCH_ASSOC));
-} catch (PDOException $e) {
- echo 'Error: ' . $e->getMessage();
-}
diff --git a/export_csv.php b/export_csv.php
index 5384d96..3c0d61e 100644
--- a/export_csv.php
+++ b/export_csv.php
@@ -10,7 +10,7 @@ if (!isset($_SESSION['user']) || $_SESSION['user'] !== 'admin') {
}
$pdo = db();
-$stmt = $pdo->query("SELECT first_name, last_name, email FROM attendees ORDER BY created_at DESC");
+$stmt = $pdo->query("SELECT first_name, last_name, email, how_did_you_hear, company FROM attendees ORDER BY created_at DESC");
$attendees = $stmt->fetchAll(PDO::FETCH_ASSOC);
header('Content-Type: text/csv; charset=utf-8');
@@ -22,14 +22,16 @@ $output = fopen('php://output', 'w');
fputs($output, "\xEF\xBB\xBF");
// Add header row
-fputcsv($output, ['First Name', 'Last Name', 'Email']);
+fputcsv($output, ['First Name', 'Last Name', 'Email', 'Source', 'Company']);
// Add data rows
foreach ($attendees as $attendee) {
fputcsv($output, [
$attendee['first_name'],
$attendee['last_name'],
- $attendee['email']
+ $attendee['email'],
+ $attendee['how_did_you_hear'] ?? '',
+ $attendee['company'] ?? ''
]);
}
diff --git a/mail/MailService.php b/mail/MailService.php
index d801067..0d65e2f 100644
--- a/mail/MailService.php
+++ b/mail/MailService.php
@@ -14,35 +14,24 @@ class MailService
{
$cfg = self::loadConfig();
- $autoload = __DIR__ . '/../vendor/autoload.php';
- if (file_exists($autoload)) {
- require_once $autoload;
- }
- if (!class_exists('PHPMailer\\PHPMailer\\PHPMailer')) {
- @require_once 'libphp-phpmailer/autoload.php';
- if (!class_exists('PHPMailer\\PHPMailer\\PHPMailer')) {
- @require_once 'libphp-phpmailer/src/Exception.php';
- @require_once 'libphp-phpmailer/src/SMTP.php';
- @require_once 'libphp-phpmailer/src/PHPMailer.php';
- }
- if (!class_exists('PHPMailer\\PHPMailer\\PHPMailer')) {
- @require_once 'PHPMailer/src/Exception.php';
- @require_once 'PHPMailer/src/SMTP.php';
- @require_once 'PHPMailer/src/PHPMailer.php';
- }
- if (!class_exists('PHPMailer\\PHPMailer\\PHPMailer')) {
- @require_once 'PHPMailer/Exception.php';
- @require_once 'PHPMailer/SMTP.php';
- @require_once 'PHPMailer/PHPMailer.php';
- }
+ // Try Composer autoload first, then fall back to the system-wide (apt) PHPMailer.
+ $composerAutoload = __DIR__ . '/../vendor/autoload.php';
+ if (file_exists($composerAutoload)) {
+ require_once $composerAutoload;
+ } elseif (file_exists('/usr/share/php/libphp-phpmailer/autoload.php')) {
+ require_once '/usr/share/php/libphp-phpmailer/autoload.php';
}
- if (!class_exists('PHPMailer\\PHPMailer\\PHPMailer')) {
+ if (!class_exists('PHPMailer\PHPMailer\PHPMailer')) {
return [ 'success' => false, 'error' => 'PHPMailer not available' ];
}
$mail = new PHPMailer\PHPMailer\PHPMailer(true);
try {
+ $mail->SMTPDebug = 2;
+ $mail->Debugoutput = function($str, $level) {
+ file_put_contents(__DIR__ . '/mail.log', $str, FILE_APPEND);
+ };
$mail->isSMTP();
$mail->Host = $cfg['smtp_host'] ?? '';
$mail->Port = (int)($cfg['smtp_port'] ?? 587);
@@ -54,7 +43,7 @@ class MailService
$mail->Username = $cfg['smtp_user'] ?? '';
$mail->Password = $cfg['smtp_pass'] ?? '';
- $fromEmail = $opts['from_email'] ?? ($cfg['from_email'] ?? 'no-reply@localhost');
+ $fromEmail = $opts['from_email'] ?? ($cfg['from_email'] ?? 'support@flatlogic.com');
$fromName = $opts['from_name'] ?? ($cfg['from_name'] ?? 'App');
$mail->setFrom($fromEmail, $fromName);
if (!empty($opts['reply_to']) && filter_var($opts['reply_to'], FILTER_VALIDATE_EMAIL)) {
@@ -118,31 +107,12 @@ class MailService
{
$cfg = self::loadConfig();
- // Try Composer autoload if available (for PHPMailer)
- $autoload = __DIR__ . '/../vendor/autoload.php';
- if (file_exists($autoload)) {
- require_once $autoload;
- }
- // Fallback to system-wide PHPMailer (installed via apt: libphp-phpmailer)
- if (!class_exists('PHPMailer\\PHPMailer\\PHPMailer')) {
- // Debian/Ubuntu package layout (libphp-phpmailer)
- @require_once 'libphp-phpmailer/autoload.php';
- if (!class_exists('PHPMailer\\PHPMailer\\PHPMailer')) {
- @require_once 'libphp-phpmailer/src/Exception.php';
- @require_once 'libphp-phpmailer/src/SMTP.php';
- @require_once 'libphp-phpmailer/src/PHPMailer.php';
- }
- // Alternative layout (older PHPMailer package names)
- if (!class_exists('PHPMailer\\PHPMailer\\PHPMailer')) {
- @require_once 'PHPMailer/src/Exception.php';
- @require_once 'PHPMailer/src/SMTP.php';
- @require_once 'PHPMailer/src/PHPMailer.php';
- }
- if (!class_exists('PHPMailer\\PHPMailer\\PHPMailer')) {
- @require_once 'PHPMailer/Exception.php';
- @require_once 'PHPMailer/SMTP.php';
- @require_once 'PHPMailer/PHPMailer.php';
- }
+ // Try Composer autoload first, then fall back to the system-wide (apt) PHPMailer.
+ $composerAutoload = __DIR__ . '/../vendor/autoload.php';
+ if (file_exists($composerAutoload)) {
+ require_once $composerAutoload;
+ } elseif (file_exists('/usr/share/php/libphp-phpmailer/autoload.php')) {
+ require_once '/usr/share/php/libphp-phpmailer/autoload.php';
}
$transport = $cfg['transport'] ?? 'smtp';
@@ -158,6 +128,10 @@ class MailService
{
$mail = new PHPMailer\PHPMailer\PHPMailer(true);
try {
+ $mail->SMTPDebug = 2;
+ $mail->Debugoutput = function($str, $level) {
+ file_put_contents(__DIR__ . '/mail.log', $str, FILE_APPEND);
+ };
$mail->isSMTP();
$mail->Host = $cfg['smtp_host'] ?? '';
$mail->Port = (int)($cfg['smtp_port'] ?? 587);
@@ -169,7 +143,7 @@ class MailService
$mail->Username = $cfg['smtp_user'] ?? '';
$mail->Password = $cfg['smtp_pass'] ?? '';
- $fromEmail = $cfg['from_email'] ?? 'no-reply@localhost';
+ $fromEmail = $cfg['from_email'] ?? 'support@flatlogic.com';
$fromName = $cfg['from_name'] ?? 'App';
$mail->setFrom($fromEmail, $fromName);
diff --git a/mail/config.php b/mail/config.php
index 626cca1..7bc9bce 100644
--- a/mail/config.php
+++ b/mail/config.php
@@ -40,15 +40,15 @@ load_dotenv_if_needed([
]);
$transport = env_val('MAIL_TRANSPORT', 'smtp');
-$smtp_host = env_val('SMTP_HOST');
+$smtp_host = env_val('SMTP_HOST', 'email-smtp.us-east-1.amazonaws.com');
$smtp_port = (int) env_val('SMTP_PORT', 587);
$smtp_secure = env_val('SMTP_SECURE', 'tls'); // tls | ssl | null
-$smtp_user = env_val('SMTP_USER');
-$smtp_pass = env_val('SMTP_PASS');
+$smtp_user = env_val('SMTP_USER', 'AKIAVEW7G4PQUBGM52OF');
+$smtp_pass = env_val('SMTP_PASS', 'BLnD4hKGb6YkSz3gaQrf8fnyLi3C3/EdjOOsLEDTDPTz');
-$from_email = env_val('MAIL_FROM', 'no-reply@localhost');
-$from_name = env_val('MAIL_FROM_NAME', 'App');
-$reply_to = env_val('MAIL_REPLY_TO');
+$from_email = env_val('MAIL_FROM', 'app@flatlogic.app');
+$from_name = env_val('MAIL_FROM_NAME', 'Flatlogic App');
+$reply_to = env_val('MAIL_REPLY_TO', 'app@flatlogic.app');
$dkim_domain = env_val('DKIM_DOMAIN');
$dkim_selector = env_val('DKIM_SELECTOR');
diff --git a/mail/mail.log b/mail/mail.log
new file mode 100644
index 0000000..66a55a5
--- /dev/null
+++ b/mail/mail.log
@@ -0,0 +1,195 @@
+SERVER -> CLIENT: 220 email-smtp.amazonaws.com ESMTP SimpleEmailService-d-5KYUAZVUF HYrGkiakGqXZYkI8moXl
+CLIENT -> SERVER: EHLO webinar-registration.dev.flatlogic.app
+SERVER -> CLIENT: 250-email-smtp.amazonaws.com
+250-8BITMIME
+250-STARTTLS
+250-AUTH PLAIN LOGIN
+250 Ok
+CLIENT -> SERVER: STARTTLS
+SERVER -> CLIENT: 220 Ready to start TLS
+CLIENT -> SERVER: EHLO webinar-registration.dev.flatlogic.app
+SERVER -> CLIENT: 250-email-smtp.amazonaws.com
+250-8BITMIME
+250-STARTTLS
+250-AUTH PLAIN LOGIN
+250 Ok
+CLIENT -> SERVER: AUTH LOGIN
+SERVER -> CLIENT: 334 VXNlcm5hbWU6
+CLIENT -> SERVER: [credentials hidden]SERVER -> CLIENT: 334 UGFzc3dvcmQ6
+CLIENT -> SERVER: [credentials hidden]SERVER -> CLIENT: 235 Authentication successful.
+CLIENT -> SERVER: MAIL FROM:
+SERVER -> CLIENT: 250 Ok
+CLIENT -> SERVER: RCPT TO:
+SERVER -> CLIENT: 250 Ok
+CLIENT -> SERVER: DATA
+SERVER -> CLIENT: 354 End data with .
+CLIENT -> SERVER: Date: Fri, 31 Oct 2025 10:33:06 +0000
+CLIENT -> SERVER: To: Blarior@gmail.com
+CLIENT -> SERVER: From: Flatlogic App
+CLIENT -> SERVER: Reply-To: app@flatlogic.app
+CLIENT -> SERVER: Subject: Confirmation: You're Registered for Building Scalable Apps with AppWizzy
+CLIENT -> SERVER: Message-ID:
+CLIENT -> SERVER: X-Mailer: PHPMailer 6.6.3 (https://github.com/PHPMailer/PHPMailer)
+CLIENT -> SERVER: MIME-Version: 1.0
+CLIENT -> SERVER: Content-Type: multipart/alternative;
+CLIENT -> SERVER: boundary="b1_b2vWqyHUE69uA6oPGIGO4Am9Ilj5uKn0OhRAVGcAg"
+CLIENT -> SERVER: Content-Transfer-Encoding: 8bit
+CLIENT -> SERVER:
+CLIENT -> SERVER: This is a multi-part message in MIME format.
+CLIENT -> SERVER:
+CLIENT -> SERVER: --b1_b2vWqyHUE69uA6oPGIGO4Am9Ilj5uKn0OhRAVGcAg
+CLIENT -> SERVER: Content-Type: text/plain; charset=iso-8859-1
+CLIENT -> SERVER: Content-Transfer-Encoding: 8bit
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER: Webinar Registration Confirmation
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER: You're Registered!
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER: Hello Почтовый,
+CLIENT -> SERVER: Thank you for registering for the Building Scalable Apps with AppWizzy webinar.
+CLIENT -> SERVER: We're excited to have you join us for this professional vibe-coding session.
+CLIENT -> SERVER:
+CLIENT -> SERVER: Webinar Details:
+CLIENT -> SERVER: Wednesday, November 19, 2025 | 10:00 AM EST
+CLIENT -> SERVER:
+CLIENT -> SERVER: 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.
+CLIENT -> SERVER:
+CLIENT -> SERVER: Access Your Dashboard
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER: Meet the Speakers
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER: Philip Daineka
+CLIENT -> SERVER: CEO, AppWizzy
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER: Alexandr Rubanau
+CLIENT -> SERVER: Lead Engineer
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER: Alexey Vertel
+CLIENT -> SERVER: Lead Engineer
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER: © 2025 AppWizzy. All rights reserved.
+CLIENT -> SERVER: You can visit our website for more information.
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER: --b1_b2vWqyHUE69uA6oPGIGO4Am9Ilj5uKn0OhRAVGcAg
+CLIENT -> SERVER: Content-Type: text/html; charset=iso-8859-1
+CLIENT -> SERVER: Content-Transfer-Encoding: 8bit
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER: Webinar Registration Confirmation
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER: You're Registered!
+CLIENT -> SERVER: |
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER: Hello Почтовый,
+CLIENT -> SERVER: Thank you for registering for the Building Scalable Apps with AppWizzy webinar.
+CLIENT -> SERVER: We're excited to have you join us for this professional vibe-coding session.
+CLIENT -> SERVER:
+CLIENT -> SERVER: Webinar Details:
+CLIENT -> SERVER: Wednesday, November 19, 2025 | 10:00 AM EST
+CLIENT -> SERVER:
+CLIENT -> SERVER: 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.
+CLIENT -> SERVER:
+CLIENT -> SERVER: Access Your Dashboard
+CLIENT -> SERVER:
+CLIENT -> SERVER: |
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER: Meet the Speakers
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER: |
+CLIENT -> SERVER: Philip Daineka
+CLIENT -> SERVER: CEO, AppWizzy
+CLIENT -> SERVER: |
+CLIENT -> SERVER:
+CLIENT -> SERVER: Alexandr Rubanau
+CLIENT -> SERVER: Lead Engineer
+CLIENT -> SERVER: |
+CLIENT -> SERVER:
+CLIENT -> SERVER: Alexey Vertel
+CLIENT -> SERVER: Lead Engineer
+CLIENT -> SERVER: |
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER: |
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER: |
+CLIENT -> SERVER: © 2025 AppWizzy. All rights reserved.
+CLIENT -> SERVER: You can visit our website for more information.
+CLIENT -> SERVER: |
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER: |
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER:
+CLIENT -> SERVER: --b1_b2vWqyHUE69uA6oPGIGO4Am9Ilj5uKn0OhRAVGcAg--
+CLIENT -> SERVER:
+CLIENT -> SERVER: .
+SERVER -> CLIENT: 250 Ok 0100019a39d403bd-4dd3eb82-372d-4d1c-9605-2624e55d57fc-000000
+CLIENT -> SERVER: QUIT
+SERVER -> CLIENT: 221 Bye
diff --git a/register.php b/register.php
index 6ce79f3..cd773b5 100644
--- a/register.php
+++ b/register.php
@@ -48,17 +48,20 @@ if (!$first_name || !$last_name || !$email) {
}
try {
- // --- CHECK IF ALREADY REGISTERED OR SOFT-DELETED -- -
+ // --- 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.']);
@@ -71,16 +74,18 @@ try {
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;
}
- // --- 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('2025-11-19 10:00:00', new DateTimeZone('America/New_York'));
+ 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('2025-11-19 10:00:00', new DateTimeZone('America/New_York'));
- $body_html = <<
@@ -152,14 +157,15 @@ try {
HTML;
- MailService::sendMail($email, $subject, $body_html);
+ MailService::sendMail($email, $subject, $body_html);
+ }
// --- PREPARE SUCCESS RESPONSE ---
$webinar_date = new DateTime('2025-11-19 10:00:00', new DateTimeZone('America/New_York'));
$webinar_date->setTimezone(new DateTimeZone('UTC'));
- $start_time_utc = $webinar_date->format('Ymd\THis\Z');
+ $start_time_utc = $webinar_date->format('Ymd H:i:s Z');
$webinar_date->add(new DateInterval('PT1H')); // Assume 1 hour duration
- $end_time_utc = $webinar_date->format('Ymd\THis\Z');
+ $end_time_utc = $webinar_date->format('Ymd H:i:s Z');
$event_title = 'Building Scalable Apps with AppWizzy at 4PM CET';
$event_description = 'Professional Vibe-Coding Webinar\n\nJoin us for this webinar at 4PM CET | 10AM EST | 7AM PST. The fastest way to go from an idea to a working app you own, running on your server, with your database, using real frameworks.';
@@ -189,8 +195,8 @@ HTML;
'outlook_link' => $outlook_link
]);
-} catch (Exception $e) {
- error_log("Registration error: " . $e->getMessage());
+}
+ catch (Exception $e) {
http_response_code(500);
echo json_encode(['success' => false, 'error' => 'An unexpected server error occurred. Please try again.']);
}
|