'; } elseif ($isFa) { return ''; } else { return '' . htmlspecialchars($icon) . ''; } } requireLogin(); $user = getCurrentUser(); $current_user_id = $user['id']; // Fetch servers user is member of $stmt = db()->prepare(" SELECT s.* FROM servers s JOIN server_members sm ON s.id = sm.server_id WHERE sm.user_id = ? LIMIT 20 "); $stmt->execute([$current_user_id]); $servers = $stmt->fetchAll(); $is_dm_view = (isset($_GET['server_id']) && $_GET['server_id'] == 'dms') || !isset($_GET['server_id']) && empty($servers); if ($is_dm_view) { $active_server_id = 'dms'; // Fetch DM channels $stmt = db()->prepare(" SELECT c.id, u.username as other_user, u.avatar_url, u.status, u.id as other_user_id FROM channels c JOIN channel_members cm1 ON c.id = cm1.channel_id JOIN channel_members cm2 ON c.id = cm2.channel_id JOIN users u ON cm2.user_id = u.id WHERE c.type = 'dm' AND cm1.user_id = ? AND cm2.user_id != ? "); $stmt->execute([$current_user_id, $current_user_id]); $dm_channels = $stmt->fetchAll(); $active_channel_id = $_GET['channel_id'] ?? ($dm_channels[0]['id'] ?? 0); $channel_theme = null; // DMs don't have custom themes for now if ($active_channel_id) { // Fetch DM messages $stmt = db()->prepare(" SELECT m.*, u.username, u.avatar_url FROM messages m JOIN users u ON m.user_id = u.id WHERE m.channel_id = ? ORDER BY m.created_at ASC LIMIT 50 "); $stmt->execute([$active_channel_id]); $messages = $stmt->fetchAll(); $current_channel_name = 'Direct Message'; foreach($dm_channels as $dm) { if ($dm['id'] == $active_channel_id) { $current_channel_name = $dm['other_user']; break; } } } else { $messages = []; $current_channel_name = 'Direct Messages'; } $channels = []; $members = []; // Members list is different for DMs or hidden } else { $active_server_id = $_GET['server_id'] ?? ($servers[0]['id'] ?? 1); // Fetch channels $stmt = db()->prepare("SELECT * FROM channels WHERE server_id = ? ORDER BY position ASC, id ASC"); $stmt->execute([$active_server_id]); $all_channels = $stmt->fetchAll(); require_once 'includes/permissions.php'; $channels = []; foreach($all_channels as $c) { if (Permissions::canViewChannel($current_user_id, $c['id'])) { $channels[] = $c; } } $active_channel_id = $_GET['channel_id'] ?? ($channels[0]['id'] ?? 0); // Fetch active channel details for theme $active_channel = null; foreach($channels as $c) { if($c['id'] == $active_channel_id) { $active_channel = $c; break; } } $is_owner = false; $can_manage_channels = false; $can_manage_server = false; $active_server = null; foreach($servers as $s) { if($s['id'] == $active_server_id) { $active_server = $s; $is_owner = ($s['owner_id'] == $current_user_id); $can_manage_channels = Permissions::hasPermission($current_user_id, $active_server_id, Permissions::MANAGE_CHANNELS) || $is_owner; $can_manage_server = Permissions::hasPermission($current_user_id, $active_server_id, Permissions::MANAGE_SERVER) || Permissions::hasPermission($current_user_id, $active_server_id, Permissions::ADMINISTRATOR) || $is_owner; break; } } $channel_theme = $active_server['theme_color'] ?? null; $channel_type = $active_channel['type'] ?? 'chat'; $active_thread_id = $_GET['thread_id'] ?? null; $active_thread = null; if ($active_thread_id) { $stmt = db()->prepare("SELECT t.*, u.username FROM forum_threads t JOIN users u ON t.user_id = u.id WHERE t.id = ?"); $stmt->execute([$active_thread_id]); $active_thread = $stmt->fetch(); if ($active_thread) { $stmt = db()->prepare(" SELECT m.*, u.username, u.avatar_url, (SELECT r.color FROM roles r JOIN user_roles ur ON r.id = ur.role_id WHERE ur.user_id = u.id AND r.server_id = ? ORDER BY r.position DESC LIMIT 1) as role_color, (SELECT r.icon_url FROM roles r JOIN user_roles ur ON r.id = ur.role_id WHERE ur.user_id = u.id AND r.server_id = ? ORDER BY r.position DESC LIMIT 1) as role_icon FROM messages m JOIN users u ON m.user_id = u.id WHERE m.thread_id = ? ORDER BY m.created_at ASC "); $stmt->execute([$active_server_id, $active_server_id, $active_thread_id]); $messages = $stmt->fetchAll(); } } if (!$active_thread && $channel_type === 'rules') { $stmt = db()->prepare("SELECT * FROM channel_rules WHERE channel_id = ? ORDER BY position ASC"); $stmt->execute([$active_channel_id]); $rules = $stmt->fetchAll(); } elseif ($channel_type === 'forum') { $filter_status = $_GET['status'] ?? 'all'; $status_where = ""; if ($filter_status === 'resolved') { $status_where = " AND t.solution_message_id IS NOT NULL"; } elseif ($filter_status === 'unresolved') { $status_where = " AND t.solution_message_id IS NULL"; } $stmt = db()->prepare(" SELECT t.*, u.username, u.avatar_url, (SELECT COUNT(*) FROM messages m WHERE m.thread_id = t.id) as message_count, (SELECT MAX(created_at) FROM messages m WHERE m.thread_id = t.id) as last_activity, (SELECT r.color FROM roles r JOIN user_roles ur ON r.id = ur.role_id WHERE ur.user_id = u.id AND r.server_id = ? ORDER BY r.position DESC LIMIT 1) as role_color, (SELECT r.icon_url FROM roles r JOIN user_roles ur ON r.id = ur.role_id WHERE ur.user_id = u.id AND r.server_id = ? ORDER BY r.position DESC LIMIT 1) as role_icon, (SELECT GROUP_CONCAT(CONCAT(ft.name, ':', ft.color) SEPARATOR '|') FROM thread_tags tt JOIN forum_tags ft ON tt.tag_id = ft.id WHERE tt.thread_id = t.id) as tags FROM forum_threads t JOIN users u ON t.user_id = u.id WHERE t.channel_id = ? " . $status_where . " ORDER BY last_activity DESC, t.created_at DESC "); $stmt->execute([$active_server_id, $active_server_id, $active_channel_id]); $threads = $stmt->fetchAll(); } else { // Fetch messages $display_limit = !empty($active_channel['message_limit']) ? (int)$active_channel['message_limit'] : 50; $stmt = db()->prepare(" SELECT m.*, u.username, u.avatar_url, (SELECT r.color FROM roles r JOIN user_roles ur ON r.id = ur.role_id WHERE ur.user_id = u.id AND r.server_id = ? ORDER BY r.position DESC LIMIT 1) as role_color, (SELECT r.icon_url FROM roles r JOIN user_roles ur ON r.id = ur.role_id WHERE ur.user_id = u.id AND r.server_id = ? ORDER BY r.position DESC LIMIT 1) as role_icon FROM messages m JOIN users u ON m.user_id = u.id WHERE m.channel_id = ? ORDER BY m.created_at ASC LIMIT " . $display_limit . " "); $stmt->execute([$active_server_id, $active_server_id, $active_channel_id]); $messages = $stmt->fetchAll(); } $current_channel_name = 'general'; foreach($channels as $c) if($c['id'] == $active_channel_id) $current_channel_name = $c['name']; // Fetch members $stmt = db()->prepare(" SELECT u.id, u.username, u.avatar_url, u.status, (SELECT GROUP_CONCAT(r.id) FROM roles r JOIN user_roles ur ON r.id = ur.role_id WHERE ur.user_id = u.id AND r.server_id = ?) as role_ids, (SELECT r.color FROM roles r JOIN user_roles ur ON r.id = ur.role_id WHERE ur.user_id = u.id AND r.server_id = ? ORDER BY r.position DESC LIMIT 1) as role_color, (SELECT r.icon_url FROM roles r JOIN user_roles ur ON r.id = ur.role_id WHERE ur.user_id = u.id AND r.server_id = ? ORDER BY r.position DESC LIMIT 1) as role_icon FROM users u JOIN server_members sm ON u.id = sm.user_id WHERE sm.server_id = ? "); $stmt->execute([$active_server_id, $active_server_id, $active_server_id, $active_server_id]); $all_server_members = $stmt->fetchAll(); $members = []; foreach($all_server_members as $m) { if (Permissions::canViewChannel($m['id'], $active_channel_id)) { $members[] = $m; } } // Fetch all server roles $stmt = db()->prepare("SELECT * FROM roles WHERE server_id = ? ORDER BY position DESC"); $stmt->execute([$active_server_id]); $server_roles = $stmt->fetchAll(); } // SEO & Env tags $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Discord-like messaging app built with PHP'; $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? ''; ?> #<?php echo htmlspecialchars($current_channel_name); ?> | <?php echo htmlspecialchars($projectDescription); ?>

">
PHP |
'; elseif ($active_channel['type'] === 'rules') echo ''; elseif ($active_channel['type'] === 'forum') echo ''; elseif ($active_channel['type'] === 'voice') echo ''; else echo ''; if (!empty($active_channel['icon'])) { echo ' ' . renderRoleIcon($active_channel['icon'], '16px') . ''; } } ?>
← Back to Forum

Discussion:

prepare("SELECT ft.* FROM forum_tags ft JOIN thread_tags tt ON ft.id = tt.tag_id WHERE tt.thread_id = ?"); $stmt_t->execute([$active_thread['id']]); $thread_tags = $stmt_t->fetchAll(); if ($thread_tags): foreach ($thread_tags as $t): ?>
">
"> SOLUTION
prepare("SELECT emoji, COUNT(*) as count, GROUP_CONCAT(user_id) as users FROM message_reactions WHERE message_id = ? GROUP BY emoji"); $stmt_react->execute([$m['id']]); $reactions = $stmt_react->fetchAll(); foreach ($reactions as $r): $reacted = in_array($current_user_id, explode(',', $r['users'])); ?> +

📜

.
prepare("SELECT 1 FROM rule_acceptances WHERE user_id = ? AND channel_id = ?"); $stmtAcc->execute([$current_user_id, $active_channel_id]); $has_accepted = $stmtAcc->fetch(); ?>
Vous avez accepté les règles.

Veuillez accepter les règles pour obtenir l'accès complet.

Welcome to #!

This is the start of the # channel.

">
"> Pinned
@' . htmlspecialchars($user['username']) . '', $msg_content); echo nl2br($msg_content); ?>
prepare("SELECT emoji, COUNT(*) as count, GROUP_CONCAT(user_id) as users FROM message_reactions WHERE message_id = ? GROUP BY emoji"); $stmt_react->execute([$m['id']]); $reactions = $stmt_react->fetchAll(); foreach ($reactions as $r): $reacted = in_array($current_user_id, explode(',', $r['users'])); ?> +
Members —
">
">