Initial commit: UK Data Services website
This commit is contained in:
432
quote-handler.php
Normal file
432
quote-handler.php
Normal file
@@ -0,0 +1,432 @@
|
||||
<?php
|
||||
// Quote Form Handler with Enhanced Security
|
||||
session_start();
|
||||
|
||||
// Security headers
|
||||
header('X-Content-Type-Options: nosniff');
|
||||
header('X-Frame-Options: DENY');
|
||||
header('X-XSS-Protection: 1; mode=block');
|
||||
header('Content-Type: application/json');
|
||||
|
||||
// Rate limiting
|
||||
function checkRateLimit() {
|
||||
$ip = $_SERVER['REMOTE_ADDR'];
|
||||
$key = 'quote_' . md5($ip);
|
||||
|
||||
if (!isset($_SESSION[$key])) {
|
||||
$_SESSION[$key] = ['count' => 0, 'time' => time()];
|
||||
}
|
||||
|
||||
$data = $_SESSION[$key];
|
||||
|
||||
if (time() - $data['time'] > 3600) {
|
||||
$_SESSION[$key] = ['count' => 0, 'time' => time()];
|
||||
$data = $_SESSION[$key];
|
||||
}
|
||||
|
||||
if ($data['count'] >= 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 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 'phone':
|
||||
return preg_match('/^[\+]?[0-9\s\-\(\)]+$/', $data) ? $data : false;
|
||||
case 'text':
|
||||
return strlen($data) > 0 ? $data : false;
|
||||
case 'long_text':
|
||||
return strlen($data) >= 20 ? $data : false;
|
||||
default:
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
// Response function
|
||||
function sendResponse($success, $message, $data = null) {
|
||||
$response = [
|
||||
'success' => $success,
|
||||
'message' => $message
|
||||
];
|
||||
|
||||
if ($data !== null) {
|
||||
$response['data'] = $data;
|
||||
}
|
||||
|
||||
echo json_encode($response);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Handle POST requests only
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
sendResponse(false, 'Invalid request method');
|
||||
}
|
||||
|
||||
// Check rate limiting
|
||||
if (!checkRateLimit()) {
|
||||
sendResponse(false, 'Too many requests. Please try again later.');
|
||||
}
|
||||
|
||||
// Validate and sanitize inputs
|
||||
$services = $_POST['services'] ?? [];
|
||||
$project_scale = validateInput($_POST['project_scale'] ?? '', 'text');
|
||||
$timeline = validateInput($_POST['timeline'] ?? '', 'text');
|
||||
$name = validateInput($_POST['name'] ?? '', 'text');
|
||||
$email = validateInput($_POST['email'] ?? '', 'email');
|
||||
$company = validateInput($_POST['company'] ?? '', 'text');
|
||||
$phone = validateInput($_POST['phone'] ?? '', 'phone');
|
||||
$data_sources = validateInput($_POST['data_sources'] ?? '', 'text');
|
||||
$requirements = validateInput($_POST['requirements'] ?? '', 'long_text');
|
||||
$budget = validateInput($_POST['budget'] ?? '', 'text');
|
||||
|
||||
// Validation
|
||||
$errors = [];
|
||||
|
||||
if (empty($services) || !is_array($services)) {
|
||||
$errors[] = 'Please select at least one service';
|
||||
}
|
||||
|
||||
if (!$project_scale) {
|
||||
$errors[] = 'Please select a project scale';
|
||||
}
|
||||
|
||||
if (!$timeline) {
|
||||
$errors[] = 'Please select a timeline';
|
||||
}
|
||||
|
||||
if (!$name || strlen($name) < 2) {
|
||||
$errors[] = 'Please enter a valid name';
|
||||
}
|
||||
|
||||
if (!$email) {
|
||||
$errors[] = 'Please enter a valid email address';
|
||||
}
|
||||
|
||||
if (!$requirements) {
|
||||
$errors[] = 'Please provide detailed project requirements';
|
||||
}
|
||||
|
||||
if (!empty($errors)) {
|
||||
sendResponse(false, implode('. ', $errors));
|
||||
}
|
||||
|
||||
// Sanitize services array
|
||||
$services = array_map(function($service) {
|
||||
return htmlspecialchars(trim($service), ENT_QUOTES, 'UTF-8');
|
||||
}, $services);
|
||||
|
||||
// Update rate limit counter
|
||||
$ip = $_SERVER['REMOTE_ADDR'];
|
||||
$key = 'quote_' . md5($ip);
|
||||
$_SESSION[$key]['count']++;
|
||||
|
||||
// Create friendly service names
|
||||
$service_names = [
|
||||
'web-scraping' => 'Web Scraping & Data Extraction',
|
||||
'business-intelligence' => 'Business Intelligence & Analytics',
|
||||
'data-processing' => 'Data Processing & Cleaning',
|
||||
'automation' => 'Automation & APIs',
|
||||
'consulting' => 'Custom Development',
|
||||
'other' => 'Other Services'
|
||||
];
|
||||
|
||||
$selected_services = array_map(function($service) use ($service_names) {
|
||||
return $service_names[$service] ?? $service;
|
||||
}, $services);
|
||||
|
||||
// Create friendly scale names
|
||||
$scale_names = [
|
||||
'small' => 'Small Project (One-time extraction, < 10k records)',
|
||||
'medium' => 'Medium Project (Regular updates, 10k-100k records)',
|
||||
'large' => 'Large Project (Ongoing service, 100k+ records)',
|
||||
'enterprise' => 'Enterprise (Complex multi-source solution)'
|
||||
];
|
||||
|
||||
$friendly_scale = $scale_names[$project_scale] ?? $project_scale;
|
||||
|
||||
// Create friendly timeline names
|
||||
$timeline_names = [
|
||||
'asap' => 'ASAP (Rush job)',
|
||||
'1-week' => 'Within 1 week',
|
||||
'2-4-weeks' => '2-4 weeks',
|
||||
'flexible' => 'Flexible timeline'
|
||||
];
|
||||
|
||||
$friendly_timeline = $timeline_names[$timeline] ?? $timeline;
|
||||
|
||||
// Prepare email content
|
||||
$to = 'info@ukdataservices.co.uk';
|
||||
$subject = 'New Quote Request - UK Data Services';
|
||||
|
||||
// Create detailed HTML email
|
||||
$emailHTML = '
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>New Quote Request</title>
|
||||
<style>
|
||||
body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }
|
||||
.container { max-width: 700px; margin: 0 auto; padding: 20px; }
|
||||
.header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 30px; text-align: center; border-radius: 8px 8px 0 0; }
|
||||
.content { background: #f9f9f9; padding: 30px; border-radius: 0 0 8px 8px; }
|
||||
.section { margin-bottom: 30px; padding: 20px; background: white; border-radius: 8px; border-left: 4px solid #667eea; }
|
||||
.section-title { font-size: 18px; font-weight: bold; color: #667eea; margin-bottom: 15px; }
|
||||
.field { margin-bottom: 12px; }
|
||||
.field-label { font-weight: bold; color: #555; }
|
||||
.field-value { margin-top: 5px; padding: 8px; background: #f8f9fa; border-radius: 4px; }
|
||||
.services-list { list-style: none; padding: 0; }
|
||||
.services-list li { padding: 8px; background: #e3f2fd; margin: 5px 0; border-radius: 4px; }
|
||||
.priority { background: #fff3cd; border-left-color: #ffc107; }
|
||||
.contact-info { background: #d4edda; border-left-color: #28a745; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h1>🚀 New Quote Request</h1>
|
||||
<p>UK Data Services</p>
|
||||
<p style="font-size: 14px; opacity: 0.9;">Received: ' . date('Y-m-d H:i:s') . ' UTC</p>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<div class="section contact-info">
|
||||
<div class="section-title">👤 Contact Information</div>
|
||||
<div class="field">
|
||||
<div class="field-label">Name:</div>
|
||||
<div class="field-value">' . htmlspecialchars($name) . '</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="field-label">Email:</div>
|
||||
<div class="field-value">' . htmlspecialchars($email) . '</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="field-label">Company:</div>
|
||||
<div class="field-value">' . htmlspecialchars($company ?: 'Not provided') . '</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="field-label">Phone:</div>
|
||||
<div class="field-value">' . htmlspecialchars($phone ?: 'Not provided') . '</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<div class="section-title">🎯 Services Required</div>
|
||||
<ul class="services-list">';
|
||||
|
||||
foreach ($selected_services as $service) {
|
||||
$emailHTML .= '<li>✓ ' . htmlspecialchars($service) . '</li>';
|
||||
}
|
||||
|
||||
$emailHTML .= '</ul>
|
||||
</div>
|
||||
|
||||
<div class="section ' . ($timeline === 'asap' ? 'priority' : '') . '">
|
||||
<div class="section-title">📊 Project Details</div>
|
||||
<div class="field">
|
||||
<div class="field-label">Project Scale:</div>
|
||||
<div class="field-value">' . htmlspecialchars($friendly_scale) . '</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="field-label">Timeline:</div>
|
||||
<div class="field-value">' . htmlspecialchars($friendly_timeline) . '</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="field-label">Budget Range:</div>
|
||||
<div class="field-value">' . htmlspecialchars($budget ?: 'Not specified') . '</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<div class="section-title">🌐 Data Sources</div>
|
||||
<div class="field-value">' . nl2br(htmlspecialchars($data_sources ?: 'Not specified')) . '</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<div class="section-title">📝 Detailed Requirements</div>
|
||||
<div class="field-value">' . nl2br(htmlspecialchars($requirements)) . '</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<div class="section-title">🔍 Submission Details</div>
|
||||
<div class="field">
|
||||
<div class="field-label">IP Address:</div>
|
||||
<div class="field-value">' . htmlspecialchars($_SERVER['REMOTE_ADDR']) . '</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="field-label">User Agent:</div>
|
||||
<div class="field-value">' . htmlspecialchars($_SERVER['HTTP_USER_AGENT']) . '</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="field-label">Referrer:</div>
|
||||
<div class="field-value">' . htmlspecialchars($_SERVER['HTTP_REFERER'] ?? 'Direct') . '</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>';
|
||||
|
||||
// Email headers
|
||||
$headers = "MIME-Version: 1.0\r\n";
|
||||
$headers .= "Content-Type: text/html; charset=UTF-8\r\n";
|
||||
$headers .= "From: \"UK Data Services Quote System\" <noreply@ukdataservices.co.uk>\r\n";
|
||||
$headers .= "Reply-To: " . $email . "\r\n";
|
||||
$headers .= "X-Mailer: PHP/" . phpversion() . "\r\n";
|
||||
$headers .= "X-Priority: " . ($timeline === 'asap' ? '1' : '3') . "\r\n";
|
||||
|
||||
// Create logs directory if it doesn't exist
|
||||
if (!file_exists('logs')) {
|
||||
mkdir('logs', 0755, true);
|
||||
}
|
||||
|
||||
// Send email
|
||||
try {
|
||||
$emailSent = mail($to, $subject, $emailHTML, $headers);
|
||||
|
||||
if ($emailSent) {
|
||||
// Log successful submission
|
||||
$logEntry = date('Y-m-d H:i:s') . " - Quote request from " . $email . " (" . $_SERVER['REMOTE_ADDR'] . ") - Services: " . implode(', ', $services) . "\n";
|
||||
file_put_contents('logs/quote-requests.log', $logEntry, FILE_APPEND | LOCK_EX);
|
||||
|
||||
// Send detailed auto-reply to user
|
||||
$autoReplySubject = 'Your Quote Request - UK Data Services';
|
||||
$autoReplyHTML = '
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Quote Request Received</title>
|
||||
<style>
|
||||
body { font-family: Arial, sans-serif; line-height: 1.6; color: #333; }
|
||||
.container { max-width: 600px; margin: 0 auto; padding: 20px; }
|
||||
.header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 30px; text-align: center; border-radius: 8px 8px 0 0; }
|
||||
.content { background: #f9f9f9; padding: 30px; border-radius: 0 0 8px 8px; }
|
||||
.highlight-box { background: #e3f2fd; padding: 20px; border-radius: 8px; margin: 20px 0; border-left: 4px solid #667eea; }
|
||||
.cta-box { background: #667eea; color: white; padding: 20px; text-align: center; margin: 20px 0; border-radius: 8px; }
|
||||
.next-steps { background: white; padding: 20px; border-radius: 8px; margin: 20px 0; }
|
||||
.step { display: flex; align-items: flex-start; margin-bottom: 15px; }
|
||||
.step-number { background: #667eea; color: white; width: 30px; height: 30px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: bold; margin-right: 15px; flex-shrink: 0; }
|
||||
.footer { text-align: center; padding: 20px; color: #666; font-size: 14px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h1>✅ Quote Request Received!</h1>
|
||||
<p>UK Data Services</p>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<p>Dear ' . htmlspecialchars($name) . ',</p>
|
||||
|
||||
<p>Thank you for your detailed quote request! We have received your inquiry for <strong>' . implode(', ', $selected_services) . '</strong> and our team is already reviewing your requirements.</p>
|
||||
|
||||
<div class="highlight-box">
|
||||
<h3>📋 Your Request Summary:</h3>
|
||||
<p><strong>Project Scale:</strong> ' . htmlspecialchars($friendly_scale) . '</p>
|
||||
<p><strong>Timeline:</strong> ' . htmlspecialchars($friendly_timeline) . '</p>
|
||||
<p><strong>Services:</strong> ' . implode(', ', $selected_services) . '</p>
|
||||
</div>
|
||||
|
||||
<div class="cta-box">
|
||||
<h3>⏱️ What Happens Next?</h3>
|
||||
<p>Our data specialists will analyze your requirements and prepare a comprehensive proposal within <strong>24 hours</strong>.</p>
|
||||
</div>
|
||||
|
||||
<div class="next-steps">
|
||||
<h3>📝 Our Process:</h3>
|
||||
<div class="step">
|
||||
<div class="step-number">1</div>
|
||||
<div>
|
||||
<strong>Requirements Analysis</strong><br>
|
||||
Our team reviews your project details and data sources
|
||||
</div>
|
||||
</div>
|
||||
<div class="step">
|
||||
<div class="step-number">2</div>
|
||||
<div>
|
||||
<strong>Technical Assessment</strong><br>
|
||||
We evaluate the complexity and create a project plan
|
||||
</div>
|
||||
</div>
|
||||
<div class="step">
|
||||
<div class="step-number">3</div>
|
||||
<div>
|
||||
<strong>Detailed Proposal</strong><br>
|
||||
You receive a comprehensive quote with timeline and deliverables
|
||||
</div>
|
||||
</div>
|
||||
<div class="step">
|
||||
<div class="step-number">4</div>
|
||||
<div>
|
||||
<strong>Consultation Call</strong><br>
|
||||
We schedule a call to discuss your project and answer questions
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>In the meantime, if you have any urgent questions or need to discuss your project immediately, please don\'t hesitate to contact us:</p>
|
||||
|
||||
<ul>
|
||||
<li>📞 <strong>Phone:</strong> +44 1692 689150</li>
|
||||
<li>📧 <strong>Email:</strong> info@ukdataservices.co.uk</li>
|
||||
<li>💬 <strong>Response Time:</strong> Within 24 hours</li>
|
||||
</ul>
|
||||
|
||||
<div class="highlight-box">
|
||||
<h3>🎯 Why Choose UK Data Services?</h3>
|
||||
<p>✓ 99.9% Data Accuracy Guarantee<br>
|
||||
✓ GDPR Compliant & Secure<br>
|
||||
✓ 24/7 Support & Monitoring<br>
|
||||
✓ Scalable Solutions<br>
|
||||
✓ Experienced Team</p>
|
||||
</div>
|
||||
|
||||
<p>We\'re excited to help transform your business with professional data solutions!</p>
|
||||
|
||||
<p>Best regards,<br>
|
||||
<strong>The UK Data Services Team</strong></p>
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<p>UK Data Services | Professional Data Solutions<br>
|
||||
Website: https://ukdataservices.co.uk | Phone: +44 1692 689150</p>
|
||||
<p><small>This is an automated response. Your request has been logged with reference: QR-' . date('Ymd') . '-' . substr(md5($email . time()), 0, 6) . '</small></p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>';
|
||||
|
||||
$autoReplyHeaders = "MIME-Version: 1.0\r\n";
|
||||
$autoReplyHeaders .= "Content-Type: text/html; charset=UTF-8\r\n";
|
||||
$autoReplyHeaders .= "From: \"UK Data Services\" <info@ukdataservices.co.uk>\r\n";
|
||||
$autoReplyHeaders .= "X-Mailer: PHP/" . phpversion() . "\r\n";
|
||||
|
||||
mail($email, $autoReplySubject, $autoReplyHTML, $autoReplyHeaders);
|
||||
|
||||
sendResponse(true, 'Thank you for your quote request! We will send you a detailed proposal within 24 hours.');
|
||||
} else {
|
||||
// Log failed email
|
||||
$logEntry = date('Y-m-d H:i:s') . " - FAILED quote request from " . $email . " (" . $_SERVER['REMOTE_ADDR'] . ")\n";
|
||||
file_put_contents('logs/quote-errors.log', $logEntry, FILE_APPEND | LOCK_EX);
|
||||
|
||||
sendResponse(false, 'There was an error sending your quote request. Please try again or contact us directly.');
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
// Log exception
|
||||
$logEntry = date('Y-m-d H:i:s') . " - EXCEPTION: " . $e->getMessage() . " from " . $email . " (" . $_SERVER['REMOTE_ADDR'] . ")\n";
|
||||
file_put_contents('logs/quote-errors.log', $logEntry, FILE_APPEND | LOCK_EX);
|
||||
|
||||
sendResponse(false, 'There was an error processing your quote request. Please try again later.');
|
||||
}
|
||||
?>
|
||||
Reference in New Issue
Block a user