Autosave: 20260315-000804
This commit is contained in:
parent
2ee58fd533
commit
9c3e061f45
@ -5,9 +5,69 @@ require_once 'includes/permissions.php';
|
|||||||
requireLogin();
|
requireLogin();
|
||||||
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
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;
|
$channel_id = $_POST['channel_id'] ?? 0;
|
||||||
$title = $_POST['title'] ?? '';
|
$title = $_POST['title'] ?? '';
|
||||||
$user_id = $_SESSION['user_id'];
|
|
||||||
|
|
||||||
if (!$channel_id || !$title) {
|
if (!$channel_id || !$title) {
|
||||||
echo json_encode(['success' => false, 'error' => 'Missing data']);
|
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()]);
|
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
|
||||||
}
|
}
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
@ -4042,5 +4042,46 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
const modal = new bootstrap.Modal(document.getElementById('pollVotersModal'));
|
const modal = new bootstrap.Modal(document.getElementById('pollVotersModal'));
|
||||||
modal.show();
|
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);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
72
index.php
72
index.php
@ -257,7 +257,7 @@ if ($is_dm_view) {
|
|||||||
$active_thread = null;
|
$active_thread = null;
|
||||||
|
|
||||||
if ($active_thread_id) {
|
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]);
|
$stmt->execute([$active_thread_id]);
|
||||||
$active_thread = $stmt->fetch();
|
$active_thread = $stmt->fetch();
|
||||||
|
|
||||||
@ -309,7 +309,7 @@ if ($is_dm_view) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$stmt = db()->prepare("
|
$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 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 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,
|
(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'] ?? '';
|
|||||||
<?php if($thread['tags']):
|
<?php if($thread['tags']):
|
||||||
$tag_list = explode('|', $thread['tags']);
|
$tag_list = explode('|', $thread['tags']);
|
||||||
foreach($tag_list as $tag_data):
|
foreach($tag_list as $tag_data):
|
||||||
list($t_name, $t_color) = explode(':', $tag_data);
|
list($t_id, $t_name, $t_color) = explode(':', $tag_data);
|
||||||
?>
|
?>
|
||||||
<span class="badge rounded-pill ms-1" style="background-color: <?php echo htmlspecialchars($t_color); ?>; font-size: 0.6em;"><?php echo htmlspecialchars($t_name); ?></span>
|
<span class="badge rounded-pill ms-1" style="background-color: <?php echo htmlspecialchars($t_color); ?>; font-size: 0.6em;"><?php echo htmlspecialchars($t_name); ?></span>
|
||||||
<?php endforeach; endif; ?>
|
<?php endforeach; endif; ?>
|
||||||
@ -1460,6 +1460,37 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
|
|||||||
<div class="small text-muted mt-1">
|
<div class="small text-muted mt-1">
|
||||||
Par <?php echo htmlspecialchars($active_thread['username']); ?> • Dans #<?php echo htmlspecialchars($current_channel_name); ?>
|
Par <?php echo htmlspecialchars($active_thread['username']); ?> • Dans #<?php echo htmlspecialchars($current_channel_name); ?>
|
||||||
</div>
|
</div>
|
||||||
|
<?php if($channel_type === 'forum'): ?>
|
||||||
|
<div class="mt-2 d-flex flex-wrap gap-1 align-items-center">
|
||||||
|
<?php if(!empty($active_thread['tags'])):
|
||||||
|
$tag_list = explode('|', $active_thread['tags']);
|
||||||
|
foreach($tag_list as $tag_data):
|
||||||
|
list($t_id, $t_name, $t_color) = explode(':', $tag_data);
|
||||||
|
?>
|
||||||
|
<span class="badge rounded-pill" style="background-color: <?php echo htmlspecialchars($t_color); ?>; font-size: 0.7em;">
|
||||||
|
<?php echo htmlspecialchars($t_name); ?>
|
||||||
|
</span>
|
||||||
|
<?php endforeach; endif; ?>
|
||||||
|
|
||||||
|
<?php if($active_thread['user_id'] == $current_user_id || $can_manage_channels): ?>
|
||||||
|
<button class="btn btn-link btn-sm p-0 ms-1 text-muted text-decoration-none edit-thread-tags"
|
||||||
|
data-thread-id="<?php echo $active_thread['id']; ?>"
|
||||||
|
data-active-tags="<?php
|
||||||
|
$active_tags_ids = [];
|
||||||
|
if (!empty($active_thread['tags'])) {
|
||||||
|
$tag_list_ids = explode('|', $active_thread['tags']);
|
||||||
|
foreach($tag_list_ids as $tdid) {
|
||||||
|
$parts_id = explode(':', $tdid);
|
||||||
|
$active_tags_ids[] = $parts_id[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
echo implode(',', $active_tags_ids);
|
||||||
|
?>" title="Gérer les tags">
|
||||||
|
<i class="fa-solid fa-pen-to-square"></i>
|
||||||
|
</button>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
<a href="?server_id=<?php echo $active_server_id; ?>&channel_id=<?php echo $active_channel_id; ?><?php echo !empty($selected_tag_ids) ? '&tags='.implode(',', $selected_tag_ids) : ''; ?>" class="btn btn-outline-secondary btn-sm">
|
<a href="?server_id=<?php echo $active_server_id; ?>&channel_id=<?php echo $active_channel_id; ?><?php echo !empty($selected_tag_ids) ? '&tags='.implode(',', $selected_tag_ids) : ''; ?>" class="btn btn-outline-secondary btn-sm">
|
||||||
<i class="fa-solid fa-arrow-left me-1"></i> Retour au forum
|
<i class="fa-solid fa-arrow-left me-1"></i> Retour au forum
|
||||||
@ -3902,5 +3933,40 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Edit Thread Tags Modal -->
|
||||||
|
<div class="modal fade" id="editThreadTagsModal" tabindex="-1">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header border-0">
|
||||||
|
<h5 class="modal-title">Modifier les tags</h5>
|
||||||
|
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<form id="edit-thread-tags-form">
|
||||||
|
<input type="hidden" name="thread_id" id="edit-tags-thread-id">
|
||||||
|
<input type="hidden" name="action" value="update_tags">
|
||||||
|
<?php if (!empty($forum_tags)): ?>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label d-block text-muted small fw-bold text-uppercase">Tags disponibles</label>
|
||||||
|
<div id="edit-thread-tags-list" class="d-flex flex-wrap gap-2 p-3 bg-dark bg-opacity-50 rounded">
|
||||||
|
<?php foreach ($forum_tags as $tag): ?>
|
||||||
|
<div class="form-check form-check-inline m-0">
|
||||||
|
<input class="btn-check tag-checkbox" type="checkbox" name="tag_ids[]" value="<?php echo $tag['id']; ?>" id="edit-tag-<?php echo $tag['id']; ?>">
|
||||||
|
<label class="btn btn-outline-secondary btn-sm rounded-pill px-3" for="edit-tag-<?php echo $tag['id']; ?>" style="--bs-btn-active-bg: <?php echo $tag['color']; ?>; --bs-btn-active-border-color: <?php echo $tag['color']; ?>;">
|
||||||
|
<?php echo htmlspecialchars($tag['name']); ?>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php else: ?>
|
||||||
|
<p class="text-muted text-center py-3">Aucun tag n'est configuré pour ce salon.</p>
|
||||||
|
<?php endif; ?>
|
||||||
|
<button type="submit" class="btn btn-primary w-100 mt-2 py-2 fw-bold">Enregistrer les modifications</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user