$v) {
$url .= '&' . urlencode($k) . '=' . urlencode((string)$v);
}
return $url;
}
function publiserPublicUrl(string $section, string $folder): string {
return '/' . rawurlencode($section) . '/' . rawurlencode($folder) . '/';
}
function publiserImageUrl(string $location, string $section, string $folder, string $filename): string {
if ($location === 'live') {
return '/' . rawurlencode($section) . '/' . rawurlencode($folder) . '/' . rawurlencode($filename);
}
return publiserBaseUrl() . '?action=image&location=' . urlencode($location)
. '§ion=' . urlencode($section) . '&folder=' . urlencode($folder) . '&file=' . urlencode($filename);
}
function publiserCheckCsrf(): void {
global $csrf;
$token = $_POST['csrf'] ?? $_SERVER['HTTP_X_CSRF_TOKEN'] ?? '';
if (!hash_equals($csrf, $token)) {
http_response_code(403);
die('Ugyldig forespørsel (utløpt økt). Last siden på nytt og prøv igjen.');
}
}
function publiserRedirect(string $url): never {
header("Location: $url");
exit;
}
function publiserItemDir(string $location, string $section, string $folder): string {
return match ($location) {
'live' => publiserLiveDir($section, $folder),
'draft' => publiserDraftDir($section, $folder),
'trash' => publiserTrashDir($section, $folder),
default => throw new RuntimeException('Ugyldig plassering'),
};
}
// --- minimal Markdown -> HTML for populating the WYSIWYG editor on load ----
// (mirrors the bounded tag set publiser.js can serialize back to Markdown)
function publiserEscapeInline(string $text): string {
return htmlspecialchars($text, ENT_QUOTES, 'UTF-8');
}
function publiserInlineMdToHtml(string $text, callable $imageUrlResolver): string {
$text = publiserEscapeInline($text);
$text = preg_replace_callback('/!\[(.*?)\]\((.*?)\)/', function ($m) use ($imageUrlResolver) {
$alt = $m[1];
$file = $m[2];
$realFile = html_entity_decode($file, ENT_QUOTES, 'UTF-8');
$url = htmlspecialchars($imageUrlResolver($realFile), ENT_QUOTES, 'UTF-8');
return '';
}, $text) ?? $text;
$text = preg_replace_callback('/\[(.*?)\]\((.*?)\)/', function ($m) {
return '' . $m[1] . '';
}, $text) ?? $text;
$text = preg_replace('/\*\*(.+?)\*\*/', '$1', $text) ?? $text;
$text = preg_replace('/(?$1', $text) ?? $text;
return $text;
}
function publiserBlockMdToHtml(string $md, callable $imageUrlResolver): string {
$md = str_replace("\r\n", "\n", trim($md));
if ($md === '') return '