164 lines
7.8 KiB
PHP
164 lines
7.8 KiB
PHP
|
|
<?php
|
|||
|
|
error_reporting(E_ALL);
|
|||
|
|
ini_set('display_errors', 1);
|
|||
|
|
|
|||
|
|
require_once '/var/www/fastuser/data/www/crm.clientright.ru/vendor/autoload.php';
|
|||
|
|
require_once '/var/www/fastuser/data/www/crm.clientright.ru/config.inc.php';
|
|||
|
|
|
|||
|
|
$config = require '/var/www/fastuser/data/www/crm.clientright.ru/crm_extensions/file_storage/config.php';
|
|||
|
|
$docIds = [386869, 394973];
|
|||
|
|
$s3Bucket = $config['s3']['bucket'];
|
|||
|
|
|
|||
|
|
echo "Восстановление удаленных файлов из S3\n";
|
|||
|
|
echo str_repeat("=", 80) . "\n\n";
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
// Инициализация 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";
|
|||
|
|
|
|||
|
|
// Получаем информацию о документе
|
|||
|
|
$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";
|
|||
|
|
}
|
|||
|
|
|