config = require __DIR__ . '/config.php'; $this->s3Client = new S3Client($this->config['s3']); $this->nextcloudClient = new NextcloudClient($this->config['nextcloud']); CRM_Logger::info('FileStorageManager initialized'); } /** * Подготовка файла для редактирования * Получает файл из vTiger и готовит его в Nextcloud */ public function prepareForEditing($recordId, $fileName) { try { CRM_Logger::info("Preparing file for editing", ['record_id' => $recordId, 'file_name' => $fileName]); // 1. Получаем информацию о файле из vTiger $fileInfo = $this->getVTigerFileInfo($recordId); if (!$fileInfo) { throw new Exception('File not found in vTiger CRM'); } // 2. Генерируем пути $nextcloudPath = $this->generateNextcloudPath($fileInfo); // 3. Проверяем есть ли файл в Nextcloud if (!$this->nextcloudClient->fileExists($nextcloudPath)) { CRM_Logger::info("File not in Nextcloud, uploading from vTiger", ['local_path' => $fileInfo['local_path']]); // Загружаем файл из локального хранилища vTiger в Nextcloud $uploadResult = $this->nextcloudClient->uploadFile($fileInfo['local_path'], $nextcloudPath); if (!$uploadResult['success']) { throw new Exception('Failed to upload to Nextcloud: ' . $uploadResult['error']); } CRM_Logger::info("File uploaded to Nextcloud successfully", ['nextcloud_path' => $nextcloudPath]); } // 4. Создаём ссылку для редактирования $editLinkResult = $this->nextcloudClient->createEditLink($nextcloudPath); if (!$editLinkResult['success']) { throw new Exception('Failed to create edit link: ' . $editLinkResult['error']); } CRM_Logger::info("Edit link created successfully", [ 'record_id' => $recordId, 'edit_url' => $editLinkResult['edit_url'] ]); return [ 'success' => true, 'edit_url' => $editLinkResult['edit_url'], 'share_url' => $editLinkResult['share_url'], 'nextcloud_path' => $nextcloudPath, 'file_info' => $fileInfo ]; } catch (Exception $e) { CRM_Logger::error("Failed to prepare file for editing", [ 'record_id' => $recordId, 'error' => $e->getMessage() ]); return [ 'success' => false, 'error' => $e->getMessage() ]; } } /** * Получение информации о файле из vTiger */ private function getVTigerFileInfo($recordId) { try { // Подключаемся к базе данных vTiger $config_inc = dirname(dirname(__DIR__)) . '/config.inc.php'; if (file_exists($config_inc)) { require_once $config_inc; } // Получаем информацию о файле из базы данных $query = " SELECT n.notesid, n.title, n.filename, n.filelocationtype, a.attachmentsid, a.name as stored_name, a.type as mime_type, a.path FROM vtiger_notes n LEFT JOIN vtiger_seattachmentsrel sar ON n.notesid = sar.crmid LEFT JOIN vtiger_attachments a ON sar.attachmentsid = a.attachmentsid WHERE n.notesid = ? "; // Используем PDO для безопасного запроса $pdo = new PDO("mysql:host=localhost;dbname=" . $dbconfig['db_name'], $dbconfig['db_username'], $dbconfig['db_password']); $stmt = $pdo->prepare($query); $stmt->execute([$recordId]); $result = $stmt->fetch(PDO::FETCH_ASSOC); if (!$result) { return null; } // Формируем полный путь к файлу $storagePath = dirname(dirname(__DIR__)) . '/storage/'; $localPath = $storagePath . $result['attachmentsid'] . '_' . $result['stored_name']; return [ 'record_id' => $recordId, 'title' => $result['title'], 'file_name' => $result['filename'], 'stored_name' => $result['stored_name'], 'mime_type' => $result['mime_type'], 'local_path' => $localPath, 'attachments_id' => $result['attachmentsid'], 'file_location_type' => $result['filelocationtype'] ]; } catch (Exception $e) { CRM_Logger::error("Failed to get vTiger file info", [ 'record_id' => $recordId, 'error' => $e->getMessage() ]); return null; } } /** * Генерация пути в Nextcloud */ private function generateNextcloudPath($fileInfo) { $recordId = $fileInfo['record_id']; $fileName = $fileInfo['file_name']; // Создаём структуру: Documents/RecordID/filename return "Documents/{$recordId}/{$fileName}"; } /** * Синхронизация после редактирования */ public function syncAfterEditing($recordId) { try { CRM_Logger::info("Syncing file after editing", ['record_id' => $recordId]); // Пока что просто логируем - полная синхронизация в следующей версии CRM_Logger::info("Sync completed (placeholder)", ['record_id' => $recordId]); return [ 'success' => true, 'message' => 'Синхронизация выполнена (базовая версия)' ]; } catch (Exception $e) { CRM_Logger::error("Failed to sync file after editing", [ 'record_id' => $recordId, 'error' => $e->getMessage() ]); return [ 'success' => false, 'error' => $e->getMessage() ]; } } }