правильный путь $filesToMove = [ // 394094 - Договор 'crm2/CRM_Active_Files/Documents/394094/doc_394094_d583b5d6.pdf' => [ 'new_path' => 'crm2/CRM_Active_Files/Documents/Project/Згурский_ООО_РЕНТСОФТ_394091/Договор_394094.pdf', 'doc_id' => 394094, ], // 394096 - Подтверждение оплаты 'crm2/CRM_Active_Files/Documents/394096/doc_394096_ce9e6bdc.pdf' => [ 'new_path' => 'crm2/CRM_Active_Files/Documents/Project/Згурский_ООО_РЕНТСОФТ_394091/Подтверждение_оплаты_394096.pdf', 'doc_id' => 394096, ], // 394100 - Ответ на претензию 'crm2/CRM_Active_Files/Documents/394100/doc_394100_3f15e3c1.pdf' => [ 'new_path' => 'crm2/CRM_Active_Files/Documents/Project/Згурский_ООО_РЕНТСОФТ_394091/Ответ_на_претензию_394100.pdf', 'doc_id' => 394100, ], // 394105 - Заявление потребителя 'crm2/CRM_Active_Files/Documents/394105/potrebitelya_Zgurskiy_1.pdf' => [ 'new_path' => 'crm2/CRM_Active_Files/Documents/Project/Згурский_ООО_РЕНТСОФТ_394091/7_заявление_потребителя_394105.pdf', 'doc_id' => 394105, ], ]; 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 ]); $db = PearDatabase::getInstance(); $stats = [ 'total' => count($filesToMove), 'moved' => 0, 'skipped' => 0, 'failed' => 0, 'errors' => [], ]; foreach ($filesToMove as $oldPath => $info) { $newPath = $info['new_path']; $docId = $info['doc_id']; echo "Документ ID: {$docId}\n"; echo " Старый путь: {$oldPath}\n"; echo " Новый путь: {$newPath}\n"; // Проверяем существование старого файла if (!$s3Client->doesObjectExist($s3Bucket, $oldPath)) { echo " ⚠️ Старый файл не найден, пропускаем\n\n"; $stats['skipped']++; continue; } // Проверяем, не существует ли уже новый файл if ($s3Client->doesObjectExist($s3Bucket, $newPath)) { echo " ⚠️ Новый файл уже существует, пропускаем\n\n"; $stats['skipped']++; continue; } if (!$dryRun) { try { // Копируем файл в новое место $s3Client->copyObject([ 'Bucket' => $s3Bucket, 'Key' => $newPath, 'CopySource' => "{$s3Bucket}/{$oldPath}", ]); echo " ✅ Файл скопирован в новое место\n"; // Удаляем старый файл $s3Client->deleteObject([ 'Bucket' => $s3Bucket, 'Key' => $oldPath, ]); echo " ✅ Старый файл удален\n"; // Обновляем БД $newFilename = 'https://s3.twcstorage.ru/' . $s3Bucket . '/' . $newPath; $db->pquery(" UPDATE vtiger_notes SET s3_key = ?, filename = ? WHERE notesid = ? ", array($newPath, $newFilename, $docId)); echo " ✅ БД обновлена\n"; $stats['moved']++; sleep(1); // Пауза между операциями } catch (Exception $e) { echo " ❌ Ошибка: " . $e->getMessage() . "\n"; $stats['failed']++; $stats['errors'][] = "{$oldPath}: " . $e->getMessage(); } } else { echo " ⏸️ Будет перемещен (dry-run)\n"; $stats['moved']++; } echo "\n"; } // Итоги echo str_repeat("=", 80) . "\n"; echo "ИТОГИ:\n"; echo "Всего файлов: {$stats['total']}\n"; if (!$dryRun) { echo "Перемещено: {$stats['moved']}\n"; echo "Пропущено: {$stats['skipped']}\n"; echo "Ошибок: {$stats['failed']}\n"; } else { echo "Будет перемещено: {$stats['moved']}\n"; echo "Будет пропущено: {$stats['skipped']}\n"; } if (!empty($stats['errors'])) { echo "\nОшибки:\n"; foreach ($stats['errors'] as $error) { echo " - {$error}\n"; } } echo "\n=== ГОТОВО ===\n"; } catch (Exception $e) { echo "❌ Критическая ошибка: " . $e->getMessage() . "\n"; exit(1); }