39514-vm/scnotification.php
Flatlogic Bot 347a95a312 V1.1.0
2026-04-09 01:27:55 +00:00

969 lines
47 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
require_once __DIR__ . '/db/auth.php';
require_once __DIR__ . '/db/scdiscord.php';
auth_start_session();
auth_bootstrap();
scdiscord_bootstrap();
if (!auth_is_logged_in()) {
header('Location: index.php');
exit;
}
$db = db();
$csrf_token = auth_csrf_token();
$flash = auth_flash_get();
$flash_type = $flash['type'] ?? '';
$flash_message = $flash['message'] ?? '';
$current_session_user = $_SESSION['user'] ?? '';
$current_session_role = $_SESSION['role'] ?? 'member';
$role_label = ($current_session_role === 'admin') ? 'Administrateur' : 'Membre';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$submitted_csrf = (string) ($_POST['csrf_token'] ?? '');
if (!auth_validate_csrf($submitted_csrf)) {
auth_flash_set('error', 'Jeton CSRF invalide.');
header('Location: scnotification.php');
exit;
}
$_SESSION['scnotification_old'] = $_POST;
$action = (string) ($_POST['action'] ?? '');
$is_legacy_send = $action === '' && (isset($_POST['description']) || isset($_POST['title']) || isset($_POST['webhook_choice']));
if ($action === 'send_notification' || $is_legacy_send) {
$legacy_webhook_choice = trim((string) ($_POST['webhook_choice'] ?? ''));
$cl_scnotification_webhook_id = (int) ($_POST['cl_scnotification_webhook_id'] ?? 0);
if ($cl_scnotification_webhook_id <= 0 && preg_match('/^notif(\d+)$/', $legacy_webhook_choice, $matches)) {
$cl_scnotification_webhook_id = (int) $matches[1];
}
$cl_scnotification_banner_id = (int) ($_POST['cl_scnotification_banner_id'] ?? 0);
$use_custom_banner = isset($_POST['cl_scnotification_use_custom_banner']) || isset($_POST['use_custom_banner']);
$cl_scnotification_custom_banner_url = trim((string) ($_POST['cl_scnotification_custom_banner_url'] ?? ($_POST['custom_banner'] ?? '')));
$notify_here = isset($_POST['cl_scnotification_notify_here']) || isset($_POST['ping_here']);
$notify_everyone = isset($_POST['cl_scnotification_notify_everyone']) || isset($_POST['ping_everyone']);
$cl_scnotification_title = trim((string) ($_POST['cl_scnotification_title'] ?? ($_POST['title'] ?? '')));
$cl_scnotification_message = trim((string) ($_POST['cl_scnotification_message'] ?? ($_POST['description'] ?? '')));
$show_footer = isset($_POST['cl_scnotification_show_footer']);
$cl_scnotification_footer_text = trim((string) ($_POST['cl_scnotification_footer_text'] ?? ''));
$cl_scnotification_footer_icon_url = trim((string) ($_POST['cl_scnotification_footer_icon_url'] ?? ''));
$show_reactions = isset($_POST['cl_scnotification_show_reactions']) || isset($_POST['use_reactions']);
$show_thread = isset($_POST['cl_scnotification_show_thread']) || isset($_POST['use_publicthread']);
$show_org = isset($_POST['cl_scnotification_show_org']);
$cl_scnotification_org_value = trim((string) ($_POST['cl_scnotification_org_value'] ?? ''));
$show_pvp = isset($_POST['cl_scnotification_show_pvp']);
$cl_scnotification_pvp_value = trim((string) ($_POST['cl_scnotification_pvp_value'] ?? ''));
$include_schedule = isset($_POST['cl_scnotification_include_schedule']);
$cl_scnotification_location = trim((string) ($_POST['cl_scnotification_location'] ?? ''));
$cl_scnotification_start_date = trim((string) ($_POST['cl_scnotification_start_date'] ?? ''));
$cl_scnotification_departure_time = trim((string) ($_POST['cl_scnotification_departure_time'] ?? ''));
$include_briefing_time = isset($_POST['cl_scnotification_include_briefing_time']);
$cl_scnotification_briefing_time = trim((string) ($_POST['cl_scnotification_briefing_time'] ?? ''));
$include_end_date = isset($_POST['cl_scnotification_include_end_date']);
$cl_scnotification_end_date = trim((string) ($_POST['cl_scnotification_end_date'] ?? ''));
$include_end_time = isset($_POST['cl_scnotification_include_end_time']);
$cl_scnotification_end_time = trim((string) ($_POST['cl_scnotification_end_time'] ?? ''));
$show_channel_url = isset($_POST['cl_scnotification_show_channel_url']);
$cl_scnotification_channel_url = trim((string) ($_POST['cl_scnotification_channel_url'] ?? ''));
$show_inventory_url = isset($_POST['cl_scnotification_show_inventory_url']);
$cl_scnotification_inventory_url = trim((string) ($_POST['cl_scnotification_inventory_url'] ?? ''));
$show_source_url = isset($_POST['cl_scnotification_show_source_url']);
$cl_scnotification_source_url = trim((string) ($_POST['cl_scnotification_source_url'] ?? ''));
if ($cl_scnotification_webhook_id <= 0) {
auth_flash_set('error', 'Veuillez sélectionner un webhook Discord.');
header('Location: scnotification.php');
exit;
}
if ($cl_scnotification_message === '') {
auth_flash_set('error', 'Le champ description est obligatoire pour envoyer la notification.');
header('Location: scnotification.php');
exit;
}
$stmt_webhook = $db->prepare('SELECT * FROM tbl_scwebhooks WHERE cl_scwebhook_id = :id LIMIT 1');
$stmt_webhook->execute(['id' => $cl_scnotification_webhook_id]);
$webhook = $stmt_webhook->fetch();
if (!$webhook) {
auth_flash_set('error', 'Webhook Discord introuvable.');
header('Location: scnotification.php');
exit;
}
$banner = null;
if ($cl_scnotification_banner_id > 0) {
$stmt_banner = $db->prepare('SELECT * FROM tbl_scbanners WHERE cl_scbanner_id = :id LIMIT 1');
$stmt_banner->execute(['id' => $cl_scnotification_banner_id]);
$banner = $stmt_banner->fetch();
}
if ($use_custom_banner && $cl_scnotification_custom_banner_url !== '' && !filter_var($cl_scnotification_custom_banner_url, FILTER_VALIDATE_URL)) {
auth_flash_set('error', 'LURL de bannière personnalisée est invalide.');
header('Location: scnotification.php');
exit;
}
foreach ([
'URL canal Discord' => [$show_channel_url, $cl_scnotification_channel_url],
'URL inventaire' => [$show_inventory_url, $cl_scnotification_inventory_url],
'URL source' => [$show_source_url, $cl_scnotification_source_url],
'Icône du footer' => [$show_footer && $cl_scnotification_footer_icon_url !== '', $cl_scnotification_footer_icon_url],
] as $label => [$enabled, $value]) {
if ($enabled && $value !== '' && !filter_var($value, FILTER_VALIDATE_URL)) {
auth_flash_set('error', $label . ' invalide.');
header('Location: scnotification.php');
exit;
}
}
$mentions = scdiscord_build_mentions($notify_here, $notify_everyone);
$banner_image_url = $use_custom_banner && $cl_scnotification_custom_banner_url !== ''
? $cl_scnotification_custom_banner_url
: (string) ($banner['cl_scbanner_url'] ?? '');
$border_color = (string) ($banner['cl_scbanner_border_color'] ?? '#ffae00');
$fields = [];
if ($show_org && $cl_scnotification_org_value !== '' && mb_strtolower($cl_scnotification_org_value) !== 'non') {
$fields[] = [
'name' => 'Tenue dorganisation',
'value' => mb_substr($cl_scnotification_org_value, 0, 1024),
'inline' => true,
];
}
if ($show_pvp && $cl_scnotification_pvp_value !== '' && mb_strtolower($cl_scnotification_pvp_value) !== 'inexistant') {
$fields[] = [
'name' => 'Risques PvP',
'value' => mb_substr($cl_scnotification_pvp_value, 0, 1024),
'inline' => true,
];
}
if ($include_schedule) {
if ($cl_scnotification_location !== '') {
$fields[] = ['name' => 'Lieu de ralliement', 'value' => mb_substr($cl_scnotification_location, 0, 1024), 'inline' => false];
}
if ($cl_scnotification_start_date !== '') {
$fields[] = ['name' => 'Date de début', 'value' => mb_substr($cl_scnotification_start_date, 0, 1024), 'inline' => true];
}
if ($cl_scnotification_departure_time !== '') {
$fields[] = ['name' => 'Heure de départ', 'value' => mb_substr($cl_scnotification_departure_time, 0, 1024), 'inline' => true];
}
if ($include_briefing_time && $cl_scnotification_briefing_time !== '') {
$fields[] = ['name' => 'Heure de briefing', 'value' => mb_substr($cl_scnotification_briefing_time, 0, 1024), 'inline' => true];
}
if ($include_end_date && $cl_scnotification_end_date !== '') {
$fields[] = ['name' => 'Date de fin', 'value' => mb_substr($cl_scnotification_end_date, 0, 1024), 'inline' => true];
}
if ($include_end_time && $cl_scnotification_end_time !== '') {
$fields[] = ['name' => 'Heure de fin', 'value' => mb_substr($cl_scnotification_end_time, 0, 1024), 'inline' => true];
}
}
if ($show_channel_url && $cl_scnotification_channel_url !== '') {
$fields[] = ['name' => 'Canal Discord', 'value' => '[Ouvrir le canal](' . $cl_scnotification_channel_url . ')', 'inline' => false];
}
if ($show_inventory_url && $cl_scnotification_inventory_url !== '') {
$fields[] = ['name' => 'Inventaire A.R.I.A', 'value' => '[Consulter linventaire](' . $cl_scnotification_inventory_url . ')', 'inline' => false];
}
if ($show_source_url && $cl_scnotification_source_url !== '') {
$fields[] = ['name' => 'Source', 'value' => '[Ouvrir la source](' . $cl_scnotification_source_url . ')', 'inline' => false];
}
$embed = [
'description' => mb_substr($cl_scnotification_message, 0, 4096),
'color' => scdiscord_hex_to_decimal($border_color),
];
if ($cl_scnotification_title !== '') {
$embed['title'] = mb_substr($cl_scnotification_title, 0, 256);
}
if (!empty($fields)) {
$embed['fields'] = $fields;
}
if ($banner_image_url !== '') {
$embed['image'] = ['url' => $banner_image_url];
}
if ($show_footer && ($cl_scnotification_footer_text !== '' || $cl_scnotification_footer_icon_url !== '')) {
$embed['footer'] = [];
if ($cl_scnotification_footer_text !== '') {
$embed['footer']['text'] = mb_substr($cl_scnotification_footer_text, 0, 2048);
}
if ($cl_scnotification_footer_icon_url !== '') {
$embed['footer']['icon_url'] = $cl_scnotification_footer_icon_url;
}
}
$payload = [
'embeds' => [$embed],
];
if (!empty($mentions)) {
$payload['content'] = implode(' ', $mentions);
$payload['allowed_mentions'] = ['parse' => ['everyone']];
}
$thread_name = $show_thread
? ('Discussion - ' . scdiscord_build_thread_name(
$cl_scnotification_title,
$cl_scnotification_location,
$cl_scnotification_start_date
))
: '';
$result = scdiscord_post_webhook((string) $webhook['cl_scwebhook_url'], $payload);
$bot_actions = [
'success' => true,
'http_code' => 200,
'response' => 'Aucune action bot demandée.',
];
if (!empty($result['success']) && ($show_reactions || $show_thread)) {
$message_data = scdiscord_decode_json_response((string) ($result['response'] ?? ''));
$bot_actions = scdiscord_apply_bot_actions($message_data, $show_reactions, $show_thread, $thread_name);
}
$log_response = json_encode([
'webhook' => [
'success' => !empty($result['success']),
'http_code' => (int) ($result['http_code'] ?? 0),
'response' => (string) ($result['response'] ?? ''),
],
'bot_actions' => [
'success' => !empty($bot_actions['success']),
'http_code' => (int) ($bot_actions['http_code'] ?? 0),
'response' => (string) ($bot_actions['response'] ?? ''),
'details' => $bot_actions['details'] ?? [],
],
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$stmt_log = $db->prepare(
'INSERT INTO tbl_scnotifications (
cl_scnotification_webhook_id,
cl_scnotification_banner_id,
cl_scnotification_title,
cl_scnotification_message,
cl_scnotification_payload,
cl_scnotification_response,
cl_scnotification_success,
cl_scnotification_created_by
) VALUES (
:webhook_id,
:banner_id,
:title,
:message,
:payload,
:response,
:success,
:created_by
)'
);
$stmt_log->execute([
'webhook_id' => $cl_scnotification_webhook_id,
'banner_id' => $cl_scnotification_banner_id > 0 ? $cl_scnotification_banner_id : null,
'title' => $cl_scnotification_title,
'message' => $cl_scnotification_message,
'payload' => json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
'response' => $log_response !== false ? $log_response : (string) ($result['response'] ?? ''),
'success' => (!empty($result['success']) && !empty($bot_actions['success'])) ? 1 : 0,
'created_by' => $current_session_user !== '' ? $current_session_user : 'Inconnu',
]);
if (empty($result['success'])) {
auth_flash_set('error', 'Échec de lenvoi Discord (HTTP ' . (int) ($result['http_code'] ?? 0) . ').');
} elseif (empty($bot_actions['success'])) {
auth_flash_set('error', 'Notification envoyée, mais échec des actions bot Discord : ' . (string) ($bot_actions['response'] ?? 'Erreur inconnue.'));
} else {
unset($_SESSION['scnotification_old']);
auth_flash_set('success', 'Notification Discord envoyée avec succès.');
}
header('Location: scnotification.php');
exit;
}
}
$old = $_SESSION['scnotification_old'] ?? [];
unset($_SESSION['scnotification_old']);
$stmt_webhooks = $db->query('SELECT * FROM tbl_scwebhooks ORDER BY cl_scwebhook_name ASC');
$webhooks = $stmt_webhooks->fetchAll();
$stmt_banners = $db->query('SELECT * FROM tbl_scbanners ORDER BY cl_scbanner_name ASC');
$banners = $stmt_banners->fetchAll();
function scnotification_old_value(array $old, string $key, string $default = ''): string
{
$value = $old[$key] ?? $default;
return is_string($value) ? $value : $default;
}
function scnotification_old_checked(array $old, string $key, bool $default = false): bool
{
if (empty($old)) {
return $default;
}
return array_key_exists($key, $old);
}
?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SC Notification | R.E.A.C.T. Admin</title>
<link rel="stylesheet" type="text/css" href="css/styles.css">
<link rel="stylesheet" type="text/css" href="css/default.css">
<style>
:root {
--primary: #a29b78;
--primary-glow: rgba(162, 155, 120, 0.4);
--bg-dark: #080a0f;
--card-bg: rgba(20, 24, 33, 0.85);
--border-glow: rgba(162, 155, 120, 0.25);
--danger: #ff4d4d;
--success: #00ff88;
--text-soft: #d7d7d7;
--text-muted: #9ea3ad;
}
@font-face {
font-family: 'Electrolize';
src: url('fonts/Electrolize-Regular.ttf') format('truetype');
}
* { box-sizing: border-box; }
body {
margin: 0;
min-height: 100vh;
background: radial-gradient(circle at top right, #1a1f2e, var(--bg-dark));
background-attachment: fixed;
color: #e0e0e0;
font-family: 'Electrolize', sans-serif;
overflow-x: hidden;
}
.admin-layout {
display: flex;
flex-direction: column;
max-width: 1400px;
margin: 0 auto;
padding: 2rem;
animation: fadeIn 0.6s ease-out;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.admin-topbar,
.page-shell,
.history-card {
background: var(--card-bg);
backdrop-filter: blur(12px);
border: 1px solid var(--border-glow);
border-radius: 12px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
}
.admin-topbar {
display: flex;
justify-content: space-between;
align-items: center;
gap: 1rem;
padding: 1.5rem 2rem;
margin-bottom: 2rem;
}
.topbar-info h1 {
margin: 0;
font-size: 1.5rem;
letter-spacing: 2px;
text-transform: uppercase;
background: linear-gradient(90deg, #fff, var(--primary));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.topbar-info p {
margin: 0.25rem 0 0;
font-size: 0.85rem;
color: var(--primary);
opacity: 0.8;
}
.btn-modern {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 0.4rem;
padding: 0.6rem 1.2rem;
border-radius: 4px;
border: 1px solid var(--primary);
background: transparent;
color: #fff;
text-decoration: none;
text-transform: uppercase;
font-size: 0.9rem;
cursor: pointer;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
font-family: 'Electrolize', sans-serif;
}
.btn-modern:hover {
background: var(--primary);
color: var(--bg-dark);
box-shadow: 0 0 15px var(--primary-glow);
}
.btn-modern.danger {
border-color: var(--danger);
color: var(--danger);
}
.btn-modern.danger:hover {
background: var(--danger);
color: #fff;
box-shadow: 0 0 15px rgba(255, 77, 77, 0.3);
}
.nav-tabs {
display: flex;
flex-wrap: wrap;
gap: 1rem;
margin-bottom: 2rem;
padding-bottom: 1rem;
border-bottom: 1px solid var(--border-glow);
}
.nav-tabs a {
text-decoration: none;
color: #888;
text-transform: uppercase;
font-size: 0.9rem;
transition: color 0.3s;
}
.nav-tabs a:hover,
.nav-tabs a.active {
color: var(--primary);
}
.flash {
margin-bottom: 1rem;
padding: 1rem 1.15rem;
border-radius: 10px;
border: 1px solid rgba(255, 255, 255, 0.08);
background: rgba(255, 255, 255, 0.04);
}
.flash.success { color: #9ff3c8; border-color: rgba(0, 255, 136, 0.25); }
.flash.error { color: #ff9d9d; border-color: rgba(255, 77, 77, 0.25); }
.page-shell {
padding: 1.5rem;
}
.page-title {
margin: 0 0 1.5rem;
padding-bottom: 0.75rem;
font-size: 1.25rem;
color: var(--primary);
border-bottom: 1px solid var(--border-glow);
}
.form-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
}
.form-column {
display: grid;
gap: 1rem;
}
.section-card {
background: rgba(255, 255, 255, 0.03);
border: 1px solid rgba(255, 255, 255, 0.05);
border-radius: 12px;
padding: 1.25rem;
}
.section-title {
margin: 0 0 1rem;
padding-bottom: 0.65rem;
color: var(--primary);
font-size: 1rem;
line-height: 1.2;
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
.field-row { margin-bottom: 0.85rem; }
.field-row:last-child { margin-bottom: 0; }
label, .inline-label {
display: block;
margin-bottom: 0.45rem;
font-size: 0.83rem;
color: #aaa;
text-transform: uppercase;
}
.check {
display: flex;
align-items: center;
gap: 0.55rem;
font-size: 0.9rem;
margin-bottom: 0.7rem;
color: #ededed;
text-transform: none;
}
.control,
textarea,
select,
input[type="text"],
input[type="url"],
input[type="date"],
input[type="time"] {
width: 100%;
padding: 0.8rem 1rem;
border-radius: 4px;
border: 1px solid #444;
background: rgba(0, 0, 0, 0.3);
color: #fff;
font-family: 'Electrolize', sans-serif;
transition: border-color 0.3s, background 0.3s;
}
.control:focus,
textarea:focus,
select:focus,
input[type="text"]:focus,
input[type="url"]:focus,
input[type="date"]:focus,
input[type="time"]:focus {
outline: none;
border-color: var(--primary);
background: rgba(0, 0, 0, 0.5);
}
textarea {
min-height: 180px;
resize: vertical;
}
input[disabled], select[disabled], textarea[disabled] {
opacity: 0.5;
cursor: not-allowed;
}
.subgrid-2 {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 0.8rem;
}
.char-counter {
margin-top: 0.3rem;
font-size: 0.72rem;
color: var(--text-muted);
text-align: right;
}
.submit-wrap {
margin-top: 1rem;
}
.submit-wrap .btn-modern {
width: 100%;
padding: 0.95rem 1.2rem;
}
.history-card {
margin-top: 1.5rem;
padding: 1.2rem;
}
.history-card h2 {
margin: 0 0 1rem;
padding-bottom: 0.75rem;
color: var(--primary);
font-size: 1.1rem;
text-transform: uppercase;
border-bottom: 1px solid var(--border-glow);
}
.history-list {
display: grid;
gap: 0.7rem;
}
.history-item {
padding: 0.85rem 0.95rem;
border-radius: 8px;
background: rgba(255, 255, 255, 0.03);
border: 1px solid rgba(255, 255, 255, 0.05);
}
.history-meta {
margin-top: 0.25rem;
color: var(--text-muted);
font-size: 0.78rem;
}
.status-pill {
display: inline-flex;
align-items: center;
gap: 0.35rem;
padding: 0.2rem 0.55rem;
border-radius: 999px;
font-size: 0.72rem;
text-transform: uppercase;
}
.status-pill.ok {
background: rgba(0, 255, 136, 0.12);
color: #9ff3c8;
}
.status-pill.ko {
background: rgba(255, 77, 77, 0.12);
color: #ffb0b0;
}
.empty-state {
padding: 1.2rem;
border: 1px dashed rgba(255, 255, 255, 0.12);
border-radius: 10px;
text-align: center;
color: var(--text-muted);
}
@media (max-width: 1024px) {
.form-grid, .subgrid-2 { grid-template-columns: 1fr; }
}
</style>
</head>
<body>
<div class="admin-layout">
<header class="admin-topbar">
<div class="topbar-info">
<h1>R.E.A.C.T. SC Notification</h1>
<p>Niveau d'accès : <strong><?php echo htmlspecialchars($role_label, ENT_QUOTES, 'UTF-8'); ?></strong> | Session : <strong><?php echo htmlspecialchars($current_session_user, ENT_QUOTES, 'UTF-8'); ?></strong></p>
</div>
<div class="topbar-actions">
<a href="index.php" class="btn-modern">Site</a>
<a href="logout.php" class="btn-modern danger">Exit</a>
</div>
</header>
<nav class="nav-tabs">
<?php if (auth_is_admin()): ?>
<a href="admin.php">Utilisateurs</a>
<a href="scwebhook.php">WEBHOOK</a>
<a href="scnotification.php" class="active">NOTIF DISCORD</a>
<a href="scitems.php">Base d'Objets</a>
<a href="scstatsitem.php">Stats Item</a>
<a href="scitemcustom.php">Item Custom</a>
<a href="scmining.php">Scanner Minage</a>
<a href="scmanufactures.php">Manufactures</a>
<a href="scvaisseaux.php">Vaisseaux</a>
<?php endif; ?>
<a href="scpreset.php">Presets Vaisseau</a>
</nav>
<?php if ($flash_message !== ''): ?>
<div class="flash <?php echo htmlspecialchars($flash_type, ENT_QUOTES, 'UTF-8'); ?>">
<?php echo htmlspecialchars($flash_message, ENT_QUOTES, 'UTF-8'); ?>
</div>
<?php endif; ?>
<div class="page-shell">
<div class="page-title">Envoi d'une notification sur Discord</div>
<form method="post">
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrf_token, ENT_QUOTES, 'UTF-8'); ?>">
<input type="hidden" name="action" value="send_notification">
<div class="form-grid">
<div class="form-column">
<section class="section-card">
<h2 class="section-title">Canal de notification</h2>
<div class="field-row">
<select class="control" name="cl_scnotification_webhook_id" required>
<option value="">Sélectionner un webhook</option>
<?php foreach ($webhooks as $webhook): ?>
<?php $selected = (string) $webhook['cl_scwebhook_id'] === scnotification_old_value($old, 'cl_scnotification_webhook_id'); ?>
<option value="<?php echo (int) $webhook['cl_scwebhook_id']; ?>" <?php echo $selected ? 'selected' : ''; ?>>
<?php echo htmlspecialchars($webhook['cl_scwebhook_name'] . (((int) $webhook['cl_scwebhook_is_forum'] === 1) ? ' [forum]' : ''), ENT_QUOTES, 'UTF-8'); ?>
</option>
<?php endforeach; ?>
</select>
</div>
</section>
<section class="section-card">
<h2 class="section-title">Bannière et Couleur de bordure</h2>
<div class="field-row">
<select class="control" name="cl_scnotification_banner_id" id="cl_scnotification_banner_id">
<option value="">Aucune bannière</option>
<?php foreach ($banners as $banner): ?>
<?php $selected = (string) $banner['cl_scbanner_id'] === scnotification_old_value($old, 'cl_scnotification_banner_id'); ?>
<option value="<?php echo (int) $banner['cl_scbanner_id']; ?>" <?php echo $selected ? 'selected' : ''; ?>>
<?php echo htmlspecialchars($banner['cl_scbanner_name'] . ' [' . scdiscord_normalize_hex_color((string) ($banner['cl_scbanner_border_color'] ?? '#ffae00')) . ']', ENT_QUOTES, 'UTF-8'); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<label class="check">
<input type="checkbox" name="cl_scnotification_use_custom_banner" id="cl_scnotification_use_custom_banner" value="1" <?php echo scnotification_old_checked($old, 'cl_scnotification_use_custom_banner') ? 'checked' : ''; ?>>
<span>Utiliser une bannière personnalisée</span>
</label>
<div class="field-row">
<input type="url" class="control" name="cl_scnotification_custom_banner_url" id="cl_scnotification_custom_banner_url" placeholder="URL personnalisée https://.../png" value="<?php echo htmlspecialchars(scnotification_old_value($old, 'cl_scnotification_custom_banner_url'), ENT_QUOTES, 'UTF-8'); ?>">
</div>
</section>
<section class="section-card">
<h2 class="section-title">Message</h2>
<label class="check">
<input type="checkbox" name="cl_scnotification_notify_here" value="1" <?php echo scnotification_old_checked($old, 'cl_scnotification_notify_here') ? 'checked' : ''; ?>>
<span>Notifier avec @here</span>
</label>
<label class="check">
<input type="checkbox" name="cl_scnotification_notify_everyone" value="1" <?php echo scnotification_old_checked($old, 'cl_scnotification_notify_everyone', true) ? 'checked' : ''; ?>>
<span>Notifier avec @everyone</span>
</label>
<div class="field-row">
<label for="cl_scnotification_title">Titre :</label>
<input type="text" class="control" id="cl_scnotification_title" name="cl_scnotification_title" value="<?php echo htmlspecialchars(scnotification_old_value($old, 'cl_scnotification_title'), ENT_QUOTES, 'UTF-8'); ?>">
</div>
<div class="field-row">
<label for="cl_scnotification_message">Description :</label>
<textarea id="cl_scnotification_message" name="cl_scnotification_message" maxlength="2500" placeholder="Compatible avec le Markdown Discord..."><?php echo htmlspecialchars(scnotification_old_value($old, 'cl_scnotification_message'), ENT_QUOTES, 'UTF-8'); ?></textarea>
<div class="char-counter"><span id="messageCount">2500</span> caractères restants</div>
</div>
</section>
<section class="section-card">
<h2 class="section-title">Options Footer</h2>
<label class="check">
<input type="checkbox" name="cl_scnotification_show_footer" id="cl_scnotification_show_footer" value="1" <?php echo scnotification_old_checked($old, 'cl_scnotification_show_footer', true) ? 'checked' : ''; ?>>
<span>Afficher le footer</span>
</label>
<div class="field-row">
<label for="cl_scnotification_footer_text">Texte du footer :</label>
<input type="text" class="control footer-toggle" id="cl_scnotification_footer_text" name="cl_scnotification_footer_text" value="<?php echo htmlspecialchars(scnotification_old_value($old, 'cl_scnotification_footer_text', 'R.E.A.C.T Initiative'), ENT_QUOTES, 'UTF-8'); ?>">
</div>
<div class="field-row">
<label for="cl_scnotification_footer_icon_url">URL icône footer :</label>
<input type="url" class="control footer-toggle" id="cl_scnotification_footer_icon_url" name="cl_scnotification_footer_icon_url" value="<?php echo htmlspecialchars(scnotification_old_value($old, 'cl_scnotification_footer_icon_url'), ENT_QUOTES, 'UTF-8'); ?>" placeholder="*.png">
</div>
</section>
<section class="section-card">
<h2 class="section-title">Réactions &amp; Fils</h2>
<label class="check">
<input type="checkbox" name="cl_scnotification_show_reactions" value="1" <?php echo scnotification_old_checked($old, 'cl_scnotification_show_reactions') ? 'checked' : ''; ?>>
<span>Afficher les réactions 👍 / ⏳ / ❓ / 👎</span>
</label>
<label class="check">
<input type="checkbox" name="cl_scnotification_show_thread" value="1" <?php echo scnotification_old_checked($old, 'cl_scnotification_show_thread', true) ? 'checked' : ''; ?>>
<span>Afficher le fil de discussion</span>
</label>
</section>
</div>
<div class="form-column">
<section class="section-card">
<h2 class="section-title">Tenue d'organisation &amp; PvP</h2>
<label class="check">
<input type="checkbox" name="cl_scnotification_show_org" id="cl_scnotification_show_org" value="1" <?php echo scnotification_old_checked($old, 'cl_scnotification_show_org') ? 'checked' : ''; ?>>
<span>Afficher la tenue d'organisation</span>
</label>
<div class="field-row">
<select class="control org-toggle" name="cl_scnotification_org_value" id="cl_scnotification_org_value">
<?php foreach (['Non', 'Tenue civile', 'Tenue organisation', 'Tenue lourde'] as $option): ?>
<option value="<?php echo htmlspecialchars($option, ENT_QUOTES, 'UTF-8'); ?>" <?php echo scnotification_old_value($old, 'cl_scnotification_org_value', 'Non') === $option ? 'selected' : ''; ?>><?php echo htmlspecialchars($option, ENT_QUOTES, 'UTF-8'); ?></option>
<?php endforeach; ?>
</select>
</div>
<label class="check">
<input type="checkbox" name="cl_scnotification_show_pvp" id="cl_scnotification_show_pvp" value="1" <?php echo scnotification_old_checked($old, 'cl_scnotification_show_pvp') ? 'checked' : ''; ?>>
<span>Afficher les risques PvP</span>
</label>
<div class="field-row">
<select class="control pvp-toggle" name="cl_scnotification_pvp_value" id="cl_scnotification_pvp_value">
<?php foreach (['Inexistant', 'Faible', 'Modéré', 'Important', 'Extrême'] as $option): ?>
<option value="<?php echo htmlspecialchars($option, ENT_QUOTES, 'UTF-8'); ?>" <?php echo scnotification_old_value($old, 'cl_scnotification_pvp_value', 'Inexistant') === $option ? 'selected' : ''; ?>><?php echo htmlspecialchars($option, ENT_QUOTES, 'UTF-8'); ?></option>
<?php endforeach; ?>
</select>
</div>
</section>
<section class="section-card">
<h2 class="section-title">Lieu, Date et Heure</h2>
<label class="check">
<input type="checkbox" name="cl_scnotification_include_schedule" id="cl_scnotification_include_schedule" value="1" <?php echo scnotification_old_checked($old, 'cl_scnotification_include_schedule') ? 'checked' : ''; ?>>
<span>Inclure date, lieu et heures</span>
</label>
<div class="field-row">
<label for="cl_scnotification_location">Lieu de ralliement :</label>
<input type="text" class="control schedule-toggle" id="cl_scnotification_location" name="cl_scnotification_location" value="<?php echo htmlspecialchars(scnotification_old_value($old, 'cl_scnotification_location'), ENT_QUOTES, 'UTF-8'); ?>">
</div>
<div class="field-row subgrid-2">
<div>
<label for="cl_scnotification_start_date">Date de début :</label>
<input type="date" class="control schedule-toggle" id="cl_scnotification_start_date" name="cl_scnotification_start_date" value="<?php echo htmlspecialchars(scnotification_old_value($old, 'cl_scnotification_start_date'), ENT_QUOTES, 'UTF-8'); ?>">
</div>
<div>
<label for="cl_scnotification_departure_time">Heure de départ :</label>
<input type="time" class="control schedule-toggle" id="cl_scnotification_departure_time" name="cl_scnotification_departure_time" value="<?php echo htmlspecialchars(scnotification_old_value($old, 'cl_scnotification_departure_time', '21:30'), ENT_QUOTES, 'UTF-8'); ?>">
</div>
</div>
<label class="check">
<input type="checkbox" name="cl_scnotification_include_briefing_time" id="cl_scnotification_include_briefing_time" value="1" <?php echo scnotification_old_checked($old, 'cl_scnotification_include_briefing_time') ? 'checked' : ''; ?>>
<span>Inclure une heure de briefing</span>
</label>
<div class="field-row">
<label for="cl_scnotification_briefing_time">Heure de briefing :</label>
<input type="time" class="control briefing-toggle" id="cl_scnotification_briefing_time" name="cl_scnotification_briefing_time" value="<?php echo htmlspecialchars(scnotification_old_value($old, 'cl_scnotification_briefing_time', '21:00'), ENT_QUOTES, 'UTF-8'); ?>">
</div>
<label class="check">
<input type="checkbox" name="cl_scnotification_include_end_date" id="cl_scnotification_include_end_date" value="1" <?php echo scnotification_old_checked($old, 'cl_scnotification_include_end_date') ? 'checked' : ''; ?>>
<span>Inclure une date de fin</span>
</label>
<div class="field-row">
<label for="cl_scnotification_end_date">Date de fin :</label>
<input type="date" class="control enddate-toggle" id="cl_scnotification_end_date" name="cl_scnotification_end_date" value="<?php echo htmlspecialchars(scnotification_old_value($old, 'cl_scnotification_end_date'), ENT_QUOTES, 'UTF-8'); ?>">
</div>
<label class="check">
<input type="checkbox" name="cl_scnotification_include_end_time" id="cl_scnotification_include_end_time" value="1" <?php echo scnotification_old_checked($old, 'cl_scnotification_include_end_time') ? 'checked' : ''; ?>>
<span>Inclure une heure de fin</span>
</label>
<div class="field-row">
<label for="cl_scnotification_end_time">Heure de fin :</label>
<input type="time" class="control endtime-toggle" id="cl_scnotification_end_time" name="cl_scnotification_end_time" value="<?php echo htmlspecialchars(scnotification_old_value($old, 'cl_scnotification_end_time', '00:00'), ENT_QUOTES, 'UTF-8'); ?>">
</div>
</section>
<section class="section-card">
<h2 class="section-title">URL externes</h2>
<label class="check">
<input type="checkbox" name="cl_scnotification_show_channel_url" id="cl_scnotification_show_channel_url" value="1" <?php echo scnotification_old_checked($old, 'cl_scnotification_show_channel_url') ? 'checked' : ''; ?>>
<span>Afficher un lien de canal Discord</span>
</label>
<div class="field-row">
<label for="cl_scnotification_channel_url">URL Canal :</label>
<input type="url" class="control channelurl-toggle" id="cl_scnotification_channel_url" name="cl_scnotification_channel_url" value="<?php echo htmlspecialchars(scnotification_old_value($old, 'cl_scnotification_channel_url', 'https://discord.com/channels/...'), ENT_QUOTES, 'UTF-8'); ?>">
</div>
<label class="check">
<input type="checkbox" name="cl_scnotification_show_inventory_url" id="cl_scnotification_show_inventory_url" value="1" <?php echo scnotification_old_checked($old, 'cl_scnotification_show_inventory_url') ? 'checked' : ''; ?>>
<span>Afficher une URL de l'inventaire A.R.I.A</span>
</label>
<div class="field-row">
<label for="cl_scnotification_inventory_url">URL Inventaire :</label>
<input type="url" class="control inventoryurl-toggle" id="cl_scnotification_inventory_url" name="cl_scnotification_inventory_url" value="<?php echo htmlspecialchars(scnotification_old_value($old, 'cl_scnotification_inventory_url', 'https://aria.blackops-agency.fr/...'), ENT_QUOTES, 'UTF-8'); ?>">
</div>
<label class="check">
<input type="checkbox" name="cl_scnotification_show_source_url" id="cl_scnotification_show_source_url" value="1" <?php echo scnotification_old_checked($old, 'cl_scnotification_show_source_url') ? 'checked' : ''; ?>>
<span>Afficher une URL source</span>
</label>
<div class="field-row">
<label for="cl_scnotification_source_url">URL Source :</label>
<input type="url" class="control sourceurl-toggle" id="cl_scnotification_source_url" name="cl_scnotification_source_url" value="<?php echo htmlspecialchars(scnotification_old_value($old, 'cl_scnotification_source_url', 'https://...'), ENT_QUOTES, 'UTF-8'); ?>">
</div>
</section>
</div>
</div>
<div class="submit-wrap">
<button type="submit" class="btn-modern">Envoyer</button>
</div>
</form>
</div>
</div>
<script>
const messageField = document.getElementById('cl_scnotification_message');
const messageCount = document.getElementById('messageCount');
function updateCounter() {
const remaining = 2500 - (messageField.value || '').length;
messageCount.textContent = remaining;
}
function toggleByCheckbox(checkboxId, selector, invert = false) {
const checkbox = document.getElementById(checkboxId);
const targets = document.querySelectorAll(selector);
if (!checkbox) return;
const enabled = invert ? !checkbox.checked : checkbox.checked;
targets.forEach((target) => {
target.disabled = !enabled;
});
}
function syncStates() {
toggleByCheckbox('cl_scnotification_use_custom_banner', '#cl_scnotification_custom_banner_url');
toggleByCheckbox('cl_scnotification_show_footer', '.footer-toggle');
toggleByCheckbox('cl_scnotification_show_org', '.org-toggle');
toggleByCheckbox('cl_scnotification_show_pvp', '.pvp-toggle');
toggleByCheckbox('cl_scnotification_include_schedule', '.schedule-toggle');
const scheduleEnabled = document.getElementById('cl_scnotification_include_schedule')?.checked;
document.getElementById('cl_scnotification_include_briefing_time').disabled = !scheduleEnabled;
document.getElementById('cl_scnotification_include_end_date').disabled = !scheduleEnabled;
document.getElementById('cl_scnotification_include_end_time').disabled = !scheduleEnabled;
toggleByCheckbox('cl_scnotification_include_briefing_time', '.briefing-toggle');
toggleByCheckbox('cl_scnotification_include_end_date', '.enddate-toggle');
toggleByCheckbox('cl_scnotification_include_end_time', '.endtime-toggle');
if (!scheduleEnabled) {
document.querySelectorAll('.briefing-toggle, .enddate-toggle, .endtime-toggle').forEach(el => el.disabled = true);
}
toggleByCheckbox('cl_scnotification_show_channel_url', '.channelurl-toggle');
toggleByCheckbox('cl_scnotification_show_inventory_url', '.inventoryurl-toggle');
toggleByCheckbox('cl_scnotification_show_source_url', '.sourceurl-toggle');
}
updateCounter();
messageField.addEventListener('input', updateCounter);
[
'cl_scnotification_use_custom_banner',
'cl_scnotification_show_footer',
'cl_scnotification_show_org',
'cl_scnotification_show_pvp',
'cl_scnotification_include_schedule',
'cl_scnotification_include_briefing_time',
'cl_scnotification_include_end_date',
'cl_scnotification_include_end_time',
'cl_scnotification_show_channel_url',
'cl_scnotification_show_inventory_url',
'cl_scnotification_show_source_url'
].forEach((id) => {
const el = document.getElementById(id);
if (el) {
el.addEventListener('change', syncStates);
}
});
syncStates();
</script>
</body>
</html>