togethere.cloud/public_html/administration/install_notes_chat.php

233 lines
10 KiB
PHP

<?php
require_once __DIR__ . '/includes/auth.php';
require_once __DIR__ . '/includes/config.php';
// Instalator/aktualizator tabel dla Dashboard: notatki + czat
// Po sukcesie najlepiej usunąć ten plik z serwera.
header('Content-Type: text/html; charset=utf-8');
function h($s) { return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); }
function tableExists(PDO $pdo, string $table): bool
{
$stmt = $pdo->prepare('SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = :t');
$stmt->execute([':t' => $table]);
return (int)$stmt->fetchColumn() > 0;
}
function columnExists(PDO $pdo, string $table, string $column): bool
{
$stmt = $pdo->prepare('SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = :t AND COLUMN_NAME = :c');
$stmt->execute([':t' => $table, ':c' => $column]);
return (int)$stmt->fetchColumn() > 0;
}
function ensureColumn(PDO $pdo, string $table, string $column, string $definition, array &$results): void
{
if (columnExists($pdo, $table, $column)) {
$results[] = ['ok' => true, 'sql' => "-- OK: $table.$column istnieje"];
return;
}
$sql = "ALTER TABLE `$table` ADD COLUMN `$column` $definition";
try {
$pdo->exec($sql);
$results[] = ['ok' => true, 'sql' => $sql];
} catch (Throwable $e) {
$results[] = ['ok' => false, 'sql' => $sql, 'error' => $e->getMessage()];
}
}
$results = [];
$ok = true;
// 1) CREATE TABLE IF NOT EXISTS
$sqlStatements = [
"CREATE TABLE IF NOT EXISTS admin_chat_messages (\n"
. " id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,\n"
. " user_id INT NOT NULL,\n"
. " username VARCHAR(100) NOT NULL,\n"
. " message TEXT NULL,\n"
. " reply_to_id BIGINT UNSIGNED NULL,\n"
. " file_name VARCHAR(255) NULL,\n"
. " file_mime VARCHAR(255) NULL,\n"
. " file_size BIGINT UNSIGNED NULL,\n"
. " file_data LONGBLOB NULL,\n"
. " is_hearted TINYINT(1) NOT NULL DEFAULT 0,\n"
. " hearted_by_user_id INT NULL,\n"
. " hearted_by_username VARCHAR(100) NULL,\n"
. " hearted_at TIMESTAMP NULL DEFAULT NULL,\n"
. " created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n"
. " updated_at TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,\n"
. " PRIMARY KEY (id),\n"
. " KEY idx_created_at (created_at),\n"
. " KEY idx_updated_at (updated_at),\n"
. " KEY idx_user_id (user_id),\n"
. " KEY idx_reply_to_id (reply_to_id),\n"
. " KEY idx_is_hearted (is_hearted)\n"
. ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;",
"CREATE TABLE IF NOT EXISTS admin_tasks (\n"
. " id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,\n"
. " title VARCHAR(255) NOT NULL,\n"
. " description TEXT NULL,\n\n"
. " is_done TINYINT(1) NOT NULL DEFAULT 0,\n"
. " done_at TIMESTAMP NULL DEFAULT NULL,\n"
. " done_by INT NULL,\n"
. " done_by_username VARCHAR(100) NULL,\n\n"
. " file_name VARCHAR(255) NULL,\n"
. " file_mime VARCHAR(255) NULL,\n"
. " file_size BIGINT UNSIGNED NULL,\n"
. " file_data LONGBLOB NULL,\n\n"
. " created_by INT NOT NULL,\n"
. " created_by_username VARCHAR(100) NOT NULL,\n"
. " created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n"
. " updated_at TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,\n\n"
. " PRIMARY KEY (id),\n"
. " KEY idx_created_at (created_at),\n"
. " KEY idx_created_by (created_by)\n"
. ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;",
"CREATE TABLE IF NOT EXISTS admin_task_files (\n"
. " id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,\n"
. " task_id BIGINT UNSIGNED NOT NULL,\n"
. " file_name VARCHAR(255) NOT NULL,\n"
. " file_mime VARCHAR(255) NULL,\n"
. " file_size BIGINT UNSIGNED NULL,\n"
. " file_data LONGBLOB NOT NULL,\n"
. " created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n"
. " PRIMARY KEY (id),\n"
. " KEY idx_task_id (task_id),\n"
. " KEY idx_created_at (created_at),\n"
. " CONSTRAINT fk_admin_task_files_task FOREIGN KEY (task_id) REFERENCES admin_tasks(id) ON DELETE CASCADE\n"
. ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;",
"CREATE TABLE IF NOT EXISTS admin_task_comments (\n"
. " id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,\n"
. " task_id BIGINT UNSIGNED NOT NULL,\n"
. " user_id INT NOT NULL,\n"
. " username VARCHAR(100) NOT NULL,\n"
. " comment TEXT NOT NULL,\n"
. " created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n"
. " updated_at TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,\n"
. " PRIMARY KEY (id),\n"
. " KEY idx_task_id (task_id),\n"
. " KEY idx_created_at (created_at),\n"
. " KEY idx_user_id (user_id),\n"
. " CONSTRAINT fk_admin_task_comments_task FOREIGN KEY (task_id) REFERENCES admin_tasks(id) ON DELETE CASCADE\n"
. ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;",
"CREATE TABLE IF NOT EXISTS admin_chat_typing (\n"
. " user_id INT NOT NULL,\n"
. " username VARCHAR(100) NOT NULL,\n"
. " updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,\n"
. " PRIMARY KEY (user_id),\n"
. " KEY idx_updated_at (updated_at)\n"
. ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;",
];
foreach ($sqlStatements as $sql) {
try {
$pdo->exec($sql);
$results[] = ['ok' => true, 'sql' => $sql];
} catch (Throwable $e) {
$ok = false;
$results[] = ['ok' => false, 'sql' => $sql, 'error' => $e->getMessage()];
}
}
// 2) Jeśli tabela czatu istniała wcześniej, dodać brakujące kolumny
if (tableExists($pdo, 'admin_chat_messages')) {
ensureColumn($pdo, 'admin_chat_messages', 'message', 'TEXT NULL', $results);
ensureColumn($pdo, 'admin_chat_messages', 'reply_to_id', 'BIGINT UNSIGNED NULL', $results);
ensureColumn($pdo, 'admin_chat_messages', 'file_name', 'VARCHAR(255) NULL', $results);
ensureColumn($pdo, 'admin_chat_messages', 'file_mime', 'VARCHAR(255) NULL', $results);
ensureColumn($pdo, 'admin_chat_messages', 'file_size', 'BIGINT UNSIGNED NULL', $results);
ensureColumn($pdo, 'admin_chat_messages', 'file_data', 'LONGBLOB NULL', $results);
ensureColumn($pdo, 'admin_chat_messages', 'is_hearted', 'TINYINT(1) NOT NULL DEFAULT 0', $results);
ensureColumn($pdo, 'admin_chat_messages', 'hearted_by_user_id', 'INT NULL', $results);
ensureColumn($pdo, 'admin_chat_messages', 'hearted_by_username', 'VARCHAR(100) NULL', $results);
ensureColumn($pdo, 'admin_chat_messages', 'hearted_at', 'TIMESTAMP NULL DEFAULT NULL', $results);
ensureColumn($pdo, 'admin_chat_messages', 'updated_at', 'TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP', $results);
// Upewnij się, że message może być NULL (starsze schematy mogły mieć NOT NULL)
$sql = 'ALTER TABLE `admin_chat_messages` MODIFY COLUMN `message` TEXT NULL';
try {
$pdo->exec($sql);
$results[] = ['ok' => true, 'sql' => $sql];
} catch (Throwable $e) {
$results[] = ['ok' => false, 'sql' => $sql, 'error' => $e->getMessage()];
$ok = false;
}
}
// 3) Jeśli tabela notatek istniała wcześniej, dodać brakujące kolumny statusu
if (tableExists($pdo, 'admin_tasks')) {
ensureColumn($pdo, 'admin_tasks', 'is_done', 'TINYINT(1) NOT NULL DEFAULT 0', $results);
ensureColumn($pdo, 'admin_tasks', 'done_at', 'TIMESTAMP NULL DEFAULT NULL', $results);
ensureColumn($pdo, 'admin_tasks', 'done_by', 'INT NULL', $results);
ensureColumn($pdo, 'admin_tasks', 'done_by_username', 'VARCHAR(100) NULL', $results);
}
// Szybki check końcowy
$mustHave = [
['admin_chat_messages', 'reply_to_id'],
['admin_chat_messages', 'file_data'],
['admin_chat_messages', 'is_hearted'],
['admin_chat_messages', 'updated_at'],
['admin_chat_typing', 'updated_at'],
['admin_tasks', 'is_done'],
['admin_task_files', 'task_id'],
['admin_task_comments', 'task_id'],
];
foreach ($mustHave as [$t, $c]) {
if (!tableExists($pdo, $t) || !columnExists($pdo, $t, $c)) {
$ok = false;
}
}
?>
<!doctype html>
<html lang="pl">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Instalator: notatki + czat</title>
<style>
body { font-family: Arial, sans-serif; background: #f1f1f1; padding: 20px; }
.box { background: #fff; border: 1px solid #ddd; border-radius: 6px; padding: 16px; max-width: 980px; }
.ok { color: #1e7e34; font-weight: 700; }
.bad { color: #b32d2e; font-weight: 700; }
pre { white-space: pre-wrap; background: #fafafa; border: 1px solid #eee; padding: 10px; border-radius: 6px; }
.hint { color: #666; font-size: 13px; }
</style>
</head>
<body>
<div class="box">
<h1>Instalator/aktualizator tabel: notatki (taski) + czat</h1>
<?php if ($ok): ?>
<p class="ok">OK: tabele/kolumny są gotowe.</p>
<?php else: ?>
<p class="bad">Błąd: nie wszystko wykonało się poprawnie.</p>
<?php endif; ?>
<h3>Szczegóły</h3>
<?php foreach ($results as $r): ?>
<p class="<?php echo $r['ok'] ? 'ok' : 'bad'; ?>"><?php echo $r['ok'] ? 'OK' : 'ERROR'; ?></p>
<pre><?php echo h($r['sql']); ?></pre>
<?php if (!$r['ok']): ?>
<pre><?php echo h($r['error'] ?? ''); ?></pre>
<?php endif; ?>
<hr />
<?php endforeach; ?>
<p class="hint">Po sukcesie usuń ten plik z serwera: <b>/administration/install_notes_chat.php</b>.</p>
<p><a href="/administration/index.php">Wróć do Dashboard</a></p>
</div>
</body>
</html>