Release History
coreX
Changelog
Alle Versionen, Neuerungen und Bugfixes von coreX im Überblick.
v0.10.0
Aktuell
08. June 2026
NEU: FormBuilder + Änderungen
Neu
- **System: Einbruchsicherer, dynamischer Formular-Builder (Phasen 1–10)**
- Ein vollständig eigenständiges Subsystem (`Admin → Content → Formulare`), um dynamic Formulare zu verwalten, die anschließend als flexibler CMS-Block verwendet werden können.
- Das System beherrscht 15 essentielle Feldtypen (wie Text, Telefon, whitelisted Select/Checkboxen, Einwilligungen und geschützte Datei-Uploads).
- Sicherheitsoptimiert: Alle hochgeladenen Dokumente landen verschlüsselt außerhalb des Webroots unter `storage/private/form_uploads` und werden im Adminbereich ausschließlich CSRF-tokengesichert (GET-Download Absicherung) über Einweg-Muster herausgestreamt.
- Integriertes, mailboxartiges Postfach zur Prüfung jeder Formulareinsendung mit Bearbeitungsverläufen, Statuswechseln, Leseautomatisierungen und privaten Notizen.
- Performance: AJAX-basiertes Senden im Frontend mit automatischen clientseitigen AbortControl-Anfragentimeouts (15s), um das Einfrieren im Browser bei Netzwerkhängern zu verhindern.
- DSGVO-Zertifiziert: Optionales, vollautomatisches, probabilistisches Housekeeping reinigt das System regelmäßig von abgelaufenen Einsendungen inklusive physischer Bereinigung verknüpfter Dateianhänge anhand des `retention_days` Timers.
- Export: Datenschutzgerechter CSV-Exporteur (geschützt via `admin.forms.export` Berechtigung) mit Byte-Order-Mark (UTF-8 BOM), um Umlautdarstellungen direkt in Microsoft Excel fehlerfrei aufzuschlüsseln.
- Zentral übersetzungsfähig: Nahtlose Einbindung aller Feldlabels und Hilfetexte in das MLS-Übersetzungsboard unter Wahrung aller technischer Regelvalidierungen.
Geändert
- **Rechtliches: Datenschutz-Sicherheitshinweise aktualisiert**
- Die englische Privacy-Policy-Vorlage wurde an die modernen coreX-Subsysteme angepasst.
- Dokumentiert werden nun die integrierte, rein lokale Besucherstatistik (ohne Drittanbieter-Dienste), die strikte Referrer-Domain-Anonymisierung, das flexible Daten-Retention-Management mit automatischem Housekeeping, die modernisierte Zwei-Faktor- bzw. Selektor-Hashed `cx_remember`-Cookie-Logik inklusive aktiver Sitzungsübersicht im Benutzerprofil sowie das mailboxartige Admin-Postfach für Kontaktformularanfragen.
v0.9.9
06. June 2026
NEU: Backup-System + Änderungen + Fixes
Neu
- **System: Datenbank-Backups**
- Der Adminbereich enthält nun eine Backup-Seite für Datenbank-Sicherungen.
- Backup-Umfang, Aufbewahrung und optionale Statistik-/Logdaten können bewusst gesteuert werden.
- Backups können geschützt heruntergeladen, geprüft und mit zusätzlicher Bestätigung wiederhergestellt werden.
- Die Security-Diagnose zeigt nun auch den erkennbaren Backup-Status und Hinweise zur ergänzenden Dateisicherung.
Geändert
- **Kontaktseite: Headline überarbeitet**
- Die Kontaktseite erhält eine stärkere zweizeilige Überschrift mit hervorgehobenem Akzenttext.
Fix
- **Kontaktseite: Headerbild aus Content Manager**
- Das pro Seite gesetzte Header-Hintergrundbild wird auf der Kontaktseite wieder berücksichtigt.
- Bestehende Kontakt-Header-Einstellungen bleiben als Fallback erhalten.
- **Seitenheader: Zentrierung und Hintergrundbilder**
- Blog- und Datenschutz-Header richten ihre Überschrift wieder vertikal sauber aus.
- Datenschutz nutzt nun das im Content Manager gesetzte Headerbild und die konfigurierte Headerhöhe.
v0.9.8
05. June 2026
NEU: Viele Neuheiten + Änderungen + Fixes
Neu
- **System: Security-Diagnose**
- Neuer Adminbereich unter System, der erkennbare Sicherheits- und Umgebungspunkte read-only bewertet.
- Die Diagnose zeigt Status, Kontext und konkrete Empfehlungen, ohne sensible Konfigurationswerte offenzulegen oder automatisch Änderungen vorzunehmen.
- Geprüft werden unter anderem Transport, PHP-/Session-Einstellungen, HTTP-Sicherheitsheader und wichtige Dateisystemgrenzen.
- **After Setup Guide**
- Die Admin-Hilfe enthält nun eine klare Start-Checkliste für neue Installationen.
- Das Dashboard verlinkt den Guide direkt, damit neue Nutzer Konfiguration, Branding, Design, Navigation, Medien und Inhalte in sinnvoller Reihenfolge einrichten können.
- **Design Optionen übersichtlicher**
- Die Design-Optionen sind nun in Reiter für Basisfarben, Bootstrap-Farben, Sektionen, Formularfelder, Mobile und Custom CSS/JS aufgeteilt.
- Die bestehende Speicherlogik bleibt erhalten, die Pflege größerer Designs wird aber deutlich übersichtlicher.
- **Admin-Posteingang überarbeitet**
- Kontaktformular-Nachrichten erscheinen nun in einer mailboxartigen Inbox mit Nachrichtenliste, Vorschau und Detailbereich.
- Beim Öffnen einer Nachricht wird der Lesestatus gespeichert, sodass der Topbar-Zähler nur echte neue Nachrichten anzeigt.
- Die Admin-Hilfe beschreibt den neuen Posteingang und die Lesestatus-Regel.
- **Logo-Seite um Favicon erweitert**
- Unter Logo & Favicon kann nun auch das Browser-Icon der Website hochgeladen und entfernt werden.
- Das Frontend verwendet automatisch das gesetzte Favicon oder fällt auf das bestehende Standard-Icon zurück.
- **Loading-Layer im Admin konfigurierbar**
- Unter Design & Layout gibt es eine eigene Loading-Layer-Seite.
- Ladebild, Bildhöhe und Hintergrundfarbe können unabhängig vom normalen Website-Logo gepflegt werden.
- Das Ladebild kann direkt aus der Mediathek gewählt oder separat hochgeladen werden.
- Ohne eigenes Ladebild verwendet coreX weiterhin das konfigurierte Logo beziehungsweise den bisherigen Fallback.
- **Content-Manager: Header-Höhe pro Seite**
- PHP-Datei-Seiten mit Header-Hintergrundbild können im Content Manager nun eine eigene Header-Höhe erhalten.
- Unterstützt werden feste Höhen und Vollbild, analog zu bestehenden Hero-/Kontakt-Einstellungen.
- Die Einstellung greift für die bestehenden Headerbereiche wie Blog, Newsletter, Profil, Changelog und technische Seiten.
- **Content-Manager: Seitensichtbarkeit nach Zugriffsstufe**
- CMS-Seiten können nun pro Seite festlegen, ob sie öffentlich, nur für angemeldete Benutzer, für Redaktion oder nur für Admins sichtbar sind.
- Geschützte Seiten verschwinden aus der öffentlichen Navigation und werden beim direkten Aufruf gegen die aktuelle Session geprüft.
- Öffentliche Sitemap-Einträge enthalten weiterhin nur frei sichtbare CMS-Seiten.
- **Content-Manager: Profi-Block erweitert**
- Der HTML-Profi-Block bietet nun getrennte CodeMirror-Felder für HTML, CSS und JavaScript.
- Blockbezogener Code wird sauberer einsortiert: Markup im Seiteninhalt, CSS im Seitenkopf und JavaScript am Seitenende.
- Seitennahe Sonderlösungen können dadurch gezielter gepflegt werden, ohne die globalen Design-Optionen für jede Einzelseite zu nutzen.
- **Übersetzungen: Hero-Texte zentraler gepflegt**
- Hero-Texte können nun im Übersetzungsbereich unter Website gepflegt werden.
- Der Hero Editor zeigt den Übersetzungsstatus und verlinkt auf die zentrale Pflege, während Layout, Medien und Design dort bleiben.
- **Übersetzungen: Dashboard ergänzt**
- Der Übersetzungsbereich startet nun mit einer Übersicht pro Sprache und Bereich.
- Filter und Direktlinks helfen dabei, offene Übersetzungen schneller zu finden.
- **Content Manager: Übersetzungen entdoppelt**
- Seitenübersetzungen für Navigation, Slug und SEO werden nun klar zur zentralen Übersetzungsseite geführt.
- Der Content Manager zeigt pro Sprache Status und Direktlinks, bleibt aber der Ort für Basis-/DE-Seitendaten.
- Block-Übersetzungen sind im Content Manager als Schnellzugang markiert; die zentrale Pflege bleibt unter Übersetzungen.
- **News / Blog: Übersetzungen zentraler geführt**
- Das News-Formular bleibt der Ort für DE-Basisbeiträge und zeigt Übersetzungsstatus sowie Direktlinks.
- Beitragsübersetzungen inklusive SEO-Metadaten werden zentral unter Übersetzungen gepflegt.
- Bestehende News-Übersetzungspfade nutzen dieselbe Speicherlogik, damit sich Formular und zentrale Seite nicht auseinanderentwickeln.
- **Übersetzungen: JSON-Systemtexte strukturierter**
- Sprachdateien werden im JSON-Bereich nach Systemmeldungen, JavaScript/UI, Frontend-Content, Layout-Parts und Forum gruppiert.
- Filter und Statusanzeigen zeigen schneller, welche Dateien oder Keys pro Sprache noch fehlen.
- Die Speicherlogik prüft Sprachdateipfade defensiver und schreibt weiterhin nur in den vorgesehenen Sprachbereich.
- **Übersetzungen: Rechtliches sichtbar**
- Der Übersetzungsbereich enthält nun einen read-only Bereich für rechtliche Sprachinhalte.
- Datenschutzstatus und Direktlinks zur Pflege sind pro Sprache sichtbar.
- Rechtlich relevante Texte bleiben bewusst im Datenschutzbereich und werden nicht automatisch mit normalen Übersetzungen vermischt.
- **Übersetzungen: Modul-Sprachdateien sichtbar**
- Der Übersetzungsbereich zeigt Modul-Sprachdateien nun read-only nach Modul und Sprache.
- Fehlende Locale-Dateien werden markiert, ohne automatisch Moduldateien zu erzeugen oder zu verändern.
- Schreibfunktionen für Modul-i18n bleiben bewusst ein späterer Schritt.
- **Übersetzungen: zentrale Pflege abgesichert**
- Die wichtigsten Übersetzungsbereiche folgen nun einer gemeinsamen Status- und Speicherlogik.
- Eine automatisierte Policy-Prüfung schützt die zentrale Übersetzungsführung vor unbeabsichtigten Rückschritten.
- **Übersetzungen: coreY-Abdeckung erweitert**
- coreY kann im zentralen Übersetzungsbereich nun auch Footer-Labels für Spalten- und Flat-Footer unterstützen.
- **Footer-Manager: Externe Links**
- Footer-Links können nun neben internen Pfaden auch externe Web-, Mail- und Telefonziele sauber speichern.
- Interne und externe Ziele werden im Frontend korrekt ausgegeben; neue Tabs erhalten passende Schutzattribute.
- **Statistik: aggregierte Langzeitauswertungen**
- Historische Statistiken (Besucher, Seiten, Referrer, Browser/OS/Gerät, Performance) werden jetzt als verdichtete Tageswerte gespeichert, statt dauerhaft Rohdaten vorzuhalten.
- Langzeit-Auswertungen im Admin sind dadurch deutlich schneller und ressourcenschonender.
- **Statistik: manuelle Datenbank-Verwaltung im Adminbereich**
- Admin → Statistik bietet jetzt Buttons zum sofortigen Aggregieren und Bereinigen mit Feedback über verarbeitete Datensätze.
- **Performance-Tracking: Aufzeichnungsrate konfigurierbar**
- Die Rate, mit der Performance-Messwerte erfasst werden, lässt sich im Admin einstellen — von jedem Request bis hin zu stichprobenartigem Sampling.
- **Statistik-Datenhaltung im Admin einstellbar**
- Aufbewahrungsfristen für Besucher-, Bot-, Performance- und Web-Vitals-Rohdaten sowie die Performance-Sampling-Rate können direkt in der Statistik gepflegt werden.
- **Automatisches Housekeeping für Sicherheits- und Sitzungsdaten**
- Abgelaufene Anmeldeversuchs-Einträge und inaktive Sitzungen werden jetzt automatisch im Hintergrund bereinigt, ohne dass ein Cron-Job nötig ist.
- **Retention: Web-Vitals-Messwerte**
- Web-Vitals-Stichproben erhalten eine eigene konfigurierbare Aufbewahrungsfrist und werden automatisch bereinigt.
Geändert
- Die designbezogenen Card-Styles und globalen Table-Styles liegen nun einheitlicher im `corex/parts`-Bereich.
- Hintergrund-Cleanup für Rohdaten läuft häufiger, um Datenbankwachstum proaktiver zu begrenzen.
- Retention-Hinweis in Admin → Statistik nennt jetzt alle konfigurierbaren Aufbewahrungsfristen.
- Performance-Auswertungen im Dashboard beziehen sich jetzt auf ein klar definiertes Zeitfenster und sind weniger anfällig für Verzerrungen durch ältere Ausreißer.
- Statistik-Reset, Langzeitaggregate und Rohdaten-Cleanup arbeiten konsistenter zusammen, damit historische Werte nicht versehentlich vor der Verdichtung verloren gehen.
- Performance-Sampling wird im Dashboard und in der Statistik klarer als Stichprobe ausgewiesen.
Fix
- **Mediathek-Auswahl: WebP-Dateinamen konsistenter**
- Media-Picker und Header-Bildfelder zeigen bei automatisch konvertierten Bildern bevorzugt den tatsächlich gespeicherten WebP-Dateinamen.
- **Forum: Topbar und Fixed-Navigation berücksichtigt**
- Forum-Seiten laden nun ebenfalls die Frontend-Topbar.
- Der Forum-Inhalt erhält einen zentralen Abstand, damit Topbar und fixe Navigation den Seitenkopf nicht überdecken.
- **Kontaktformular: Rückmeldung nach Submit repariert**
- Erfolgs- und Fehlermeldungen nach Kontaktformular-Submit werden wieder korrekt gerendert.
- Captcha-Fehler führen dadurch wieder zur normalen Formularmeldung statt zu einem Seitenabbruch.
- **Content Manager: Quill-CDN korrigiert**
- Der gemeinsame Quill-Editor lädt Version 1.3.7 nun über die stabile jsDelivr-URL.
- SRI- und CORS-Attribute bleiben erhalten, sodass der Block-Editor wieder ohne CDN-Redirect-/Hashfehler startet.
- **Content Manager: Admin-Fetch-Basis robuster**
- Die gemeinsame Fetch-Vorbereitung wird im Admin nun ohne zusätzlichen Asset-Request geladen.
- Dadurch bleibt der Block-Editor auch auf sprachpräfigierten Admin-URLs stabil.
- **Konfiguration: OAuth-Speichern klarer getrennt**
- Das Speichern von Social-Login-Daten verändert keine allgemeinen Website-/coreY-Beschreibungsfelder mehr.
- **Cookie-Einstellungen: Fallback-Hinweis**
- Wenn ein Browser-Add-on die Cookie-Einstellungen blockiert, zeigt der Footer-Link nun einen verständlichen Hinweis statt still wirkungslos zu bleiben.
- Veraltete, nicht mehr genutzte Datenbankspalte und Legacy-Tabellen ohne aktive Verwendung wurden bereinigt.
- Referrer in der Besucherstatistik werden datensparsamer als Domain gespeichert, statt vollständige Pfade oder Query-Parameter dauerhaft abzulegen.
v0.9.7
01. June 2026
Änderungen
Geändert
- **Medienverarbeitung robuster gemacht**
- Upload-, Medien- und Bildableitungspfade pruefen Dateien jetzt frueher und einheitlicher, bevor weitere Verarbeitung startet.
- Ungueltige oder ungewoehnlich grosse Medien werden klarer abgelehnt, statt Admin-Aktionen unnoetig zu belasten.
- Die Mediathek zeigt Upload-Grenzen und relevante Serverfaehigkeiten nun transparenter im Adminbereich an.
- Eine automatisierte Regression prueft die wichtigsten Medienregeln in Composer und CI.
- **Redirect-Verhalten stabilisiert**
- Inhaltsredirects greifen nur noch bei normalen Seitenaufrufen; Formular- und API-Anfragen erreichen verlaesslich ihre eigentlichen Endpunkte.
- Der Redirect-Manager erklaert die neue Regel im Adminbereich und schuetzt technische Systempfade vor versehentlichen Regeln.
- Eine automatisierte Regression prueft die Redirect-Regeln in Composer und CI.
- **Externe Frontend- und Admin-Ressourcen klarer abgesichert**
- Aktive externe Bibliotheken werden konsequenter mit festen Versionen, Integritaetspruefung und CORS-Attributen eingebunden.
- Die Frontend-CSP bleibt bei eigenen Scripts nonce-basiert; der Admin-Zwischenstand und der weitere Abbau alter Inline-Muster sind dokumentiert.
- Custom JavaScript ist in den Design-Optionen deutlicher als bewusst vertrauenswuerdiger Frontend-Code gekennzeichnet.
- Eine automatisierte Regression prueft die wichtigsten CSP-/SRI-Regeln in Composer und CI.
- **Statistik-Datenhaltung transparenter gemacht**
- Besucher-, Bot- und Performance-Rohdaten haben nun zentrale Aufbewahrungsfristen und werden fehlertolerant bereinigt.
- Der Adminbereich zeigt klarer, auf welchen Datenzeitraum sich Statistik- und Performanceanzeigen beziehen.
- Tracking-Grenzen fuer technische Requests und Adminbereiche wurden geschaerft; IP-Anzeigen werden konsistenter anonymisiert.
- Eine automatisierte Regression prueft die wichtigsten Tracking-/Retention-Regeln in Composer und CI.
- **Modul-Paketpreview aussagekraeftiger gemacht**
- Die Paketpruefung zeigt vor Installation oder Update kompakt, welche technischen Erweiterungen ein Modul mitbringt.
- Herkunftspruefung, Dev-/Recovery-Hinweise und technische Wirkung werden klarer getrennt dargestellt.
- Unverifizierte Pakete mit umfangreicher Wirkung brauchen eine bewusstere Bestaetigung; Audit-Eintraege bleiben abstrakt und ohne Paketdetails.
- Eine automatisierte Regression prueft die wichtigsten Preview-Regeln in Composer und CI.
- **Architektur-Hotspots entschärft**
- Wiederverwendete Layout- und Admin-Views beziehen kleine Datenpunkte nun konsequenter ueber Services, Manager oder ViewModels.
- Frontcontroller-, Routing- und Admin-JavaScript-Folgepfade sind klarer dokumentiert, damit spaetere Umbauten gezielter und testbarer bleiben.
- Eine automatisierte Regression schuetzt die neuen Architekturgrenzen in Composer und CI.
- **Automatisches Testnetz ausgebaut**
- Stabile Sicherheits- und Architekturpruefungen sind in Composer-Testgruppen zusammengefasst.
- Die CI fuehrt Validierung, Lint, Policy-Tests und isolierte Smokes aus, ohne produktive Dienste oder echte Datenbanken zu benoetigen.
- Manuelle und release-nahe Pruefungen sind klar von automatischen Tests getrennt dokumentiert.
v0.9.6
30. May 2026
NEU: Sichere Paket-Verarbeitung + Änderungen + Fixes
Neu
- **Asset-Versionierung vorbereitet**
- Neuer zentraler `AssetVersionService` plus globaler `cx_asset()`-Helper erzeugen versionierte interne Asset-URLs mit `filemtime()` und korrektem `APP_BASE`.
- Bestehende Query-Strings bleiben erhalten; externe URLs und Sonder-URLs werden nicht veraendert.
- Frontend-/Admin-Layoutassets, Loading-Logo und Modul-Assets nutzen die zentrale Versionierung; generierte Part-CSS behalten `css_parts_version` als fachliche Version.
- Generierte Part-CSS-Versionen werden monoton gebumpt; Button-Palette-Dateien erhalten zusaetzlich einen Zufallsanteil im Dateinamen, damit schnelle Mehrfach-Saves keine Cache-URL wiederverwenden.
- `.htaccess` setzt explizite Langzeit-Cache-Control-Header fuer statische Assets; dynamische Design-CSS/JS-PHP-Endpunkte revalidieren statt blind langfristig zu cachen.
- Neuer Regressionstest `.tests/asset-versioning-policy-test.php` ist als `composer test:fund10` in Composer und CI angebunden.
- **Sichere Paket-Verarbeitung — Staging und Rollback**
- Core-Update-ZIPs werden in einem isolierten Staging-Bereich außerhalb des Webroots entpackt; erst nach vollständiger Validierung werden Dateien in den Zielbaum übernommen.
- Bei Fehlern während des Deployments stellt ein automatischer Rollback den vorherigen Zustand wieder her. Ein Snapshot des Originalzustands bleibt für manuelle Inspektion erhalten.
- ZIP-Validierung erkennt Symlinks, Path-Traversal-Versuche und ungültige Einträge.
- **Modul-Upload-Pfad gehärtet**
- Temporäre Dateien bei Modul-Uploads werden in einem Verzeichnis außerhalb des Webroots abgelegt — unabhängig von der Webserver-Konfiguration nie per HTTP erreichbar.
- Temporäre Verzeichnisse werden nach Installation oder Fehler zuverlässig bereinigt.
- **ManifestVersion-Konsistenz sichergestellt**
- Die Manifest-Versionsnummer wird nach jedem Generierungsvorgang korrekt persistiert; monotones Wachstum ist damit garantiert.
- **Admin-UI: Manifest-Status**
- Die Manifest-Verwaltungsseite zeigt Versionsnummer und Schlüssel-ID des aktuellen Manifests.
- **Ed25519-signiertes Paket-Manifest**
- Alle offiziellen Pakete werden über ein kryptographisch signiertes Manifest autorisiert.
- Sowohl Core-Updates als auch Module durchlaufen dieselbe Verifikationskette — keine getrennte Signaturlogik.
- Der private Signierungsschlüssel ist nicht Teil der Webserver-Distribution und muss offline gehalten werden.
- **Admin-UI: Manifest generieren** (`/admin/updates/manifest`)
- Statusübersicht (Schlüssel, Manifest-Datum, Paket-Anzahl) und Signierungsvorgang per Formular; zugänglich nur für autorisierte Nutzer.
- **Strikter Paketpfad für Module**
- Module werden im normalen Installationspfad nur akzeptiert, wenn ihr SHA-256-Hash im gültig signierten Manifest registriert ist.
- Ein separat berechtigter Sonderweg ermöglicht bei Bedarf eine Recovery-Installation. Solche Installationen werden im Audit-Log sichtbar markiert.
- **Replay- und Downgrade-Schutz**
- Bereits akzeptierte Manifest-Versionen werden lokal vermerkt; ältere signierte Manifeste werden als Replay erkannt und abgelehnt.
- Core- und Modul-Downgrades werden im normalen Pfad blockiert.
- **Key-Ring für Manifest-Verifikation**
- Manifeste enthalten eine Key-ID; der Verifizierer unterstützt aktive, veraltete und widerrufene Schlüssel. Widerrufene oder unbekannte Key-IDs werden abgelehnt. Spätere Key-Rotation ist vorbereitet.
Geändert
- **Update-Verteilung gehärtet**
- Paket-Manifeste werden als signierte Artefakte öffentlich verteilt; ZIPs legitimieren sich nur über Hashvergleich gegen das gültig signierte Manifest.
Fix
- **Module-Installer**: Paket-Preview zeigte fälschlicherweise beide Buttons (Installieren + Aktualisieren) wenn Modul bereits installiert war — korrigiert.
v0.9.5
28. May 2026
Änderung: Sicherheitshärtung
Geändert
- **Sicherheitshärtung** — Interner Sicherheits-Audit abgeschlossen; mehrere präventive Verbesserungen in Authentifizierung, Verschlüsselung und Input-Validierung umgesetzt.
v0.9.4
28. May 2026
Änderung Migrationspfad
Geändert
- **Einheitlicher Migrationspfad**
- Es existiert genau ein Migrationsdienst und eine Migrations-History-Tabelle; Legacy-Einträge werden automatisch importiert.
- Der Migrationsdienst ist nun isoliert testbar ohne echte Datenbankverbindung.
v0.9.3
27. May 2026
NEU: Profil-Panel + Änderungen
Neu
- **Profil-Panel "Aktive Anmeldungen"**
- Das Nutzerprofil zeigt alle aktiven Remember-Me-Sitzungen inkl. Gerät/User-Agent, Anmeldedatum und Ablaufdatum.
- Die aktuelle Sitzung wird mit einem "Dieses Gerät"-Badge hervorgehoben.
- "Alle anderen Geräte abmelden" beendet alle anderen Sitzungen mit einem Klick. Vollständig übersetzt (DE/EN).
- **Remember-Me-Token gehärtet**
- Tokens werden in einer eigenen Datenbanktabelle mit Selektor-/Hash-Trennung gespeichert statt als einzelner Wert im Nutzerdatensatz.
- Bei jedem Auto-Login rotiert der Token; der alte Cookie-Wert wird sofort ungültig.
- **Logout bereinigt alle Sitzungen**
- Beim Logout werden alle aktiven Remember-Me-Tokens des Nutzers entfernt.
Geändert
- **`cx_remember`-Cookie-Attribute**
- SameSite=Lax, HttpOnly und Secure (bei HTTPS) werden nun korrekt gesetzt.
- **Effizienter Token-Lookup**
- Tokens werden direkt per Datenbankindex gesucht; abgelaufene Tokens werden opportunistisch bereinigt.
v0.9.2
26. May 2026
NEU: CSRF-Regressionstest + Änderungen + Fixes
Neu
- **CSRF-Regressionstest für Admin-Mutationen**
- Automatisierte Regressionstests prüfen gehärtete Admin-Schreibaktionen mit fehlendem und ungültigem Token.
- Ergänzende manuelle Testmatrix dokumentiert reversible Save-Prüfungen mit gültigem Admin-Token.
- **HTML/CSS-Profi-Block mit klarer JavaScript-Grenze**
- `raw_html` bleibt als flexibler Block für HTML, Bootstrap-Klassen, Inline-Styles und `<style>`-Blöcke erhalten.
- Der Editor kennzeichnet ihn als **HTML/CSS (Profi)** und zeigt bei JavaScript-Eingaben eine direkte Warnung mit Verweis auf den zentralen Custom-JS-Bereich.
- Automatisierte Policy-Tests decken erlaubte HTML-/CSS-Inhalte, verbotene JavaScript-Vektoren und Altinhalt-Rendering ab.
- **Sichere Verwaltung externer Dienstzugänge**
- OAuth-, PSI- und coreY-Zugangsdaten werden über eine gemeinsame Secret-Verwaltung gepflegt.
- Ein geführter Admin-Flow unterstützt die sichere Umstellung bereits hinterlegter Dienstzugänge.
- Automatisierte Policy-Tests prüfen Verschlüsselung, Admin-Maskierung, Migration und Fehlerfälle.
- **Bewusste OAuth-Kontoverknüpfung**
- Neue OAuth-Zuordnung trennt bestehende Provider-Logins, neue OAuth-Registrierungen und bewusstes Verbinden aus dem eingeloggten Profil.
- Das Profil zeigt verbundene Google-/Facebook-Anmeldewege und bietet sichere Verbinden-/Trennen-Aktionen.
- ergänzt Metadaten für Entstehungsweg und letzte Nutzung.
- Automatisierte Policy-Tests prüfen Provider-Vertrauen, Profil-Linking, Konfliktfälle und Metadaten.
Geändert
- **Zentrale Absicherung mutierender Admin-Routen**
- `Router::dispatch()` erzwingt für `POST`, `PUT`, `PATCH` und `DELETE` unter `admin/*` einen gültigen CSRF-Token vor Ausführung des Handlers.
- Bestehende route- und controllerseitige Prüfungen bleiben als zusätzliche Absicherung erhalten.
- Permission-Prüfungen für alle Admin-Bereiche vervollständigt.
- **Custom Code klar getrennt**
- Eigener JavaScript-Code wird weiterhin zentral unter *Design Optionen -> Custom JavaScript* gepflegt; die Admin-UI erläutert diese Trennung zum Content-Block.
- Abgelehnte JavaScript-Speicherversuche aus Profi-Blöcken und deren Übersetzungen werden ohne Speicherung des eingegebenen Codes im Audit-Log vermerkt.
- **Dienstzugänge zentral und maskiert gepflegt**
- Gespeicherte externe Zugangsdaten werden in den Admin-Ansichten nicht offengelegt und können gezielt ersetzt oder entfernt werden.
- Änderungen und sichere Umstellungen sind im Audit-Log nachvollziehbar, ohne vertrauliche Inhalte auszugeben.
- **OAuth-Login-Logik gekapselt**
- `OAuthProviderProfile` normalisiert Providerdaten inklusive Vertrauensstatus der E-Mail.
- `OAuthAccountService` entscheidet zentral über bestehende Links, neue Konten, Profil-Verknüpfungen und Konflikte.
- OAuth-Aktionen werden im Audit-Log nachvollziehbar, aber ohne Tokens, Secrets, Provider-IDs oder unnötige Profildaten protokolliert.
- **Profilseite als dynamischer Kontobereich**
- `PageRenderer` bereitet den Profil-Kontext zentral vor, egal ob `/profile` als Spezialseite oder als CMS-`php_file` gerendert wird.
- Profilansicht, OAuth-Verknüpfungen und aktive Sitzungen erhalten dadurch denselben vorbereiteten User-Kontext.
Fix
- **CSRF-Absicherung aller Admin-Schreibaktionen vereinheitlicht**
- Alle mutativen Admin-Aktionen (Einstellungen, Content, Konfiguration, Migrationen) erzwingen einen gültigen CSRF-Token.
- Newsletter-Verwaltung und Kontaktanfragen-Status nutzen CSRF-gesicherte POST-Requests.
- **`raw_html`-Block auf HTML/CSS beschränkt**
- Der Profi-Block akzeptiert nur noch reines HTML und CSS; unerlaubte Inhalte werden serverseitig abgelehnt und bestehende Inhalte defensiv bereinigt.
- **Profilseite zeigt Userdaten wieder zuverlässig**
- Bei als CMS-`php_file` eingebundener Profilseite werden Avatar, Benutzername, E-Mail und Rollenstatus wieder aus dem vorbereiteten Profil-Kontext statt aus leeren View-Defaults gerendert.
v0.9.1
25. May 2026
NEU: Mobile First Einstellungen + Fixes + Änderungen
Neu
- **Mobile Hintergrundbilder für CMS-Blöcke (Phase 1)**
- Alle 5 Block-Typen mit Hintergrundbild-Unterstützung (hero, text, two_col, cards, cta) haben jetzt ein optionales Feld **Mobil-HG (9:16)**.
- Im Admin-Block-Editor (`block-forms.js`) erscheint unter dem Desktop-BG jeweils ein zweiter Mediathek-Slot „Mobil-HG · 9:16 · optional · <768px" mit URL-Input, Mediathek-Button und Clear-Button.
- Im Frontend wird bei gesetztem `mobile_bg_image` ein inline `<style nonce>` mit `@media (max-width: 767px)` ausgegeben, das das Desktop-Hintergrundbild überschreibt — kein JS, kein DB-Schema-Change nötig (Block-JSON).
- `ContentController::extractBlockData()` persistiert `mobile_bg_image` für alle 5 Block-Typen.
- **Mobile Hintergrundbilder für News-Detailseite und Homepage-Hero (Phase 1b)**
- **News/Blog-Post**: Neues DB-Feld `cms_news.mobile_hero_image` (Migration `2026_05_27_000057_news_mobile_hero_image.sql`). Im Admin-Formular erscheint unter dem Desktop-Hero ein Mobil-HG-Picker. `views/content/blog-post.php` gibt bei gesetztem Wert ein `@media (max-width: 767px)`-Override für `.cx-bpost-header-pb` aus.
- **Homepage-Hero**: Pro Hero-Slot kann unter dem Desktop-Hintergrundbild ein **Mobil-HG** hinterlegt werden (`hero{1|2|3}_mobile_bg_src` in `site_settings`). `HeroSettingsService` speichert den Wert, `views/parts/hero.php` gibt das `@media`-Override-CSS für alle 3 Layout-Varianten (Cinematic, Split, Centered) aus. Im Admin (`views/admin/hero.php`) gibt es je Slot einen neuen Mediathek-Slot für das Mobilbild.
- **Mobile / Responsive Settings (Phase 2)**
- Neuer Admin-Abschnitt in *Design-Optionen* mit 4 Slidern + 2 Toggles: Hero-Höhe Mobile (vh), Section-Padding Mobile (px), H1-Schriftgröße Mobile (px), H2-Schriftgröße Mobile (px), CTA-Buttons volle Breite, Topbar ausblenden.
- `DesignSettingsService::MOBILE_KEYS` — typisiertes Konstanten-Array mit Validierungsregeln (int/bool, min/max).
- `saveDesignOptions()` persistiert alle 6 Mobile-Keys via `DesignSettingsRepository::upsert()` in `design_settings`.
- Migration `2026_05_27_000058_mobile_settings.sql` — INSERT IGNORE der 6 Default-Werte in `design_settings`.
- **Generiertes Mobile CSS (Phase 3)**
- Neuer `MobileCssGenerator` nach `CssPartInterface` erzeugt `public/assets/css/corex/parts/mobile.css` aus den Einstellungen des aktiven Designs.
- Das generierte Stylesheet setzt mobile Hero-Höhen, Section-Abstände und fluid begrenzte H1/H2-Größen; CTA-Fullwidth und das Ausblenden der Topbar inklusive Reset des Fixed-Topbar-Navbar-Abstands werden optional zugeschaltet.
- `DesignSettingsService::saveDesignOptions()` regeneriert die Datei beim Speichern; `views/parts/header.php` lädt sie global mit dem bestehenden `css_parts_version` Cache-Busting.
- **Mobile Polish & Performance (Phase 4, ohne PSI)**
- Hero-LCP: echte Hero-Bilder werden priorisiert geladen; für Homepage- und News-Heros kann der Head nun getrennte Desktop-/Mobile-Preloads per Media Query ausgeben.
- `ResponsiveImageService` erzeugt für Mediathek-Bilder WebP-Varianten mit 640 px und 1200 px Breite unter `assets/img/uploads/responsive/`; neue Uploads und Paste-Bilder werden sofort verarbeitet, der Mediathek-Scan rüstet Bestandsbilder nach.
- Blog-, Blogpost-, CMS-Text- und Two-Col-Bilder nutzen `<picture>`/`srcset`, sobald Varianten vorhanden sind; die Lightbox öffnet dabei die tatsächlich aktive Bildquelle.
- Die Design-Optionen besitzen eine 390-px-Mobile-Vorschau der gespeicherten Startseite, und der Block-Editor warnt live bei Desktop-Hintergrund ohne mobiles Ersatzbild.
- Mobile Hintergrundbilder verdrängen auf kleinen Viewports nun auch gesetzte Hero-/Text-Hintergrundvideos korrekt.
- **News/Blog — SEO-Metas mehrsprachig**
- News-Formular zeigt bei bestehenden Beiträgen wie der Content Manager einen Sprach-Tab für Non-DE Locales.
- Pro Sprache können Blog-Titel, Blog-Slug, Meta-Titel, Meta-Description und Meta-Keywords direkt am Beitrag gepflegt werden.
- Neue Route `/admin/news/i18n/{id}` speichert News-Meta-Übersetzungen mit CSRF und `admin.news.edit`.
- Migration `2026_05_23_000056_news_i18n_meta_fields.sql`: ergänzt `cms_news_i18n.meta_title`, `meta_description` und `meta_keywords`.
- **Zentrale Mobile Einstellungen (Phase 5–6)**
- Die bestehende Seite `/admin/mobile-nav` wurde zur zentralen Seite **Mobile Einstellungen** ausgebaut; die Mobile-Regler aus den allgemeinen Design-Optionen werden dort gebündelt verwaltet.
- Ergänzte Design-Werte: Mobile-Fließtextgröße, Zeilenhöhe, Container-Gutter, Hero-Textausrichtung und bewusste Ausnahme für dekorative Videos mit vorhandenem Mobilbild-Fallback.
- `MobileSettingsService` trennt weiterhin navigationsbezogene `site_settings` von designbezogenen `mobile_*`-Werten und synchronisiert die generierte `mobile.css`.
- Migration `2026_05_27_000059_extended_mobile_settings.sql` legt die erweiterten Mobile-Design-Defaults an.
- **Core Mobile Baseline & Content-Robustheit (Phase 5 und 7)**
- Vollflächige Mobile-Heros verwenden robuste `vh`-/`svh`-/`dvh`-Höhen, Safe-Area-Abstände und mindestens 44 px große zentrale Touchflächen.
- Die mobile Navigation unterstützt sichtbaren Tastaturfokus, Escape-Schließen, Fokus-Rückgabe und saubere ARIA-Zustände.
- `prefers-reduced-motion` reduziert nicht notwendige Animationen; Slider-Autoplay, Parallax und dekorative Videos werden bei reduzierter Bewegung entschärft.
- Parallax wird auf kleinen Displays standardmäßig deaktiviert; CMS-Tabellen, Embeds, lange Links und Medien-Platzhalter sind auf schmalen Viewports robuster.
- Der Block-Editor warnt zusätzlich bei Hintergrundvideos ohne geeignetes mobiles Fallback-Bild.
- **Responsive Vorschau & Mobile Release-Check (Phase 8)**
- Die Admin-Vorschau unterstützt die Viewport-Presets `320`, `360`, `390`, `430` und `768 px` sowie Hoch- und Querformat.
- Als Vorschauziel können Startseite, veröffentlichte CMS-Seiten und News-Detailseiten gewählt werden.
- Die Vorschau weist auf fehlende Mobilbilder, Videos ohne Fallback und horizontalen Overflow hin; ein manueller Mobile-Release-Check ist direkt in den Einstellungen dokumentiert.
- **Konfigurierbarer Umschaltpunkt für mobile Hintergrundbilder**
- Die Mobile Einstellungen bieten eine Bootstrap-Breakpoint-Auswahl bis `xl` (`max-width: 1199.98px`) für alternative mobile Hintergrundbilder.
- Home-Hero, CMS-Block-Hintergründe, News-Hero-Quellen, Preloads und dekorative Video-Fallbacks verwenden denselben contentweiten Wert `mobile_bg_breakpoint`.
- Migration `2026_05_27_000060_mobile_background_breakpoint.sql` ergänzt den neuen `site_settings`-Default.
- **Mobile Navigation — Link- und Button-Darstellung**
- In den Mobile Einstellungen kann für Navigationslinks zwischen **Buttons / Kacheln** und **Nur Linktext** gewählt werden.
- Für den Buttonmodus können Hintergrundfarbe, Rahmenfarbe und Eckenradius gesetzt werden; Link-, Hover- und Akzentfarben bleiben zentral editierbar.
- Im Textmodus nutzt die Hover-Akzentfarbe einen Text-Glow, ohne Hintergrund oder Rahmen einzublenden.
- Migration `2026_05_27_000061_mobile_nav_link_style.sql` ergänzt die neuen Darstellungs-Defaults.
Geändert
- **CMS-Block-Styles**
- Eingebaute CMS-Block-Sections tragen nun stabile `data-cx-block="<typ>"`-Attribute, damit globale und blocktypbezogene Frontend-Styles gezielt aufgebaut werden können.
- **Mobile CSS-Pipeline**
- `mobile.css` wird beim Öffnen und Speichern der zentralen Mobile Einstellungen sowie beim Aktivieren eines anderen Designs aus den persistierten Werten neu erzeugt.
- Einstellbare Mobile-Werte werden exakt ausgegeben; H1/H2 erhalten keine zusätzliche verdeckte `clamp()`-Verkleinerung.
- Schreibfehler beim Erzeugen der CSS-Datei werden im Admin sichtbar gemeldet, statt einen erfolgreichen Save vorzutäuschen.
Fix
- **Hero-Höhe im Frontend**
- Die Einstellung `/admin/hero` für `Vollbild (100 vh)` wird für alle Homepage-Hero-Layouts explizit ausgegeben und nutzt `svh`/`dvh`-Unterstützung, statt von zufälligen Layout-CSS-Höhen abhängig zu sein.
- Bei Split-Hero Layout 2 neutralisiert Mobile-CSS eine feste Desktop-Höhe, sodass die separate Mobile-Hero-Höhe tatsächlich Vorrang erhält.
- **Mobile Navigation — gespeicherte Farben**
- Link- und Hover-Farben der mobilen Sidebar werden über spezifische `#mobile-nav`-Regeln ausgegeben und nicht mehr durch allgemeine Linkfarben der Design-Dynamic-CSS überstimmt.
v0.9.0
21. May 2026
NEU: Mediathek 2.0 & coreZ & Quill Image Resize + Fixes + Änderungen
Neu
- **Mediathek 2.0 — Ordner-Workflow**
- Media-Grid um ein zweispaltiges Layout erweitert; rechts erscheint eine Ordner-Sidebar nach Ordner-Zugehörigkeit.
- Ordner werden als ca. 120x120px große Kacheln mit Name, Datei-Anzahl und Gesamtgröße angezeigt.
- Filterbutton „Nicht zugeordnete Bilder“ zwischen „Alle“ und „Bilder“ ergänzt; zeigt nur Bilder ohne Ordner-Zuordnung.
- Bild-Karten sind nun per Drag & Drop auf Ordner-Kacheln verschiebbar; Videos bleiben nicht ziehbar.
- Ordner-Kacheln filtern per Klick die Mediathek und zeigen beim Drag-over visuelles Drop-Feedback.
- Die Drag-&-Drop-Zuweisung nutzt den bestehenden AJAX-Endpunkt `/admin/media/meta` mit CSRF-Token und vorhandener Permission-Prüfung.
- Ordner können direkt in der Sidebar erstellt und per Stift-Icon inline umbenannt werden.
- Bulk-Aufräumen: Mehrfachauswahl im Media-Grid mit Toolbar-Dropdown und Ordner-Zuweisung per Sidebar-Klick oder „Zuweisen"-Button.
- Neue Admin-Route `/admin/media/bulk-assign-folder` für Bulk-Zuweisungen mit CSRF-Token und `admin.media.upload`.
- Komfortfunktionen: URL-Copy-Button direkt auf Media-Karten, Sortierung nach Name/Bildgröße/Dateigröße/Datum und umschaltbare Grid-Größen.
- Bilder ohne Alt-Text zeigen in der Mediathek ein `ALT`-Badge als schnellen SEO-/Accessibility-Hinweis.
- `MediaUsageService`: Nutzungsnachweis für Media-Dateien in CMS-Seiten, Blöcken, Übersetzungen, News und Settings.
- Detail-Modal zeigt „Verwendet in“ mit Quelle, Feld und Link zum passenden Admin-Bereich.
- Neue Admin-Route `/admin/media/usage` für den Nutzungsnachweis mit `admin.media.view`.
- Neues Datenbankfeld für Hash-basierte Duplikat-Hinweise bei Uploads und Sync-Importen.
- Neue Tabelle für persistente leere Ordner; vorhandene Ordner-Zuordnungen werden übernommen.
- **Design & Layout — Allgemein**
- Neue Admin-Seite `/admin/design-general` unter „Design & Layout“ für globale Body-Typografie und den Bildscrollen-Schalter.
- Defaults pro Design für `body_font_family`, `body_font_size`, `body_line_height`, `body_font_weight` und `parallax_scroll_enabled`.
- **Übersetzungen — Footer Links**
- Neuer Tab „Footer Links“ unter `/admin/translations` zur Pflege von `footer_links_i18n` und `footer_flat_links_i18n`.
- Neue Route `/admin/translations/footer-links/save` speichert Label- und URL-Übersetzungen pro Sprache mit CSRF und `admin.mls.edit`.
- **Admin-Hilfe**
- Neue statische Hilfeseite `/admin/help` mit Suche, Sticky-Themenliste und Abschnitten zu Content, Quill, Mediathek, MLS, Design, SEO, System und Tastenkürzeln.
- Sidebar-Link „Hilfe“ vor Logout ergänzt.
- **coreZ — Modulkonzept**
- Neues Architekturpapier `coreX-coreZ.md` für ein installierbares Modul-Andocksystem inklusive Manifest, Registry, Installer, Rechte, CSRF, CSP, Assets, Routen und Pilotmodul-Vorschlag.
- Offene Architekturfragen zu Composer-Abhängigkeiten, Paketierung, coreZ-Modulzentrale, Marketplace und Core-Hooks mit Entscheidungen/Erklärungen ergänzt.
- Umsetzungsplan auf coreZ-Modulmanager mit Paketprüfung, getrennten coreX/coreZ-Updates, Content-Targets sowie direkten SEO-/Media-/Dashboard-Hooks angepasst.
- Phase 0 abgeschlossen: `modules/` als offizielles Modulverzeichnis angelegt, Manifest-v1 konkretisiert und Registry-/Permission-/Paketprüfungs-Grundlagen festgehalten.
- Phase 1 abgeschlossen: `ModuleManager` und `ModuleEvents` als Registry-/Hook-Basis eingeführt, Modul-Manifeste werden gescannt/validiert und aktivierte Module können Autoload, Admin-/Frontend-Routen, Content-Targets, Assets sowie SEO-/Media-/Dashboard-Hooks bereitstellen.
- ergänzt `corex_modules`, `corex_module_migrations` sowie die Permissions `admin.modules.view` und `admin.modules.manage`.
- Phase 2 abgeschlossen: Neue Admin-Seite `/admin/modules` mit Registry-Status, System-Sidebar-Eintrag, ZIP-Uploadbereich, temporärer Paketentpackung, `module.json`-Validierung und SHA-256-Paketprüfung.
- `ModulePackageInspector` vorbereitet RAR bewusst nur als späteres Format; echte Installation/Aktivierung/Updates bleiben getrennt für Phase 3.
- Phase 3 abgeschlossen: `ModuleInstaller` installiert lokale Module und geprüfte ZIP-Pakete, registriert Modul-Permissions, führt Modul-Migrationen aus, trackt diese in `corex_module_migrations` und schreibt den Aktivstatus nach `corex_modules`.
- coreZ Updates sichern vorhandene Modulordner vor der Aktualisierung und führen bei Fehlern ein automatisches Rollback der Moduldateien aus.
- Aktivieren/Deaktivieren ist im Modulmanager möglich; Deaktivierung löscht keine Dateien und keine Moduldaten.
- Phase 4 abgeschlossen: Modul-Assets werden sicher über `/module-asset` ausgeliefert, Admin-/Frontend-CSS und JS aus aktivierten Modulen automatisch eingebunden und Manifest-CSP in die bestehende Content-Security-Policy gemerged.
- Content Manager: Die „PHP-Datei“-Selectbox zeigt aktivierte Modul-Targets als eigene Gruppe; aktivierte Module können optional eigene Views oder Routen bereitstellen.
- Phase 5 abgeschlossen: `seo.urls.collect` ist an Sitemap und SEO-Übersicht angebunden, Modul-Content-Targets mit Route werden als Modul-URLs sichtbar und können direkt geöffnet werden.
- `media.usage.collect` ist an den `MediaUsageService` angebunden, damit Module Media-Nutzungen für Löschwarnungen und „Verwendet in“ melden können.
- `dashboard.widgets.collect` ist im Admin-Dashboard angebunden; optionale Widget-Permissions werden vor Anzeige geprüft.
- Phase 6 abgeschlossen: Pilotmodul `modules/faq` mit Manifest, Migration, Admin-/Frontend-Routen, Repository, Controllern, Glass-Admin-View, Frontend-Accordion, JSON-LD `FAQPage`, Dashboard-Widget und MediaUsage-Hook erstellt.
- Modul-i18n ist Pflicht: `module.json` muss `i18n` deklarieren; lokale Module und Paketprüfungen verlangen DE-/EN-JSON-Dateien.
- Admin-Sidebar rendert Modul-Menüpunkte aus `admin.menu.collect` in einer eigenen Gruppe „Module“.
- Phase 7 abgeschlossen: `content.blocks.collect` bindet Modul-Content-Blocks in den Content Manager ein; Modul-Blöcke werden als `module:slug:key` gespeichert, über Manifest-Schema editiert/sanitisiert und im Frontend per Modul-Render-View ausgegeben.
- Das FAQ-Pilotmodul liefert den ersten Modul-Block `FAQ Teaser` für bestehende CMS-Seiten inklusive übersetzbarer Felder, Limit, Kategorie-Badges und Button zur FAQ-Seite.
- Vorbereitete Komfort-Hooks ergänzt: `search.index.collect` für spätere globale Suche, `module.backup.collect` für Modul-Exports/Backups und `module.registry.collect` als Registry-/Marketplace-Grundlage.
- `SeoAnalyzerService` kann Modul-Block-Felder als statischen SEO-Kontext auswerten.
- coreZ Paketprüfung: Offizielle Modul-Hashes werden außerhalb des ZIPs geprüft; bekannte offizielle Pakete erscheinen im Admin als Success-Hinweis.
- **Quill — Image Resize im Editor**
- Bilder im Editor können per Drag-Handle skaliert werden; die angepasste Breite wird gespeichert und im Frontend responsiv dargestellt.
- **GLightbox im öffentlichen Frontend**
- CDN (CSS in `views/parts/header.php`, JS in `views/parts/footer.php`) mit CSP-Nonce.
- Auto-Wrap-Script: findet alle `<img>` in `.blog-content` und `section[data-cx-cms-block="text"]`, die nicht bereits in einem `<a>` stecken, und wrapped sie als `<a class="glightbox">`. Init via `GLightbox({ touchNavigation: true, loop: false })`.
- `views/blocks/text.php`: `<section>` erhält `data-cx-cms-block="text"` — erweiterbar für weitere Block-Typen.
- `public/assets/css/cx-global.css`: `section[data-cx-cms-block] img { max-width:100%; height:auto; }` ergänzt.
Geändert
- **Mediathek**
- Ordner-Dropdown, Datalist und Sidebar werden nach Meta-Änderungen, Löschaktionen oder Drag-&-Drop-Zuweisungen im Browser synchron aktualisiert.
- Auf kleineren Screens rutscht die Ordner-Sidebar unter das Grid und bleibt kompakt nutzbar.
- Aktivzustand der Mediathek-Filter vereinheitlicht.
- Der Spezialfilter „Nicht zugeordnete Bilder“ leert den Ordnerfilter automatisch; eine spätere Ordnerauswahl verlässt den Spezialfilter.
- Im Filter „Nicht zugeordnete Bilder“ verschwindet eine einsortierte Bild-Karte direkt aus dem Grid.
- Ordner-Umbenennung aktualisiert alle bestehenden Datei-Zuordnungen in `media_files.folder`.
- Auswahlstatus der Mediathek wird nach Filter-/Suchwechsel, Löschaktionen und erfolgreicher Bulk-Zuweisung robust zurückgesetzt; Tastatur-Basics für Karten und Ordner-Kacheln ergänzt.
- Das Detail-Modal aktualisiert Alt-Text-Status, Ordner-Badges, Sidebar und aktive Filter nach dem Speichern direkt im Browser.
- Einzel- und Bulk-Löschung warnen vor dem Entfernen, wenn Dateien noch in Content, News oder Settings referenziert werden.
- Upload, Paste-Upload und Sync-Import speichern SHA-256-Hashes, sobald die neue Hash-Migration eingespielt ist; Duplikate werden als Hinweis an die UI gemeldet.
- Video-Dateien werden in Grid und Detail-Modal als echte HTML5-Video-Elemente angezeigt; das Detail-Modal spielt Videos direkt mit Controls ab und hält die Preview-Box formatstabil.
- Mediathek-Header zeigt, ob `ffmpeg`/`ffprobe` über PHP verfügbar sind oder ob `exec()` deaktiviert ist.
- Content-Mediathek-Picker (`Bild aus Mediathek wählen`) bietet zusätzlich zur Suche einen Ordnerfilter.
- **Frontend-Design**
- Dynamic-CSS aller Designs gibt gemeinsame `--cx-body-*` Variablen aus und wendet sie auf `body` an.
- Parallax-JS liest `--cx-parallax-scroll-enabled`; bei deaktiviertem Bildscrollen wird nur die JS-Positionsbewegung gestoppt, das Hintergrundbild bleibt per `background-attachment: fixed` fest.
- **Admin-Oberfläche**
- Die neue Hilfeseite nutzt den bestehenden Glass-Mode mit `var(--admin-card-bg)` und Blur statt eigener Sonder-Hintergründe.
- Der neue Übersetzungs-Tab „Footer Links“ wurde optisch an den Admin-Glass-Mode angepasst; Bootstrap-Default-Hintergründe in Accordion und Tabellen wurden überschrieben.
Fix
- **Frontend — Parallax**
- Parallax-JS setzt `background-position-y` nun mit `!important`, damit es gegen die vorhandene `.parallax-section`-CSS-Regel gewinnt.
- AOS-Initialisierung im coreX-Design ist fehlertolerant, damit fehlendes AOS den restlichen Frontend-Init nicht stoppt.
- Design-JS aus Manifest und `assets/js/corex/main.js` werden mit `filemtime()` versioniert, damit Frontend-JS-Änderungen nicht im Browsercache hängen bleiben.
- **Mediathek — Nutzungsnachweis**
- `MediaUsageService` prüft Text-/JSON-Felder jetzt PHP-seitig mit normalisierten Varianten (`\/` → `/`, HTML-Entities dekodiert), damit CMS-Hero-Blockdaten und andere JSON-Referenzen zuverlässig erkannt werden.
- Zusätzlich werden Upload-Dateinamen aus normalisierten Text-/JSON-Feldern extrahiert und über den Basename verglichen; dadurch greifen CMS-Block-Referenzen auch bei unterschiedlichen URL-Schreibweisen.
- CMS-Blockdaten werden nun vor der Suche als JSON dekodiert und rekursiv nach Stringwerten durchsucht; `bg_image`-Referenzen in Hero-/Cards-/Text-Blöcken werden dadurch zuverlässig erkannt.
- Tabellen-/Spalten-Erkennung im Nutzungsservice von fragilen `SHOW ... LIKE ?`-Checks auf `information_schema` mit sicherem Fallback umgestellt, damit Quellen nicht still übersprungen werden.
- **Quill — Tabellen gehen beim Speichern verloren**
- Tabellen-Inhalte im Editor wurden beim Speichern durch einen Browser-internen Timing-Konflikt entfernt — korrigiert.
v0.8.9
20. May 2026
NEU: Quill WYSIWYG + Änderungen
Neu
- **Quill WYSIWYG — Einheitlicher Rich-Text-Editor**
- Alle Textfelder im Admin (Seiten, Blöcke, News, Übersetzungen) nutzen denselben Editor mit einheitlicher Toolbar und Mediathek-Integration.
- Screenshots lassen sich per Ctrl+V direkt in den Editor einfügen — automatischer Upload als WebP in die Mediathek.
Geändert
- **DB-Query-Optimierung — Frontend-Seitenlast stark reduziert**
- `src/Models/SiteSettings::getAll()`: Request-scoped static cache — `SELECT site_settings` wird nur noch einmal pro Request ausgeführt, egal wie oft `getAll()` aufgerufen wird.
- `src/Repositories/DesignSettingsRepository::getAllByDesign()`: Request-scoped static cache per Design-Slug — verhindert doppelte `design_settings`-Queries.
- `src/Controllers/ContentController::getBlocksForPage()`: N+1-Problem für nicht-DE Locales gefixt — statt 1 Query pro Block wird jetzt eine einzige `cms_blocks_i18n WHERE block_id IN (...)` Batch-Query ausgeführt (spart bei N Blöcken N-1 Queries).
- `src/Models/FooterManager`: `getFooterData()`, `getActiveSocials()`, `getTopbarSocials()`, `getFlatLinks()` und neues `getRevisionVersion()` haben jetzt request-scoped static caches.
- `src/Controllers/SettingsController`: Neue öffentliche Delegator-Methoden `getActiveSocials()`, `getTopbarSocials()`, `getFlatLinks()`, `getRevisionVersion()`.
- `views/parts/footer.php`: Alle 4–6 Inline-Queries entfernt. Socials, Revision-Version, Footer-Spalten/-Links und Flat-Links werden jetzt via `$page->settingsCtrl->*()` (gecacht) bezogen. Klaro-Services: `new SettingsController()` durch `$page->settingsCtrl->getKlaroServices()` ersetzt — kein redundanter Controller-Bootstrap mehr.
- `views/parts/topbar.php`: Inline-Query für `footer_socials` entfernt, nutzt jetzt `$page->settingsCtrl->getTopbarSocials()` (gecacht).
- `views/parts/navi.php`: Inline-Query `SELECT value FROM site_settings WHERE key='available_languages'` entfernt — Wert wird direkt aus bereits geladenem `$siteSettings`-Array gelesen.
- **Ergebnis**: Frontend-Seitenlast DE & nicht-DE-Locale Queries um ~50% reduziert (inkl. Block-i18n-Batch).
v0.8.8
19. May 2026
NEU: Brute-Force-Login-Schutz u.v.m. + Änderungen + Fixes
Neu
- **Brute-Force-Schutz für Login**
- `BruteForceService`: IP-basierte Versuchszählung — ≥3 Versuche = Captcha, ≥5 = 15 min Block, ≥10 = 60 min Block
- Login-View zeigt Captcha-Block automatisch anhand `$_cx_brute['show_captcha']`
- `AuthController::login()` prüft Block → Captcha → logt Erfolg/Fehler via AuditService
- Admin-View `views/admin/users/ip-locks.php`: Tabelle aller IP-Sperren, Unlock per AJAX
- Neue Permission `admin.users.ip-locks`
- **Audit-Log**
- `AuditService`: Zwei-Schicht-Logging — Schicht 1: automatischer Router-Hook für alle POST-Routen, Schicht 2: `AuditService::log()` in Controllers/Services für Before/After-Werte
- `AuthController`: login success/fail + logout werden explizit geloggt
- `UserController::save()` + `delete()`: user.create / user.save / user.delete geloggt
- Admin-View `views/admin/system/audit-log.php`: DataTables server-side, action-Badge mit Farb-Codierung, JSON old/new in aufklappbarem Modal
- Route `admin/system/audit-log` + AJAX `admin/audit-log/data`
- Neue Permission `admin.audit.view`
- Probabilistisches Cleanup (1 % der Writes löscht Einträge älter als `audit_retention_days` Tage, Default 90)
- **DataTableService** (`src/Services/DataTableService.php`): Generischer server-side Endpunkt — einheitliches `respond()` für alle DataTables-Endpunkte im Admin
- **MailService mit SMTP** (`src/Services/MailService.php`)
- Natives SMTP via PHP-Streams — kein Composer/PHPMailer nötig
- Unterstützt STARTTLS (Port 587), SSL (Port 465), AUTH LOGIN, native mail()-Fallback
- HTML + Plain-Text Multipart-Mails
- `.env`-Vars: `MAIL_HOST`, `MAIL_PORT`, `MAIL_ENCRYPTION`, `MAIL_USER`, `MAIL_PASS`, `MAIL_FROM`, `MAIL_FROM_NAME`
- **Passwort-Reset per E-Mail** vollständig aktiviert
- Routen `/forgot-password` + `/reset-password` (Views + Controller-Logik + i18n waren bereits vorbereitet)
- SMTP-Versand via `MailService`, branded HTML-Mail-Template mit Reset-Button
- **Admin → System: Test-Mail**
- Formular zum Versenden einer Test-Mail zur Verifikation der SMTP-Konfiguration
- Zeigt aktuellen Versandmodus (SMTP-Host oder native mail())
- **coreY: Modell-Selectbox**
- Dropdown statt Freitext für alle Cloud-Provider (Gemini, OpenAI, Groq, Mistral, Anthropic)
- Deprecated-Modelle mit ⚠-Warnung markiert, empfohlene Modelle mit ★
- Freitext-Fallback für ollama/custom + manuellen Eintrag per `✏ Eigenes Modell eingeben…`
- **DataTables CSP-konform (MLS Phase 6 ✅)**
- Admin-CSP-Erkennung locale-prefix-aware: erkennt `/de/admin/...` korrekt als Admin-Request
- `cdn.datatables.net` in Admin-CSP whitelisted; i18n-Dateien via CDN
- `views/admin/parts/datatables-defaults.php`: Globale Defaults (stateSave, lengthMenu, Processing-Logo), Locale-Change-Detection IIFE
Geändert
- `UserController::data()`: nutzt jetzt `DataTableService::respond()`
- Router: `AuditService::autoLog()` wird vor jedem `call_user_func` aufgerufen (nur POST)
- Admin-Sidebar: Audit-Log Eintrag unter System (Permission-gesichert)
- `public/index.php`: Admin-Erkennung prüft erste 2 URL-Segmente (Locale-Prefix-Support)
- `views/admin/parts/top-navbar.php`: DataTables-State wird beim Locale-Wechsel via click-Handler gelöscht
Fix
- `siteBase()` in `AuthController` nutzte hardcodierten `/corex`-Pfad statt `APP_BASE` — Passwort-Reset-Link war auf falscher URL
v0.8.7
18. May 2026
NEU: Einladungscode-System + Änderungen + Fixes
Neu
- **Einladungscode-System für Registrierung**
- Neuer Registrierungsmodus `invite`: Admin generiert Einladungscodes (32-stellig, kryptographisch sicher), bekommt einen kopierbaren Einladungslink, den er der einzuladenden Person weitergibt
- Einladungslinks: `/register?invite=CODE` — Code wird im Formular vorausgefüllt
- Codes sind einzeln und einmalig: nach Verwendung als `used_by` / `used_at` markiert
- Optionale Notiz (Name/E-Mail) und optionales Ablaufdatum (1–365 Tage) pro Code
- Ungenutzte Codes können widerrufen werden
- `database/migrations/2026_05_18_000049_invitations.sql`: Tabelle `cx_invitations` + Setting `registration_mode` + Permission `admin.invitations.manage`
- `src/Controllers/InvitationController.php`: `index()`, `generate()`, `revoke()`
- `views/admin/invitations.php`: Admin-Übersicht mit Code-Liste, Kopier-Button, Status-Badges
- Admin-Sidebar: Eintrag „Einladungen" unter Benutzer (Permission-gesichert)
Geändert
- **Registrierungsmodus** — `registration_enabled` (0/1) ersetzt durch `registration_mode` (`disabled` / `open` / `invite`) in `site_settings`
- `src/Services/ConfigSettingsService.php`: speichert neues `registration_mode`-Setting
- `views/admin/config.php`: Toggle durch 3-Wege-Select ersetzt; bei Modus `invite` direkter Link zu Einladungscodes
- `views/content/auth.php`: Registrierungsformular zeigt Einladungscode-Feld nur im Modus `invite`; Login-Seite zeigt Registrierungslink nur bei Modus `open`
- `views/parts/navi.php`: Registrierungslink im Nav nur noch bei Modus `open`
- `src/Config/Routes.php`: neue Routen `admin/invitations`, `admin/invitations/generate`, `admin/invitations/revoke`
Fix
- **MLS Block-Zähler (Top-Karte)**: `TranslationService::getMissingI18n()` filtert jetzt ebenfalls mit `blockHasTranslatableFields()` — Zahl in der oberen Übersichts-Box stimmt nun mit der Liste überein
- **coreY: `<translation>`-Tag im Output**: Fallback-Pfad entfernt jetzt `<translation>`/`</translation>` aus dem Rohtext bevor er gespeichert wird (trat auf wenn Modell kein schließendes Tag lieferte)
- **cx-global.css für alle Designs**: Nav-Avatar/Pill-Klassen (`cx-nav-pill`, `cx-nav-avatar*`, `cx-logo-img`, `cx-mn-*`) aus `corex-custom.css` in `cx-global.css` verschoben, damit alle Designs die Klassen erhalten
- **Button-Palette im Block-Editor unsichtbar**: Generierte `buttons-{timestamp}.css` wurde nur im Frontend-Header eingebunden, nicht im Admin-Header. `views/admin/parts/header.php` liest `buttons_css_file` jetzt per DB-Query und lädt die Datei — Button-Vorschauen in allen CMS-Block-Editoren werden nun korrekt dargestellt
v0.8.6
18. May 2026
NEU: Cloud-Provider-Unterstützung + Fixes
Neu
- **coreY: Cloud-Provider-Unterstützung (Google Gemini, OpenAI, Groq, Mistral, Anthropic, Custom)**
- `CoreYProviderInterface` (`src/Contracts/`): Einheitliches Interface `chat()`, `stream()`, `ping()` für alle Provider
- `OpenAiProvider` (`src/Services/CoreY/`): Vollständige Implementierung für alle OpenAI-kompatiblen APIs inkl. SSE-Streaming; Google Gemini nutzt denselben Provider über `generativelanguage.googleapis.com/v1beta/openai`
- Sensible Zugangsdaten (API-Keys) werden verschlüsselt in der Datenbank gespeichert; in Admin-Ansichten werden sie maskiert dargestellt.
- `CoreYService` refactored: Provider-Factory `makeCloudProvider()`, `chat()` / `streamChat()` / `pingWithError()` routen automatisch zum aktiven Provider; Ollama-Pfad bleibt vollständig erhalten
- Globaler Admin-System-Prompt: Wenn gefüllt, ersetzt er den eingebauten coreY-Basis-Prompt vollständig
- Admin-Seite coreY-Einstellungen: Neue Sektionen „Provider & API" (Provider-Dropdown, Endpoint, verschlüsselter API-Key) und „Persona & System-Prompt" (2000-Zeichen-Textarea); Ollama-URL/Model werden provider-abhängig ein-/ausgeblendet (JS)
- 4 neue Keys in `site_settings` (`corey_provider`, `corey_api_key`, `corey_api_endpoint`, `corey_system_prompt`)
- **coreY: DB-basierter Chat-Verlauf + Multi-Turn-Kontext**
- Neue Tabelle `corey_chats`: speichert alle User- und AI-Nachrichten pro Nutzer
- Chat-Verlauf wird beim Öffnen des Panels aus der DB geladen (`GET /admin/corey/history`)
- Multi-Turn-Kontext: Letzte 20 Nachrichten werden als History an den AI-Provider (Gemini/OpenAI-kompatibel) übergeben
- Begrüßungsnachricht wird einmalig gespeichert — erscheint nach Seiten-Navigation nicht erneut
- Neue Endpunkte: `clear-history` (POST), `save-message` (POST), `history` (GET)
- **coreY: Streaming-Toggle in Einstellungen**
- Schalter „Streaming aktivieren" in coreY-Einstellungen
- **coreY: Panel-State per localStorage persistent**
- Panel bleibt beim Navigieren zwischen Admin-Seiten offen
Fix
- Chat scrollt nach Laden des Verlaufs und nach neuen Nachrichten zuverlässig ans Ende
- Close-Button im Panel-Header funktioniert bei allen Fensterbreiten (`.coreY-debug` war fälschlicherweise über dem Button positioniert)
- User-Nachricht in der DB speichert nun den tatsächlichen Eingabetext statt dem Action-Prompt
- CSS-Struktur: `corey-response-area` als Flex-Container, `corey-chat-list` als eigentliche Scroll-Box
v0.8.5
14. May 2026
NEU: coreX SEO Analyzer + Fixes + Änderungen
Neu
- **coreX SEO Analyzer (Admin → System):** Vollständiges SEO-Analyse-Tool für alle CMS-Seiten und Blog-Posts
- **Übersichtsseite** (`/admin/seo`): Tabelle aller Seiten mit Score-Badge, letztem Scan-Datum, Schnellscan-Button (AJAX) und PSI-Link; Tab für globale SEO-Einstellungen (Twitter-Handle, Author, Google/Bing-Verification, PSI-API-Key, Standard-Meta-Desc)
- **Detailseite** (`/admin/seo/{type}/{id}`): 4 Score-Karten (Gesamt, On-Page, Technisch, Content), aufklappbare Fehler-/Warnungsliste mit Priorität, Core Web Vitals (LCP/INP/CLS via PageSpeed Insights API), Scan-Verlauf/Historie als Sparkline-Chart
- **`SeoAnalyzerService`:** 13 Prüfungen (Meta-Title/-Desc, Canonical, hreflang, H1, Bilder-Alt, robots, Open Graph, Twitter Card, JSON-LD, HTTPS, Ladezeit), 100-Punkte-System
- **`SeoFetcherService`:** Live-Fetch der Frontend-URL via cURL, DOM-Parsing mit DOMDocument
- **`SeoPageSpeedService`:** Integration der Google PageSpeed Insights API v5 (Mobile, LCP/INP/CLS)
- **`SeoSnapshotService`:** Speicherung von Scan-Ergebnissen in `seo_snapshots`-Tabelle, Verlaufsabfrage, Site-Übersicht
- **`SeoController`:** 7 neue Routen (`/admin/seo`, `/admin/seo/scan`, `/admin/seo/detail`, `/admin/seo/settings`, `/admin/seo/history`, `/admin/seo/snapshot`, `/admin/seo/site-overview`)
- **News/Blog SEO-Felder:** `meta_title`, `meta_description`, `meta_canonical` für Blog-Posts im Editor editierbar; `NewsController` speichert und liest diese Felder
- **PSI-API-Key:** Einstellbar unter Admin → Konfiguration; `ConfigSettingsService` verwaltet den Key
- **Nav-Link:** SEO Analyzer unter Admin → System → „coreX SEO Analyzer" (`bi-graph-up-arrow`)
- **coreY-Integration (Phase 7):** „coreY fragen"-Button in der Detailansicht — übergibt Seiten-Titel, URL, Score und alle gefundenen Probleme als Kontext; neuer `seo_expert`-Action-Mode in `CoreYController` und `CoreYService`; globale Funktion `window.coreyOpenWith()` für programmgesteuerte Panel-Öffnung
- **Migrationen:** `seo_snapshots`-Tabelle, News-SEO-Felder, `admin.seo.view`/`admin.seo.edit`-Permissions, `psi_api_key` in `site_settings`
- **Social Icons — zentrale Verwaltung:** URLs und Icon-Klassen aller Plattformen werden nun ausschließlich unter *Verwaltung → Konfiguration → Social Medien* gepflegt. Die Tabelle `footer_socials` ist Single Source of Truth für alle Plattformen.
- **Social Icons — Topbar-Steuerung:** Neue Spalte `show_in_topbar` in `footer_socials` steuert, welche Plattformen in der Topbar erscheinen. Admin-Seite *Topbar → Social Icons* zeigt Toggles statt URL-Felder.
- **Neue Social-Plattformen:** Facebook, Xing, Telegram, Threads, WhatsApp, Bluesky als Standardplattformen in `footer_socials` ergänzt.
Geändert
- **Frontend / Topbar:** `<style>`-Block aus dem `<body>` in den `<head>` ausgelagert — CSS-Variablen und Marquee-Keyframes werden jetzt korrekt im `<head>` via `header.php` ausgegeben (kein FOUC mehr möglich)
- **Frontend / Desktop-Nav:** `<style>`-Block für Navbar-Farben/Blur/Schatten aus `navi.php` (`<body>`) in den `<head>` (`header.php`) verschoben; kompletter `$_dn*`-Berechnungsblock aus `navi.php` entfernt
- **Frontend / Parallax:** `corex-init.js` um JS-basierten Scroll-Handler für `.parallax-section` ergänzt (verschiebt `backgroundPositionY` beim Scrollen, analog zu `light_blue-init.js`); `background-attachment: fixed` aus `corex-custom.css` entfernt da es mit JS-Parallax kollidiert und in bestimmten Kontexten (transform-Ancestors, iOS) nicht funktioniert
- **Performance / `.htaccess`:** gzip-Komprimierung (`mod_deflate`) und Browser-Caching (`mod_expires`, 1 Jahr für statische Assets) aktiviert
- **Admin / Footer → Social Icons:** Tab zeigt nur noch Ein/Aus-Toggles (Sichtbarkeit im Footer), keine URL-/Icon-Inputs mehr. Link zu Konfiguration für zentrale Verwaltung.
- **Admin / Topbar → Social Icons:** Abschnitt zeigt Toggles für `show_in_topbar` statt URL-Eingabefelder. Live-Vorschau reagiert auf Toggles.
- **Frontend / Topbar:** Liest Social Icons dynamisch aus `footer_socials WHERE show_in_topbar=1 AND url != ''` statt aus `site_settings`-Einzelschlüsseln.
- **`TopbarSettingsService`:** Speichert keine `topbar_social_*`-Schlüssel mehr in `site_settings`.
Fix
- **SEO / hreflang Startseite:** hreflang-Tags zeigten auf `/de/home` statt `/de/` — Slug `home` wird in `SeoService::hreflangForCmsPage()` jetzt wie ein leerer Slug behandelt
- **SEO / Canonical URL:** Canonical-URL enthielt keinen Sprach-Prefix (`/kontakt/`) und stimmte daher mit keinem hreflang-Tag überein — Canonical wird jetzt mit Locale-Prefix gebaut (`/de/kontakt`), sodass Canonical und hreflang für die aktuelle Sprache exakt übereinstimmen; gilt für CMS-Seiten und Blog-Posts
- **SEO / Twitter Cards (Blog-Posts):** `twitter:site` fehlte auf Blog-Post-Seiten — `$twHandle` wurde in `buildBlogPostContext()` nicht aus `$siteSettings` gelesen und nicht in das Twitter-Array aufgenommen
Migration
- `2026_05_15_000041_social_centralize.sql` — `show_in_topbar`-Spalte, neue Plattformen, Bereinigung alter `site_settings`-Social-Keys.
v0.8.4
13. May 2026
NEU: Error Log DataTables + Fixes
Neu
- **Admin / Error Log:** DataTables 2.x Integration — serverseitige Pagination entfernt, alle Einträge werden client-seitig von DataTables paginiert, sortiert und durchsucht (25 Einträge/Seite, konfigurierbar); Level-Filter-Badges bleiben serverseitig über GET-Parameter; Detail-Modal per Klick
Fix
- **Admin / Error Log:** Fehlerhafter Funktionsaufruf verhinderte die Darstellung des Error-Log-Inhalts — korrigiert.
- **Admin / Error Log:** DataTables-Scripts blockiert durch fehlende CSP-Whitelist — `cdn.datatables.net` in `script-src`, `style-src` und `connect-src` der Admin-CSP in `public/index.php` ergänzt
- **Admin / Error Log:** `jQuery is not defined` / `DataTable is not defined` — DataTables v2 benötigt jQuery; jQuery 3.7.1 wird nun dynamisch vor DataTables geladen
- **Übersetzungsseite / Inhaltsblöcke:** Block-Typ wurde als `?` angezeigt und es erschien "Keine übersetzbaren Textfelder", obwohl der Block Texte enthält — `TranslationService::getBlockDeData()` las nur die `data`-JSON-Spalte, aber `block_type` ist eine eigene DB-Spalte; wird nun mitgeladen und ins Array injiziert
- **Übersetzungsseite / Inhaltsblöcke:** Semantische Text-Felder (`text`, `content`, `description`) wurden bei kurzem DE-Inhalt (<80 Zeichen) fälschlicherweise als einzeiliges `<input>` statt als `<textarea>` gerendert — Fix: Feld-Key wird nun zusätzlich geprüft (Suffix `text`, `content`, `description` → immer Textarea)
- **Smooth Scroll:** `scroll-behavior: smooth` im CSS (corex, universe, light_blue) kollidierte mit dem JS-basierten `window.scrollTo({ behavior: 'smooth' })` — Browser animierte zu schnell/unkontrolliert; CSS-Property entfernt, eigene `cxSmoothScrollTo()`-Funktion mit 700ms EaseInOutCubic-Easing eingebaut
- **Übersetzungsseite / JSON-Tab:** Fortschritts-Badge zeigte Datei-Existenz (`1/1`) statt tatsächliche Key-Übersetzungsquote; Badge zeigt nun übersetzt/gesamt (z.B. `8/10`)
v0.8.3
12. May 2026
NEU: Redirect-Manager; Newsletter-System + Fixes
Neu
- **Newsletter / Subscriber-System**
- Tabelle `cx_newsletter_subscribers` (email, name, confirm_token, confirmed_at, unsubscribe_token, is_active) + Permission `admin.newsletter.edit`
- `src/Repositories/NewsletterRepository.php` — `all()`, `count()`, `countConfirmed()`, `findByEmail()`, `findByConfirmToken()`, `findByUnsubscribeToken()`, `insert()`, `confirm()`, `deactivate()`, `toggleActive()`, `delete()`, `allConfirmed()`
- `src/Services/NewsletterService.php` — `subscribe()` (Doppel-Anmeldeschutz, Re-Aktivierung), `confirm()` (Token-basiert), `unsubscribe()` (Token-basiert), `sendConfirmMail()` (UTF-8 encoded subject, PHP `mail()`)
- `src/Controllers/NewsletterController.php` — Admin: `index()`, `delete()`, `toggle()`, `export()` (CSV mit UTF-8 BOM)
- `src/Controllers/NewsletterPublicController.php` — Public: `subscribe()` (AJAX + Fallback), `confirm()` (GET), `unsubscribe()` (GET) mit eigenem Render-Page
- `views/admin/newsletter/index.php` — Übersicht mit Bestätigt/Ausstehend/Abgemeldet-Badge, Toggle, AJAX-Delete, CSV-Export-Button
- `views/parts/newsletter-form.php` — wiederverwendbares Anmeldeformular-Snippet (AJAX, Flash-Message, Spinner)
- Routen: `newsletter/subscribe`, `newsletter/confirm`, `newsletter/unsubscribe` (public) + `admin/newsletter/**` (auth + permission)
- Navi-Eintrag unter Verwaltung → Newsletter (`bi-envelope-at`)
- **Geplantes Veröffentlichen (Scheduled Publishing)** für Blog-Posts
- `src/Controllers/NewsController.php`: `getPublished()` + `getBySlug()` filtern jetzt `AND published_at <= NOW()` — Posts mit Zukunftsdatum bleiben unsichtbar bis zum Zeitpunkt
- `views/admin/news/index.php`: Neues "Geplant"-Badge (warning/clock) wenn `is_published=1` und `published_at` in der Zukunft; Datum zeigt Uhrzeit für geplante Posts
- `views/admin/news/form.php`: Datetime-Feld mit Hint-Box "Der Beitrag wird automatisch zum gewählten Zeitpunkt sichtbar" + JS-Toggle; kein Cron-Job nötig — rein query-basiert
- **Redirect-Manager** (`/admin/redirects`) — 301/302-Weiterleitungen verwalten
- Tabelle `cx_redirects` + Permission `admin.redirects.edit`
- `src/Repositories/RedirectRepository.php` — `findByPath()`, `all()`, `upsert()`, `update()`, `toggleActive()`, `delete()`, `incrementHit()`
- `src/Controllers/RedirectController.php` — `index()`, `save()`, `toggle()`, `delete()`
- `views/admin/redirects.php` — Übersicht-Tabelle mit Hit-Counter, Modal für Neu/Bearbeiten, Inline-Toggle, AJAX-Delete
- Weiterleitungen werden zentral vor dem normalen Routing ausgewertet.
- Navi-Eintrag unter Verwaltung → Redirects (`bi-sign-turn-right`)
Fix
- **Parallax-Bug (Text-Block, Two-Col, Blog-Post-Hero)**: Alle drei Blöcke nutzten einen veralteten JS+inner-Div-Ansatz (`data-parallax="0.5"` mit `top:-650px;bottom:-650px`) — jetzt einheitlich auf CSS `parallax-section` + `background-attachment:fixed` umgestellt (wie `cards.php`)
- **Blog-Listing Teaser**: Fallback-Teaser nutzte `strip_tags()` mit erlaubten HTML-Tags — wird jetzt sauber durch `$blogWordPreview()` als Plaintext gerendert
- **Übersetzungseditor (`views/admin/translations.php`)**: Quill WYSIWYG durch einfache Monospace-Textarea + Toolbar ersetzt (identisches Konzept wie News-Editor); Quill-CDN-Einbindung entfernt; `cx-corey-quill-field`-Sonderfall im coreY-Handler entfernt
v0.8.2
11. May 2026
NEU: coreY SSE-Streaming + Settings-Seite
Neu
- **Phase 8c — coreY SSE-Streaming + Settings-Seite**
- `src/Services/CoreYService.php`: `streamChat()` — streamt Ollama-Antwort Token-für-Token als Server-Sent Events; `getAvailableModels()` — lädt verfügbare Modelle vom Ollama-Server; `sanitizeInputPublic()` — öffentlicher Zugriff auf interne Sanitizer; neue Properties: `$tone`, `$responseLength`, `$responseLang`, `$personality` aus `site_settings`; neue Getter; `buildSystemPrompt()` berücksichtigt jetzt Ton, Länge, Sprache und Persönlichkeit
- `src/Controllers/CoreYController.php`: `stream()` (GET, SSE), `settings()` (GET, View), `settingsSave()` (POST, DB-Write)
- `src/Config/Routes.php`: Routen `corey/stream`, `corey/settings`, `corey/settings/save` ergänzt
- `views/admin/corey-settings.php` — neue Settings-Seite mit Verbindungstest, Modell-Auswahl, Ton/Länge/Sprache-Optionskarten und Persönlichkeits-Textarea
- `public/assets/admin/js/corey.js`: `sendRequest()` auf SSE-Streaming (fetch + ReadableStream) umgebaut — Token-für-Token-Rendering statt JSON-Volltext
- `views/admin/parts/aside-navi-left.php`: coreY-Link unter Verwaltung → Konfiguration ergänzt (nur wenn COREY_ENABLED + Permission)
- `database/migrations/2026_05_11_000037_corey_behavior_settings.sql` — `corey_tone`, `corey_response_length`, `corey_response_lang`, `corey_personality` in `site_settings`
v0.8.1
10. May 2026
Änderungen + Fixes
Neu
- `src/Services/Parts/FooterCssGenerator.php` — generiert `public/assets/css/corex/parts/footer.css` mit DB-dynamischem Footer-Padding (5rem für columns, 2rem für flat/none) sowie optionalen Link-Farbe, Hover-Farbe, Text-Shadow und Font-Size aus den Footer-Settings
- `public/assets/css/corex/parts/footer.css` — neue generierte Part-CSS-Datei (Default: `padding-top:5rem`)
Geändert
- **Sprint F — footer Inline-Style Cleanup**
- `src/Models/FooterManager.php`: `saveSettings()` triggert `FooterCssGenerator::generate()` nach jedem Save; `use`-Imports für `CssGeneratorService` + `FooterCssGenerator` ergänzt
- `views/parts/header.php`: `footer.css` global eingebunden (als zweite Zeile nach `navi.css`)
- `views/parts/footer.php`: `<style>`-Block (statische + DB-dynamische Regeln) vollständig entfernt; PHP-Vars für Farb-Interpolation entfernt; `style="padding-top:..."` auf `<footer>` → `class="cx-footer"`; Inline-Opacities/Cursor → CSS-Klassen (`cx-foot-slogan`, `cx-foot-divider`, `cx-foot-copyright`, `cx-foot-sep`, `cx-foot-copyright-dim`, `cx-cursor-pointer`)
- `public/assets/css/corex/corex-custom.css`: Sprint-F-Sektion mit 9 neuen Utility-Klassen ergänzt
- **Sprint E — content Inline-Style Cleanup**
- `views/content/datenschutz.php`: `padding-bottom:3rem` → `pb-5`; Divider → `.cx-divider-line`; `line-height:1.8` → `.cx-lh-18`; alle `color:var(--eyecatcher)` auf h2 → `.text-eyecatcher`; `color:var(--neon-blue)` auf Links → `.text-neon-blue`
- `views/content/technical.php`: Header-Section padding+position → `pb-5 position-relative`; Hintergrundbild-Wrapper → `.cx-hero-bg-wrapper` / `.cx-hero-bg-video`; Video-Höhe → `.cx-hvb-427`; Kicker-Span → `.cx-section-kicker`; Divider (×3) → `.cx-divider-line`; Lead-Text → `.cx-lead-narrow`; DB-dynamische Farben bleiben inline
- `views/content/changelog.php`: Analog technical.php + subtitle-Span → `.cx-changelog-subtitle`; Lead max-width → `.cx-lead-narrow`; Container → `.cx-content-narrow`; Current-Badge → `.cx-badge-current`
- `views/content/profile.php`: Section position → `position-relative`; Bg-Wrapper/-Video → `.cx-hero-bg-wrapper/.cx-hero-bg-video`; Divider → `.cx-divider-line`; Avatar-Bild → `.cx-avatar-lg`; Avatar-Initial-Div → `.cx-avatar-lg-initial`; Karten → `.cx-card-glass`
- `views/content/blog.php`: Sections position → `position-relative`/`pb-5 position-relative`; Bg-Wrapper/-Video → Klassen; Video-Höhen → `.cx-hvb-300` / `.cx-hvb-300-mt`; Divider → `.cx-divider-line`; Blog-Section padding → `.cx-py-4rem`; Card-Bild → `.cx-blog-card-img`
- `views/content/blog-post.php`: Header padding/overflow → `.cx-bpost-header-pb` + `overflow-hidden`-Klasse (conditional); Parallax-Wrapper → `.cx-bpost-parallax-bg`; Bg-Wrapper/-Video → Klassen; Layer-Overlays → `.cx-overlay-55` / `.cx-overlay-light-35`; Container z-index → `.cx-rel-z2`; Featured-Img → `.cx-blogpost-featured-img`; Back-Section padding → `.cx-bpost-footer-section`
- `views/content/features.php`: Summary-Card → `.cx-card-surface`; Done-Icons (×5) → `.cx-table-check`; Feature-Card → `.cx-feat-card`; Num/Icon/Title/Desc → `.cx-feat-num/.cx-feat-icon-sm/.cx-feat-title/.cx-feat-desc`
- `views/content/contact.php`: Textarea → `.cx-textarea-constrained`; Captcha-Wrapper (×2) → `.cx-captcha-wrapper/.cx-captcha-wrapper-rounded`; Captcha-Bilder → `.cx-captcha-img-sm/.cx-captcha-img-lg`; Refresh-Buttons → `.cx-captcha-refresh-btn`; `margin-top:unset` → `mt-0`; Divider (×2) → `.cx-divider-line`; `padding-bottom:3rem` → `pb-5`; `z-index:2;padding:2rem` → `.cx-z2-pad`; alle DB-dynamischen Styles bleiben inline
- `public/assets/css/corex/corex-custom.css`: Sprint-E-Sektion mit ~35 neuen Utility-Klassen ergänzt
- **Sprint B — blocks Inline-Style Cleanup**
- `views/blocks/slider.php`: Section-Höhe → CSS-Custom-Property `--sl-height` + `.cx-sl-section`; Swiper-Höhe, Slide-Overflow, Overlay-z-index, Content-z-index → CSS-Klassen (`.cx-sl-section > .swiper`, `.cx-sl-content`, `.cx-sl-bg-fallback`, `.cx-sl-text`, `.cx-sl-lead`); `.sl-bg` strukturelle Properties → CSS (nur `background-image:url()` bleibt inline)
- `views/blocks/hero.php` (Block): Strukturelles CSS (position, display, align, color) → `.cx-blk-hero`; `.hero-container` Padding → CSS; Description max-width → `.cx-blk-hero-desc`; dynamische Background/Höhe bleibt inline
- `views/blocks/cta.php`: `color:#fff` → `.cx-blk-cta`; `background-size:cover;background-position:center` → `.cx-blk-cta-cover`; dynamische Background-Farbe/-Bild bleibt inline
- `public/assets/css/corex/corex-custom.css`: Sprint-B-Sektion mit allen obigen Klassen ergänzt
- **Sprint D — parts Inline-Style Cleanup**
- `views/parts/navi.php`: Alle hardcodierten `style=""`-Attribute (Nav-Pills, Avatare, Mobile-Nav, Sprach-Divider) durch neue CSS-Klassen ersetzt (`cx-nav-pill`, `cx-nav-avatar`, `cx-nav-avatar-initial`, `cx-nav-avatar-guest`, `cx-nav-lang-code`, `cx-mn-overlay-light`, `cx-mn-video-wrapper`, `cx-mn-lang-divider`, `cx-mn-lang-active`, `cx-mn-lang-muted`)
- Logo-Höhe: `style="width:auto;max-height:Xpx"` in navi.php + header.php → CSS-Klasse `cx-logo-img` + CSS-Variable `--cx-logo-height` (geschrieben von `NaviCssGenerator`)
- `views/parts/header.php`: Loading-Layer-Logo-Styles → `cx-logo-img`
- `views/parts/hero.php`: `<style>`-Block mit `.hero-layout-1/2/3` structural CSS → `corex-custom.css` ausgelagert; DB-dynamische Section-Backgrounds bleiben bis HeroCssGenerator-Sprint
- `src/Services/Parts/NaviCssGenerator.php`: Schreibt jetzt `:root{--cx-logo-height:Xpx}` in die generierte `navi.css`
- `public/assets/css/corex/corex-custom.css`: Neue Sprint-D-CSS-Sektion mit allen obigen Klassen + Hero-Layout-CSS
v0.8.0
02. May 2026
NEU: coreX MLS; coreX ErrorLog + Fixes + Änderungen
Neu
- **coreX MLS Phase 5 — URL-Struktur mit Sprach-Prefix** (Option A, Breaking Change)
- Alle Frontend-URLs tragen jetzt den Sprach-Prefix: `/de/kontakt`, `/en/contact`, `/de/forum`, etc.
- `CX_SUPPORTED_LANGS` Konstante — komma-separierte Liste unterstützter Sprachen, aus `$__cxSupported` abgeleitet
- `CX_BASE` Konstante — `APP_BASE . '/' . CX_LOCALE`, z.B. `/corex/de` — Basis für alle Frontend-Links
- `cx_url(string $path = ''): string` Hilfsfunktion in `CoreXMLS.php` — generiert locale-präfixierte URLs; externe URLs (`https://`, `//`) und Anker (`#`) werden unverändert durchgereicht
- **Canonical Redirect**: GET-Requests ohne Sprach-Prefix werden per 301 auf `APP_BASE/{locale}/{path}` umgeleitet. Ausgenommen: `admin/*`, `captcha`, `robots.txt`, `sitemap.xml`, `install/*`, `auth/*`, `lang/*`. POST-Requests werden nie umgeleitet.
- **Router** (`src/Core/Router.php`): Strips den Sprach-Prefix nach dem APP_BASE-Stripping — `de/login` → `login`, `en/forum` → `forum`
- **`PageRenderer::resolveSlug()`**: Strippt ebenfalls den Locale-Prefix nach dem APP_BASE-Strip — behebt 404 für alle CMS-Seiten unter `/de/...`
- **Maintenance-Check**: berücksichtigt jetzt den Sprach-Prefix beim Pfad-Matching
- `<html lang="...">` in `views/parts/header.php` dynamisch aus `CX_LOCALE`
- Admin-Bereich bleibt ohne Sprach-Prefix: `APP_BASE/admin/...`
- **`cx_url()` in alle Link-Quellen eingebaut** — Breaking Change vollständig geheilt:
- `views/parts/navi.php` — Logo, CMS-Slugs, Profil/Login/Logout/Register → `cx_url()` / `CX_BASE`; Admin-Link bleibt `APP_BASE`
- `views/parts/footer.php` — `$pageroot` auf `CX_BASE`; Flat-Links via `cx_url()`
- `views/blocks/hero.php`, `cta.php`, `text.php`, `slider.php` — Button-URLs via `cx_url()`
- `src/Core/BasePage.php` + `PageRenderer.php` — Home-Redirects und 404-Link nutzen `CX_BASE` statt `APP_BASE`
- **coreX MLS — Sprachumschalter im Frontend**
- **Globus-Dropdown** (`bi-globe2`) in der Desktop-Navi (links vom User-Avatar) — zeigt aktiven Locale-Code, Checkmark bei aktiver Sprache
- Gleiche Sprachlinks in der **Mobile-Nav-Sidebar** (mit Trennlinie, oben in der User-Sektion)
- Wird nur gerendert wenn `available_languages` in `site_settings` mehr als 1 Sprache enthält
- **`MlsController::switchLanguage()`** — setzt Session + Cookie, leitet auf äquivalente URL der neuen Sprache (tauscht Locale-Segment: `/de/kontakt` → `/en/kontakt`)
- **Route `GET /lang/switch?to=en&back={url}`** — außerhalb der `admin`-Gruppe, vor Catch-all registriert
- **coreX MLS Phase 3 — Frontend-Views migriert** — alle Frontend-Seiten mit UI-Strings nutzen jetzt `coreX_mls()`
- `views/parts/navi.php` — Navigation (Login, Register, Profil, Admin Panel, Abmelden, Menü-Labels)
- `views/content/auth.php` — Login, Registrierung, Passwort-Vergessen, Passwort-Zurücksetzen
- `views/content/blog.php` + `blog-post.php` — Leerlauf-Texte, Weiterlesen, Fehlerseite
- `views/content/contact.php` — Überschrift, Formularfelder, Platzhalter, Absenden-Button, Adressblock
- `views/content/maintenance.php` — Wartungsseite (Titel, Überschrift, Standard-Nachricht)
- `views/content/profile.php` — Profilformular (alle Labels, Buttons, JS-Passwort-Validierung)
- `views/content/changelog.php` — Seitenüberschrift, „Aktuell"-Badge, Leerstand-Text
- `views/forum/*.php` — Forum-Index, Threads-Liste, Thread-Ansicht, Neues-Thema, Verboten-Seite
- 20+ neue Lang-Dateien in `lang/de/` und `lang/en/`
- Statische Inhaltsseiten (`datenschutz.php`, `technical.php`, `features.php`) werden in Phase 4 als CMS-Content behandelt
- **coreX Error Log** — DB-basiertes Error-Logging-System; fängt alle PHP-Fehler (Warnings, Notices, Exceptions, Fatals) via `set_error_handler`, `set_exception_handler` und `register_shutdown_function` ab
- **`ErrorLogger`** (`src/Core/ErrorLogger.php`) — Singleton, schreibt in `cx_error_log`; Stack-Trace-Sanitization, Fallback auf natives `error_log()`
- **Admin-UI** unter *System → Error Log* — Tabelle mit Filterung nach Level, Freitextsuche, Pagination, Detail-Modal, Log-leeren-Button (mit CSRF)
- **coreX MLS Phase 1 — Core-Infrastruktur** — MultiLanguage System Fundament
- `src/Core/Translator.php` — Singleton, Lazy-Loading JSON, Dotted-Key-Notation, Plural-Unterstützung, 6-stufige Fallback-Chain (URL → Session → Cookie → Accept-Language → DB → `de`)
- `src/Helpers/CoreXMLS.php` — globale Funktionen `coreX_mls()`, `coreX_mls_group()`, `cx_locale()`
- Locale-Erkennung in `public/index.php` direkt nach APP_BASE; Dev-Modus loggt fehlende Keys
- Erste Lang-Dateien: `lang/de/parts/footer.json` + `lang/en/parts/footer.json`
- **coreX MLS Phase 2 — Admin-Konfiguration** — Verwaltung → coreX MLS
- `src/Services/LanguageSettingsService.php` — liest/schreibt Sprachkonfiguration, berechnet Übersetzungsfortschritt in %
- `src/Controllers/MlsController.php` — GET-Seite + POST-Speichern, Permission `admin.mls.edit`
- `views/admin/mls.php` — Standardsprache, aktive Sprachen (DE immer Fallback), Fortschritts-Balken je Sprache
- Migrations: `2026_05_02_000030_error_log.sql`, `2026_05_02_000031_mls_settings.sql`
- **coreX MLS Phase 4 — Datenbank i18n (Mehrsprachige DB-Inhalte)**
- **3 neue i18n-Tabellen** via Migration `2026_05_02_000032_mls_i18n_tables.sql`:
- `cms_pages_i18n` `(page_id, lang, nav_label, slug, page_title, meta_description, meta_keywords)` — übersetzt Seiten-Metadaten und URL-Slugs je Sprache
- `cms_news_i18n` `(news_id, lang, title, slug, excerpt, content)` — übersetzt News/Blog-Beiträge; `content = NULL` = DE-Fallback
- `cms_blocks_i18n` `(block_id, lang, data JSON)` — übersetzt Block-Inhalte; `data = NULL` = DE-Fallback
- **EN-Seed-Daten** direkt in der Migration: 15 Seiten-Slugs + Titel auf EN, 4 News-Einträge mit EN-Titeln/Slugs/Excerpts
- Haupttabellen (`cms_pages`, `cms_news`, `cms_blocks`) bleiben **unverändert** — sie sind der DE-Hardcoded-Fallback
- **`ContentController` i18n-aware** (`src/Controllers/ContentController.php`):
- `getPageBySlug()`: Prüft für Nicht-DE-Locales erst `cms_pages_i18n WHERE slug=? AND lang=CX_LOCALE` via JOIN, Fallback auf `cms_pages.slug` (DE)
- `resolvePage()`: Merged nach Slug-Lookup automatisch i18n-Metadaten (`nav_label`, `page_title`, `meta_description`, `meta_keywords`) aus `cms_pages_i18n` auf das Page-Array
- `getBlocksForPage()`: Nach dem Laden der Blöcke wird je Block `cms_blocks_i18n WHERE block_id=? AND lang=CX_LOCALE` geprüft — bei vorhandenem `data`-JSON wird dieses per `array_merge` über die DE-Daten gelegt (strukturelle Keys wie `bg_image` bleiben aus DE)
- **`NewsController` i18n-aware** (`src/Controllers/NewsController.php`):
- `getBySlug()`: Für Nicht-DE-Locales zuerst JOIN auf `cms_news_i18n` via übersetztem Slug; Fallback auf DE-Slug mit LEFT JOIN; `COALESCE` für title/slug/excerpt/content
- `getPublished()`: LEFT JOIN `cms_news_i18n` — `COALESCE(NULLIF(i.title,''), n.title)` etc. — Liste zeigt automatisch übersetzte Titel/Slugs/Excerpts; `content = NULL` = DE
- **Admin-UI: Seitenübersetzungen** (in `views/admin/content/page_form.php`):
- Neue Karte „Seitenübersetzungen" am Ende jeder Edit-Seite (nur bei `$isEdit`)
- Tab je aktiver Nicht-DE-Sprache mit Feldern: Nav-Label, URL-Slug, Browser-Titel, Meta Description, Meta Keywords
- Speichert per `POST /admin/content/i18n/{id}` → Upsert in `cms_pages_i18n` (Slug-Eindeutigkeit wird sichergestellt)
- Neue Route `admin/content/i18n/{id}` + `ContentController::savePageI18n()`
- **Admin-UI: Block-Übersetzungen** (in `views/admin/content/page_form.php`):
- Neuer Übersetzen-Button (`btn-outline-info`, `bi-translate`) je Block in der Block-Liste
- Modal „Block übersetzen" mit Tab je Nicht-DE-Sprache
- Zeigt je Block-Typ nur die übersetzbaren Textfelder: `headline`, `content`, `description`, `btn_text` etc.
- Unterstützt auch Cards-Karten-Array (Titel + Text je Karte) und Slider-Slides (Headline, Text, Button)
- Lädt bestehende i18n-Daten per AJAX `GET /admin/content/block/i18n/get?block_id=X&lang=en`
- Speichert per AJAX `POST /admin/content/block/i18n/save` → Upsert in `cms_blocks_i18n`; Leaf-Values werden serverseitig sanitized
- Neue Routen: `admin/content/block/i18n/get` + `admin/content/block/i18n/save`
- Neue Controller-Methoden: `getBlockI18n()`, `saveBlockI18n()`, `getPageI18nAll()` (privat: `sanitizeI18nData()`)
- **`hreflang`-Tags im `<head>`** (`views/parts/header.php`) — SEO-Pflicht bei Mehrsprachigkeit:
- Für CMS-Seiten: liest `cms_pages_i18n` je `page_id` → erzeugt `<link rel="alternate" hreflang="{lang}" href="...">` für alle konfigurierten Sprachen
- Für Blog-Posts: liest `cms_news_i18n` je `news_id` → gleiches Schema mit `/blog/{slug}`-Pfad
- `x-default` zeigt immer auf die erste Sprache (DE)
- `og:locale` und `inLanguage` in Schema.org-Blöcken jetzt dynamisch aus `CX_LOCALE` (statt hardcodiert `de_DE`)
- Locale-to-OG-Locale Map: `de → de_DE`, `en → en_US`, `fr → fr_FR`, `es → es_ES`
- **coreX MLS — Phase 3 Ergänzungen + Phase 1 Fertigstellung**
- **`views/parts/hero.php`** — Fallback-Strings für Subtitle, Titel und Button-Text jetzt aus `coreX_mls('parts.hero.*')` statt hartkodiertem DE — `/lang/de/parts/hero.json` + `/lang/en/parts/hero.json` angelegt
- **Klaro Cookie-Banner i18n** — Klaro's `translations`-Objekt wird jetzt mit DE + EN Sprachblöcken aus `/lang/de/parts/klaro.json` + `/lang/en/parts/klaro.json` befüllt; `lang`-Key im Klaro-Config-Objekt dynamisch auf `CX_LOCALE`; admin-konfigurierte Texte (Notice, Accept, Decline) fließen in beide Blöcke ein
- **Neue Hilfsfunktion `coreX_mls_for(string $key, array $vars, string $locale): string`** — übersetzt einen Key für eine bestimmte Locale unabhängig von der aktiven Locale (nützlich für Multi-Locale-Rendering im selben Request, z.B. Klaro, hreflang-Labels)
- In `src/Helpers/CoreXMLS.php` als globale Funktion
- In `src/Core/Translator.php` als `getFor(string $key, array $vars, string $locale): string` Methode
- **`window.CX_TRANS` — JS-Übersetzungs-Objekt** — Server rendert globales JS-Objekt mit allen übersetzten JS-Strings in den `<head>`:
- Frontend: `views/parts/header.php` — `window.CX_TRANS = <?= json_encode(coreX_mls_group('js')) ?>;`
- Admin: `views/admin/parts/header.php` — selbes Objekt, locale-aware
- Lang-Dateien: `/lang/de/js.json` + `/lang/en/js.json` (flat, alle JS-sichtbaren Strings)
- Migrierte JS-Strings in: `corey.js` (modeLabels, Kopieren/Kopiert!, Fehlermeldungen), `cx-admin.js` (Gespeichert, Fehler, Netzwerkfehler, Schließen), `block-helpers.js` (blockLabels, bearbeiten-Suffix, kein-Formular), `block-forms.js` (Linke/Rechte Spalte, Links/Rechts, Kein Effekt, Card-Style-Labels, Timeline-Defaults)
- Alle JS-Strings mit `(window.CX_TRANS && CX_TRANS.key || 'DE-Fallback')` für Rückwärtskompatibilität
- **Flash-/Systemmeldungen Infrastruktur** — `/lang/de/messages.json` + `/lang/en/messages.json` angelegt mit allen gängigen System-Meldungs-Keys (`saved`, `deleted`, `error_generic`, `invalid_token`, `fill_required`, `upload_success` etc.); inkrementelle Ablösung der Controller-Strings durch `coreX_mls('messages.key')` läuft
Hinweis
- **Breaking Change behoben**: Alle intern verlinkten Views nutzen jetzt `cx_url()` oder `CX_BASE`. Externe Links und Anker bleiben unberührt. CMS-Block-Inhalte die in der DB gespeicherte Pfade haben (z.B. `/kontakt`) bekommen Locale-Prefix automatisch beim Rendern via `cx_url()`.
Fix
- **Besucher-Tracking**: Admin-Routen (`/admin/*`) werden nicht mehr in `visitor_tracking` gezählt
Neu (Nachtrag 2026-05-02 / 2026-05-03)
- **MLS Phase 4 — DB i18n Starter-Übersetzungen (EN)**
- Migration `000033`: EN-Übersetzungen für alle CMS-Blöcke auf 5 Seiten (Home, About, Impressum, Team, Download) in `cms_blocks_i18n`
- Migration `000034`: EN-Inhalte für 3 News-Artikel in `cms_news_i18n`
- Migration `000035`: `footer_links_i18n` + `footer_flat_links_i18n` Tabellen + EN-Einträge für alle Footer-Navigationspunkte
- Migration `000036`: `revisions_i18n` Tabelle + EN-Übersetzungen für alle 27 Changelog-Einträge (0.3.6 – 0.7.5); label + vollständiges Markdown-Changelog je Version
- Migration `000037`: `site_settings_i18n` Tabelle (generisch, Key-Value mit Locale) + EN Hero-Texte (`hero_subtitle`, `hero_title`, `hero_description`, `hero_btn_text`, alle Highlight-Word-Keys)
- **`ContentController::getNavTree()` i18n-aware** — merged `nav_label` + `slug` aus `cms_pages_i18n` für Nicht-DE-Locales in einem einzigen Query; DE-Fallback bleibt in den Hauptfeldern
- **`views/parts/footer.php` i18n-aware** — Footer-Links (Spalten-Modus) und Flat-Links lesen Label + URL aus `footer_links_i18n` / `footer_flat_links_i18n` mit COALESCE-Fallback
- **`views/content/changelog.php` i18n-aware** — LEFT JOIN auf `revisions_i18n` mit COALESCE(i.label, r.label) + COALESCE(i.changelog, r.changelog); DE-Query bleibt unverändert
- **`views/parts/hero.php` i18n-aware** — lädt bei Locale ≠ `de` alle passenden `site_settings_i18n`-Einträge in einem Query und überschreibt `$siteSettings[$key]` direkt; alle nachfolgenden Hero-Variablen (Subtitle, Titel, Beschreibung, Button, Highlight-Words) greifen automatisch auf die übersetzte Version
- **Captcha: Design-angepasstes Styling**
- `src/Core/Captcha.php`: Liest `input_bg_color`, `input_text_color`, `input_border_color` aus `design_settings` (aktives Design via `site_settings`) — Captcha-Bild passt sich automatisch dem aktiven Design an; neuer privater `hexToRgb()`-Helper (unterstützt `#rgb`, `#rrggbb`, `#rrggbbaa`); Fallback auf bisherige Defaults wenn DB nicht erreichbar
- `views/content/contact.php`: Beide Captcha-Wrapper nutzen jetzt `var(--input-bg)` + `var(--input-border)` + `var(--input-text)` statt hardcoded `bg-dark` / `#dee2e6` / `#333` — konsistentes Layout mit den Formular-Inputs in allen Designs
v0.7.5
02. May 2026
NEU: coreY - Der KI-Assistent von coreX
Neu
- **coreY KI-Assistent** — integrierter KI-Assistent auf Basis von [Ollama](https://ollama.com/) (self-hosted, kein Cloud-Zwang)
- **`CoreYService`** (`src/Services/CoreYService.php`) — Ollama HTTP-Client, liest Konfiguration aus DB, baut System-Prompt mit Website-Kontext (`site_name`, `site_description`, `site_language`), Injection-Schutz via `sanitizeInput()`
- **`CoreYController`** (`src/Controllers/CoreYController.php`) — 3 AJAX-Endpunkte: `POST /admin/corey/chat`, `GET /admin/corey/ping`, `GET /admin/corey/context`; Auth + Permission-Check + CSRF auf jedem Endpunkt
- **5 KI-Modi**: Verbessern, SEO, Meta-Daten generieren, Zusammenfassen, Ideen generieren
- **Right-Aside-Panel** (`views/admin/parts/corey-aside.php`) — aufklappbares Panel rechts im Admin, mit Modus-Tabs, Textarea, Zeichenzähler, Copy-Button, Live-Statusanzeige (Ping)
- **Begrüßungsnachricht** beim ersten Panel-Öffnen: coreY liest `site_name` + `site_description` aus DB und zeigt personalisierte Willkommensnachricht
- **Toggle-Button in der Admin-Topbar** (lila Kreis mit „C" + Label „coreY") - wird noch ersetzt durch das coreY-Icon
- **`corey.css`** + **`corey.js`** — eigenständige Assets, nur geladen wenn coreY aktiv
- **Permission** `admin.corey.use`
- **`site_description`-Feld** in Verwaltung → Konfiguration — Kurzbeschreibung der Website für coreY-Kontext
- **Migration**
Infrastruktur
- coreY läuft auf einem abgesicherten Self-hosted Server.
v0.7.0
30. April 2026
NEU: Forum-System + Änderungen
Neu
- **Forum-System** komplett neu: Kategorien → Foren → Threads → Posts (klassische 4-Ebenen-Struktur)
- **`forum_categories`**, **`forum_forums`**, **`forum_threads`**, **`forum_posts`**, **`forum_user_bans`** — 5 neue DB-Tabellen
- **Forum-Permissions**: `admin.forum.manage`, `forum.post`, `forum.threads.close`, `forum.posts.delete`, `forum.threads.move`, `forum.threads.pin`, `forum.users.ban`
- **Neue Rolle: `forum_moderator` (Forum-Moderator)** mit Permissions: `forum.post`, `forum.threads.close`, `forum.posts.delete`, `forum.threads.move`, `forum.threads.pin`, `forum.users.ban`
- **`ForumAdminController`** — CRUD für Kategorien und Foren (inkl. Reihenfolge, Leserechte, Toggle, Delete)
- **`ForumFrontendController`** — Übersicht, Thread-Liste, Thread-Ansicht, Antworten, Moderations-Aktionen
- **Admin-View `views/admin/forum.php`** — Verwaltungsseite mit Modals, Inline-Bearbeitung
- **Frontend-Views** (`views/forum/`): `index.php`, `threads.php`, `thread.php`, `new-thread.php`, `forbidden.php`
- **Frontend-Routen** `/forum`, `/forum/f/{id}`, `/forum/t/{id}`, `/forum/t/{id}/reply`, Moderations-Endpunkte
- **Migration** `database/migrations-webserver/2026_04_30_000028_forum.sql`
- **FileScanner** — verbesserte Ausschlussregeln: `database/migrations-webserver/` explizit whitelisted, Root-Dateien komplett ausgeschlossen, `IGNORE_PATHS` für Entwickler-only Views/Controller eingeführt
Geändert
- Rolle `moderator` → umbenannt zu **`Blog-Moderator`** (DB-Label)
- Admin-Sidebar: Forum-Eintrag im Content-Submenu (sichtbar bei `admin.forum.manage`)
- `public/index.php`: `ForumAdminController` + `ForumFrontendController` instantiiert und ans Routing übergeben
v0.6.94
30. April 2026
Änderungen + Fixes
Geändert
- **`public/robots.txt`**: Physische Datei in `public/` mit sauberer Struktur — alle Suchmaschinen, SEO-Tools und KI-Assistenten erlaubt; bekannte bösartige Scraper, Scanner, Email-Harvester und Exploit-Tools geblockt (`nikto`, `sqlmap`, `HTTrack`, `EmailCollector` etc.)
- **`LogoUploadService` → `ImageUploadService`**: Klasse, Datei (`src/Services/ImageUploadService.php`) und alle Referenzen in `SettingsController` umbenannt — der Service verwaltet nicht nur das Logo, sondern auch Admin-Hintergrundbilder
- **`ImageUploadService::saveAdminBackground()`**: Regex erweitert von `\.png` auf `\.(png|jpg|jpeg|webp)` — Admin-Hintergrundbilder können jetzt in allen gängigen Formaten hinterlegt werden
Fix
- **CSP `script-src-attr`-Violations** (aiqia.de): Footer-Links (Flat-Modus) und Social-Icons hatten `onmouseover="this.style.opacity='1'"` / `onmouseout="this.style.opacity='.75'"` als inline HTML-Attribute — durch CSS-Klassen `cx-foot-link` / `cx-foot-social` mit `:hover`-Regeln ersetzt
- **CSP `script-src-attr`-Violations** (Wartungsseite): Admin-Login-Link in `views/content/maintenance.php` hatte ebenfalls `onmouseover`/`onmouseout` — durch CSS-Klasse `cx-maint-admin-link` ersetzt
Ergebnis - Mozilla Observatory Score - vorher → nacher
- Mozilla Observatory Score: von 0/100 → 130/100
v0.6.93
30. April 2026
NEU: HTTP Security Headers + Fixes
Neu
- **HTTP Security Headers**: `public/index.php` sendet jetzt bei jedem Request folgende Header: `X-Content-Type-Options: nosniff`, `X-Frame-Options: DENY`, `Referrer-Policy: strict-origin-when-cross-origin`, `Cross-Origin-Resource-Policy: same-origin`, `Permissions-Policy: geolocation=(), microphone=(), camera=()`
- **HSTS**: `Strict-Transport-Security: max-age=63072000; includeSubDomains` wird automatisch gesetzt wenn HTTPS erkannt wird (lokal nicht aktiv)
- **Content Security Policy**: Vollständige CSP-Allowlist für alle genutzten CDNs (Bootstrap, Font Awesome, Animate.css, AOS, Swiper, CodeMirror, Klaro, Leaflet/OpenStreetMap, Google Fonts, reCAPTCHA). Wurde über `Content-Security-Policy-Report-Only` getestet bevor scharf gestellt
- **Subresource Integrity (SRI)**: Alle 24 externen CDN-Ressourcen in `views/parts/header.php`, `views/parts/footer.php`, `views/admin/parts/header.php` und `views/admin/parts/footer.php` haben jetzt `integrity="sha384-..."` + `crossorigin="anonymous"` Attribute — verhindert Manipulation durch CDN-Kompromittierung
- **Swiper auf exakte Version gepinnt**, Voraussetzung für stabile Subresource-Integrity-Hashes.
Fix
- **`cookie_secure`**: Session-Cookie setzt das `Secure`-Flag nun dynamisch wenn HTTPS aktiv ist.
v0.6.92
24. April 2026
NEU: WebP-Konvertierung beim Upload + Fixes
Neu
- **WebP-Konvertierung beim Upload**: `MediaController::upload()` konvertiert JPEG/PNG automatisch zu WebP (Qualität 82) und löscht das Original. Resultat: ~78% weniger übertragene Daten, Ladezeit halbiert (670 ms → 322 ms)
- **Automatisches Resize auf 1920px**: Bilder breiter als 1920px werden proportional auf Full-HD herunterskaliert — verhindert, dass unerfahrene User unkomprimierte Hochlösung-Fotos (6–10 MB) hochladen
- **Upload-Limit auf 20 MB erhöht**: Da das Original nach WebP-Konvertierung stark schrumpft, wurde das Limit angehoben damit auch große RAW-Fotos ankommen
Fix
- **`file_size` in DB**: Wird nun nach der WebP-Konvertierung via `filesize()` ermittelt — spiegelt die tatsächliche Dateigröße wider, nicht die des Original-Uploads
- **Mediathek 0 Dateien**: Namenskonflikt einer internen Variable verhinderte die korrekte Anzeige der Mediathek — korrigiert.
- **Mediathek Sync-Button**: Neuer „Sync"-Button in der Mediathek-Toolbar. Scannt `public/assets/img/uploads/` und importiert per FTP/direkt kopierte Dateien die noch nicht in `media_files` registriert sind (`MediaController::scan()`, Route `admin/media/scan`)
- **Blog Header-Bild**: Leerer-Zustand-Branch (`empty($posts)`) ignorierte `$page['header_image']` — jetzt beide Branches (leer + mit Posts) unterstützen das Header-Bild aus dem Content Manager
- **Profil-Seite Header-Bild**: `PageRenderer` lud `profile.php` ohne `$page` zu setzen. Jetzt analog zu `technical` und `changelog` via `$cmsCtrl->getPageBySlug('profile')`. Hardcodiertes Hintergrundbild entfernt, `$page['header_image']` wird verwendet
v0.6.91
23. April 2026
Fixes
Fix
- **Button Palette: Buttons wurden nicht angezeigt** — `ButtonPaletteController::index()` übergab `$buttons` nicht ans View. `$buttons ?? []` griff auf leeres Array zurück. Behoben: `$buttons = $this->manager->getAll($theme)` wird jetzt vor dem View-Include geladen
- **Button Palette: Timestamp-Dateiname** — Generierte CSS-Datei heißt jetzt `buttons-{timestamp}.css` statt fest `buttons-generated.css`. Filename wird in `site_settings` (`buttons_css_file`) gespeichert, `header.php` liest ihn dynamisch. Alte Datei wird beim nächsten Speichern automatisch gelöscht → Updates können die Datei nicht mehr überschreiben
- **Parallax-Blöcke (text, two_col, blog-post)**: Hintergrund-Div hatte `inset:0` — bei `translateY()`-Verschiebung wurden Ränder freigelegt. Behoben mit `top:-120px; bottom:-120px` statt Prozentwerten (Prozentwerte funktionierten nicht bei `height:auto`-Sections)
- **Footer `REQUEST_URI`**: `basename($_SERVER['SCRIPT_NAME'])` gibt immer `index.php` zurück (Single-Entry-Point-Router). Ersetzt durch `$_currentPath = strtok($_SERVER['REQUEST_URI'], '?')` für korrekte Seiten-Erkennung
- **Versionen-Admin**: Eingabefeld für Versionsnummer war `col-md-2` (zu schmal), `pattern`-Attribut ergänzt (`[0-9]+\.[0-9]+(\.[0-9]+)*`) — erlaubt jetzt 4-stellige Versionen wie `0.6.91`
v0.6.9
23. April 2026
Cards Admin-Seite + Änderungen
Neu
- **Cards Admin-Seite** (`/admin/cards`): Neues Admin-Modul unter Layout → Cards zum Einstellen aller Card-Effekte pro Theme. Einstellbar: Hintergrund-Transparenz, Border-Opazität, Border-Radius, Padding, Backdrop-Blur, Hover-Effekte (TranslateY, Rotation, Schatten), Übergangs-Dauer und Easing-Kurve. Live-Vorschau im Admin.
- **`corex-cards.css`**: Neue designabhängige CSS-Datei mit allen Card-Stilen (aus `corex-custom.css` ausgelagert). Alle Effekte werden via CSS-Variablen (`--card-*`) gesteuert, die `corex-dynamic.php` aus `design_settings` liest.
- **12 neue `card_*`-Keys** in `design_settings` für alle 4 Themes. Migration `2026_04_22_000027_card_settings.sql`.
Geändert
- **`corex-custom.css`**: Alle card-bezogenen Styles auskommentiert (nach `corex-cards.css` verschoben).
- **`corex-dynamic.php`**: Liest jetzt alle 12 `card_*`-Keys und schreibt CSS-Variablen in `:root`.
- **Inline-Styles auskommentiert** in `features.php`, `technical.php`, `changelog.php` (Vorbereitung für globales Stylesheet).
v0.6.89
23. April 2026
Button Palette + Änderungen
Neu
- **Button Palette** (`/admin/buttons`): Neues Admin-Modul zum Erstellen, Bearbeiten und Löschen eigener CSS-Buttons pro Theme. Eigenschaften: Hintergrundfarbe + Verlauf, Textfarbe, Schriftgröße, Border, Border-Radius, Schatten, Glow, Glasmorphismus, Hover-Effekt, Padding für sm/md/lg. Speichern schreibt `public/assets/css/buttons-generated.css` (statische Datei, wird im Frontend eingebunden).
- **Erweiterte `.btn-eyecatcher`-Steuerung**: Alle 4 Theme-Dynamic-CSS-Dateien (`corex`, `universe`, `light_blue`, `solaris`) lesen jetzt `btn_ec_*`-Keys aus `design_settings` und rendern den vollständigen `.btn-eyecatcher`-Block inkl. `:hover`, `btn-sm`, `btn-lg`, Schatten, Glow, Glasmorphismus und Padding.
- **Neue DB-Tabelle `button_palette`**: Speichert Custom-Buttons pro Theme als JSON. Migration `2026_04_21_000020_button_palette.sql`.
- **Neue `design_settings`-Keys** (`btn_ec_*`): Defaults für alle 4 Themes in Migration `2026_04_21_000021_btn_ec_defaults.sql`.
Geändert
- `views/parts/header.php`: Bindet `assets/css/buttons-generated.css` im Frontend ein.
- `.btn-outline-eyecatcher` + `.btn-futuristic`: Aus den `*-custom.css`- und `*-dynamic.php`-Dateien entfernt — werden jetzt ausschließlich über die Button Palette verwaltet.
v0.6.88
23. April 2026
Content Manager: Block-Layer-Auswahl + Änderungen + Fixes
Neu
- **Content Manager: Block-Layer-Auswahl**: Hero-Banner-, Cards- und Slider-Blöcke haben jetzt eine eigene Layer-Option (Dark / Light / Kein Layer). Bisher war bei gesetztem Hintergrundbild immer ein Dark-Layer hardcodiert. Neue Radio-Buttons im Admin, Validierung in `ContentController::extractBlockData()`, Ausgabe in `views/blocks/hero.php` und `views/blocks/cards.php` dynamisch per `overlay-dark` / `overlay-light`-Klasse
- **Content Manager: Card-Animations-Effekt pro Karte**: Jede Karte im Cards-Block hat jetzt ein eigenes Animations-Dropdown (AOS: ↑ Fade Up, ↓ Fade Down, ← Fade Links, → Fade Rechts, Einblenden, Zoom In/Out, Flip Links/Rechts, Slide Up/Down, Keine Animation). Das Select erscheint links vom Löschen-Button in jeder Card-Zeile. `syncCards()` serialisiert das `animation`-Feld mit, Frontend liest es in allen 3 Card-Styles aus
Geändert
- **`ContentController::extractBlockData()`**: `hero`-Case ergänzt um `bg_layer`, `cards`-Case ergänzt um `bg_layer`, `slider`-Case ergänzt um `layer` (war im Admin-UI bereits vorhanden, wurde aber nie gespeichert)
- **`views/blocks/hero.php`**: `$hasOverlay` + hardcodiertes `overlay-dark` ersetzt durch `$bgLayer`-Variable (default `'dark'` für Rückwärtskompatibilität)
- **`views/blocks/cards.php`**: Analog zu Hero — dynamischer Layer, alle 3 Card-Styles lesen `$card['animation']` mit Allowlist-Validierung, Fallback `fade-up`
- **`views/admin/content/page_form.php`**: Layer-Radios in Hero-Formular und Cards-Formular (Parallax-Row + neue Layer-Row, beide per `oninput` ein-/ausblendbar); `cardRow()` + `syncCards()` um `animation`-Feld erweitert
Fix
- **Slider Layer**: Der Layer-Select im Slider-Formular wurde zwar angezeigt, der Wert aber nicht in `extractBlockData()` gespeichert — behoben
v0.6.83
21. April 2026
Hero Editor: Textfarben + Änderungen + Fixes
Neu
- **`Hero Editor: Textfarben`**: Für Kicker, Titel und Beschreibung kann im Hero-Editor jeweils eine individuelle Textfarbe gesetzt werden (`hero_subtitle_color`, `hero_title_color`, `hero_desc_color`). Die Farbe wird als inline `style="color:…"` direkt am jeweiligen Element ausgegeben — kombiniert mit einer eventuell gesetzten Schriftgröße in einem einzigen `style`-Attribut
- **Hero Editor: Highlight-Wörter**: Für Kicker, Titel und Beschreibung kann eine kommagetrennte Liste von Wörtern angegeben werden, die im Frontend automatisch in einer wählbaren Farbe hervorgehoben werden (`hero_subtitle_highlight_words`, `hero_subtitle_highlight_color` etc.). Die Wörter werden im bereits HTML-kodierten String per Regex gesucht und in `<span style="color:…">` eingebettet. Highlight-Farbe-Standard: `#e87b00`
- **Colorpicker: Alpha/Transparenz-Unterstützung**: Alle `<input type="color">`-Felder im Admin werden jetzt vollständig alpha-fähig. `cxAddAlphaSupport()` in `cx-admin.js` baut unter jedem Chip einen Schieberegler mit Checkerboard-Hintergrund auf. Der gespeicherte Wert ist 8-stelliges Hex (`#rrggbbaa`). Alle 4 Theme-Dynamic-PHP-Dateien und Nav/Mobile-Nav-Files akzeptieren das neue Format
- **Colorpicker: Viewport-Erkennung**: Color-Chips die sich nahe am unteren Seitenrand befinden, öffnen das Popup nach oben statt nach unten — verhindert Abschneiden des Pickers
- **Admin `cx-admin.js` Cache-Busting**: Script-Tag in `views/admin/parts/footer.php` nutzt jetzt `filemtime()` als Query-String — Browser lädt immer die aktuelle Version
Geändert
- **`HeroSettingsService::save()`**: 9 neue Keys — `hero_subtitle_color`, `hero_subtitle_highlight_words`, `hero_subtitle_highlight_color` und Äquivalente für `title` + `desc`. Farben via `SettingsSanitizer::sanitizeColor()`, Texte via `sanitizeText()` (max. 500 Zeichen)
- **`views/parts/hero.php`**: `$_heroSubtitleFs` / `$_heroTitleFs` / `$_heroDescFs` (reine Größen-Style-Strings) ersetzt durch `$_buildStyle($px, $color)` — kombiniert `font-size` und `color` in einem Attribut. `$_titleHtml()`-Closure erhält zusätzlich `$highlightWords`, `$highlightColor` und `$_applyHighlight` als Parameter und gibt den fertigen HTML-String mit eingebetteten Highlight-Spans zurück
- **Colorpicker: Native OS-Dialog-Fix**: `cxEnhanceColorPicker()` entfernt Bootstrap-Klassen `form-control`, `form-control-color`, `w-100` vom Input — verhinderte auf Nav/Mobile-Nav-Seiten das Öffnen des nativen OS-Pickers
Fix
- **Colorpicker: Alpha-Slider verdeckt**: `.c-chip input[type=color]` hatte `inset:0` als Positionierung, das den Alpha-Schieberegler unter dem Chip überlagerte. Fix: Regel auf `.c-chip > input[type=color]` (Pre-JS-Fallback, nur Swatch-Höhe) und `.c-chip .c-swatch input[type=color]` (nach JS-Umbau, `inset:0` korrekt gescoped) aufgeteilt
- **Colorpicker: Alpha-Wert beim Speichern**: Submit-Time-Sync-Schleife in `cxAttachAjax` (cx-admin.js) stellt sicher, dass der 8-stellige Hex-Wert des Hidden-Inputs direkt vor dem Absenden nochmals aus aktuellem RGB + Alpha-Slider-Position berechnet wird — verhindert veraltete Werte bei schnellem Absenden
v0.6.8
21. April 2026
Erweiterungen + Änderungen + Fixes
Neu
- **Content Manager: Block-Layer-Auswahl**: Hero-Banner-, Cards- und Slider-Blöcke haben jetzt eine eigene Layer-Option (Dark / Light / Kein Layer). Bisher war bei gesetztem Hintergrundbild immer ein Dark-Layer hardcodiert. Neue Radio-Buttons im Admin, Validierung in `ContentController::extractBlockData()`, Ausgabe in `views/blocks/hero.php` und `views/blocks/cards.php` dynamisch per `overlay-dark` / `overlay-light`-Klasse
- **Content Manager: Card-Animations-Effekt pro Karte**: Jede Karte im Cards-Block hat jetzt ein eigenes Animations-Dropdown (AOS: ↑ Fade Up, ↓ Fade Down, ← Fade Links, → Fade Rechts, Einblenden, Zoom In/Out, Flip Links/Rechts, Slide Up/Down, Keine Animation). Das Select erscheint links vom Löschen-Button in jeder Card-Zeile. `syncCards()` serialisiert das `animation`-Feld mit, Frontend liest es in allen 3 Card-Styles aus
Geändert
- **`ContentController::extractBlockData()`**: `hero`-Case ergänzt um `bg_layer`, `cards`-Case ergänzt um `bg_layer`, `slider`-Case ergänzt um `layer` (war im Admin-UI bereits vorhanden, wurde aber nie gespeichert)
- **`views/blocks/hero.php`**: `$hasOverlay` + hardcodiertes `overlay-dark` ersetzt durch `$bgLayer`-Variable (default `'dark'` für Rückwärtskompatibilität)
- **`views/blocks/cards.php`**: Analog zu Hero — dynamischer Layer, alle 3 Card-Styles lesen `$card['animation']` mit Allowlist-Validierung, Fallback `fade-up`
- **`views/admin/content/page_form.php`**: Layer-Radios in Hero-Formular und Cards-Formular (Parallax-Row + neue Layer-Row, beide per `oninput` ein-/ausblendbar); `cardRow()` + `syncCards()` um `animation`-Feld erweitert
Fix
- **Slider Layer**: Der Layer-Select im Slider-Formular wurde zwar angezeigt, der Wert aber nicht in `extractBlockData()` gespeichert — behoben
v0.6.7
20. April 2026
Hero: Schriftgröße pro Textfeld + Änderungen + Fixes
Neu
- **Hero: Schriftgröße pro Textfeld**: Im Hero-Editor kann für Kicker, Titel und Beschreibung jeweils eine individuelle Schriftgröße in px eingestellt werden (8–200 px). Das Eingabefeld erscheint direkt rechts neben dem Textfeld als `input-group` mit Fontsymbol. Wird kein Wert gesetzt, greift das bisherige CSS ohne inline-Style
- **Cards-Block Style 3 (Icon Links)**: Neuer Kartenstil im Content Manager — Icon links, Titel und Text rechts daneben (horizontal). Eigene CSS-Klassen `.cx-card3-item`, `.cx-card3-icon`, `.cx-card3-title`, `.cx-card3-text` in `cx-global.css`. Der Stil wird über einen 3-Button-Tab-Group-Picker (Style 1 / 2 / 3) im Block-Editor gewählt
- **Design-Einstellung `input_focus_color`**: Neue Farbeinstellung in den Design-Optionen — steuert die Fokus-Farbe von Formular-Inputs (`--input-focus-color`). Integration in alle 4 Themes (`corex`, `universe`, `solaris`, `light_blue`). Migration `2026_04_19_000020_input_focus_color.sql`
- **Setup-Wizard: Passwort-Stärke-Prüfung**: Beim Erstellen des Admin-Kontos werden jetzt Mindestanforderungen erzwungen (Großbuchstabe, Kleinbuchstabe, Ziffer, Sonderzeichen). Server-seitige Validierung per Regex; client-seitige Live-Anzeige mit 4 grün/rot-Indikatoren unter dem Passwortfeld
Geändert
- **`HeroSettingsService`**: Speichert 3 neue Keys — `hero_subtitle_size`, `hero_title_size`, `hero_description_size` (Integer, geclampt auf 8–200)
- **`views/parts/hero.php`**: Liest Schriftgrößen und setzt inline `style="font-size:Xpx"` an Kicker `<span>`, `<h1>` und Beschreibungs-`<p>` in allen 3 Layout-Varianten (Cinematic / Split / Centered). Kein Style-Attribut wenn Wert leer
Fix
- **`UserController::save()`**: Passwort-Fallback auf `'Secret123!'` bei leerem Passwortfeld entfernt — neues Passwort ist beim Anlegen eines Nutzers jetzt Pflicht. Fehlender `email_verified_at = NOW()`-Eintrag ergänzt (verhinderte Frontend-Login für admin-erstellte Accounts). `PASSWORD_DEFAULT` → `PASSWORD_BCRYPT`. `catch (\Exception)` → `catch (\Throwable)`
- **`AuthController`**: Alle 6 `catch (\Exception)`-Blöcke auf `catch (\Throwable)` erweitert — Error-Subklassen (z. B. `TypeError`) wurden zuvor nicht abgefangen
v0.6.6
18. April 2026
NEU: "Kontaktformular im Header"-Modus + Fixes + Änderungen
Neu
- **Kontaktseite: "Formular im Header"-Modus**: Neues Toggle im Admin (`/admin/contact-page` → Header-Tab). Wenn aktiv, wird das Kontaktformular direkt im Hero-Bereich links im Split-Layout eingebettet — rechts nur noch Headline und Teaser. Kein separater Formular-Abschnitt unterhalb. Funktioniert auch ohne Hintergrundbild
- **Adressblock unterhalb des Heros**: Im "Formular im Header"-Modus werden Adresse, Telefon, E-Mail und Antwortzeit in einer 4-spaltigen Icon-Box-Reihe unterhalb des Heros ausgegeben — über der Karte falls aktiviert
- **Migration** `2026_04_18_000025_contact_form_in_header.sql`: Neuer `site_settings`-Eintrag `contact_form_in_header`
Geändert
- **`PageRenderer::renderFull()` / `render()`**: `$siteSettings`-Array wird jetzt als Parameter weitergegeben, sodass alle `php_file`-Templates (contact.php, blog.php, datenschutz.php …) Zugriff auf die DB-Einstellungen haben. Zuvor liefen alle auf Defaults, weil der Scope der statischen Methode `$siteSettings` aus `views/index.php` nicht sah
- **Fetch-Interceptor** (`views/admin/parts/header.php`): `X-Requested-With`-Header wird jetzt nur noch bei Same-Origin-Requests gesetzt. Externe API-Calls (z. B. Nominatim-Geocoding) lösen keinen CORS-Preflight mehr aus
- **Leaflet CDN**: `integrity`-Attribute aus Leaflet CSS/JS-Tags entfernt — Hash stimmte nicht mehr mit aktuellem unpkg-Content überein (`L is not defined`-Fehler behoben)
- **Kontaktseite Hero-Karte glassmorphism**: Formular-Card passt sich dem Hintergrund an — ohne Bild transparent/unstyled, mit Bild helles Weiß-Glas statt dunklem Panel
- **Admin: Höhen-Select** (`contact_header_height`): `(string)$_hv`-Cast ergänzt — numerische Array-Keys wurden von PHP zu `int` konvertiert, wodurch `===`-Vergleich mit dem String aus der DB immer `false` war und die Selectbox stets „Vollbild" anzeigte
Fix
- **Kontaktseite**: Settings (`contact_form_in_header`, Höhe, Layer, Bild) wurden nicht korrekt übernommen, weil `$siteSettings` im `php_file`-Template-Scope fehlte
v0.6.5
18. April 2026
Top Navbar — Farben & Stil + Änderungen + Fixes
Neu
- **Top Navbar — Farben & Stil** (`/admin/navigation`): Unterhalb des Layout-Pickers neuer Formularblock. Hintergrund-Typ (Transparent / Farbe / Blur-Glas), Hintergrundfarbe, Rahmenfarbe (untere Trennlinie, optional), Schatten-Stärke (Kein / Klein / Mittel / Groß) und Link-Farben (Normal, Hover, Akzent/Glow) direkt einstellbar. Alle Werte werden als inline `<style>` auf `.navbar` angewendet — ohne Theme-Anpassung notwendig
- **Kontaktseiten-Adminbereich** (`/admin/contact-page`): Neuer Admin-Bereich mit 3 Tabs — Header (Mediathek-Picker, Typ, Layer, Höhe), Karte (Leaflet-Map, Lat/Lng/Zoom aktivierbar) und Einstellungen (Adresse, Telefon, E-Mail, Antwortzeit). Einstellungen werden in `site_settings` gespeichert
- **Kontaktseite Frontend dynamisch**: `views/content/contact.php` liest alle `contact_*`-Settings aus der DB. Header mit Bild/Video/Layer/Höhe; Info-Spalte mit Adresse, Telefon, E-Mail, Antwortzeit; optionale Leaflet-Karte (CDN, OpenStreetMap) mit Marker und Adress-Popup
- **Timeline/Roadmap-Block: Farben & Glow**: Im Content Manager können für jeden Timeline-Block die Farbe der vertikalen Linie und der Kreise individuell eingestellt werden. Checkbox "Glow-Effekt" lässt die Kreise in der gewählten Kreisfarbe schimmern (box-shadow)
- **Migration** `2026_04_17_000021_contact_settings.sql`: 17 neue `site_settings`-Einträge für Kontaktseite
- **Migration** `2026_04_18_000022_desktop_nav_settings.sql`: 7 neue `site_settings`-Einträge für Desktop-Navbar
Geändert
- **Navigation Admin** (`/admin/navigation`): Sidebar-Eintrag bleibt unter Layout; Seite erweitert um Desktop-Navbar-Formular (Hintergrund, Farben, Rahmen, Schatten)
- **Sidebar**: Neuer Eintrag "Kontaktseite" unter Content-Submenu (`bi-telephone`)
- `views/blocks/timeline.php` und `extractBlockData()` in `ContentController`: Neue Keys `line_color`, `dot_color`, `dot_glow` — bestehende Blöcke ohne diese Felder behalten Default-CSS-Verhalten
Fix
- **Footer Manager** `FooterManager::sanitizeUrl()`: Regex-Delimiter-Konflikt behoben (`#` als Delimiter kollidierte mit `#`-Ankern in URLs) → Delimiter geändert auf `~`
- **Footer Admin** `views/admin/footer.php`: `setFooterMode()`-Funktion war referenziert aber nie definiert → neue `applyFooterMode()`-Funktion ersetzt kaputten onclick-Handler
- **Footer Frontend** `views/parts/footer.php`: Flat-Mode renderte kein korrektes Layout → jetzt als Bottom-Bar (Copyright links, Links Mitte, Social rechts)
v0.6.4
17. April 2026
Änderungen + Fixes
Neu
- **Footer Manager** (`/admin/footer`): Eigener Admin-Bereich mit 3 Tabs — Navigation (Spalten & Links), Social Icons, Einstellungen. Vollständig AJAX-basiert, kein Seitenreload beim Speichern
- **Social Icons im Footer**: Neue Tabelle `footer_socials` (Migration `2026_04_17_000019_footer_socials.sql`). 20+ vorbelegte Plattformen (Twitter/X, GitHub, LinkedIn, Discord, Instagram, YouTube, TikTok, Twitch, Reddit, Pinterest, Mastodon, Vimeo, Spotify, Behance, Dribbble & mehr). Jeder Eintrag hat Icon-Klasse, URL, Aktivierungs-Toggle. Anpassbarer Display-Name und Icon-Override
- **Frontend Social Icons dynamisch**: `views/parts/footer.php` liest `footer_socials` direkt aus DB — keine hardcodierten Social-Links mehr; fontawesome `fab`-Icons ersetzt durch Bootstrap Icons
- **Icon-Picker: Gruppen-Tabs**: Beim Öffnen des Icon-Pickers werden automatisch alle Kategorien als Filter-Pills generiert (Alle / ⭐ Beliebt / 🏢 Business / 💻 Technologie / 📄 Dokumente / 🎨 Design & Medien / 💬 Kommunikation / 👤 Personen / 🗺️ Navigation / 🔒 Sicherheit / ⚙️ System / 🌟 Symbole / 📱 Social Media). Suche und Gruppen kombinierbar
- **Icon-Bibliothek massiv erweitert**: 1.200+ Icons in 13 kategorisierten Gruppen statt zuvor ~60 Icons in einer flachen Liste
Geändert
- **Content Manager** (`/admin/content`): Footer-Verwaltungsbereich entfernt — jetzt unter `/admin/footer`. Seite zeigt nur noch die Seiten-Tabelle
- **Sidebar**: Neuer Eintrag "Footer" unter Layout-Submenu (`bi-layout-sidebar-inset-reverse`)
- **Icon-Picker**: Doppelter `selectIcon`-Code entfernt; `pickIcon`-Funktion ersetzt `selectIcon`; Grid-Höhe auf 360px begrenzt und scrollbar
Fix
- Icon-Picker: Orphan-Code (duplizierter Template-Literal-Block nach `renderIconPickerModal`) entfernt — verhinderte korrekte Icon-Auswahl in Karten-Blöcken
- `/admin/content`-Formulare: AJAX nicht aktiv gewesen → Umleitung nach `/admin/config` behoben (`data-cx-ajax` ergänzt)
v0.6.3
17. April 2026
Setup-Wizard + Änderungen
Neu
- **Setup-Wizard** (`/install/`): Vollständiger 4-Schritt-Installations-Assistent. Schritt 1: Server Check (PHP-Version, MySQLi, PDO, Schreibrechte), Schritt 2: Datenbankverbindung + Websitename + optionaler APP_BASE-Pfad, Schritt 3: Admin-Konto (Benutzername, Name, E-Mail, Passwort), Schritt 4: Installation (SQL-Import, Admin-User-Erstellung, `.env`-Generierung, Lock-Datei). Dark Space Glassmorphism Design, responsiv
- **Install-Redirect** in `public/index.php`: Fehlt `.installed`, wird automatisch auf `/install/` weitergeleitet — kein manuelles Setup-Aufrufen nötig
- **Slider-Block: Layer-Option**: Neue globale Einstellung im Slider-Editor — Auswahl zwischen "Dark Layer", "Light Layer" und "Kein Layer". Gesteuert über `$d['layer']` in `slider.php`
Geändert
- `MediaController::upload()`: URL-Antwort korrigiert — `/public/assets/img/uploads/` → `/assets/img/uploads/` (Web-Pfad stimmte nicht mit Dateisystem-Pfad überein)
- `PageRenderer.php`: Block-Loop übergibt jetzt `$_blockSectionClass` (alternierend `section-1`/`section-2`) an jeden Block-Template
- Block-Templates: `text.php`, `two_col.php`, `timeline.php`, `cards.php` nutzen jetzt `$_blockSectionClass` — Sektion-Hintergrundfarben aus den Design-Einstellungen werden korrekt angewendet. `cta.php`, `slider.php`, `hero.php` bleiben unverändert (eigene Hintergründe)
v0.6.2
17. April 2026
Design-Manifest-System + Fixes
Neu
- **** (`manifest.json` pro Design in `assets/css/{design}/`): Deklariert Fonts, externe CSS/JS-Abhängigkeiten (Head + Body), CSS-Dateiliste, Dynamic-CSS/JS und JS-Dateiliste. Ermöglicht Custom-Designs ohne hardcodierten PHP-Code
- **Dynamic JS pro Design** (`{design}-dynamic.js.php` in `assets/js/{design}/`): Gibt DB-gespeicherte Design-Variablen als `window.CX_DESIGN`-Objekt aus — verfügbar für alle Design-JS-Dateien. Manifest-Key: `dynamic_js`
- **cx-global.css**: Zentrale design-agnostische Strukturstyles — `overflow-x:hidden`, `.layer-dark`, `.devider-line-short`, Mobile-Nav-Hide, Roadmap/Timeline-Layout, vollständiger Klaro Cookie-Banner Mobile-Fix
- **Navigations-Adminseite** (`/admin/navigation`): Eigene Seite für das Nav-Layout, ausgelagert aus dem Content Manager — erreichbar über Sidebar unter Content → Navigation
- Design-Assets in Unterordner aufgeteilt: `assets/css/{design}/` und `assets/js/{design}/`
- Font-Loading aus Manifest statt hardcodiertem if/elseif pro Design
- jQuery (Universe) wird über Manifest-Eintrag `head.external_js` deklariert — kein hardcodierter Check mehr
Geändert
- **Admin-Designs-Seite** (`/admin/designs`): Zeigt jetzt Infos aus `manifest.json` — Name, Version, Autor, Beschreibung, Tags, Mode, Fonts-Anzahl, jQuery-Abhängigkeit, Dynamic JS. DesignController scannt automatisch alle installierten Designs
- **Content Manager**: Nav-Layout-Picker entfernt (→ eigene Nav-Seite)
- `header.php`: Liest fonts, external_css, external_js (head) und CSS-Dateiliste vollständig aus Manifest — kein Glob mehr, kein altes `universe-manifest.json`
- `footer.php`: Liest dynamic_js, JS-Dateiliste und body.external_js aus Manifest — kein Glob mehr
- Design-CSS-Dateien: Duplizierte Styles (Roadmap, Klaro, Mobile-Nav-Hide, devider-line) in cx-global.css ausgelagert
Fix
- Designs-Seite: "Aktivieren"-Button aktualisiert jetzt das aktiv-Badge korrekt (Page-Reload nach AJAX via `data-cx-reload`)
- Admin-Benutzer-Seite: `$ is not defined`-Fehler behoben — jQuery-Abhängigkeit durch Vanilla JS ersetzt
v0.6.1
15. April 2026
Several fixes
Fix
- Nav-Layout-Karte im Content Manager zeigt jetzt einheitlich ein grünes "aktiv"-Badge (wie Hero-Editor)
- Nav-Layout-Speichern nutzt jetzt den einheitlichen Toast statt altem internen Hinweis-Div
- Header-Hintergrundbild wird nun korrekt auf `php_file`-Seiten (z.B. Blog) angezeigt
- User-Dropdown im Sidebar-Layout (nav-layout-3) öffnet jetzt nach oben statt aus dem Viewport zu verschwinden
- Mediathek-Picker im Content Manager (Header-Image) öffnete altes Browser-Popup — jetzt einheitliches Modal
v0.6.0
15. April 2026
AdminArea-AJAX-Migration + coreX script optimizations + Subpages-Header-BG + Fixes
Neu: Vollständige AJAX-Migration des Admin-Bereichs
- Alle Admin-Formulare nutzen jetzt AJAX — keine Seiten-Neulads mehr beim Speichern
- Neues Toast-Benachrichtigungssystem (`cx-toast`) mit BEM-Klassen für Erfolg, Fehler, Warnung, Info
- Neue gemeinsame Admin-JS-Datei `public/assets/admin/js/cx-admin.js` mit Form-Interceptor & Toast-Engine
- `AjaxResponse`-Helper in `src/Core/` für einheitliche JSON-Antworten (`ok()`, `error()`, `isAjax()`)
- `data-cx-ajax` — Opt-in-Attribut für Formulare
- `data-cx-confirm="..."` — Bestätigungsdialoge als Attribut (ersetzt `onsubmit="return confirm()"`)
- `data-cx-reload` — Seite nach Erfolg neu laden
Neu: 4 neue MVC-Controller
- `RolesController` — Rollen & Rechte verwalten (index, savePermissions, createRole, deleteRole)
- `SystemController` — Wartungsmodus & System-Nachricht (index, toggleMaintenance, saveMessage)
- `RevisionController` — Versionsverwaltung CRUD (index, store, update, delete, setCurrent)
- `DesignController` — Design aktivieren (index, activate)
- Inline-PHP komplett aus `roles.php`, `system.php`, `revisions.php`, `designs.php` entfernt
Neu: Header-Hintergrundbild je CMS-Seite
- Neue Spalte `header_image` in `cms_pages` — jede Seite kann ein eigenes Header-Bild bekommen
- Admin-UI im Content Manager mit Mediathek-Picker direkt im Seiten-Edit-Formular
Geändert
- `FooterManager`, `KlaroManager`, `ConfigSettingsService` — Redirect-Logik entfernt, AJAX-kompatibel
- CSRF-Prüfung beim User-Delete nachgezogen
- `NewsController::store()` leitet nach Erstellen direkt zur Edit-Seite weiter
- Alle `?saved=1` Flash-Weiterleitungen durch Toast-Feedback ersetzt
- Mediathek-Picker im Content Manager öffnet jetzt einheitlich ein Modal (kein Browser-Popup mehr)
Fix
- `$flashMsg` undefined Variable in `system.php` nach MVC-Umbau behoben
- Toast-CSS BEM-Klassen (`cx-toast--success` etc.) konsistent mit JS-Output
v0.5.5
14. April 2026
Several updates
Neu: Navbar-Layout-Auswahl (3 Varianten)
- Neue Admin-Seite im Content Manager: Benutzer kann zwischen 3 Navbar-Varianten wählen
- **Layout 1 (Standard)**: klassische Top-Navbar
- **Layout 2 (Slim)**: kompakte Top-Navbar (0.18 rem Padding, kleinere Schrift & Logo)
- **Layout 3 (Sidebar)**: fixierte Sidebar-Navigation links (252 px), restliche Inhalte eingerückt
- Auswahl wird via AJAX gespeichert (`admin/nav/save`) und sofort visuell bestätigt
- CSS-Klassen `nav-layout-1/2/3` auf `<body>` und `<nav>` — vollständig in `nav-layouts.css`
- `nav_layout` in `site_settings` gespeichert
Neu: Sidebar-Navigation Flyout-Submenus
- Dropdown-Menüs in Layout 3 öffnen sich als **Flyout nach rechts** (dunkle Karte, Schatten, abgerundet)
- `<main>`-Wrapper um Content-Bereich (navi.php → footer.php) erzeugt eigenen Stacking Context
- Sidebar-Nav liegt unter `<main>` (`z-index`), Flyout ragt in den Content-Bereich hinein
- User-Menü in Layout 3 via `margin-top: auto` ans untere Ende der Sidebar gepinnt
Neu: Hero-Slot-System (3 unabhängige Hero-Konfigurationen)
- Startseiten-Hero vollständig refaktoriert: 3 unabhängige Slots (nicht mehr design-gebunden)
- Jeder Slot konfiguriert: **Layout** (Cinematic / Split / Centered) + **Hintergrund** (Bild oder Video)
- `active_hero_slot` steuert welcher Slot auf der Startseite angezeigt wird
- Admin-UI (`/admin/hero`): Radio-Buttons wählen Slot — 3 Layout-Karten als Vorschau mit grünem „aktiv"-Badge
- Hintergrund-Konfiguration pro Slot: URL-Eingabe, Mediathek-Picker, Datei-Upload, Vorschau
- `HeroSettingsService` übernimmt komplette Speicherlogik (Keys: `hero1/2/3_layout`, `_bg_src`, `_bg_type`)
- `views/parts/hero.php` liest immer SRC + TYPE aus demselben Slot-Bucket (kein Bucket-Mismatch mehr)
Neu: SettingsController Refaktorierung (Service-Architektur)
- `SettingsController` in eigenständige Klassen aufgeteilt:
- `src/Helpers/SettingsSanitizer.php` — Input-Sanitierung
- `src/Repositories/DesignSettingsRepository.php` — DB-Zugriff Design-Settings
- `src/Services/DesignSettingsService.php` — Design-Logik
- `src/Services/HeroSettingsService.php` — Hero-Slot-Logik
- `src/Services/ConfigSettingsService.php` — allgemeine Konfig
- `src/Services/LogoUploadService.php` — Logo-Upload
- `SettingsController` delegiert nur noch, enthält keine eigene Geschäftslogik mehr
Neu: Designs Universe & Solaris
- **Universe**: zweites Frontend-Design mit eigener CSS-Datei (`universe-custom.css`)
- **Solaris**: drittes Frontend-Design (`solaris-custom.css`, cremefarbene Palette, Sonne-Deko)
- Design-Isolation: pro aktivem Design wird nur die zugehörige CSS-Datei geladen
Fix: Solaris Unterseiten (Changelog, Technisches)
- Video-Section-Header auf Solaris-Unterseiten waren zerschossen (großes Video, kein Overlay, cream-BG)
- Ursache: `corex-custom.css` wird bei Solaris nicht geladen → `.hero-video-bg` und `.overlay-dark` hatten kein CSS
- Fix: `.hero-video-bg`, `.overlay-dark`, `section:has(.hero-video-bg)` in `solaris-custom.css` definiert
UI-Verbesserungen Admin
- Hero-Admin-Seite neu strukturiert: Texte zuerst, dann Hero-Slots (Info-Alert-Box erklärt das System)
- Layout-Vorschaukarten zeigen Name & Beschreibung als Overlay direkt auf dem SVG-Preview
v0.5.0
12. April 2026
UpdateInstaller
Neu: Update-Installer (`/admin/updates/install`)
- Neue Admin-Seite **Updates installieren** — listet alle verfügbaren Update-Pakete mit Status (Installiert / Ausstehend / Gesperrt)
- Erzwungene Reihenfolge — ältere Pakete müssen zuerst eingespielt werden
- Bestätigungs-Modal vor jedem Install mit Paket-Infos und Sicherheitshinweis
- Changelog-Modal pro Paket (read-only Vorschau)
- Wartungsmodus wird automatisch aktiviert/deaktiviert (`try/finally`)
- Zusammenfassungs-Karten (Gesamt / Installiert / Ausstehend)
Neu: `src/Core/UpdatePackager.php`
- `getPackages()` — alle Pakete absteigend nach ID
- `getPackageFiles()` — Dateiliste eines Pakets
- `applyPackage()` — ZIP entpacken, Migrationen ausführen, `installed_at` setzen
- ZIP Path-Traversal-Schutz: jeder Eintrag wird vor dem Extrahieren validiert (kein `realpath()` auf nicht-existente Dateien — manuelle Segment-Auflösung)
- Migrations-Runner: neue `.sql`-Dateien aus `database/migrations-webserver/` werden alphabetisch ausgeführt und in `migrations`-Tabelle eingetragen
Neue DB-Tabellen (Migration `000002`)
- `update_packages` — Paket-Metadaten (Version, Label, Changelog, Archivpfad, Dateizahl, Größe, `installed_at`)
- `update_package_files` — Datei-Manifest pro Paket (Pfad + Änderungstyp)
- Neue Permissions: `admin.updates.create` + `admin.updates.install` (nur Superadmin)
Routing & Sidebar
- Route `GET/POST admin/updates/install` hinzugefügt
- Sidebar: "Updates" → zwei Einträge: **Update-Scanner** + **Updates installieren**
- `updates-install` zu `$systemPages` hinzugefügt
v0.4.8
12. April 2026
Maintenance + FileScanner + CleanUps
Neu: Designs-System (`/admin/designs`)
- Neue Admin-Seite **Designs** unter "Layout" — zeigt verfügbare Frontend-Designs als Cards
- Design "corex" als Standard aktiv; Platzhalter-Card für zukünftige Designs verlinkt auf Updates
- `active_design`-Eintrag in `site_settings` (Migration `000029`)
- Permission `admin.designs.view` + Vergabe an Admin-Rolle
- Custom CSS / JS jetzt design-präfixiert: `corex_custom_css` / `corex_custom_js` — bei Design-Wechsel bleibt Custom Code pro Design erhalten
- `SettingsController::save()` liest `active_design` dynamisch und speichert unter `{design}_custom_css` / `{design}_custom_js`
- Route `admin/designs` hinzugefügt
Neu: Wartungsmodus (`/admin/system`)
- Neue Admin-Seite **System** mit Toggle für Wartungsmodus und editierbarer Meldung
- Frontend-Check in `public/index.php` — eingeloggte Admins werden durchgelassen, alle anderen sehen 503-Seite
- Eigenständige Maintenance-Seite (`views/content/maintenance.php`) — HTTP 503, `Retry-After: 3600`, kein Layout-Overhead
- `maintenance_mode` + `maintenance_message` in `site_settings` (Migration `000028`)
- PRG-Pattern: Flash in `$_SESSION['_flash_system']`, Redirect nach POST → kein "Formular erneut senden"-Dialog bei F5
- Permission `admin.system.view` + Vergabe an Admin-Rolle
Neu: File Scanner & Updates-Vorbereitung (`/admin/updates`)
- `src/Core/FileScanner.php` — scannt Projekt-Dateien, erstellt SHA256-Snapshots, erkennt Änderungen
- `src/Controllers/UpdateController.php` — verwaltet Snapshots
- Admin-Seite `views/admin/updates.php` — zeigt geänderte/neue/gelöschte Dateien seit letztem Snapshot
- DB-Tabelle `file_snapshots` (Migration `000026`)
- `database/migrations` im Scanner-Ignore-Verzeichnis, `database/migrations-webserver` wird erfasst
- Konzeptdokument für vollständigen Update-Installer erstellt (`updates-install.md`)
Asset-Umbenennung & Design-Struktur
- `public/assets/css/custom.css` → `corex-custom.css`
- `public/assets/css/dynamic.php` → `corex-dynamic.php`
- Alle Bild-Assets aus `public/assets/img/` verschoben nach `public/assets/img/corex/`
- Alle Referenzen in Views, CSS, PHP-Controllern aktualisiert (`glob`-Pfade, `url()`, `<img src=`...)
Admin-Sidebar: Umstrukturierung
- Neues Submenu **System**: Wartungsmodus, coreX Versionen, Updates
- **Layout**-Submenu nach Content verschoben, "Designs" als erster Eintrag
- **Verwaltung** jetzt nach Layout
UI: Admin Button-Overrides
- Globale `.btn-*`-Overrides in `main.css` — Gradient-Hintergründe, Neon-Glow, `scale(0.97)` on active
- Outline-Varianten und btn-sm/btn-lg-Anpassungen
Bugfixes
- Maintenance-Check: `=== '1'` → `== '1'` (robust bei DB-Typen), `exit()` → `die()`
- Admin-BG-Thumbnail-URLs auf `assets/img/corex/`-Pfad aktualisiert
- `corex-custom.css`: hard-codierter `url('../img/hero-bg5.png')` → `../img/corex/hero-bg5.png`
v0.4.1
12. April 2026
CleanUp
jQuery vollständig entfernt (Vanilla JS)
- `public/assets/js/corex-init.js` komplett auf Vanilla JS umgeschrieben:
- `$(function)` → `DOMContentLoaded`
- `$.fadeOut` → CSS-Opacity-Transition
- `$(window).scroll` → `addEventListener('scroll', ..., { passive: true })`
- `$.addClass/removeClass` → `classList.toggle`
- `$.css('transform')` → `el.style.transform`
- `$.animate scrollTop` → `window.scrollTo({ behavior: 'smooth' })`
- `views/parts/footer.php`: jQuery-Script-Tag entfernt, Contact-Form-Handler in Vanilla JS übersetzt
- `public/index.html`: jQuery-Script-Tag entfernt, alle jQuery-Blöcke (AOS, Navbar-Scroll, Mouse-Glow, Parallax, Smooth-Scroll, Kontaktformular) auf Vanilla JS umgestellt
bootstrapv5-colorpicker durch Pickr ersetzt (`/admin/settings`)
- `bootstrapv5-colorpicker@0.0.2` (jQuery-Plugin) vollständig entfernt aus `views/admin/parts/footer.php`
- Ersetzt durch **Pickr** (`@simonweis/pickr@1.9.1`) — zero-dependency Vanilla JS Color Picker
- Alle jQuery-Initialisierungsblöcke, Bootstrap-Shim und Slider-Fix-Workaround entfernt
- Pickr angepasstes Dark-Theme (passend zur Admin-Oberfläche)
- `.c-chip`-Klick öffnet Pickr; Farbänderungen synchronisieren live zu `input[type=color]` und dispatchen `input`-Events (alle `oninput`-Handler wie `updateEye()`, `chipSync()` bleiben kompatibel)
Konzept: Update-System (`updatesystem.md`)
- Konzeptdokument für zentrales coreX-Update-System erstellt
- Update-Server (`update.aiqia.de`) liefert signierte `.zip`-Pakete + `manifest.json`
- Update-Client im Admin: Version prüfen, Paket herunterladen, SHA256-Verifikation, Rollback-Snapshot, File-Patches + SQL-Migrationen anwenden
- Implementierungsplan in 3 Phasen für AI-Assistant dokumentiert
v0.4.0
11. April 2026
Rollen- & Rechtesystem + Revisionen/Versionierung
- Rollenbasiertes Rechtesystem, Rollen & Rechte Admin-UI
- Revisionen/Versionen
- Sidebar-Submenüs
- InBlock AOS-Animationen
- UI-Polishing & Bugfixes.
v0.3.6
11. April 2026
Initiales Release
- Routing, Authentifizierung, Adminbereich
- Content Manager & Block-Editor
- Mediathek, News/Blog
- Design Optionen, Hero Editor
coreX Technische Daten → Technische Dokumentation