'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"; // Получаем информацию о документе $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 notesid, title, s3_key, s3_etag FROM vtiger_notes WHERE notesid = ?'); $stmt->execute([$docId]); $doc = $stmt->fetch(PDO::FETCH_ASSOC); if (!$doc) { echo " Документ не найден в БД\n\n"; continue; } $s3Key = $doc['s3_key']; echo " Название: {$doc['title']}\n"; echo " Путь: $s3Key\n\n"; // Получаем delete markers try { $versions = $s3Client->listObjectVersions([ 'Bucket' => $s3Bucket, 'Prefix' => $s3Key, 'MaxKeys' => 100 ]); if (isset($versions['DeleteMarkers']) && !empty($versions['DeleteMarkers'])) { echo " Найдено delete markers: " . count($versions['DeleteMarkers']) . "\n"; // Удаляем все delete markers (самый новый будет удален последним) // Сортируем по дате удаления (от новых к старым) usort($versions['DeleteMarkers'], function($a, $b) { $dateA = isset($a['LastModified']) ? strtotime($a['LastModified']) : 0; $dateB = isset($b['LastModified']) ? strtotime($b['LastModified']) : 0; return $dateB - $dateA; // От новых к старым }); foreach ($versions['DeleteMarkers'] as $marker) { $versionId = $marker['VersionId']; $deleteDate = $marker['LastModified'] ?? 'не указана'; echo " Удаление delete marker: VersionId=$versionId (дата удаления: $deleteDate)\n"; try { $s3Client->deleteObject([ 'Bucket' => $s3Bucket, 'Key' => $s3Key, 'VersionId' => $versionId ]); echo " ✅ Delete marker удален\n"; } catch (\Aws\Exception\AwsException $e) { echo " ❌ Ошибка при удалении delete marker: " . $e->getMessage() . "\n"; } } // Проверяем, восстановился ли файл echo "\n Проверка восстановления файла...\n"; try { $headResult = $s3Client->headObject([ 'Bucket' => $s3Bucket, 'Key' => $s3Key ]); echo " ✅ Файл успешно восстановлен!\n"; echo " Размер: " . number_format($headResult['ContentLength'] / 1024, 2) . " KB\n"; echo " ETag: " . (isset($headResult['ETag']) ? trim($headResult['ETag'], '"') : 'не указан') . "\n"; echo " Дата: " . ($headResult['LastModified'] ?? 'не указана') . "\n"; } catch (\Aws\Exception\AwsException $e) { if ($e->getAwsErrorCode() == 'NotFound') { echo " ⚠️ Файл все еще не доступен (возможно, нужно восстановить конкретную версию)\n"; // Пробуем восстановить последнюю версию напрямую if (isset($versions['Versions']) && !empty($versions['Versions'])) { $latestVersion = $versions['Versions'][0]; // Первая версия - самая новая $versionId = $latestVersion['VersionId']; echo " Попытка восстановить версию: VersionId=$versionId\n"; try { // Копируем версию в текущий объект $s3Client->copyObject([ 'Bucket' => $s3Bucket, 'CopySource' => $s3Bucket . '/' . $s3Key . '?versionId=' . $versionId, 'Key' => $s3Key ]); echo " ✅ Версия восстановлена\n"; // Проверяем еще раз $headResult = $s3Client->headObject([ 'Bucket' => $s3Bucket, 'Key' => $s3Key ]); echo " ✅ Файл восстановлен и доступен!\n"; echo " Размер: " . number_format($headResult['ContentLength'] / 1024, 2) . " KB\n"; } catch (\Aws\Exception\AwsException $e) { echo " ❌ Ошибка при восстановлении версии: " . $e->getMessage() . "\n"; } } } else { echo " ❌ Ошибка при проверке: " . $e->getMessage() . "\n"; } } } else { echo " ❌ Delete markers не найдены\n"; } } catch (\Aws\Exception\AwsException $e) { echo " ❌ Ошибка при работе с версиями: " . $e->getMessage() . "\n"; } echo "\n"; } echo str_repeat("=", 80) . "\n"; echo "Восстановление завершено!\n"; echo "Проверьте доступность файлов в интерфейсе CRM\n"; } catch (Exception $e) { echo "ОШИБКА: " . $e->getMessage() . "\n"; echo "Trace: " . $e->getTraceAsString() . "\n"; }