Files

118 lines
4.1 KiB
PHP

<?php
/**
* HELP4BIS Contact Form Handler
* Receives JSON POST from main.js, sends via local mail transport (sendmail).
* Handles fields from contact.html and sos-fix.html.
* MAIL_TO/MAIL_FROM can be overridden via /home/help4bis/.env if present.
*/
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: https://help4bis.com');
header('Access-Control-Allow-Methods: POST');
// Only accept POST
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
echo json_encode(['ok' => false, 'error' => 'Method not allowed']);
exit;
}
// Load .env
$env = [];
$envFile = '/home/help4bis/.env';
if (file_exists($envFile)) {
foreach (file($envFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $line) {
if (str_starts_with(trim($line), '#') || !str_contains($line, '=')) continue;
[$key, $val] = explode('=', $line, 2);
$env[trim($key)] = trim($val);
}
}
// Parse JSON body
$data = json_decode(file_get_contents('php://input'), true);
if (!$data) {
// Fall back to form-encoded
$data = $_POST;
}
// Spam check (cockpit #164). Bots fill the hidden hp_trap field or post straight to this
// handler without the fill time the page script adds, or submit faster than a person can type.
// Answer ok so the bot learns nothing, send nothing, and leave one log line to measure with.
$fillMs = $data['fill_ms'] ?? null;
if (!empty($data['hp_trap']) || !is_numeric($fillMs) || (float)$fillMs < 3000) {
error_log('HELP4BIS contact form: spam dropped (' . (!empty($data['hp_trap']) ? 'honeypot' : (!is_numeric($fillMs) ? 'no fill time' : 'too fast')) . ')');
echo json_encode(['ok' => true]);
exit;
}
// Sanitise and validate required fields
$name = trim(strip_tags($data['name'] ?? ''));
$email = trim(strip_tags($data['email'] ?? ''));
$service = trim(strip_tags($data['service'] ?? ''));
$budget = trim(strip_tags($data['budget'] ?? ''));
$timeline = trim(strip_tags($data['timeline'] ?? ''));
// Message field — normalise across all forms
$message = trim(strip_tags($data['message'] ?? $data['details'] ?? $data['description'] ?? ''));
// sos-fix.html specific fields
$source = trim(strip_tags($data['source'] ?? ''));
$url = trim(strip_tags($data['url'] ?? ''));
$issue_type = trim(strip_tags($data['issue_type'] ?? ''));
$wp_access = trim(strip_tags($data['wp_access'] ?? ''));
$urgency = trim(strip_tags($data['urgency'] ?? ''));
if (!$name || !$email || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
http_response_code(422);
echo json_encode(['ok' => false, 'error' => 'Name and a valid email address are required.']);
exit;
}
// Build email subject
$subject = $source === 'sos-fix'
? "SOS Fix request from {$name}" . ($issue_type ? " — {$issue_type}" : '')
: "New brief from {$name}" . ($service ? " — {$service}" : '');
// Build email body
$body = "Name: {$name}\n";
$body .= "Email: {$email}\n";
if ($source) $body .= "Source: {$source}\n";
if ($url) $body .= "Website: {$url}\n";
if ($service) $body .= "Service: {$service}\n";
if ($issue_type) $body .= "Issue type: {$issue_type}\n";
if ($budget) $body .= "Budget: {$budget}\n";
if ($timeline) $body .= "Timeline: {$timeline}\n";
if ($wp_access) $body .= "WP access: {$wp_access}\n";
if ($urgency) $body .= "Urgency: {$urgency}\n";
$body .= "\n--- Message ---\n{$message}\n";
// PHPMailer
require __DIR__ . '/vendor/autoload.php';
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
$mail = new PHPMailer(true);
try {
$mail->isMail();
$mail->setFrom($env['MAIL_FROM'] ?? 'project@help4bis.com', $env['SMTP_FROM_NAME'] ?? 'HELP4BIS');
$mail->addAddress($env['MAIL_TO'] ?? 'project@help4bis.com');
$mail->addReplyTo($email, $name);
$mail->Subject = $subject;
$mail->Body = $body;
$mail->send();
echo json_encode(['ok' => true]);
} catch (Exception $e) {
error_log('HELP4BIS contact form mailer error: ' . $mail->ErrorInfo);
http_response_code(500);
echo json_encode(['ok' => false, 'error' => 'Mail could not be sent. Please email project@help4bis.com directly.']);
}