WebOrbiton
v3.0.0.0

FlatlyPage

209 lines · 6.8 KB
  1. <?php
  2. require_once __DIR__ . '/config.php';
  3. $site_settings = get_site_settings();
  4. if (session_status() === PHP_SESSION_NONE) {
  5. session_start();
  6. }
  7. function generate_form_token() {
  8. $token = bin2hex(random_bytes(32));
  9. $_SESSION['form_token'] = hash('sha256', $token);
  10. $_SESSION['form_token_time'] = time();
  11. return $token;
  12. }
  13. function validate_form_token($submitted) {
  14. if (empty($submitted) || empty($_SESSION['form_token'])) {
  15. return false;
  16. }
  17. if (time() - ($_SESSION['form_token_time'] ?? 0) > 1800) {
  18. return false;
  19. }
  20. $valid = hash_equals($_SESSION['form_token'], hash('sha256', $submitted));
  21. if ($valid) {
  22. unset($_SESSION['form_token'], $_SESSION['form_token_time']);
  23. }
  24. return $valid;
  25. }
  26. function validate_contact_form($data) {
  27. $errors = [];
  28. if (!empty($data['website'])) {
  29. $errors['_honeypot'] = 'Bot detected';
  30. return $errors;
  31. }
  32. $load_time = intval($data['_lt'] ?? 0);
  33. if (time() - $load_time < 3 || time() - $load_time > 3600) {
  34. $errors['_time'] = 'Please take a moment before submitting';
  35. }
  36. if (!validate_form_token($data['_token'] ?? '')) {
  37. $errors['_token'] = 'Invalid form token, please refresh the page';
  38. }
  39. $antibot_input = strtoupper(trim($data['antibot'] ?? ''));
  40. $antibot_answer = strtoupper($_SESSION['antibot_answer'] ?? '');
  41. $antibot_age = time() - intval($_SESSION['antibot_time'] ?? 0);
  42. if (empty($antibot_answer) || $antibot_age > 1800) {
  43. $errors['antibot'] = 'ANTIBOT expired, please refresh the image';
  44. } elseif ($antibot_input !== $antibot_answer) {
  45. $errors['antibot'] = 'Incorrect code, please try again';
  46. } else {
  47. unset($_SESSION['antibot_answer'], $_SESSION['antibot_time']);
  48. }
  49. if (empty($data['name'])) {
  50. $errors['name'] = 'Name is required';
  51. } elseif (strlen($data['name']) > 100) {
  52. $errors['name'] = 'Name cannot exceed 100 characters';
  53. }
  54. if (empty($data['email'])) {
  55. $errors['email'] = 'Email is required';
  56. } elseif (!filter_var($data['email'], FILTER_VALIDATE_EMAIL)) {
  57. $errors['email'] = 'Invalid email format';
  58. }
  59. if (empty($data['message'])) {
  60. $errors['message'] = 'Message is required';
  61. } elseif (strlen($data['message']) > 5000) {
  62. $errors['message'] = 'Message cannot exceed 5000 characters';
  63. }
  64. return $errors;
  65. }
  66. function send_contact_email($name, $email, $message) {
  67. $to = get_site_settings()['contact_email'];
  68. $subject = "New Message from " . get_site_settings()['site_name'] . " Contact Form";
  69. $email_body = "You have received a new message from the contact form.\n\n";
  70. $email_body .= "- - - - - - MESSAGE DETAILS - - - - - - \n";
  71. $email_body .= "Name: " . $name . "\n";
  72. $email_body .= "Email: " . $email . "\n\n";
  73. $email_body .= "Message:\n" . wordwrap($message, 72) . "\n";
  74. $email_body .= "- - - - - - - - - - - - - - - \n";
  75. $email_body .= "Sent on: " . date('Y-m-d H:i:s') . "\n";
  76. $email_body .= "Automated message from " . get_site_settings()['site_name'] . "\n";
  77. $headers = "From: " . $email . "\r\n";
  78. $headers .= "Reply-To: " . $email . "\r\n";
  79. $headers .= "Content-Type: text/plain; charset=UTF-8\r\n";
  80. return mail($to, $subject, $email_body, $headers);
  81. }
  82. function save_contact_to_file($name, $email, $message) {
  83. $log_dir = __DIR__ . '/contacts';
  84. if (!is_dir($log_dir)) {
  85. mkdir($log_dir, 0755, true);
  86. }
  87. $filename = $log_dir . '/contacts_' . date('Y-m') . '.txt';
  88. $log_entry = "\n" . str_repeat('-', 50) . "\n";
  89. $log_entry .= "Date: " . date('Y-m-d H:i:s') . "\n";
  90. $log_entry .= "Name: " . $name . "\n";
  91. $log_entry .= "Email: " . $email . "\n";
  92. $log_entry .= "Message:\n" . $message . "\n";
  93. $log_entry .= str_repeat('-', 50) . "\n";
  94. return file_put_contents($filename, $log_entry, FILE_APPEND | LOCK_EX);
  95. }
  96. if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  97. $name = trim($_POST['name'] ?? '');
  98. $email = trim($_POST['email'] ?? '');
  99. $message = trim($_POST['message'] ?? '');
  100. $errors = validate_contact_form([
  101. 'name' => $name,
  102. 'email' => $email,
  103. 'message' => $message,
  104. 'website' => $_POST['website'] ?? '',
  105. '_lt' => $_POST['_lt'] ?? 0,
  106. '_token' => $_POST['_token'] ?? '',
  107. 'antibot' => $_POST['antibot'] ?? '',
  108. ]);
  109. $spam_keys = ['_honeypot', '_time', '_token'];
  110. $is_spam = false;
  111. foreach ($spam_keys as $k) {
  112. if (isset($errors[$k])) {
  113. $is_spam = true;
  114. break;
  115. }
  116. }
  117. if ($is_spam) {
  118. $_SESSION['contact_success'] = true;
  119. header('Location: ' . $_SERVER['PHP_SELF'] . '?slug=' . ($slug ?? 'contact') . '&success=1');
  120. exit;
  121. }
  122. $user_errors = array_diff_key($errors, array_flip($spam_keys));
  123. if (empty($user_errors)) {
  124. save_contact_to_file($name, $email, $message);
  125. $email_sent = send_contact_email($name, $email, $message);
  126. if ($email_sent) {
  127. $_SESSION['contact_success'] = true;
  128. header('Location: ' . $_SERVER['PHP_SELF'] . '?slug=' . ($slug ?? 'contact') . '&success=1');
  129. exit;
  130. } else {
  131. $_SESSION['contact_error'] = 'An error occurred while sending the message. Please try again later.';
  132. }
  133. } else {
  134. $_SESSION['contact_errors'] = $user_errors;
  135. $_SESSION['contact_data'] = [
  136. 'name' => $name,
  137. 'email' => $email,
  138. 'message' => $message,
  139. ];
  140. }
  141. }
  142. $_SESSION['form_token_raw'] = generate_form_token();
  143. function get_contact_message() {
  144. if (isset($_GET['success']) && $_GET['success'] == '1') {
  145. return [
  146. 'type' => 'success',
  147. 'text' => 'Thank you for your message! We will respond as soon as possible.',
  148. ];
  149. }
  150. if (isset($_SESSION['contact_error'])) {
  151. $error = $_SESSION['contact_error'];
  152. unset($_SESSION['contact_error']);
  153. return ['type' => 'error', 'text' => $error];
  154. }
  155. return null;
  156. }
  157. function get_contact_data($field) {
  158. if (isset($_SESSION['contact_data'][$field])) {
  159. $value = $_SESSION['contact_data'][$field];
  160. return htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
  161. }
  162. return '';
  163. }
  164. function get_contact_error($field) {
  165. if (isset($_SESSION['contact_errors'][$field])) {
  166. return $_SESSION['contact_errors'][$field];
  167. }
  168. return '';
  169. }
  170. if (isset($_SESSION['contact_errors']) || isset($_SESSION['contact_data'])) {
  171. register_shutdown_function(function () {
  172. unset($_SESSION['contact_errors']);
  173. unset($_SESSION['contact_data']);
  174. });
  175. }