122 lines
5.1 KiB
PHP
122 lines
5.1 KiB
PHP
|
|
<?php
|
|||
|
|
/*+***********************************************************************************
|
|||
|
|
* The contents of this file are subject to the vtiger CRM Public License Version 1.0
|
|||
|
|
* ("License"); You may not use this file except in compliance with the License
|
|||
|
|
* The Original Code is: vtiger CRM Open Source
|
|||
|
|
* The Initial Developer of the Original Code is vtiger.
|
|||
|
|
* Portions created by vtiger are Copyright (C) vtiger.
|
|||
|
|
* All Rights Reserved.
|
|||
|
|
*************************************************************************************/
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* DownloadS3 Action
|
|||
|
|
* Скачивание файлов из S3 хранилища через presigned URLs
|
|||
|
|
*
|
|||
|
|
* @author AI Assistant
|
|||
|
|
* @date 2025-09-20
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
class Documents_DownloadS3_Action extends Vtiger_Action_Controller {
|
|||
|
|
|
|||
|
|
public function requiresPermission(\Vtiger_Request $request) {
|
|||
|
|
return array();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public function checkPermission(\Vtiger_Request $request) {
|
|||
|
|
$moduleName = $request->getModule();
|
|||
|
|
$moduleModel = Vtiger_Module_Model::getInstance($moduleName);
|
|||
|
|
|
|||
|
|
$userPrivilegesModel = Users_Privileges_Model::getCurrentUserPrivilegesModel();
|
|||
|
|
$permission = $userPrivilegesModel->hasModulePermission($moduleModel->getId());
|
|||
|
|
|
|||
|
|
if(!$permission) {
|
|||
|
|
throw new AppException(vtranslate($moduleName).' '.vtranslate('LBL_NOT_ACCESSIBLE'));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
$recordId = $request->get('record');
|
|||
|
|
if($recordId) {
|
|||
|
|
$recordEntityName = getSalesEntityType($recordId);
|
|||
|
|
if($recordEntityName !== $moduleName) {
|
|||
|
|
throw new AppException(vtranslate('LBL_PERMISSION_DENIED'));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public function process(\Vtiger_Request $request) {
|
|||
|
|
global $log;
|
|||
|
|
|
|||
|
|
$recordId = $request->get('record');
|
|||
|
|
$moduleName = $request->getModule();
|
|||
|
|
|
|||
|
|
$log->debug("DownloadS3: Processing download for record $recordId");
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
// Получаем информацию о документе
|
|||
|
|
$recordModel = Vtiger_Record_Model::getInstanceById($recordId, $moduleName);
|
|||
|
|
|
|||
|
|
if (!$recordModel) {
|
|||
|
|
throw new Exception("Document not found: $recordId");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Проверяем, есть ли S3 метаданные
|
|||
|
|
$db = PearDatabase::getInstance();
|
|||
|
|
$result = $db->pquery(
|
|||
|
|
"SELECT s3_bucket, s3_key, filename FROM vtiger_notes WHERE notesid = ? AND s3_key IS NOT NULL",
|
|||
|
|
array($recordId)
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
if ($db->num_rows($result) > 0) {
|
|||
|
|
// Файл в S3 - используем presigned URL
|
|||
|
|
$row = $db->query_result_rowdata($result, 0);
|
|||
|
|
$s3Bucket = $row['s3_bucket'];
|
|||
|
|
$s3Key = $row['s3_key'];
|
|||
|
|
$filename = $row['filename'];
|
|||
|
|
|
|||
|
|
$log->debug("DownloadS3: Found S3 file - bucket: $s3Bucket, key: $s3Key");
|
|||
|
|
|
|||
|
|
// Загружаем S3 Storage Service
|
|||
|
|
require_once __DIR__ . '/../../../include/Storage/S3StorageService.php';
|
|||
|
|
$s3Service = new S3StorageService();
|
|||
|
|
|
|||
|
|
// Генерируем presigned URL
|
|||
|
|
$presignedUrl = $s3Service->presignGet($s3Key, '+10 minutes');
|
|||
|
|
|
|||
|
|
$log->debug("DownloadS3: Generated presigned URL for record $recordId");
|
|||
|
|
|
|||
|
|
// Перенаправляем на presigned URL
|
|||
|
|
header('Location: ' . $presignedUrl, true, 302);
|
|||
|
|
exit;
|
|||
|
|
|
|||
|
|
} else {
|
|||
|
|
// Файл в локальном storage - используем старый метод
|
|||
|
|
$log->debug("DownloadS3: No S3 metadata found, falling back to local storage for record $recordId");
|
|||
|
|
|
|||
|
|
// Проверяем, есть ли файл в локальном storage
|
|||
|
|
$fileDetails = $recordModel->getFileDetails();
|
|||
|
|
if (!empty($fileDetails) && $recordModel->get('filelocationtype') == 'I') {
|
|||
|
|
// Используем старый метод скачивания
|
|||
|
|
$recordModel->downloadFile();
|
|||
|
|
} else {
|
|||
|
|
throw new Exception("File not found in S3 or local storage for record: $recordId");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
} catch (Exception $e) {
|
|||
|
|
$log->error("DownloadS3: Error downloading file for record $recordId: " . $e->getMessage());
|
|||
|
|
|
|||
|
|
// Показываем пользователю ошибку
|
|||
|
|
header('Content-Type: text/html; charset=utf-8');
|
|||
|
|
echo '<html><head><title>Ошибка скачивания</title></head><body>';
|
|||
|
|
echo '<h1>Ошибка скачивания файла</h1>';
|
|||
|
|
echo '<p>Не удалось скачать файл. Попробуйте позже.</p>';
|
|||
|
|
echo '<p><a href="javascript:history.back()">Вернуться назад</a></p>';
|
|||
|
|
echo '</body></html>';
|
|||
|
|
exit;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
?>
|
|||
|
|
|
|||
|
|
|
|||
|
|
|