'8_Договор_на_оказание_услуг_373981.pdf', 373983 => '9_Подтверждение_оплаты_по_договору_373983.pdf', 373985 => '10_2_Скрин_личного_кабинета_Истца_и_программа_обуч_373985.pdf', 373987 => '10_1_Скрин_личного_кабинета_Истца_и_программа_обуч_373987.pdf', 373989 => '11_1_Подтверждение_проведения_претензионной_работы_373989.pdf', 373991 => '7_заявление_потребителя_373991.pdf', 374017 => '11_Доказательство_соблюдения_претензионного_порядк_374017.pdf', 375402 => '11.2_Претензия_в_защиту_интересов_Полулях_Ольга_1_375402.pdf', 375404 => '11.3_Доказательство_оплаты_направления_претензии_о_375404.pdf', 375406 => '11.4_Доказательство_направления_претензии_ответчик_375406.pdf', 376051 => '0_Исковое_заявление_по_делу_Полулях_7_стр_376051.pdf', 376054 => '6_Расчет_исковых_требований_Полулях_1_стр_376054.pdf', 376080 => '12.1_Доказательство_оплаты_направления_иска_ответч_376080.pdf', 376082 => '12.2_Доказательство_направления_иска_ответчику_376082.pdf', ]; echo "=== ВОССТАНОВЛЕНИЕ ДОКУМЕНТОВ ПРОЕКТА {$projectId} ===\n"; echo str_repeat("=", 80) . "\n\n"; $dryRun = isset($argv[1]) && $argv[1] === '--dry-run'; if ($dryRun) { echo "⚠️ РЕЖИМ ПРОВЕРКИ (dry-run)\n\n"; } try { $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 ]); $stats = [ 'total' => count($files), 'restored' => 0, 'already_exists' => 0, 'no_versions' => 0, 'failed' => 0, ]; foreach ($files as $docId => $filename) { $key = $prefix . $filename; echo "Документ ID: {$docId}\n"; echo " Файл: {$filename}\n"; // Проверяем, существует ли файл if ($s3Client->doesObjectExist($s3Bucket, $key)) { echo " ✅ Файл уже существует\n\n"; $stats['already_exists']++; continue; } // Проверяем версии try { $versions = $s3Client->listObjectVersions([ 'Bucket' => $s3Bucket, 'Prefix' => $key, 'MaxKeys' => 10, ]); $deleteMarkers = $versions['DeleteMarkers'] ?? []; $fileVersions = $versions['Versions'] ?? []; if (empty($deleteMarkers) && empty($fileVersions)) { echo " ❌ Нет версий для восстановления\n\n"; $stats['no_versions']++; continue; } echo " Найдено delete markers: " . count($deleteMarkers) . "\n"; echo " Найдено версий: " . count($fileVersions) . "\n"; if (!$dryRun) { // Удаляем все delete markers foreach ($deleteMarkers as $marker) { try { $s3Client->deleteObject([ 'Bucket' => $s3Bucket, 'Key' => $key, 'VersionId' => $marker['VersionId'], ]); echo " ✅ Delete marker удален\n"; } catch (Exception $e) { echo " ⚠️ Ошибка удаления delete marker: " . $e->getMessage() . "\n"; } } // Проверяем, появился ли файл после удаления delete marker if (!$s3Client->doesObjectExist($s3Bucket, $key) && !empty($fileVersions)) { // Копируем последнюю версию $latestVersion = $fileVersions[0]; try { $s3Client->copyObject([ 'Bucket' => $s3Bucket, 'Key' => $key, 'CopySource' => "{$s3Bucket}/{$key}?versionId={$latestVersion['VersionId']}", ]); echo " ✅ Файл восстановлен из версии\n"; } catch (Exception $e) { echo " ⚠️ Ошибка копирования версии: " . $e->getMessage() . "\n"; } } else { echo " ✅ Файл восстановлен\n"; } $stats['restored']++; sleep(1); } else { echo " ⏸️ Будет восстановлен (dry-run)\n"; $stats['restored']++; } } catch (Exception $e) { echo " ❌ Ошибка: " . $e->getMessage() . "\n"; $stats['failed']++; } echo "\n"; } // Итоги echo str_repeat("=", 80) . "\n"; echo "ИТОГИ:\n"; echo "Всего файлов: {$stats['total']}\n"; if (!$dryRun) { echo "Восстановлено: {$stats['restored']}\n"; echo "Уже существует: {$stats['already_exists']}\n"; echo "Нет версий: {$stats['no_versions']}\n"; echo "Ошибок: {$stats['failed']}\n"; } else { echo "Будет восстановлено: {$stats['restored']}\n"; echo "Уже существует: {$stats['already_exists']}\n"; echo "Нет версий: {$stats['no_versions']}\n"; } echo "\n=== ГОТОВО ===\n"; } catch (Exception $e) { echo "❌ Критическая ошибка: " . $e->getMessage() . "\n"; exit(1); }