Files
crm.clientright.ru/crm_extensions/file_storage/api/prepare_edit.php
Fedor f582cf9c0f fix: Обновлены пути Nextcloud с /crm2/ на /crm/ для нового сервера
Обновленные файлы:
- crm_extensions/nextcloud_editor/js/nextcloud-editor.js (5 путей)
- crm_extensions/file_storage/api/get_edit_urls.php (6 путей)
- modules/Documents/actions/NcPrepareEdit.php (2 пути)
- crm_extensions/file_storage/api/prepare_edit.php (1 путь)
- crm_extensions/file_storage/NextcloudClient.php (1 путь)
- data/CRMEntity.php (nc_path для новых файлов)

Все пути теперь используют /crm/ вместо /crm2/ для соответствия новому External Storage на office.clientright.ru
2025-10-20 17:23:20 +03:00

305 lines
11 KiB
PHP
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.

<?php
/**
* API для подготовки файла к редактированию в Nextcloud
* Проверяет расположение файла и копирует в S3 при необходимости
*/
// Подключаем конфигурацию
$config = require_once __DIR__ . '/../config.php';
require_once __DIR__ . '/../NextcloudClient.php';
// Подключаем AWS SDK
require_once __DIR__ . '/../../vendor/autoload.php';
// Устанавливаем заголовки для JSON
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type');
// Включаем отображение ошибок для отладки
error_reporting(E_ALL);
ini_set('display_errors', 1);
// Обрабатываем OPTIONS запросы
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(200);
exit;
}
try {
// Логируем запрос для отладки
error_log("Nextcloud API called with: " . json_encode($_GET));
// Получаем параметры
$recordId = $_GET['recordId'] ?? $_POST['recordId'] ?? null;
$fileName = $_GET['fileName'] ?? $_POST['fileName'] ?? null;
// Декодируем URL-кодированное имя файла
if ($fileName) {
$fileName = urldecode($fileName);
}
error_log("Parsed parameters: recordId=$recordId, fileName=$fileName");
if (!$recordId || !$fileName) {
throw new Exception('Необходимы параметры recordId и fileName');
}
// Инициализируем клиенты
$nextcloudClient = new NextcloudClient($config['nextcloud']);
// Получаем информацию о файле из CRM
$fileInfo = getFileInfoFromCRM($recordId, $fileName);
if (!$fileInfo) {
throw new Exception('Файл не найден в CRM');
}
// Проверяем расположение файла
$fileLocation = checkFileLocation($fileInfo, $config);
// Если файл локальный, копируем в S3
if ($fileLocation['type'] === 'local') {
$s3Path = copyFileToS3($fileInfo, $recordId, $config);
$fileLocation['s3_path'] = $s3Path;
$fileLocation['type'] = 's3';
}
// Формируем путь для Nextcloud (используем внешнее хранилище S3)
$actualFileName = basename($fileName); // Извлекаем только имя файла
// Убираем подчеркивание в начале, если есть
if (substr($actualFileName, 0, 1) === '_') {
$actualFileName = substr($actualFileName, 1);
}
$nextcloudPath = '/crm/CRM_Active_Files/Documents/' . $recordId . '/' . $actualFileName;
// Проверяем, существует ли файл в Nextcloud
$fileExists = $nextcloudClient->fileExists($nextcloudPath);
if (!$fileExists) {
// Если файла нет в Nextcloud, загружаем его
if ($fileLocation['type'] === 's3') {
// Загружаем из S3
$uploadResult = uploadFileFromS3($fileLocation['s3_path'], $nextcloudPath, $config);
} else {
// Загружаем локальный файл
$uploadResult = uploadLocalFile($fileInfo['path'], $nextcloudPath, $config);
}
if (!$uploadResult['success']) {
throw new Exception('Ошибка загрузки файла: ' . $uploadResult['error']);
}
}
// Создаём прямую ссылку для редактирования
$editResult = $nextcloudClient->createDirectEditLink($nextcloudPath, $recordId, $actualFileName);
if (!$editResult['success']) {
throw new Exception('Ошибка создания ссылки для редактирования: ' . $editResult['error']);
}
// Возвращаем результат
echo json_encode([
'success' => true,
'data' => [
'record_id' => $recordId,
'file_name' => $fileName,
'file_id' => $editResult['file_id'] ?? 662,
'file_location' => $fileLocation,
'nextcloud_path' => $nextcloudPath,
'edit_url' => $editResult['edit_url'],
'share_url' => $editResult['share_url'] ?? null,
'message' => 'Файл подготовлен к редактированию'
]
]);
} catch (Exception $e) {
http_response_code(500);
echo json_encode([
'success' => false,
'error' => $e->getMessage()
]);
}
/**
* Получает информацию о файле из CRM
*/
function getFileInfoFromCRM($recordId, $fileName) {
try {
// Пробуем разные возможные пути к файлу
$possiblePaths = [
'/var/www/fastuser/data/www/crm.clientright.ru/storage/' . $recordId . '/' . $fileName,
'/var/www/fastuser/data/www/crm.clientright.ru/storage/Documents/' . $recordId . '/' . $fileName,
'/var/www/fastuser/data/www/crm.clientright.ru/storage/' . $fileName,
'/var/www/fastuser/data/www/crm.clientright.ru/storage/Documents/' . $fileName,
];
$filePath = null;
foreach ($possiblePaths as $path) {
if (file_exists($path)) {
$filePath = $path;
break;
}
}
if (!$filePath) {
// Если файл не найден локально, создаём заглушку для тестирования
$filePath = '/tmp/test_' . $recordId . '_' . $fileName;
file_put_contents($filePath, 'Test document content for ' . $fileName);
}
return [
'id' => $recordId,
'name' => $fileName,
'path' => $filePath,
'size' => filesize($filePath),
'type' => 'local'
];
} catch (Exception $e) {
error_log("Error getting file info from CRM: " . $e->getMessage());
return null;
}
}
/**
* Проверяет расположение файла (локальный или S3)
*/
function checkFileLocation($fileInfo, $config) {
// Проверяем, есть ли файл в S3
$s3Path = 'CRM_Active_Files/Documents/' . $fileInfo['id'] . '/' . $fileInfo['name'];
try {
$s3Client = new Aws\S3\S3Client([
'version' => 'latest',
'region' => $config['s3']['region'],
'credentials' => [
'key' => $config['s3']['key'],
'secret' => $config['s3']['secret']
],
'endpoint' => $config['s3']['endpoint']
]);
$exists = $s3Client->doesObjectExist($config['s3']['bucket'], $s3Path);
return [
'type' => $exists ? 's3' : 'local',
's3_path' => $exists ? $s3Path : null,
'local_path' => $exists ? null : $fileInfo['path']
];
} catch (Exception $e) {
error_log("Error checking S3 file location: " . $e->getMessage());
return [
'type' => 'local',
's3_path' => null,
'local_path' => $fileInfo['path']
];
}
}
/**
* Копирует локальный файл в S3
*/
function copyFileToS3($fileInfo, $recordId, $config) {
try {
$s3Client = new Aws\S3\S3Client([
'version' => 'latest',
'region' => $config['s3']['region'],
'credentials' => [
'key' => $config['s3']['key'],
'secret' => $config['s3']['secret']
],
'endpoint' => $config['s3']['endpoint']
]);
$s3Path = 'CRM_Active_Files/Documents/' . $recordId . '/' . $fileInfo['name'];
// Определяем MIME тип
$mimeType = mime_content_type($fileInfo['path']);
if (!$mimeType) {
// Fallback для определения MIME типа по расширению
$extension = strtolower(pathinfo($fileInfo['name'], PATHINFO_EXTENSION));
$mimeTypes = [
'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',
'pdf' => 'application/pdf',
'txt' => 'text/plain',
'rtf' => 'application/rtf',
'odt' => 'application/vnd.oasis.opendocument.text',
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
'odp' => 'application/vnd.oasis.opendocument.presentation'
];
$mimeType = $mimeTypes[$extension] ?? 'application/octet-stream';
}
$result = $s3Client->putObject([
'Bucket' => $config['s3']['bucket'],
'Key' => $s3Path,
'SourceFile' => $fileInfo['path'],
'ContentType' => $mimeType
]);
return $s3Path;
} catch (Exception $e) {
error_log("Error copying file to S3: " . $e->getMessage());
throw new Exception('Ошибка копирования файла в S3: ' . $e->getMessage());
}
}
/**
* Загружает файл из S3 в Nextcloud
*/
function uploadFileFromS3($s3Path, $nextcloudPath, $config) {
try {
$s3Client = new Aws\S3\S3Client([
'version' => 'latest',
'region' => $config['s3']['region'],
'credentials' => [
'key' => $config['s3']['key'],
'secret' => $config['s3']['secret']
],
'endpoint' => $config['s3']['endpoint']
]);
// Скачиваем файл из S3 во временную папку
$tempFile = tempnam(sys_get_temp_dir(), 'nextcloud_upload_');
$s3Client->getObject([
'Bucket' => $config['s3']['bucket'],
'Key' => $s3Path,
'SaveAs' => $tempFile
]);
// Загружаем в Nextcloud
$nextcloudClient = new NextcloudClient($config['nextcloud']);
$result = $nextcloudClient->uploadFile($tempFile, $nextcloudPath);
// Удаляем временный файл
unlink($tempFile);
return $result;
} catch (Exception $e) {
error_log("Error uploading file from S3 to Nextcloud: " . $e->getMessage());
return ['success' => false, 'error' => $e->getMessage()];
}
}
/**
* Загружает локальный файл в Nextcloud
*/
function uploadLocalFile($localPath, $nextcloudPath, $config) {
try {
$nextcloudClient = new NextcloudClient($config['nextcloud']);
return $nextcloudClient->uploadFile($localPath, $nextcloudPath);
} catch (Exception $e) {
error_log("Error uploading local file to Nextcloud: " . $e->getMessage());
return ['success' => false, 'error' => $e->getMessage()];
}
}