'; case 'moderator': return ''; default: return ''; } } // Générer un token CSRF si non existant if (empty($_SESSION['csrf_token'])) { $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); } $csrf_token = $_SESSION['csrf_token']; // Récupérer les informations de l'utilisateur connecté pour la navbar if(isset($_SESSION['user_id'])) { $avatar_url = htmlspecialchars($_SESSION['avatar_url'] ?? 'https://via.placeholder.com/40', ENT_QUOTES, 'UTF-8'); $role = htmlspecialchars($_SESSION['role'] ?? 'user', ENT_QUOTES, 'UTF-8'); $username = htmlspecialchars($_SESSION['username'] ?? 'Utilisateur', ENT_QUOTES, 'UTF-8'); } // Fonction pour parser le contenu et appliquer la mise en forme function parseContent($text) { // Échapper les caractères spéciaux pour prévenir les XSS $text = htmlspecialchars($text, ENT_QUOTES, 'UTF-8'); // Appliquer les transformations de mise en forme // Gras: **texte** $text = preg_replace('/\*\*(.*?)\*\*/s', '$1', $text); // Italique: *texte* $text = preg_replace('/\*(.*?)\*/s', '$1', $text); // Souligné: [underline]texte[/underline] $text = preg_replace('/\[underline\](.*?)\[\/underline\]/s', '$1', $text); // Barré: [strike]texte[/strike] $text = preg_replace('/\[strike\](.*?)\[\/strike\]/s', '$1', $text); // Centré: [center]texte[/center] $text = preg_replace('/\[center\](.*?)\[\/center\]/s', '
$1
', $text); // Spoiler: [spoiler]texte[/spoiler] $text = preg_replace('/\[spoiler\](.*?)\[\/spoiler\]/s', '$1', $text); // Bloc de Code: [code]code ici[/code] $text = preg_replace('/\[code\](.*?)\[\/code\]/s', '
$1
', $text); // Lien: [link=https://exemple.com]texte du lien[/link] $text = preg_replace('/\[link=(https?:\/\/[^\]]+)\](.*?)\[\/link\]/s', '$2', $text); // Image: [img]https://exemple.com/image.jpg[/img] $text = preg_replace('/\[img\](https?:\/\/[^\]]+\.(?:jpg|jpeg|png|gif|bmp|webp))\[\/img\]/s', 'Image', $text); // Liste non ordonnée: [ul][li]Item 1[/li][li]Item 2[/li][/ul] $text = preg_replace('/\[ul\](.*?)\[\/ul\]/s', '
    $1
', $text); $text = preg_replace('/\[li\](.*?)\[\/li\]/s', '
  • $1
  • ', $text); // Liste ordonnée: [ol][li]Item 1[/li][li]Item 2[/li][/ol] $text = preg_replace('/\[ol\](.*?)\[\/ol\]/s', '
      $1
    ', $text); // Surligné: [highlight]texte[/highlight] $text = preg_replace('/\[highlight\](.*?)\[\/highlight\]/s', '$1', $text); // Citation: [blockquote]texte[/blockquote] $text = preg_replace('/\[blockquote\](.*?)\[\/blockquote\]/s', '
    $1
    ', $text); // Tableau: [table]...[/table] $text = preg_replace('/\[table\](.*?)\[\/table\]/s', '$1
    ', $text); $text = preg_replace('/\[tr\](.*?)\[\/tr\]/s', '$1', $text); $text = preg_replace('/\[th\](.*?)\[\/th\]/s', '$1', $text); $text = preg_replace('/\[td\](.*?)\[\/td\]/s', '$1', $text); return $text; } // Récupérer les informations du sujet try { $stmt = $pdo->prepare(" SELECT topics.*, users.username, users.avatar_url, users.role, categories.name AS category_name, categories.image_url AS category_image FROM topics JOIN users ON topics.user_id = users.id JOIN categories ON topics.category_id = categories.id WHERE topics.id = :id "); $stmt->execute(['id' => $topic_id]); $topic = $stmt->fetch(); if (!$topic) { header("Location: index.php"); exit; } } catch (PDOException $e) { die("Erreur lors de la récupération du sujet : " . htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8')); } // Récupérer les badges de l'auteur du sujet try { $stmt = $pdo->prepare(" SELECT badges.* FROM user_badges JOIN badges ON user_badges.badge_id = badges.id WHERE user_badges.user_id = :user_id "); $stmt->execute(['user_id' => $topic['user_id']]); $topic_badges = $stmt->fetchAll(); } catch (PDOException $e) { $topic_badges = []; $badge_error = "Erreur lors de la récupération des badges de l'auteur : " . htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8'); } // Récupérer les messages du sujet try { $stmt = $pdo->prepare(" SELECT posts.*, users.username, users.avatar_url, users.role, (SELECT GROUP_CONCAT(badges.name SEPARATOR ', ') FROM user_badges JOIN badges ON user_badges.badge_id = badges.id WHERE user_badges.user_id = users.id) AS badges FROM posts JOIN users ON posts.user_id = users.id WHERE posts.topic_id = :topic_id ORDER BY posts.created_at ASC "); $stmt->execute(['topic_id' => $topic_id]); $posts = $stmt->fetchAll(); } catch (PDOException $e) { $posts = []; $error = "Erreur lors de la récupération des messages : " . htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8'); } // Récupérer les réactions du sujet try { $stmt = $pdo->prepare(" SELECT reaction, COUNT(*) as count FROM topic_reactions WHERE topic_id = :topic_id GROUP BY reaction "); $stmt->execute(['topic_id' => $topic_id]); $reactions = $stmt->fetchAll(PDO::FETCH_KEY_PAIR); // [reaction => count] } catch (PDOException $e) { $reactions = []; $reaction_error = "Erreur lors de la récupération des réactions : " . htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8'); } // Traitement du formulaire d'ajout de message $comment = ''; $comment_errors = []; if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_SESSION['user_id'])) { // Vérifier le token CSRF if (!isset($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) { $comment_errors[] = "Token de sécurité invalide. Veuillez réessayer."; } // Vérifier si le formulaire de commentaire a été soumis if (isset($_POST['submit_comment'])) { // Vérifier si le sujet est verrouillé if ($topic['is_locked']) { $comment_errors[] = "Ce sujet est verrouillé. Vous ne pouvez pas ajouter de réponses."; } else { // Récupérer et nettoyer les données $comment = trim($_POST['comment']); // Validation des champs if (empty($comment)) { $comment_errors[] = "Le commentaire ne peut pas être vide."; } if (empty($comment_errors)) { try { $stmt = $pdo->prepare("INSERT INTO posts (user_id, topic_id, content, created_at) VALUES (:user_id, :topic_id, :content, NOW())"); $stmt->execute([ 'user_id' => $_SESSION['user_id'], 'topic_id' => $topic_id, 'content' => $comment ]); header("Location: topic.php?id=" . $topic_id); exit; } catch (PDOException $e) { $comment_errors[] = "Erreur lors de l'ajout du commentaire : " . htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8'); } } } } // Vérifier si une réaction a été ajoutée if (isset($_POST['add_reaction'])) { // Récupérer et nettoyer les données $reaction = trim($_POST['reaction']); // Validation des réactions (par exemple, limiter à certaines valeurs) $allowed_reactions = ['like', 'love', 'haha', 'wow', 'sad', 'angry']; if (!in_array($reaction, $allowed_reactions)) { $comment_errors[] = "Réaction invalide."; } if (empty($comment_errors)) { try { // Vérifier si l'utilisateur a déjà réagi avec la même réaction $stmt = $pdo->prepare("SELECT * FROM topic_reactions WHERE user_id = :user_id AND topic_id = :topic_id AND reaction = :reaction"); $stmt->execute([ 'user_id' => $_SESSION['user_id'], 'topic_id' => $topic_id, 'reaction' => $reaction ]); $existing_reaction = $stmt->fetch(); if (!$existing_reaction) { // Ajouter la réaction $stmt = $pdo->prepare("INSERT INTO topic_reactions (user_id, topic_id, reaction, created_at) VALUES (:user_id, :topic_id, :reaction, NOW())"); $stmt->execute([ 'user_id' => $_SESSION['user_id'], 'topic_id' => $topic_id, 'reaction' => $reaction ]); } else { // Supprimer la réaction (toggle) $stmt = $pdo->prepare("DELETE FROM topic_reactions WHERE id = :id"); $stmt->execute(['id' => $existing_reaction['id']]); } header("Location: topic.php?id=" . $topic_id); exit; } catch (PDOException $e) { $comment_errors[] = "Erreur lors de l'ajout de la réaction : " . htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8'); } } } // Gestion des actions de verrouillage/déverrouillage (admins uniquement) if (isset($_POST['lock_topic']) && $role === 'admin') { // Vérifier le token CSRF if (!isset($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) { $_SESSION['error'] = "Token de sécurité invalide. Veuillez réessayer."; } else { // Changer l'état de verrouillage $new_lock_status = $topic['is_locked'] ? 0 : 1; try { $stmt = $pdo->prepare("UPDATE topics SET is_locked = :is_locked WHERE id = :id"); $stmt->execute([ 'is_locked' => $new_lock_status, 'id' => $topic_id ]); $_SESSION['message'] = $new_lock_status ? "Sujet verrouillé avec succès." : "Sujet déverrouillé avec succès."; header("Location: topic.php?id=" . $topic_id); exit; } catch (PDOException $e) { $_SESSION['error'] = "Erreur lors de la mise à jour du statut du sujet."; } } } } // Récupérer le nombre de likes try { $stmt = $pdo->prepare("SELECT COUNT(*) AS like_count FROM topic_likes WHERE topic_id = :topic_id"); $stmt->execute(['topic_id' => $topic_id]); $like_data = $stmt->fetch(); $like_count = $like_data ? $like_data['like_count'] : 0; } catch (PDOException $e) { $like_count = 0; } // Gérer les messages flash $message = ''; if (isset($_SESSION['message'])) { $message = $_SESSION['message']; unset($_SESSION['message']); } $error_msg = ''; if (isset($_SESSION['error'])) { $error_msg = $_SESSION['error']; unset($_SESSION['error']); } ?> <?= htmlspecialchars($topic['title'], ENT_QUOTES, 'UTF-8') ?> - Blue Exorcist Forum
    Blue Exorcist Forum
    • Avatar <?= $username ?>
      • Avatar <?= $username ?>


      • Mon Profil
      • Paramètres
      • Administration
      • Modérateur
      • Déconnexion
    • Inscription
    • Connexion
    Logo <?= htmlspecialchars($topic['category_name'], ENT_QUOTES, 'UTF-8') ?> Logo par défaut

    Avatar <?= htmlspecialchars($topic['username'], ENT_QUOTES, 'UTF-8') ?> <?= htmlspecialchars($badge['name'], ENT_QUOTES, 'UTF-8') ?> | | Catégorie :

    Likes

    Réactions

    'fas fa-thumbs-up', 'love' => 'fas fa-heart', 'haha' => 'fas fa-laugh', 'wow' => 'fas fa-surprise', 'sad' => 'fas fa-sad-tear', 'angry' => 'fas fa-angry' ]; $allowed_reactions = array_keys($reaction_icons); ?>

    Réponses

    Avatar <?= htmlspecialchars($post['username'], ENT_QUOTES, 'UTF-8') ?>
    prepare("SELECT * FROM badges WHERE name = :name"); $badge_stmt->execute(['name' => $badge_name]); $badge = $badge_stmt->fetch(); ?> <?= htmlspecialchars($badge['name'], ENT_QUOTES, 'UTF-8') ?>

    Aucun message pour le moment. Soyez le premier à répondre !

    Ajouter une Réponse

    Utilisez les boutons ci-dessus pour formater votre texte. Vous pouvez également utiliser les balises suivantes : **gras**, *italique*, [underline]texte[/underline], [strike]texte[/strike], [center]texte[/center], [spoiler]texte[/spoiler], [code]code ici[/code], [link=https://exemple.com]texte du lien[/link], [img]https://exemple.com/image.jpg[/img], [ul][li]Item 1[/li][li]Item 2[/li][/ul], [ol][li]Item 1[/li][li]Item 2[/li][/ol], [highlight]texte surligné[/highlight], [blockquote]citation[/blockquote], [table]....

    Vous devez vous connecter pour répondre à ce sujet.

    © Blue Exorcist Forum. Tous droits réservés.