Display-Seiten individuell gestalten
Some checks are pending
CI / PHP Lint (push) Waiting to run
CI / PHP Lint (pull_request) Waiting to run
CI / PHP Lint-1 (pull_request) Waiting to run
CI / PHP Lint-1 (push) Waiting to run
CI / Unit Tests & Static Analysis (pull_request) Waiting to run
CI / Unit Tests & Static Analysis (push) Waiting to run
Some checks are pending
CI / PHP Lint (push) Waiting to run
CI / PHP Lint (pull_request) Waiting to run
CI / PHP Lint-1 (pull_request) Waiting to run
CI / PHP Lint-1 (push) Waiting to run
CI / Unit Tests & Static Analysis (pull_request) Waiting to run
CI / Unit Tests & Static Analysis (push) Waiting to run
Jede Display-Seite bringt jetzt ihr eigenes Erscheinungsbild mit – der Empfang sieht anders aus als der Tagungsraum nebenan: - eigenes Logo (leer = Logo aus den Einstellungen) - formatfüllendes Hintergrundbild mit einstellbarer Abdunklung (0–90 %), damit die Karte auf hellen Fotos lesbar bleibt - eigene Akzentfarbe für den Knopf (leer = Farbe aus dem Design-Tab) - Karte wahlweise hell oder dunkel; auf Fotos wirkt dunkel meist ruhiger Logo und Hintergrund lassen sich hochladen oder als URL hinterlegen; beim Löschen einer Display-Seite verschwinden die hochgeladenen Dateien mit. Nebenbei aufgeräumt: das Bildfeld (Vorschau + Upload + URL + Entfernen) lag als Funktion in admin/settings.php und wird jetzt von beiden Seiten genutzt – Ui::imageField() für die Darstellung, Upload::resolveField() für die Auswertung. Sicherheit: die Akzentfarbe landet in einem style-Attribut, deshalb wird sie sowohl beim Speichern als auch beim Ausgeben auf eine echte Hex-Farbe geprüft; ein Test hält das fest. Migration 0006, database.sql nachgezogen, 4 neue Tests (42 gesamt), Screenshots ergänzt, Version 2.8.0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
943e427150
commit
4159b92268
31 changed files with 405 additions and 82 deletions
|
|
@ -42,33 +42,6 @@ if (isset($_POST['ajax_smtp_test'])) {
|
|||
$error = '';
|
||||
$success = '';
|
||||
|
||||
/**
|
||||
* Liefert den neuen Wert eines Bildfeldes: Upload schlaegt URL, und ein
|
||||
* gesetzter Entfernen-Schalter loescht die bisherige Datei.
|
||||
*/
|
||||
function resolveImageField(string $name, Database $db, string $kind): string
|
||||
{
|
||||
$current = (string)$db->getSetting($name, '');
|
||||
|
||||
$uploaded = Upload::store($_FILES[$name . '_file'] ?? [], $kind);
|
||||
if ($uploaded !== '') {
|
||||
Upload::delete($current);
|
||||
return $uploaded;
|
||||
}
|
||||
|
||||
if (!empty($_POST[$name . '_remove'])) {
|
||||
Upload::delete($current);
|
||||
return '';
|
||||
}
|
||||
|
||||
$value = trim($_POST[$name] ?? '');
|
||||
if ($value !== $current && Upload::isLocal($current) && !Upload::isLocal($value)) {
|
||||
Upload::delete($current);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
// Einstellungen speichern
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['save_settings'])) {
|
||||
if (!$auth->validateCsrfToken($_POST['csrf_token'] ?? '')) {
|
||||
|
|
@ -80,8 +53,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['save_settings'])) {
|
|||
|
||||
if ($formType === 'general') {
|
||||
$settings['app_title'] = trim($_POST['app_title'] ?? '');
|
||||
$settings['logo_url'] = resolveImageField('logo_url', $db, 'image');
|
||||
$settings['favicon_url'] = resolveImageField('favicon_url', $db, 'favicon');
|
||||
$settings['logo_url'] = Upload::resolveField('logo_url', (string)$db->getSetting('logo_url', ''), 'image');
|
||||
$settings['favicon_url'] = Upload::resolveField('favicon_url', (string)$db->getSetting('favicon_url', ''), 'favicon');
|
||||
$settings['instruction_header'] = trim($_POST['instruction_header'] ?? '');
|
||||
$settings['instruction_text'] = $_POST['instruction_text'] ?? '';
|
||||
$settings['public_access'] = isset($_POST['public_access']) ? '1' : '0';
|
||||
|
|
@ -99,12 +72,12 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['save_settings'])) {
|
|||
if ($formType === 'login') {
|
||||
$settings['login_panel_enabled'] = isset($_POST['login_panel_enabled']) ? '1' : '0';
|
||||
$settings['login_brand_name'] = trim($_POST['login_brand_name'] ?? '');
|
||||
$settings['login_logo_url'] = resolveImageField('login_logo_url', $db, 'image');
|
||||
$settings['login_logo_url'] = Upload::resolveField('login_logo_url', (string)$db->getSetting('login_logo_url', ''), 'image');
|
||||
$settings['login_claim_title'] = trim($_POST['login_claim_title'] ?? '');
|
||||
$settings['login_claim_text'] = trim($_POST['login_claim_text'] ?? '');
|
||||
$settings['login_features'] = trim($_POST['login_features'] ?? '');
|
||||
$settings['login_footer'] = trim($_POST['login_footer'] ?? '');
|
||||
$settings['login_bg_image'] = resolveImageField('login_bg_image', $db, 'image');
|
||||
$settings['login_bg_image'] = Upload::resolveField('login_bg_image', (string)$db->getSetting('login_bg_image', ''), 'image');
|
||||
$settings['login_bg_from'] = trim($_POST['login_bg_from'] ?? '');
|
||||
$settings['login_bg_to'] = trim($_POST['login_bg_to'] ?? '');
|
||||
$overlay = (int)($_POST['login_bg_overlay'] ?? 40);
|
||||
|
|
@ -263,41 +236,6 @@ $cs = [
|
|||
'last_cron_sync' => $db->getSetting('last_cron_sync', ''),
|
||||
];
|
||||
|
||||
/**
|
||||
* Bildfeld: Vorschau, Upload, alternativ URL – plus Entfernen-Schalter.
|
||||
*/
|
||||
function imageField(string $name, string $label, ?string $value, string $hint = '', string $accept = 'image/*'): void
|
||||
{
|
||||
$value = (string)$value;
|
||||
$preview = Ui::mediaUrl($value, '../');
|
||||
?>
|
||||
<div class="form-group">
|
||||
<label><?= htmlspecialchars($label) ?></label>
|
||||
<div class="image-field">
|
||||
<div class="image-preview">
|
||||
<?php if ($preview !== ''): ?>
|
||||
<img src="<?= htmlspecialchars($preview) ?>" alt="">
|
||||
<?php else: ?>
|
||||
<i class="fas fa-image" aria-hidden="true"></i>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="image-field-controls">
|
||||
<input type="file" name="<?= $name ?>_file" accept="<?= htmlspecialchars($accept) ?>">
|
||||
<input type="text" name="<?= $name ?>" value="<?= htmlspecialchars($value) ?>"
|
||||
placeholder="<?= htmlspecialchars(__('settings_image_url_placeholder')) ?>">
|
||||
<?php if ($value !== ''): ?>
|
||||
<label class="chk"><input type="checkbox" name="<?= $name ?>_remove" value="1"> <?= __('settings_image_remove') ?></label>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php if ($hint !== ''): ?><div class="help-text"><?= htmlspecialchars($hint) ?></div><?php endif; ?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
// Aktiver Tab per ?tab=… (Deep-Link, funktioniert auch ohne JavaScript)
|
||||
$activeTab = preg_replace('/[^a-z_]/', '', (string)($_GET['tab'] ?? 'general')) ?: 'general';
|
||||
|
||||
$currentPage = 'settings';
|
||||
$adminBase = '';
|
||||
?>
|
||||
|
|
@ -350,8 +288,8 @@ $adminBase = '';
|
|||
<input type="hidden" name="form_type" value="general">
|
||||
<div class="form-group"><label><?= __('settings_app_title') ?></label><input type="text" name="app_title" value="<?= htmlspecialchars($cs['app_title']) ?>" required></div>
|
||||
<div class="form-grid">
|
||||
<?php imageField('logo_url', __('settings_logo_url'), $cs['logo_url'], __('settings_upload_hint')); ?>
|
||||
<?php imageField('favicon_url', __('settings_favicon_url'), $cs['favicon_url'], __('settings_favicon_hint'), 'image/x-icon,image/png,image/svg+xml'); ?>
|
||||
<?= Ui::imageField('logo_url', __('settings_logo_url'), $cs['logo_url'], __('settings_upload_hint')) ?>
|
||||
<?= Ui::imageField('favicon_url', __('settings_favicon_url'), $cs['favicon_url'], __('settings_favicon_hint'), 'image/x-icon,image/png,image/svg+xml') ?>
|
||||
</div>
|
||||
<hr class="section-divider">
|
||||
<div class="form-group"><label><?= __('settings_instr_header') ?></label><input type="text" name="instruction_header" value="<?= htmlspecialchars($cs['instruction_header']) ?>"></div>
|
||||
|
|
@ -485,7 +423,7 @@ $adminBase = '';
|
|||
<input type="text" name="login_brand_name" value="<?= htmlspecialchars($cs['login_brand_name']) ?>" placeholder="<?= htmlspecialchars($cs['app_title']) ?>">
|
||||
<div class="help-text"><?= __('settings_login_brand_hint') ?></div>
|
||||
</div>
|
||||
<?php imageField('login_logo_url', __('settings_login_logo'), $cs['login_logo_url'], __('settings_login_logo_hint')); ?>
|
||||
<?= Ui::imageField('login_logo_url', __('settings_login_logo'), $cs['login_logo_url'], __('settings_login_logo_hint')) ?>
|
||||
</div>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
|
@ -510,7 +448,7 @@ $adminBase = '';
|
|||
|
||||
<hr class="section-divider">
|
||||
|
||||
<?php imageField('login_bg_image', __('settings_login_bg_image'), $cs['login_bg_image'], __('settings_login_bg_image_hint')); ?>
|
||||
<?= Ui::imageField('login_bg_image', __('settings_login_bg_image'), $cs['login_bg_image'], __('settings_login_bg_image_hint')) ?>
|
||||
<div class="form-grid">
|
||||
<div class="form-group">
|
||||
<label><?= __('settings_login_bg_from') ?></label>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue