Shop Project - Documentation
Label System & Localization (i18n)
Central infrastructure for all language-dependent user interface (UI) texts. The system strictly separates interface text from view code and loads them performantly at runtime via the app core.
Architecture & State Retention
The system differs from traditional, purely static helpers: It is data-driven, managed via the tables tb_language, tb_label_key, and tb_label. Loaded texts are centrally held for the duration of the request within the app core (app/core/app.php) inside the cApp instance.
Strict Separation: Interface vs. Trading Catalog
Content data such as category names, product names, or article texts do not belong in this label system. While this system is exclusively responsible for the UI structure (buttons, error messages, menus), catalog data resides in separate language tables (e.g., tb_category_lang).
Active System Components
- label.model.php: Contains the central loading functions
getLabel()andgetLabels()for database access. - vw_label_export: The high-performance database view serving as the primary export source for bulk and multi-queries.
- Central Storage: The
cAppclass stores page labels and navigation labels isolated from each other. - Template Access: Depending on the context, views either use the core call
cApp::getInstance()->getLabel()or access a locally passed$labelsarray directly.
Loading Mechanism in 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');
}Runtime Filter Logic & Query Core
The getLabels() function dynamically combines the selected language with optional filters for page IDs, functional groups, and global status, utilizing highly flexible SQL queries:
- Page Assignment: Matching via comma-separated IDs utilizing
FIND_IN_SET(:pagID, pag_IDs). - Group Tags: Filtering subsets via group identifiers using
lky_group LIKE '% -tag-%'. - Global Status: Direct selection via the
lky_is_globalflag (e.g., for standardized buttons and error messages).
SQL Query Core (Principle)
SELECT DISTINCT lky_key, label_value
FROM vw_label_export
WHERE lan_ID = :lanID
AND (...)
ORDER BY lky_key ASCPrefix Conventions & Data Structure
| lky_key | Beispiel-Zuweisung | Zweck / Typ |
|---|---|---|
btn_save | Speichern / Save | Aktions-Buttons (Global) |
nav_trading | Handel / Trading | Navigationselemente (Nav-Gruppe) |
msg_login_fail | Login fehlgeschlagen | System- / Validierungsmeldungen |
lbl_username | Benutzername / Username | Formular-Beschriftungen (Global) |
The strict use of descriptive prefixes prevents key collisions across different page contexts.
Error Handling & Scaling Strategy
Strict Error Display instead of Silent-Fallback
The methods getLabel() and getNavLabel() access entries strictly. If a key is completely missing in the system or chosen language, an error is logged. In the frontend, the error is intentionally made visible via the placeholder Label error: <key> to catch missing translations immediately during development.
Scaling via Filesystem Caching (Outlook)
For high-traffic scenarios, the architecture is prepared for two-stage caching. In addition to the active request cache within the app instance, automatic generation of native PHP cache files (e.g., /cache/labels_nav_de.php) can be prepended. This completely unburdens the SQL database as the service includes data via lightning-fast include statements until an administrative update triggers an automatic cache invalidation.