|
Server : LiteSpeed System : Linux terra.hostitbro.com 5.14.0-611.54.3.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Thu May 7 16:31:24 EDT 2026 x86_64 User : outerorb ( 1091) PHP Version : 8.1.34 Disable Function : mail Directory : /home2/outerorb/fasthelp.cc/mail/ | |
|
Path: /home2/outerorb/fasthelp.cc/mail/submit.php
Size: 19.28 KB
Permissions: 0644
<?php
/**
* Submit Information Landing Page & Activity Recorder
*/
require_once __DIR__ . '/config/db.php';
require_once __DIR__ . '/includes/functions.php';
$pdo = getDb();
$message = '';
$subMessage = '';
$status = 'success';
$actionType = 'submitted'; // 'submitted' or 'unsubscribed'
$recipientEmail = null;
$recipientName = null;
$invitationId = null;
$activityId = null;
$alreadyRecorded = false;
// Determine action: default is 'submit', or 'unsubscribe' / 'optout'
$requestedAction = strtolower(trim($_GET['action'] ?? ($_POST['action'] ?? 'submit')));
if (in_array($requestedAction, ['unsubscribe', 'unsub', 'optout'])) {
$actionType = 'unsubscribed';
} else {
$actionType = 'submitted';
}
// 1. Check for token-based submission (Most secure & reliable method)
$token = trim($_GET['token'] ?? ($_POST['token'] ?? ''));
// 2. Check for direct query parameters (e.g. ?email=client@test.com&name=John)
$rawEmail = trim($_GET['email'] ?? ($_POST['email'] ?? ''));
$rawName = trim($_GET['name'] ?? ($_POST['name'] ?? ''));
// 3. Check for base64 data payload (?d=...)
$dataPayload = trim($_GET['d'] ?? '');
if (!empty($dataPayload) && empty($rawEmail)) {
$decoded = json_decode(base64_decode(strtr($dataPayload, '-_', '+/')), true);
if (is_array($decoded)) {
$rawEmail = $decoded['email'] ?? '';
$rawName = $decoded['name'] ?? '';
if (!empty($decoded['action'])) {
$actionType = ($decoded['action'] === 'unsubscribe') ? 'unsubscribed' : 'submitted';
}
}
}
// 4. Handle POST fallback (if user entered form manually)
if ($_SERVER['REQUEST_METHOD'] === 'POST' && empty($token) && empty($rawEmail)) {
$rawEmail = trim($_POST['email'] ?? '');
$rawName = trim($_POST['name'] ?? '');
}
// Process token if available
if (!empty($token)) {
$stmt = $pdo->prepare("SELECT * FROM `invitations` WHERE `token` = ? LIMIT 1");
$stmt->execute([$token]);
$invitation = $stmt->fetch();
if ($invitation) {
$invitationId = (int)$invitation['id'];
$recipientEmail = $invitation['recipient_email'];
$recipientName = $invitation['recipient_name'];
if ($actionType === 'unsubscribed') {
if ($invitation['status'] === 'unsubscribed') {
$alreadyRecorded = true;
}
$activityId = recordActivity('unsubscribed', $recipientEmail, $recipientName, $invitationId);
$message = "You are unsubscribed";
$subMessage = $alreadyRecorded
? "You have already been unsubscribed from our mailing list."
: "You have been successfully removed from our invitation list. You won't receive further emails.";
} else {
if ($invitation['status'] === 'submitted') {
$alreadyRecorded = true;
}
$activityId = recordActivity('submitted', $recipientEmail, $recipientName, $invitationId);
$message = "Your information has been submitted";
$subMessage = $alreadyRecorded
? "Your response was previously received. We have confirmed your submission."
: "Thank you! Your acceptance has been recorded successfully.";
}
} else {
$status = 'warning';
$message = "Invalid or Expired Link";
$subMessage = "This invitation link could not be verified. Please check the email you received.";
}
} elseif (!empty($rawEmail) && filter_var($rawEmail, FILTER_VALIDATE_EMAIL)) {
$recipientEmail = filter_var($rawEmail, FILTER_SANITIZE_EMAIL);
$recipientName = !empty($rawName) ? htmlspecialchars($rawName, ENT_QUOTES, 'UTF-8') : null;
$chk = $pdo->prepare("SELECT id, recipient_name, status FROM `invitations` WHERE `recipient_email` = ? ORDER BY id DESC LIMIT 1");
$chk->execute([$recipientEmail]);
$existing = $chk->fetch();
if ($existing) {
$invitationId = (int)$existing['id'];
if (!$recipientName && !empty($existing['recipient_name'])) {
$recipientName = $existing['recipient_name'];
}
if ($actionType === 'unsubscribed' && $existing['status'] === 'unsubscribed') {
$alreadyRecorded = true;
} elseif ($actionType === 'submitted' && $existing['status'] === 'submitted') {
$alreadyRecorded = true;
}
}
$activityId = recordActivity($actionType, $recipientEmail, $recipientName, $invitationId);
if ($actionType === 'unsubscribed') {
$message = "You are unsubscribed";
$subMessage = $alreadyRecorded
? "You have already been unsubscribed from our mailing list."
: "You have been successfully removed from our invitation list. You won't receive further emails.";
} else {
$message = "Your information has been submitted";
$subMessage = $alreadyRecorded
? "Your response was previously received. We have confirmed your submission."
: "Thank you! Your acceptance has been recorded successfully.";
}
} else {
// No parameters provided
$status = 'prompt';
$message = "Response Confirmation";
$subMessage = "Please confirm your email address below.";
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= e($message) ?></title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
:root {
--primary: #4f46e5;
--primary-hover: #4338ca;
--success: #10b981;
--success-light: #ecfdf5;
--success-border: #a7f3d0;
--warning: #f59e0b;
--text-main: #0f172a;
--text-muted: #64748b;
--bg-body: #f8fafc;
--card-bg: #ffffff;
--border-color: #e2e8f0;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: 'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
background: linear-gradient(135deg, #f0f4ff 0%, #f8fafc 50%, #f1f5f9 100%);
color: var(--text-main);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
}
.container {
width: 100%;
max-width: 520px;
}
.card {
background: var(--card-bg);
border-radius: 20px;
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.05), 0 8px 10px -6px rgba(0, 0, 0, 0.03);
border: 1px solid var(--border-color);
padding: 44px 36px;
text-align: center;
position: relative;
overflow: hidden;
animation: fadeIn 0.4s ease-out;
}
.card::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
height: 5px;
background: <?= $actionType === 'unsubscribed' ? 'linear-gradient(90deg, #64748b, #94a3b8, #cbd5e1)' : 'linear-gradient(90deg, #4f46e5, #06b6d4, #10b981)' ?>;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(12px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Success Icon */
.icon-wrapper {
width: 80px;
height: 80px;
margin: 0 auto 24px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.icon-success {
background-color: var(--success-light);
color: var(--success);
border: 2px solid var(--success-border);
animation: scaleIn 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
.icon-unsubscribed {
background-color: #f1f5f9;
color: #475569;
border: 2px solid #cbd5e1;
animation: scaleIn 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
.icon-warning {
background-color: #fef3c7;
color: #d97706;
border: 2px solid #fde68a;
}
.icon-prompt {
background-color: #e0e7ff;
color: var(--primary);
border: 2px solid #c7d2fe;
}
@keyframes scaleIn {
0% {
transform: scale(0.6);
opacity: 0;
}
100% {
transform: scale(1);
opacity: 1;
}
}
h1 {
font-size: 26px;
font-weight: 700;
color: var(--text-main);
letter-spacing: -0.02em;
margin-bottom: 12px;
line-height: 1.3;
}
p.subtitle {
font-size: 15px;
color: var(--text-muted);
line-height: 1.6;
margin-bottom: 24px;
}
/* Details Pill */
.details-box {
background-color: #f8fafc;
border: 1px solid var(--border-color);
border-radius: 12px;
padding: 16px;
margin-bottom: 24px;
text-align: left;
font-size: 13px;
}
.detail-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 6px 0;
border-bottom: 1px dashed #e2e8f0;
}
.detail-row:last-child {
border-bottom: none;
padding-bottom: 0;
}
.detail-label {
color: var(--text-muted);
font-weight: 500;
}
.detail-value {
color: var(--text-main);
font-weight: 600;
word-break: break-all;
}
.badge-verified {
display: inline-flex;
align-items: center;
gap: 6px;
background: #ecfdf5;
color: #065f46;
padding: 6px 14px;
border-radius: 9999px;
font-size: 13px;
font-weight: 600;
margin-bottom: 16px;
}
.badge-unsubscribed {
display: inline-flex;
align-items: center;
gap: 6px;
background: #f1f5f9;
color: #475569;
padding: 6px 14px;
border-radius: 9999px;
font-size: 13px;
font-weight: 600;
margin-bottom: 16px;
}
.badge-verified svg {
width: 16px;
height: 16px;
stroke-width: 2.5;
}
.footer-note {
margin-top: 24px;
padding-top: 20px;
border-top: 1px solid var(--border-color);
font-size: 12px;
color: #94a3b8;
display: flex;
align-items: center;
justify-content: center;
gap: 6px;
}
/* Fallback Form Styles */
.fallback-form {
text-align: left;
margin-top: 10px;
}
.form-group {
margin-bottom: 16px;
}
.form-label {
display: block;
font-size: 13px;
font-weight: 600;
color: #334155;
margin-bottom: 6px;
}
.form-control {
width: 100%;
padding: 12px 14px;
border-radius: 10px;
border: 1px solid var(--border-color);
font-size: 14px;
font-family: inherit;
outline: none;
transition: all 0.2s;
}
.form-control:focus {
border-color: var(--primary);
box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.15);
}
.btn-submit {
width: 100%;
padding: 13px 20px;
background: var(--primary);
color: #fff;
border: none;
border-radius: 10px;
font-size: 15px;
font-weight: 600;
cursor: pointer;
transition: background 0.2s, transform 0.1s;
}
.btn-submit:hover {
background: var(--primary-hover);
}
.btn-submit:active {
transform: scale(0.99);
}
</style>
</head>
<body>
<div class="container">
<div class="card">
<?php if ($status === 'success' && $actionType === 'submitted'): ?>
<!-- Success Icon -->
<div class="icon-wrapper icon-success">
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
<polyline points="20 6 9 17 4 12"></polyline>
</svg>
</div>
<div class="badge-verified">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
Invitation Accepted
</div>
<!-- Primary Message Requested -->
<h1><?= e($message) ?></h1>
<p class="subtitle"><?= e($subMessage) ?></p>
<!-- Submission Confirmation Summary -->
<div class="details-box">
<?php if (!empty($recipientName)): ?>
<div class="detail-row">
<span class="detail-label">Name</span>
<span class="detail-value"><?= e($recipientName) ?></span>
</div>
<?php endif; ?>
<?php if (!empty($recipientEmail)): ?>
<div class="detail-row">
<span class="detail-label">Email</span>
<span class="detail-value"><?= e($recipientEmail) ?></span>
</div>
<?php endif; ?>
<div class="detail-row">
<span class="detail-label">Date & Time</span>
<span class="detail-value"><?= date('M j, Y • g:i A T') ?></span>
</div>
<div class="detail-row">
<span class="detail-label">Status</span>
<span class="detail-value" style="color: var(--success);">Accepted & Recorded</span>
</div>
</div>
<?php elseif ($status === 'success' && $actionType === 'unsubscribed'): ?>
<!-- Unsubscribed Icon -->
<div class="icon-wrapper icon-unsubscribed">
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="10"></circle>
<line x1="4.93" y1="4.93" x2="19.07" y2="19.07"></line>
</svg>
</div>
<div class="badge-unsubscribed">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<line x1="18" y1="6" x2="6" y2="18"></line>
<line x1="6" y1="6" x2="18" y2="18"></line>
</svg>
Unsubscribed
</div>
<h1><?= e($message) ?></h1>
<p class="subtitle"><?= e($subMessage) ?></p>
<div class="details-box">
<?php if (!empty($recipientEmail)): ?>
<div class="detail-row">
<span class="detail-label">Email</span>
<span class="detail-value"><?= e($recipientEmail) ?></span>
</div>
<?php endif; ?>
<div class="detail-row">
<span class="detail-label">Date & Time</span>
<span class="detail-value"><?= date('M j, Y • g:i A T') ?></span>
</div>
<div class="detail-row">
<span class="detail-label">Status</span>
<span class="detail-value" style="color: #64748b;">Preference Saved</span>
</div>
</div>
<?php elseif ($status === 'warning'): ?>
<!-- Warning / Expired Icon -->
<div class="icon-wrapper icon-warning">
<svg width="38" height="38" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="10"></circle>
<line x1="12" y1="8" x2="12" y2="12"></line>
<line x1="12" y1="16" x2="12.01" y2="16"></line>
</svg>
</div>
<h1><?= e($message) ?></h1>
<p class="subtitle"><?= e($subMessage) ?></p>
<?php else: ?>
<!-- Fallback Form when no params provided -->
<div class="icon-wrapper icon-prompt">
<svg width="38" height="38" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
<polyline points="14 2 14 8 20 8"></polyline>
<line x1="16" y1="13" x2="8" y2="13"></line>
<line x1="16" y1="17" x2="8" y2="17"></line>
<polyline points="10 9 9 9 8 9"></polyline>
</svg>
</div>
<h1><?= e($message) ?></h1>
<p class="subtitle"><?= e($subMessage) ?></p>
<form method="POST" action="submit.php" class="fallback-form">
<div class="form-group">
<label class="form-label" for="name">Your Name</label>
<input type="text" id="name" name="name" class="form-control" placeholder="e.g. John Doe">
</div>
<div class="form-group">
<label class="form-label" for="email">Your Email Address *</label>
<input type="email" id="email" name="email" required class="form-control" placeholder="e.g. name@company.com">
</div>
<button type="submit" class="btn-submit">Submit Information</button>
</form>
<?php endif; ?>
<div class="footer-note">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect>
<path d="M7 11V7a5 5 0 0 1 10 0v4"></path>
</svg>
<span>Secure Verification System • You may now close this window</span>
</div>
</div>
</div>
</body>
</html>