PDO::ERRMODE_EXCEPTION] ); $stmt = $pdo->prepare('SELECT notesid, title, s3_key, filename, filelocationtype FROM vtiger_notes WHERE notesid = ?'); $stmt->execute([$docId]); $doc = $stmt->fetch(PDO::FETCH_ASSOC); if (!$doc) { die("Документ $docId не найден в БД\n"); } echo "Информация о документе:\n"; echo " ID: {$doc['notesid']}\n"; echo " Название: {$doc['title']}\n"; echo " S3 Key (ожидаемый): " . ($doc['s3_key'] ?: 'не указан') . "\n"; echo " Filename: " . substr($doc['filename'], 0, 150) . "\n"; echo " Тип хранения: " . ($doc['filelocationtype'] ?: 'не указан') . "\n\n"; // Инициализация S3 клиента $s3Client = new \Aws\S3\S3Client([ 'version' => 'latest', 'region' => $config['s3']['region'], 'endpoint' => $config['s3']['endpoint'], 'use_path_style_endpoint' => true, 'credentials' => [ 'key' => $config['s3']['key'], 'secret' => $config['s3']['secret'], ], 'suppress_php_deprecation_warning' => true ]); $foundFiles = []; // 1. Проверяем ожидаемый путь echo "1. Проверка ожидаемого пути в S3...\n"; if (!empty($doc['s3_key'])) { try { $result = $s3Client->headObject([ 'Bucket' => $s3Bucket, 'Key' => $doc['s3_key'] ]); echo " ✅ Файл найден по ожидаемому пути!\n"; echo " Путь: {$doc['s3_key']}\n"; echo " Размер: " . number_format($result['ContentLength'] / 1024, 2) . " KB\n"; $foundFiles[] = [ 'key' => $doc['s3_key'], 'size' => $result['ContentLength'], 'source' => 'ожидаемый путь' ]; } catch (\Aws\Exception\AwsException $e) { echo " ❌ Файл не найден по ожидаемому пути: " . $e->getAwsErrorCode() . "\n"; } } echo "\n"; // 2. Поиск по точному ID документа echo "2. Поиск файлов с точным ID $docId...\n"; $searchPatterns = [ (string)$docId, (string)($docId - 1), (string)($docId + 1), (string)($docId - 2), (string)($docId + 2), ]; $totalChecked = 0; $maxFilesToCheck = 50000; foreach ($searchPatterns as $pattern) { echo " Поиск по паттерну: $pattern\n"; try { $isTruncated = true; $continuationToken = null; $pageCount = 0; $maxPages = 50; while ($isTruncated && $pageCount < $maxPages && $totalChecked < $maxFilesToCheck) { $params = [ 'Bucket' => $s3Bucket, 'MaxKeys' => 1000 ]; if ($continuationToken) { $params['ContinuationToken'] = $continuationToken; } $objects = $s3Client->listObjectsV2($params); $pageCount++; $totalChecked += isset($objects['Contents']) ? count($objects['Contents']) : 0; if (isset($objects['Contents'])) { foreach ($objects['Contents'] as $object) { $key = $object['Key']; // Ищем файлы, содержащие паттерн if (strpos($key, $pattern) !== false) { // Проверяем, не добавили ли уже этот файл $alreadyAdded = false; foreach ($foundFiles as $found) { if ($found['key'] === $key) { $alreadyAdded = true; break; } } if (!$alreadyAdded) { try { $headResult = $s3Client->headObject([ 'Bucket' => $s3Bucket, 'Key' => $key ]); echo " ✅ НАЙДЕН: $key\n"; echo " Размер: " . number_format($headResult['ContentLength'] / 1024, 2) . " KB\n"; echo " Дата: " . ($headResult['LastModified'] ?? 'не указана') . "\n"; $foundFiles[] = [ 'key' => $key, 'size' => $headResult['ContentLength'], 'source' => "поиск по ID $pattern", 'date' => $headResult['LastModified'] ?? null ]; } catch (\Aws\Exception\AwsException $e) { // Пропускаем недоступные файлы } } } } } $isTruncated = isset($objects['IsTruncated']) && $objects['IsTruncated']; $continuationToken = isset($objects['NextContinuationToken']) ? $objects['NextContinuationToken'] : null; if (!$isTruncated) { break; } } } catch (\Aws\Exception\AwsException $e) { echo " Ошибка при поиске: " . $e->getMessage() . "\n"; } } echo " Проверено файлов: $totalChecked\n\n"; // 3. Поиск по ключевым словам из названия документа echo "3. Поиск по ключевым словам из названия...\n"; $title = mb_strtolower($doc['title']); $keywords = []; // Извлекаем ключевые слова if (strpos($title, 'исковое') !== false) $keywords[] = 'iskovoe'; if (strpos($title, 'заявление') !== false) $keywords[] = 'zayavlenie'; if (strpos($title, 'марсель') !== false) $keywords[] = 'marse'; if (strpos($title, 'гафиев') !== false) $keywords[] = 'gafiev'; if (strpos($title, 'gafiev') !== false) $keywords[] = 'gafiev'; echo " Ключевые слова: " . implode(', ', $keywords) . "\n"; if (!empty($keywords)) { // Ищем в temp/ папках try { $objects = $s3Client->listObjectsV2([ 'Bucket' => $s3Bucket, 'Prefix' => 'temp/', 'MaxKeys' => 10000 ]); if (isset($objects['Contents'])) { foreach ($objects['Contents'] as $object) { $key = $object['Key']; $keyLower = mb_strtolower($key); // Проверяем совпадение по ключевым словам $matches = 0; foreach ($keywords as $keyword) { if (strpos($keyLower, $keyword) !== false) { $matches++; } } // Если совпало хотя бы 2 ключевых слова if ($matches >= 2) { $alreadyAdded = false; foreach ($foundFiles as $found) { if ($found['key'] === $key) { $alreadyAdded = true; break; } } if (!$alreadyAdded) { try { $headResult = $s3Client->headObject([ 'Bucket' => $s3Bucket, 'Key' => $key ]); echo " ✅ НАЙДЕН по ключевым словам: $key\n"; echo " Размер: " . number_format($headResult['ContentLength'] / 1024, 2) . " KB\n"; $foundFiles[] = [ 'key' => $key, 'size' => $headResult['ContentLength'], 'source' => 'поиск по ключевым словам', 'date' => $headResult['LastModified'] ?? null ]; } catch (\Aws\Exception\AwsException $e) { // Пропускаем } } } } } } catch (\Aws\Exception\AwsException $e) { echo " Ошибка при поиске: " . $e->getMessage() . "\n"; } } echo "\n"; // 4. Поиск в папке проекта (если известен projectId) echo "4. Поиск в папке проекта...\n"; $stmt = $pdo->prepare('SELECT crmid FROM vtiger_senotesrel WHERE notesid = ? LIMIT 1'); $stmt->execute([$docId]); $projectRel = $stmt->fetch(PDO::FETCH_ASSOC); if ($projectRel) { $projectId = $projectRel['crmid']; echo " Проект ID: $projectId\n"; $projectPrefixes = [ "crm2/CRM_Active_Files/Documents/Project/", "temp/$projectId/", ]; foreach ($projectPrefixes as $prefix) { try { $objects = $s3Client->listObjectsV2([ 'Bucket' => $s3Bucket, 'Prefix' => $prefix, 'MaxKeys' => 1000 ]); if (isset($objects['Contents'])) { foreach ($objects['Contents'] as $object) { $key = $object['Key']; // Ищем файлы с ID документа if (strpos($key, (string)$docId) !== false || strpos($key, (string)($docId - 1)) !== false || strpos($key, (string)($docId + 1)) !== false) { $alreadyAdded = false; foreach ($foundFiles as $found) { if ($found['key'] === $key) { $alreadyAdded = true; break; } } if (!$alreadyAdded) { try { $headResult = $s3Client->headObject([ 'Bucket' => $s3Bucket, 'Key' => $key ]); echo " ✅ НАЙДЕН в папке проекта: $key\n"; echo " Размер: " . number_format($headResult['ContentLength'] / 1024, 2) . " KB\n"; $foundFiles[] = [ 'key' => $key, 'size' => $headResult['ContentLength'], 'source' => "папка проекта $projectId", 'date' => $headResult['LastModified'] ?? null ]; } catch (\Aws\Exception\AwsException $e) { // Пропускаем } } } } } } catch (\Aws\Exception\AwsException $e) { // Пропускаем ошибки } } } echo "\n"; // Итоги echo str_repeat("=", 80) . "\n"; echo "ИТОГОВЫЕ РЕЗУЛЬТАТЫ:\n"; echo " Всего найдено файлов: " . count($foundFiles) . "\n\n"; if (!empty($foundFiles)) { echo "НАЙДЕННЫЕ ФАЙЛЫ:\n"; foreach ($foundFiles as $i => $file) { echo " " . ($i + 1) . ". {$file['key']}\n"; echo " Размер: " . number_format($file['size'] / 1024, 2) . " KB\n"; echo " Источник: {$file['source']}\n"; if ($file['date']) { echo " Дата: {$file['date']}\n"; } echo "\n"; } // Определяем наиболее вероятный файл echo "💡 РЕКОМЕНДАЦИЯ:\n"; $bestMatch = null; foreach ($foundFiles as $file) { if ($file['source'] === 'ожидаемый путь') { $bestMatch = $file; break; } } if (!$bestMatch && !empty($foundFiles)) { // Берем первый найденный файл $bestMatch = $foundFiles[0]; } if ($bestMatch) { echo " Наиболее вероятный файл: {$bestMatch['key']}\n"; echo " Этот файл можно использовать для обновления s3_key в БД\n"; } } else { echo " ❌ Файлы не найдены в S3\n"; echo " Возможно, файл находится в Nextcloud или локальном хранилище\n"; } } catch (Exception $e) { echo "ОШИБКА: " . $e->getMessage() . "\n"; echo "Trace: " . $e->getTraceAsString() . "\n"; }