Files
crm.clientright.ru/upload_documents_to_crm.php.backup

369 lines
14 KiB
Plaintext
Raw Permalink Normal View History

<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');
// Для POST запросов отключаем вывод ошибок в HTML
$IS_POST = ($_SERVER['REQUEST_METHOD'] === 'POST');
if ($IS_POST) {
ini_set('display_errors', '0');
ini_set('display_startup_errors', '0');
}
// Функция для записи в лог
function writeLog($message) {
$timestamp = date('Y-m-d H:i:s');
$line = "[$timestamp] $message\n";
// Пробуем писать в основной лог
@file_put_contents(__DIR__ . '/logs/upload_documents.log', $line, FILE_APPEND | LOCK_EX);
// И в /tmp как запасной вариант
@file_put_contents('/tmp/upload_documents.log', $line, FILE_APPEND | LOCK_EX);
// И в системный лог
error_log('[upload_documents] ' . $message);
}
// Функция для JSON ответа
function json_response($data, $code = 200) {
if (!headers_sent()) {
http_response_code($code);
header('Content-Type: application/json; charset=utf-8');
}
echo json_encode($data, JSON_UNESCAPED_UNICODE);
exit;
}
// Быстрый ping
if (isset($_GET['ping'])) {
header('Content-Type: text/plain; charset=utf-8');
echo 'pong';
exit;
}
// Для POST запросов регистрируем обработчик фатальных ошибок
if ($IS_POST) {
register_shutdown_function(function() {
$error = error_get_last();
if ($error && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) {
writeLog('FATAL: ' . $error['message'] . ' in ' . $error['file'] . ':' . $error['line']);
json_response([
'success' => false,
'error' => [
'type' => 'fatal',
'message' => 'Internal error'
]
], 500);
}
});
}
// Инициализация CRM
require_once 'config.inc.php';
require_once 'include/utils/utils.php';
require_once 'includes/Loader.php';
vimport('includes.runtime.Globals');
require_once 'include/database/PearDatabase.php';
require_once 'modules/Users/Users.php';
require_once 'include/Webservices/Utils.php';
require_once 'include/Webservices/Create.php';
require_once 'include/Webservices/Login.php';
require_once 'include/Webservices/AuthToken.php';
require_once 'include/Webservices/AddRelated.php';
$adb = PearDatabase::getInstance();
// Вспомогательные функции из test_ws_documents.php
function getUserWsPrefix() {
global $adb;
$rs = $adb->pquery("SELECT id FROM vtiger_ws_entity WHERE name=?", ['Users']);
return ($rs && $adb->num_rows($rs) > 0) ? $adb->query_result($rs, 0, 'id') : 19;
}
function getProjectWsIdFromDB($projectId) {
global $adb;
$rs = $adb->pquery("SELECT id FROM vtiger_ws_entity WHERE name=?", ['Project']);
return ($rs && $adb->num_rows($rs) > 0) ? $adb->query_result($rs, 0, 'id') . 'x' . (int)$projectId : null;
}
function getDocumentFoldersWsPrefix() {
global $adb;
$rs = $adb->pquery("SELECT id FROM vtiger_ws_entity WHERE name=?", ['DocumentFolders']);
return ($rs && $adb->num_rows($rs) > 0) ? (int)$adb->query_result($rs, 0, 'id') : 22;
}
function getFolderWsIdByName($folderName) {
global $adb;
$rs = $adb->pquery('SELECT folderid FROM vtiger_attachmentsfolder WHERE foldername = ? LIMIT 1', [$folderName]);
if ($rs && $adb->num_rows($rs) > 0) {
$folderId = (int)$adb->query_result($rs, 0, 'folderid');
$prefix = getDocumentFoldersWsPrefix();
return $prefix . 'x' . $folderId;
}
return null;
}
// Основная функция для создания документов
function createDocumentsInCRM($filesArray, $userName = 'api') {
global $adb, $current_user;
writeLog('🚀 Начинаем создание документов...');
// 1. Получаем access key пользователя
$rs = $adb->pquery('SELECT id, accesskey FROM vtiger_users WHERE user_name=?', [$userName]);
if (!$rs || $adb->num_rows($rs) == 0) {
writeLog("❌ Пользователь $userName не найден");
return ['error' => "Пользователь $userName не найден"];
}
$userId = $adb->query_result($rs, 0, 'id');
$accessKey = $adb->query_result($rs, 0, 'accesskey');
// 2. Получаем challenge token
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$endpointUrl = 'https://crm.clientright.ru/webservice.php';
// getchallenge
curl_setopt($ch, CURLOPT_URL, $endpointUrl . '?operation=getchallenge&username=' . urlencode($userName));
$resp = curl_exec($ch);
if ($resp === false) {
writeLog('❌ CURL error: ' . curl_error($ch));
return ['error' => 'Network error'];
}
$resp = ltrim($resp, "\xEF\xBB\xBF\x00\x09\x0A\x0D\x20");
$challenge = json_decode($resp, true);
if (!$challenge || empty($challenge['result']['token'])) {
writeLog('❌ Invalid challenge response: ' . substr($resp, 0, 100));
return ['error' => 'Authentication failed'];
}
$token = $challenge['result']['token'];
// 3. Логинимся
$key = md5($token . $accessKey);
curl_setopt($ch, CURLOPT_URL, $endpointUrl);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, [
'operation' => 'login',
'username' => $userName,
'accessKey' => $key,
]);
$resp = curl_exec($ch);
if ($resp === false) {
writeLog('❌ CURL error: ' . curl_error($ch));
return ['error' => 'Network error'];
}
$resp = ltrim($resp, "\xEF\xBB\xBF\x00\x09\x0A\x0D\x20");
$login = json_decode($resp, true);
if (!$login || empty($login['result']['sessionName'])) {
writeLog('❌ Login failed: ' . substr($resp, 0, 100));
return ['error' => 'Authentication failed'];
}
$sessionId = $login['result']['sessionName'];
// 4. Устанавливаем current_user для CRMEntity
$current_user = new Users();
$current_user->retrieveCurrentUserInfoFromFile((int)$userId);
// 5. Создаём документы
$results = [];
foreach ($filesArray as $i => $f) {
writeLog("📄 Обрабатываем файл #{$i}: " . ($f['file_name'] ?? 'Unknown'));
try {
// Получаем WS ID проекта
$projectWsId = getProjectWsIdFromDB((int)$f['projectid']);
if (!$projectWsId) {
throw new Exception("Не найден Project ID {$f['projectid']}");
}
// WS ID пользователя
$usersPrefix = getUserWsPrefix();
$assignedUserWsId = $usersPrefix . 'x' . (int)$f['user_id'];
// Папка (сначала Суд, потом Default)
$folderWsId = getFolderWsIdByName('Суд');
if (!$folderWsId) {
$folderWsId = '22x1';
writeLog("⚠️ Папка 'Суд' не найдена, используем Default");
}
// Создаём документ
$docElement = [
'notes_title' => $f['description'] ?: $f['file_name'],
'filename' => $f['url'],
'assigned_user_id' => $assignedUserWsId,
'notecontent' => 'Авто из S3. Контакт: ' . ($f['contactid'] ?? ''),
'filetype' => 'application/pdf',
'filesize' => '0',
'filelocationtype' => 'E',
'fileversion' => '1.0',
'filestatus' => '1',
'folderid' => $folderWsId,
];
curl_setopt($ch, CURLOPT_POSTFIELDS, [
'operation' => 'create',
'sessionName' => $sessionId,
'elementType' => 'Documents',
'element' => json_encode($docElement, JSON_UNESCAPED_UNICODE),
]);
$resp = curl_exec($ch);
if ($resp === false) {
throw new Exception('CURL error: ' . curl_error($ch));
}
$resp = ltrim($resp, "\xEF\xBB\xBF\x00\x09\x0A\x0D\x20");
$doc = json_decode($resp, true);
if (!$doc || empty($doc['result']['id'])) {
throw new Exception('Failed to create document: ' . substr($resp, 0, 100));
}
$documentWsId = $doc['result']['id'];
// Привязываем к проекту
curl_setopt($ch, CURLOPT_POSTFIELDS, [
'operation' => 'AddRelated',
'sessionName' => $sessionId,
'sourceRecordId' => $projectWsId,
'relatedRecordId' => $documentWsId,
]);
$resp = curl_exec($ch);
// Проверяем успех AddRelated
$ok = false;
if ($resp !== false) {
$resp = ltrim($resp, "\xEF\xBB\xBF\x00\x09\x0A\x0D\x20");
$rel = json_decode($resp, true);
$ok = isset($rel['result']['message']) && $rel['result']['message'] === 'successfull';
}
// Если webservice не сработал - используем прямую привязку
if (!$ok) {
writeLog("⚠️ AddRelated не сработал, используем прямую привязку");
require_once 'data/CRMEntity.php';
require_once 'modules/Vtiger/CRMEntity.php';
list(, $docNumericId) = explode('x', $documentWsId, 2);
$focus = CRMEntity::getInstance('Project');
relateEntities($focus, 'Project', (int)$f['projectid'], 'Documents', (int)$docNumericId);
}
// Возвращаем все входные данные + результат
$result = array_merge($f, [
'status' => 'success',
'crm_result' => [
'document_id' => $documentWsId,
'document_numeric_id' => $docNumericId,
'project_id' => $f['projectid'],
'folder_id' => $folderWsId,
'message' => 'Документ создан и привязан к проекту' . (!$ok ? ' (прямая привязка)' : '')
]
]);
$results[] = $result;
writeLog("✅ Документ {$f['file_name']} успешно создан и привязан");
} catch (Exception $e) {
writeLog("❌ Ошибка для файла {$f['file_name']}: " . $e->getMessage());
// В случае ошибки тоже возвращаем все входные данные
$results[] = array_merge($f, [
'status' => 'error',
'crm_result' => [
'message' => $e->getMessage()
]
]);
}
}
curl_close($ch);
return $results;
}
// Обработка запроса
if ($IS_POST) {
writeLog('=== START POST REQUEST ===');
writeLog('Headers: ' . json_encode(getallheaders(), JSON_UNESCAPED_UNICODE));
// Получаем и проверяем входные данные
$input = file_get_contents('php://input');
writeLog('Raw input: ' . substr($input, 0, 1000) . (strlen($input) > 1000 ? '...(truncated)' : ''));
$input = ltrim($input, "\xEF\xBB\xBF\x00\x09\x0A\x0D\x20");
$data = json_decode($input, true);
if (json_last_error() !== JSON_ERROR_NONE) {
writeLog('❌ JSON Error: ' . json_last_error_msg());
json_response([
'success' => false,
'error' => ['message' => 'Invalid JSON: ' . json_last_error_msg()]
], 400);
}
writeLog('Parsed data: ' . json_encode($data, JSON_UNESCAPED_UNICODE));
// Нормализуем формат данных
$filesArray = $data;
// Проверяем массив
if (!is_array($filesArray)) {
writeLog('❌ Error: Input is not an array');
json_response([
'success' => false,
'error' => ['message' => 'Input must be an array of files']
], 400);
}
writeLog('Processing ' . count($filesArray) . ' files...');
// Создаём документы
$results = createDocumentsInCRM($filesArray);
// Проверяем результат
if (isset($results['error'])) {
writeLog('❌ Error: ' . $results['error']);
json_response([
'success' => false,
'error' => ['message' => $results['error']]
], 500);
}
// Успешный ответ
writeLog('✅ Success: processed ' . count($results) . ' files');
json_response([
'success' => true,
'total_processed' => count($filesArray),
'results' => $results
]);
} else {
// GET запрос - тестовый режим
$testData = [
[
'session_token' => 'sess_test',
'group_session_token' => 'token_test',
'user_id' => 1,
'group' => 'group_0',
'contactid' => 120374,
'files_count' => 2,
'group_index_num' => 0,
'description' => 'Иск',
'projectid' => 354918,
'telegram_id' => 295410106,
'unified_id' => 'usr_test',
'pages' => 2,
'url' => 'https://s3.twcstorage.ru/f9825c87-4e3558f6-f9b6-405c-ad3d-d1535c49b61c/clientright/120374/1757346451126.pdf',
'file_name' => '1757346451126.pdf',
'field_name' => '120374',
'folder' => 'clientright/120374',
'newfile' => 'clientright/120374/1757346451126.pdf'
]
];
$results = createDocumentsInCRM($testData);
header('Content-Type: application/json; charset=utf-8');
echo json_encode([
'success' => true,
'total_processed' => count($testData),
'results' => $results
], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
}
?>