diff --git a/api_v1_threads.php b/api_v1_threads.php index 2903d23..3d8d61b 100644 --- a/api_v1_threads.php +++ b/api_v1_threads.php @@ -5,9 +5,69 @@ require_once 'includes/permissions.php'; requireLogin(); if ($_SERVER['REQUEST_METHOD'] === 'POST') { + $action = $_POST['action'] ?? ''; + $user_id = $_SESSION['user_id']; + + if ($action === 'update_tags') { + $thread_id = $_POST['thread_id'] ?? 0; + $tag_ids = $_POST['tag_ids'] ?? []; + if (is_string($tag_ids)) { + $tag_ids = array_filter(explode(',', $tag_ids)); + } + + if (!$thread_id) { + echo json_encode(['success' => false, 'error' => 'Missing thread_id']); + exit; + } + + // Verify permission + $stmt = db()->prepare("SELECT t.*, c.server_id FROM forum_threads t JOIN channels c ON t.channel_id = c.id WHERE t.id = ?"); + $stmt->execute([$thread_id]); + $thread = $stmt->fetch(); + + if (!$thread) { + echo json_encode(['success' => false, 'error' => 'Thread not found']); + exit; + } + + $stmtServer = db()->prepare("SELECT owner_id FROM servers WHERE id = ?"); + $stmtServer->execute([$thread['server_id']]); + $server = $stmtServer->fetch(); + + $is_admin = Permissions::hasPermission($user_id, $thread['server_id'], Permissions::ADMINISTRATOR) || + Permissions::hasPermission($user_id, $thread['server_id'], Permissions::MANAGE_SERVER) || + Permissions::hasPermission($user_id, $thread['server_id'], Permissions::MANAGE_MESSAGES) || + $server['owner_id'] == $user_id; + + if ($thread['user_id'] != $user_id && !$is_admin) { + echo json_encode(['success' => false, 'error' => 'Unauthorized']); + exit; + } + + try { + db()->beginTransaction(); + // Delete old tags + $stmt = db()->prepare("DELETE FROM thread_tags WHERE thread_id = ?"); + $stmt->execute([$thread_id]); + + // Insert new tags + if (!empty($tag_ids)) { + $stmtTag = db()->prepare("INSERT INTO thread_tags (thread_id, tag_id) VALUES (?, ?)"); + foreach ($tag_ids as $tag_id) { + if ($tag_id) $stmtTag->execute([$thread_id, $tag_id]); + } + } + db()->commit(); + echo json_encode(['success' => true]); + } catch (Exception $e) { + db()->rollBack(); + echo json_encode(['success' => false, 'error' => $e->getMessage()]); + } + exit; + } + $channel_id = $_POST['channel_id'] ?? 0; $title = $_POST['title'] ?? ''; - $user_id = $_SESSION['user_id']; if (!$channel_id || !$title) { echo json_encode(['success' => false, 'error' => 'Missing data']); @@ -133,4 +193,4 @@ if ($_SERVER['REQUEST_METHOD'] === 'PATCH' || $_SERVER['REQUEST_METHOD'] === 'DE echo json_encode(['success' => false, 'error' => $e->getMessage()]); } exit; -} +} \ No newline at end of file diff --git a/assets/js/main.js b/assets/js/main.js index 3f22b38..3d29f83 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -4042,5 +4042,46 @@ document.addEventListener('DOMContentLoaded', () => { const modal = new bootstrap.Modal(document.getElementById('pollVotersModal')); modal.show(); } + + // Forum: Edit Thread Tags + const editThreadTagsBtn = e.target.closest('.edit-thread-tags'); + if (editThreadTagsBtn) { + const threadId = editThreadTagsBtn.dataset.threadId; + const tagIds = editThreadTagsBtn.dataset.tagIds ? editThreadTagsBtn.dataset.tagIds.split(',') : []; + const modal = document.getElementById('editThreadTagsModal'); + if (modal) { + document.getElementById('edit-tags-thread-id').value = threadId; + + // Clear and then check checkboxes + const checkboxes = modal.querySelectorAll('.tag-checkbox'); + checkboxes.forEach(cb => { + cb.checked = tagIds.includes(cb.value); + }); + + const bsModal = new bootstrap.Modal(modal); + bsModal.show(); + } + } + }); + + document.getElementById('edit-thread-tags-form')?.addEventListener('submit', async (ev) => { + ev.preventDefault(); + const form = ev.target; + const formData = new FormData(form); + + try { + const resp = await fetch('api_v1_threads.php', { + method: 'POST', + body: formData + }); + const data = await resp.json(); + if (data.success) { + location.reload(); + } else { + alert(data.error || 'Erreur lors de la mise à jour des tags'); + } + } catch (err) { + console.error(err); + } }); }); diff --git a/index.php b/index.php index 1211b2b..9e9b249 100644 --- a/index.php +++ b/index.php @@ -257,7 +257,7 @@ if ($is_dm_view) { $active_thread = null; if ($active_thread_id) { - $stmt = db()->prepare("SELECT t.*, (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, u.display_name as username, u.username as login_name FROM forum_threads t JOIN users u ON t.user_id = u.id WHERE t.id = ?"); + $stmt = db()->prepare("SELECT t.*, (SELECT GROUP_CONCAT(CONCAT(ft.id, ':', 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, u.display_name as username, u.username as login_name 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(); @@ -309,7 +309,7 @@ if ($is_dm_view) { } $stmt = db()->prepare(" - SELECT t.*, (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, u.display_name as username, u.avatar_url, + SELECT t.*, (SELECT GROUP_CONCAT(CONCAT(ft.id, ':', 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, u.display_name as 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_message_at, (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, @@ -1428,7 +1428,7 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? ''; @@ -1460,6 +1460,37 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
Par • Dans #
+ +
+ + + + + + + + + +
+ Retour au forum @@ -3902,5 +3933,40 @@ document.addEventListener('DOMContentLoaded', () => { + +