Save all currently accumulated repository changes as a backup snapshot for Gitea so no local work is lost.
270 lines
9.2 KiB
PHP
270 lines
9.2 KiB
PHP
<?php
|
||
/**
|
||
* Поиск файла в S3 по различным вариантам
|
||
*/
|
||
|
||
error_reporting(E_ALL);
|
||
ini_set('display_errors', 1);
|
||
|
||
require_once 'config.inc.php';
|
||
require_once 'crm_extensions/file_storage/config.php';
|
||
require_once 'include/database/PearDatabase.php';
|
||
|
||
global $adb;
|
||
if (!$adb) {
|
||
$adb = PearDatabase::getInstance();
|
||
}
|
||
|
||
$recordId = 397217;
|
||
|
||
echo "=== Поиск файла для документа ID: $recordId ===\n\n";
|
||
|
||
// Получаем информацию о документе
|
||
$query = "SELECT s3_bucket, s3_key, filename, title, notecontent, filesize
|
||
FROM vtiger_notes
|
||
WHERE notesid = ?";
|
||
$result = $adb->pquery($query, array($recordId));
|
||
$row = $adb->fetchByAssoc($result, -1, false);
|
||
|
||
if (!$row) {
|
||
echo "❌ Документ не найден!\n";
|
||
exit(1);
|
||
}
|
||
|
||
$originalBucket = $row['s3_bucket'];
|
||
$originalKey = $row['s3_key'];
|
||
$filename = $row['filename'];
|
||
$title = $row['title'];
|
||
$notecontent = $row['notecontent'];
|
||
$filesize = $row['filesize'];
|
||
|
||
echo "📄 Информация о документе:\n";
|
||
echo " - Title: $title\n";
|
||
echo " - Original Bucket: $originalBucket\n";
|
||
echo " - Original Key: $originalKey\n";
|
||
echo " - Filename: $filename\n";
|
||
echo " - Filesize: $filesize байт\n";
|
||
echo " - Notecontent: $notecontent\n\n";
|
||
|
||
// Загружаем конфиг S3
|
||
$config = require 'crm_extensions/file_storage/config.php';
|
||
require_once 'vendor/autoload.php';
|
||
|
||
$awsClient = new Aws\S3\S3Client([
|
||
'version' => 'latest',
|
||
'region' => $config['s3']['region'],
|
||
'endpoint' => $config['s3']['endpoint'],
|
||
'use_path_style_endpoint' => $config['s3']['use_path_style_endpoint'],
|
||
'credentials' => [
|
||
'key' => $config['s3']['key'],
|
||
'secret' => $config['s3']['secret'],
|
||
],
|
||
]);
|
||
|
||
// Варианты для поиска
|
||
$searchVariants = [];
|
||
|
||
// 1. Оригинальный путь
|
||
$searchVariants[] = [
|
||
'bucket' => $originalBucket,
|
||
'key' => $originalKey,
|
||
'description' => 'Оригинальный путь из БД'
|
||
];
|
||
|
||
// 2. Извлекаем bucket из filename URL
|
||
if (preg_match('#https?://s3\.twcstorage\.ru/([^/]+)/(.+)#', $filename, $matches)) {
|
||
$searchVariants[] = [
|
||
'bucket' => $matches[1],
|
||
'key' => $matches[2],
|
||
'description' => 'Извлечено из filename URL'
|
||
];
|
||
}
|
||
|
||
// 3. Проверяем bucket из конфига
|
||
$configBucket = $config['s3']['bucket'];
|
||
if ($configBucket !== $originalBucket) {
|
||
$searchVariants[] = [
|
||
'bucket' => $configBucket,
|
||
'key' => $originalKey,
|
||
'description' => 'Bucket из конфига, key из БД'
|
||
];
|
||
}
|
||
|
||
// 4. Различные варианты пути (без префикса clientright/)
|
||
if (strpos($originalKey, 'clientright/') === 0) {
|
||
$keyWithoutPrefix = substr($originalKey, strlen('clientright/'));
|
||
$searchVariants[] = [
|
||
'bucket' => $originalBucket,
|
||
'key' => $keyWithoutPrefix,
|
||
'description' => 'Key без префикса clientright/'
|
||
];
|
||
|
||
// Также пробуем с bucket из конфига
|
||
$searchVariants[] = [
|
||
'bucket' => $configBucket,
|
||
'key' => $keyWithoutPrefix,
|
||
'description' => 'Bucket из конфига, key без префикса'
|
||
];
|
||
}
|
||
|
||
// 5. Пробуем найти файл по имени в разных bucket'ах
|
||
$fileNameFromKey = basename($originalKey);
|
||
$possibleBuckets = [$originalBucket, $configBucket];
|
||
|
||
foreach ($possibleBuckets as $bucket) {
|
||
// Ищем в корне bucket
|
||
$searchVariants[] = [
|
||
'bucket' => $bucket,
|
||
'key' => $fileNameFromKey,
|
||
'description' => "Файл в корне bucket $bucket"
|
||
];
|
||
|
||
// Ищем в clientright/
|
||
$searchVariants[] = [
|
||
'bucket' => $bucket,
|
||
'key' => 'clientright/' . $fileNameFromKey,
|
||
'description' => "Файл в clientright/ bucket $bucket"
|
||
];
|
||
|
||
// Ищем в clientright/0/
|
||
$searchVariants[] = [
|
||
'bucket' => $bucket,
|
||
'key' => 'clientright/0/' . $fileNameFromKey,
|
||
'description' => "Файл в clientright/0/ bucket $bucket"
|
||
];
|
||
}
|
||
|
||
// Удаляем дубликаты
|
||
$uniqueVariants = [];
|
||
foreach ($searchVariants as $variant) {
|
||
$key = $variant['bucket'] . '|' . $variant['key'];
|
||
if (!isset($uniqueVariants[$key])) {
|
||
$uniqueVariants[$key] = $variant;
|
||
}
|
||
}
|
||
$searchVariants = array_values($uniqueVariants);
|
||
|
||
echo "🔍 Проверяю " . count($searchVariants) . " вариантов...\n\n";
|
||
|
||
$found = false;
|
||
foreach ($searchVariants as $index => $variant) {
|
||
$bucket = $variant['bucket'];
|
||
$key = $variant['key'];
|
||
$description = $variant['description'];
|
||
|
||
echo "[" . ($index + 1) . "/" . count($searchVariants) . "] $description\n";
|
||
echo " Bucket: $bucket\n";
|
||
echo " Key: $key\n";
|
||
|
||
try {
|
||
$result = $awsClient->headObject([
|
||
'Bucket' => $bucket,
|
||
'Key' => $key
|
||
]);
|
||
|
||
echo " ✅ ФАЙЛ НАЙДЕН!\n";
|
||
echo " - ContentLength: " . ($result['ContentLength'] ?? 'N/A') . " байт\n";
|
||
echo " - ContentType: " . ($result['ContentType'] ?? 'N/A') . "\n";
|
||
echo " - LastModified: " . ($result['LastModified'] ?? 'N/A') . "\n";
|
||
echo " - ETag: " . ($result['ETag'] ?? 'N/A') . "\n\n";
|
||
|
||
// Генерируем presigned URL для проверки
|
||
$cmd = $awsClient->getCommand('GetObject', [
|
||
'Bucket' => $bucket,
|
||
'Key' => $key
|
||
]);
|
||
$request = $awsClient->createPresignedRequest($cmd, '+10 minutes');
|
||
$presignedUrl = (string)$request->getUri();
|
||
|
||
echo " 🔗 Presigned URL:\n";
|
||
echo " $presignedUrl\n\n";
|
||
|
||
// Проверяем доступность
|
||
$ch = curl_init($presignedUrl);
|
||
curl_setopt($ch, CURLOPT_NOBODY, true);
|
||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||
curl_exec($ch);
|
||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||
curl_close($ch);
|
||
|
||
if ($httpCode == 200) {
|
||
echo " ✅ URL работает! (HTTP $httpCode)\n\n";
|
||
|
||
// Предлагаем обновить БД
|
||
echo "💾 Предлагаю обновить запись в БД:\n";
|
||
echo " UPDATE vtiger_notes SET s3_bucket = '$bucket', s3_key = '$key' WHERE notesid = $recordId;\n\n";
|
||
|
||
$found = true;
|
||
break;
|
||
} else {
|
||
echo " ⚠️ URL не работает (HTTP $httpCode)\n\n";
|
||
}
|
||
|
||
} catch (Aws\S3\Exception\S3Exception $e) {
|
||
if ($e->getAwsErrorCode() == 'NoSuchKey' || $e->getAwsErrorCode() == 'NotFound') {
|
||
echo " ❌ Не найден\n";
|
||
} else if ($e->getAwsErrorCode() == '403' || $e->getStatusCode() == 403) {
|
||
echo " ⚠️ Доступ запрещен (403)\n";
|
||
} else {
|
||
echo " ❌ Ошибка: " . $e->getAwsErrorCode() . "\n";
|
||
}
|
||
} catch (Exception $e) {
|
||
echo " ❌ Исключение: " . $e->getMessage() . "\n";
|
||
}
|
||
|
||
echo "\n";
|
||
}
|
||
|
||
if (!$found) {
|
||
echo "❌ Файл не найден ни в одном из проверенных вариантов.\n\n";
|
||
|
||
// Пробуем поискать похожие файлы по имени
|
||
echo "🔍 Пробую найти похожие файлы по имени...\n";
|
||
$fileNameFromKey = basename($originalKey);
|
||
|
||
try {
|
||
// Список объектов в bucket
|
||
$result = $awsClient->listObjectsV2([
|
||
'Bucket' => $originalBucket,
|
||
'Prefix' => 'clientright/',
|
||
'MaxKeys' => 1000
|
||
]);
|
||
|
||
if (isset($result['Contents'])) {
|
||
$similarFiles = [];
|
||
foreach ($result['Contents'] as $object) {
|
||
$objectKey = $object['Key'];
|
||
$objectName = basename($objectKey);
|
||
|
||
// Ищем файлы с похожим именем или размером
|
||
if ($objectName == $fileNameFromKey ||
|
||
$object['Size'] == $filesize ||
|
||
strpos($objectName, pathinfo($fileNameFromKey, PATHINFO_FILENAME)) !== false) {
|
||
$similarFiles[] = [
|
||
'key' => $objectKey,
|
||
'size' => $object['Size'],
|
||
'modified' => $object['LastModified']
|
||
];
|
||
}
|
||
}
|
||
|
||
if (!empty($similarFiles)) {
|
||
echo " Найдено " . count($similarFiles) . " похожих файлов:\n";
|
||
foreach ($similarFiles as $file) {
|
||
echo " - Key: {$file['key']}\n";
|
||
echo " Size: {$file['size']} байт\n";
|
||
echo " Modified: {$file['modified']}\n\n";
|
||
}
|
||
} else {
|
||
echo " Похожие файлы не найдены.\n";
|
||
}
|
||
}
|
||
} catch (Exception $e) {
|
||
echo " Ошибка при поиске: " . $e->getMessage() . "\n";
|
||
}
|
||
}
|
||
|
||
echo "\n=== Поиск завершен ===\n";
|