- 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.
216 lines
12 KiB
PHP
216 lines
12 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.
|
||
*************************************************************************************/
|
||
require_once 'include/utils/WhatsApp.php';
|
||
require_once 'include/utils/Telegram.php';
|
||
require_once 'include/utils/utils.php';
|
||
|
||
class ModComments_SaveAjax_Action extends Vtiger_SaveAjax_Action {
|
||
|
||
public function checkPermission(Vtiger_Request $request) {
|
||
$moduleName = $request->getModule();
|
||
$record = $request->get('record');
|
||
//Do not allow ajax edit of existing comments
|
||
if ($record) {
|
||
throw new AppException(vtranslate('LBL_PERMISSION_DENIED'));
|
||
}
|
||
}
|
||
|
||
public function process(Vtiger_Request $request) {
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] MODCOMMENTS_PROCESS_START: process() called' . PHP_EOL, FILE_APPEND);
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] MODCOMMENTS_PROCESS_FILES: ' . print_r($_FILES, true) . PHP_EOL, FILE_APPEND);
|
||
|
||
$currentUserModel = Users_Record_Model::getCurrentUserModel();
|
||
$userId = $currentUserModel->getId();
|
||
$request->set('assigned_user_id', $userId);
|
||
$request->set('userid', $userId);
|
||
|
||
// DEBUG: Логирование в серверные логи (НЕ в браузер!)
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] MODCOMMENTS_SAVEAJAX_START: User ID=' . $userId . PHP_EOL, FILE_APPEND);
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] MODCOMMENTS_CONTENT: ' . $request->getRaw('commentcontent') . PHP_EOL, FILE_APPEND);
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] MODCOMMENTS_TYPE: ' . $request->get('commenttype') . PHP_EOL, FILE_APPEND);
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] MODCOMMENTS_RELATED_TO: ' . $request->get('related_to') . PHP_EOL, FILE_APPEND);
|
||
|
||
// DEBUG: Логирование входящих данных
|
||
$debugLog = "/tmp/modcomments_debug.log";
|
||
file_put_contents($debugLog, "=== ModComments SaveAjax DEBUG START ===\n", FILE_APPEND);
|
||
file_put_contents($debugLog, "User ID: " . $userId . "\n", FILE_APPEND);
|
||
file_put_contents($debugLog, "Request data: " . print_r($request->getAll(), true) . "\n", FILE_APPEND);
|
||
file_put_contents($debugLog, "Comment content: " . $request->getRaw('commentcontent') . "\n", FILE_APPEND);
|
||
file_put_contents($debugLog, "Comment type: " . $request->get('commenttype') . "\n", FILE_APPEND);
|
||
file_put_contents($debugLog, "Is private: " . $request->get('is_private') . "\n", FILE_APPEND);
|
||
file_put_contents($debugLog, "Related to: " . $request->get('related_to') . "\n", FILE_APPEND);
|
||
|
||
$recordModel = $this->saveRecord($request);
|
||
|
||
$fieldModelList = $recordModel->getModule()->getFields();
|
||
$result = array();
|
||
foreach ($fieldModelList as $fieldName => $fieldModel) {
|
||
if($fieldModel->isViewable()){
|
||
$fieldValue = $recordModel->get($fieldName);
|
||
$result[$fieldName] = array('value' => $fieldValue, 'display_value' => $fieldModel->getDisplayValue($fieldValue));
|
||
}
|
||
}
|
||
$result['id'] = $result['_recordId'] = $recordModel->getId();
|
||
$result['_recordLabel'] = $recordModel->getName();
|
||
|
||
// DEBUG: Логирование результата в серверные логи
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] MODCOMMENTS_SAVEAJAX_RESULT: ' . json_encode($result) . PHP_EOL, FILE_APPEND);
|
||
|
||
$response = new Vtiger_Response();
|
||
$response->setEmitType(Vtiger_Response::$EMIT_JSON);
|
||
$response->setResult($result);
|
||
$response->emit();
|
||
}
|
||
|
||
/**
|
||
* Function to save record
|
||
* @param <Vtiger_Request> $request - values of the record
|
||
* @return <RecordModel> - record Model of saved record
|
||
*/
|
||
public function saveRecord($request) {
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] MODCOMMENTS_SAVERECORD_START: saveRecord called' . PHP_EOL, FILE_APPEND);
|
||
|
||
try {
|
||
// Временно сохраняем файлы для обработки после сохранения комментария
|
||
$filesToProcess = array();
|
||
if (!empty($_FILES) && isset($_FILES['filename'])) {
|
||
$files = $_FILES['filename'];
|
||
if (isset($files['name']) && is_array($files['name'])) {
|
||
$processedFiles = array(); // Для отслеживания уже обработанных файлов
|
||
for ($i = 0; $i < count($files['name']); $i++) {
|
||
if ($files['error'][$i] == 0 && $files['name'][$i] != '' && $files['size'][$i] > 0) {
|
||
// Создаем уникальный ключ для файла (без tmp_name, так как он может отличаться для дубликатов)
|
||
$fileKey = $files['name'][$i] . '_' . $files['size'][$i];
|
||
|
||
// Проверяем что файл еще не был обработан
|
||
if (!isset($processedFiles[$fileKey])) {
|
||
$filesToProcess[] = [
|
||
'name' => $files['name'][$i],
|
||
'type' => $files['type'][$i],
|
||
'tmp_name' => $files['tmp_name'][$i],
|
||
'error' => $files['error'][$i],
|
||
'size' => $files['size'][$i],
|
||
'original_name' => $files['name'][$i]
|
||
];
|
||
$processedFiles[$fileKey] = true;
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] MODCOMMENTS_FILE_ADDED: ' . $files['name'][$i] . ', index=' . $i . PHP_EOL, FILE_APPEND);
|
||
} else {
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] MODCOMMENTS_FILE_DUPLICATE: ' . $files['name'][$i] . ', index=' . $i . ' - SKIPPED' . PHP_EOL, FILE_APPEND);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
// Очищаем $_FILES чтобы они не мешали сохранению комментария
|
||
unset($_FILES['filename']);
|
||
}
|
||
|
||
$recordModel = $this->getRecordModelFromRequest($request);
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] MODCOMMENTS_RECORDMODEL_OK: getRecordModelFromRequest success' . PHP_EOL, FILE_APPEND);
|
||
|
||
$recordModel->save();
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] MODCOMMENTS_SAVE_OK: recordModel->save() success, ID=' . $recordModel->getId() . PHP_EOL, FILE_APPEND);
|
||
|
||
// Обрабатываем файлы после сохранения комментария
|
||
if (!empty($filesToProcess)) {
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] MODCOMMENTS_PROCESSING_FILES: Comment ID=' . $recordModel->getId() . ', files count=' . count($filesToProcess) . PHP_EOL, FILE_APPEND);
|
||
|
||
require_once('data/CRMEntity.php');
|
||
$crmEntity = new CRMEntity();
|
||
|
||
// Обрабатываем сохраненные файлы
|
||
foreach ($filesToProcess as $file) {
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] MODCOMMENTS_FILE: ' . $file['name'] . ', size=' . $file['size'] . PHP_EOL, FILE_APPEND);
|
||
|
||
// Загружаем файл как Documents, а не ModComments
|
||
$attachmentId = $crmEntity->uploadAndSaveFile(null, 'Documents', $file, 'Attachment');
|
||
|
||
if ($attachmentId) {
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] MODCOMMENTS_FILE_SUCCESS: attachmentId=' . $attachmentId . PHP_EOL, FILE_APPEND);
|
||
|
||
// Связываем файл с комментарием через базу данных
|
||
global $adb;
|
||
$commentId = $recordModel->getId();
|
||
|
||
// Добавляем связь в vtiger_seattachmentsrel
|
||
$query = "INSERT INTO vtiger_seattachmentsrel (crmid, attachmentsid) VALUES (?, ?)";
|
||
$adb->pquery($query, array($commentId, $attachmentId));
|
||
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] MODCOMMENTS_LINK_CREATED: commentId=' . $commentId . ', attachmentId=' . $attachmentId . PHP_EOL, FILE_APPEND);
|
||
} else {
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] MODCOMMENTS_FILE_FAILED: ' . $file['name'] . PHP_EOL, FILE_APPEND);
|
||
}
|
||
}
|
||
}
|
||
|
||
} catch (Exception $e) {
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] MODCOMMENTS_SAVERECORD_ERROR: ' . $e->getMessage() . PHP_EOL, FILE_APPEND);
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] MODCOMMENTS_SAVERECORD_TRACE: ' . $e->getTraceAsString() . PHP_EOL, FILE_APPEND);
|
||
throw $e;
|
||
}
|
||
|
||
// 10.10.2023 Руденко И.Е. - ПОСЛЕ обработки файлов отправляем в whatsapp или телегу
|
||
$commentType = $request->get('commenttype');
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] MODCOMMENTS_COMMENTTYPE_AFTER_FILES: ' . $commentType . PHP_EOL, FILE_APPEND);
|
||
|
||
if ($commentType == 'WhatsApp') {
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] MODCOMMENTS_WHATSAPP_CALL_AFTER_FILES: ID=' . $recordModel->getId() . PHP_EOL, FILE_APPEND);
|
||
$result = WhatsAppSendComment($recordModel->getId(), $request->get('commentcontent'));
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] MODCOMMENTS_WHATSAPP_RESULT_AFTER_FILES: ' . $result . PHP_EOL, FILE_APPEND);
|
||
}
|
||
if ($commentType == 'Telegram') {
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] MODCOMMENTS_TELEGRAM_CALL_AFTER_FILES: ID=' . $recordModel->getId() . PHP_EOL, FILE_APPEND);
|
||
$result = TelegramSendComment($recordModel->getId(), $request->get('commentcontent'));
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] MODCOMMENTS_TELEGRAM_RESULT_AFTER_FILES: ' . $result . PHP_EOL, FILE_APPEND);
|
||
}
|
||
|
||
if($request->get('relationOperation')) {
|
||
$parentModuleName = $request->get('sourceModule');
|
||
$parentModuleModel = Vtiger_Module_Model::getInstance($parentModuleName);
|
||
$parentRecordId = $request->get('sourceRecord');
|
||
$relatedModule = $recordModel->getModule();
|
||
$relatedRecordId = $recordModel->getId();
|
||
|
||
$relationModel = Vtiger_Relation_Model::getInstance($parentModuleModel, $relatedModule);
|
||
$relationModel->addRelation($parentRecordId, $relatedRecordId);
|
||
}
|
||
|
||
return $recordModel;
|
||
}
|
||
|
||
/**
|
||
* Function to get the record model based on the request parameters
|
||
* @param Vtiger_Request $request
|
||
* @return Vtiger_Record_Model or Module specific Record Model instance
|
||
*/
|
||
public function getRecordModelFromRequest(Vtiger_Request $request) {
|
||
$recordModel = parent::getRecordModelFromRequest($request);
|
||
|
||
// DEBUG: Логирование данных модели в серверные логи
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] MODCOMMENTS_RECORD_MODEL: commentcontent=' . $request->getRaw('commentcontent') . PHP_EOL, FILE_APPEND);
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] MODCOMMENTS_RECORD_MODEL: is_private=' . $request->get('is_private') . PHP_EOL, FILE_APPEND);
|
||
file_put_contents('logs/debug.log', '[' . date('Y-m-d H:i:s') . '] MODCOMMENTS_RECORD_MODEL: channel=' . $request->get('commenttype') . PHP_EOL, FILE_APPEND);
|
||
|
||
// DEBUG: Логирование данных модели
|
||
error_log("=== RecordModel DEBUG ===");
|
||
error_log("Setting commentcontent: " . $request->getRaw('commentcontent'));
|
||
error_log("Setting is_private: " . $request->get('is_private'));
|
||
error_log("Setting channel: " . $request->get('commenttype'));
|
||
|
||
$recordModel->set('commentcontent', $request->getRaw('commentcontent'));
|
||
$recordModel->set('is_private', $request->get('is_private'));
|
||
$recordModel->set('channel', $request->get('commenttype'));
|
||
|
||
// DEBUG: Логирование финальных данных модели
|
||
error_log("Final recordModel data: " . print_r($recordModel->getData(), true));
|
||
error_log("=== RecordModel DEBUG END ===");
|
||
|
||
return $recordModel;
|
||
}
|
||
} |