Files
crm.clientright.ru/crm_extensions/file_storage/api/create_nextcloud_file.php
Fedor 7e3f0dcede Исправление путей к папкам проектов в Nextcloud + создание файлов из CRM
🔧 Исправления:
- Исправлены пути к папкам проектов: теперь /Documents/Project/{Name}_{Id}
- Исправлена функция openProjectFolder() во всех JS файлах
- Добавлены кнопки создания Word/Excel/PowerPoint из CRM (10 модулей)
- Создание файлов напрямую в S3 с автоиндексацией через Redis
- Исправлена ошибка 'Class Redis not found' (использован Predis)

📁 Изменённые файлы:
- layouts/v7/lib/nextcloud-editor.js
- crm_extensions/nextcloud_editor/js/nextcloud-editor.js
- layouts/v7/lib/nextcloud-editor-v3.js
- crm_extensions/file_storage/api/create_nextcloud_file.php
- layouts/v7/modules/*/DetailViewHeaderTitle.tpl (10 модулей)
- layouts/v7/modules/Documents/*.tpl (кнопки редактирования)

🎯 Результат:
- Кнопка 'Папка в Nextcloud' открывает правильную папку
- Создание файлов работает молниеносно (прямо в S3)
- Redis события публикуются корректно
- OnlyOffice открывается для редактирования

Проект 391552 теперь открывается по правильному пути!
2025-11-01 12:22:12 +03:00

234 lines
7.7 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
/**
* Создание нового файла в 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';
}
?>