Files
crm.clientright.ru/crm_extensions/file_storage/analyze_broken_files_detailed.php

321 lines
12 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* Детальный анализ "битых" файлов
*
* Анализирует файлы, которые есть в БД, но физически отсутствуют
* Проверяет зависимости, категоризирует и дает рекомендации
*/
require_once '/var/www/fastuser/data/www/crm.clientright.ru/config.inc.php';
$mysqli = new mysqli($dbconfig['db_server'], $dbconfig['db_username'], $dbconfig['db_password'], $dbconfig['db_name']);
if ($mysqli->connect_error) {
die("Connection failed: " . $mysqli->connect_error);
}
$mysqli->set_charset("utf8");
echo "=== ДЕТАЛЬНЫЙ АНАЛИЗ БИТЫХ ФАЙЛОВ ===\n";
echo "Дата анализа: " . date('Y-m-d H:i:s') . "\n\n";
// Получаем все "битые" файлы
$query = "SELECT notesid, filename, filesize, filetype, filelocationtype
FROM vtiger_notes
WHERE filelocationtype = 'I'
AND (s3_key IS NULL OR s3_key = '')
ORDER BY notesid ASC";
$result = $mysqli->query($query);
$totalBroken = $result->num_rows;
echo "Всего битых файлов: $totalBroken\n";
echo "==========================================\n\n";
// Анализируем по категориям
$categories = [
'empty_filename' => [],
'zero_size' => [],
'duplicate_names' => [],
'file_15_series' => [],
'evidence_files' => [],
'old_files' => [],
'pdf_files' => [],
'image_files' => [],
'other' => []
];
$filenameCounts = [];
$fileTypes = [];
$sizeRanges = [
'0 bytes' => 0,
'1-1KB' => 0,
'1-10KB' => 0,
'10-100KB' => 0,
'100KB-1MB' => 0,
'1MB+' => 0
];
$idRanges = [
'1-1000' => 0,
'1000-10000' => 0,
'10000-50000' => 0,
'50000-100000' => 0,
'100000+' => 0
];
while ($row = $result->fetch_assoc()) {
$notesid = $row['notesid'];
$filename = $row['filename'];
$filesize = $row['filesize'];
$filetype = $row['filetype'];
// Подсчет по размерам
if ($filesize == 0) {
$sizeRanges['0 bytes']++;
} elseif ($filesize < 1024) {
$sizeRanges['1-1KB']++;
} elseif ($filesize < 10240) {
$sizeRanges['1-10KB']++;
} elseif ($filesize < 102400) {
$sizeRanges['10-100KB']++;
} elseif ($filesize < 1048576) {
$sizeRanges['100KB-1MB']++;
} else {
$sizeRanges['1MB+']++;
}
// Подсчет по ID диапазонам
if ($notesid <= 1000) {
$idRanges['1-1000']++;
} elseif ($notesid <= 10000) {
$idRanges['1000-10000']++;
} elseif ($notesid <= 50000) {
$idRanges['10000-50000']++;
} elseif ($notesid <= 100000) {
$idRanges['50000-100000']++;
} else {
$idRanges['100000+']++;
}
// Подсчет типов файлов
$fileTypes[$filetype] = ($fileTypes[$filetype] ?? 0) + 1;
// Подсчет имен файлов
$filenameCounts[$filename] = ($filenameCounts[$filename] ?? 0) + 1;
// Категоризация
if (empty($filename) || $filename == '') {
$categories['empty_filename'][] = $row;
} elseif ($filesize == 0) {
$categories['zero_size'][] = $row;
} elseif (strpos($filename, 'file_15_') === 0) {
$categories['file_15_series'][] = $row;
} elseif (strpos($filename, 'доказательство') !== false || strpos($filename, 'evidence') !== false) {
$categories['evidence_files'][] = $row;
} elseif (strpos($filename, '7777777') !== false) {
$categories['old_files'][] = $row;
} elseif (strtolower(pathinfo($filename, PATHINFO_EXTENSION)) == 'pdf') {
$categories['pdf_files'][] = $row;
} elseif (in_array(strtolower(pathinfo($filename, PATHINFO_EXTENSION)), ['jpg', 'jpeg', 'png', 'gif'])) {
$categories['image_files'][] = $row;
} else {
$categories['other'][] = $row;
}
}
// Выводим статистику по размерам
echo "РАСПРЕДЕЛЕНИЕ ПО РАЗМЕРАМ:\n";
foreach ($sizeRanges as $range => $count) {
if ($count > 0) {
$percentage = round(($count / $totalBroken) * 100, 1);
echo " $range: $count файлов ($percentage%)\n";
}
}
echo "\n";
// Выводим статистику по ID диапазонам
echo "РАСПРЕДЕЛЕНИЕ ПО ID ДИАПАЗОНАМ:\n";
foreach ($idRanges as $range => $count) {
if ($count > 0) {
$percentage = round(($count / $totalBroken) * 100, 1);
echo " ID $range: $count файлов ($percentage%)\n";
}
}
echo "\n";
// Выводим статистику по типам файлов
echo "РАСПРЕДЕЛЕНИЕ ПО ТИПАМ ФАЙЛОВ:\n";
arsort($fileTypes);
foreach ($fileTypes as $type => $count) {
$percentage = round(($count / $totalBroken) * 100, 1);
echo " $type: $count файлов ($percentage%)\n";
}
echo "\n";
// Выводим дубликаты имен
echo "ДУБЛИКАТЫ ИМЕН ФАЙЛОВ (топ-10):\n";
$duplicates = array_filter($filenameCounts, function($count) { return $count > 1; });
arsort($duplicates);
$duplicateCount = 0;
foreach ($duplicates as $filename => $count) {
if ($duplicateCount >= 10) break;
echo " '$filename': $count раз\n";
$duplicateCount++;
}
if (count($duplicates) > 10) {
echo " ... и еще " . (count($duplicates) - 10) . " дубликатов\n";
}
echo "\n";
// Выводим категории
echo "КАТЕГОРИИ ФАЙЛОВ:\n";
foreach ($categories as $category => $files) {
if (count($files) > 0) {
$percentage = round((count($files) / $totalBroken) * 100, 1);
echo " $category: " . count($files) . " файлов ($percentage%)\n";
// Показываем примеры для каждой категории
if (count($files) <= 5) {
foreach ($files as $file) {
echo " - ID: {$file['notesid']}, File: {$file['filename']}, Size: {$file['filesize']}\n";
}
} else {
echo " Примеры:\n";
for ($i = 0; $i < 3; $i++) {
$file = $files[$i];
echo " - ID: {$file['notesid']}, File: {$file['filename']}, Size: {$file['filesize']}\n";
}
echo " ... и еще " . (count($files) - 3) . " файлов\n";
}
echo "\n";
}
}
// Проверяем зависимости
echo "ПРОВЕРКА ЗАВИСИМОСТЕЙ:\n";
// Проверяем vtiger_attachments
$attachmentQuery = "SELECT COUNT(*) as count FROM vtiger_attachments WHERE notesid IN (
SELECT notesid FROM vtiger_notes
WHERE filelocationtype = 'I'
AND (s3_key IS NULL OR s3_key = '')
)";
$attachmentResult = $mysqli->query($attachmentQuery);
$attachmentCount = $attachmentResult->fetch_assoc()['count'];
echo " Записи в vtiger_attachments: $attachmentCount\n";
// Проверяем vtiger_crmentity
$crmentityQuery = "SELECT COUNT(*) as count FROM vtiger_crmentity WHERE crmid IN (
SELECT notesid FROM vtiger_notes
WHERE filelocationtype = 'I'
AND (s3_key IS NULL OR s3_key = '')
)";
$crmentityResult = $mysqli->query($crmentityQuery);
$crmentityCount = $crmentityResult->fetch_assoc()['count'];
echo " Записи в vtiger_crmentity: $crmentityCount\n";
// Проверяем связи с другими модулями
$relationsQuery = "SELECT COUNT(*) as count FROM vtiger_crmentityrel WHERE crmid IN (
SELECT notesid FROM vtiger_notes
WHERE filelocationtype = 'I'
AND (s3_key IS NULL OR s3_key = '')
)";
$relationsResult = $mysqli->query($relationsQuery);
$relationsCount = $relationsResult->fetch_assoc()['count'];
echo " Связи в vtiger_crmentityrel: $relationsCount\n";
// Проверяем vtiger_seattachmentsrel
$seattachmentsQuery = "SELECT COUNT(*) as count FROM vtiger_seattachmentsrel WHERE attachmentsid IN (
SELECT notesid FROM vtiger_notes
WHERE filelocationtype = 'I'
AND (s3_key IS NULL OR s3_key = '')
)";
$seattachmentsResult = $mysqli->query($seattachmentsQuery);
$seattachmentsCount = $seattachmentsResult->fetch_assoc()['count'];
echo " Связи в vtiger_seattachmentsrel: $seattachmentsCount\n";
echo "\n";
// Анализ безопасности удаления
echo "=== АНАЛИЗ БЕЗОПАСНОСТИ УДАЛЕНИЯ ===\n";
$safeToDelete = 0;
$needsCheck = 0;
// Файлы с пустыми именами - безопасно удалять
if (count($categories['empty_filename']) > 0) {
$safeToDelete += count($categories['empty_filename']);
echo "✅ БЕЗОПАСНО УДАЛИТЬ: " . count($categories['empty_filename']) . " файлов с пустыми именами\n";
}
// Файлы размером 0 байт - безопасно удалять
if (count($categories['zero_size']) > 0) {
$safeToDelete += count($categories['zero_size']);
echo "✅ БЕЗОПАСНО УДАЛИТЬ: " . count($categories['zero_size']) . " файлов размером 0 байт\n";
}
// Старые тестовые файлы - безопасно удалять
if (count($categories['file_15_series']) > 0) {
$safeToDelete += count($categories['file_15_series']);
echo "✅ БЕЗОПАСНО УДАЛИТЬ: " . count($categories['file_15_series']) . " старых тестовых файлов (file_15_*)\n";
}
// Файлы без зависимостей
if ($attachmentCount == 0 && $crmentityCount == 0 && $relationsCount == 0 && $seattachmentsCount == 0) {
echo "✅ БЕЗОПАСНО УДАЛИТЬ: Все файлы не имеют зависимостей в других таблицах\n";
$safeToDelete = $totalBroken;
} else {
echo "⚠️ ТРЕБУЕТ ПРОВЕРКИ: " . ($attachmentCount + $crmentityCount + $relationsCount + $seattachmentsCount) . " файлов имеют зависимости\n";
$needsCheck = $totalBroken - $safeToDelete;
}
echo "\n";
// Рекомендации
echo "=== РЕКОМЕНДАЦИИ ===\n";
if ($safeToDelete > 0) {
echo "🗑️ МОЖНО УДАЛИТЬ БЕЗОПАСНО: $safeToDelete файлов\n";
echo " - Файлы с пустыми именами\n";
echo " - Файлы размером 0 байт\n";
echo " - Старые тестовые файлы\n";
}
if ($needsCheck > 0) {
echo "🔍 ТРЕБУЕТ ПРОВЕРКИ: $needsCheck файлов\n";
echo " - Проверить зависимости в других таблицах\n";
echo " - Возможно, архивировать вместо удаления\n";
}
if (count($duplicates) > 0) {
echo "🔄 ДУБЛИКАТЫ: " . count($duplicates) . " файлов с одинаковыми именами\n";
echo " - Проверить, какие из них реально нужны\n";
}
echo "\n";
// SQL команды для очистки
echo "=== SQL КОМАНДЫ ДЛЯ ОЧИСТКИ ===\n";
if ($safeToDelete > 0) {
echo "-- Безопасное удаление файлов с пустыми именами\n";
echo "DELETE FROM vtiger_notes WHERE filelocationtype = 'I' AND (s3_key IS NULL OR s3_key = '') AND (filename IS NULL OR filename = '');\n\n";
echo "-- Безопасное удаление файлов размером 0 байт\n";
echo "DELETE FROM vtiger_notes WHERE filelocationtype = 'I' AND (s3_key IS NULL OR s3_key = '') AND filesize = 0;\n\n";
echo "-- Безопасное удаление старых тестовых файлов\n";
echo "DELETE FROM vtiger_notes WHERE filelocationtype = 'I' AND (s3_key IS NULL OR s3_key = '') AND filename LIKE 'file_15_%';\n\n";
}
if ($attachmentCount == 0 && $crmentityCount == 0 && $relationsCount == 0 && $seattachmentsCount == 0) {
echo "-- Удаление всех битых файлов (если нет зависимостей)\n";
echo "DELETE FROM vtiger_notes WHERE filelocationtype = 'I' AND (s3_key IS NULL OR s3_key = '');\n\n";
}
echo "=== АНАЛИЗ ЗАВЕРШЕН ===\n";
echo "Всего проанализировано: $totalBroken файлов\n";
echo "Безопасно удалить: $safeToDelete файлов\n";
echo "Требует проверки: $needsCheck файлов\n";
$mysqli->close();
?>