PDO::ERRMODE_EXCEPTION] ); // Инициализация 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 ]); foreach ($docIds as $docId) { echo "Поиск файла для документа $docId:\n"; echo str_repeat("-", 80) . "\n"; $stmt = $pdo->prepare('SELECT notesid, title, s3_key, s3_etag, filesize FROM vtiger_notes WHERE notesid = ?'); $stmt->execute([$docId]); $doc = $stmt->fetch(PDO::FETCH_ASSOC); if (!$doc) { echo " Документ не найден в БД\n\n"; continue; } echo " Название: {$doc['title']}\n"; echo " Ожидаемый путь: {$doc['s3_key']}\n"; echo " ETag: {$doc['s3_etag']}\n"; echo " Размер: " . number_format($doc['filesize'] / 1024, 2) . " KB\n\n"; $s3Key = $doc['s3_key']; $targetEtag = trim($doc['s3_etag'], '"'); $targetSize = $doc['filesize']; // 1. Проверяем версии объекта (если включено versioning) echo " 1. Проверка версий объекта...\n"; try { $versions = $s3Client->listObjectVersions([ 'Bucket' => $s3Bucket, 'Prefix' => $s3Key, 'MaxKeys' => 100 ]); if (isset($versions['Versions']) && !empty($versions['Versions'])) { echo " ✅ Найдено версий: " . count($versions['Versions']) . "\n"; foreach ($versions['Versions'] as $version) { $versionKey = $version['Key']; $versionId = $version['VersionId']; $isDeleteMarker = isset($version['IsDeleteMarker']) && $version['IsDeleteMarker']; $versionEtag = isset($version['ETag']) ? trim($version['ETag'], '"') : null; $versionSize = isset($version['Size']) ? $version['Size'] : null; if ($isDeleteMarker) { echo " ⚠️ Delete Marker: VersionId=$versionId, Дата: " . ($version['LastModified'] ?? 'не указана') . "\n"; } else { $matchInfo = []; if ($versionEtag === $targetEtag) { $matchInfo[] = "ETag совпадает"; } if ($versionSize && abs($versionSize - $targetSize) <= 100) { $matchInfo[] = "размер совпадает (" . number_format($versionSize / 1024, 2) . " KB)"; } echo " ✅ Версия: VersionId=$versionId\n"; echo " Размер: " . ($versionSize ? number_format($versionSize / 1024, 2) . " KB" : 'не указан') . "\n"; echo " ETag: " . ($versionEtag ?: 'не указан') . "\n"; echo " Дата: " . ($version['LastModified'] ?? 'не указана') . "\n"; if (!empty($matchInfo)) { echo " " . implode(', ', $matchInfo) . "\n"; } echo "\n"; } } } else { echo " ❌ Версии не найдены (возможно, versioning не включен)\n"; } } catch (\Aws\Exception\AwsException $e) { if ($e->getAwsErrorCode() == 'AccessDenied' || strpos($e->getMessage(), 'versioning') !== false) { echo " ⚠️ Версионирование не включено или нет доступа: " . $e->getAwsErrorCode() . "\n"; } else { echo " ❌ Ошибка: " . $e->getMessage() . "\n"; } } echo "\n"; // 2. Проверяем delete markers echo " 2. Проверка delete markers...\n"; try { $deleteMarkers = $s3Client->listObjectVersions([ 'Bucket' => $s3Bucket, 'Prefix' => $s3Key, 'MaxKeys' => 100 ]); if (isset($deleteMarkers['DeleteMarkers']) && !empty($deleteMarkers['DeleteMarkers'])) { echo " ✅ Найдено delete markers: " . count($deleteMarkers['DeleteMarkers']) . "\n"; foreach ($deleteMarkers['DeleteMarkers'] as $marker) { echo " ⚠️ Delete Marker найден:\n"; echo " VersionId: " . ($marker['VersionId'] ?? 'не указан') . "\n"; echo " Дата удаления: " . ($marker['LastModified'] ?? 'не указана') . "\n"; echo " Ключ: " . ($marker['Key'] ?? 'не указан') . "\n"; echo "\n"; echo " 💡 Файл был удален, но можно восстановить, удалив delete marker\n"; } } else { echo " ❌ Delete markers не найдены\n"; } } catch (\Aws\Exception\AwsException $e) { echo " ⚠️ Ошибка при проверке delete markers: " . $e->getAwsErrorCode() . "\n"; } echo "\n"; // 3. Проверяем папки с названиями типа trash, deleted, recycle и т.д. echo " 3. Поиск в папках корзины...\n"; $trashPrefixes = [ 'trash/', 'deleted/', 'recycle/', '.trash/', 'deleted_files/', 'removed/', ]; $foundInTrash = false; foreach ($trashPrefixes as $trashPrefix) { try { $objects = $s3Client->listObjectsV2([ 'Bucket' => $s3Bucket, 'Prefix' => $trashPrefix, 'MaxKeys' => 1000 ]); if (isset($objects['Contents'])) { foreach ($objects['Contents'] as $object) { $key = $object['Key']; // Ищем файлы с ID документа или похожим размером if (strpos($key, (string)$docId) !== false || (isset($object['Size']) && abs($object['Size'] - $targetSize) <= 100)) { try { $headResult = $s3Client->headObject([ 'Bucket' => $s3Bucket, 'Key' => $key ]); $fileEtag = isset($headResult['ETag']) ? trim($headResult['ETag'], '"') : null; echo " ✅ НАЙДЕН в $trashPrefix:\n"; echo " Путь: $key\n"; echo " Размер: " . number_format($headResult['ContentLength'] / 1024, 2) . " KB\n"; echo " ETag: " . ($fileEtag ?: 'не указан') . "\n"; if ($fileEtag === $targetEtag) { echo " ✅ ТОЧНОЕ СОВПАДЕНИЕ ПО ETAG!\n"; } $foundInTrash = true; echo "\n"; } catch (\Aws\Exception\AwsException $e) { // Пропускаем } } } } } catch (\Aws\Exception\AwsException $e) { // Пропускаем ошибки } } if (!$foundInTrash) { echo " ❌ Файлы не найдены в папках корзины\n"; } echo "\n"; // 4. Проверяем, может быть файл был перемещен в другую папку проекта echo " 4. Поиск по ETag во всех папках проекта...\n"; $projectId = 384256; // Из предыдущих запросов $projectPrefixes = [ "crm2/CRM_Active_Files/Documents/Project/Гафиев_ООО_ЭДЭКС_$projectId/", "temp/$projectId/", ]; $foundByEtag = false; 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']; try { $headResult = $s3Client->headObject([ 'Bucket' => $s3Bucket, 'Key' => $key ]); $fileEtag = isset($headResult['ETag']) ? trim($headResult['ETag'], '"') : null; if ($fileEtag === $targetEtag) { echo " ✅ НАЙДЕН ПО ETAG в $prefix:\n"; echo " Путь: $key\n"; echo " Размер: " . number_format($headResult['ContentLength'] / 1024, 2) . " KB\n"; echo " ETag: $fileEtag\n"; echo " 💡 Это точно нужный файл!\n"; $foundByEtag = true; echo "\n"; } } catch (\Aws\Exception\AwsException $e) { // Пропускаем } } } } catch (\Aws\Exception\AwsException $e) { // Пропускаем ошибки } } if (!$foundByEtag) { echo " ❌ Файл с таким ETag не найден в папках проекта\n"; } echo "\n"; } } catch (Exception $e) { echo "ОШИБКА: " . $e->getMessage() . "\n"; echo "Trace: " . $e->getTraceAsString() . "\n"; }