Release V1.5
This commit is contained in:
parent
3cc1513512
commit
6114c7d5a8
@ -62,6 +62,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if ($icon === '') $icon = null;
|
||||
$category_id = !empty($_POST['category_id']) ? (int)$_POST['category_id'] : null;
|
||||
$rules_role_id = !empty($_POST['rules_role_id']) ? (int)$_POST['rules_role_id'] : null;
|
||||
$ai_moderation_enabled = isset($_POST['ai_moderation_enabled']) ? 1 : 0;
|
||||
|
||||
// Check if user has permission to manage channels
|
||||
$stmt = db()->prepare("SELECT server_id FROM channels WHERE id = ?");
|
||||
@ -73,8 +74,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
// Allow spaces, accents and mixed case
|
||||
$name = trim($name);
|
||||
// Explicitly exclude position from update to prevent jumping to bottom
|
||||
$stmt = db()->prepare("UPDATE channels SET name = ?, type = ?, status = ?, allow_file_sharing = ?, message_limit = ?, icon = ?, category_id = ?, rules_role_id = ? WHERE id = ?");
|
||||
$stmt->execute([$name, $type, $status, $allow_file_sharing, $message_limit, $icon, $category_id, $rules_role_id, $channel_id]);
|
||||
$stmt = db()->prepare("UPDATE channels SET name = ?, type = ?, status = ?, allow_file_sharing = ?, ai_moderation_enabled = ?, message_limit = ?, icon = ?, category_id = ?, rules_role_id = ? WHERE id = ?");
|
||||
$stmt->execute([$name, $type, $status, $allow_file_sharing, $ai_moderation_enabled, $message_limit, $icon, $category_id, $rules_role_id, $channel_id]);
|
||||
|
||||
if ($message_limit !== null) {
|
||||
require_once 'db/config.php';
|
||||
@ -115,6 +116,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if ($icon === '') $icon = null;
|
||||
$category_id = !empty($_POST['category_id']) ? (int)$_POST['category_id'] : null;
|
||||
$rules_role_id = !empty($_POST['rules_role_id']) ? (int)$_POST['rules_role_id'] : null;
|
||||
$ai_moderation_enabled = isset($_POST['ai_moderation_enabled']) ? 1 : 0;
|
||||
|
||||
// Get next position
|
||||
$stmtPos = db()->prepare("SELECT MAX(position) as max_pos FROM channels WHERE server_id = ?");
|
||||
@ -122,8 +124,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$maxPos = $stmtPos->fetch();
|
||||
$nextPos = ($maxPos['max_pos'] ?? -1) + 1;
|
||||
|
||||
$stmt = db()->prepare("INSERT INTO channels (server_id, name, type, allow_file_sharing, message_limit, icon, category_id, position, rules_role_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
$stmt->execute([$server_id, $name, $type, $allow_file_sharing, $message_limit, $icon, $category_id, $nextPos, $rules_role_id]);
|
||||
$stmt = db()->prepare("INSERT INTO channels (server_id, name, type, allow_file_sharing, ai_moderation_enabled, message_limit, icon, category_id, position, rules_role_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
$stmt->execute([$server_id, $name, $type, $allow_file_sharing, $ai_moderation_enabled, $message_limit, $icon, $category_id, $nextPos, $rules_role_id]);
|
||||
$channel_id = db()->lastInsertId();
|
||||
|
||||
header('Location: index.php?server_id=' . $server_id . '&channel_id=' . $channel_id);
|
||||
|
||||
@ -270,6 +270,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'DELETE') {
|
||||
}
|
||||
|
||||
$content = '';
|
||||
|
||||
$channel_id = 0;
|
||||
$thread_id = null;
|
||||
$attachment_url = null;
|
||||
@ -313,6 +314,11 @@ if (empty($content) && empty($attachment_url)) {
|
||||
}
|
||||
|
||||
// Check granular permissions
|
||||
// Check if AI moderation is enabled for this channel
|
||||
$stmtMod = db()->prepare("SELECT ai_moderation_enabled FROM channels WHERE id = ?");
|
||||
$stmtMod->execute([$channel_id]);
|
||||
$channelMod = $stmtMod->fetch();
|
||||
$ai_moderation_enabled = $channelMod ? (bool)$channelMod["ai_moderation_enabled"] : true;
|
||||
$can_send = Permissions::canSendInChannel($user_id, $channel_id);
|
||||
if ($thread_id) {
|
||||
// For threads, we check the specific thread permission instead of the general channel permission
|
||||
@ -336,7 +342,7 @@ if ($thread_id) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($content)) {
|
||||
if (!empty($content) && $ai_moderation_enabled) {
|
||||
$moderation = moderateContent($content);
|
||||
if (!$moderation['is_safe']) {
|
||||
echo json_encode(['success' => false, 'error' => 'Message flagged as inappropriate: ' . ($moderation['reason'] ?? 'Violation of community standards')]);
|
||||
@ -380,7 +386,7 @@ if (isset($_POST['is_announcement']) && $_POST['is_announcement'] == '1') {
|
||||
'poll_end_date' => $end_date,
|
||||
'poll_color' => $_POST['poll_color'] ?? '#3c6f7c'
|
||||
]);
|
||||
} elseif (!empty($content)) {
|
||||
} elseif (!empty($content) && $ai_moderation_enabled) {
|
||||
$urls = extractUrls($content);
|
||||
if (!empty($urls)) {
|
||||
// Fetch OG data for the first URL
|
||||
|
||||
@ -1563,6 +1563,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
}
|
||||
|
||||
modal.querySelector('#edit-channel-files').checked = btn.dataset.files == '1';
|
||||
modal.querySelector('#edit-channel-ai-moderation').checked = btn.dataset.aiModeration == '1';
|
||||
modal.querySelector('#edit-channel-limit').value = btn.dataset.limit || '';
|
||||
modal.querySelector('#edit-channel-status').value = btn.dataset.status || '';
|
||||
modal.querySelector('#edit-channel-icon').value = btn.dataset.icon || '';
|
||||
@ -1595,6 +1596,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
}
|
||||
if (editFilesContainer) {
|
||||
editFilesContainer.style.display = (channelType === 'rules' || channelType === 'autorole' || channelType === 'poll' || isRoleChannel) ? 'none' : 'block';
|
||||
const aiModContainer = document.getElementById('edit-channel-ai-moderation-container');
|
||||
if (aiModContainer) aiModContainer.style.display = (channelType === 'chat' || channelType === 'announcement' || channelType === 'forum') ? 'block' : 'none';
|
||||
}
|
||||
if (clearChatBtn) clearChatBtn.style.display = (channelType === 'rules' || channelType === 'poll') ? 'none' : 'inline-block';
|
||||
|
||||
@ -3005,6 +3008,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
}
|
||||
}
|
||||
if (filesContainer) filesContainer.style.display = (type === 'rules' || type === 'autorole' || type === 'poll') ? 'none' : 'block';
|
||||
const aiModContainer = document.getElementById('add-channel-ai-moderation-container');
|
||||
if (aiModContainer) aiModContainer.style.display = (type === 'chat' || type === 'announcement' || type === 'forum') ? 'block' : 'none';
|
||||
});
|
||||
|
||||
// User Settings - Avatar Search
|
||||
|
||||
BIN
assets/pasted-20260313-233133-648dd6ef.png
Normal file
BIN
assets/pasted-20260313-233133-648dd6ef.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 291 KiB |
@ -186,6 +186,7 @@ CREATE TABLE `channels` (
|
||||
`position` int(11) DEFAULT 0,
|
||||
`category_id` int(11) DEFAULT NULL,
|
||||
`rules_role_id` int(11) DEFAULT NULL,
|
||||
`ai_moderation_enabled` tinyint(1) DEFAULT 1,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `server_id` (`server_id`),
|
||||
CONSTRAINT `channels_ibfk_1` FOREIGN KEY (`server_id`) REFERENCES `servers` (`id`) ON DELETE CASCADE
|
||||
|
||||
2
db/migrations/20260313_add_ai_moderation_to_channels.sql
Normal file
2
db/migrations/20260313_add_ai_moderation_to_channels.sql
Normal file
@ -0,0 +1,2 @@
|
||||
-- Add ai_moderation_enabled column to channels table
|
||||
ALTER TABLE `channels` ADD COLUMN `ai_moderation_enabled` TINYINT(1) DEFAULT 1;
|
||||
20
index.php
20
index.php
@ -668,7 +668,7 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
|
||||
data-status=""
|
||||
data-icon="<?php echo htmlspecialchars($c['icon'] ?? ''); ?>"
|
||||
data-rules-role="<?php echo $c['rules_role_id'] ?? ''; ?>"
|
||||
data-category="<?php echo $c['category_id'] ?? ''; ?>">
|
||||
data-ai-moderation="<?php echo $c["ai_moderation_enabled"]; ?>" data-category="<?php echo $c['category_id'] ?? ''; ?>">
|
||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33 1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82 1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
@ -719,7 +719,7 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
|
||||
data-status="<?php echo htmlspecialchars($c['status'] ?? ''); ?>"
|
||||
data-icon="<?php echo htmlspecialchars($c['icon'] ?? ''); ?>"
|
||||
data-rules-role="<?php echo $c['rules_role_id'] ?? ''; ?>"
|
||||
data-category="<?php echo $c['category_id'] ?? ''; ?>">
|
||||
data-ai-moderation="<?php echo $c["ai_moderation_enabled"]; ?>" data-category="<?php echo $c['category_id'] ?? ''; ?>">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33 1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82 1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
@ -776,7 +776,7 @@ $projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
|
||||
data-status=""
|
||||
data-icon="<?php echo htmlspecialchars($item['icon'] ?? ''); ?>"
|
||||
data-rules-role="<?php echo $item['rules_role_id'] ?? ''; ?>"
|
||||
data-category=""
|
||||
data-category="" data-ai-moderation="<?php echo $item['ai_moderation_enabled']; ?>"
|
||||
data-theme="">
|
||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33 1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82 1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg>
|
||||
</span>
|
||||
@ -2781,6 +2781,13 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
<label class="form-label text-uppercase fw-bold" style="font-size: 0.7em; color: var(--text-muted);">Limite de messages</label>
|
||||
<input type="number" name="message_limit" class="form-control" placeholder="ex: 50 (Laissez vide pour aucune limite)">
|
||||
<div class="form-text text-muted" style="font-size: 0.8em;">Conserve automatiquement seulement les X derniers messages de ce salon.</div>
|
||||
<div id="add-channel-ai-moderation-container">
|
||||
<div class="form-check form-switch mb-3">
|
||||
<input class="form-check-input" type="checkbox" name="ai_moderation_enabled" id="add-channel-ai-moderation" value="1" checked>
|
||||
<label class="form-check-label text-white" for="add-channel-ai-moderation">Modération par IA (AI Filtering)</label>
|
||||
<div class="small text-muted">Vérifie automatiquement les messages inappropriés via l'IA. Peut ralentir l'envoi.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -3101,6 +3108,13 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
<input type="number" name="message_limit" id="edit-channel-limit" class="form-control bg-dark text-white border-secondary" placeholder="Conserver tous les messages">
|
||||
</div>
|
||||
</div>
|
||||
<div id="edit-channel-ai-moderation-container">
|
||||
<div class="form-check form-switch mb-4">
|
||||
<input class="form-check-input" type="checkbox" name="ai_moderation_enabled" id="edit-channel-ai-moderation" value="1">
|
||||
<label class="form-check-label text-white" for="edit-channel-ai-moderation">Modération par IA (AI Filtering)</label>
|
||||
<div class="small text-muted">Vérifie automatiquement les messages inappropriés via l'IA. Peut ralentir l'envoi.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="edit-channel-files-container">
|
||||
<div class="form-check form-switch mb-4">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user