$entries) { $limits[$key] = array_filter($entries, fn($t) => $now - $t < $windowSeconds); if (empty($limits[$key])) { unset($limits[$key]); } } $count = count($limits[$ip] ?? []); if ($count >= $maxRequests) { return false; } $limits[$ip][] = $now; $dir = dirname($file); if (!is_dir($dir)) { mkdir($dir, 0755, true); } file_put_contents($file, json_encode($limits)); return true; } $action = $_GET['action'] ?? ''; switch ($action) { case 'contact': if ($_SERVER['REQUEST_METHOD'] !== 'POST') { http_response_code(405); echo json_encode(['error' => 'Method not allowed']); exit; } // Honeypot if (!empty($_POST['website'])) { echo json_encode(['success' => true]); exit; } // Rate limit $ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown'; if (!checkRateLimit($ip)) { http_response_code(429); echo json_encode(['error' => 'Liian monta viestiä. Yritä myöhemmin uudelleen.']); exit; } // Validate $name = trim($_POST['name'] ?? ''); $company = trim($_POST['company'] ?? ''); $email = trim($_POST['email'] ?? ''); $phone = trim($_POST['phone'] ?? ''); $message = trim($_POST['message'] ?? ''); if (!$name || !$email || !$message) { echo json_encode(['error' => 'Täytä kaikki pakolliset kentät.']); exit; } if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { echo json_encode(['error' => 'Tarkista sähköpostiosoite.']); exit; } // Save to file $contactFile = __DIR__ . '/data/contacts.json'; $contacts = []; if (file_exists($contactFile)) { $contacts = json_decode(file_get_contents($contactFile), true) ?: []; } $contacts[] = [ 'id' => uniqid(), 'name' => $name, 'company' => $company, 'email' => $email, 'phone' => $phone, 'message' => $message, 'ip' => $ip, 'created_at' => date('Y-m-d H:i:s') ]; $dir = dirname($contactFile); if (!is_dir($dir)) { mkdir($dir, 0755, true); } file_put_contents($contactFile, json_encode($contacts, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)); // Send email $to = 'asiakaspalvelu@konesaliturku.fi'; $subject = 'Yhteydenotto: ' . $name . ($company ? " ($company)" : ''); $body = "Uusi yhteydenotto konesaliturku.fi:n kautta\n\n"; $body .= "Nimi: $name\n"; if ($company) $body .= "Yritys: $company\n"; $body .= "Sähköposti: $email\n"; if ($phone) $body .= "Puhelin: $phone\n"; $body .= "\nViesti:\n$message\n"; $headers = "From: noreply@konesaliturku.fi\r\n"; $headers .= "Reply-To: $email\r\n"; $headers .= "Content-Type: text/plain; charset=UTF-8\r\n"; @mail($to, $subject, $body, $headers); echo json_encode(['success' => true]); break; case 'quote': if ($_SERVER['REQUEST_METHOD'] !== 'POST') { http_response_code(405); echo json_encode(['error' => 'Method not allowed']); exit; } // Honeypot if (!empty($_POST['website'])) { echo json_encode(['success' => true]); exit; } // Rate limit $ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown'; if (!checkRateLimit($ip)) { http_response_code(429); echo json_encode(['error' => 'Liian monta pyyntöä. Yritä myöhemmin uudelleen.']); exit; } // Captcha $captcha = trim($_POST['captcha'] ?? ''); $captchaAnswer = trim($_POST['captcha_answer'] ?? ''); if (!$captcha || $captcha !== $captchaAnswer) { echo json_encode(['error' => 'Väärä vastaus varmistuskysymykseen.']); exit; } // Validate $name = trim($_POST['name'] ?? ''); $email = trim($_POST['email'] ?? ''); if (!$email) { echo json_encode(['error' => 'Sähköposti on pakollinen.']); exit; } if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { echo json_encode(['error' => 'Tarkista sähköpostiosoite.']); exit; } // Collect form data $company = trim($_POST['company'] ?? ''); $phone = trim($_POST['phone'] ?? ''); $message = trim($_POST['message'] ?? ''); // Laitepaikat $units1u = intval($_POST['units_1u'] ?? 0); $units2u = intval($_POST['units_2u'] ?? 0); $units4u = intval($_POST['units_4u'] ?? 0); $unitsRack = intval($_POST['units_rack'] ?? 0); // Yhteys $connection = $_POST['connection'] ?? '0'; $redundantPort = !empty($_POST['redundant_port']); $bgp = intval($_POST['bgp'] ?? 0); // VPN $vpn = $_POST['vpn'] ?? '0'; // Lisäpalvelut $anycastDns = !empty($_POST['anycast_dns']); $blockStorage = !empty($_POST['block_storage']); $s3Storage = !empty($_POST['s3_storage']); $remoteHands = !empty($_POST['remote_hands']); // Build email body $body = "Uusi tarjouspyyntö konesaliturku.fi:n kautta\n"; $body .= str_repeat('=', 50) . "\n\n"; $body .= "YHTEYSTIEDOT\n"; $body .= "Nimi: $name\n"; if ($company) $body .= "Yritys: $company\n"; $body .= "Sähköposti: $email\n"; if ($phone) $body .= "Puhelin: $phone\n"; $body .= "\n"; // Laitepaikat $body .= "LAITEPAIKAT\n"; if ($units1u) $body .= " 1U laitepaikka: {$units1u} kpl (á €49/kk)\n"; if ($units2u) $body .= " 2U laitepaikka: {$units2u} kpl (á €79/kk)\n"; if ($units4u) $body .= " 4U laitepaikka: {$units4u} kpl (á €139/kk)\n"; if ($unitsRack) $body .= " Kokokaappi (42U): {$unitsRack} kpl\n"; if (!$units1u && !$units2u && !$units4u && !$unitsRack) $body .= " Ei valittu\n"; $body .= "\n"; // Yhteys $body .= "YHTEYS\n"; $connLabels = [ '0' => '1 Gbit/s jaettu (sis. hintaan)', '99' => '1 Gbit/s dedicated (€99/kk)', '299' => '10 Gbit/s dedicated (€299/kk)', 'custom' => '100 Gbit/s (räätälöity)', ]; $body .= " Nopeus: " . ($connLabels[$connection] ?? 'Ei valittu') . "\n"; if ($redundantPort) $body .= " Varmennettu portti: Kyllä (€10/kk)\n"; if ($bgp === 20) $body .= " BGP-reititys: Default-route (€20/kk)\n"; if ($bgp === 50) $body .= " BGP-reititys: Koko internet (€50/kk)\n"; $body .= "\n"; // VPN $vpnLabels = [ '0' => null, '95' => '1G Site-to-Site (alk. €95/kk)', '129' => '10G Site-to-Site (alk. €129/kk)', 'custom' => 'Dedicated L2/MPLS (räätälöity)', ]; if ($vpn !== '0' && isset($vpnLabels[$vpn])) { $body .= "VPN\n"; $body .= " " . $vpnLabels[$vpn] . "\n\n"; } // Lisäpalvelut $addons = []; if ($anycastDns) $addons[] = 'Anycast DNS (€19/kk)'; if ($blockStorage) $addons[] = 'Blokkitason storage (alk. €29/kk)'; if ($s3Storage) $addons[] = 'S3-levypinta (alk. €19/kk)'; if ($remoteHands) $addons[] = 'Remote Hands (tuntiveloitus)'; if ($addons) { $body .= "LISÄPALVELUT\n"; foreach ($addons as $a) $body .= " $a\n"; $body .= "\n"; } if ($message) { $body .= "VIESTI\n$message\n\n"; } $body .= str_repeat('-', 50) . "\n"; $body .= "IP: $ip | Aika: " . date('d.m.Y H:i:s') . "\n"; // Save to file $quoteFile = __DIR__ . '/data/quotes.json'; $quotes = []; if (file_exists($quoteFile)) { $quotes = json_decode(file_get_contents($quoteFile), true) ?: []; } $quotes[] = [ 'id' => uniqid(), 'name' => $name, 'company' => $company, 'email' => $email, 'phone' => $phone, 'units_1u' => $units1u, 'units_2u' => $units2u, 'units_4u' => $units4u, 'units_rack' => $unitsRack, 'connection' => $connection, 'redundant_port' => $redundantPort, 'bgp' => $bgp, 'vpn' => $vpn, 'anycast_dns' => $anycastDns, 'block_storage' => $blockStorage, 's3_storage' => $s3Storage, 'remote_hands' => $remoteHands, 'message' => $message, 'ip' => $ip, 'created_at' => date('Y-m-d H:i:s') ]; $dir = dirname($quoteFile); if (!is_dir($dir)) { mkdir($dir, 0755, true); } file_put_contents($quoteFile, json_encode($quotes, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)); // Send email $to = 'asiakaspalvelu@konesaliturku.fi'; $subject = 'Tarjouspyyntö: ' . $name . ($company ? " ($company)" : ''); $headers = "From: noreply@konesaliturku.fi\r\n"; $headers .= "Reply-To: $email\r\n"; $headers .= "Content-Type: text/plain; charset=UTF-8\r\n"; $mailSent = mail($to, $subject, $body, $headers); echo json_encode(['success' => true, 'mail_sent' => $mailSent]); break; default: http_response_code(404); echo json_encode(['error' => 'Unknown action']); break; }