Files
crm.clientright.ru/crm_extensions/file_storage/api/create_nextcloud_file.php

234 lines
7.7 KiB
PHP
Raw Normal View History

2025-11-01 12:22:12 +03:00
<?php
/**
* Создание нового файла в Nextcloud
* Создаёт пустой DOCX/XLSX/PPTX и открывает для редактирования
*/
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', 1);
// Параметры
$module = $_GET['module'] ?? '';
$recordId = $_GET['recordId'] ?? '';
$recordName = $_GET['recordName'] ?? '';
$fileName = $_GET['fileName'] ?? '';
$fileType = $_GET['fileType'] ?? 'docx';
if (empty($module) || empty($recordId) || empty($fileName)) {
die("Не указаны обязательные параметры");
}
// Nextcloud credentials
$nextcloudUrl = 'https://office.clientright.ru:8443';
$username = 'admin';
$password = 'office';
// Определяем папку модуля
$moduleFolders = [
'Project' => 'Project',
'Contacts' => 'Contacts',
'Accounts' => 'Accounts',
'Invoice' => 'Invoice',
'Quotes' => 'Quotes',
'SalesOrder' => 'SalesOrder',
'PurchaseOrder' => 'PurchaseOrder',
'HelpDesk' => 'HelpDesk',
'Leads' => 'Leads',
'Potentials' => 'Potentials'
];
$moduleFolder = $moduleFolders[$module] ?? 'Other';
// Формируем имя папки записи
$recordName = preg_replace('/[\/\\\\:\*\?"<>\|]/', '_', $recordName); // Убираем недопустимые символы
$folderName = $recordName . '_' . $recordId;
// Формируем путь к файлу в Nextcloud
$ncPath = "/crm/crm2/CRM_Active_Files/Documents/{$moduleFolder}/{$folderName}/{$fileName}.{$fileType}";
$webdavUrl = $nextcloudUrl . '/remote.php/dav/files/' . $username . $ncPath;
error_log("=== CREATE NEXTCLOUD FILE ===");
error_log("Module: " . $module);
error_log("Record ID: " . $recordId);
error_log("File name: " . $fileName);
error_log("File type: " . $fileType);
error_log("Nextcloud path: " . $ncPath);
error_log("WebDAV URL: " . $webdavUrl);
// СОЗДАЁМ ФАЙЛ ЧЕРЕЗ NEXTCLOUD OCS API (Direct Editing)
// Используем встроенный API Nextcloud для создания нового файла
$templateMap = [
'docx' => 'onlyoffice',
'xlsx' => 'onlyoffice',
'pptx' => 'onlyoffice'
];
$editorId = $templateMap[$fileType] ?? 'onlyoffice';
// Используем OCS API v2 для создания нового файла
$createUrl = $nextcloudUrl . '/ocs/v2.php/apps/files/api/v1/directEditing/create';
$postData = http_build_query([
'path' => $ncPath,
'editorId' => $editorId,
'templateId' => '',
'templateType' => $fileType
]);
error_log("Creating file via OCS API: " . $createUrl);
error_log("Post data: " . $postData);
// Вызываем API создания
$ch = curl_init($createUrl);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'OCS-APIRequest: true',
'Content-Type: application/x-www-form-urlencoded',
'Accept: application/json'
]);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
error_log("OCS API response code: " . $httpCode);
error_log("OCS API response: " . substr($response, 0, 500));
// Если API сработал - парсим ответ и получаем URL редактора
if ($httpCode === 200) {
$data = json_decode($response, true);
if (isset($data['ocs']['data']['url'])) {
$editorUrl = $data['ocs']['data']['url'];
error_log("Got editor URL from API: " . $editorUrl);
header('Location: ' . $nextcloudUrl . $editorUrl);
exit;
}
}
// Если API не сработал - создаём файл НАПРЯМУЮ В S3 и открываем через OnlyOffice!
error_log("OCS API failed, creating file directly in S3");
// Извлекаем S3 путь из Nextcloud пути
// /crm/crm2/CRM_Active_Files/... → crm2/CRM_Active_Files/...
$s3Path = ltrim($ncPath, '/');
// S3 credentials
$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';
// Создаём минимальный пустой файл
$emptyContent = createEmptyFile($fileType);
error_log("Creating file in S3: " . $s3Path . " (" . strlen($emptyContent) . " bytes)");
// Загружаем файл в S3
try {
$result = $s3Client->putObject([
'Bucket' => $bucket,
'Key' => $s3Path,
'Body' => $emptyContent,
'ContentType' => getContentType($fileType)
]);
error_log("✅ File created in S3!");
} catch (Exception $e) {
error_log("Failed to create file in S3: " . $e->getMessage());
die("Не удалось создать файл в S3: " . $e->getMessage());
}
// Формируем S3 URL
$s3Url = 'https://s3.twcstorage.ru/' . $bucket . '/' . $s3Path;
error_log("S3 URL: " . $s3Url);
// Публикуем событие в Redis для индексации Nextcloud
try {
// Используем Predis (установлен через composer)
$redis = new Predis\Client([
'scheme' => 'tcp',
'host' => '147.45.146.17',
'port' => 6379,
'password' => 'CRM_Redis_Pass_2025_Secure!'
]);
$event = json_encode([
'type' => 'file_created',
'source' => 'crm_create_file',
'path' => $s3Path,
'timestamp' => time()
]);
$redis->publish('crm:file:events', $event);
error_log("✅ Published event to Redis");
} catch (Exception $e) {
error_log("Redis publish failed: " . $e->getMessage());
}
// Открываем файл НАПРЯМУЮ через OnlyOffice (быстро!)
$redirectUrl = '/crm_extensions/file_storage/api/open_file_v2.php?recordId=' . urlencode($recordId) . '&fileName=' . urlencode($s3Url);
error_log("Redirecting to OnlyOffice: " . $redirectUrl);
// Редирект
header('Location: ' . $redirectUrl);
exit;
/**
* Создаёт минимальное пустое содержимое для Office файла
*/
function createEmptyFile($fileType) {
// Используем готовые минимальные шаблоны
$templatePath = __DIR__ . '/../templates/empty.' . $fileType;
if (file_exists($templatePath)) {
$content = file_get_contents($templatePath);
error_log("Using template: " . $templatePath . " (" . strlen($content) . " bytes)");
return $content;
}
error_log("Template not found: " . $templatePath);
// Fallback: пустая строка (не будет работать, но хотя бы не упадёт)
return '';
}
/**
* Определяет Content-Type для файла
*/
function getContentType($fileType) {
$types = [
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'doc' => 'application/msword',
'xls' => 'application/vnd.ms-excel',
'ppt' => 'application/vnd.ms-powerpoint'
];
return $types[$fileType] ?? 'application/octet-stream';
}
?>