Files
crm.clientright.ru/crm_extensions/file_storage/migrate_all_projects.php
Fedor 9245768987 🚀 CRM Files Migration & Real-time Features
 Features:
- Migrated ALL files to new S3 structure (Projects, Contacts, Accounts, HelpDesk, Invoice, etc.)
- Added Nextcloud folder buttons to ALL modules
- Fixed Nextcloud editor integration
- WebSocket server for real-time updates
- Redis Pub/Sub integration
- File path manager for organized storage
- Redis caching for performance (Functions.php)

📁 New Structure:
Documents/Project/ProjectName_ID/file_docID.ext
Documents/Contacts/FirstName_LastName_ID/file_docID.ext
Documents/Accounts/AccountName_ID/file_docID.ext

🔧 Technical:
- FilePathManager for standardized paths
- S3StorageService integration
- WebSocket server (Node.js + Docker)
- Redis cache for getBasicModuleInfo()
- Predis library for Redis connectivity

📝 Scripts:
- Migration scripts for all modules
- Test pages for WebSocket/SSE/Polling
- Documentation (MIGRATION_*.md, REDIS_*.md)

🎯 Result: 15,000+ files migrated successfully!
2025-10-24 19:59:28 +03:00

246 lines
9.2 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
/**
* Миграция ВСЕХ проектов (архив, завершено, активные)
* Переносит файлы из старой структуры в новую: Project/название_ID/файл_docID.pdf
*/
// Включаем отображение ошибок
error_reporting(E_ALL);
ini_set('display_errors', 1);
echo "🚀 МИГРАЦИЯ ВСЕХ ПРОЕКТОВ\n";
echo "========================\n\n";
// Подключаем конфигурацию
require_once '/var/www/fastuser/data/www/crm.clientright.ru/config.inc.php';
require_once '/var/www/fastuser/data/www/crm.clientright.ru/vendor/autoload.php';
require_once '/var/www/fastuser/data/www/crm.clientright.ru/crm_extensions/file_storage/FilePathManager.php';
require_once '/var/www/fastuser/data/www/crm.clientright.ru/crm_extensions/shared/EnvLoader.php';
// Загружаем переменные окружения
EnvLoader::load('/var/www/fastuser/data/www/crm.clientright.ru/crm_extensions/.env');
// Создаем PDO подключение напрямую
try {
$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]
);
echo "✅ PDO подключен\n";
} catch (Exception $e) {
die("❌ Ошибка PDO: " . $e->getMessage() . "\n");
}
// S3 конфигурация
$s3Config = [
'version' => 'latest',
'region' => 'ru-1',
'endpoint' => 'https://s3.twcstorage.ru',
'bucket' => 'f9825c87-4e3558f6-f9b6-405c-ad3d-d1535c49b61c',
'use_path_style_endpoint' => true,
'key' => EnvLoader::getRequired('S3_ACCESS_KEY'),
'secret' => EnvLoader::getRequired('S3_SECRET_KEY')
];
try {
echo "🔧 Создаем S3 клиент...\n";
$s3 = new Aws\S3\S3Client($s3Config);
echo "✅ S3 подключен\n";
} catch (Exception $e) {
die("❌ Ошибка S3: " . $e->getMessage() . "\n");
}
echo "🔧 Создаем FilePathManager...\n";
$pathMgr = new FilePathManager();
echo "✅ FilePathManager создан\n";
// 1. Анализируем статусы проектов
echo "\n📊 АНАЛИЗ ПРОЕКТОВ:\n";
echo "===================\n";
$sql = "SELECT projectstatus, COUNT(*) as count FROM vtiger_project GROUP BY projectstatus ORDER BY count DESC";
$result = $pdo->query($sql);
$statusCounts = [];
while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
$statusCounts[$row['projectstatus']] = $row['count'];
echo "{$row['projectstatus']}: {$row['count']} проектов\n";
}
// 2. Получаем все проекты с файлами
echo "\n📁 ПОИСК ПРОЕКТОВ С ФАЙЛАМИ:\n";
echo "============================\n";
$sql = "SELECT DISTINCT p.projectid, p.projectname, p.projectstatus, p.projecttype,
COUNT(n.notesid) as file_count
FROM vtiger_project p
INNER JOIN vtiger_senotesrel sr ON p.projectid = sr.crmid
INNER JOIN vtiger_notes n ON sr.notesid = n.notesid
WHERE n.filelocationtype = 'E' AND n.s3_key IS NOT NULL
GROUP BY p.projectid, p.projectname, p.projectstatus, p.projecttype
ORDER BY p.projectstatus, p.projectname";
$result = $pdo->query($sql);
$projectsWithFiles = [];
while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
$projectsWithFiles[] = $row;
echo "{$row['projectname']} ({$row['projectstatus']}): {$row['file_count']} файлов\n";
}
echo "\n📈 ИТОГО: " . count($projectsWithFiles) . " проектов с файлами\n";
// 3. Подсчитываем общее количество файлов
$totalFiles = 0;
foreach ($projectsWithFiles as $project) {
$sql = "SELECT COUNT(*) as count FROM vtiger_notes n
INNER JOIN vtiger_senotesrel sr ON n.notesid = sr.notesid
WHERE sr.crmid = ? AND n.filelocationtype = 'E' AND n.s3_key IS NOT NULL";
$stmt = $pdo->prepare($sql);
$stmt->execute([$project['projectid']]);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$totalFiles += $row['count'];
}
echo "📁 ИТОГО ФАЙЛОВ: $totalFiles\n";
// 4. Спрашиваем пользователя
echo "\n❓ ВОПРОС:\n";
echo "===========\n";
echo "Мигрировать ВСЕ проекты? (y/n): ";
$handle = fopen("php://stdin", "r");
$line = fgets($handle);
fclose($handle);
if (trim(strtolower($line)) !== 'y') {
echo "❌ Миграция отменена\n";
exit;
}
// 5. Начинаем миграцию
echo "\n🚀 НАЧИНАЕМ МИГРАЦИЮ:\n";
echo "====================\n";
$migratedProjects = 0;
$migratedFiles = 0;
$errors = 0;
foreach ($projectsWithFiles as $project) {
$projectId = $project['projectid'];
$projectName = $project['projectname'];
$projectStatus = $project['projectstatus'];
echo "\n📁 Проект: $projectName (ID: $projectId, Статус: $projectStatus)\n";
// Получаем все файлы проекта
$sql = "SELECT n.notesid, n.title, n.filename, n.s3_key, n.s3_bucket
FROM vtiger_notes n
INNER JOIN vtiger_senotesrel sr ON n.notesid = sr.notesid
WHERE sr.crmid = ? AND n.filelocationtype = 'E' AND n.s3_key IS NOT NULL";
$stmt = $pdo->prepare($sql);
$stmt->execute([$projectId]);
$files = [];
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$files[] = $row;
}
echo " 📄 Файлов для миграции: " . count($files) . "\n";
$projectMigratedFiles = 0;
$projectErrors = 0;
foreach ($files as $file) {
$documentId = $file['notesid'];
$fileName = $file['filename'];
$oldS3Key = $file['s3_key'];
$title = $file['title'];
// Генерируем новый путь
$newFilePath = $pathMgr->getFilePath('Project', $projectId, $documentId, $fileName, $title, $projectName);
$newS3Key = $newFilePath;
// Проверяем, нужно ли мигрировать
if ($oldS3Key === $newS3Key) {
echo " ✅ Файл уже в новой структуре: $fileName\n";
$projectMigratedFiles++;
continue;
}
echo " 🔄 Мигрируем: $fileName\n";
echo " Старый путь: $oldS3Key\n";
echo " Новый путь: $newS3Key\n";
try {
// Проверяем существование старого файла
$oldUrl = "https://s3.twcstorage.ru/{$s3Config['bucket']}/{$oldS3Key}";
$headers = @get_headers($oldUrl);
if (!$headers || strpos($headers[0], '200') === false) {
echo " ⚠️ Файл не найден в S3: $oldUrl\n";
$projectErrors++;
continue;
}
// Скачиваем файл
$fileContent = file_get_contents($oldUrl);
if ($fileContent === false) {
echo "Не удалось скачать файл\n";
$projectErrors++;
continue;
}
// Загружаем в новое место
$uploadResult = $s3->putObject([
'Bucket' => $s3Config['bucket'],
'Key' => $newS3Key,
'Body' => $fileContent,
'ContentType' => mime_content_type('data://text/plain;base64,' . base64_encode($fileContent))
]);
// Обновляем БД
$updateSql = "UPDATE vtiger_notes SET s3_key = ? WHERE notesid = ?";
$updateStmt = $pdo->prepare($updateSql);
$updateStmt->execute([$newS3Key, $documentId]);
// Удаляем старый файл
try {
$s3->deleteObject([
'Bucket' => $s3Config['bucket'],
'Key' => $oldS3Key
]);
echo " ✅ Старый файл удален\n";
} catch (Exception $e) {
echo " ⚠️ Не удалось удалить старый файл: " . $e->getMessage() . "\n";
}
echo " ✅ Файл мигрирован успешно\n";
$projectMigratedFiles++;
} catch (Exception $e) {
echo " ❌ Ошибка миграции: " . $e->getMessage() . "\n";
$projectErrors++;
}
}
echo " 📊 Результат проекта: $projectMigratedFiles файлов мигрировано, $projectErrors ошибок\n";
$migratedProjects++;
$migratedFiles += $projectMigratedFiles;
$errors += $projectErrors;
}
// 6. Итоговая статистика
echo "\n🎉 МИГРАЦИЯ ЗАВЕРШЕНА!\n";
echo "======================\n";
echo "📁 Проектов обработано: $migratedProjects\n";
echo "📄 Файлов мигрировано: $migratedFiles\n";
echo "❌ Ошибок: $errors\n";
echo "✅ Успешность: " . round(($migratedFiles / ($migratedFiles + $errors)) * 100, 2) . "%\n";
echo "\n🚀 Все проекты мигрированы в новую структуру!\n";
?>