0, 'time' => time()]; } $data = $_SESSION[$key]; if (time() - $data['time'] > 3600) { $_SESSION[$key] = ['count' => 0, 'time' => time()]; $data = $_SESSION[$key]; } return $data['count'] < 5; // Allow 5 submissions per hour } // Input validation function validateInput($data, $type = 'text') { $data = trim($data); $data = stripslashes($data); $data = htmlspecialchars($data, ENT_QUOTES, 'UTF-8'); switch ($type) { case 'email': return filter_var($data, FILTER_VALIDATE_EMAIL) ? $data : false; case 'text': return strlen($data) > 0 ? $data : ''; default: return $data; } } // Check if request is AJAX function isAjaxRequest() { return !empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'; } // Response function function sendResponse($success, $message) { if (isAjaxRequest()) { header('Content-Type: application/json'); echo json_encode(['success' => $success, 'message' => $message]); exit; } // HTML fallback $title = $success ? 'Quote Request Sent' : 'Error'; $class = $success ? 'success' : 'error'; echo "$title

$title

" . htmlspecialchars($message) . "

Back to form | Home

"; exit; } // Handle POST requests only if ($_SERVER['REQUEST_METHOD'] !== 'POST') { sendResponse(false, 'Invalid request method'); } logDebug("Form submission from " . $_SERVER['REMOTE_ADDR'] . " - Session ID: " . session_id()); // CSRF Validation $csrfToken = $_POST['csrf_token'] ?? ''; if (empty($csrfToken)) { logDebug("CSRF: No token in POST data"); sendResponse(false, 'Security validation failed. Please refresh the page and try again.'); } if (!validateCSRFToken($csrfToken)) { sendResponse(false, 'Security validation failed. Please refresh the page and try again.'); } logDebug("CSRF validation passed"); // Rate limiting if (!checkRateLimit()) { logDebug("Rate limit exceeded for " . $_SERVER['REMOTE_ADDR']); sendResponse(false, 'Too many requests. Please try again later.'); } // reCAPTCHA (if enabled) require_once __DIR__ . '/.recaptcha-config.php'; if (RECAPTCHA_ENABLED) { $recaptchaResponse = $_POST['recaptcha_response'] ?? ''; if (empty($recaptchaResponse)) { sendResponse(false, 'Security verification failed. Please try again.'); } $verifyData = [ 'secret' => RECAPTCHA_SECRET_KEY, 'response' => $recaptchaResponse, 'remoteip' => $_SERVER['REMOTE_ADDR'] ]; $result = @file_get_contents('https://www.google.com/recaptcha/api/siteverify', false, stream_context_create(['http' => [ 'method' => 'POST', 'header' => 'Content-type: application/x-www-form-urlencoded', 'content' => http_build_query($verifyData) ]])); if ($result) { $resultJson = json_decode($result, true); if (!$resultJson['success'] || ($resultJson['score'] ?? 1) < RECAPTCHA_THRESHOLD) { logDebug("reCAPTCHA failed: " . print_r($resultJson, true)); sendResponse(false, 'Security verification failed. Please try again.'); } } } // Honeypot check if (!empty($_POST['website'])) { logDebug("Honeypot triggered"); sendResponse(false, 'Spam detected'); } // Bot detection - user agent check $userAgent = $_SERVER['HTTP_USER_AGENT'] ?? ''; $suspiciousAgents = ['curl', 'wget', 'python-requests', 'scrapy']; foreach ($suspiciousAgents as $agent) { if (stripos($userAgent, $agent) !== false) { logDebug("Suspicious user agent: $userAgent"); sendResponse(false, 'Automated submissions not allowed'); } } // Extract and validate form data $service_type = validateInput($_POST['service_type'] ?? ''); $scale = validateInput($_POST['scale'] ?? ''); $name = validateInput($_POST['name'] ?? ''); $email = validateInput($_POST['email'] ?? '', 'email'); $company = validateInput($_POST['company'] ?? ''); $timeline = validateInput($_POST['timeline'] ?? ''); $data_sources = validateInput($_POST['data_sources'] ?? ''); $requirements = validateInput($_POST['requirements'] ?? ''); // Validation $errors = []; if (empty($service_type)) $errors[] = 'Please select a service'; if (empty($scale)) $errors[] = 'Please select a scale'; if (empty($name) || strlen($name) < 2) $errors[] = 'Please enter a valid name'; if (!$email) $errors[] = 'Please enter a valid email address'; if (empty($timeline)) $errors[] = 'Please select a timeline'; if (!empty($errors)) { logDebug("Validation errors: " . implode(', ', $errors)); sendResponse(false, implode('. ', $errors)); } // Spam content check $spamKeywords = ['viagra', 'cialis', 'casino', 'lottery', 'bitcoin', 'forex', 'pharmacy', 'click here', 'act now']; $contentToCheck = strtolower($requirements . ' ' . $name . ' ' . $company . ' ' . $data_sources); foreach ($spamKeywords as $keyword) { if (strpos($contentToCheck, $keyword) !== false) { logDebug("Spam keyword detected: $keyword"); sendResponse(false, 'Invalid content detected'); } } // Update rate limit counter $ip = $_SERVER['REMOTE_ADDR']; $key = 'quote_' . md5($ip); $_SESSION[$key]['count']++; // Prepare friendly labels $serviceLabels = [ 'web-scraping' => 'Web Scraping', 'data-cleaning' => 'Data Cleaning', 'api-development' => 'API Development', 'automation' => 'Automation', 'custom' => 'Custom Solution', 'other' => 'Other' ]; $scaleLabels = [ 'small' => 'Small (under 1,000 records)', 'medium' => 'Medium (1,000 - 50,000 records)', 'large' => 'Large (50,000 - 500,000 records)', 'enterprise' => 'Enterprise (500,000+ records)', 'unsure' => 'Not sure yet' ]; $timelineLabels = [ 'asap' => 'ASAP', '2weeks' => 'Within 2 weeks', '1month' => 'Within a month', 'flexible' => 'Flexible / No rush' ]; // Build email $to = 'info@ukaiautomation.co.uk'; $subject = 'New Quote Request - ' . ($serviceLabels[$service_type] ?? $service_type); $emailHTML = '

New Quote Request

UK AI Automation

Contact Details

Name: ' . $name . '

Email: ' . $email . '

Company: ' . ($company ?: 'Not provided') . '

Project Details

Service: ' . ($serviceLabels[$service_type] ?? $service_type) . '

Scale: ' . ($scaleLabels[$scale] ?? $scale) . '

Timeline: ' . ($timelineLabels[$timeline] ?? $timeline) . '

Target Sources: ' . ($data_sources ?: 'Not specified') . '

'; if (!empty($requirements)) { $emailHTML .= '

Requirements

' . nl2br($requirements) . '

'; } $emailHTML .= '

Submitted: ' . date('Y-m-d H:i:s') . ' UTC

IP: ' . $_SERVER['REMOTE_ADDR'] . '

'; $headers = "MIME-Version: 1.0\r\n"; $headers .= "Content-Type: text/html; charset=UTF-8\r\n"; $headers .= "From: \"UK AI Automation\" \r\n"; $headers .= "Reply-To: " . $email . "\r\n"; $headers .= "X-Priority: " . ($timeline === 'asap' ? '1' : '3') . "\r\n"; // Send email $emailSent = @mail($to, $subject, $emailHTML, $headers); if ($emailSent) { logDebug("SUCCESS: Quote from $email ($name) - Service: $service_type"); // Log to file $logEntry = date('Y-m-d H:i:s') . " | $name | $email | $service_type | $scale | $timeline\n"; file_put_contents($logDir . '/quote-requests.log', $logEntry, FILE_APPEND | LOCK_EX); sendResponse(true, 'Thank you for your quote request! We will send you a detailed proposal within 24 hours.'); } else { $error = error_get_last(); logDebug("FAILED: Email send failed - " . ($error['message'] ?? 'Unknown error')); sendResponse(false, 'There was an error sending your request. Please try again or contact us at info@ukaiautomation.co.uk'); } ?>