'', 'level' => 'info']; if (!is_file(ANN_FILE)) return $empty; $raw = trim((string)@file_get_contents(ANN_FILE)); if ($raw === '') return $empty; $d = json_decode($raw, true); return is_array($d) ? $d + $empty : null; } // Writes the announcement atomically. Returns an error message or null. function ann_save($text, $level) { $lock = @fopen(__DIR__ . '/data/.lock', 'c'); if (!$lock || !flock($lock, LOCK_EX)) return 'Cannot write to announcement/data. Check its permissions.'; if (ann_read() === null) return 'announcement.json is malformed. Nothing was saved; fix or delete the file.'; $json = json_encode(['text' => $text, 'level' => $level], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); $tmp = @tempnam(__DIR__ . '/data', 'ann'); if ($json === false || !$tmp || file_put_contents($tmp, $json) !== strlen($json) || !@rename($tmp, ANN_FILE)) { if ($tmp) @unlink($tmp); return 'Could not save. Check the announcement/data permissions.'; } return null; } // Save or clear (admin only, with CSRF token). $annNotice = null; $annSaved = false; $annAct = $_POST['announcement_action'] ?? null; if ($_SERVER['REQUEST_METHOD'] === 'POST' && in_array($annAct, ['save', 'clear'], true)) { if (!$isAdmin || !hash_equals($csrf, (string)($_POST['csrf'] ?? ''))) { $annNotice = ['danger', 'Not allowed.']; } else { $annText = $annAct === 'clear' ? '' : trim((string)($_POST['announcement_text'] ?? '')); $annLevel = $annAct === 'clear' ? 'info' : ($_POST['announcement_level'] ?? ''); if (!in_array($annLevel, ANN_LEVELS, true)) { $annNotice = ['danger', 'Invalid colour choice.']; } elseif (!preg_match('/^[^\x00-\x1F\x7F]{0,300}$/u', $annText)) { $annNotice = ['danger', 'The announcement must be one line, up to 300 characters.']; } else { $annErr = ann_save($annText, $annLevel); $annNotice = $annErr ? ['danger', $annErr] : ['success', 'Announcement saved.']; $annSaved = !$annErr; } } } $ann = ann_read(); if ($ann === null) { $ann = ['text' => '', 'level' => 'info']; if ($isAdmin && !$annNotice) $annNotice = ['danger', 'announcement.json is malformed. Fix or delete it.']; } $annLevelOk = in_array($ann['level'], ANN_LEVELS, true) ? $ann['level'] : 'info'; $annEditing = $isAdmin && $edit === 'announcement' && !$annSaved; ?>
Cancel

+ Add announcement