Files
crm.clientright.ru/modules/Documents/models/Record.php
Fedor 840acca51a feat(documents): дедупликация documents_meta и исправление field_label
- Исправлен N8N_CODE_PROCESS_UPLOADED_FILES_FIXED.js: использовать uploads_field_labels[0] вместо [grp]
- Создан SQL_CLAIMSAVE_FIXED_NEW_FLOW_DEDUP.sql с дедупликацией documents_meta
- Создан SQL_CLEANUP_DOCUMENTS_META_DUPLICATES.sql для очистки существующих дубликатов
- Создан полный уникальный индекс idx_document_texts_hash_unique на document_texts(file_hash)
- Добавлен SESSION_LOG_2025-11-28_documents_dedup.md с описанием всех изменений

Fixes:
- field_label теперь корректно отображает 'Переписка' вместо 'group-2'
- documents_meta не накапливает дубликаты при повторных сохранениях
- ON CONFLICT (file_hash) теперь работает для document_texts
2025-11-28 18:16:53 +03:00

151 lines
5.6 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
/*+***********************************************************************************
* 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.
*************************************************************************************/
class Documents_Record_Model extends Vtiger_Record_Model {
/**
* Function to get the Display Name for the record
* @return <String> - Entity Display Name for the record
*/
function getDisplayName() {
return Vtiger_Util_Helper::getRecordName($this->getId());
}
function getDownloadFileURL() {
// Проверяем наличие S3 метаданных для любого типа файла
$db = PearDatabase::getInstance();
$result = $db->pquery("SELECT s3_bucket, s3_key FROM vtiger_notes WHERE notesid = ? AND s3_bucket IS NOT NULL AND s3_key IS NOT NULL", array($this->getId()));
if ($db->num_rows($result) > 0) {
// Файл в S3 - используем DownloadS3 action для генерации presigned URL
return 'index.php?module='. $this->getModuleName() .'&action=DownloadS3&record='. $this->getId();
}
// Если нет S3 метаданных, обрабатываем по типу хранения
if ($this->get('filelocationtype') == 'E') {
// Внешняя ссылка (не S3, а другой внешний источник)
return $this->get('filename');
} else if ($this->get('filelocationtype') == 'I') {
// Файл в локальном storage - используем старый метод
$fileDetails = $this->getFileDetails();
return 'index.php?module='. $this->getModuleName() .'&action=DownloadFile&record='. $this->getId() .'&fileid='. $fileDetails['attachmentsid'].'&name='. $fileDetails['name'];
} else {
// По умолчанию - внешняя ссылка
return $this->get('filename');
}
}
function checkFileIntegrityURL() {
return "javascript:Documents_Detail_Js.checkFileIntegrity('index.php?module=".$this->getModuleName()."&action=CheckFileIntegrity&record=".$this->getId()."')";
}
function checkFileIntegrity() {
$recordId = $this->get('id');
$downloadType = $this->get('filelocationtype');
$returnValue = false;
if ($downloadType == 'I') {
$fileDetails = $this->getFileDetails();
if (!empty ($fileDetails)) {
$filePath = $fileDetails['path'];
$storedFileName = $fileDetails['storedname'];
$savedFile = $fileDetails['attachmentsid']."_".$storedFileName;
if(fopen($filePath.$savedFile, "r")) {
$returnValue = true;
}
}
}
return $returnValue;
}
function getFileDetails() {
$db = PearDatabase::getInstance();
$fileDetails = array();
$result = $db->pquery("SELECT * FROM vtiger_attachments
INNER JOIN vtiger_seattachmentsrel ON vtiger_seattachmentsrel.attachmentsid = vtiger_attachments.attachmentsid
WHERE crmid = ?", array($this->get('id')));
if($db->num_rows($result)) {
$fileDetails = $db->query_result_rowdata($result);
}
return $fileDetails;
}
function downloadFile() {
$fileDetails = $this->getFileDetails();
$fileContent = false;
if (!empty ($fileDetails)) {
$filePath = $fileDetails['path'];
$fileName = $fileDetails['name'];
$storedFileName = $fileDetails['storedname'];
if ($this->get('filelocationtype') == 'I') {
$fileName = html_entity_decode($fileName, ENT_QUOTES, vglobal('default_charset'));
if (!empty($fileName)) {
if(!empty($storedFileName)){
$savedFile = $fileDetails['attachmentsid']."_".$storedFileName;
}else if(is_null($storedFileName)){
$savedFile = $fileDetails['attachmentsid']."_".$fileName;
}
while(ob_get_level()) {
ob_end_clean();
}
$fileSize = filesize($filePath.$savedFile);
$fileSize = $fileSize + ($fileSize % 1024);
if (fopen($filePath.$savedFile, "r")) {
$fileContent = fread(fopen($filePath.$savedFile, "r"), $fileSize);
header("Content-type: ".$fileDetails['type']);
header("Pragma: public");
header("Cache-Control: private");
header("Content-Disposition: attachment; filename=\"$fileName\"");
header("Content-Description: PHP Generated Data");
header("Content-Encoding: none");
}
}
}
}
echo $fileContent;
}
function updateFileStatus() {
$db = PearDatabase::getInstance();
$db->pquery("UPDATE vtiger_notes SET filestatus = 0 WHERE notesid= ?", array($this->get('id')));
}
function updateDownloadCount() {
$db = PearDatabase::getInstance();
$notesId = $this->get('id');
$result = $db->pquery("SELECT filedownloadcount FROM vtiger_notes WHERE notesid = ?", array($notesId));
$downloadCount = $db->query_result($result, 0, 'filedownloadcount') + 1;
$db->pquery("UPDATE vtiger_notes SET filedownloadcount = ? WHERE notesid = ?", array($downloadCount, $notesId));
}
function getDownloadCountUpdateUrl() {
return "index.php?module=Documents&action=UpdateDownloadCount&record=".$this->getId();
}
function get($key) {
$value = parent::get($key);
if ($key === 'notecontent') {
return decode_html($value);
}
return $value;
}
}