Alle Frontend-Assets lokal ausliefern statt über CDNs
Inter, Font Awesome, Chart.js, qrcodejs und TinyMCE liegen jetzt unter assets/vendor/ und werden vom eigenen Server ausgeliefert. Warum: - Datenschutz: bisher ging bei jedem Seitenaufruf die IP der Nutzer an Google Fonts, cdnjs, jsDelivr und Tiny Cloud - Funktion: UniFi-Installationen stehen oft in abgeschotteten Netzen – dort fehlten bisher Schrift, Icons, Diagramme und Editor Neu: includes/Ui.php - Ui::head()/Ui::script() binden die Assets ein und hängen einen Versionsstempel an (?v=filemtime), damit Browser nach einem Update nicht das alte CSS aus dem Cache nehmen - Ui::themeScript() setzt das Theme aus der gespeicherten Auswahl oder – wenn keine vorliegt – aus prefers-color-scheme; global.js folgt Systemwechseln live, solange nichts manuell gewählt wurde - <meta name="color-scheme"> ergänzt, damit Formularelemente passen Der TinyMCE-API-Key entfällt: der Editor läuft immer lokal (GPL-Variante), inklusive deutscher Oberfläche, wenn die App auf Deutsch steht. Neu: tools/demo/build.py – baut aus dem Projekt eine Demo-Instanz ohne Datenbank (Stubs für Database/Auth, feste Beispieldaten). Damit lassen sich Screenshots reproduzierbar erzeugen und alle Seiten einmal rendern (Smoke-Test), ohne eine MySQL-Instanz aufzusetzen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
ba90ffef03
commit
6da46f040a
57 changed files with 1479 additions and 267 deletions
|
|
@ -8,6 +8,7 @@ require_once __DIR__ . '/../includes/Database.php';
|
|||
require_once __DIR__ . '/../includes/Auth.php';
|
||||
require_once __DIR__ . '/../includes/Mailer.php';
|
||||
require_once __DIR__ . '/../includes/I18n.php';
|
||||
require_once __DIR__ . '/../includes/Ui.php';
|
||||
|
||||
$auth = new Auth();
|
||||
$auth->requireAdmin();
|
||||
|
|
@ -113,7 +114,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['save_settings'])) {
|
|||
}
|
||||
|
||||
if ($formType === 'system') {
|
||||
$settings['tinymce_api_key'] = trim($_POST['tinymce_api_key'] ?? '');
|
||||
$settings['print_template'] = $_POST['print_template'] ?? '';
|
||||
}
|
||||
|
||||
|
|
@ -203,7 +203,6 @@ $cs = [
|
|||
'email_voucher_body' => $db->getSetting('email_voucher_body', "Hallo,\n\nIhr Code: {VOUCHER_CODE}\n\nGültigkeit: 8h\nGeräte: {MAX_USES}\nSite: {SITE_NAME}"),
|
||||
'email_user_notification_subject' => $db->getSetting('email_user_notification_subject', '{APP_TITLE} - Berechtigungen geändert'),
|
||||
'email_user_notification_body' => $db->getSetting('email_user_notification_body', "Hallo {USER_NAME},\n\n{CHANGES}"),
|
||||
'tinymce_api_key' => $db->getSetting('tinymce_api_key', ''),
|
||||
'print_template' => $db->getSetting('print_template', '<div style="text-align:center;padding:40px"><h1>{APP_TITLE}</h1><h2>WLAN Code</h2><div style="font-size:48px;font-weight:bold;margin:30px 0;font-family:monospace">{VOUCHER_CODE}</div><p><strong>Gültig bis:</strong> {EXPIRY_DATE} {EXPIRY_TIME}</p><p><strong>Site:</strong> {SITE_NAME}</p><p><strong>Geräte:</strong> {MAX_USES}</p><hr style="margin:30px 0"><div>{INSTRUCTIONS}</div></div>'),
|
||||
'login_panel_enabled' => $db->getSetting('login_panel_enabled', '1'),
|
||||
'login_brand_name' => $db->getSetting('login_brand_name', ''),
|
||||
|
|
@ -230,13 +229,9 @@ $adminBase = '';
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title><?= __('settings_title') ?> - <?= htmlspecialchars($appTitle) ?></title>
|
||||
|
||||
<?php if (!empty($cs['tinymce_api_key'])): ?>
|
||||
<script src="https://cdn.tiny.cloud/1/<?= htmlspecialchars($cs['tinymce_api_key']) ?>/tinymce/6/tinymce.min.js"></script>
|
||||
<?php else: ?>
|
||||
<!-- Ohne API-Key die GPL-Variante von cdnjs laden: gleiche Funktionen, kein Hinweis-Banner. -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/tinymce/6.8.3/tinymce.min.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
<script>window.TINYMCE_BASE_URL = 'https://cdnjs.cloudflare.com/ajax/libs/tinymce/6.8.3';</script>
|
||||
<?php endif; ?>
|
||||
<!-- TinyMCE wird lokal ausgeliefert (GPL-Variante) – keine externen Aufrufe. -->
|
||||
<?= Ui::script('assets/vendor/tinymce/tinymce.min.js', '../') ?>
|
||||
<script>window.TINYMCE_BASE_URL = '../assets/vendor/tinymce';</script>
|
||||
|
||||
<?php include __DIR__ . '/../includes/admin_nav.php'; ?>
|
||||
|
||||
|
|
@ -531,10 +526,10 @@ $adminBase = '';
|
|||
<input type="hidden" name="csrf_token" value="<?= $auth->getCsrfToken() ?>">
|
||||
<input type="hidden" name="form_type" value="system">
|
||||
<div class="info-box">
|
||||
<h4><i class="fas fa-info-circle"></i> TinyMCE API Key</h4>
|
||||
<p>Kostenlosen API Key: <a href="https://www.tiny.cloud/auth/signup/" target="_blank" rel="noopener" style="color:#0066cc;">tiny.cloud/signup</a></p>
|
||||
<h4><i class="fas fa-info-circle"></i> WYSIWYG-Editor</h4>
|
||||
<p>Der Editor (TinyMCE, GPL-Variante) wird lokal aus <code>assets/vendor/</code> geladen – es werden keine externen Dienste aufgerufen.</p>
|
||||
</div>
|
||||
<div class="form-group"><label>TinyMCE API Key</label><input type="text" name="tinymce_api_key" value="<?= htmlspecialchars($cs['tinymce_api_key']) ?>" placeholder="your-api-key-here"><div class="help-text">Für WYSIWYG-Editor in Anleitungen</div></div>
|
||||
|
||||
<hr class="section-divider">
|
||||
<h3 style="margin-bottom:15px; color: var(--text-primary);">Druck-Template</h3>
|
||||
<div class="placeholder-info"><h4>Platzhalter:</h4><div class="placeholder-list"><code>{VOUCHER_CODE}</code><code>{EXPIRY_DATE}</code><code>{EXPIRY_TIME}</code><code>{SITE_NAME}</code><code>{MAX_USES}</code><code>{APP_TITLE}</code><code>{INSTRUCTIONS}</code></div></div>
|
||||
|
|
@ -655,6 +650,10 @@ function initTinyMCE() {
|
|||
tinymce.baseURL = window.TINYMCE_BASE_URL;
|
||||
config.base_url = window.TINYMCE_BASE_URL;
|
||||
config.suffix = '.min';
|
||||
if (document.documentElement.lang === 'de') {
|
||||
config.language = 'de';
|
||||
config.language_url = window.TINYMCE_BASE_URL + '/langs/de.js';
|
||||
}
|
||||
}
|
||||
tinymce.init(config);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue