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()]; } }