Fix forms: return JSON instead of redirect for AJAX compatibility

- send_plan.php: replace redirect with JSON response
- send_ask.php: replace redirect with JSON response
- Fixes white page issue (fetch API doesn't follow redirects)
- Update .gitignore: allow forms folder but protect .env file
This commit is contained in:
Kirik
2025-10-27 15:35:46 +01:00
parent a34a81e0a1
commit 776dbb5e76
7 changed files with 782 additions and 1 deletions
+1 -1
View File
@@ -45,7 +45,7 @@ gitea.pub
telegram/
migration-s3/
INFO/
forms/
forms/.env
# Debug and test pages - не для продакшена
static/debug-*.html
+304
View File
@@ -0,0 +1,304 @@
<?php
/**
* Вспомогательные функции для обработки форм
* Поддержка настроек из .env файла
*/
/**
* Загрузка переменных из .env файла
*/
function load_env_file($file_path = '../.env') {
if (!file_exists($file_path)) {
return false;
}
$lines = file($file_path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($lines as $line) {
if (strpos(trim($line), '#') === 0) {
continue; // Пропускаем комментарии
}
list($name, $value) = explode('=', $line, 2);
$name = trim($name);
$value = trim($value);
if (!array_key_exists($name, $_SERVER) && !array_key_exists($name, $_ENV)) {
putenv(sprintf('%s=%s', $name, $value));
$_ENV[$name] = $value;
$_SERVER[$name] = $value;
}
}
return true;
}
/**
* Получение настроек форм из .env
*/
function get_forms_settings() {
return [
'send_email' => getenv('FORMS_SEND_EMAIL') === 'true',
'send_telegram' => getenv('FORMS_SEND_TELEGRAM') === 'true',
'save_json' => getenv('FORMS_SAVE_JSON') === 'true',
'notifications' => getenv('FORMS_NOTIFICATIONS') === 'true',
'telegram_bot_token' => getenv('TELEGRAM_BOT_TOKEN'),
'telegram_chat_id' => getenv('TELEGRAM_ADMIN_CHAT_ID'),
'encryption_key' => getenv('FORMS_ENCRYPTION_KEY') ?: 'default_key_change_me'
];
}
/**
* Простое шифрование данных для безопасного хранения
*/
function encrypt_data($data, $key) {
$json = json_encode($data, JSON_UNESCAPED_UNICODE);
$iv = random_bytes(16);
$encrypted = openssl_encrypt($json, 'AES-256-CBC', hash('sha256', $key), 0, $iv);
return base64_encode($iv . $encrypted);
}
/**
* Расшифровка данных
*/
function decrypt_data($encrypted_data, $key) {
$data = base64_decode($encrypted_data);
$iv = substr($data, 0, 16);
$encrypted = substr($data, 16);
$decrypted = openssl_decrypt($encrypted, 'AES-256-CBC', hash('sha256', $key), 0, $iv);
return json_decode($decrypted, true);
}
/**
* Сохранение заявки в зашифрованный JSON файл
*/
function save_application_to_json($form_data, $form_type) {
$settings = get_forms_settings();
if (!$settings['save_json']) {
return true; // Сохранение отключено
}
// Создаем безопасную директорию для хранения (вне веб-доступа)
$secure_dir = '/var/secure/forms/';
if (!is_dir($secure_dir)) {
mkdir($secure_dir, 0700, true);
}
// Подготавливаем данные для сохранения
$application = [
'id' => uniqid('app_'),
'type' => $form_type,
'timestamp' => date('Y-m-d H:i:s'),
'data' => $form_data,
'status' => 'new'
];
try {
// Шифруем данные
$encrypted_data = encrypt_data($application, $settings['encryption_key']);
// Сохраняем в файл с временной меткой
$filename = $secure_dir . $form_type . '_' . date('Y-m-d') . '.json';
// Загружаем существующие данные или создаем новый массив
$existing_data = [];
if (file_exists($filename)) {
$file_content = file_get_contents($filename);
if ($file_content) {
$existing_data = json_decode($file_content, true) ?: [];
}
}
// Добавляем новую заявку
$existing_data[] = [
'id' => $application['id'],
'timestamp' => $application['timestamp'],
'encrypted_data' => $encrypted_data
];
// Сохраняем обновленный файл
file_put_contents($filename, json_encode($existing_data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
chmod($filename, 0600); // Только владелец может читать
return $application['id'];
} catch (Exception $e) {
error_log("Ошибка сохранения заявки: " . $e->getMessage());
return false;
}
}
/**
* Отправка уведомления в Telegram
*/
function send_telegram_notification($form_data, $form_type) {
$settings = get_forms_settings();
if (!$settings['send_telegram'] || !$settings['notifications']) {
return true; // Отправка отключена
}
if (empty($settings['telegram_bot_token']) || empty($settings['telegram_chat_id'])) {
error_log("Telegram настройки не настроены");
return false;
}
// Подготавливаем сообщение
$message = "🔔 *Новая заявка*\n\n";
$message .= "📝 *Тип:* " . ($form_type === 'plan' ? 'Заявка на поездку' : 'Вопрос') . "\n";
$message .= "👤 *Имя:* " . $form_data['name'] . "\n";
$message .= "📧 *Email:* " . $form_data['email'] . "\n";
if ($form_type === 'plan') {
$message .= "📱 *Телефон:* " . ($form_data['phone'] ?: 'не указан') . "\n";
$message .= "✈️ *Поездка:* " . ($form_data['trip_period'] ?: 'не выбрана') . "\n";
$message .= "🚁 *БВС/Направление:* " . ($form_data['bvs_number'] ?: 'не указано') . "\n";
} else {
if (!empty($form_data['telegram'])) {
$message .= "📱 *Telegram:* " . $form_data['telegram'] . "\n";
}
if (!empty($form_data['phone'])) {
$message .= "☎️ *Телефон:* " . $form_data['phone'] . "\n";
}
$message .= "💬 *Тема:* " . $form_data['subject'] . "\n";
$message .= "📝 *Сообщение:* " . substr($form_data['message'], 0, 200) . "...\n";
}
$message .= "\n⏰ *Время:* " . date('Y-m-d H:i:s');
// Отправляем сообщение
$url = "https://api.telegram.org/bot" . $settings['telegram_bot_token'] . "/sendMessage";
$data = [
'chat_id' => $settings['telegram_chat_id'],
'text' => $message,
'parse_mode' => 'Markdown'
];
$context = stream_context_create([
'http' => [
'method' => 'POST',
'header' => 'Content-Type: application/x-www-form-urlencoded',
'content' => http_build_query($data)
]
]);
try {
$result = file_get_contents($url, false, $context);
$response = json_decode($result, true);
if ($response && $response['ok']) {
return true;
} else {
error_log("Ошибка отправки в Telegram: " . $result);
return false;
}
} catch (Exception $e) {
error_log("Исключение при отправке в Telegram: " . $e->getMessage());
return false;
}
}
/**
* Получение списка всех заявок (для Telegram бота)
*/
function get_all_applications() {
$settings = get_forms_settings();
$secure_dir = '/var/secure/forms/';
if (!is_dir($secure_dir)) {
return [];
}
$applications = [];
$files = glob($secure_dir . '*.json');
foreach ($files as $file) {
$file_content = file_get_contents($file);
if (!$file_content) continue;
$file_data = json_decode($file_content, true);
if (!$file_data) continue;
foreach ($file_data as $item) {
try {
$decrypted = decrypt_data($item['encrypted_data'], $settings['encryption_key']);
$applications[] = $decrypted;
} catch (Exception $e) {
error_log("Ошибка расшифровки заявки: " . $e->getMessage());
}
}
}
// Сортируем по времени (новые сначала)
usort($applications, function($a, $b) {
return strtotime($b['timestamp']) - strtotime($a['timestamp']);
});
return $applications;
}
/**
* Отметить заявку как рассмотренную
*/
function mark_application_as_reviewed($app_id) {
$settings = get_forms_settings();
$secure_dir = '/var/secure/forms/';
$files = glob($secure_dir . '*.json');
foreach ($files as $file) {
$file_content = file_get_contents($file);
if (!$file_content) continue;
$file_data = json_decode($file_content, true);
if (!$file_data) continue;
$updated = false;
foreach ($file_data as &$item) {
try {
$decrypted = decrypt_data($item['encrypted_data'], $settings['encryption_key']);
if ($decrypted['id'] === $app_id) {
$decrypted['status'] = 'reviewed';
$item['encrypted_data'] = encrypt_data($decrypted, $settings['encryption_key']);
$updated = true;
break;
}
} catch (Exception $e) {
continue;
}
}
if ($updated) {
file_put_contents($file, json_encode($file_data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
return true;
}
}
return false;
}
/**
* Очистка старых заявок (старше 30 дней)
*/
function cleanup_old_applications() {
$secure_dir = '/var/secure/forms/';
if (!is_dir($secure_dir)) return;
$files = glob($secure_dir . '*.json');
$cutoff_date = strtotime('-30 days');
foreach ($files as $file) {
// Извлекаем дату из имени файла
if (preg_match('/(\d{4}-\d{2}-\d{2})\.json$/', $file, $matches)) {
$file_date = strtotime($matches[1]);
if ($file_date < $cutoff_date) {
unlink($file);
error_log("Удален старый файл заявок: " . basename($file));
}
}
}
}
// Автоматическая очистка старых файлов (вызывается при каждом обращении к формам)
if (rand(1, 100) === 1) { // 1% вероятность
cleanup_old_applications();
}
?>
+116
View File
@@ -0,0 +1,116 @@
<?php
require_once 'forms_helper.php';
// Загружаем настройки из .env
load_env_file(__DIR__ . '/.env');
$settings = get_forms_settings();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$name = trim($_POST['name'] ?? '');
$email = trim($_POST['email'] ?? '');
$telegram = trim($_POST['telegram'] ?? '');
$phone = trim($_POST['phone'] ?? '');
$subject = trim($_POST['subject'] ?? '');
$message = trim($_POST['message'] ?? '');
// Валидация
if (empty($name) || empty($subject) || empty($message)) {
$error = "Имя, тема и сообщение обязательны для заполнения.";
} elseif (empty($email) && empty($telegram)) {
$error = "Укажите email или Telegram ник (одно из двух обязательно).";
} elseif (!empty($email) && !filter_var($email, FILTER_VALIDATE_EMAIL)) {
$error = "Некорректный email адрес.";
} else {
// Подготавливаем данные заявки
$form_data = [
'name' => $name,
'email' => $email,
'telegram' => $telegram,
'phone' => $phone,
'subject' => $subject,
'message' => $message
];
$success_messages = [];
$error_messages = [];
// 1. Отправка email (если включено)
if ($settings['send_email']) {
$to = getenv('FORMS_MAIN_EMAIL') ?: "sleeptrip@mail.ru";
$email_subject = "Вопрос с сайта: " . $subject;
$email_body = "Новый вопрос с сайта:\n\n";
$email_body .= "Имя: " . $name . "\n";
$email_body .= "Email: " . ($email ?: 'не указан') . "\n";
$email_body .= "Telegram: " . ($telegram ?: 'не указан') . "\n";
$email_body .= "Телефон: " . ($phone ?: 'не указан') . "\n";
$email_body .= "Тема: " . $subject . "\n\n";
$email_body .= "Сообщение:\n" . $message . "\n\n";
$email_body .= "---\n";
$email_body .= "Отправлено с: " . $_SERVER['HTTP_HOST'] . "\n";
$email_body .= "Дата: " . date('Y-m-d H:i:s') . "\n";
$from_email = getenv('FORMS_FROM_EMAIL') ?: 'noreply@sleeptrip.ru';
$headers = "From: " . $from_email . "\r\n";
if (!empty($email)) {
$headers .= "Reply-To: " . $email . "\r\n";
}
$headers .= "X-Mailer: PHP/" . phpversion();
$headers .= "Content-Type: text/plain; charset=UTF-8\r\n";
if (mail($to, $email_subject, $email_body, $headers)) {
$success_messages[] = "Email отправлен";
} else {
$error_messages[] = "Ошибка отправки email";
}
}
// 2. Сохранение в JSON (если включено)
if ($settings['save_json']) {
$json_saved = save_application_to_json($form_data, 'ask');
if ($json_saved) {
$success_messages[] = "Вопрос сохранен";
} else {
$error_messages[] = "Ошибка сохранения вопроса";
}
}
// 3. Уведомление в Telegram (если включено)
if ($settings['send_telegram'] && $settings['notifications']) {
$telegram_sent = send_telegram_notification($form_data, 'ask');
if ($telegram_sent) {
$success_messages[] = "Уведомление отправлено";
} else {
$error_messages[] = "Ошибка уведомления в Telegram";
}
}
// Формируем итоговое сообщение
if (!empty($success_messages)) {
$success = "Сообщение отправлено! Мы ответим вам в ближайшее время.";
// Очистить форму
$name = $email = $telegram = $phone = $subject = $message = '';
}
if (!empty($error_messages) && empty($success_messages)) {
$error = "Ошибка отправки. Попробуйте еще раз или свяжитесь через Telegram.";
}
}
}
// Возвращаем JSON для AJAX совместимости
if (isset($success)) {
header('Content-Type: application/json; charset=utf-8');
echo json_encode([
'success' => true,
'message' => $success
], JSON_UNESCAPED_UNICODE);
exit;
} elseif (isset($error)) {
header('Content-Type: application/json; charset=utf-8');
echo json_encode([
'success' => false,
'error' => $error
], JSON_UNESCAPED_UNICODE);
exit;
}
?>
+115
View File
@@ -0,0 +1,115 @@
<?php
// Проверка расширений PHP
if (!extension_loaded('openssl')) {
die('OpenSSL extension required for PDF encryption');
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$name = trim($_POST['name'] ?? '');
$email = trim($_POST['email'] ?? '');
$subject = trim($_POST['subject'] ?? '');
$message = trim($_POST['message'] ?? '');
// Валидация
if (empty($name) || empty($email) || empty($subject) || empty($message)) {
$error = "Все поля обязательны для заполнения.";
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$error = "Некорректный email адрес.";
} else {
// Функция создания зашифрованного PDF
function createEncryptedPDF($data, $password = null) {
// Если пароль не указан, генерируем случайный
if (!$password) {
$password = bin2hex(random_bytes(8));
}
// Создаем простой PDF контент
$pdf_content = "%PDF-1.4\n";
$pdf_content .= "1 0 obj\n<< /Type /Catalog /Pages 2 0 R >>\nendobj\n";
$pdf_content .= "2 0 obj\n<< /Type /Pages /Kids [3 0 R] /Count 1 >>\nendobj\n";
$pdf_content .= "3 0 obj\n<< /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792] /Contents 4 0 R >>\nendobj\n";
$pdf_content .= "4 0 obj\n<< /Length " . strlen($data) . " >>\nstream\n";
$pdf_content .= "BT /F1 12 Tf 72 720 Td (" . $data . ") Tj ET\n";
$pdf_content .= "endstream\nendobj\n";
$pdf_content .= "xref\n0 5\n0000000000 65535 f \n0000000010 00000 n \n0000000053 00000 n \n0000000125 00000 n \n0000000202 00000 n \n";
$pdf_content .= "trailer\n<< /Size 5 /Root 1 0 R >>\nstartxref\n" . strlen($pdf_content) . "\n%%EOF";
// Шифруем содержимое
$encrypted = openssl_encrypt($pdf_content, 'AES-256-CBC', $password, 0, substr(hash('sha256', $password), 0, 16));
return ['content' => $encrypted, 'password' => $password];
}
// Подготовка данных для PDF
$pdf_data = "Вопрос с сайта\n\n";
$pdf_data .= "Имя: " . $name . "\n";
$pdf_data .= "Email: " . $email . "\n";
$pdf_data .= "Тема: " . $subject . "\n\n";
$pdf_data .= "Сообщение:\n" . $message . "\n\n";
$pdf_data .= "Дата отправки: " . date('Y-m-d H:i:s') . "\n";
// Создаем зашифрованный PDF
$encrypted_pdf = createEncryptedPDF($pdf_data);
// Подготовка email
$to = "test@yourdomain.com"; // ЗАМЕНИТЕ на ваш тестовый email!
$email_subject = "Вопрос с сайта: " . $subject;
$email_body = "Новый вопрос с сайта:\n\n";
$email_body .= "Имя: " . $name . "\n";
$email_body .= "Email: " . $email . "\n";
$email_body .= "Тема: " . $subject . "\n\n";
$email_body .= "Сообщение:\n" . $message . "\n\n";
$email_body .= "К письму приложен зашифрованный PDF файл с данными сообщения.\n";
$email_body .= "Пароль для расшифровки: " . $encrypted_pdf['password'] . "\n\n";
$email_body .= "---\n";
$email_body .= "Отправлено с: " . $_SERVER['HTTP_HOST'] . "\n";
$email_body .= "Дата: " . date('Y-m-d H:i:s') . "\n";
$email_body .= "IP: " . $_SERVER['REMOTE_ADDR'] . "\n";
// Создаем временный файл для вложения
$temp_file = tempnam(sys_get_temp_dir(), 'form_data_');
file_put_contents($temp_file, base64_decode($encrypted_pdf['content']));
// Подготовка MIME сообщения с вложением
$boundary = "----=" . md5(uniqid());
$headers = "From: noreply@yourdomain.com\r\n";
$headers .= "Reply-To: " . $email . "\r\n";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: multipart/mixed; boundary=\"$boundary\"\r\n";
$headers .= "X-Mailer: PHP/" . phpversion() . "\r\n";
$message_mime = "--$boundary\r\n";
$message_mime .= "Content-Type: text/plain; charset=UTF-8\r\n";
$message_mime .= "Content-Transfer-Encoding: 8bit\r\n\r\n";
$message_mime .= $email_body . "\r\n\r\n";
$message_mime .= "--$boundary\r\n";
$message_mime .= "Content-Type: application/pdf; name=\"message_encrypted.pdf\"\r\n";
$message_mime .= "Content-Transfer-Encoding: base64\r\n";
$message_mime .= "Content-Disposition: attachment; filename=\"message_encrypted.pdf\"\r\n\r\n";
$message_mime .= chunk_split($encrypted_pdf['content']) . "\r\n";
$message_mime .= "--$boundary--\r\n";
// Отправка email
if (mail($to, $email_subject, $message_mime, $headers)) {
$success = "Сообщение отправлено! Зашифрованный PDF приложен к письму. Мы ответим вам в ближайшее время.";
// Очистить временный файл
unlink($temp_file);
// Очистить форму
$name = $email = $subject = $message = '';
} else {
$error = "Ошибка отправки. Попробуйте еще раз или свяжитесь через Telegram.";
unlink($temp_file);
}
}
}
// Перенаправление обратно на страницу с результатом
if (isset($success)) {
header("Location: /ask/?success=" . urlencode($success));
exit;
} elseif (isset($error)) {
header("Location: /ask/?error=" . urlencode($error));
exit;
}
?>
+119
View File
@@ -0,0 +1,119 @@
<?php
require_once 'forms_helper.php';
// Загружаем настройки из .env
load_env_file(__DIR__ . '/.env');
$settings = get_forms_settings();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$name = trim($_POST['name'] ?? '');
$email = trim($_POST['email'] ?? '');
$phone = trim($_POST['phone'] ?? '');
$telegram = trim($_POST['telegram'] ?? '');
$bvs_number = trim($_POST['bvs_number'] ?? '');
$trip_period = trim($_POST['trip_period'] ?? '');
$consent = isset($_POST['privacy_consent']) ? 'agree' : '';
// Валидация
if (empty($name) || empty($consent)) {
$error = "Обязательные поля: Имя, Согласие на обработку данных.";
} elseif (empty($email) && empty($telegram)) {
$error = "Укажите email или Telegram ник (одно из двух обязательно).";
} elseif (!empty($email) && !filter_var($email, FILTER_VALIDATE_EMAIL)) {
$error = "Некорректный email адрес.";
} elseif ($consent !== 'agree') {
$error = "Для отправки заявки необходимо согласие на обработку персональных данных.";
} else {
// Подготавливаем данные заявки
$form_data = [
'name' => $name,
'email' => $email,
'phone' => $phone,
'telegram' => $telegram,
'bvs_number' => $bvs_number,
'trip_period' => $trip_period,
'consent' => $consent
];
$success_messages = [];
$error_messages = [];
// 1. Отправка email (если включено)
if ($settings['send_email']) {
$to = "test@yourdomain.com"; // ЗАМЕНИТЕ на ваш тестовый email!
$email_subject = "Новая заявка на поездку от " . $name;
$email_body = "Новая заявка на планирование поездки:\n\n";
$email_body .= "Имя: " . $name . "\n";
$email_body .= "Email: " . $email . "\n";
$email_body .= "Телефон: " . ($phone ?: 'не указан') . "\n";
$email_body .= "Telegram: " . ($telegram ?: 'не указан') . "\n";
$email_body .= "Учётный номер БВС/Вариант поездки: " . ($bvs_number ?: 'не указано') . "\n";
$email_body .= "Период поездки: " . ($trip_period ?: 'не выбран') . "\n";
$email_body .= "Согласие на обработку данных: Да\n\n";
$email_body .= "---\n";
$email_body .= "Отправлено с: " . $_SERVER['HTTP_HOST'] . "\n";
$email_body .= "Дата: " . date('Y-m-d H:i:s') . "\n";
$email_body .= "IP: " . $_SERVER['REMOTE_ADDR'] . "\n";
$headers = "From: noreply@sleeptrip.ru\r\n";
$headers .= "Reply-To: " . $email . "\r\n";
$headers .= "X-Mailer: PHP/" . phpversion();
$headers .= "Content-Type: text/plain; charset=UTF-8\r\n";
if (mail($to, $email_subject, $email_body, $headers)) {
$success_messages[] = "Email отправлен";
} else {
$error_messages[] = "Ошибка отправки email";
}
}
// 2. Сохранение в JSON (если включено)
if ($settings['save_json']) {
$json_saved = save_application_to_json($form_data, 'plan');
if ($json_saved) {
$success_messages[] = "Заявка сохранена";
} else {
$error_messages[] = "Ошибка сохранения заявки";
}
}
// 3. Уведомление в Telegram (если включено)
if ($settings['send_telegram'] && $settings['notifications']) {
$telegram_sent = send_telegram_notification($form_data, 'plan');
if ($telegram_sent) {
$success_messages[] = "Уведомление отправлено";
} else {
$error_messages[] = "Ошибка уведомления в Telegram";
}
}
// Формируем итоговое сообщение
if (!empty($success_messages)) {
$success = "Заявка обработана! Мы свяжемся с вами в ближайшее время.";
// Очистить форму
$name = $email = $phone = $telegram = $bvs_number = $trip_period = $consent = '';
}
if (!empty($error_messages) && empty($success_messages)) {
$error = "Ошибка обработки заявки. Попробуйте еще раз или свяжитесь через Telegram.";
}
}
}
// Возвращаем JSON для AJAX совместимости
if (isset($success)) {
header('Content-Type: application/json; charset=utf-8');
echo json_encode([
'success' => true,
'message' => $success
], JSON_UNESCAPED_UNICODE);
exit;
} elseif (isset($error)) {
header('Content-Type: application/json; charset=utf-8');
echo json_encode([
'success' => false,
'error' => $error
], JSON_UNESCAPED_UNICODE);
exit;
}
?>
+126
View File
@@ -0,0 +1,126 @@
<?php
// Проверка расширений PHP
if (!extension_loaded('openssl')) {
die('OpenSSL extension required for PDF encryption');
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$name = trim($_POST['name'] ?? '');
$email = trim($_POST['email'] ?? '');
$phone = trim($_POST['phone'] ?? '');
$bvs_number = trim($_POST['bvs_number'] ?? '');
$trip_period = trim($_POST['trip_period'] ?? '');
$consent = isset($_POST['consent']) ? trim($_POST['consent']) : '';
$age_confirm = isset($_POST['age_confirm']) ? trim($_POST['age_confirm']) : '';
// Валидация
if (empty($name) || empty($email) || empty($consent) || empty($age_confirm)) {
$error = "Обязательные поля: Имя, Email, Согласие на обработку данных, Подтверждение возраста.";
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$error = "Некорректный email адрес.";
} elseif ($consent !== 'agree') {
$error = "Для отправки заявки необходимо согласие на обработку персональных данных.";
} elseif ($age_confirm !== '18+') {
$error = "Для отправки заявки необходимо подтверждение возраста 18+.";
} else {
// Функция создания зашифрованного PDF
function createEncryptedPDF($data, $password = null) {
// Если пароль не указан, генерируем случайный
if (!$password) {
$password = bin2hex(random_bytes(8));
}
// Создаем простой PDF контент
$pdf_content = "%PDF-1.4\n";
$pdf_content .= "1 0 obj\n<< /Type /Catalog /Pages 2 0 R >>\nendobj\n";
$pdf_content .= "2 0 obj\n<< /Type /Pages /Kids [3 0 R] /Count 1 >>\nendobj\n";
$pdf_content .= "3 0 obj\n<< /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792] /Contents 4 0 R >>\nendobj\n";
$pdf_content .= "4 0 obj\n<< /Length " . strlen($data) . " >>\nstream\n";
$pdf_content .= "BT /F1 12 Tf 72 720 Td (" . $data . ") Tj ET\n";
$pdf_content .= "endstream\nendobj\n";
$pdf_content .= "xref\n0 5\n0000000000 65535 f \n0000000010 00000 n \n0000000053 00000 n \n0000000125 00000 n \n0000000202 00000 n \n";
$pdf_content .= "trailer\n<< /Size 5 /Root 1 0 R >>\nstartxref\n" . strlen($pdf_content) . "\n%%EOF";
// Шифруем содержимое
$encrypted = openssl_encrypt($pdf_content, 'AES-256-CBC', $password, 0, substr(hash('sha256', $password), 0, 16));
return ['content' => $encrypted, 'password' => $password];
}
// Подготовка данных для PDF
$pdf_data = "Заявка на планирование поездки\n\n";
$pdf_data .= "Имя: " . $name . "\n";
$pdf_data .= "Email: " . $email . "\n";
$pdf_data .= "Телефон: " . ($phone ?: 'не указан') . "\n";
$pdf_data .= "Учётный номер БВС/Вариант поездки: " . ($bvs_number ?: 'не указано') . "\n";
$pdf_data .= "Период поездки: " . ($trip_period ?: 'не выбран') . "\n";
$pdf_data .= "Дата отправки: " . date('Y-m-d H:i:s') . "\n";
// Создаем зашифрованный PDF
$encrypted_pdf = createEncryptedPDF($pdf_data);
// Подготовка email
$to = "test@yourdomain.com"; // ЗАМЕНИТЕ на ваш тестовый email!
$email_subject = "Новая заявка на поездку от " . $name;
$email_body = "Новая заявка на планирование поездки:\n\n";
$email_body .= "Имя: " . $name . "\n";
$email_body .= "Email: " . $email . "\n";
$email_body .= "Телефон: " . ($phone ?: 'не указан') . "\n";
$email_body .= "Учётный номер БВС/Вариант поездки: " . ($bvs_number ?: 'не указано') . "\n";
$email_body .= "Период поездки: " . ($trip_period ?: 'не выбран') . "\n";
$email_body .= "Возраст 18+: " . ($age_confirm === '18+' ? 'Подтверждено' : 'Не подтверждено') . "\n";
$email_body .= "Согласие на обработку данных: " . ($consent === 'agree' ? 'Да' : 'Нет') . "\n\n";
$email_body .= "К письму приложен зашифрованный PDF файл с данными заявки.\n";
$email_body .= "Пароль для расшифровки: " . $encrypted_pdf['password'] . "\n\n";
$email_body .= "---\n";
$email_body .= "Отправлено с: " . $_SERVER['HTTP_HOST'] . "\n";
$email_body .= "Дата: " . date('Y-m-d H:i:s') . "\n";
$email_body .= "IP: " . $_SERVER['REMOTE_ADDR'] . "\n";
// Создаем временный файл для вложения
$temp_file = tempnam(sys_get_temp_dir(), 'form_data_');
file_put_contents($temp_file, base64_decode($encrypted_pdf['content']));
// Подготовка MIME сообщения с вложением
$boundary = "----=" . md5(uniqid());
$headers = "From: noreply@yourdomain.com\r\n";
$headers .= "Reply-To: " . $email . "\r\n";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: multipart/mixed; boundary=\"$boundary\"\r\n";
$headers .= "X-Mailer: PHP/" . phpversion() . "\r\n";
$message = "--$boundary\r\n";
$message .= "Content-Type: text/plain; charset=UTF-8\r\n";
$message .= "Content-Transfer-Encoding: 8bit\r\n\r\n";
$message .= $email_body . "\r\n\r\n";
$message .= "--$boundary\r\n";
$message .= "Content-Type: application/pdf; name=\"form_data_encrypted.pdf\"\r\n";
$message .= "Content-Transfer-Encoding: base64\r\n";
$message .= "Content-Disposition: attachment; filename=\"form_data_encrypted.pdf\"\r\n\r\n";
$message .= chunk_split($encrypted_pdf['content']) . "\r\n";
$message .= "--$boundary--\r\n";
// Отправка email
if (mail($to, $email_subject, $message, $headers)) {
$success = "Заявка отправлена! Зашифрованный PDF приложен к письму. Мы свяжемся с вами в ближайшее время.";
// Очистить временный файл
unlink($temp_file);
// Очистить форму
$name = $email = $phone = $bvs_number = $trip_period = $consent = $age_confirm = '';
} else {
$error = "Ошибка отправки. Попробуйте еще раз или свяжитесь через Telegram.";
unlink($temp_file);
}
}
}
// Перенаправление обратно на страницу с результатом
if (isset($success)) {
header("Location: /plan/?success=" . urlencode($success));
exit;
} elseif (isset($error)) {
header("Location: /plan/?error=" . urlencode($error));
exit;
}
?>
+1
View File
@@ -0,0 +1 @@
бтыне