2025-11-01 01:02:03 +03:00
|
|
|
|
<?php
|
|
|
|
|
|
/**
|
|
|
|
|
|
* OnlyOffice Callback для сохранения файлов в S3
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
require_once '/var/www/fastuser/data/www/crm.clientright.ru/crm_extensions/shared/EnvLoader.php';
|
|
|
|
|
|
require_once '/var/www/fastuser/data/www/crm.clientright.ru/vendor/autoload.php';
|
|
|
|
|
|
EnvLoader::load('/var/www/fastuser/data/www/crm.clientright.ru/crm_extensions/.env');
|
|
|
|
|
|
|
|
|
|
|
|
error_reporting(E_ALL);
|
|
|
|
|
|
ini_set('display_errors', 0);
|
2025-11-01 10:32:51 +03:00
|
|
|
|
ini_set('log_errors', 1);
|
|
|
|
|
|
ini_set('error_log', '/var/www/fastuser/data/www/crm.clientright.ru/crm_extensions/file_storage/onlyoffice_callback.log');
|
2025-11-01 01:02:03 +03:00
|
|
|
|
|
|
|
|
|
|
// Логируем все запросы
|
|
|
|
|
|
$input = file_get_contents('php://input');
|
|
|
|
|
|
$data = json_decode($input, true);
|
|
|
|
|
|
|
|
|
|
|
|
error_log("=== ONLYOFFICE CALLBACK ===");
|
|
|
|
|
|
error_log("Method: " . $_SERVER['REQUEST_METHOD']);
|
|
|
|
|
|
error_log("Body: " . $input);
|
|
|
|
|
|
|
|
|
|
|
|
// OnlyOffice отправляет POST с JSON данными
|
|
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($data)) {
|
|
|
|
|
|
$status = $data['status'] ?? 0;
|
|
|
|
|
|
$key = $data['key'] ?? 'unknown';
|
|
|
|
|
|
|
|
|
|
|
|
error_log("Callback Status: $status, Key: $key");
|
|
|
|
|
|
|
|
|
|
|
|
// Status 2 = файл сохранён, нужно скачать и загрузить в S3
|
|
|
|
|
|
if ($status == 2 && isset($data['url'])) {
|
|
|
|
|
|
$downloadUrl = $data['url'];
|
|
|
|
|
|
error_log("File saved! Download URL: " . $downloadUrl);
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
// Скачиваем изменённый файл от OnlyOffice
|
|
|
|
|
|
$fileContent = file_get_contents($downloadUrl);
|
|
|
|
|
|
|
|
|
|
|
|
if ($fileContent === false) {
|
|
|
|
|
|
error_log("Failed to download file from OnlyOffice");
|
|
|
|
|
|
http_response_code(500);
|
|
|
|
|
|
echo json_encode(['error' => 1]);
|
|
|
|
|
|
exit;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
error_log("Downloaded file: " . strlen($fileContent) . " bytes");
|
|
|
|
|
|
|
2025-11-01 10:32:51 +03:00
|
|
|
|
// Получаем оригинальный путь файла из query параметра
|
|
|
|
|
|
$s3Path = $_GET['s3Path'] ?? null;
|
2025-11-01 01:02:03 +03:00
|
|
|
|
|
2025-11-01 10:32:51 +03:00
|
|
|
|
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);
|
|
|
|
|
|
}
|
2025-11-01 01:02:03 +03:00
|
|
|
|
|
|
|
|
|
|
// Инициализируем S3 клиент
|
|
|
|
|
|
$s3Client = new Aws\S3\S3Client([
|
|
|
|
|
|
'version' => 'latest',
|
|
|
|
|
|
'region' => 'ru-1',
|
|
|
|
|
|
'endpoint' => 'https://s3.twcstorage.ru',
|
|
|
|
|
|
'use_path_style_endpoint' => true,
|
|
|
|
|
|
'credentials' => [
|
|
|
|
|
|
'key' => EnvLoader::getRequired('S3_ACCESS_KEY'),
|
|
|
|
|
|
'secret' => EnvLoader::getRequired('S3_SECRET_KEY')
|
|
|
|
|
|
],
|
|
|
|
|
|
'suppress_php_deprecation_warning' => true
|
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
|
|
$bucket = 'f9825c87-4e3558f6-f9b6-405c-ad3d-d1535c49b61c';
|
|
|
|
|
|
|
2025-11-01 10:32:51 +03:00
|
|
|
|
// Сохраняем в ОРИГИНАЛЬНОЕ место!
|
|
|
|
|
|
$savedPath = $s3Path;
|
|
|
|
|
|
|
|
|
|
|
|
// Определяем Content-Type на основе расширения файла
|
|
|
|
|
|
$contentType = getContentType($savedPath);
|
|
|
|
|
|
error_log("Content-Type: " . $contentType);
|
2025-11-01 01:02:03 +03:00
|
|
|
|
|
|
|
|
|
|
$result = $s3Client->putObject([
|
|
|
|
|
|
'Bucket' => $bucket,
|
|
|
|
|
|
'Key' => $savedPath,
|
|
|
|
|
|
'Body' => $fileContent,
|
2025-11-01 10:32:51 +03:00
|
|
|
|
'ContentType' => $contentType
|
2025-11-01 01:02:03 +03:00
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
|
|
error_log("File saved to S3: " . $savedPath);
|
|
|
|
|
|
error_log("S3 Response: " . json_encode($result->toArray()));
|
|
|
|
|
|
|
|
|
|
|
|
http_response_code(200);
|
|
|
|
|
|
echo json_encode(['error' => 0]);
|
|
|
|
|
|
exit;
|
|
|
|
|
|
|
|
|
|
|
|
} catch (Exception $e) {
|
|
|
|
|
|
error_log("Error saving file to S3: " . $e->getMessage());
|
|
|
|
|
|
http_response_code(500);
|
|
|
|
|
|
echo json_encode(['error' => 1, 'message' => $e->getMessage()]);
|
|
|
|
|
|
exit;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Другие статусы (1 = открыт, 4 = закрыт и т.д.)
|
|
|
|
|
|
http_response_code(200);
|
|
|
|
|
|
echo json_encode(['error' => 0]);
|
|
|
|
|
|
exit;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Для всех остальных запросов - 200 OK
|
|
|
|
|
|
http_response_code(200);
|
|
|
|
|
|
echo json_encode(['error' => 0]);
|
2025-11-01 10:32:51 +03:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Определяет 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';
|
|
|
|
|
|
}
|
2025-11-01 01:02:03 +03:00
|
|
|
|
?>
|
|
|
|
|
|
|