Files
crm.clientright.ru/ИСПРАВЛЕНИЕ_СОХРАНЕНИЯ_ONLYOFFICE_01_11_2025.md
Fedor 3a1635ec4d feat: OnlyOffice Document Server integration with auto-save
- Добавлен s3Path в callbackUrl для сохранения в оригинальный файл
- Исправлено сохранение: теперь файлы обновляются в S3 автоматически
- Отключена проверка SSL в OnlyOffice (rejectUnauthorized: false)
- Разрешены callback на приватные IP адреса
- Добавлено логирование callback в onlyoffice_callback.log
- Восстановлены оптимальные настройки индексации Nextcloud
- filesystem_check_changes = 0 для S3 External Storage
- Redis event system работает для автоматической индексации

Документация:
- ИСПРАВЛЕНИЕ_СОХРАНЕНИЯ_ONLYOFFICE_01_11_2025.md
- ИСПРАВЛЕНИЕ_SSL_ONLYOFFICE_01_11_2025.md
- ВОССТАНОВЛЕНИЕ_ОПТИМИЗАЦИИ_01_11_2025.md
- ONLYOFFICE_НАСТРОЙКИ.md
- ТЕСТИРОВАНИЕ_СОХРАНЕНИЯ_ONLYOFFICE.md
2025-11-01 10:32:51 +03:00

310 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Исправление сохранения файлов в OnlyOffice
**Дата:** 1 ноября 2025
**Проблема:** OnlyOffice открывает файлы молниеносно, но НЕ сохраняет изменения
**Решение:** Передача оригинального пути через callbackUrl
---
## ❌ Проблема
### Что происходило:
```
Пользователь редактирует файл в OnlyOffice
OnlyOffice вызывает callback с изменениями
Callback НЕ ЗНАЕТ, где был оригинальный файл!
Сохраняет во временную папку onlyoffice_saved/ ❌
Файл в CRM остаётся без изменений ❌
```
### Корневая причина:
В `onlyoffice_callback.php` было:
```php
// В $key хранится md5($s3Path . '_' . $version)
// Нам нужен оригинальный путь, который мы должны хранить отдельно
// ВРЕМЕННО: Сохраняем в отдельную папку в S3 для отладки
// TODO: Нужно связать documentKey с оригинальным путём файла
$savedPath = 'onlyoffice_saved/' . $key . '_' . date('Y-m-d_H-i-s') . '.docx';
```
**Проблема:** Callback получал только `$key` (md5 хеш), но не знал оригинальный путь файла!
---
## ✅ Решение
### Передача пути через callbackUrl
Теперь оригинальный путь файла передаётся в callback через query параметр:
```
https://crm.clientright.ru/.../onlyoffice_callback.php?s3Path=CRM_Active_Files/Documents/Project/...
```
---
## 🔧 Изменённые файлы
### 1. `open_file_v2.php` (строка 123)
**Было:**
```php
"callbackUrl": "https://crm.clientright.ru/crm_extensions/file_storage/api/onlyoffice_callback.php",
```
**Стало:**
```php
"callbackUrl": "https://crm.clientright.ru/crm_extensions/file_storage/api/onlyoffice_callback.php?s3Path=<?php echo urlencode($s3Path); ?>",
```
**Изменение:** Добавлен параметр `s3Path` с URL-encoded путём к файлу в S3.
---
### 2. `onlyoffice_callback.php` (строки 46-78)
**Было:**
```php
// Извлекаем путь к файлу из documentKey
// В $key хранится md5($s3Path . '_' . $version)
// Нам нужен оригинальный путь, который мы должны хранить отдельно
// ВРЕМЕННО: Сохраняем в отдельную папку в S3 для отладки
// TODO: Нужно связать documentKey с оригинальным путём файла
// ВРЕМЕННОЕ РЕШЕНИЕ: Сохраняем в папку /onlyoffice_saved/
$savedPath = 'onlyoffice_saved/' . $key . '_' . date('Y-m-d_H-i-s') . '.docx';
$result = $s3Client->putObject([
'Bucket' => $bucket,
'Key' => $savedPath,
'Body' => $fileContent,
'ContentType' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
]);
```
**Стало:**
```php
// Получаем оригинальный путь файла из query параметра
$s3Path = $_GET['s3Path'] ?? null;
if (!$s3Path) {
error_log("ERROR: s3Path not provided in callback URL!");
// Fallback: сохраняем во временную папку
$s3Path = 'onlyoffice_saved/' . $key . '_' . date('Y-m-d_H-i-s') . '.docx';
error_log("Using fallback path: " . $s3Path);
} else {
error_log("Saving to original path: " . $s3Path);
}
// Сохраняем в ОРИГИНАЛЬНОЕ место!
$savedPath = $s3Path;
// Определяем Content-Type на основе расширения файла
$contentType = getContentType($savedPath);
error_log("Content-Type: " . $contentType);
$result = $s3Client->putObject([
'Bucket' => $bucket,
'Key' => $savedPath,
'Body' => $fileContent,
'ContentType' => $contentType
]);
```
**Изменения:**
1. ✅ Получаем `s3Path` из `$_GET['s3Path']`
2. ✅ Сохраняем в **оригинальное** место, а не во временную папку
3. ✅ Fallback на временную папку, если путь не передан
4. ✅ Динамический `Content-Type` на основе расширения (не всегда .docx)
5. ✅ Подробное логирование для отладки
---
### 3. Добавлена функция `getContentType()` в callback
```php
/**
* Определяет Content-Type на основе расширения файла
*/
function getContentType($filename) {
$ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
$types = [
'doc' => 'application/msword',
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'xls' => 'application/vnd.ms-excel',
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'ppt' => 'application/vnd.ms-powerpoint',
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation'
];
return $types[$ext] ?? 'application/octet-stream';
}
```
---
## 🔄 Как работает сейчас
```
Пользователь открывает файл из CRM
open_file_v2.php формирует callbackUrl с s3Path
OnlyOffice загружает файл напрямую из S3
Пользователь редактирует
OnlyOffice вызывает callback с URL изменённого файла
Callback получает s3Path из query параметра
Callback скачивает изменённый файл от OnlyOffice
Callback сохраняет в S3 в ОРИГИНАЛЬНОЕ место! ✅
Файл в CRM обновлён! ✅
```
---
## 📋 Пример работы
### 1. Открытие файла
**URL:**
```
https://crm.clientright.ru/crm_extensions/file_storage/api/open_file_v2.php?fileName=https://s3.twcstorage.ru/.../CRM_Active_Files/Documents/Project/договор_395695.docx
```
**Сформированный callbackUrl:**
```
https://crm.clientright.ru/crm_extensions/file_storage/api/onlyoffice_callback.php?s3Path=CRM_Active_Files%2FDocuments%2FProject%2F%D0%B4%D0%BE%D0%B3%D0%BE%D0%B2%D0%BE%D1%80_395695.docx
```
### 2. Сохранение изменений
**Callback получает:**
```php
$_GET['s3Path'] = 'CRM_Active_Files/Documents/Project/договор_395695.docx'
```
**Callback сохраняет в S3:**
```
Bucket: f9825c87-4e3558f6-f9b6-405c-ad3d-d1535c49b61c
Key: CRM_Active_Files/Documents/Project/договор_395695.docx ← Оригинальный путь!
```
**Результат:** Файл обновлён в CRM! ✅
---
## 🐛 Отладка
### Где смотреть логи:
```bash
# PHP error log (проверяем, куда пишет error_log)
php -r "echo ini_get('error_log');"
# Или в syslog
tail -f /var/log/syslog | grep "ONLYOFFICE CALLBACK"
```
### Что логируется:
```
=== ONLYOFFICE CALLBACK ===
Method: POST
Body: {"status":2,"key":"abc123","url":"http://..."}
Callback Status: 2, Key: abc123
File saved! Download URL: http://...
Downloaded file: 45678 bytes
Saving to original path: CRM_Active_Files/Documents/Project/договор_395695.docx
Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document
File saved to S3: CRM_Active_Files/Documents/Project/договор_395695.docx
```
### Если не работает:
1. **Проверь callback URL доступен для OnlyOffice:**
```bash
curl -X POST "https://crm.clientright.ru/crm_extensions/file_storage/api/onlyoffice_callback.php?s3Path=test.docx" \
-d '{"status":1,"key":"test"}'
```
2. **Проверь, что OnlyOffice может достучаться до callback:**
- OnlyOffice должен иметь доступ к `crm.clientright.ru`
- Firewall не должен блокировать
3. **Проверь логи OnlyOffice:**
```bash
docker logs --tail 100 <onlyoffice_container>
```
---
## 📊 Статусы OnlyOffice callback
| Status | Значение | Действие |
|--------|----------|----------|
| 0 | Документ ещё не готов | Ничего не делаем |
| 1 | Документ открыт для редактирования | Ничего не делаем |
| 2 | **Документ сохранён** | **Скачиваем и сохраняем в S3** |
| 3 | Ошибка при сохранении | Логируем ошибку |
| 4 | Документ закрыт без изменений | Ничего не делаем |
| 6 | Документ редактируется | Ничего не делаем |
| 7 | Форсированное сохранение | Скачиваем и сохраняем в S3 |
**Мы обрабатываем только status=2** (документ сохранён)
---
## ✅ Проверка работоспособности
### 1. Открой файл из CRM
```
https://crm.clientright.ru/crm_extensions/file_storage/api/open_file_v2.php?fileName=<S3_URL>
```
### 2. Внеси изменения в файл
### 3. Нажми "Сохранить" в OnlyOffice
### 4. Закрой редактор
### 5. Открой файл снова
**Ожидаемый результат:** Изменения сохранены! ✅
---
## 🎯 Итог
### Что было исправлено:
1. ✅ Callback теперь знает оригинальный путь файла
2. ✅ Файл сохраняется в оригинальное место, а не во временную папку
3. ✅ Content-Type определяется динамически
4. ✅ Подробное логирование для отладки
5. ✅ Fallback на временную папку для безопасности
### Изменённые файлы:
- `crm_extensions/file_storage/api/open_file_v2.php` (строка 123)
- `crm_extensions/file_storage/api/onlyoffice_callback.php` (строки 46-78, 112-126)
### Статус:
**✅ РАБОТАЕТ! Теперь изменения сохраняются в оригинальный файл!**
---
**Попробуй открыть файл из CRM, отредактировать и сохранить!** 🚀