Major changes: - New ThemeManager with Twig templating and SCSS compilation - Dynamic themes system (themes/default, themes/demo) - LogManager with SQLite storage and syslog forwarding - RequestLogger with static helper methods - Admin UI overhaul (Bootstrap 5, dark mode) - Admin config page with logging and theme settings - Admin logs page with filters and search - Removed legacy Mustache templates - Removed test plugin and theme - Composer dependencies: Twig, scssphp, CommonMark, MaxMind GeoIP
225 lines
13 KiB
PHP
225 lines
13 KiB
PHP
<h2 class="mb-4"><i class="bi bi-sliders"></i> Configuratie</h2>
|
||
|
||
<form method="POST" action="/admin/config">
|
||
<input type="hidden" name="csrf_token" value="<?= $csrf ?>">
|
||
|
||
<div class="card shadow-sm mb-4">
|
||
<div class="card-header">
|
||
<i class="bi bi-globe"></i> Algemene instellingen
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="row mb-3">
|
||
<div class="col-md-6">
|
||
<label for="site_title" class="form-label">Site titel</label>
|
||
<input type="text" class="form-control" id="site_title" name="site_title"
|
||
value="<?= htmlspecialchars($configData['site_title'] ?? 'CodePress') ?>">
|
||
</div>
|
||
<div class="col-md-6">
|
||
<label for="default_page" class="form-label">Standaard/startpagina</label>
|
||
<select name="default_page" id="default_page" class="form-select">
|
||
<option value="auto" <?= ($configData['default_page'] ?? 'auto') === 'auto' ? 'selected' : '' ?>>Auto (eerste beschikbare pagina)</option>
|
||
<option value="newest" <?= ($configData['default_page'] ?? '') === 'newest' ? 'selected' : '' ?>>Nieuwste (laatste gewijzigde pagina)</option>
|
||
<?php foreach ($availablePages as $page): ?>
|
||
<option value="<?= htmlspecialchars($page) ?>" <?= ($configData['default_page'] ?? '') === $page ? 'selected' : '' ?>>
|
||
<?= htmlspecialchars(ucwords(str_replace(['-', '_'], ' ', $page))) ?>
|
||
</option>
|
||
<?php endforeach; ?>
|
||
</select>
|
||
<small class="form-text text-muted">Welke pagina wordt getoond als bezoekers de site openen.</small>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card shadow-sm mb-4">
|
||
<div class="card-header">
|
||
<i class="bi bi-translate"></i> Taal
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="row mb-3">
|
||
<div class="col-md-4">
|
||
<label for="language_default" class="form-label">Standaard taal</label>
|
||
<select name="language_default" id="language_default" class="form-select">
|
||
<?php foreach (['nl' => 'Nederlands', 'en' => 'English'] as $code => $label): ?>
|
||
<option value="<?= $code ?>" <?= ($configData['language']['default'] ?? 'nl') === $code ? 'selected' : '' ?>>
|
||
<?= $label ?>
|
||
</option>
|
||
<?php endforeach; ?>
|
||
</select>
|
||
</div>
|
||
<div class="col-md-8">
|
||
<label class="form-label">Beschikbare talen</label>
|
||
<div>
|
||
<?php $availLangs = $configData['language']['available'] ?? ['nl', 'en']; ?>
|
||
<div class="form-check form-check-inline">
|
||
<input type="checkbox" class="form-check-input" id="lang_nl" name="language_available[]" value="nl" <?= in_array('nl', $availLangs) ? 'checked' : '' ?>>
|
||
<label class="form-check-label" for="lang_nl">Nederlands</label>
|
||
</div>
|
||
<div class="form-check form-check-inline">
|
||
<input type="checkbox" class="form-check-input" id="lang_en" name="language_available[]" value="en" <?= in_array('en', $availLangs) ? 'checked' : '' ?>>
|
||
<label class="form-check-label" for="lang_en">English</label>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card shadow-sm mb-4">
|
||
<div class="card-header">
|
||
<i class="bi bi-search"></i> SEO
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="mb-3">
|
||
<label for="seo_description" class="form-label">Meta beschrijving</label>
|
||
<textarea class="form-control" id="seo_description" name="seo_description" rows="2"><?= htmlspecialchars($configData['seo']['description'] ?? '') ?></textarea>
|
||
</div>
|
||
<div class="mb-3">
|
||
<label for="seo_keywords" class="form-label">Meta keywords</label>
|
||
<input type="text" class="form-control" id="seo_keywords" name="seo_keywords"
|
||
value="<?= htmlspecialchars($configData['seo']['keywords'] ?? '') ?>">
|
||
<small class="form-text text-muted">Komma-gescheiden trefwoorden.</small>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card shadow-sm mb-4">
|
||
<div class="card-header">
|
||
<i class="bi bi-person"></i> Auteur
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="row mb-3">
|
||
<div class="col-md-6">
|
||
<label for="author_name" class="form-label">Naam</label>
|
||
<input type="text" class="form-control" id="author_name" name="author_name"
|
||
value="<?= htmlspecialchars($configData['author']['name'] ?? '') ?>">
|
||
</div>
|
||
<div class="col-md-6">
|
||
<label for="author_website" class="form-label">Website URL</label>
|
||
<input type="text" class="form-control" id="author_website" name="author_website"
|
||
value="<?= htmlspecialchars($configData['author']['website'] ?? '') ?>" placeholder="bijv. noorlander.info">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card shadow-sm mb-4">
|
||
<div class="card-header">
|
||
<i class="bi bi-toggle-on"></i> Features
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="form-check mb-2">
|
||
<input type="checkbox" class="form-check-input" id="feature_auto_link" name="feature_auto_link" value="1" <?= !empty($configData['features']['auto_link_pages']) ? 'checked' : '' ?>>
|
||
<label class="form-check-label" for="feature_auto_link">Automatisch pagina's linken</label>
|
||
</div>
|
||
<div class="form-check mb-2">
|
||
<input type="checkbox" class="form-check-input" id="feature_search" name="feature_search" value="1" <?= !empty($configData['features']['search_enabled']) ? 'checked' : '' ?>>
|
||
<label class="form-check-label" for="feature_search">Zoekfunctie inschakelen</label>
|
||
</div>
|
||
<div class="form-check mb-2">
|
||
<input type="checkbox" class="form-check-input" id="feature_breadcrumbs" name="feature_breadcrumbs" value="1" <?= !empty($configData['features']['breadcrumbs_enabled']) ? 'checked' : '' ?>>
|
||
<label class="form-check-label" for="feature_breadcrumbs">Breadcrumbs tonen</label>
|
||
</div>
|
||
<div class="form-check">
|
||
<input type="checkbox" class="form-check-input" id="show_version" name="show_version" value="1" <?= !empty($configData['show_version']) ? 'checked' : '' ?>>
|
||
<label class="form-check-label" for="show_version">CMS versie tonen in footer</label>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card shadow-sm mb-4">
|
||
<div class="card-header">
|
||
<i class="bi bi-eye-slash"></i> IP Uitsluitingen
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="mb-3">
|
||
<label for="excluded_ips" class="form-label fw-bold">IP-adressen uitsluiten van statistieken en beveiliging</label>
|
||
<textarea class="form-control font-monospace" id="excluded_ips" name="excluded_ips" rows="4" placeholder="Één IP per regel (bijv. 127.0.0.1)"><?= htmlspecialchars(implode("\n", $configData['analytics']['excluded_ips'] ?? [])) ?></textarea>
|
||
<div class="form-text">Verzoeken van deze IP-adressen worden niet opgenomen in de statistieken en overgeslagen bij beveiligingscontroles (bot-detectie, rate limiting).</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card shadow-sm mb-4">
|
||
<div class="card-header">
|
||
<i class="bi bi-journal-text"></i> Logging
|
||
</div>
|
||
<div class="card-body">
|
||
<?php $logging = $configData['logging'] ?? []; ?>
|
||
<div class="form-check mb-3">
|
||
<input type="checkbox" class="form-check-input" id="logging_enabled" name="logging_enabled" value="1" <?= !empty($logging['enabled']) ? 'checked' : '' ?>>
|
||
<label class="form-check-label" for="logging_enabled">Logging inschakelen</label>
|
||
</div>
|
||
|
||
<div class="row mb-3">
|
||
<div class="col-md-6">
|
||
<label for="logging_driver" class="form-label">Opslag</label>
|
||
<select class="form-select" id="logging_driver" name="logging_driver">
|
||
<option value="sqlite" <?= ($logging['driver'] ?? 'sqlite') === 'sqlite' ? 'selected' : '' ?>>SQLite (standaard)</option>
|
||
<option value="syslog" <?= ($logging['driver'] ?? '') === 'syslog' ? 'selected' : '' ?>>Syslog</option>
|
||
</select>
|
||
<div class="form-text">Kies <strong>Syslog</strong> om logregels naar een externe syslog-server te sturen. Logregels worden altijd ook lokaal opgeslagen.</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="row g-3 mb-3">
|
||
<div class="col-md-6">
|
||
<label for="syslog_host" class="form-label">Syslog server (host)</label>
|
||
<input type="text" class="form-control font-monospace" id="syslog_host" name="syslog_host"
|
||
value="<?= htmlspecialchars($logging['syslog_host'] ?? '') ?>" placeholder="bijv. 192.168.1.10">
|
||
<div class="form-text">Vul de host van de syslog-server in (bijv. <code>192.168.1.10</code> of <code>logs.example.com</code>).</div>
|
||
</div>
|
||
<div class="col-md-3">
|
||
<label for="syslog_port" class="form-label">Poort</label>
|
||
<input type="number" class="form-control" id="syslog_port" name="syslog_port" min="1" max="65535"
|
||
value="<?= (int)($logging['syslog_port'] ?? 514) ?>">
|
||
</div>
|
||
<div class="col-md-3">
|
||
<label for="syslog_facility" class="form-label">Facility</label>
|
||
<select class="form-select" id="syslog_facility" name="syslog_facility">
|
||
<?php foreach (['local0', 'local1', 'local2', 'local3', 'local4', 'local5', 'local6', 'local7', 'daemon', 'user', 'auth'] as $fac): ?>
|
||
<option value="<?= $fac ?>" <?= ($logging['syslog_facility'] ?? 'local0') === $fac ? 'selected' : '' ?>><?= $fac ?></option>
|
||
<?php endforeach; ?>
|
||
</select>
|
||
<div class="form-text">Categorie van de logbron (bijv. <code>local0</code>–<code>local7</code> voor eigen applicaties).</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="mb-3">
|
||
<label for="syslog_ident" class="form-label">Syslog ident</label>
|
||
<input type="text" class="form-control font-monospace" id="syslog_ident" name="syslog_ident"
|
||
value="<?= htmlspecialchars($logging['syslog_ident'] ?? 'codepress') ?>">
|
||
</div>
|
||
|
||
<div class="mb-3">
|
||
<label class="form-label fw-bold">Te registreren gebeurtenissen</label>
|
||
<?php $events = $logging['events'] ?? []; ?>
|
||
<div class="row">
|
||
<?php
|
||
$eventLabels = [
|
||
'admin' => 'Admin activiteiten',
|
||
'requests' => 'Requests (pagina bezoeken)',
|
||
'errors' => 'Fouten & waarschuwingen',
|
||
'security' => 'Beveiliging',
|
||
'content' => 'Content wijzigingen',
|
||
'system' => 'Systeem',
|
||
];
|
||
foreach ($eventLabels as $key => $label):
|
||
?>
|
||
<div class="col-md-4">
|
||
<div class="form-check">
|
||
<input type="checkbox" class="form-check-input" id="logging_event_<?= $key ?>" name="logging_events[]" value="<?= $key ?>" <?= !empty($events[$key]) ? 'checked' : '' ?>>
|
||
<label class="form-check-label" for="logging_event_<?= $key ?>"><?= $label ?></label>
|
||
</div>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<button type="submit" class="btn btn-primary btn-lg">
|
||
<i class="bi bi-check-lg"></i> Configuratie opslaan
|
||
</button>
|
||
</form>
|