Shop Projekt - Dokumentation

Label-System & Lokalisierung (i18n)

Zentrale Infrastruktur für alle sprachabhängigen Texte der Benutzeroberfläche (Interface). Das System trennt Interface-Texte strikt vom View-Code und lädt diese performant zur Laufzeit über den App-Core.

🗺️ Stufe 1 | 📚 Entwurf | 📟 2026 06 15 | 📍 Kernsystem

Architektur & Zustandshaltung

Das System unterscheidet sich von klassischen, rein statischen Helpern: Die Steuerung erfolgt datengetrieben über die Tabellen tb_language, tb_label_key und tb_label. Die geladenen Texte werden für die Dauer des Requests zentral innerhalb des App-Kerns (app/core/app.php) in der Instanz von cApp vorgehalten.

Strikte Trennung: Interface vs. Handelskatalog

Inhaltsdaten wie Kategorienamen, Produktnamen oder Artikeltexte gehören nicht in dieses Label-System. Während dieses System ausschließlich für die UI-Struktur (Buttons, Fehlermeldungen, Menüs) zuständig ist, liegen Katalogdaten in separaten Sprachtabellen (z.B. tb_category_lang).

Aktive System-Bausteine

  • label.model.php: Beinhaltet die zentralen Ladefunktionen getLabel() und getLabels() für Datenbankzugriffe.
  • vw_label_export: Die performante Datenbank-View, welche als primäre Exportquelle für Bulk- und Mehrfachabfragen dient.
  • Zentrale Speicherung: Die Klasse cApp speichert Seitenlabels und Navigationslabels isoliert voneinander.
  • Template-Zugriff: Views nutzen je nach Kontext entweder den Core-Aufruf cApp::getInstance()->getLabel() oder greifen direkt auf ein lokal übergebenes $labels-Array zu.

Lade-Mechanismus im App-Core

public function setLabels(): void {
    $this->labels = getLabels(cSession::getLangID(), cSession::getPageID(), cSession::getCatKey(), true);
}

public function setNavLabels(): void {
    $this->navLabels = getLabels(cSession::getLangID(), null, 'nav');
}

Laufzeit-Filterlogik & Query-Kern

Die Funktion getLabels() kombiniert die selektierte Sprache dynamisch mit optionalen Filtern für Seiten-IDs, funktionale Gruppen und den Global-Status. Dabei kommen hochflexible SQL-Abfragen zum Einsatz:

  • Seiten-Zuordnung: Abgleich über kommagetrennte IDs mittels FIND_IN_SET(:pagID, pag_IDs).
  • Gruppen-Tags: Filterung von Teilmengen über Gruppen-Bezeichner mittels lky_group LIKE '% -tag-%'.
  • Global-Status: Direkte Selektion über das Flag lky_is_global (z.B. für standardisierte Buttons und Fehlermeldungen).

SQL-Abfrage-Kern (Prinzip)

SELECT DISTINCT lky_key, label_value
FROM vw_label_export
WHERE lan_ID = :lanID
  AND (...)
ORDER BY lky_key ASC

Präfix-Konventionen & Datenstruktur

lky_keyBeispiel-ZuweisungZweck / Typ
btn_saveSpeichern / SaveAktions-Buttons (Global)
nav_tradingHandel / TradingNavigationselemente (Nav-Gruppe)
msg_login_failLogin fehlgeschlagenSystem- / Validierungsmeldungen
lbl_usernameBenutzername / UsernameFormular-Beschriftungen (Global)

Die strikte Nutzung sprechender Präfixe verhindert Schlüssel-Kollisionen über verschiedene Seiten-Kontexte hinweg.

Fehlerbehandlung & Skalierungs-Strategie

Strikte Fehleranzeige statt Silent-Fallback

Die Methoden getLabel() und getNavLabel() greifen strikt zu. Sollte ein Key im System oder in der gewählten Sprache komplett fehlen, wird ein Fehler im System-Log verankert. Im Frontend wird der Fehler über den Platzhalter Label error: <key> bewusst sichtbar ausgegeben, um fehlende Übersetzungen sofort in der Entwicklung zu erkennen.

Skalierung durch Dateisystem-Caching (Ausblick)

Für High-Traffic-Szenarien ist die Architektur für ein zweistufiges Caching vorbereitet. Neben dem aktiven Request-Cache in der App-Instanz kann eine automatische Generierung nativer PHP-Cachedateien (z.B. /cache/labels_nav_de.php) vorgeschaltet werden. Dies entlastet die SQL-Datenbank vollständig, da der Service Daten per blitzschnellem include einbindet, bis im Admin-Bereich eine Änderung eine automatische Cache-Invalidierung auslöst.