'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 ]); // Подключение к БД $pdo = new PDO( "mysql:host={$dbconfig['db_server']};port=3306;dbname={$dbconfig['db_name']};charset=utf8", $dbconfig['db_username'], $dbconfig['db_password'], [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION] ); // Получаем все документы проекта $stmt = $pdo->prepare(' SELECT n.notesid, n.title, n.s3_key, n.filename, n.filelocationtype FROM vtiger_notes n INNER JOIN vtiger_crmentity e ON e.crmid = n.notesid INNER JOIN vtiger_senotesrel snr ON snr.notesid = n.notesid WHERE snr.crmid = ? AND e.deleted = 0 ORDER BY n.notesid ASC '); $stmt->execute([$projectId]); $docs = $stmt->fetchAll(PDO::FETCH_ASSOC); echo "Всего документов в проекте: " . count($docs) . "\n\n"; $accessible = []; $notAccessible = []; foreach ($docs as $doc) { $docId = $doc['notesid']; $title = $doc['title']; $s3Key = $doc['s3_key']; $filelocationtype = $doc['filelocationtype']; echo "ID: $docId | $title\n"; if ($filelocationtype == 'E' && !empty($s3Key)) { // Проверяем доступность в S3 try { $result = $s3Client->headObject([ 'Bucket' => $s3Bucket, 'Key' => $s3Key ]); $size = number_format($result['ContentLength'] / 1024, 2); echo " ✅ Доступен в S3 (" . $size . " KB)\n"; echo " Путь: $s3Key\n"; $accessible[] = ['doc' => $doc, 'size' => $result['ContentLength']]; } catch (\Aws\Exception\AwsException $e) { if ($e->getAwsErrorCode() == 'NotFound') { echo " ❌ НЕ найден в S3\n"; echo " Ожидаемый путь: $s3Key\n"; $notAccessible[] = $doc; } else { echo " ⚠️ Ошибка доступа: " . $e->getAwsErrorCode() . "\n"; $notAccessible[] = $doc; } } } else { echo " ⚠️ Тип хранения: " . ($filelocationtype ?: 'не указан') . "\n"; if (!empty($doc['filename'])) { echo " Filename: " . substr($doc['filename'], 0, 100) . "\n"; } } echo "\n"; } echo str_repeat("=", 80) . "\n"; echo "СТАТИСТИКА:\n"; echo " Доступных файлов: " . count($accessible) . "\n"; echo " Недоступных файлов: " . count($notAccessible) . "\n\n"; // Поиск недоступных файлов в других местах S3 if (!empty($notAccessible)) { echo "Поиск недоступных файлов в других местах S3...\n\n"; foreach ($notAccessible as $doc) { $docId = $doc['notesid']; $title = $doc['title']; echo "Поиск файла для документа $docId: $title\n"; // Ищем по ID документа в разных местах $searchPatterns = [ "temp/$projectId/", "temp/", "crm2/CRM_Active_Files/Documents/", "Documents/", ]; $found = false; foreach ($searchPatterns 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) { // Проверяем доступность try { $headResult = $s3Client->headObject([ 'Bucket' => $s3Bucket, 'Key' => $key ]); echo " ✅ НАЙДЕН: $key\n"; echo " Размер: " . number_format($headResult['ContentLength'] / 1024, 2) . " KB\n"; echo " Дата: " . ($headResult['LastModified'] ?? 'не указана') . "\n"; // Предлагаем переместить echo " 💡 Рекомендация: переместить в правильный путь\n"; $found = true; break 2; } catch (\Aws\Exception\AwsException $e) { // Пропускаем } } } } } catch (\Aws\Exception\AwsException $e) { // Пропускаем ошибки } } if (!$found) { echo " ❌ Файл не найден ни в одном месте S3\n"; } echo "\n"; } } } catch (Exception $e) { echo "ОШИБКА: " . $e->getMessage() . "\n"; echo "Trace: " . $e->getTraceAsString() . "\n"; }