Files
Fedor ac7467f0b4 Major CRM updates: AI Assistant, Court Status API, S3 integration improvements, and extensive file storage system
- 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.
2025-10-16 11:17:21 +03:00

264 lines
8.9 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.
* *********************************************************************************** */
//required for auto detecting file endings for files create in mac
ini_set("auto_detect_line_endings", true);
class Import_Utils_Helper {
static $AUTO_MERGE_NONE = 0;
static $AUTO_MERGE_IGNORE = 1;
static $AUTO_MERGE_OVERWRITE = 2;
static $AUTO_MERGE_MERGEFIELDS = 3;
static $supportedFileEncoding = array('UTF-8'=>'UTF-8', 'ISO-8859-1'=>'ISO-8859-1');
static $supportedDelimiters = array(','=>'comma', ';'=>'semicolon', '|'=> 'Pipe', '^'=>'Caret');
static $supportedFileExtensions = array('csv','vcf');
public function getSupportedFileExtensions() {
return self::$supportedFileExtensions;
}
public function getSupportedFileEncoding() {
return self::$supportedFileEncoding;
}
public function getSupportedDelimiters() {
return self::$supportedDelimiters;
}
public static function getAutoMergeTypes($moduleName) {
$mergeTypes = array(self::$AUTO_MERGE_IGNORE => 'Skip');
if (Users_Privileges_Model::isPermitted($moduleName, 'EditView')) {
$mergeTypes[self::$AUTO_MERGE_OVERWRITE] = 'Overwrite';
$mergeTypes[self::$AUTO_MERGE_MERGEFIELDS] = 'Merge';
}
return $mergeTypes;
}
public static function getMaxUploadSize() {
global $upload_maxsize;
return $upload_maxsize;
}
public static function getImportDirectory() {
global $import_dir;
$importDir = dirname(__FILE__). '/../../../'.$import_dir;
return $importDir;
}
public static function getImportFilePath($user) {
$importDirectory = self::getImportDirectory();
return $importDirectory. "IMPORT_".$user->id;
}
public static function getFileReaderInfo($type) {
$configReader = new Import_Config_Model();
$importTypeConfig = $configReader->get('importTypes');
if(isset($importTypeConfig[$type])) {
return $importTypeConfig[$type];
}
return null;
}
public static function getFileReader($request, $user) {
$fileReaderInfo = self::getFileReaderInfo($request->get('type'));
if(!empty($fileReaderInfo)) {
require_once $fileReaderInfo['classpath'];
$fileReader = new $fileReaderInfo['reader'] ($request, $user);
} else {
$fileReader = null;
}
return $fileReader;
}
public static function getDbTableName($user) {
$configReader = new Import_Config_Model();
$userImportTablePrefix = $configReader->get('userImportTablePrefix');
$tableName = $userImportTablePrefix;
if(method_exists($user, 'getId')){
$tableName .= $user->getId();
} else {
$tableName .= $user->id;
}
return $tableName;
}
public static function showErrorPage($errorMessage, $errorDetails=false, $customActions=false) {
$viewer = new Vtiger_Viewer();
$viewer->assign('ERROR_MESSAGE', $errorMessage);
$viewer->assign('ERROR_DETAILS', $errorDetails);
$viewer->assign('CUSTOM_ACTIONS', $customActions);
$viewer->assign('MODULE','Import');
$viewer->view('ImportError.tpl', 'Import');
}
public static function showImportLockedError($lockInfo) {
$moduleName = getTabModuleName($lockInfo['tabid']);
$userName = getUserFullName($lockInfo['userid']);
$errorMessage = sprintf("%s is importing %s. Please try after some time.",$userName, $moduleName);
self::showErrorPage($errorMessage);
}
public static function showImportTableBlockedError($moduleName, $user) {
$errorMessage = vtranslate('ERR_UNIMPORTED_RECORDS_EXIST', 'Import');
$customActions = array('LBL_CLEAR_DATA' => "location.href='index.php?module={$moduleName}&view=Import&mode=clearCorruptedData'");
self::showErrorPage($errorMessage, '', $customActions);
}
public static function isUserImportBlocked($user) {
$adb = PearDatabase::getInstance();
$tableName = self::getDbTableName($user);
if(Vtiger_Utils::CheckTable($tableName)) {
$result = $adb->pquery('SELECT 1 FROM '.$tableName.' WHERE status = ?', array(Import_Data_Action::$IMPORT_RECORD_NONE));
if($adb->num_rows($result) > 0) {
return true;
}
}
return false;
}
public static function clearUserImportInfo($user) {
$adb = PearDatabase::getInstance();
$tableName = self::getDbTableName($user);
$adb->pquery('DROP TABLE IF EXISTS '.$tableName, array());
Import_Lock_Action::unLock($user);
Import_Queue_Action::removeForUser($user);
}
public static function getAssignedToUserList($module) {
$cache = Vtiger_Cache::getInstance();
if($cache->getUserList($module,$current_user->id)){
return $cache->getUserList($module,$current_user->id);
} else {
$userList = get_user_array(FALSE, "Active", $current_user->id);
$cache->setUserList($module,$userList,$current_user->id);
return $userList;
}
}
public static function getAssignedToGroupList($module) {
$cache = Vtiger_Cache::getInstance();
if($cache->getGroupList($module,$current_user->id)){
return $cache->getGroupList($module,$current_user->id);
} else {
$groupList = get_group_array(FALSE, "Active", $current_user->id);
$cache->setGroupList($module,$groupList,$current_user->id);
return $groupList;
}
}
public static function hasAssignPrivilege($moduleName, $assignToUserId) {
$assignableUsersList = self::getAssignedToUserList($moduleName);
if(array_key_exists($assignToUserId, $assignableUsersList)) {
return true;
}
$assignableGroupsList = self::getAssignedToGroupList($moduleName);
if(array_key_exists($assignToUserId, $assignableGroupsList)) {
return true;
}
return false;
}
public static function validateFileUpload($request) {
$current_user = Users_Record_Model::getCurrentUserModel();
$uploadMaxSize = self::getMaxUploadSize();
$importDirectory = self::getImportDirectory();
$temporaryFileName = self::getImportFilePath($current_user);
if($_FILES['import_file']['error']) {
$request->set('error_message', self::fileUploadErrorMessage($_FILES['import_file']['error']));
return false;
}
if(!is_uploaded_file($_FILES['import_file']['tmp_name'])) {
$request->set('error_message', vtranslate('LBL_FILE_UPLOAD_FAILED', 'Import'));
return false;
}
if ($_FILES['import_file']['size'] > $uploadMaxSize) {
$request->set('error_message', vtranslate('LBL_IMPORT_ERROR_LARGE_FILE', 'Import').
$uploadMaxSize.' '.vtranslate('LBL_IMPORT_CHANGE_UPLOAD_SIZE', 'Import'));
return false;
}
if(!is_writable($importDirectory)) {
$request->set('error_message', vtranslate('LBL_IMPORT_DIRECTORY_NOT_WRITABLE', 'Import'));
return false;
}
if ($request->get('type') == "ics" || $request->get('type') == "vcf") {
$fileCopied = move_uploaded_file($_FILES['import_file']['tmp_name'], $temporaryFileName);
}else{
$fileCopied = self::neutralizeAndMoveFile($_FILES['import_file']['tmp_name'], $temporaryFileName, $request->get('delimiter'));
}
if(!$fileCopied) {
$request->set('error_message', vtranslate('LBL_IMPORT_FILE_COPY_FAILED', 'Import'));
return false;
}
$fileReader = Import_Utils_Helper::getFileReader($request, $current_user);
if($fileReader == null) {
$request->set('error_message', vtranslate('LBL_INVALID_FILE', 'Import'));
return false;
}
$hasHeader = $fileReader->hasHeader();
$firstRow = $fileReader->getFirstRowData($hasHeader);
if($firstRow === false) {
$request->set('error_message', vtranslate('LBL_NO_ROWS_FOUND', 'Import'));
return false;
}
return true;
}
/**
* To remove carriage return(\r) in end of every line and make the file neutral
* @param type $uploadedFileName
* @param type $temporaryFileName
* @return boolean
*/
public static function neutralizeAndMoveFile($uploadedFileName, $temporaryFileName, $delimiter = ','){
$file_read = fopen($uploadedFileName,'r');
$file_write = fopen($temporaryFileName,'w+');
while($data = fgetcsv($file_read, 0, $delimiter)){
fputcsv($file_write, $data, $delimiter);
}
fclose($file_read);
fclose($file_write);
return true;
}
static function fileUploadErrorMessage($error_code) {
switch ($error_code) {
case 1 : $errorMessage = 'The uploaded file exceeds the upload_max_filesize directive in php.ini';
case 2 : $errorMessage = 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form';
case 3 : $errorMessage = 'The uploaded file was only partially uploaded';
case 4 : $errorMessage = 'No file was uploaded';
case 6 : $errorMessage = 'Missing a temporary folder';
case 7 : $errorMessage = 'Failed to write file to disk';
case 8 : $errorMessage = 'File upload stopped by extension';
default : $errorMessage = 'Unknown upload error';
}
//SalesPlatform.ru begin
$errorMessage = vtranslate($errorMessage);
//SalesPlatform.ru end
return $errorMessage;
}
}