131 lines
4.4 KiB
PHP
131 lines
4.4 KiB
PHP
<?php
|
||
declare(strict_types=1);
|
||
/**
|
||
* Skrypt migracji: przenosi istniejące pliki z BLOB (file_data)
|
||
* na dysk do katalogu /var/www/togethere.cloud/files/.
|
||
*
|
||
* Uruchom raz po zastosowaniu file_storage_migration.sql.
|
||
* Dostępny tylko z IP serwera lub przez terminal – chroń go przed publicznym dostępem!
|
||
*
|
||
* Uruchomienie z CLI:
|
||
* php /var/www/togethere.cloud/public_html/administration/migrate_blobs_to_disk.php
|
||
*
|
||
* Lub przez przeglądarkę (tylko localhost):
|
||
* https://togethere.cloud/administration/migrate_blobs_to_disk.php?token=<MIGRATION_TOKEN>
|
||
*/
|
||
|
||
// 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";
|