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
";
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');
}
?>