diff --git a/api_v1_threads.php b/api_v1_threads.php index 3d8d61b..14481e9 100644 --- a/api_v1_threads.php +++ b/api_v1_threads.php @@ -5,69 +5,9 @@ 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']); @@ -105,7 +45,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { exit; } -if ($_SERVER['REQUEST_METHOD'] === 'PATCH' || $_SERVER['REQUEST_METHOD'] === 'DELETE' || (isset($_GET['action']) && in_array($_GET['action'], ['solve', 'pin', 'unpin', 'lock', 'unlock', 'delete']))) { +if ($_SERVER['REQUEST_METHOD'] === 'PATCH' || $_SERVER['REQUEST_METHOD'] === 'DELETE' || (isset($_GET['action']) && in_array($_GET['action'], ['solve', 'pin', 'unpin', 'lock', 'unlock', 'delete', 'update_tags']))) { $data = json_decode(file_get_contents('php://input'), true) ?? $_POST; $thread_id = $data['thread_id'] ?? $_GET['thread_id'] ?? 0; $message_id = $data['message_id'] ?? null; @@ -187,9 +127,25 @@ if ($_SERVER['REQUEST_METHOD'] === 'PATCH' || $_SERVER['REQUEST_METHOD'] === 'DE $stmt = db()->prepare("DELETE FROM forum_threads WHERE id = ?"); $stmt->execute([$thread_id]); db()->commit(); + } elseif ($action === 'update_tags') { + if ($thread['user_id'] != $user_id && !$is_admin) { + echo json_encode(['success' => false, 'error' => 'Unauthorized']); exit; + } + $tag_ids = $data['tag_ids'] ?? []; + db()->beginTransaction(); + $stmt = db()->prepare("DELETE FROM thread_tags WHERE thread_id = ?"); + $stmt->execute([$thread_id]); + 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) { + if (db()->inTransaction()) db()->rollBack(); echo json_encode(['success' => false, 'error' => $e->getMessage()]); } exit; diff --git a/assets/js/main.js b/assets/js/main.js index 3d29f83..a8c7104 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -4042,46 +4042,67 @@ 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; + // Manage Thread Tags + const manageThreadTagsBtn = document.getElementById('manage-thread-tags'); + if (manageThreadTagsBtn) { + manageThreadTagsBtn.addEventListener('click', () => { + const threadId = manageThreadTagsBtn.dataset.id; + const currentTags = manageThreadTagsBtn.dataset.tags ? manageThreadTagsBtn.dataset.tags.split(',').filter(id => id !== "") : []; + + const threadIdInput = document.getElementById('manage-tags-thread-id'); + if (threadIdInput) threadIdInput.value = threadId; + + // Reset all checkboxes + document.querySelectorAll('.tag-checkbox').forEach(cb => { + cb.checked = currentTags.includes(cb.value); + }); + + const modalEl = document.getElementById('manageThreadTagsModal'); + if (modalEl) { + const modal = new bootstrap.Modal(modalEl); + modal.show(); + } + }); + } + + const saveThreadTagsBtn = document.getElementById('save-thread-tags-btn'); + if (saveThreadTagsBtn) { + saveThreadTagsBtn.addEventListener('click', async () => { + const threadIdInput = document.getElementById('manage-tags-thread-id'); + const threadId = threadIdInput ? threadIdInput.value : null; + if (!threadId) return; + + const selectedTags = Array.from(document.querySelectorAll('.tag-checkbox:checked')).map(cb => cb.value); + + try { + saveThreadTagsBtn.disabled = true; + saveThreadTagsBtn.innerHTML = ' Enregistrement...'; - // Clear and then check checkboxes - const checkboxes = modal.querySelectorAll('.tag-checkbox'); - checkboxes.forEach(cb => { - cb.checked = tagIds.includes(cb.value); + const resp = await fetch('api_v1_threads.php?action=update_tags', { + method: 'PATCH', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + thread_id: threadId, + tag_ids: selectedTags + }) }); - const bsModal = new bootstrap.Modal(modal); - bsModal.show(); + const result = await resp.json(); + if (result.success) { + location.reload(); + } else { + alert(result.error || 'Erreur lors de la mise à jour des tags'); + saveThreadTagsBtn.disabled = false; + saveThreadTagsBtn.innerHTML = 'Enregistrer'; + } + } catch (e) { + console.error(e); + alert('Une erreur est survenue'); + saveThreadTagsBtn.disabled = false; + saveThreadTagsBtn.innerHTML = 'Enregistrer'; } - } - }); - - 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); - } - }); -}); + }); + } +}); \ No newline at end of file diff --git a/index.php b/index.php index 9e9b249..9899109 100644 --- a/index.php +++ b/index.php @@ -257,11 +257,14 @@ if ($is_dm_view) { $active_thread = null; if ($active_thread_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 = 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->execute([$active_thread_id]); $active_thread = $stmt->fetch(); if ($active_thread) { + $stmt_t_ids = db()->prepare("SELECT tag_id FROM thread_tags WHERE thread_id = ?"); + $stmt_t_ids->execute([$active_thread_id]); + $active_thread_tag_ids = $stmt_t_ids->fetchAll(PDO::FETCH_COLUMN); $stmt = db()->prepare(" SELECT m.*, u.display_name as username, u.username as login_name, 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, @@ -309,7 +312,7 @@ if ($is_dm_view) { } $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.avatar_url, + 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 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, @@ -881,6 +884,11 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
← Retour au forum
+ + + - -
-
Retour au forum @@ -3933,40 +3910,46 @@ document.addEventListener('DOMContentLoaded', () => { - -