- Added comprehensive AI Assistant system (aiassist/ directory): * Vector search and embedding capabilities * Typebot proxy integration * Elastic search functionality * Message classification and chat history * MCP proxy for external integrations - Implemented Court Status API (GetCourtStatus.php): * Real-time court document status checking * Integration with external court systems * Comprehensive error handling and logging - Enhanced S3 integration: * Improved file backup system with metadata * Batch processing capabilities * Enhanced error logging and recovery * Copy operations with URL fixing - Added Telegram contact creation API - Improved error logging across all modules - Enhanced callback system for AI responses - Extensive backup file storage with timestamps - Updated documentation and README files - File storage improvements: * Thousands of backup files with proper metadata * Fix operations for broken file references * Project-specific backup and recovery systems * Comprehensive file integrity checking Total: 26,461+ files added/modified including AWS SDK, vendor dependencies, and extensive backup system.
156 lines
3.9 KiB
PHP
156 lines
3.9 KiB
PHP
<?php
|
|
|
|
class Vtiger_Base_Service
|
|
{
|
|
public static function getDocs($record)
|
|
{
|
|
$module = 'Documents';
|
|
$relation = Vtiger_RelationListView_Model::getInstance(
|
|
$record,
|
|
$module
|
|
);
|
|
|
|
$pager = new Vtiger_Paging_Model();
|
|
$pager->set('limit', 1000);
|
|
return $relation->getEntries($pager);
|
|
}
|
|
|
|
public static function getPaths($docs = [])
|
|
{
|
|
$archived = 0;
|
|
$errors = [];
|
|
$files = [];
|
|
foreach ($docs as $x) {
|
|
if (empty($x->get('filename'))) {
|
|
$errors[] = 'skip non-file docs';
|
|
continue;
|
|
}
|
|
|
|
$details = $x->getFileDetails();
|
|
$name = $details['attachmentsid'] . '_' . $details['storedname'];
|
|
$fullPath = $details['path'] . $name;
|
|
if (!file_exists($fullPath)) {
|
|
$errors[] = "{$fullPath} is missing!";
|
|
continue;
|
|
}
|
|
|
|
$archived++;
|
|
$files[] = [
|
|
'name' => $name,
|
|
'path' => $fullPath
|
|
];
|
|
};
|
|
|
|
return compact(
|
|
'files',
|
|
'errors',
|
|
'archived'
|
|
);
|
|
}
|
|
|
|
public static function createArchive($id)
|
|
{
|
|
$record = Vtiger_Record_Model::getInstanceById($id);
|
|
if (! $record) {
|
|
return false;
|
|
}
|
|
|
|
$docs = self::getDocs($record);
|
|
if (count($docs) == 0) {
|
|
return false;
|
|
}
|
|
|
|
$files = self::getPaths($docs);
|
|
if ($files['archived'] == 0) {
|
|
return false;
|
|
}
|
|
|
|
$ts = date('Ymd_His_') . array_pop(explode('.', microtime(1)));
|
|
$zipFile = "cache/{$id}_documents_{$ts}.zip";
|
|
$zip = new ZipArchive();
|
|
$zip->open($zipFile, ZipArchive::CREATE);
|
|
foreach ($files['files'] as $x) {
|
|
$zip->addFile($x['path'], $x['name']);
|
|
}
|
|
$zip->close();
|
|
|
|
$size = filesize($zipFile);
|
|
if ($size == 0) {
|
|
//exit('Zero file');
|
|
return false;
|
|
}
|
|
|
|
return [
|
|
'total' => count($docs),
|
|
'archived' => $files['archived'],
|
|
'path' => $zipFile,
|
|
'size' => $size,
|
|
'errors' => $files['errors'],
|
|
];
|
|
}
|
|
|
|
public static function getArchive($id)
|
|
{
|
|
$module = 'Documents';
|
|
$record = Vtiger_Record_Model::getInstanceById($id);
|
|
if (! $record) {
|
|
return false;
|
|
}
|
|
|
|
$docs = self::getDocs($record);
|
|
if (count($docs) == 0) {
|
|
return self::response('Record has no documents');
|
|
}
|
|
|
|
$files = self::getPaths($docs);
|
|
if ($files['archived'] == 0) {
|
|
return self::response('Nothing to archive');
|
|
}
|
|
|
|
$ts = date('Ymd_His_') . array_pop(explode('.', microtime(1)));
|
|
$archive = "{$id}_documents_{$ts}.zip";
|
|
$zipFile = "cache/{$archive}";
|
|
$zip = new ZipArchive();
|
|
$result = $zip->open($zipFile, ZipArchive::CREATE|ZipArchive::OVERWRITE);
|
|
if (! $result) {
|
|
return self::response('Unable to create file');
|
|
}
|
|
|
|
foreach ($files['files'] as $x) {
|
|
$zip->addFile($x['path'], $x['name']);
|
|
}
|
|
|
|
$result = $zip->close();
|
|
if (! $result) {
|
|
return self::response('Unable to write file');
|
|
}
|
|
|
|
$size = filesize($zipFile);
|
|
|
|
if ($size == 0) {
|
|
//exit('Zero file');
|
|
return self::response('Error creating archive');
|
|
}
|
|
|
|
header('Content-disposition: attachment; filename='.$archive);
|
|
header('Content-type: application/zip');
|
|
readfile($zipFile);
|
|
//unlink($zipFile);
|
|
exit();
|
|
|
|
return self::response([
|
|
'file' => $zipName,
|
|
'docsCount' => count($docs),
|
|
'size' => $size,
|
|
]);
|
|
}
|
|
|
|
public static function response($data)
|
|
{
|
|
$response = new Vtiger_Response();
|
|
$response->setResult($data);
|
|
|
|
return $response->emit();
|
|
}
|
|
}
|