diff --git a/.gitignore b/.gitignore index c84efee..9e3b0f1 100644 --- a/.gitignore +++ b/.gitignore @@ -45,6 +45,7 @@ gitea.pub telegram/ migration-s3/ INFO/ +!INFO/Deployment/*.md forms/.env # Debug and test pages - не для продакшена diff --git a/INFO/Deployment/ERRORS_COLLECTION.md b/INFO/Deployment/ERRORS_COLLECTION.md new file mode 100644 index 0000000..0a2e1c6 --- /dev/null +++ b/INFO/Deployment/ERRORS_COLLECTION.md @@ -0,0 +1,436 @@ +# 🐛 Коллекция ошибок при развертывании на VPS + +**Документация всех проблем и решений при установке PTP на VPS** + +--- + +## 📋 Содержание + +1. [Git Push Problems](#1-git-push-problems) +2. [S3 Upload Issues](#2-s3-upload-issues) +3. [Telegram Bot Path Issues](#3-telegram-bot-path-issues) +4. [Forms White Page (AJAX/Redirect)](#4-forms-white-page-ajaxredirect) +5. [.env File Parsing Bug](#5-env-file-parsing-bug) +6. [Permission Errors](#6-permission-errors) +7. [Script Line Endings](#7-script-line-endings) + +--- + +## 1. Git Push Problems + +### ❌ Проблема +```bash +fatal: The current branch main has no upstream branch. +``` + +### 🔍 Причина +Локальная ветка `main` не связана с удалённой `github/main`. + +### ✅ Решение +```bash +git branch --set-upstream-to=github/main main +git pull --no-rebase +git push +``` + +### 📝 Урок +Всегда проверять связь веток перед первым push после клонирования. + +--- + +## 2. S3 Upload Issues + +### ❌ Проблема +Telegram бот не может загружать фото на S3 REG.RU: +``` +which aws +/usr/bin/aws + +aws configure list + Name Value Type Location + ---- ----- ---- -------- + profile None None +access_key None None +secret_key None None + region None None +``` + +### 🔍 Причина +AWS CLI установлен, но не настроен. Пытались установить через pip3, но получили: +``` +error: externally-managed-environment +``` + +### ✅ Решение +Не использовать AWS CLI! Переключиться на **direct HTTP upload** метод: +```python +# В telegram_bot.py использовать: +upload_photo_direct() # вместо upload_photo_s3() +``` + +Этот метод использует только `requests` библиотеку и прямой HTTP PUT запрос к S3. + +### 📝 Урок +На Ubuntu 24.04+ pip установка блокируется по умолчанию. Лучше использовать HTTP API напрямую без CLI инструментов. + +--- + +## 3. Telegram Bot Path Issues + +### ❌ Проблема +```python +fatal: not a git repository +``` +Бот не может выполнить git команды. + +### 🔍 Причина +В коде бота путь к репозиторию был захардкожен: +```python +GIT_REPO_PATH = '/var/www/hugo-site' # Неправильный путь! +``` + +### ✅ Решение +Читать из `.env`: +```python +GIT_REPO_PATH = os.getenv('GIT_REPO_PATH', '/var/www/hugo-source') +TRIPS_JSON_PATH = os.path.join(GIT_REPO_PATH, 'static/data/upcoming-trips.json') +``` + +В `/var/www/telegram-bot/.env`: +```bash +GIT_REPO_PATH=/var/www/hugo-source +``` + +### 📝 Урок +Никогда не хардкодить пути. Всегда использовать переменные окружения. + +--- + +## 4. Forms White Page (AJAX/Redirect) + +### ❌ Проблема +После отправки формы - **белая страница**, хотя POST данные приходят: +``` +=== Request at 2025-10-27 15:02:32 === +Array ( + [name] => Test + [email] => test@test.com + ... +) +``` + +### 🔍 Причина +**Несовместимость AJAX и HTTP redirect:** + +JavaScript в `plan.md`: +```javascript +fetch('/forms/send_plan.php', { + method: 'POST', + body: formData +}) +.then(response => response.text()) +.then(text => { + const data = JSON.parse(text); // Ожидает JSON! + ... +}) +``` + +PHP в `send_plan.php` (старая версия): +```php +header("Location: /plan/?success=" . urlencode($success)); // Редирект! +exit; +``` + +**fetch() API НЕ следует редиректам автоматически** → получает пустой ответ → белая страница! + +### ✅ Решение (3 части) + +**1. PHP - вернуть JSON вместо redirect:** +```php +// send_plan.php и send_ask.php +if (isset($success)) { + header('Content-Type: application/json; charset=utf-8'); + echo json_encode([ + 'success' => true, + 'message' => $success + ], JSON_UNESCAPED_UNICODE); + exit; +} +``` + +**2. HTML - привязать JavaScript обработчик к форме:** +```html +
+``` + +**3. Добавить fallback на случай если переменные не установлены:** +```php +// В конце send_plan.php перед ?> +if (!isset($success) && !isset($error)) { + header('Content-Type: application/json; charset=utf-8'); + echo json_encode(['success' => false, 'error' => 'Неизвестная ошибка обработки']); + exit; +} +``` + +### 📝 Урок +- AJAX формы **ВСЕГДА** должны возвращать JSON, не redirect +- Проверять что обработчик формы **привязан** через `onsubmit` +- История проблем важна - нашли решение в `CHANGELOG.md` от 2025-09-03! + +--- + +## 5. .env File Parsing Bug + +### ❌ Проблема +Форма возвращает ошибку "Неизвестная ошибка обработки", хотя в `.env` установлено: +```bash +FORMS_SEND_TELEGRAM=true # Уведомления в Telegram +FORMS_NOTIFICATIONS=true # Push-уведомления +``` + +Проверка настроек показывает: +``` +Send telegram: false ❌ +Notifications: false ❌ +``` + +### 🔍 Причина +**Пробелы и комментарии в .env файле!** + +При парсинге строки: +```bash +FORMS_SEND_TELEGRAM=true # Уведомления в Telegram +``` + +Функция `load_env_file()` сохраняет: +```php +$_ENV['FORMS_SEND_TELEGRAM'] = 'true # Уведомления в Telegram' + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Лишние символы! +``` + +Затем проверка: +```php +getenv('FORMS_SEND_TELEGRAM') === 'true' // FALSE! +// 'true # Уведомления...' !== 'true' +``` + +**Видимость с `cat -A`:** +```bash +FORMS_SEND_TELEGRAM=true # M-PM-#M-PM-2... + ^^^^^^^^ Пробелы! +``` + +### ✅ Решение + +**Метод 1: Исправить .env файл (быстро):** +```bash +# Убрать всё после # и лишние пробелы +sudo sed -i 's/=\(.*\)#.*/=\1/' /var/www/forms/.env +sudo sed -i 's/= */=/g' /var/www/forms/.env +sudo sed -i 's/ *$//g' /var/www/forms/.env +``` + +**Результат:** +```bash +FORMS_SEND_EMAIL=false +FORMS_SEND_TELEGRAM=true +FORMS_NOTIFICATIONS=true +``` + +**Метод 2: Улучшить load_env_file() (надёжно):** +```php +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; + } + + // Убираем inline комментарии + if (strpos($line, '#') !== false) { + $line = substr($line, 0, strpos($line, '#')); + } + + 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; +} +``` + +### 📝 Урок +- **ВСЕГДА trim() значения** из .env файлов! +- Использовать `cat -A` для проверки невидимых символов +- .env формат не стандартизирован - парсить осторожно +- Эта проблема встречалась **ДВА раза**: + 1. В начале октября - отступы в начале строк + 2. Сегодня - пробелы перед комментариями + +--- + +## 6. Permission Errors + +### ❌ Проблема +```bash +fatal: could not create work tree dir: Permission denied +``` + +### 🔍 Причина +Неправильные владельцы файлов. Telegram бот работает от `www-data`, но файлы принадлежат `root`. + +### ✅ Решение +```bash +# Git репозиторий +sudo chown -R www-data:www-data /var/www/hugo-source + +# Формы +sudo chown -R www-data:www-data /var/www/forms +sudo chmod 600 /var/www/forms/.env + +# Secure storage +sudo chown -R www-data:www-data /var/secure/forms +sudo chmod 700 /var/secure/forms +``` + +### 📝 Урок +Всегда проверять кто запускает процесс (`systemctl status service | grep User`) и выставлять права соответственно. + +**Создан набор скриптов:** `INFO/Deployment/permissions/*.sh` + +--- + +## 7. Script Line Endings + +### ❌ Проблема +```bash +./enable-forms-debug.sh +-bash: ./enable-forms-debug.sh: cannot execute: required file not found +``` + +### 🔍 Причина +**CRLF line endings** (Windows/Mac) вместо LF (Unix): +```bash +#!/bin/bash\r\n # ← \r\n вместо \n +``` + +Bash ищет интерпретатор `/bin/bash\r` который не существует! + +### ✅ Решение +```bash +# Конвертировать в Unix формат +sed -i 's/\r$//' /var/www/enable-forms-debug.sh + +# Или через dos2unix +sudo apt install dos2unix +dos2unix /var/www/enable-forms-debug.sh +``` + +### 📝 Урок +При создании скриптов на Mac/Windows для Linux: +- Использовать редактор с LF endings (не CRLF) +- Или конвертировать через `dos2unix` перед запуском + +--- + +## 🎯 Общие уроки + +### 1. Документация критична +Создание `CHANGELOG.md` помогло найти решение для AJAX проблемы через 2 месяца! + +### 2. Debug логи спасают +```php +file_put_contents("/tmp/debug.log", print_r($data, true), FILE_APPEND); +``` +Помогли найти что POST данные приходят, но ответ пустой. + +### 3. Системные инструменты +- `cat -A` - показывает невидимые символы +- `ls -la` - проверяет права +- `grep -n` - находит строки с номерами +- `curl -v` - тестирует HTTP запросы + +### 4. Порядок проверки при пустом ответе PHP +1. ✅ POST данные приходят? → Debug лог +2. ✅ PHP ошибки? → `/var/log/php8.3-fpm.log` +3. ✅ Content-Type правильный? → `curl -I` +4. ✅ Переменные устанавливаются? → Debug перед выводом +5. ✅ .env загружается? → Тест парсинга +6. ✅ Значения правильные? → `cat -A` для невидимых символов + +### 5. Git workflow важен +- Формы теперь в git → автоматический deploy через webhook +- `.env` защищён через `.gitignore` +- Версионирование всех изменений + +--- + +## 📊 Статистика проблем + +| Категория | Количество | Критичность | +|-----------|------------|-------------| +| **Права доступа** | 5 | Высокая | +| **Парсинг .env** | 2 | Критическая | +| **AJAX/HTTP** | 1 | Критическая | +| **Пути к файлам** | 3 | Средняя | +| **Line endings** | 1 | Низкая | +| **AWS CLI** | 1 | Средняя | + +**Общее время на решение:** ~4 часа чистого времени отладки + +**Самая долгая проблема:** Forms white page (2+ часа) + +**Самая коварная:** .env пробелы (не видны глазом!) + +--- + +## 🚀 Профилактика + +### Перед развертыванием проверить: + +1. **Права:** + ```bash + ./INFO/Deployment/permissions/check-permissions.sh + ``` + +2. **.env файлы:** + ```bash + cat -A .env | grep "=" # Проверить на пробелы + ``` + +3. **Line endings скриптов:** + ```bash + file script.sh # Должно быть "ASCII text", не "CRLF" + ``` + +4. **Git remote:** + ```bash + git remote -v + git branch -vv # Проверить upstream + ``` + +5. **Формы AJAX:** + - Проверить `onsubmit` привязан + - PHP возвращает JSON + - JavaScript ожидает JSON + +--- + +**Создано:** 2025-10-27 +**Последнее обновление:** 2025-10-27 +**Автор:** Собрано в процессе развертывания PTP на VPS + +*Этот документ будет обновляться по мере обнаружения новых проблем.* diff --git a/content/ask.md b/content/ask.md index 2fa8034..d3de6a8 100755 --- a/content/ask.md +++ b/content/ask.md @@ -65,9 +65,72 @@ disableComments = true }; document.head.appendChild(script); }); + + // Обработчик отправки формы + function handleFormSubmit(event) { + event.preventDefault(); + + const form = event.target; + const formData = new FormData(form); + const submitBtn = form.querySelector('.submit-btn'); + + // Показываем состояние загрузки + submitBtn.textContent = 'Отправляем...'; + submitBtn.disabled = true; + + fetch('/forms/send_ask.php', { + method: 'POST', + body: formData + }) + .then(response => { + console.log('HTTP статус:', response.status); + console.log('Content-Type:', response.headers.get('content-type')); + return response.text(); + }) + .then(text => { + console.log('Ответ сервера:', text); + try { + const data = JSON.parse(text); + return data; + } catch (e) { + throw new Error('Сервер вернул не JSON: ' + text.substring(0, 100)); + } + }) + .then(data => { + if (data.success) { + // Успех + const successDiv = document.createElement('div'); + successDiv.className = 'form-message form-success'; + successDiv.textContent = data.message; + form.parentNode.insertBefore(successDiv, form); + form.reset(); + } else { + // Ошибка + const errorDiv = document.createElement('div'); + errorDiv.className = 'form-message form-error'; + errorDiv.textContent = data.error; + form.parentNode.insertBefore(errorDiv, form); + } + }) + .catch(error => { + // Ошибка сети + const errorDiv = document.createElement('div'); + errorDiv.className = 'form-message form-error'; + errorDiv.textContent = 'Ошибка отправки формы. Попробуйте еще раз.'; + form.parentNode.insertBefore(errorDiv, form); + }) + .finally(() => { + // Восстанавливаем кнопку + submitBtn.textContent = 'Отправить вопрос'; + submitBtn.disabled = false; + }); + + return false; + } + - +
diff --git a/forms/forms_helper.php b/forms/forms_helper.php index c405401..e3ccc1a 100644 --- a/forms/forms_helper.php +++ b/forms/forms_helper.php @@ -11,17 +11,28 @@ 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; // Пропускаем комментарии + continue; } - + + // Убираем inline комментарии (всё после #) + if (strpos($line, '#') !== false) { + $line = substr($line, 0, strpos($line, '#')); + } + + // Проверяем что есть знак = + if (strpos($line, '=') === false) { + continue; + } + list($name, $value) = explode('=', $line, 2); $name = trim($name); - $value = trim($value); - + $value = trim($value); // ВАЖНО: убирает пробелы до и после значения + if (!array_key_exists($name, $_SERVER) && !array_key_exists($name, $_ENV)) { putenv(sprintf('%s=%s', $name, $value)); $_ENV[$name] = $value;