*/ // Zabezpieczenie – token musi być przekazany jako argument CLI lub GET param define('MIGRATION_TOKEN', getenv('MIGRATION_TOKEN') ?: 'CHANGE_BEFORE_USE'); $isCli = PHP_SAPI === 'cli'; header('Content-Type: text/plain; charset=utf-8'); // ---- Konfiguracja ---- $filesBaseDir = '/var/www/togethere.cloud/files'; $dbHost = 'localhost'; $dbName = 'togethere_cloud'; $dbUser = 'root'; $dbPass = 'HasloDoSQL'; // ---- Połączenie z bazą ---- try { $pdo = new PDO( "mysql:host=$dbHost;dbname=$dbName;charset=utf8mb4", $dbUser, $dbPass, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION] ); } catch (PDOException $e) { exit('Błąd połączenia z bazą: ' . $e->getMessage()); } /** * Przenieś BLOBy z danej tabeli na dysk. */ function migrate_table( PDO $pdo, string $filesBaseDir, string $table, string $subfolder, string $idColumn, string $taskIdColumn = '' ): void { echo "=== Migracja tabeli: $table (subfolder: $subfolder) ===\n"; // Sprawdź czy kolumna file_path istnieje $cols = $pdo->query("SHOW COLUMNS FROM `$table`")->fetchAll(PDO::FETCH_COLUMN); if (!in_array('file_path', $cols, true)) { echo "POMINIĘTO: kolumna file_path nie istnieje – uruchom najpierw file_storage_migration.sql\n\n"; return; } if (!in_array('file_data', $cols, true)) { echo "POMINIĘTO: kolumna file_data nie istnieje – migracja prawdopodobnie już wykonana\n\n"; return; } $targetDir = $filesBaseDir . '/' . ltrim($subfolder, '/'); if (!is_dir($targetDir) && !mkdir($targetDir, 0750, true)) { echo "BŁĄD: nie można utworzyć katalogu $targetDir\n\n"; return; } // Pobierz rekordy z BLOBem i bez file_path $stmt = $pdo->query( "SELECT $idColumn AS id, file_name, file_mime, file_data " . "FROM `$table` " . "WHERE file_data IS NOT NULL AND file_data <> '' " . " AND (file_path IS NULL OR file_path = '')" ); $migrated = 0; $errors = 0; while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { $id = (int)$row['id']; $origName = (string)($row['file_name'] ?? 'plik'); $ext = strtolower(pathinfo($origName, PATHINFO_EXTENSION)); $safeExts = ['jpg','jpeg','png','gif','webp','pdf','txt','zip','mp4','mp3','wav','doc','docx','xls','xlsx']; if (!in_array($ext, $safeExts, true)) { $ext = 'bin'; } $storedName = bin2hex(random_bytes(16)) . '.' . $ext; $filePath = $targetDir . '/' . $storedName; $dbPath = $subfolder . '/' . $storedName; // Zapisz na dysk $blob = $row['file_data']; if (is_resource($blob)) { $blob = stream_get_contents($blob); } if (file_put_contents($filePath, $blob) === false) { echo " BŁĄD [id=$id]: nie można zapisać pliku $filePath\n"; $errors++; continue; } chmod($filePath, 0640); // Zaktualizuj rekord w bazie $upd = $pdo->prepare( "UPDATE `$table` SET file_path = :fp WHERE $idColumn = :id" ); $upd->execute([':fp' => $dbPath, ':id' => $id]); echo " OK [id=$id] $origName -> $dbPath\n"; $migrated++; } echo "Zakończono: $migrated przeniesionych, $errors błędów.\n\n"; } // ---- Uruchom migrację dla każdej tabeli ---- migrate_table($pdo, $filesBaseDir, 'admin_chat_messages', 'admin_chat', 'id'); migrate_table($pdo, $filesBaseDir, 'admin_task_files', 'admin_tasks', 'id'); migrate_table($pdo, $filesBaseDir, 'admin_tasks', 'admin_tasks', 'id'); echo "=== Migracja zakończona. ===\n"; echo "Zweryfikuj dane, a następnie usuń kolumny file_data (patrz file_storage_migration.sql).\n";