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 $request - values of the record * @return - 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; } }